xref: /kernel/linux/linux-5.10/net/mac80211/chan.c (revision 8c2ecf20)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * mac80211 - channel management
4 */
5
6#include <linux/nl80211.h>
7#include <linux/export.h>
8#include <linux/rtnetlink.h>
9#include <net/cfg80211.h>
10#include "ieee80211_i.h"
11#include "driver-ops.h"
12
13static int ieee80211_chanctx_num_assigned(struct ieee80211_local *local,
14					  struct ieee80211_chanctx *ctx)
15{
16	struct ieee80211_sub_if_data *sdata;
17	int num = 0;
18
19	lockdep_assert_held(&local->chanctx_mtx);
20
21	list_for_each_entry(sdata, &ctx->assigned_vifs, assigned_chanctx_list)
22		num++;
23
24	return num;
25}
26
27static int ieee80211_chanctx_num_reserved(struct ieee80211_local *local,
28					  struct ieee80211_chanctx *ctx)
29{
30	struct ieee80211_sub_if_data *sdata;
31	int num = 0;
32
33	lockdep_assert_held(&local->chanctx_mtx);
34
35	list_for_each_entry(sdata, &ctx->reserved_vifs, reserved_chanctx_list)
36		num++;
37
38	return num;
39}
40
41int ieee80211_chanctx_refcount(struct ieee80211_local *local,
42			       struct ieee80211_chanctx *ctx)
43{
44	return ieee80211_chanctx_num_assigned(local, ctx) +
45	       ieee80211_chanctx_num_reserved(local, ctx);
46}
47
48static int ieee80211_num_chanctx(struct ieee80211_local *local)
49{
50	struct ieee80211_chanctx *ctx;
51	int num = 0;
52
53	lockdep_assert_held(&local->chanctx_mtx);
54
55	list_for_each_entry(ctx, &local->chanctx_list, list)
56		num++;
57
58	return num;
59}
60
61static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local)
62{
63	lockdep_assert_held(&local->chanctx_mtx);
64	return ieee80211_num_chanctx(local) < ieee80211_max_num_channels(local);
65}
66
67static struct ieee80211_chanctx *
68ieee80211_vif_get_chanctx(struct ieee80211_sub_if_data *sdata)
69{
70	struct ieee80211_local *local __maybe_unused = sdata->local;
71	struct ieee80211_chanctx_conf *conf;
72
73	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
74					 lockdep_is_held(&local->chanctx_mtx));
75	if (!conf)
76		return NULL;
77
78	return container_of(conf, struct ieee80211_chanctx, conf);
79}
80
81static const struct cfg80211_chan_def *
82ieee80211_chanctx_reserved_chandef(struct ieee80211_local *local,
83				   struct ieee80211_chanctx *ctx,
84				   const struct cfg80211_chan_def *compat)
85{
86	struct ieee80211_sub_if_data *sdata;
87
88	lockdep_assert_held(&local->chanctx_mtx);
89
90	list_for_each_entry(sdata, &ctx->reserved_vifs,
91			    reserved_chanctx_list) {
92		if (!compat)
93			compat = &sdata->reserved_chandef;
94
95		compat = cfg80211_chandef_compatible(&sdata->reserved_chandef,
96						     compat);
97		if (!compat)
98			break;
99	}
100
101	return compat;
102}
103
104static const struct cfg80211_chan_def *
105ieee80211_chanctx_non_reserved_chandef(struct ieee80211_local *local,
106				       struct ieee80211_chanctx *ctx,
107				       const struct cfg80211_chan_def *compat)
108{
109	struct ieee80211_sub_if_data *sdata;
110
111	lockdep_assert_held(&local->chanctx_mtx);
112
113	list_for_each_entry(sdata, &ctx->assigned_vifs,
114			    assigned_chanctx_list) {
115		if (sdata->reserved_chanctx != NULL)
116			continue;
117
118		if (!compat)
119			compat = &sdata->vif.bss_conf.chandef;
120
121		compat = cfg80211_chandef_compatible(
122				&sdata->vif.bss_conf.chandef, compat);
123		if (!compat)
124			break;
125	}
126
127	return compat;
128}
129
130static const struct cfg80211_chan_def *
131ieee80211_chanctx_combined_chandef(struct ieee80211_local *local,
132				   struct ieee80211_chanctx *ctx,
133				   const struct cfg80211_chan_def *compat)
134{
135	lockdep_assert_held(&local->chanctx_mtx);
136
137	compat = ieee80211_chanctx_reserved_chandef(local, ctx, compat);
138	if (!compat)
139		return NULL;
140
141	compat = ieee80211_chanctx_non_reserved_chandef(local, ctx, compat);
142	if (!compat)
143		return NULL;
144
145	return compat;
146}
147
148static bool
149ieee80211_chanctx_can_reserve_chandef(struct ieee80211_local *local,
150				      struct ieee80211_chanctx *ctx,
151				      const struct cfg80211_chan_def *def)
152{
153	lockdep_assert_held(&local->chanctx_mtx);
154
155	if (ieee80211_chanctx_combined_chandef(local, ctx, def))
156		return true;
157
158	if (!list_empty(&ctx->reserved_vifs) &&
159	    ieee80211_chanctx_reserved_chandef(local, ctx, def))
160		return true;
161
162	return false;
163}
164
165static struct ieee80211_chanctx *
166ieee80211_find_reservation_chanctx(struct ieee80211_local *local,
167				   const struct cfg80211_chan_def *chandef,
168				   enum ieee80211_chanctx_mode mode)
169{
170	struct ieee80211_chanctx *ctx;
171
172	lockdep_assert_held(&local->chanctx_mtx);
173
174	if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
175		return NULL;
176
177	list_for_each_entry(ctx, &local->chanctx_list, list) {
178		if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
179			continue;
180
181		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
182			continue;
183
184		if (!ieee80211_chanctx_can_reserve_chandef(local, ctx,
185							   chandef))
186			continue;
187
188		return ctx;
189	}
190
191	return NULL;
192}
193
194enum nl80211_chan_width ieee80211_get_sta_bw(struct ieee80211_sta *sta)
195{
196	switch (sta->bandwidth) {
197	case IEEE80211_STA_RX_BW_20:
198		if (sta->ht_cap.ht_supported)
199			return NL80211_CHAN_WIDTH_20;
200		else
201			return NL80211_CHAN_WIDTH_20_NOHT;
202	case IEEE80211_STA_RX_BW_40:
203		return NL80211_CHAN_WIDTH_40;
204	case IEEE80211_STA_RX_BW_80:
205		return NL80211_CHAN_WIDTH_80;
206	case IEEE80211_STA_RX_BW_160:
207		/*
208		 * This applied for both 160 and 80+80. since we use
209		 * the returned value to consider degradation of
210		 * ctx->conf.min_def, we have to make sure to take
211		 * the bigger one (NL80211_CHAN_WIDTH_160).
212		 * Otherwise we might try degrading even when not
213		 * needed, as the max required sta_bw returned (80+80)
214		 * might be smaller than the configured bw (160).
215		 */
216		return NL80211_CHAN_WIDTH_160;
217	default:
218		WARN_ON(1);
219		return NL80211_CHAN_WIDTH_20;
220	}
221}
222
223static enum nl80211_chan_width
224ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata)
225{
226	enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
227	struct sta_info *sta;
228
229	rcu_read_lock();
230	list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) {
231		if (sdata != sta->sdata &&
232		    !(sta->sdata->bss && sta->sdata->bss == sdata->bss))
233			continue;
234
235		max_bw = max(max_bw, ieee80211_get_sta_bw(&sta->sta));
236	}
237	rcu_read_unlock();
238
239	return max_bw;
240}
241
242static enum nl80211_chan_width
243ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
244				      struct ieee80211_chanctx_conf *conf)
245{
246	struct ieee80211_sub_if_data *sdata;
247	enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
248
249	rcu_read_lock();
250	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
251		struct ieee80211_vif *vif = &sdata->vif;
252		enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20_NOHT;
253
254		if (!ieee80211_sdata_running(sdata))
255			continue;
256
257		if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
258			continue;
259
260		switch (vif->type) {
261		case NL80211_IFTYPE_AP:
262		case NL80211_IFTYPE_AP_VLAN:
263			width = ieee80211_get_max_required_bw(sdata);
264			break;
265		case NL80211_IFTYPE_STATION:
266			/*
267			 * The ap's sta->bandwidth is not set yet at this
268			 * point, so take the width from the chandef, but
269			 * account also for TDLS peers
270			 */
271			width = max(vif->bss_conf.chandef.width,
272				    ieee80211_get_max_required_bw(sdata));
273			break;
274		case NL80211_IFTYPE_P2P_DEVICE:
275		case NL80211_IFTYPE_NAN:
276			continue;
277		case NL80211_IFTYPE_ADHOC:
278		case NL80211_IFTYPE_WDS:
279		case NL80211_IFTYPE_MESH_POINT:
280		case NL80211_IFTYPE_OCB:
281			width = vif->bss_conf.chandef.width;
282			break;
283		case NL80211_IFTYPE_UNSPECIFIED:
284		case NUM_NL80211_IFTYPES:
285		case NL80211_IFTYPE_MONITOR:
286		case NL80211_IFTYPE_P2P_CLIENT:
287		case NL80211_IFTYPE_P2P_GO:
288			WARN_ON_ONCE(1);
289		}
290		max_bw = max(max_bw, width);
291	}
292
293	/* use the configured bandwidth in case of monitor interface */
294	sdata = rcu_dereference(local->monitor_sdata);
295	if (sdata && rcu_access_pointer(sdata->vif.chanctx_conf) == conf)
296		max_bw = max(max_bw, conf->def.width);
297
298	rcu_read_unlock();
299
300	return max_bw;
301}
302
303/*
304 * recalc the min required chan width of the channel context, which is
305 * the max of min required widths of all the interfaces bound to this
306 * channel context.
307 */
308void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
309				      struct ieee80211_chanctx *ctx)
310{
311	enum nl80211_chan_width max_bw;
312	struct cfg80211_chan_def min_def;
313
314	lockdep_assert_held(&local->chanctx_mtx);
315
316	/* don't optimize non-20MHz based and radar_enabled confs */
317	if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 ||
318	    ctx->conf.def.width == NL80211_CHAN_WIDTH_10 ||
319	    ctx->conf.def.width == NL80211_CHAN_WIDTH_1 ||
320	    ctx->conf.def.width == NL80211_CHAN_WIDTH_2 ||
321	    ctx->conf.def.width == NL80211_CHAN_WIDTH_4 ||
322	    ctx->conf.def.width == NL80211_CHAN_WIDTH_8 ||
323	    ctx->conf.def.width == NL80211_CHAN_WIDTH_16 ||
324	    ctx->conf.radar_enabled) {
325		ctx->conf.min_def = ctx->conf.def;
326		return;
327	}
328
329	max_bw = ieee80211_get_chanctx_max_required_bw(local, &ctx->conf);
330
331	/* downgrade chandef up to max_bw */
332	min_def = ctx->conf.def;
333	while (min_def.width > max_bw)
334		ieee80211_chandef_downgrade(&min_def);
335
336	if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def))
337		return;
338
339	ctx->conf.min_def = min_def;
340	if (!ctx->driver_present)
341		return;
342
343	drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_MIN_WIDTH);
344}
345
346static void ieee80211_change_chanctx(struct ieee80211_local *local,
347				     struct ieee80211_chanctx *ctx,
348				     const struct cfg80211_chan_def *chandef)
349{
350	if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) {
351		ieee80211_recalc_chanctx_min_def(local, ctx);
352		return;
353	}
354
355	WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
356
357	ctx->conf.def = *chandef;
358	drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH);
359	ieee80211_recalc_chanctx_min_def(local, ctx);
360
361	if (!local->use_chanctx) {
362		local->_oper_chandef = *chandef;
363		ieee80211_hw_config(local, 0);
364	}
365}
366
367static struct ieee80211_chanctx *
368ieee80211_find_chanctx(struct ieee80211_local *local,
369		       const struct cfg80211_chan_def *chandef,
370		       enum ieee80211_chanctx_mode mode)
371{
372	struct ieee80211_chanctx *ctx;
373
374	lockdep_assert_held(&local->chanctx_mtx);
375
376	if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
377		return NULL;
378
379	list_for_each_entry(ctx, &local->chanctx_list, list) {
380		const struct cfg80211_chan_def *compat;
381
382		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACE_NONE)
383			continue;
384
385		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
386			continue;
387
388		compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef);
389		if (!compat)
390			continue;
391
392		compat = ieee80211_chanctx_reserved_chandef(local, ctx,
393							    compat);
394		if (!compat)
395			continue;
396
397		ieee80211_change_chanctx(local, ctx, compat);
398
399		return ctx;
400	}
401
402	return NULL;
403}
404
405bool ieee80211_is_radar_required(struct ieee80211_local *local)
406{
407	struct ieee80211_sub_if_data *sdata;
408
409	lockdep_assert_held(&local->mtx);
410
411	rcu_read_lock();
412	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
413		if (sdata->radar_required) {
414			rcu_read_unlock();
415			return true;
416		}
417	}
418	rcu_read_unlock();
419
420	return false;
421}
422
423static bool
424ieee80211_chanctx_radar_required(struct ieee80211_local *local,
425				 struct ieee80211_chanctx *ctx)
426{
427	struct ieee80211_chanctx_conf *conf = &ctx->conf;
428	struct ieee80211_sub_if_data *sdata;
429	bool required = false;
430
431	lockdep_assert_held(&local->chanctx_mtx);
432	lockdep_assert_held(&local->mtx);
433
434	rcu_read_lock();
435	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
436		if (!ieee80211_sdata_running(sdata))
437			continue;
438		if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
439			continue;
440		if (!sdata->radar_required)
441			continue;
442
443		required = true;
444		break;
445	}
446	rcu_read_unlock();
447
448	return required;
449}
450
451static struct ieee80211_chanctx *
452ieee80211_alloc_chanctx(struct ieee80211_local *local,
453			const struct cfg80211_chan_def *chandef,
454			enum ieee80211_chanctx_mode mode)
455{
456	struct ieee80211_chanctx *ctx;
457
458	lockdep_assert_held(&local->chanctx_mtx);
459
460	ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL);
461	if (!ctx)
462		return NULL;
463
464	INIT_LIST_HEAD(&ctx->assigned_vifs);
465	INIT_LIST_HEAD(&ctx->reserved_vifs);
466	ctx->conf.def = *chandef;
467	ctx->conf.rx_chains_static = 1;
468	ctx->conf.rx_chains_dynamic = 1;
469	ctx->mode = mode;
470	ctx->conf.radar_enabled = false;
471	ieee80211_recalc_chanctx_min_def(local, ctx);
472
473	return ctx;
474}
475
476static int ieee80211_add_chanctx(struct ieee80211_local *local,
477				 struct ieee80211_chanctx *ctx)
478{
479	u32 changed;
480	int err;
481
482	lockdep_assert_held(&local->mtx);
483	lockdep_assert_held(&local->chanctx_mtx);
484
485	if (!local->use_chanctx)
486		local->hw.conf.radar_enabled = ctx->conf.radar_enabled;
487
488	/* turn idle off *before* setting channel -- some drivers need that */
489	changed = ieee80211_idle_off(local);
490	if (changed)
491		ieee80211_hw_config(local, changed);
492
493	if (!local->use_chanctx) {
494		local->_oper_chandef = ctx->conf.def;
495		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
496	} else {
497		err = drv_add_chanctx(local, ctx);
498		if (err) {
499			ieee80211_recalc_idle(local);
500			return err;
501		}
502	}
503
504	return 0;
505}
506
507static struct ieee80211_chanctx *
508ieee80211_new_chanctx(struct ieee80211_local *local,
509		      const struct cfg80211_chan_def *chandef,
510		      enum ieee80211_chanctx_mode mode)
511{
512	struct ieee80211_chanctx *ctx;
513	int err;
514
515	lockdep_assert_held(&local->mtx);
516	lockdep_assert_held(&local->chanctx_mtx);
517
518	ctx = ieee80211_alloc_chanctx(local, chandef, mode);
519	if (!ctx)
520		return ERR_PTR(-ENOMEM);
521
522	err = ieee80211_add_chanctx(local, ctx);
523	if (err) {
524		kfree(ctx);
525		return ERR_PTR(err);
526	}
527
528	list_add_rcu(&ctx->list, &local->chanctx_list);
529	return ctx;
530}
531
532static void ieee80211_del_chanctx(struct ieee80211_local *local,
533				  struct ieee80211_chanctx *ctx)
534{
535	lockdep_assert_held(&local->chanctx_mtx);
536
537	if (!local->use_chanctx) {
538		struct cfg80211_chan_def *chandef = &local->_oper_chandef;
539		/* S1G doesn't have 20MHz, so get the correct width for the
540		 * current channel.
541		 */
542		if (chandef->chan->band == NL80211_BAND_S1GHZ)
543			chandef->width =
544				ieee80211_s1g_channel_width(chandef->chan);
545		else
546			chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
547		chandef->center_freq1 = chandef->chan->center_freq;
548		chandef->freq1_offset = chandef->chan->freq_offset;
549		chandef->center_freq2 = 0;
550
551		/* NOTE: Disabling radar is only valid here for
552		 * single channel context. To be sure, check it ...
553		 */
554		WARN_ON(local->hw.conf.radar_enabled &&
555			!list_empty(&local->chanctx_list));
556
557		local->hw.conf.radar_enabled = false;
558
559		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
560	} else {
561		drv_remove_chanctx(local, ctx);
562	}
563
564	ieee80211_recalc_idle(local);
565}
566
567static void ieee80211_free_chanctx(struct ieee80211_local *local,
568				   struct ieee80211_chanctx *ctx)
569{
570	lockdep_assert_held(&local->chanctx_mtx);
571
572	WARN_ON_ONCE(ieee80211_chanctx_refcount(local, ctx) != 0);
573
574	list_del_rcu(&ctx->list);
575	ieee80211_del_chanctx(local, ctx);
576	kfree_rcu(ctx, rcu_head);
577}
578
579void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
580				       struct ieee80211_chanctx *ctx)
581{
582	struct ieee80211_chanctx_conf *conf = &ctx->conf;
583	struct ieee80211_sub_if_data *sdata;
584	const struct cfg80211_chan_def *compat = NULL;
585	struct sta_info *sta;
586
587	lockdep_assert_held(&local->chanctx_mtx);
588
589	rcu_read_lock();
590	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
591
592		if (!ieee80211_sdata_running(sdata))
593			continue;
594		if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
595			continue;
596		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
597			continue;
598
599		if (!compat)
600			compat = &sdata->vif.bss_conf.chandef;
601
602		compat = cfg80211_chandef_compatible(
603				&sdata->vif.bss_conf.chandef, compat);
604		if (WARN_ON_ONCE(!compat))
605			break;
606	}
607
608	/* TDLS peers can sometimes affect the chandef width */
609	list_for_each_entry_rcu(sta, &local->sta_list, list) {
610		if (!sta->uploaded ||
611		    !test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW) ||
612		    !test_sta_flag(sta, WLAN_STA_AUTHORIZED) ||
613		    !sta->tdls_chandef.chan)
614			continue;
615
616		compat = cfg80211_chandef_compatible(&sta->tdls_chandef,
617						     compat);
618		if (WARN_ON_ONCE(!compat))
619			break;
620	}
621	rcu_read_unlock();
622
623	if (!compat)
624		return;
625
626	ieee80211_change_chanctx(local, ctx, compat);
627}
628
629static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local,
630					   struct ieee80211_chanctx *chanctx)
631{
632	bool radar_enabled;
633
634	lockdep_assert_held(&local->chanctx_mtx);
635	/* for ieee80211_is_radar_required */
636	lockdep_assert_held(&local->mtx);
637
638	radar_enabled = ieee80211_chanctx_radar_required(local, chanctx);
639
640	if (radar_enabled == chanctx->conf.radar_enabled)
641		return;
642
643	chanctx->conf.radar_enabled = radar_enabled;
644
645	if (!local->use_chanctx) {
646		local->hw.conf.radar_enabled = chanctx->conf.radar_enabled;
647		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
648	}
649
650	drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR);
651}
652
653static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
654					struct ieee80211_chanctx *new_ctx)
655{
656	struct ieee80211_local *local = sdata->local;
657	struct ieee80211_chanctx_conf *conf;
658	struct ieee80211_chanctx *curr_ctx = NULL;
659	int ret = 0;
660
661	if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN))
662		return -ENOTSUPP;
663
664	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
665					 lockdep_is_held(&local->chanctx_mtx));
666
667	if (conf) {
668		curr_ctx = container_of(conf, struct ieee80211_chanctx, conf);
669
670		drv_unassign_vif_chanctx(local, sdata, curr_ctx);
671		conf = NULL;
672		list_del(&sdata->assigned_chanctx_list);
673	}
674
675	if (new_ctx) {
676		ret = drv_assign_vif_chanctx(local, sdata, new_ctx);
677		if (ret)
678			goto out;
679
680		conf = &new_ctx->conf;
681		list_add(&sdata->assigned_chanctx_list,
682			 &new_ctx->assigned_vifs);
683	}
684
685out:
686	rcu_assign_pointer(sdata->vif.chanctx_conf, conf);
687
688	sdata->vif.bss_conf.idle = !conf;
689
690	if (curr_ctx && ieee80211_chanctx_num_assigned(local, curr_ctx) > 0) {
691		ieee80211_recalc_chanctx_chantype(local, curr_ctx);
692		ieee80211_recalc_smps_chanctx(local, curr_ctx);
693		ieee80211_recalc_radar_chanctx(local, curr_ctx);
694		ieee80211_recalc_chanctx_min_def(local, curr_ctx);
695	}
696
697	if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) {
698		ieee80211_recalc_txpower(sdata, false);
699		ieee80211_recalc_chanctx_min_def(local, new_ctx);
700	}
701
702	if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
703	    sdata->vif.type != NL80211_IFTYPE_MONITOR)
704		ieee80211_bss_info_change_notify(sdata,
705						 BSS_CHANGED_IDLE);
706
707	ieee80211_check_fast_xmit_iface(sdata);
708
709	return ret;
710}
711
712void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
713				   struct ieee80211_chanctx *chanctx)
714{
715	struct ieee80211_sub_if_data *sdata;
716	u8 rx_chains_static, rx_chains_dynamic;
717
718	lockdep_assert_held(&local->chanctx_mtx);
719
720	rx_chains_static = 1;
721	rx_chains_dynamic = 1;
722
723	rcu_read_lock();
724	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
725		u8 needed_static, needed_dynamic;
726
727		if (!ieee80211_sdata_running(sdata))
728			continue;
729
730		if (rcu_access_pointer(sdata->vif.chanctx_conf) !=
731						&chanctx->conf)
732			continue;
733
734		switch (sdata->vif.type) {
735		case NL80211_IFTYPE_P2P_DEVICE:
736		case NL80211_IFTYPE_NAN:
737			continue;
738		case NL80211_IFTYPE_STATION:
739			if (!sdata->u.mgd.associated)
740				continue;
741			break;
742		case NL80211_IFTYPE_AP_VLAN:
743			continue;
744		case NL80211_IFTYPE_AP:
745		case NL80211_IFTYPE_ADHOC:
746		case NL80211_IFTYPE_WDS:
747		case NL80211_IFTYPE_MESH_POINT:
748		case NL80211_IFTYPE_OCB:
749			break;
750		default:
751			WARN_ON_ONCE(1);
752		}
753
754		switch (sdata->smps_mode) {
755		default:
756			WARN_ONCE(1, "Invalid SMPS mode %d\n",
757				  sdata->smps_mode);
758			fallthrough;
759		case IEEE80211_SMPS_OFF:
760			needed_static = sdata->needed_rx_chains;
761			needed_dynamic = sdata->needed_rx_chains;
762			break;
763		case IEEE80211_SMPS_DYNAMIC:
764			needed_static = 1;
765			needed_dynamic = sdata->needed_rx_chains;
766			break;
767		case IEEE80211_SMPS_STATIC:
768			needed_static = 1;
769			needed_dynamic = 1;
770			break;
771		}
772
773		rx_chains_static = max(rx_chains_static, needed_static);
774		rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic);
775	}
776
777	/* Disable SMPS for the monitor interface */
778	sdata = rcu_dereference(local->monitor_sdata);
779	if (sdata &&
780	    rcu_access_pointer(sdata->vif.chanctx_conf) == &chanctx->conf)
781		rx_chains_dynamic = rx_chains_static = local->rx_chains;
782
783	rcu_read_unlock();
784
785	if (!local->use_chanctx) {
786		if (rx_chains_static > 1)
787			local->smps_mode = IEEE80211_SMPS_OFF;
788		else if (rx_chains_dynamic > 1)
789			local->smps_mode = IEEE80211_SMPS_DYNAMIC;
790		else
791			local->smps_mode = IEEE80211_SMPS_STATIC;
792		ieee80211_hw_config(local, 0);
793	}
794
795	if (rx_chains_static == chanctx->conf.rx_chains_static &&
796	    rx_chains_dynamic == chanctx->conf.rx_chains_dynamic)
797		return;
798
799	chanctx->conf.rx_chains_static = rx_chains_static;
800	chanctx->conf.rx_chains_dynamic = rx_chains_dynamic;
801	drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS);
802}
803
804static void
805__ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
806				      bool clear)
807{
808	struct ieee80211_local *local __maybe_unused = sdata->local;
809	struct ieee80211_sub_if_data *vlan;
810	struct ieee80211_chanctx_conf *conf;
811
812	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP))
813		return;
814
815	lockdep_assert_held(&local->mtx);
816
817	/* Check that conf exists, even when clearing this function
818	 * must be called with the AP's channel context still there
819	 * as it would otherwise cause VLANs to have an invalid
820	 * channel context pointer for a while, possibly pointing
821	 * to a channel context that has already been freed.
822	 */
823	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
824					 lockdep_is_held(&local->chanctx_mtx));
825	WARN_ON(!conf);
826
827	if (clear)
828		conf = NULL;
829
830	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
831		rcu_assign_pointer(vlan->vif.chanctx_conf, conf);
832}
833
834void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
835					 bool clear)
836{
837	struct ieee80211_local *local = sdata->local;
838
839	mutex_lock(&local->chanctx_mtx);
840
841	__ieee80211_vif_copy_chanctx_to_vlans(sdata, clear);
842
843	mutex_unlock(&local->chanctx_mtx);
844}
845
846int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata)
847{
848	struct ieee80211_chanctx *ctx = sdata->reserved_chanctx;
849
850	lockdep_assert_held(&sdata->local->chanctx_mtx);
851
852	if (WARN_ON(!ctx))
853		return -EINVAL;
854
855	list_del(&sdata->reserved_chanctx_list);
856	sdata->reserved_chanctx = NULL;
857
858	if (ieee80211_chanctx_refcount(sdata->local, ctx) == 0) {
859		if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
860			if (WARN_ON(!ctx->replace_ctx))
861				return -EINVAL;
862
863			WARN_ON(ctx->replace_ctx->replace_state !=
864			        IEEE80211_CHANCTX_WILL_BE_REPLACED);
865			WARN_ON(ctx->replace_ctx->replace_ctx != ctx);
866
867			ctx->replace_ctx->replace_ctx = NULL;
868			ctx->replace_ctx->replace_state =
869					IEEE80211_CHANCTX_REPLACE_NONE;
870
871			list_del_rcu(&ctx->list);
872			kfree_rcu(ctx, rcu_head);
873		} else {
874			ieee80211_free_chanctx(sdata->local, ctx);
875		}
876	}
877
878	return 0;
879}
880
881int ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata,
882				  const struct cfg80211_chan_def *chandef,
883				  enum ieee80211_chanctx_mode mode,
884				  bool radar_required)
885{
886	struct ieee80211_local *local = sdata->local;
887	struct ieee80211_chanctx *new_ctx, *curr_ctx, *ctx;
888
889	lockdep_assert_held(&local->chanctx_mtx);
890
891	curr_ctx = ieee80211_vif_get_chanctx(sdata);
892	if (curr_ctx && local->use_chanctx && !local->ops->switch_vif_chanctx)
893		return -ENOTSUPP;
894
895	new_ctx = ieee80211_find_reservation_chanctx(local, chandef, mode);
896	if (!new_ctx) {
897		if (ieee80211_can_create_new_chanctx(local)) {
898			new_ctx = ieee80211_new_chanctx(local, chandef, mode);
899			if (IS_ERR(new_ctx))
900				return PTR_ERR(new_ctx);
901		} else {
902			if (!curr_ctx ||
903			    (curr_ctx->replace_state ==
904			     IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
905			    !list_empty(&curr_ctx->reserved_vifs)) {
906				/*
907				 * Another vif already requested this context
908				 * for a reservation. Find another one hoping
909				 * all vifs assigned to it will also switch
910				 * soon enough.
911				 *
912				 * TODO: This needs a little more work as some
913				 * cases (more than 2 chanctx capable devices)
914				 * may fail which could otherwise succeed
915				 * provided some channel context juggling was
916				 * performed.
917				 *
918				 * Consider ctx1..3, vif1..6, each ctx has 2
919				 * vifs. vif1 and vif2 from ctx1 request new
920				 * different chandefs starting 2 in-place
921				 * reserations with ctx4 and ctx5 replacing
922				 * ctx1 and ctx2 respectively. Next vif5 and
923				 * vif6 from ctx3 reserve ctx4. If vif3 and
924				 * vif4 remain on ctx2 as they are then this
925				 * fails unless `replace_ctx` from ctx5 is
926				 * replaced with ctx3.
927				 */
928				list_for_each_entry(ctx, &local->chanctx_list,
929						    list) {
930					if (ctx->replace_state !=
931					    IEEE80211_CHANCTX_REPLACE_NONE)
932						continue;
933
934					if (!list_empty(&ctx->reserved_vifs))
935						continue;
936
937					curr_ctx = ctx;
938					break;
939				}
940			}
941
942			/*
943			 * If that's true then all available contexts already
944			 * have reservations and cannot be used.
945			 */
946			if (!curr_ctx ||
947			    (curr_ctx->replace_state ==
948			     IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
949			    !list_empty(&curr_ctx->reserved_vifs))
950				return -EBUSY;
951
952			new_ctx = ieee80211_alloc_chanctx(local, chandef, mode);
953			if (!new_ctx)
954				return -ENOMEM;
955
956			new_ctx->replace_ctx = curr_ctx;
957			new_ctx->replace_state =
958					IEEE80211_CHANCTX_REPLACES_OTHER;
959
960			curr_ctx->replace_ctx = new_ctx;
961			curr_ctx->replace_state =
962					IEEE80211_CHANCTX_WILL_BE_REPLACED;
963
964			list_add_rcu(&new_ctx->list, &local->chanctx_list);
965		}
966	}
967
968	list_add(&sdata->reserved_chanctx_list, &new_ctx->reserved_vifs);
969	sdata->reserved_chanctx = new_ctx;
970	sdata->reserved_chandef = *chandef;
971	sdata->reserved_radar_required = radar_required;
972	sdata->reserved_ready = false;
973
974	return 0;
975}
976
977static void
978ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata)
979{
980	switch (sdata->vif.type) {
981	case NL80211_IFTYPE_ADHOC:
982	case NL80211_IFTYPE_AP:
983	case NL80211_IFTYPE_MESH_POINT:
984	case NL80211_IFTYPE_OCB:
985		ieee80211_queue_work(&sdata->local->hw,
986				     &sdata->csa_finalize_work);
987		break;
988	case NL80211_IFTYPE_STATION:
989		ieee80211_queue_work(&sdata->local->hw,
990				     &sdata->u.mgd.chswitch_work);
991		break;
992	case NL80211_IFTYPE_UNSPECIFIED:
993	case NL80211_IFTYPE_AP_VLAN:
994	case NL80211_IFTYPE_WDS:
995	case NL80211_IFTYPE_MONITOR:
996	case NL80211_IFTYPE_P2P_CLIENT:
997	case NL80211_IFTYPE_P2P_GO:
998	case NL80211_IFTYPE_P2P_DEVICE:
999	case NL80211_IFTYPE_NAN:
1000	case NUM_NL80211_IFTYPES:
1001		WARN_ON(1);
1002		break;
1003	}
1004}
1005
1006static void
1007ieee80211_vif_update_chandef(struct ieee80211_sub_if_data *sdata,
1008			     const struct cfg80211_chan_def *chandef)
1009{
1010	struct ieee80211_sub_if_data *vlan;
1011
1012	sdata->vif.bss_conf.chandef = *chandef;
1013
1014	if (sdata->vif.type != NL80211_IFTYPE_AP)
1015		return;
1016
1017	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
1018		vlan->vif.bss_conf.chandef = *chandef;
1019}
1020
1021static int
1022ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
1023{
1024	struct ieee80211_local *local = sdata->local;
1025	struct ieee80211_vif_chanctx_switch vif_chsw[1] = {};
1026	struct ieee80211_chanctx *old_ctx, *new_ctx;
1027	const struct cfg80211_chan_def *chandef;
1028	u32 changed = 0;
1029	int err;
1030
1031	lockdep_assert_held(&local->mtx);
1032	lockdep_assert_held(&local->chanctx_mtx);
1033
1034	new_ctx = sdata->reserved_chanctx;
1035	old_ctx = ieee80211_vif_get_chanctx(sdata);
1036
1037	if (WARN_ON(!sdata->reserved_ready))
1038		return -EBUSY;
1039
1040	if (WARN_ON(!new_ctx))
1041		return -EINVAL;
1042
1043	if (WARN_ON(!old_ctx))
1044		return -EINVAL;
1045
1046	if (WARN_ON(new_ctx->replace_state ==
1047		    IEEE80211_CHANCTX_REPLACES_OTHER))
1048		return -EINVAL;
1049
1050	chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
1051				&sdata->reserved_chandef);
1052	if (WARN_ON(!chandef))
1053		return -EINVAL;
1054
1055	ieee80211_change_chanctx(local, new_ctx, chandef);
1056
1057	vif_chsw[0].vif = &sdata->vif;
1058	vif_chsw[0].old_ctx = &old_ctx->conf;
1059	vif_chsw[0].new_ctx = &new_ctx->conf;
1060
1061	list_del(&sdata->reserved_chanctx_list);
1062	sdata->reserved_chanctx = NULL;
1063
1064	err = drv_switch_vif_chanctx(local, vif_chsw, 1,
1065				     CHANCTX_SWMODE_REASSIGN_VIF);
1066	if (err) {
1067		if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
1068			ieee80211_free_chanctx(local, new_ctx);
1069
1070		goto out;
1071	}
1072
1073	list_move(&sdata->assigned_chanctx_list, &new_ctx->assigned_vifs);
1074	rcu_assign_pointer(sdata->vif.chanctx_conf, &new_ctx->conf);
1075
1076	if (sdata->vif.type == NL80211_IFTYPE_AP)
1077		__ieee80211_vif_copy_chanctx_to_vlans(sdata, false);
1078
1079	ieee80211_check_fast_xmit_iface(sdata);
1080
1081	if (ieee80211_chanctx_refcount(local, old_ctx) == 0)
1082		ieee80211_free_chanctx(local, old_ctx);
1083
1084	if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width)
1085		changed = BSS_CHANGED_BANDWIDTH;
1086
1087	ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
1088
1089	ieee80211_recalc_smps_chanctx(local, new_ctx);
1090	ieee80211_recalc_radar_chanctx(local, new_ctx);
1091	ieee80211_recalc_chanctx_min_def(local, new_ctx);
1092
1093	if (changed)
1094		ieee80211_bss_info_change_notify(sdata, changed);
1095
1096out:
1097	ieee80211_vif_chanctx_reservation_complete(sdata);
1098	return err;
1099}
1100
1101static int
1102ieee80211_vif_use_reserved_assign(struct ieee80211_sub_if_data *sdata)
1103{
1104	struct ieee80211_local *local = sdata->local;
1105	struct ieee80211_chanctx *old_ctx, *new_ctx;
1106	const struct cfg80211_chan_def *chandef;
1107	int err;
1108
1109	old_ctx = ieee80211_vif_get_chanctx(sdata);
1110	new_ctx = sdata->reserved_chanctx;
1111
1112	if (WARN_ON(!sdata->reserved_ready))
1113		return -EINVAL;
1114
1115	if (WARN_ON(old_ctx))
1116		return -EINVAL;
1117
1118	if (WARN_ON(!new_ctx))
1119		return -EINVAL;
1120
1121	if (WARN_ON(new_ctx->replace_state ==
1122		    IEEE80211_CHANCTX_REPLACES_OTHER))
1123		return -EINVAL;
1124
1125	chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
1126				&sdata->reserved_chandef);
1127	if (WARN_ON(!chandef))
1128		return -EINVAL;
1129
1130	ieee80211_change_chanctx(local, new_ctx, chandef);
1131
1132	list_del(&sdata->reserved_chanctx_list);
1133	sdata->reserved_chanctx = NULL;
1134
1135	err = ieee80211_assign_vif_chanctx(sdata, new_ctx);
1136	if (err) {
1137		if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
1138			ieee80211_free_chanctx(local, new_ctx);
1139
1140		goto out;
1141	}
1142
1143out:
1144	ieee80211_vif_chanctx_reservation_complete(sdata);
1145	return err;
1146}
1147
1148static bool
1149ieee80211_vif_has_in_place_reservation(struct ieee80211_sub_if_data *sdata)
1150{
1151	struct ieee80211_chanctx *old_ctx, *new_ctx;
1152
1153	lockdep_assert_held(&sdata->local->chanctx_mtx);
1154
1155	new_ctx = sdata->reserved_chanctx;
1156	old_ctx = ieee80211_vif_get_chanctx(sdata);
1157
1158	if (!old_ctx)
1159		return false;
1160
1161	if (WARN_ON(!new_ctx))
1162		return false;
1163
1164	if (old_ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
1165		return false;
1166
1167	if (new_ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1168		return false;
1169
1170	return true;
1171}
1172
1173static int ieee80211_chsw_switch_hwconf(struct ieee80211_local *local,
1174					struct ieee80211_chanctx *new_ctx)
1175{
1176	const struct cfg80211_chan_def *chandef;
1177
1178	lockdep_assert_held(&local->mtx);
1179	lockdep_assert_held(&local->chanctx_mtx);
1180
1181	chandef = ieee80211_chanctx_reserved_chandef(local, new_ctx, NULL);
1182	if (WARN_ON(!chandef))
1183		return -EINVAL;
1184
1185	local->hw.conf.radar_enabled = new_ctx->conf.radar_enabled;
1186	local->_oper_chandef = *chandef;
1187	ieee80211_hw_config(local, 0);
1188
1189	return 0;
1190}
1191
1192static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local,
1193				      int n_vifs)
1194{
1195	struct ieee80211_vif_chanctx_switch *vif_chsw;
1196	struct ieee80211_sub_if_data *sdata;
1197	struct ieee80211_chanctx *ctx, *old_ctx;
1198	int i, err;
1199
1200	lockdep_assert_held(&local->mtx);
1201	lockdep_assert_held(&local->chanctx_mtx);
1202
1203	vif_chsw = kcalloc(n_vifs, sizeof(vif_chsw[0]), GFP_KERNEL);
1204	if (!vif_chsw)
1205		return -ENOMEM;
1206
1207	i = 0;
1208	list_for_each_entry(ctx, &local->chanctx_list, list) {
1209		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1210			continue;
1211
1212		if (WARN_ON(!ctx->replace_ctx)) {
1213			err = -EINVAL;
1214			goto out;
1215		}
1216
1217		list_for_each_entry(sdata, &ctx->reserved_vifs,
1218				    reserved_chanctx_list) {
1219			if (!ieee80211_vif_has_in_place_reservation(
1220					sdata))
1221				continue;
1222
1223			old_ctx = ieee80211_vif_get_chanctx(sdata);
1224			vif_chsw[i].vif = &sdata->vif;
1225			vif_chsw[i].old_ctx = &old_ctx->conf;
1226			vif_chsw[i].new_ctx = &ctx->conf;
1227
1228			i++;
1229		}
1230	}
1231
1232	err = drv_switch_vif_chanctx(local, vif_chsw, n_vifs,
1233				     CHANCTX_SWMODE_SWAP_CONTEXTS);
1234
1235out:
1236	kfree(vif_chsw);
1237	return err;
1238}
1239
1240static int ieee80211_chsw_switch_ctxs(struct ieee80211_local *local)
1241{
1242	struct ieee80211_chanctx *ctx;
1243	int err;
1244
1245	lockdep_assert_held(&local->mtx);
1246	lockdep_assert_held(&local->chanctx_mtx);
1247
1248	list_for_each_entry(ctx, &local->chanctx_list, list) {
1249		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1250			continue;
1251
1252		if (!list_empty(&ctx->replace_ctx->assigned_vifs))
1253			continue;
1254
1255		ieee80211_del_chanctx(local, ctx->replace_ctx);
1256		err = ieee80211_add_chanctx(local, ctx);
1257		if (err)
1258			goto err;
1259	}
1260
1261	return 0;
1262
1263err:
1264	WARN_ON(ieee80211_add_chanctx(local, ctx));
1265	list_for_each_entry_continue_reverse(ctx, &local->chanctx_list, list) {
1266		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1267			continue;
1268
1269		if (!list_empty(&ctx->replace_ctx->assigned_vifs))
1270			continue;
1271
1272		ieee80211_del_chanctx(local, ctx);
1273		WARN_ON(ieee80211_add_chanctx(local, ctx->replace_ctx));
1274	}
1275
1276	return err;
1277}
1278
1279static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
1280{
1281	struct ieee80211_sub_if_data *sdata, *sdata_tmp;
1282	struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx;
1283	struct ieee80211_chanctx *new_ctx = NULL;
1284	int err, n_assigned, n_reserved, n_ready;
1285	int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0;
1286
1287	lockdep_assert_held(&local->mtx);
1288	lockdep_assert_held(&local->chanctx_mtx);
1289
1290	/*
1291	 * If there are 2 independent pairs of channel contexts performing
1292	 * cross-switch of their vifs this code will still wait until both are
1293	 * ready even though it could be possible to switch one before the
1294	 * other is ready.
1295	 *
1296	 * For practical reasons and code simplicity just do a single huge
1297	 * switch.
1298	 */
1299
1300	/*
1301	 * Verify if the reservation is still feasible.
1302	 *  - if it's not then disconnect
1303	 *  - if it is but not all vifs necessary are ready then defer
1304	 */
1305
1306	list_for_each_entry(ctx, &local->chanctx_list, list) {
1307		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1308			continue;
1309
1310		if (WARN_ON(!ctx->replace_ctx)) {
1311			err = -EINVAL;
1312			goto err;
1313		}
1314
1315		if (!local->use_chanctx)
1316			new_ctx = ctx;
1317
1318		n_ctx++;
1319
1320		n_assigned = 0;
1321		n_reserved = 0;
1322		n_ready = 0;
1323
1324		list_for_each_entry(sdata, &ctx->replace_ctx->assigned_vifs,
1325				    assigned_chanctx_list) {
1326			n_assigned++;
1327			if (sdata->reserved_chanctx) {
1328				n_reserved++;
1329				if (sdata->reserved_ready)
1330					n_ready++;
1331			}
1332		}
1333
1334		if (n_assigned != n_reserved) {
1335			if (n_ready == n_reserved) {
1336				wiphy_info(local->hw.wiphy,
1337					   "channel context reservation cannot be finalized because some interfaces aren't switching\n");
1338				err = -EBUSY;
1339				goto err;
1340			}
1341
1342			return -EAGAIN;
1343		}
1344
1345		ctx->conf.radar_enabled = false;
1346		list_for_each_entry(sdata, &ctx->reserved_vifs,
1347				    reserved_chanctx_list) {
1348			if (ieee80211_vif_has_in_place_reservation(sdata) &&
1349			    !sdata->reserved_ready)
1350				return -EAGAIN;
1351
1352			old_ctx = ieee80211_vif_get_chanctx(sdata);
1353			if (old_ctx) {
1354				if (old_ctx->replace_state ==
1355				    IEEE80211_CHANCTX_WILL_BE_REPLACED)
1356					n_vifs_switch++;
1357				else
1358					n_vifs_assign++;
1359			} else {
1360				n_vifs_ctxless++;
1361			}
1362
1363			if (sdata->reserved_radar_required)
1364				ctx->conf.radar_enabled = true;
1365		}
1366	}
1367
1368	if (WARN_ON(n_ctx == 0) ||
1369	    WARN_ON(n_vifs_switch == 0 &&
1370		    n_vifs_assign == 0 &&
1371		    n_vifs_ctxless == 0) ||
1372	    WARN_ON(n_ctx > 1 && !local->use_chanctx) ||
1373	    WARN_ON(!new_ctx && !local->use_chanctx)) {
1374		err = -EINVAL;
1375		goto err;
1376	}
1377
1378	/*
1379	 * All necessary vifs are ready. Perform the switch now depending on
1380	 * reservations and driver capabilities.
1381	 */
1382
1383	if (local->use_chanctx) {
1384		if (n_vifs_switch > 0) {
1385			err = ieee80211_chsw_switch_vifs(local, n_vifs_switch);
1386			if (err)
1387				goto err;
1388		}
1389
1390		if (n_vifs_assign > 0 || n_vifs_ctxless > 0) {
1391			err = ieee80211_chsw_switch_ctxs(local);
1392			if (err)
1393				goto err;
1394		}
1395	} else {
1396		err = ieee80211_chsw_switch_hwconf(local, new_ctx);
1397		if (err)
1398			goto err;
1399	}
1400
1401	/*
1402	 * Update all structures, values and pointers to point to new channel
1403	 * context(s).
1404	 */
1405	list_for_each_entry(ctx, &local->chanctx_list, list) {
1406		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1407			continue;
1408
1409		if (WARN_ON(!ctx->replace_ctx)) {
1410			err = -EINVAL;
1411			goto err;
1412		}
1413
1414		list_for_each_entry(sdata, &ctx->reserved_vifs,
1415				    reserved_chanctx_list) {
1416			u32 changed = 0;
1417
1418			if (!ieee80211_vif_has_in_place_reservation(sdata))
1419				continue;
1420
1421			rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf);
1422
1423			if (sdata->vif.type == NL80211_IFTYPE_AP)
1424				__ieee80211_vif_copy_chanctx_to_vlans(sdata,
1425								      false);
1426
1427			ieee80211_check_fast_xmit_iface(sdata);
1428
1429			sdata->radar_required = sdata->reserved_radar_required;
1430
1431			if (sdata->vif.bss_conf.chandef.width !=
1432			    sdata->reserved_chandef.width)
1433				changed = BSS_CHANGED_BANDWIDTH;
1434
1435			ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
1436			if (changed)
1437				ieee80211_bss_info_change_notify(sdata,
1438								 changed);
1439
1440			ieee80211_recalc_txpower(sdata, false);
1441		}
1442
1443		ieee80211_recalc_chanctx_chantype(local, ctx);
1444		ieee80211_recalc_smps_chanctx(local, ctx);
1445		ieee80211_recalc_radar_chanctx(local, ctx);
1446		ieee80211_recalc_chanctx_min_def(local, ctx);
1447
1448		list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1449					 reserved_chanctx_list) {
1450			if (ieee80211_vif_get_chanctx(sdata) != ctx)
1451				continue;
1452
1453			list_del(&sdata->reserved_chanctx_list);
1454			list_move(&sdata->assigned_chanctx_list,
1455				  &ctx->assigned_vifs);
1456			sdata->reserved_chanctx = NULL;
1457
1458			ieee80211_vif_chanctx_reservation_complete(sdata);
1459		}
1460
1461		/*
1462		 * This context might have been a dependency for an already
1463		 * ready re-assign reservation interface that was deferred. Do
1464		 * not propagate error to the caller though. The in-place
1465		 * reservation for originally requested interface has already
1466		 * succeeded at this point.
1467		 */
1468		list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1469					 reserved_chanctx_list) {
1470			if (WARN_ON(ieee80211_vif_has_in_place_reservation(
1471					sdata)))
1472				continue;
1473
1474			if (WARN_ON(sdata->reserved_chanctx != ctx))
1475				continue;
1476
1477			if (!sdata->reserved_ready)
1478				continue;
1479
1480			if (ieee80211_vif_get_chanctx(sdata))
1481				err = ieee80211_vif_use_reserved_reassign(
1482						sdata);
1483			else
1484				err = ieee80211_vif_use_reserved_assign(sdata);
1485
1486			if (err) {
1487				sdata_info(sdata,
1488					   "failed to finalize (re-)assign reservation (err=%d)\n",
1489					   err);
1490				ieee80211_vif_unreserve_chanctx(sdata);
1491				cfg80211_stop_iface(local->hw.wiphy,
1492						    &sdata->wdev,
1493						    GFP_KERNEL);
1494			}
1495		}
1496	}
1497
1498	/*
1499	 * Finally free old contexts
1500	 */
1501
1502	list_for_each_entry_safe(ctx, ctx_tmp, &local->chanctx_list, list) {
1503		if (ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
1504			continue;
1505
1506		ctx->replace_ctx->replace_ctx = NULL;
1507		ctx->replace_ctx->replace_state =
1508				IEEE80211_CHANCTX_REPLACE_NONE;
1509
1510		list_del_rcu(&ctx->list);
1511		kfree_rcu(ctx, rcu_head);
1512	}
1513
1514	return 0;
1515
1516err:
1517	list_for_each_entry(ctx, &local->chanctx_list, list) {
1518		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1519			continue;
1520
1521		list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1522					 reserved_chanctx_list) {
1523			ieee80211_vif_unreserve_chanctx(sdata);
1524			ieee80211_vif_chanctx_reservation_complete(sdata);
1525		}
1526	}
1527
1528	return err;
1529}
1530
1531static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
1532{
1533	struct ieee80211_local *local = sdata->local;
1534	struct ieee80211_chanctx_conf *conf;
1535	struct ieee80211_chanctx *ctx;
1536	bool use_reserved_switch = false;
1537
1538	lockdep_assert_held(&local->chanctx_mtx);
1539
1540	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1541					 lockdep_is_held(&local->chanctx_mtx));
1542	if (!conf)
1543		return;
1544
1545	ctx = container_of(conf, struct ieee80211_chanctx, conf);
1546
1547	if (sdata->reserved_chanctx) {
1548		if (sdata->reserved_chanctx->replace_state ==
1549		    IEEE80211_CHANCTX_REPLACES_OTHER &&
1550		    ieee80211_chanctx_num_reserved(local,
1551						   sdata->reserved_chanctx) > 1)
1552			use_reserved_switch = true;
1553
1554		ieee80211_vif_unreserve_chanctx(sdata);
1555	}
1556
1557	ieee80211_assign_vif_chanctx(sdata, NULL);
1558	if (ieee80211_chanctx_refcount(local, ctx) == 0)
1559		ieee80211_free_chanctx(local, ctx);
1560
1561	sdata->radar_required = false;
1562
1563	/* Unreserving may ready an in-place reservation. */
1564	if (use_reserved_switch)
1565		ieee80211_vif_use_reserved_switch(local);
1566}
1567
1568int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
1569			      const struct cfg80211_chan_def *chandef,
1570			      enum ieee80211_chanctx_mode mode)
1571{
1572	struct ieee80211_local *local = sdata->local;
1573	struct ieee80211_chanctx *ctx;
1574	u8 radar_detect_width = 0;
1575	int ret;
1576
1577	lockdep_assert_held(&local->mtx);
1578
1579	WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev));
1580
1581	mutex_lock(&local->chanctx_mtx);
1582
1583	ret = cfg80211_chandef_dfs_required(local->hw.wiphy,
1584					    chandef,
1585					    sdata->wdev.iftype);
1586	if (ret < 0)
1587		goto out;
1588	if (ret > 0)
1589		radar_detect_width = BIT(chandef->width);
1590
1591	sdata->radar_required = ret;
1592
1593	ret = ieee80211_check_combinations(sdata, chandef, mode,
1594					   radar_detect_width);
1595	if (ret < 0)
1596		goto out;
1597
1598	__ieee80211_vif_release_channel(sdata);
1599
1600	ctx = ieee80211_find_chanctx(local, chandef, mode);
1601	if (!ctx)
1602		ctx = ieee80211_new_chanctx(local, chandef, mode);
1603	if (IS_ERR(ctx)) {
1604		ret = PTR_ERR(ctx);
1605		goto out;
1606	}
1607
1608	ieee80211_vif_update_chandef(sdata, chandef);
1609
1610	ret = ieee80211_assign_vif_chanctx(sdata, ctx);
1611	if (ret) {
1612		/* if assign fails refcount stays the same */
1613		if (ieee80211_chanctx_refcount(local, ctx) == 0)
1614			ieee80211_free_chanctx(local, ctx);
1615		goto out;
1616	}
1617
1618	ieee80211_recalc_smps_chanctx(local, ctx);
1619	ieee80211_recalc_radar_chanctx(local, ctx);
1620 out:
1621	if (ret)
1622		sdata->radar_required = false;
1623
1624	mutex_unlock(&local->chanctx_mtx);
1625	return ret;
1626}
1627
1628int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata)
1629{
1630	struct ieee80211_local *local = sdata->local;
1631	struct ieee80211_chanctx *new_ctx;
1632	struct ieee80211_chanctx *old_ctx;
1633	int err;
1634
1635	lockdep_assert_held(&local->mtx);
1636	lockdep_assert_held(&local->chanctx_mtx);
1637
1638	new_ctx = sdata->reserved_chanctx;
1639	old_ctx = ieee80211_vif_get_chanctx(sdata);
1640
1641	if (WARN_ON(!new_ctx))
1642		return -EINVAL;
1643
1644	if (WARN_ON(new_ctx->replace_state ==
1645		    IEEE80211_CHANCTX_WILL_BE_REPLACED))
1646		return -EINVAL;
1647
1648	if (WARN_ON(sdata->reserved_ready))
1649		return -EINVAL;
1650
1651	sdata->reserved_ready = true;
1652
1653	if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) {
1654		if (old_ctx)
1655			return ieee80211_vif_use_reserved_reassign(sdata);
1656
1657		return ieee80211_vif_use_reserved_assign(sdata);
1658	}
1659
1660	/*
1661	 * In-place reservation may need to be finalized now either if:
1662	 *  a) sdata is taking part in the swapping itself and is the last one
1663	 *  b) sdata has switched with a re-assign reservation to an existing
1664	 *     context readying in-place switching of old_ctx
1665	 *
1666	 * In case of (b) do not propagate the error up because the requested
1667	 * sdata already switched successfully. Just spill an extra warning.
1668	 * The ieee80211_vif_use_reserved_switch() already stops all necessary
1669	 * interfaces upon failure.
1670	 */
1671	if ((old_ctx &&
1672	     old_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
1673	    new_ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
1674		err = ieee80211_vif_use_reserved_switch(local);
1675		if (err && err != -EAGAIN) {
1676			if (new_ctx->replace_state ==
1677			    IEEE80211_CHANCTX_REPLACES_OTHER)
1678				return err;
1679
1680			wiphy_info(local->hw.wiphy,
1681				   "depending in-place reservation failed (err=%d)\n",
1682				   err);
1683		}
1684	}
1685
1686	return 0;
1687}
1688
1689int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1690				   const struct cfg80211_chan_def *chandef,
1691				   u32 *changed)
1692{
1693	struct ieee80211_local *local = sdata->local;
1694	struct ieee80211_chanctx_conf *conf;
1695	struct ieee80211_chanctx *ctx;
1696	const struct cfg80211_chan_def *compat;
1697	int ret;
1698
1699	if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
1700				     IEEE80211_CHAN_DISABLED))
1701		return -EINVAL;
1702
1703	mutex_lock(&local->chanctx_mtx);
1704	if (cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) {
1705		ret = 0;
1706		goto out;
1707	}
1708
1709	if (chandef->width == NL80211_CHAN_WIDTH_20_NOHT ||
1710	    sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) {
1711		ret = -EINVAL;
1712		goto out;
1713	}
1714
1715	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1716					 lockdep_is_held(&local->chanctx_mtx));
1717	if (!conf) {
1718		ret = -EINVAL;
1719		goto out;
1720	}
1721
1722	ctx = container_of(conf, struct ieee80211_chanctx, conf);
1723
1724	compat = cfg80211_chandef_compatible(&conf->def, chandef);
1725	if (!compat) {
1726		ret = -EINVAL;
1727		goto out;
1728	}
1729
1730	switch (ctx->replace_state) {
1731	case IEEE80211_CHANCTX_REPLACE_NONE:
1732		if (!ieee80211_chanctx_reserved_chandef(local, ctx, compat)) {
1733			ret = -EBUSY;
1734			goto out;
1735		}
1736		break;
1737	case IEEE80211_CHANCTX_WILL_BE_REPLACED:
1738		/* TODO: Perhaps the bandwidth change could be treated as a
1739		 * reservation itself? */
1740		ret = -EBUSY;
1741		goto out;
1742	case IEEE80211_CHANCTX_REPLACES_OTHER:
1743		/* channel context that is going to replace another channel
1744		 * context doesn't really exist and shouldn't be assigned
1745		 * anywhere yet */
1746		WARN_ON(1);
1747		break;
1748	}
1749
1750	ieee80211_vif_update_chandef(sdata, chandef);
1751
1752	ieee80211_recalc_chanctx_chantype(local, ctx);
1753
1754	*changed |= BSS_CHANGED_BANDWIDTH;
1755	ret = 0;
1756 out:
1757	mutex_unlock(&local->chanctx_mtx);
1758	return ret;
1759}
1760
1761void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
1762{
1763	WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev));
1764
1765	lockdep_assert_held(&sdata->local->mtx);
1766
1767	mutex_lock(&sdata->local->chanctx_mtx);
1768	__ieee80211_vif_release_channel(sdata);
1769	mutex_unlock(&sdata->local->chanctx_mtx);
1770}
1771
1772void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata)
1773{
1774	struct ieee80211_local *local = sdata->local;
1775	struct ieee80211_sub_if_data *ap;
1776	struct ieee80211_chanctx_conf *conf;
1777
1778	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss))
1779		return;
1780
1781	ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
1782
1783	mutex_lock(&local->chanctx_mtx);
1784
1785	conf = rcu_dereference_protected(ap->vif.chanctx_conf,
1786					 lockdep_is_held(&local->chanctx_mtx));
1787	rcu_assign_pointer(sdata->vif.chanctx_conf, conf);
1788	mutex_unlock(&local->chanctx_mtx);
1789}
1790
1791void ieee80211_iter_chan_contexts_atomic(
1792	struct ieee80211_hw *hw,
1793	void (*iter)(struct ieee80211_hw *hw,
1794		     struct ieee80211_chanctx_conf *chanctx_conf,
1795		     void *data),
1796	void *iter_data)
1797{
1798	struct ieee80211_local *local = hw_to_local(hw);
1799	struct ieee80211_chanctx *ctx;
1800
1801	rcu_read_lock();
1802	list_for_each_entry_rcu(ctx, &local->chanctx_list, list)
1803		if (ctx->driver_present)
1804			iter(hw, &ctx->conf, iter_data);
1805	rcu_read_unlock();
1806}
1807EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic);
1808