xref: /linux/net/mac80211/chan.c (revision dfecb0c5af3b07ebfa84be63a7a21bfc9e29a872)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * mac80211 - channel management
4  * Copyright 2020-2026 Intel Corporation
5  */
6 
7 #include <linux/nl80211.h>
8 #include <linux/export.h>
9 #include <linux/rtnetlink.h>
10 #include <net/cfg80211.h>
11 #include "ieee80211_i.h"
12 #include "driver-ops.h"
13 #include "rate.h"
14 
15 struct ieee80211_chanctx_user_iter {
16 	struct ieee80211_chan_req *chanreq;
17 	struct ieee80211_sub_if_data *sdata;
18 	struct ieee80211_link_data *link;
19 	enum nl80211_iftype iftype;
20 	bool reserved, radar_required, done;
21 	enum {
22 		CHANCTX_ITER_POS_ASSIGNED,
23 		CHANCTX_ITER_POS_RESERVED,
24 		CHANCTX_ITER_POS_DONE,
25 	} per_link;
26 };
27 
28 enum ieee80211_chanctx_iter_type {
29 	CHANCTX_ITER_ALL,
30 	CHANCTX_ITER_RESERVED,
31 	CHANCTX_ITER_ASSIGNED,
32 };
33 
34 static void ieee80211_chanctx_user_iter_next(struct ieee80211_local *local,
35 					     struct ieee80211_chanctx *ctx,
36 					     struct ieee80211_chanctx_user_iter *iter,
37 					     enum ieee80211_chanctx_iter_type type,
38 					     bool start)
39 {
40 	lockdep_assert_wiphy(local->hw.wiphy);
41 
42 	if (start) {
43 		memset(iter, 0, sizeof(*iter));
44 		goto next_interface;
45 	}
46 
47 next_link:
48 	for (int link_id = iter->link ? iter->link->link_id : 0;
49 	     link_id < ARRAY_SIZE(iter->sdata->link);
50 	     link_id++) {
51 		struct ieee80211_link_data *link;
52 
53 		link = sdata_dereference(iter->sdata->link[link_id],
54 					 iter->sdata);
55 		if (!link)
56 			continue;
57 
58 		switch (iter->per_link) {
59 		case CHANCTX_ITER_POS_ASSIGNED:
60 			iter->per_link = CHANCTX_ITER_POS_RESERVED;
61 			if (type != CHANCTX_ITER_RESERVED &&
62 			    rcu_access_pointer(link->conf->chanctx_conf) == &ctx->conf) {
63 				iter->link = link;
64 				iter->reserved = false;
65 				iter->radar_required = link->radar_required;
66 				iter->chanreq = &link->conf->chanreq;
67 				return;
68 			}
69 			fallthrough;
70 		case CHANCTX_ITER_POS_RESERVED:
71 			iter->per_link = CHANCTX_ITER_POS_DONE;
72 			if (type != CHANCTX_ITER_ASSIGNED &&
73 			    link->reserved_chanctx == ctx) {
74 				iter->link = link;
75 				iter->reserved = true;
76 				iter->radar_required =
77 					link->reserved_radar_required;
78 
79 				iter->chanreq = &link->reserved;
80 				return;
81 			}
82 			fallthrough;
83 		case CHANCTX_ITER_POS_DONE:
84 			iter->per_link = CHANCTX_ITER_POS_ASSIGNED;
85 			continue;
86 		}
87 	}
88 
89 next_interface:
90 	/* next (or first) interface */
91 	iter->sdata = list_prepare_entry(iter->sdata, &local->interfaces, list);
92 	list_for_each_entry_continue(iter->sdata, &local->interfaces, list) {
93 		if (!ieee80211_sdata_running(iter->sdata))
94 			continue;
95 
96 		/* AP_VLAN has a chanctx pointer but follows AP */
97 		if (iter->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
98 			continue;
99 
100 		iter->link = NULL;
101 		iter->per_link = CHANCTX_ITER_POS_ASSIGNED;
102 		iter->iftype = iter->sdata->vif.type;
103 		goto next_link;
104 	}
105 
106 	iter->done = true;
107 }
108 
109 #define for_each_chanctx_user_assigned(local, ctx, iter)		\
110 	for (ieee80211_chanctx_user_iter_next(local, ctx, iter,		\
111 					      CHANCTX_ITER_ASSIGNED,	\
112 					      true);			\
113 	     !((iter)->done);						\
114 	     ieee80211_chanctx_user_iter_next(local, ctx, iter,		\
115 					      CHANCTX_ITER_ASSIGNED,	\
116 					      false))
117 
118 #define for_each_chanctx_user_reserved(local, ctx, iter)		\
119 	for (ieee80211_chanctx_user_iter_next(local, ctx, iter,		\
120 					      CHANCTX_ITER_RESERVED,	\
121 					      true);			\
122 	     !((iter)->done);						\
123 	     ieee80211_chanctx_user_iter_next(local, ctx, iter,		\
124 					      CHANCTX_ITER_RESERVED,	\
125 					      false))
126 
127 #define for_each_chanctx_user_all(local, ctx, iter)			\
128 	for (ieee80211_chanctx_user_iter_next(local, ctx, iter,		\
129 					      CHANCTX_ITER_ALL,		\
130 					      true);			\
131 	     !((iter)->done);						\
132 	     ieee80211_chanctx_user_iter_next(local, ctx, iter,		\
133 					      CHANCTX_ITER_ALL,		\
134 					      false))
135 
136 static int ieee80211_chanctx_num_assigned(struct ieee80211_local *local,
137 					  struct ieee80211_chanctx *ctx)
138 {
139 	struct ieee80211_chanctx_user_iter iter;
140 	int num = 0;
141 
142 	for_each_chanctx_user_assigned(local, ctx, &iter)
143 		num++;
144 
145 	return num;
146 }
147 
148 static int ieee80211_chanctx_num_reserved(struct ieee80211_local *local,
149 					  struct ieee80211_chanctx *ctx)
150 {
151 	struct ieee80211_chanctx_user_iter iter;
152 	int num = 0;
153 
154 	for_each_chanctx_user_reserved(local, ctx, &iter)
155 		num++;
156 
157 	return num;
158 }
159 
160 int ieee80211_chanctx_refcount(struct ieee80211_local *local,
161 			       struct ieee80211_chanctx *ctx)
162 {
163 	struct ieee80211_chanctx_user_iter iter;
164 	int num = 0;
165 
166 	for_each_chanctx_user_all(local, ctx, &iter)
167 		num++;
168 
169 	/*
170 	 * This ctx is in the process of getting used,
171 	 * take it into consideration
172 	 */
173 	if (ctx->will_be_used)
174 		num++;
175 
176 	return num;
177 }
178 
179 static int ieee80211_num_chanctx(struct ieee80211_local *local, int radio_idx)
180 {
181 	struct ieee80211_chanctx *ctx;
182 	int num = 0;
183 
184 	lockdep_assert_wiphy(local->hw.wiphy);
185 
186 	list_for_each_entry(ctx, &local->chanctx_list, list) {
187 		if (radio_idx >= 0 && ctx->conf.radio_idx != radio_idx)
188 			continue;
189 		num++;
190 	}
191 
192 	return num;
193 }
194 
195 static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local,
196 					     int radio_idx)
197 {
198 	lockdep_assert_wiphy(local->hw.wiphy);
199 
200 	return ieee80211_num_chanctx(local, radio_idx) <
201 	       ieee80211_max_num_channels(local, radio_idx);
202 }
203 
204 static struct ieee80211_chanctx *
205 ieee80211_link_get_chanctx(struct ieee80211_link_data *link)
206 {
207 	struct ieee80211_local *local __maybe_unused = link->sdata->local;
208 	struct ieee80211_chanctx_conf *conf;
209 
210 	conf = rcu_dereference_protected(link->conf->chanctx_conf,
211 					 lockdep_is_held(&local->hw.wiphy->mtx));
212 	if (!conf)
213 		return NULL;
214 
215 	return container_of(conf, struct ieee80211_chanctx, conf);
216 }
217 
218 bool ieee80211_chanreq_identical(const struct ieee80211_chan_req *a,
219 				 const struct ieee80211_chan_req *b)
220 {
221 	if (!cfg80211_chandef_identical(&a->oper, &b->oper))
222 		return false;
223 	if (!a->ap.chan && !b->ap.chan)
224 		return true;
225 	return cfg80211_chandef_identical(&a->ap, &b->ap);
226 }
227 
228 static const struct ieee80211_chan_req *
229 ieee80211_chanreq_compatible(const struct ieee80211_chan_req *a,
230 			     const struct ieee80211_chan_req *b,
231 			     struct ieee80211_chan_req *tmp)
232 {
233 	const struct cfg80211_chan_def *compat;
234 
235 	if (a->ap.chan && b->ap.chan &&
236 	    !cfg80211_chandef_identical(&a->ap, &b->ap))
237 		return NULL;
238 
239 	compat = cfg80211_chandef_compatible(&a->oper, &b->oper);
240 	if (!compat)
241 		return NULL;
242 
243 	/* Note: later code assumes this always fills & returns tmp if compat */
244 	tmp->oper = *compat;
245 	tmp->ap = a->ap.chan ? a->ap : b->ap;
246 	return tmp;
247 }
248 
249 /*
250  * When checking for compatible, check against all the links using
251  * the chanctx (except the one passed that might be changing) to
252  * allow changes to the AP's bandwidth for wider bandwidth OFDMA
253  * purposes, which wouldn't be treated as compatible by checking
254  * against the chanctx's oper/ap chandefs.
255  */
256 static const struct ieee80211_chan_req *
257 _ieee80211_chanctx_compatible(struct ieee80211_local *local,
258 			      struct ieee80211_link_data *skip_link,
259 			      struct ieee80211_chanctx *ctx,
260 			      const struct ieee80211_chan_req *req,
261 			      struct ieee80211_chan_req *tmp)
262 {
263 	const struct ieee80211_chan_req *ret = req;
264 	struct ieee80211_chanctx_user_iter iter;
265 
266 	lockdep_assert_wiphy(local->hw.wiphy);
267 
268 	for_each_chanctx_user_all(local, ctx, &iter) {
269 		if (iter.link && iter.link == skip_link)
270 			continue;
271 
272 		ret = ieee80211_chanreq_compatible(ret, iter.chanreq, tmp);
273 		if (!ret)
274 			return NULL;
275 	}
276 
277 	*tmp = *ret;
278 	return tmp;
279 }
280 
281 static const struct ieee80211_chan_req *
282 ieee80211_chanctx_compatible(struct ieee80211_local *local,
283 			     struct ieee80211_chanctx *ctx,
284 			     const struct ieee80211_chan_req *req,
285 			     struct ieee80211_chan_req *tmp)
286 {
287 	return _ieee80211_chanctx_compatible(local, NULL, ctx, req, tmp);
288 }
289 
290 static const struct ieee80211_chan_req *
291 ieee80211_chanctx_reserved_chanreq(struct ieee80211_local *local,
292 				   struct ieee80211_chanctx *ctx,
293 				   const struct ieee80211_chan_req *req,
294 				   struct ieee80211_chan_req *tmp)
295 {
296 	struct ieee80211_chanctx_user_iter iter;
297 
298 	lockdep_assert_wiphy(local->hw.wiphy);
299 
300 	if (WARN_ON(!req))
301 		return NULL;
302 
303 	for_each_chanctx_user_reserved(local, ctx, &iter) {
304 		req = ieee80211_chanreq_compatible(iter.chanreq, req, tmp);
305 		if (!req)
306 			break;
307 	}
308 
309 	return req;
310 }
311 
312 static const struct ieee80211_chan_req *
313 ieee80211_chanctx_non_reserved_chandef(struct ieee80211_local *local,
314 				       struct ieee80211_chanctx *ctx,
315 				       const struct ieee80211_chan_req *compat,
316 				       struct ieee80211_chan_req *tmp)
317 {
318 	const struct ieee80211_chan_req *comp_def = compat;
319 	struct ieee80211_chanctx_user_iter iter;
320 
321 	lockdep_assert_wiphy(local->hw.wiphy);
322 
323 	for_each_chanctx_user_assigned(local, ctx, &iter) {
324 		if (iter.link->reserved_chanctx)
325 			continue;
326 
327 		comp_def = ieee80211_chanreq_compatible(iter.chanreq,
328 							comp_def, tmp);
329 		if (!comp_def)
330 			break;
331 	}
332 
333 	return comp_def;
334 }
335 
336 static bool
337 ieee80211_chanctx_can_reserve(struct ieee80211_local *local,
338 			      struct ieee80211_chanctx *ctx,
339 			      const struct ieee80211_chan_req *req)
340 {
341 	struct ieee80211_chan_req tmp;
342 
343 	lockdep_assert_wiphy(local->hw.wiphy);
344 
345 	if (!ieee80211_chanctx_reserved_chanreq(local, ctx, req, &tmp))
346 		return false;
347 
348 	if (!ieee80211_chanctx_non_reserved_chandef(local, ctx, req, &tmp))
349 		return false;
350 
351 	if (ieee80211_chanctx_num_reserved(local, ctx) != 0 &&
352 	    ieee80211_chanctx_reserved_chanreq(local, ctx, req, &tmp))
353 		return true;
354 
355 	return false;
356 }
357 
358 static struct ieee80211_chanctx *
359 ieee80211_find_reservation_chanctx(struct ieee80211_local *local,
360 				   const struct ieee80211_chan_req *chanreq,
361 				   enum ieee80211_chanctx_mode mode)
362 {
363 	struct ieee80211_chanctx *ctx;
364 
365 	lockdep_assert_wiphy(local->hw.wiphy);
366 
367 	if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
368 		return NULL;
369 
370 	list_for_each_entry(ctx, &local->chanctx_list, list) {
371 		if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
372 			continue;
373 
374 		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
375 			continue;
376 
377 		if (!ieee80211_chanctx_can_reserve(local, ctx, chanreq))
378 			continue;
379 
380 		return ctx;
381 	}
382 
383 	return NULL;
384 }
385 
386 static enum nl80211_chan_width ieee80211_get_sta_bw(struct sta_info *sta,
387 						    unsigned int link_id)
388 {
389 	enum ieee80211_sta_rx_bandwidth width;
390 	struct link_sta_info *link_sta;
391 
392 	link_sta = wiphy_dereference(sta->local->hw.wiphy, sta->link[link_id]);
393 
394 	/* no effect if this STA has no presence on this link */
395 	if (!link_sta)
396 		return NL80211_CHAN_WIDTH_20_NOHT;
397 
398 	/*
399 	 * We assume that TX/RX might be asymmetric (so e.g. VHT operating
400 	 * mode notification changes what a STA wants to receive, but not
401 	 * necessarily what it will transmit to us), and therefore use the
402 	 * capabilities here. Calling it RX bandwidth capability is a bit
403 	 * wrong though, since capabilities are in fact symmetric.
404 	 */
405 	width = ieee80211_sta_cap_rx_bw(link_sta);
406 
407 	switch (width) {
408 	case IEEE80211_STA_RX_BW_20:
409 		if (link_sta->pub->ht_cap.ht_supported)
410 			return NL80211_CHAN_WIDTH_20;
411 		else
412 			return NL80211_CHAN_WIDTH_20_NOHT;
413 	case IEEE80211_STA_RX_BW_40:
414 		return NL80211_CHAN_WIDTH_40;
415 	case IEEE80211_STA_RX_BW_80:
416 		return NL80211_CHAN_WIDTH_80;
417 	case IEEE80211_STA_RX_BW_160:
418 		/*
419 		 * This applied for both 160 and 80+80. since we use
420 		 * the returned value to consider degradation of
421 		 * ctx->conf.min_def, we have to make sure to take
422 		 * the bigger one (NL80211_CHAN_WIDTH_160).
423 		 * Otherwise we might try degrading even when not
424 		 * needed, as the max required sta_bw returned (80+80)
425 		 * might be smaller than the configured bw (160).
426 		 */
427 		return NL80211_CHAN_WIDTH_160;
428 	case IEEE80211_STA_RX_BW_320:
429 		return NL80211_CHAN_WIDTH_320;
430 	default:
431 		WARN_ON(1);
432 		return NL80211_CHAN_WIDTH_20;
433 	}
434 }
435 
436 static enum nl80211_chan_width
437 ieee80211_get_max_required_bw(struct ieee80211_link_data *link)
438 {
439 	struct ieee80211_sub_if_data *sdata = link->sdata;
440 	unsigned int link_id = link->link_id;
441 	enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
442 	struct sta_info *sta;
443 
444 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
445 
446 	list_for_each_entry(sta, &sdata->local->sta_list, list) {
447 		if (sdata != sta->sdata &&
448 		    !(sta->sdata->bss && sta->sdata->bss == sdata->bss))
449 			continue;
450 
451 		max_bw = max(max_bw, ieee80211_get_sta_bw(sta, link_id));
452 	}
453 
454 	return max_bw;
455 }
456 
457 static enum nl80211_chan_width
458 ieee80211_get_width_of_link(struct ieee80211_link_data *link)
459 {
460 	struct ieee80211_local *local = link->sdata->local;
461 
462 	switch (link->sdata->vif.type) {
463 	case NL80211_IFTYPE_STATION:
464 		if (!link->sdata->vif.cfg.assoc) {
465 			/*
466 			 * The AP's sta->bandwidth may not yet be set
467 			 * at this point (pre-association), so simply
468 			 * take the width from the chandef. We cannot
469 			 * have TDLS peers yet (only after association).
470 			 */
471 			return link->conf->chanreq.oper.width;
472 		}
473 		/*
474 		 * otherwise just use min_def like in AP, depending on what
475 		 * we currently think the AP STA (and possibly TDLS peers)
476 		 * require(s)
477 		 */
478 		fallthrough;
479 	case NL80211_IFTYPE_AP:
480 	case NL80211_IFTYPE_AP_VLAN:
481 		return ieee80211_get_max_required_bw(link);
482 	case NL80211_IFTYPE_P2P_DEVICE:
483 	case NL80211_IFTYPE_NAN:
484 		break;
485 	case NL80211_IFTYPE_MONITOR:
486 		WARN_ON_ONCE(!ieee80211_hw_check(&local->hw,
487 						 NO_VIRTUAL_MONITOR));
488 		fallthrough;
489 	case NL80211_IFTYPE_ADHOC:
490 	case NL80211_IFTYPE_MESH_POINT:
491 	case NL80211_IFTYPE_OCB:
492 		return link->conf->chanreq.oper.width;
493 	case NL80211_IFTYPE_WDS:
494 	case NL80211_IFTYPE_UNSPECIFIED:
495 	case NUM_NL80211_IFTYPES:
496 	case NL80211_IFTYPE_P2P_CLIENT:
497 	case NL80211_IFTYPE_P2P_GO:
498 	case NL80211_IFTYPE_NAN_DATA:
499 		WARN_ON_ONCE(1);
500 		break;
501 	}
502 
503 	/* Take the lowest possible, so it won't change the max width */
504 	return NL80211_CHAN_WIDTH_20_NOHT;
505 }
506 
507 static enum nl80211_chan_width
508 ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
509 				      struct ieee80211_chanctx *ctx,
510 				      struct ieee80211_link_data *rsvd_for,
511 				      bool check_reserved)
512 {
513 	enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
514 	struct ieee80211_chanctx_user_iter iter;
515 	struct ieee80211_sub_if_data *sdata;
516 	enum nl80211_chan_width width;
517 
518 	if (WARN_ON(check_reserved && rsvd_for))
519 		return ctx->conf.def.width;
520 
521 	/* When this is true we only care about the reserving links */
522 	if (check_reserved) {
523 		for_each_chanctx_user_reserved(local, ctx, &iter) {
524 			width = ieee80211_get_width_of_link(iter.link);
525 			max_bw = max(max_bw, width);
526 		}
527 		goto check_monitor;
528 	}
529 
530 	/* Consider all assigned links */
531 	for_each_chanctx_user_assigned(local, ctx, &iter) {
532 		width = ieee80211_get_width_of_link(iter.link);
533 		max_bw = max(max_bw, width);
534 	}
535 
536 	if (!rsvd_for ||
537 	    rsvd_for->sdata == rcu_access_pointer(local->monitor_sdata))
538 		goto check_monitor;
539 
540 	/* Consider the link for which this chanctx is reserved/going to be assigned */
541 	width = ieee80211_get_width_of_link(rsvd_for);
542 	max_bw = max(max_bw, width);
543 
544 check_monitor:
545 	/* use the configured bandwidth in case of monitor interface */
546 	sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata);
547 	if (sdata &&
548 	    rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) == &ctx->conf)
549 		max_bw = max(max_bw, ctx->conf.def.width);
550 
551 	return max_bw;
552 }
553 
554 /*
555  * recalc the min required chan width of the channel context, which is
556  * the max of min required widths of all the interfaces bound to this
557  * channel context.
558  */
559 static u32
560 __ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
561 				   struct ieee80211_chanctx *ctx,
562 				   struct ieee80211_link_data *rsvd_for,
563 				   bool check_reserved)
564 {
565 	enum nl80211_chan_width max_bw;
566 	struct cfg80211_chan_def min_def;
567 
568 	lockdep_assert_wiphy(local->hw.wiphy);
569 
570 	/* don't optimize non-20MHz based and radar_enabled confs */
571 	if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 ||
572 	    ctx->conf.def.width == NL80211_CHAN_WIDTH_10 ||
573 	    ctx->conf.def.width == NL80211_CHAN_WIDTH_1 ||
574 	    ctx->conf.def.width == NL80211_CHAN_WIDTH_2 ||
575 	    ctx->conf.def.width == NL80211_CHAN_WIDTH_4 ||
576 	    ctx->conf.def.width == NL80211_CHAN_WIDTH_8 ||
577 	    ctx->conf.def.width == NL80211_CHAN_WIDTH_16 ||
578 	    ctx->conf.radar_enabled) {
579 		ctx->conf.min_def = ctx->conf.def;
580 		return 0;
581 	}
582 
583 	max_bw = ieee80211_get_chanctx_max_required_bw(local, ctx, rsvd_for,
584 						       check_reserved);
585 
586 	/* downgrade chandef up to max_bw */
587 	min_def = ctx->conf.def;
588 	while (min_def.width > max_bw)
589 		ieee80211_chandef_downgrade(&min_def, NULL);
590 
591 	if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def))
592 		return 0;
593 
594 	ctx->conf.min_def = min_def;
595 	if (!ctx->driver_present)
596 		return 0;
597 
598 	return IEEE80211_CHANCTX_CHANGE_MIN_DEF;
599 }
600 
601 static void ieee80211_chan_bw_change(struct ieee80211_local *local,
602 				     struct ieee80211_chanctx *ctx,
603 				     bool reserved, bool narrowed)
604 {
605 	struct sta_info *sta;
606 	struct ieee80211_supported_band *sband =
607 		local->hw.wiphy->bands[ctx->conf.def.chan->band];
608 
609 	rcu_read_lock();
610 	list_for_each_entry_rcu(sta, &local->sta_list,
611 				list) {
612 		struct ieee80211_sub_if_data *sdata;
613 		enum ieee80211_sta_rx_bandwidth new_sta_bw;
614 		unsigned int link_id;
615 
616 		if (!ieee80211_sdata_running(sta->sdata))
617 			continue;
618 
619 		sdata = get_bss_sdata(sta->sdata);
620 
621 		for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) {
622 			struct ieee80211_link_data *link =
623 				rcu_dereference(sdata->link[link_id]);
624 			struct ieee80211_bss_conf *link_conf;
625 			struct cfg80211_chan_def *new_chandef;
626 			struct link_sta_info *link_sta;
627 
628 			if (!link)
629 				continue;
630 
631 			link_conf = link->conf;
632 
633 			if (rcu_access_pointer(link_conf->chanctx_conf) != &ctx->conf)
634 				continue;
635 
636 			link_sta = rcu_dereference(sta->link[link_id]);
637 			if (!link_sta)
638 				continue;
639 
640 			if (reserved)
641 				new_chandef = &link->reserved.oper;
642 			else
643 				new_chandef = &link_conf->chanreq.oper;
644 
645 			new_sta_bw = _ieee80211_sta_cur_vht_bw(link_sta,
646 							       new_chandef);
647 
648 			/* nothing change */
649 			if (new_sta_bw == link_sta->pub->bandwidth)
650 				continue;
651 
652 			/* vif changed to narrow BW and narrow BW for station wasn't
653 			 * requested or vice versa */
654 			if ((new_sta_bw < link_sta->pub->bandwidth) == !narrowed)
655 				continue;
656 
657 			link_sta->pub->bandwidth = new_sta_bw;
658 			rate_control_rate_update(local, sband, link_sta,
659 						 IEEE80211_RC_BW_CHANGED);
660 		}
661 	}
662 	rcu_read_unlock();
663 }
664 
665 /*
666  * recalc the min required chan width of the channel context, which is
667  * the max of min required widths of all the interfaces bound to this
668  * channel context.
669  */
670 static void
671 _ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
672 				  struct ieee80211_chanctx *ctx,
673 				  struct ieee80211_link_data *rsvd_for,
674 				  bool check_reserved)
675 {
676 	u32 changed = __ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for,
677 							 check_reserved);
678 
679 	if (!changed)
680 		return;
681 
682 	/* check is BW narrowed */
683 	ieee80211_chan_bw_change(local, ctx, false, true);
684 
685 	drv_change_chanctx(local, ctx, changed);
686 
687 	/* check is BW wider */
688 	ieee80211_chan_bw_change(local, ctx, false, false);
689 }
690 
691 void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
692 				      struct ieee80211_chanctx *ctx)
693 {
694 	_ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false);
695 }
696 
697 static void _ieee80211_change_chanctx(struct ieee80211_local *local,
698 				      struct ieee80211_chanctx *ctx,
699 				      struct ieee80211_chanctx *old_ctx,
700 				      const struct ieee80211_chan_req *chanreq,
701 				      struct ieee80211_link_data *rsvd_for)
702 {
703 	const struct cfg80211_chan_def *chandef = &chanreq->oper;
704 	struct ieee80211_chan_req ctx_req = {
705 		.oper = ctx->conf.def,
706 		.ap = ctx->conf.ap,
707 	};
708 	u32 changed = 0;
709 
710 	/* 5/10 MHz not handled here */
711 	switch (chandef->width) {
712 	case NL80211_CHAN_WIDTH_1:
713 	case NL80211_CHAN_WIDTH_2:
714 	case NL80211_CHAN_WIDTH_4:
715 	case NL80211_CHAN_WIDTH_8:
716 	case NL80211_CHAN_WIDTH_16:
717 		/*
718 		 * mac80211 currently only supports sharing identical
719 		 * chanctx's for S1G interfaces.
720 		 */
721 		WARN_ON(!ieee80211_chanreq_identical(&ctx_req, chanreq));
722 		return;
723 	case NL80211_CHAN_WIDTH_20_NOHT:
724 	case NL80211_CHAN_WIDTH_20:
725 	case NL80211_CHAN_WIDTH_40:
726 	case NL80211_CHAN_WIDTH_80:
727 	case NL80211_CHAN_WIDTH_80P80:
728 	case NL80211_CHAN_WIDTH_160:
729 	case NL80211_CHAN_WIDTH_320:
730 		break;
731 	default:
732 		WARN_ON(1);
733 	}
734 
735 	/* Check maybe BW narrowed - we do this _before_ calling recalc_chanctx_min_def
736 	 * due to maybe not returning from it, e.g in case new context was added
737 	 * first time with all parameters up to date.
738 	 */
739 	ieee80211_chan_bw_change(local, old_ctx, false, true);
740 
741 	if (ieee80211_chanreq_identical(&ctx_req, chanreq)) {
742 		_ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for, false);
743 		return;
744 	}
745 
746 	WARN_ON(ieee80211_chanctx_refcount(local, ctx) > 1 &&
747 		!cfg80211_chandef_compatible(&ctx->conf.def, &chanreq->oper));
748 
749 	ieee80211_remove_wbrf(local, &ctx->conf.def);
750 
751 	if (!cfg80211_chandef_identical(&ctx->conf.def, &chanreq->oper)) {
752 		if (ctx->conf.def.width != chanreq->oper.width)
753 			changed |= IEEE80211_CHANCTX_CHANGE_WIDTH;
754 		if (ctx->conf.def.punctured != chanreq->oper.punctured)
755 			changed |= IEEE80211_CHANCTX_CHANGE_PUNCTURING;
756 	}
757 	if (!cfg80211_chandef_identical(&ctx->conf.ap, &chanreq->ap))
758 		changed |= IEEE80211_CHANCTX_CHANGE_AP;
759 	ctx->conf.def = *chandef;
760 	ctx->conf.ap = chanreq->ap;
761 
762 	/* check if min chanctx also changed */
763 	changed |= __ieee80211_recalc_chanctx_min_def(local, ctx, rsvd_for,
764 						      false);
765 
766 	ieee80211_add_wbrf(local, &ctx->conf.def);
767 
768 	drv_change_chanctx(local, ctx, changed);
769 
770 	/* check if BW is wider */
771 	ieee80211_chan_bw_change(local, old_ctx, false, false);
772 }
773 
774 static void ieee80211_change_chanctx(struct ieee80211_local *local,
775 				     struct ieee80211_chanctx *ctx,
776 				     struct ieee80211_chanctx *old_ctx,
777 				     const struct ieee80211_chan_req *chanreq)
778 {
779 	_ieee80211_change_chanctx(local, ctx, old_ctx, chanreq, NULL);
780 }
781 
782 /* Note: if successful, the returned chanctx will_be_used flag is set */
783 static struct ieee80211_chanctx *
784 ieee80211_find_chanctx(struct ieee80211_local *local,
785 		       const struct ieee80211_chan_req *chanreq,
786 		       enum ieee80211_chanctx_mode mode)
787 {
788 	struct ieee80211_chan_req tmp;
789 	struct ieee80211_chanctx *ctx;
790 
791 	lockdep_assert_wiphy(local->hw.wiphy);
792 
793 	if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
794 		return NULL;
795 
796 	list_for_each_entry(ctx, &local->chanctx_list, list) {
797 		const struct ieee80211_chan_req *compat;
798 
799 		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACE_NONE)
800 			continue;
801 
802 		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
803 			continue;
804 
805 		compat = ieee80211_chanctx_compatible(local, ctx, chanreq,
806 						      &tmp);
807 		if (!compat)
808 			continue;
809 
810 		compat = ieee80211_chanctx_reserved_chanreq(local, ctx,
811 							    compat, &tmp);
812 		if (!compat)
813 			continue;
814 
815 		/*
816 		 * Mark the chanctx as will be used, as the driver might change
817 		 * active links during callbacks we make into it below and/or
818 		 * later during assignment, which could (otherwise) cause the
819 		 * context to actually be removed.
820 		 */
821 		ctx->will_be_used = true;
822 
823 		ieee80211_change_chanctx(local, ctx, ctx, compat);
824 
825 		return ctx;
826 	}
827 
828 	return NULL;
829 }
830 
831 bool ieee80211_is_radar_required(struct ieee80211_local *local,
832 				 struct cfg80211_scan_request *req)
833 {
834 	struct wiphy *wiphy = local->hw.wiphy;
835 	struct ieee80211_link_data *link;
836 	struct ieee80211_channel *chan;
837 	int radio_idx;
838 
839 	lockdep_assert_wiphy(local->hw.wiphy);
840 
841 	if (!req)
842 		return false;
843 
844 	for_each_sdata_link(local, link) {
845 		if (link->radar_required) {
846 			chan = link->conf->chanreq.oper.chan;
847 			radio_idx = cfg80211_get_radio_idx_by_chan(wiphy, chan);
848 
849 			if (ieee80211_is_radio_idx_in_scan_req(wiphy, req,
850 							       radio_idx))
851 				return true;
852 		}
853 	}
854 
855 	return false;
856 }
857 
858 static bool
859 ieee80211_chanctx_radar_required(struct ieee80211_local *local,
860 				 struct ieee80211_chanctx *ctx)
861 {
862 	struct ieee80211_chanctx_user_iter iter;
863 
864 	lockdep_assert_wiphy(local->hw.wiphy);
865 
866 	for_each_chanctx_user_assigned(local, ctx, &iter) {
867 		if (iter.radar_required)
868 			return true;
869 	}
870 
871 	return false;
872 }
873 
874 static struct ieee80211_chanctx *
875 ieee80211_alloc_chanctx(struct ieee80211_local *local,
876 			const struct ieee80211_chan_req *chanreq,
877 			enum ieee80211_chanctx_mode mode,
878 			int radio_idx)
879 {
880 	struct ieee80211_chanctx *ctx;
881 
882 	lockdep_assert_wiphy(local->hw.wiphy);
883 
884 	ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL);
885 	if (!ctx)
886 		return NULL;
887 
888 	ctx->conf.def = chanreq->oper;
889 	ctx->conf.ap = chanreq->ap;
890 	ctx->conf.rx_chains_static = 1;
891 	ctx->conf.rx_chains_dynamic = 1;
892 	ctx->mode = mode;
893 	ctx->conf.radar_enabled = false;
894 	ctx->conf.radio_idx = radio_idx;
895 	ctx->radar_detected = false;
896 	__ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false);
897 
898 	return ctx;
899 }
900 
901 static int ieee80211_add_chanctx(struct ieee80211_local *local,
902 				 struct ieee80211_chanctx *ctx)
903 {
904 	u32 changed;
905 	int err;
906 
907 	lockdep_assert_wiphy(local->hw.wiphy);
908 
909 	ieee80211_add_wbrf(local, &ctx->conf.def);
910 
911 	/* turn idle off *before* setting channel -- some drivers need that */
912 	changed = ieee80211_idle_off(local);
913 	if (changed)
914 		ieee80211_hw_config(local, -1, changed);
915 
916 	err = drv_add_chanctx(local, ctx);
917 	if (err) {
918 		ieee80211_recalc_idle(local);
919 		return err;
920 	}
921 
922 	return 0;
923 }
924 
925 static struct ieee80211_chanctx *
926 ieee80211_new_chanctx(struct ieee80211_local *local,
927 		      const struct ieee80211_chan_req *chanreq,
928 		      enum ieee80211_chanctx_mode mode,
929 		      bool assign_on_failure,
930 		      int radio_idx)
931 {
932 	struct ieee80211_chanctx *ctx;
933 	int err;
934 
935 	lockdep_assert_wiphy(local->hw.wiphy);
936 
937 	ctx = ieee80211_alloc_chanctx(local, chanreq, mode, radio_idx);
938 	if (!ctx)
939 		return ERR_PTR(-ENOMEM);
940 
941 	err = ieee80211_add_chanctx(local, ctx);
942 	if (!assign_on_failure && err) {
943 		kfree(ctx);
944 		return ERR_PTR(err);
945 	}
946 	/* We ignored a driver error, see _ieee80211_set_active_links */
947 	WARN_ON_ONCE(err && !local->in_reconfig);
948 
949 	list_add_rcu(&ctx->list, &local->chanctx_list);
950 	return ctx;
951 }
952 
953 static void ieee80211_del_chanctx(struct ieee80211_local *local,
954 				  struct ieee80211_chanctx *ctx,
955 				  bool skip_idle_recalc)
956 {
957 	lockdep_assert_wiphy(local->hw.wiphy);
958 
959 	drv_remove_chanctx(local, ctx);
960 
961 	if (!skip_idle_recalc)
962 		ieee80211_recalc_idle(local);
963 
964 	ieee80211_remove_wbrf(local, &ctx->conf.def);
965 }
966 
967 static void ieee80211_free_chanctx(struct ieee80211_local *local,
968 				   struct ieee80211_chanctx *ctx,
969 				   bool skip_idle_recalc)
970 {
971 	lockdep_assert_wiphy(local->hw.wiphy);
972 
973 	WARN_ON_ONCE(ieee80211_chanctx_refcount(local, ctx) != 0);
974 
975 	list_del_rcu(&ctx->list);
976 	ieee80211_del_chanctx(local, ctx, skip_idle_recalc);
977 	kfree_rcu(ctx, rcu_head);
978 }
979 
980 void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
981 				       struct ieee80211_chanctx *ctx)
982 {
983 	struct ieee80211_chanctx_conf *conf = &ctx->conf;
984 	const struct ieee80211_chan_req *compat = NULL;
985 	struct ieee80211_chanctx_user_iter iter;
986 	struct ieee80211_chan_req tmp;
987 	struct sta_info *sta;
988 
989 	lockdep_assert_wiphy(local->hw.wiphy);
990 
991 	for_each_chanctx_user_assigned(local, ctx, &iter) {
992 		if (!compat)
993 			compat = iter.chanreq;
994 
995 		compat = ieee80211_chanreq_compatible(iter.chanreq,
996 						      compat, &tmp);
997 		if (WARN_ON_ONCE(!compat))
998 			return;
999 	}
1000 
1001 	if (WARN_ON_ONCE(!compat))
1002 		return;
1003 
1004 	/* TDLS peers can sometimes affect the chandef width */
1005 	list_for_each_entry(sta, &local->sta_list, list) {
1006 		struct ieee80211_sub_if_data *sdata = sta->sdata;
1007 		struct ieee80211_chan_req tdls_chanreq = {};
1008 		struct ieee80211_link_data *link;
1009 		int tdls_link_id;
1010 
1011 		if (!sta->uploaded ||
1012 		    !test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW) ||
1013 		    !test_sta_flag(sta, WLAN_STA_AUTHORIZED) ||
1014 		    !sta->tdls_chandef.chan)
1015 			continue;
1016 
1017 		tdls_link_id = ieee80211_tdls_sta_link_id(sta);
1018 		link = sdata_dereference(sdata->link[tdls_link_id], sdata);
1019 		if (!link)
1020 			continue;
1021 
1022 		if (rcu_access_pointer(link->conf->chanctx_conf) != conf)
1023 			continue;
1024 
1025 		tdls_chanreq.oper = sta->tdls_chandef;
1026 
1027 		/* note this always fills and returns &tmp if compat */
1028 		compat = ieee80211_chanreq_compatible(&tdls_chanreq,
1029 						      compat, &tmp);
1030 		if (WARN_ON_ONCE(!compat))
1031 			return;
1032 	}
1033 
1034 	ieee80211_change_chanctx(local, ctx, ctx, compat);
1035 }
1036 
1037 static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local,
1038 					   struct ieee80211_chanctx *chanctx)
1039 {
1040 	bool radar_enabled;
1041 
1042 	lockdep_assert_wiphy(local->hw.wiphy);
1043 
1044 	radar_enabled = ieee80211_chanctx_radar_required(local, chanctx);
1045 
1046 	if (radar_enabled == chanctx->conf.radar_enabled)
1047 		return;
1048 
1049 	chanctx->conf.radar_enabled = radar_enabled;
1050 
1051 	drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR);
1052 }
1053 
1054 static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,
1055 					 struct ieee80211_chanctx *new_ctx,
1056 					 bool assign_on_failure)
1057 {
1058 	struct ieee80211_sub_if_data *sdata = link->sdata;
1059 	struct ieee80211_local *local = sdata->local;
1060 	struct ieee80211_chanctx_conf *conf;
1061 	struct ieee80211_chanctx *curr_ctx = NULL;
1062 	bool new_idle;
1063 	int ret;
1064 
1065 	if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN))
1066 		return -EOPNOTSUPP;
1067 
1068 	conf = rcu_dereference_protected(link->conf->chanctx_conf,
1069 					 lockdep_is_held(&local->hw.wiphy->mtx));
1070 
1071 	if (conf && !local->in_reconfig) {
1072 		curr_ctx = container_of(conf, struct ieee80211_chanctx, conf);
1073 
1074 		drv_unassign_vif_chanctx(local, sdata, link->conf, curr_ctx);
1075 		conf = NULL;
1076 	}
1077 
1078 	if (new_ctx) {
1079 		/* recalc considering the link we'll use it for now */
1080 		_ieee80211_recalc_chanctx_min_def(local, new_ctx, link, false);
1081 
1082 		ret = drv_assign_vif_chanctx(local, sdata, link->conf, new_ctx);
1083 		if (assign_on_failure || !ret) {
1084 			/* Need to continue, see _ieee80211_set_active_links */
1085 			WARN_ON_ONCE(ret && !local->in_reconfig);
1086 			ret = 0;
1087 
1088 			/* succeeded, so commit it to the data structures */
1089 			conf = &new_ctx->conf;
1090 		}
1091 	} else {
1092 		ret = 0;
1093 	}
1094 
1095 	rcu_assign_pointer(link->conf->chanctx_conf, conf);
1096 
1097 	if (curr_ctx && ieee80211_chanctx_num_assigned(local, curr_ctx) > 0) {
1098 		ieee80211_recalc_chanctx_chantype(local, curr_ctx);
1099 		ieee80211_recalc_smps_chanctx(local, curr_ctx);
1100 		ieee80211_recalc_radar_chanctx(local, curr_ctx);
1101 		ieee80211_recalc_chanctx_min_def(local, curr_ctx);
1102 	}
1103 
1104 	if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) {
1105 		ieee80211_recalc_txpower(link, false);
1106 		ieee80211_recalc_chanctx_min_def(local, new_ctx);
1107 	}
1108 
1109 	if (conf) {
1110 		new_idle = false;
1111 	} else {
1112 		struct ieee80211_link_data *tmp;
1113 
1114 		new_idle = true;
1115 		for_each_sdata_link(local, tmp) {
1116 			if (rcu_access_pointer(tmp->conf->chanctx_conf)) {
1117 				new_idle = false;
1118 				break;
1119 			}
1120 		}
1121 	}
1122 
1123 	if (new_idle != sdata->vif.cfg.idle) {
1124 		sdata->vif.cfg.idle = new_idle;
1125 
1126 		if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
1127 		    sdata->vif.type != NL80211_IFTYPE_MONITOR)
1128 			ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_IDLE);
1129 	}
1130 
1131 	ieee80211_check_fast_xmit_iface(sdata);
1132 
1133 	return ret;
1134 }
1135 
1136 void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
1137 				   struct ieee80211_chanctx *chanctx)
1138 {
1139 	struct ieee80211_chanctx_user_iter iter;
1140 	struct ieee80211_sub_if_data *sdata;
1141 	u8 rx_chains_static, rx_chains_dynamic;
1142 
1143 	lockdep_assert_wiphy(local->hw.wiphy);
1144 
1145 	rx_chains_static = 1;
1146 	rx_chains_dynamic = 1;
1147 
1148 	for_each_chanctx_user_assigned(local, chanctx, &iter) {
1149 		u8 needed_static, needed_dynamic;
1150 
1151 		switch (iter.iftype) {
1152 		case NL80211_IFTYPE_STATION:
1153 			if (!iter.sdata->u.mgd.associated)
1154 				continue;
1155 			break;
1156 		case NL80211_IFTYPE_MONITOR:
1157 			if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
1158 				continue;
1159 			break;
1160 		case NL80211_IFTYPE_AP:
1161 		case NL80211_IFTYPE_ADHOC:
1162 		case NL80211_IFTYPE_MESH_POINT:
1163 		case NL80211_IFTYPE_OCB:
1164 			break;
1165 		default:
1166 			continue;
1167 		}
1168 
1169 		if (iter.iftype == NL80211_IFTYPE_MONITOR) {
1170 			rx_chains_dynamic = rx_chains_static = local->rx_chains;
1171 			break;
1172 		}
1173 
1174 		switch (iter.link->smps_mode) {
1175 		default:
1176 			WARN_ONCE(1, "Invalid SMPS mode %d\n",
1177 				  iter.link->smps_mode);
1178 			fallthrough;
1179 		case IEEE80211_SMPS_OFF:
1180 			needed_static = iter.link->needed_rx_chains;
1181 			needed_dynamic = iter.link->needed_rx_chains;
1182 			break;
1183 		case IEEE80211_SMPS_DYNAMIC:
1184 			needed_static = 1;
1185 			needed_dynamic = iter.link->needed_rx_chains;
1186 			break;
1187 		case IEEE80211_SMPS_STATIC:
1188 			needed_static = 1;
1189 			needed_dynamic = 1;
1190 			break;
1191 		}
1192 
1193 		rx_chains_static = max(rx_chains_static, needed_static);
1194 		rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic);
1195 	}
1196 
1197 	/* Disable SMPS for the monitor interface */
1198 	sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata);
1199 	if (sdata &&
1200 	    rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) == &chanctx->conf)
1201 		rx_chains_dynamic = rx_chains_static = local->rx_chains;
1202 
1203 	if (rx_chains_static == chanctx->conf.rx_chains_static &&
1204 	    rx_chains_dynamic == chanctx->conf.rx_chains_dynamic)
1205 		return;
1206 
1207 	chanctx->conf.rx_chains_static = rx_chains_static;
1208 	chanctx->conf.rx_chains_dynamic = rx_chains_dynamic;
1209 	drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS);
1210 }
1211 
1212 static void
1213 __ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link,
1214 				       bool clear)
1215 {
1216 	struct ieee80211_sub_if_data *sdata = link->sdata;
1217 	unsigned int link_id = link->link_id;
1218 	struct ieee80211_bss_conf *link_conf = link->conf;
1219 	struct ieee80211_local *local __maybe_unused = sdata->local;
1220 	struct ieee80211_sub_if_data *vlan;
1221 	struct ieee80211_chanctx_conf *conf;
1222 
1223 	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP))
1224 		return;
1225 
1226 	lockdep_assert_wiphy(local->hw.wiphy);
1227 
1228 	/* Check that conf exists, even when clearing this function
1229 	 * must be called with the AP's channel context still there
1230 	 * as it would otherwise cause VLANs to have an invalid
1231 	 * channel context pointer for a while, possibly pointing
1232 	 * to a channel context that has already been freed.
1233 	 */
1234 	conf = rcu_dereference_protected(link_conf->chanctx_conf,
1235 					 lockdep_is_held(&local->hw.wiphy->mtx));
1236 	WARN_ON(!conf);
1237 
1238 	if (clear)
1239 		conf = NULL;
1240 
1241 	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
1242 		struct ieee80211_bss_conf *vlan_conf;
1243 
1244 		vlan_conf = wiphy_dereference(local->hw.wiphy,
1245 					      vlan->vif.link_conf[link_id]);
1246 		if (WARN_ON(!vlan_conf))
1247 			continue;
1248 
1249 		rcu_assign_pointer(vlan_conf->chanctx_conf, conf);
1250 	}
1251 }
1252 
1253 void ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link,
1254 					  bool clear)
1255 {
1256 	struct ieee80211_local *local = link->sdata->local;
1257 
1258 	lockdep_assert_wiphy(local->hw.wiphy);
1259 
1260 	__ieee80211_link_copy_chanctx_to_vlans(link, clear);
1261 }
1262 
1263 void ieee80211_link_unreserve_chanctx(struct ieee80211_link_data *link)
1264 {
1265 	struct ieee80211_sub_if_data *sdata = link->sdata;
1266 	struct ieee80211_chanctx *ctx = link->reserved_chanctx;
1267 
1268 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
1269 
1270 	if (WARN_ON(!ctx))
1271 		return;
1272 
1273 	link->reserved_chanctx = NULL;
1274 
1275 	if (ieee80211_chanctx_refcount(sdata->local, ctx) == 0) {
1276 		if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
1277 			if (WARN_ON(!ctx->replace_ctx))
1278 				return;
1279 
1280 			WARN_ON(ctx->replace_ctx->replace_state !=
1281 			        IEEE80211_CHANCTX_WILL_BE_REPLACED);
1282 			WARN_ON(ctx->replace_ctx->replace_ctx != ctx);
1283 
1284 			ctx->replace_ctx->replace_ctx = NULL;
1285 			ctx->replace_ctx->replace_state =
1286 					IEEE80211_CHANCTX_REPLACE_NONE;
1287 
1288 			list_del_rcu(&ctx->list);
1289 			kfree_rcu(ctx, rcu_head);
1290 		} else {
1291 			ieee80211_free_chanctx(sdata->local, ctx, false);
1292 		}
1293 	}
1294 }
1295 
1296 static struct ieee80211_chanctx *
1297 ieee80211_replace_chanctx(struct ieee80211_local *local,
1298 			  const struct ieee80211_chan_req *chanreq,
1299 			  enum ieee80211_chanctx_mode mode,
1300 			  struct ieee80211_chanctx *curr_ctx)
1301 {
1302 	struct ieee80211_chanctx *new_ctx, *ctx;
1303 	struct wiphy *wiphy = local->hw.wiphy;
1304 	const struct wiphy_radio *radio;
1305 
1306 	if (!curr_ctx ||
1307 	    curr_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED ||
1308 	    ieee80211_chanctx_num_reserved(local, curr_ctx) != 0) {
1309 		/*
1310 		 * Another link already requested this context for a
1311 		 * reservation. Find another one hoping all links assigned
1312 		 * to it will also switch soon enough.
1313 		 *
1314 		 * TODO: This needs a little more work as some cases
1315 		 * (more than 2 chanctx capable devices) may fail which could
1316 		 * otherwise succeed provided some channel context juggling was
1317 		 * performed.
1318 		 *
1319 		 * Consider ctx1..3, link1..6, each ctx has 2 links. link1 and
1320 		 * link2 from ctx1 request new different chandefs starting 2
1321 		 * in-place reservations with ctx4 and ctx5 replacing ctx1 and
1322 		 * ctx2 respectively. Next link5 and link6 from ctx3 reserve
1323 		 * ctx4. If link3 and link4 remain on ctx2 as they are then this
1324 		 * fails unless `replace_ctx` from ctx5 is replaced with ctx3.
1325 		 */
1326 		list_for_each_entry(ctx, &local->chanctx_list, list) {
1327 			if (ctx->replace_state !=
1328 			    IEEE80211_CHANCTX_REPLACE_NONE)
1329 				continue;
1330 
1331 			if (ieee80211_chanctx_num_reserved(local, ctx) != 0)
1332 				continue;
1333 
1334 			if (ctx->conf.radio_idx >= 0) {
1335 				radio = &wiphy->radio[ctx->conf.radio_idx];
1336 				if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper))
1337 					continue;
1338 			}
1339 
1340 			curr_ctx = ctx;
1341 			break;
1342 		}
1343 	}
1344 
1345 	/*
1346 	 * If that's true then all available contexts already have reservations
1347 	 * and cannot be used.
1348 	 */
1349 	if (!curr_ctx ||
1350 	    curr_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED ||
1351 	    ieee80211_chanctx_num_reserved(local, curr_ctx) != 0)
1352 		return ERR_PTR(-EBUSY);
1353 
1354 	new_ctx = ieee80211_alloc_chanctx(local, chanreq, mode, -1);
1355 	if (!new_ctx)
1356 		return ERR_PTR(-ENOMEM);
1357 
1358 	new_ctx->replace_ctx = curr_ctx;
1359 	new_ctx->replace_state = IEEE80211_CHANCTX_REPLACES_OTHER;
1360 
1361 	curr_ctx->replace_ctx = new_ctx;
1362 	curr_ctx->replace_state = IEEE80211_CHANCTX_WILL_BE_REPLACED;
1363 
1364 	list_add_rcu(&new_ctx->list, &local->chanctx_list);
1365 
1366 	return new_ctx;
1367 }
1368 
1369 static bool
1370 ieee80211_find_available_radio(struct ieee80211_local *local,
1371 			       const struct ieee80211_chan_req *chanreq,
1372 			       u32 radio_mask, int *radio_idx)
1373 {
1374 	struct wiphy *wiphy = local->hw.wiphy;
1375 	const struct wiphy_radio *radio;
1376 	int i;
1377 
1378 	*radio_idx = -1;
1379 	if (!wiphy->n_radio)
1380 		return true;
1381 
1382 	for (i = 0; i < wiphy->n_radio; i++) {
1383 		if (!(radio_mask & BIT(i)))
1384 			continue;
1385 
1386 		radio = &wiphy->radio[i];
1387 		if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper))
1388 			continue;
1389 
1390 		if (!ieee80211_can_create_new_chanctx(local, i))
1391 			continue;
1392 
1393 		*radio_idx = i;
1394 		return true;
1395 	}
1396 
1397 	return false;
1398 }
1399 
1400 int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link,
1401 				   const struct ieee80211_chan_req *chanreq,
1402 				   enum ieee80211_chanctx_mode mode,
1403 				   bool radar_required)
1404 {
1405 	struct ieee80211_sub_if_data *sdata = link->sdata;
1406 	struct ieee80211_local *local = sdata->local;
1407 	struct ieee80211_chanctx *new_ctx, *curr_ctx;
1408 	int radio_idx;
1409 
1410 	lockdep_assert_wiphy(local->hw.wiphy);
1411 
1412 	curr_ctx = ieee80211_link_get_chanctx(link);
1413 	if (curr_ctx && !local->ops->switch_vif_chanctx)
1414 		return -EOPNOTSUPP;
1415 
1416 	new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode);
1417 	if (!new_ctx) {
1418 		if (ieee80211_can_create_new_chanctx(local, -1) &&
1419 		    ieee80211_find_available_radio(local, chanreq,
1420 						   sdata->wdev.radio_mask,
1421 						   &radio_idx))
1422 			new_ctx = ieee80211_new_chanctx(local, chanreq, mode,
1423 							false, radio_idx);
1424 		else
1425 			new_ctx = ieee80211_replace_chanctx(local, chanreq,
1426 							    mode, curr_ctx);
1427 		if (IS_ERR(new_ctx))
1428 			return PTR_ERR(new_ctx);
1429 	}
1430 
1431 	link->reserved_chanctx = new_ctx;
1432 	link->reserved = *chanreq;
1433 	link->reserved_radar_required = radar_required;
1434 	link->reserved_ready = false;
1435 
1436 	return 0;
1437 }
1438 
1439 static void
1440 ieee80211_link_chanctx_reservation_complete(struct ieee80211_link_data *link)
1441 {
1442 	struct ieee80211_sub_if_data *sdata = link->sdata;
1443 
1444 	switch (sdata->vif.type) {
1445 	case NL80211_IFTYPE_ADHOC:
1446 	case NL80211_IFTYPE_AP:
1447 	case NL80211_IFTYPE_MESH_POINT:
1448 	case NL80211_IFTYPE_OCB:
1449 		wiphy_work_queue(sdata->local->hw.wiphy,
1450 				 &link->csa.finalize_work);
1451 		break;
1452 	case NL80211_IFTYPE_STATION:
1453 		wiphy_hrtimer_work_queue(sdata->local->hw.wiphy,
1454 					 &link->u.mgd.csa.switch_work, 0);
1455 		break;
1456 	case NL80211_IFTYPE_UNSPECIFIED:
1457 	case NL80211_IFTYPE_AP_VLAN:
1458 	case NL80211_IFTYPE_WDS:
1459 	case NL80211_IFTYPE_MONITOR:
1460 	case NL80211_IFTYPE_P2P_CLIENT:
1461 	case NL80211_IFTYPE_P2P_GO:
1462 	case NL80211_IFTYPE_P2P_DEVICE:
1463 	case NL80211_IFTYPE_NAN:
1464 	case NL80211_IFTYPE_NAN_DATA:
1465 	case NUM_NL80211_IFTYPES:
1466 		WARN_ON(1);
1467 		break;
1468 	}
1469 }
1470 
1471 static void
1472 ieee80211_link_update_chanreq(struct ieee80211_link_data *link,
1473 			      const struct ieee80211_chan_req *chanreq)
1474 {
1475 	struct ieee80211_sub_if_data *sdata = link->sdata;
1476 	unsigned int link_id = link->link_id;
1477 	struct ieee80211_sub_if_data *vlan;
1478 
1479 	link->conf->chanreq = *chanreq;
1480 
1481 	if (sdata->vif.type != NL80211_IFTYPE_AP)
1482 		return;
1483 
1484 	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
1485 		struct ieee80211_bss_conf *vlan_conf;
1486 
1487 		vlan_conf = wiphy_dereference(sdata->local->hw.wiphy,
1488 					      vlan->vif.link_conf[link_id]);
1489 		if (WARN_ON(!vlan_conf))
1490 			continue;
1491 
1492 		vlan_conf->chanreq = *chanreq;
1493 	}
1494 }
1495 
1496 static int
1497 ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link)
1498 {
1499 	struct ieee80211_sub_if_data *sdata = link->sdata;
1500 	struct ieee80211_bss_conf *link_conf = link->conf;
1501 	struct ieee80211_local *local = sdata->local;
1502 	struct ieee80211_vif_chanctx_switch vif_chsw[1] = {};
1503 	struct ieee80211_chanctx *old_ctx, *new_ctx;
1504 	const struct ieee80211_chan_req *chanreq;
1505 	struct ieee80211_chan_req tmp;
1506 	u64 changed = 0;
1507 	int err;
1508 
1509 	lockdep_assert_wiphy(local->hw.wiphy);
1510 
1511 	new_ctx = link->reserved_chanctx;
1512 	old_ctx = ieee80211_link_get_chanctx(link);
1513 
1514 	if (WARN_ON(!link->reserved_ready))
1515 		return -EBUSY;
1516 
1517 	if (WARN_ON(!new_ctx))
1518 		return -EINVAL;
1519 
1520 	if (WARN_ON(!old_ctx))
1521 		return -EINVAL;
1522 
1523 	if (WARN_ON(new_ctx->replace_state ==
1524 		    IEEE80211_CHANCTX_REPLACES_OTHER))
1525 		return -EINVAL;
1526 
1527 	chanreq = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
1528 							 &link->reserved,
1529 							 &tmp);
1530 	if (WARN_ON(!chanreq))
1531 		return -EINVAL;
1532 
1533 	if (link_conf->chanreq.oper.width != link->reserved.oper.width)
1534 		changed = BSS_CHANGED_BANDWIDTH;
1535 
1536 	ieee80211_link_update_chanreq(link, &link->reserved);
1537 
1538 	_ieee80211_change_chanctx(local, new_ctx, old_ctx, chanreq, link);
1539 
1540 	vif_chsw[0].vif = &sdata->vif;
1541 	vif_chsw[0].old_ctx = &old_ctx->conf;
1542 	vif_chsw[0].new_ctx = &new_ctx->conf;
1543 	vif_chsw[0].link_conf = link->conf;
1544 
1545 	link->reserved_chanctx = NULL;
1546 
1547 	err = drv_switch_vif_chanctx(local, vif_chsw, 1,
1548 				     CHANCTX_SWMODE_REASSIGN_VIF);
1549 	if (err) {
1550 		if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
1551 			ieee80211_free_chanctx(local, new_ctx, false);
1552 
1553 		goto out;
1554 	}
1555 
1556 	link->radar_required = link->reserved_radar_required;
1557 	rcu_assign_pointer(link_conf->chanctx_conf, &new_ctx->conf);
1558 
1559 	if (sdata->vif.type == NL80211_IFTYPE_AP)
1560 		__ieee80211_link_copy_chanctx_to_vlans(link, false);
1561 
1562 	ieee80211_check_fast_xmit_iface(sdata);
1563 
1564 	if (ieee80211_chanctx_refcount(local, old_ctx) == 0)
1565 		ieee80211_free_chanctx(local, old_ctx, false);
1566 
1567 	ieee80211_recalc_chanctx_min_def(local, new_ctx);
1568 	ieee80211_recalc_smps_chanctx(local, new_ctx);
1569 	ieee80211_recalc_radar_chanctx(local, new_ctx);
1570 
1571 	if (changed)
1572 		ieee80211_link_info_change_notify(sdata, link, changed);
1573 
1574 out:
1575 	ieee80211_link_chanctx_reservation_complete(link);
1576 	return err;
1577 }
1578 
1579 static int
1580 ieee80211_link_use_reserved_assign(struct ieee80211_link_data *link)
1581 {
1582 	struct ieee80211_sub_if_data *sdata = link->sdata;
1583 	struct ieee80211_local *local = sdata->local;
1584 	struct ieee80211_chanctx *old_ctx, *new_ctx;
1585 	const struct ieee80211_chan_req *chanreq;
1586 	struct ieee80211_chan_req tmp;
1587 	int err;
1588 
1589 	old_ctx = ieee80211_link_get_chanctx(link);
1590 	new_ctx = link->reserved_chanctx;
1591 
1592 	if (WARN_ON(!link->reserved_ready))
1593 		return -EINVAL;
1594 
1595 	if (WARN_ON(old_ctx))
1596 		return -EINVAL;
1597 
1598 	if (WARN_ON(!new_ctx))
1599 		return -EINVAL;
1600 
1601 	if (WARN_ON(new_ctx->replace_state ==
1602 		    IEEE80211_CHANCTX_REPLACES_OTHER))
1603 		return -EINVAL;
1604 
1605 	chanreq = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
1606 							 &link->reserved,
1607 							 &tmp);
1608 	if (WARN_ON(!chanreq))
1609 		return -EINVAL;
1610 
1611 	ieee80211_change_chanctx(local, new_ctx, new_ctx, chanreq);
1612 
1613 	link->reserved_chanctx = NULL;
1614 
1615 	err = ieee80211_assign_link_chanctx(link, new_ctx, false);
1616 	if (err) {
1617 		if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
1618 			ieee80211_free_chanctx(local, new_ctx, false);
1619 
1620 		goto out;
1621 	}
1622 
1623 out:
1624 	ieee80211_link_chanctx_reservation_complete(link);
1625 	return err;
1626 }
1627 
1628 static bool
1629 ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link)
1630 {
1631 	struct ieee80211_sub_if_data *sdata = link->sdata;
1632 	struct ieee80211_chanctx *old_ctx, *new_ctx;
1633 
1634 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
1635 
1636 	new_ctx = link->reserved_chanctx;
1637 	old_ctx = ieee80211_link_get_chanctx(link);
1638 
1639 	if (!old_ctx)
1640 		return false;
1641 
1642 	if (WARN_ON(!new_ctx))
1643 		return false;
1644 
1645 	if (old_ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
1646 		return false;
1647 
1648 	if (new_ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1649 		return false;
1650 
1651 	return true;
1652 }
1653 
1654 static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local,
1655 				      int n_vifs)
1656 {
1657 	struct ieee80211_vif_chanctx_switch *vif_chsw;
1658 	struct ieee80211_chanctx *ctx, *old_ctx;
1659 	int i, err;
1660 
1661 	lockdep_assert_wiphy(local->hw.wiphy);
1662 
1663 	vif_chsw = kzalloc_objs(vif_chsw[0], n_vifs);
1664 	if (!vif_chsw)
1665 		return -ENOMEM;
1666 
1667 	i = 0;
1668 	list_for_each_entry(ctx, &local->chanctx_list, list) {
1669 		struct ieee80211_chanctx_user_iter iter;
1670 
1671 		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1672 			continue;
1673 
1674 		if (WARN_ON(!ctx->replace_ctx)) {
1675 			err = -EINVAL;
1676 			goto out;
1677 		}
1678 
1679 		for_each_chanctx_user_reserved(local, ctx, &iter) {
1680 			if (!ieee80211_link_has_in_place_reservation(iter.link))
1681 				continue;
1682 
1683 			old_ctx = ieee80211_link_get_chanctx(iter.link);
1684 			vif_chsw[i].vif = &iter.sdata->vif;
1685 			vif_chsw[i].old_ctx = &old_ctx->conf;
1686 			vif_chsw[i].new_ctx = &ctx->conf;
1687 			vif_chsw[i].link_conf = iter.link->conf;
1688 
1689 			i++;
1690 		}
1691 	}
1692 
1693 	err = drv_switch_vif_chanctx(local, vif_chsw, n_vifs,
1694 				     CHANCTX_SWMODE_SWAP_CONTEXTS);
1695 
1696 out:
1697 	kfree(vif_chsw);
1698 	return err;
1699 }
1700 
1701 static int ieee80211_chsw_switch_ctxs(struct ieee80211_local *local)
1702 {
1703 	struct ieee80211_chanctx *ctx;
1704 	int err;
1705 
1706 	lockdep_assert_wiphy(local->hw.wiphy);
1707 
1708 	list_for_each_entry(ctx, &local->chanctx_list, list) {
1709 		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1710 			continue;
1711 
1712 		if (ieee80211_chanctx_num_assigned(local, ctx) != 0)
1713 			continue;
1714 
1715 		ieee80211_del_chanctx(local, ctx->replace_ctx, false);
1716 		err = ieee80211_add_chanctx(local, ctx);
1717 		if (err)
1718 			goto err;
1719 	}
1720 
1721 	return 0;
1722 
1723 err:
1724 	WARN_ON(ieee80211_add_chanctx(local, ctx));
1725 	list_for_each_entry_continue_reverse(ctx, &local->chanctx_list, list) {
1726 		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1727 			continue;
1728 
1729 		if (ieee80211_chanctx_num_assigned(local, ctx) != 0)
1730 			continue;
1731 
1732 		ieee80211_del_chanctx(local, ctx, false);
1733 		WARN_ON(ieee80211_add_chanctx(local, ctx->replace_ctx));
1734 	}
1735 
1736 	return err;
1737 }
1738 
1739 static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
1740 {
1741 	struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx;
1742 	int err, n_assigned, n_reserved, n_ready;
1743 	int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0;
1744 
1745 	lockdep_assert_wiphy(local->hw.wiphy);
1746 
1747 	/*
1748 	 * If there are 2 independent pairs of channel contexts performing
1749 	 * cross-switch of their vifs this code will still wait until both are
1750 	 * ready even though it could be possible to switch one before the
1751 	 * other is ready.
1752 	 *
1753 	 * For practical reasons and code simplicity just do a single huge
1754 	 * switch.
1755 	 */
1756 
1757 	/*
1758 	 * Verify if the reservation is still feasible.
1759 	 *  - if it's not then disconnect
1760 	 *  - if it is but not all vifs necessary are ready then defer
1761 	 */
1762 
1763 	list_for_each_entry(ctx, &local->chanctx_list, list) {
1764 		struct ieee80211_chanctx_user_iter iter;
1765 
1766 		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1767 			continue;
1768 
1769 		if (WARN_ON(!ctx->replace_ctx)) {
1770 			err = -EINVAL;
1771 			goto err;
1772 		}
1773 
1774 		n_ctx++;
1775 
1776 		n_assigned = 0;
1777 		n_reserved = 0;
1778 		n_ready = 0;
1779 
1780 		for_each_chanctx_user_assigned(local, ctx->replace_ctx, &iter) {
1781 			n_assigned++;
1782 			if (iter.link->reserved_chanctx) {
1783 				n_reserved++;
1784 				if (iter.link->reserved_ready)
1785 					n_ready++;
1786 			}
1787 		}
1788 
1789 		if (n_assigned != n_reserved) {
1790 			if (n_ready == n_reserved) {
1791 				wiphy_info(local->hw.wiphy,
1792 					   "channel context reservation cannot be finalized because some interfaces aren't switching\n");
1793 				err = -EBUSY;
1794 				goto err;
1795 			}
1796 
1797 			return -EAGAIN;
1798 		}
1799 
1800 		ctx->conf.radar_enabled = false;
1801 		for_each_chanctx_user_reserved(local, ctx, &iter) {
1802 			if (ieee80211_link_has_in_place_reservation(iter.link) &&
1803 			    !iter.link->reserved_ready)
1804 				return -EAGAIN;
1805 
1806 			old_ctx = ieee80211_link_get_chanctx(iter.link);
1807 			if (old_ctx) {
1808 				if (old_ctx->replace_state ==
1809 				    IEEE80211_CHANCTX_WILL_BE_REPLACED)
1810 					n_vifs_switch++;
1811 				else
1812 					n_vifs_assign++;
1813 			} else {
1814 				n_vifs_ctxless++;
1815 			}
1816 
1817 			if (iter.radar_required)
1818 				ctx->conf.radar_enabled = true;
1819 		}
1820 	}
1821 
1822 	if (WARN_ON(n_ctx == 0) ||
1823 	    WARN_ON(n_vifs_switch == 0 &&
1824 		    n_vifs_assign == 0 &&
1825 		    n_vifs_ctxless == 0)) {
1826 		err = -EINVAL;
1827 		goto err;
1828 	}
1829 
1830 	/* update station rate control and min width before switch */
1831 	list_for_each_entry(ctx, &local->chanctx_list, list) {
1832 		struct ieee80211_chanctx_user_iter iter;
1833 
1834 		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1835 			continue;
1836 
1837 		if (WARN_ON(!ctx->replace_ctx)) {
1838 			err = -EINVAL;
1839 			goto err;
1840 		}
1841 
1842 		for_each_chanctx_user_reserved(local, ctx, &iter) {
1843 			if (!ieee80211_link_has_in_place_reservation(iter.link))
1844 				continue;
1845 
1846 			ieee80211_chan_bw_change(local,
1847 						 ieee80211_link_get_chanctx(iter.link),
1848 						 true, true);
1849 		}
1850 
1851 		_ieee80211_recalc_chanctx_min_def(local, ctx, NULL, true);
1852 	}
1853 
1854 	/*
1855 	 * All necessary vifs are ready. Perform the switch now depending on
1856 	 * reservations and driver capabilities.
1857 	 */
1858 
1859 	if (n_vifs_switch > 0) {
1860 		err = ieee80211_chsw_switch_vifs(local, n_vifs_switch);
1861 		if (err)
1862 			goto err;
1863 	}
1864 
1865 	if (n_vifs_assign > 0 || n_vifs_ctxless > 0) {
1866 		err = ieee80211_chsw_switch_ctxs(local);
1867 		if (err)
1868 			goto err;
1869 	}
1870 
1871 	/*
1872 	 * Update all structures, values and pointers to point to new channel
1873 	 * context(s).
1874 	 */
1875 	list_for_each_entry(ctx, &local->chanctx_list, list) {
1876 		struct ieee80211_chanctx_user_iter iter;
1877 
1878 		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1879 			continue;
1880 
1881 		if (WARN_ON(!ctx->replace_ctx)) {
1882 			err = -EINVAL;
1883 			goto err;
1884 		}
1885 
1886 		for_each_chanctx_user_reserved(local, ctx, &iter) {
1887 			struct ieee80211_link_data *link = iter.link;
1888 			struct ieee80211_sub_if_data *sdata = iter.sdata;
1889 			struct ieee80211_bss_conf *link_conf = link->conf;
1890 			u64 changed = 0;
1891 
1892 			if (!ieee80211_link_has_in_place_reservation(link))
1893 				continue;
1894 
1895 			rcu_assign_pointer(link_conf->chanctx_conf,
1896 					   &ctx->conf);
1897 
1898 			if (sdata->vif.type == NL80211_IFTYPE_AP)
1899 				__ieee80211_link_copy_chanctx_to_vlans(link,
1900 								       false);
1901 
1902 			ieee80211_check_fast_xmit_iface(sdata);
1903 
1904 			link->radar_required = iter.radar_required;
1905 
1906 			if (link_conf->chanreq.oper.width != iter.chanreq->oper.width)
1907 				changed = BSS_CHANGED_BANDWIDTH;
1908 
1909 			ieee80211_link_update_chanreq(link, &link->reserved);
1910 			if (changed)
1911 				ieee80211_link_info_change_notify(sdata,
1912 								  link,
1913 								  changed);
1914 
1915 			ieee80211_recalc_txpower(link, false);
1916 		}
1917 
1918 		ieee80211_recalc_chanctx_chantype(local, ctx);
1919 		ieee80211_recalc_smps_chanctx(local, ctx);
1920 		ieee80211_recalc_radar_chanctx(local, ctx);
1921 		ieee80211_recalc_chanctx_min_def(local, ctx);
1922 
1923 		for_each_chanctx_user_reserved(local, ctx, &iter) {
1924 			if (ieee80211_link_get_chanctx(iter.link) != ctx)
1925 				continue;
1926 
1927 			iter.link->reserved_chanctx = NULL;
1928 
1929 			ieee80211_link_chanctx_reservation_complete(iter.link);
1930 			ieee80211_chan_bw_change(local, ctx, false, false);
1931 		}
1932 
1933 		/*
1934 		 * This context might have been a dependency for an already
1935 		 * ready re-assign reservation interface that was deferred. Do
1936 		 * not propagate error to the caller though. The in-place
1937 		 * reservation for originally requested interface has already
1938 		 * succeeded at this point.
1939 		 */
1940 		for_each_chanctx_user_reserved(local, ctx, &iter) {
1941 			struct ieee80211_link_data *link = iter.link;
1942 
1943 			if (WARN_ON(ieee80211_link_has_in_place_reservation(link)))
1944 				continue;
1945 
1946 			if (!link->reserved_ready)
1947 				continue;
1948 
1949 			if (ieee80211_link_get_chanctx(link))
1950 				err = ieee80211_link_use_reserved_reassign(link);
1951 			else
1952 				err = ieee80211_link_use_reserved_assign(link);
1953 
1954 			if (err) {
1955 				link_info(link,
1956 					  "failed to finalize (re-)assign reservation (err=%d)\n",
1957 					  err);
1958 				ieee80211_link_unreserve_chanctx(link);
1959 				cfg80211_stop_iface(local->hw.wiphy,
1960 						    &link->sdata->wdev,
1961 						    GFP_KERNEL);
1962 			}
1963 		}
1964 	}
1965 
1966 	/*
1967 	 * Finally free old contexts
1968 	 */
1969 
1970 	list_for_each_entry_safe(ctx, ctx_tmp, &local->chanctx_list, list) {
1971 		if (ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
1972 			continue;
1973 
1974 		ctx->replace_ctx->replace_ctx = NULL;
1975 		ctx->replace_ctx->replace_state =
1976 				IEEE80211_CHANCTX_REPLACE_NONE;
1977 
1978 		list_del_rcu(&ctx->list);
1979 		kfree_rcu(ctx, rcu_head);
1980 	}
1981 
1982 	return 0;
1983 
1984 err:
1985 	list_for_each_entry(ctx, &local->chanctx_list, list) {
1986 		struct ieee80211_chanctx_user_iter iter;
1987 
1988 		if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1989 			continue;
1990 
1991 		for_each_chanctx_user_reserved(local, ctx, &iter) {
1992 			ieee80211_link_unreserve_chanctx(iter.link);
1993 			ieee80211_link_chanctx_reservation_complete(iter.link);
1994 		}
1995 	}
1996 
1997 	return err;
1998 }
1999 
2000 void __ieee80211_link_release_channel(struct ieee80211_link_data *link,
2001 				      bool skip_idle_recalc)
2002 {
2003 	struct ieee80211_sub_if_data *sdata = link->sdata;
2004 	struct ieee80211_bss_conf *link_conf = link->conf;
2005 	struct ieee80211_local *local = sdata->local;
2006 	struct ieee80211_chanctx_conf *conf;
2007 	struct ieee80211_chanctx *ctx;
2008 	bool use_reserved_switch = false;
2009 
2010 	lockdep_assert_wiphy(local->hw.wiphy);
2011 
2012 	conf = rcu_dereference_protected(link_conf->chanctx_conf,
2013 					 lockdep_is_held(&local->hw.wiphy->mtx));
2014 	if (!conf)
2015 		return;
2016 
2017 	ctx = container_of(conf, struct ieee80211_chanctx, conf);
2018 
2019 	if (link->reserved_chanctx) {
2020 		if (link->reserved_chanctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER &&
2021 		    ieee80211_chanctx_num_reserved(local, link->reserved_chanctx) > 1)
2022 			use_reserved_switch = true;
2023 
2024 		ieee80211_link_unreserve_chanctx(link);
2025 	}
2026 
2027 	ieee80211_assign_link_chanctx(link, NULL, false);
2028 	if (ieee80211_chanctx_refcount(local, ctx) == 0)
2029 		ieee80211_free_chanctx(local, ctx, skip_idle_recalc);
2030 
2031 	link->radar_required = false;
2032 
2033 	/* Unreserving may ready an in-place reservation. */
2034 	if (use_reserved_switch)
2035 		ieee80211_vif_use_reserved_switch(local);
2036 }
2037 
2038 static struct ieee80211_chanctx *
2039 ieee80211_find_or_create_chanctx(struct ieee80211_sub_if_data *sdata,
2040 				 const struct ieee80211_chan_req *chanreq,
2041 				 enum ieee80211_chanctx_mode mode,
2042 				 bool assign_on_failure,
2043 				 bool *reused_ctx)
2044 {
2045 	struct ieee80211_local *local = sdata->local;
2046 	struct ieee80211_chanctx *ctx;
2047 	int radio_idx;
2048 
2049 	lockdep_assert_wiphy(local->hw.wiphy);
2050 
2051 	ctx = ieee80211_find_chanctx(local, chanreq, mode);
2052 	if (ctx) {
2053 		*reused_ctx = true;
2054 		return ctx;
2055 	}
2056 
2057 	*reused_ctx = false;
2058 
2059 	if (!ieee80211_find_available_radio(local, chanreq,
2060 					    sdata->wdev.radio_mask,
2061 					    &radio_idx))
2062 		return ERR_PTR(-EBUSY);
2063 
2064 	return ieee80211_new_chanctx(local, chanreq, mode,
2065 				     assign_on_failure, radio_idx);
2066 }
2067 
2068 int _ieee80211_link_use_channel(struct ieee80211_link_data *link,
2069 				const struct ieee80211_chan_req *chanreq,
2070 				enum ieee80211_chanctx_mode mode,
2071 				bool assign_on_failure)
2072 {
2073 	struct ieee80211_sub_if_data *sdata = link->sdata;
2074 	struct ieee80211_local *local = sdata->local;
2075 	struct ieee80211_chanctx *ctx;
2076 	u8 radar_detect_width = 0;
2077 	bool reused_ctx = false;
2078 	int ret;
2079 
2080 	lockdep_assert_wiphy(local->hw.wiphy);
2081 
2082 	if (!ieee80211_vif_link_active(&sdata->vif, link->link_id)) {
2083 		ieee80211_link_update_chanreq(link, chanreq);
2084 		return 0;
2085 	}
2086 
2087 	ret = cfg80211_chandef_dfs_required(local->hw.wiphy,
2088 					    &chanreq->oper,
2089 					    sdata->wdev.iftype);
2090 	if (ret < 0)
2091 		goto out;
2092 	if (ret > 0)
2093 		radar_detect_width = BIT(chanreq->oper.width);
2094 
2095 	link->radar_required = ret;
2096 
2097 	ret = ieee80211_check_combinations(sdata, &chanreq->oper, mode,
2098 					   radar_detect_width, -1);
2099 	if (ret < 0)
2100 		goto out;
2101 
2102 	if (!local->in_reconfig)
2103 		__ieee80211_link_release_channel(link, false);
2104 
2105 	ctx = ieee80211_find_or_create_chanctx(sdata, chanreq, mode,
2106 					       assign_on_failure, &reused_ctx);
2107 	if (IS_ERR(ctx)) {
2108 		ret = PTR_ERR(ctx);
2109 		goto out;
2110 	}
2111 
2112 	ieee80211_link_update_chanreq(link, chanreq);
2113 
2114 	ret = ieee80211_assign_link_chanctx(link, ctx, assign_on_failure);
2115 
2116 	/*
2117 	 * In case an existing channel context is being used, we marked it as
2118 	 * will_be_used, now that it is assigned - clear this indication
2119 	 */
2120 	if (reused_ctx) {
2121 		WARN_ON(!ctx->will_be_used);
2122 		ctx->will_be_used = false;
2123 	}
2124 
2125 	if (ret) {
2126 		/* if assign fails refcount stays the same */
2127 		if (ieee80211_chanctx_refcount(local, ctx) == 0)
2128 			ieee80211_free_chanctx(local, ctx, false);
2129 		goto out;
2130 	}
2131 
2132 	ieee80211_recalc_smps_chanctx(local, ctx);
2133 	ieee80211_recalc_radar_chanctx(local, ctx);
2134  out:
2135 	if (ret)
2136 		link->radar_required = false;
2137 
2138 	return ret;
2139 }
2140 
2141 int ieee80211_link_use_reserved_context(struct ieee80211_link_data *link)
2142 {
2143 	struct ieee80211_sub_if_data *sdata = link->sdata;
2144 	struct ieee80211_local *local = sdata->local;
2145 	struct ieee80211_chanctx *new_ctx;
2146 	struct ieee80211_chanctx *old_ctx;
2147 	int err;
2148 
2149 	lockdep_assert_wiphy(local->hw.wiphy);
2150 
2151 	new_ctx = link->reserved_chanctx;
2152 	old_ctx = ieee80211_link_get_chanctx(link);
2153 
2154 	if (WARN_ON(!new_ctx))
2155 		return -EINVAL;
2156 
2157 	if (WARN_ON(new_ctx->replace_state ==
2158 		    IEEE80211_CHANCTX_WILL_BE_REPLACED))
2159 		return -EINVAL;
2160 
2161 	if (WARN_ON(link->reserved_ready))
2162 		return -EINVAL;
2163 
2164 	link->reserved_ready = true;
2165 
2166 	if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) {
2167 		if (old_ctx)
2168 			return ieee80211_link_use_reserved_reassign(link);
2169 
2170 		return ieee80211_link_use_reserved_assign(link);
2171 	}
2172 
2173 	/*
2174 	 * In-place reservation may need to be finalized now either if:
2175 	 *  a) sdata is taking part in the swapping itself and is the last one
2176 	 *  b) sdata has switched with a re-assign reservation to an existing
2177 	 *     context readying in-place switching of old_ctx
2178 	 *
2179 	 * In case of (b) do not propagate the error up because the requested
2180 	 * sdata already switched successfully. Just spill an extra warning.
2181 	 * The ieee80211_vif_use_reserved_switch() already stops all necessary
2182 	 * interfaces upon failure.
2183 	 */
2184 	if ((old_ctx &&
2185 	     old_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
2186 	    new_ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
2187 		err = ieee80211_vif_use_reserved_switch(local);
2188 		if (err && err != -EAGAIN) {
2189 			if (new_ctx->replace_state ==
2190 			    IEEE80211_CHANCTX_REPLACES_OTHER)
2191 				return err;
2192 
2193 			wiphy_info(local->hw.wiphy,
2194 				   "depending in-place reservation failed (err=%d)\n",
2195 				   err);
2196 		}
2197 	}
2198 
2199 	return 0;
2200 }
2201 
2202 int ieee80211_link_change_chanreq(struct ieee80211_link_data *link,
2203 				  const struct ieee80211_chan_req *chanreq,
2204 				  u64 *changed)
2205 {
2206 	struct ieee80211_sub_if_data *sdata = link->sdata;
2207 	struct ieee80211_bss_conf *link_conf = link->conf;
2208 	struct ieee80211_local *local = sdata->local;
2209 	struct ieee80211_chanctx_conf *conf;
2210 	struct ieee80211_chanctx *ctx;
2211 	const struct ieee80211_chan_req *compat;
2212 	struct ieee80211_chan_req tmp;
2213 
2214 	lockdep_assert_wiphy(local->hw.wiphy);
2215 
2216 	if (!cfg80211_chandef_usable(sdata->local->hw.wiphy,
2217 				     &chanreq->oper,
2218 				     IEEE80211_CHAN_DISABLED))
2219 		return -EINVAL;
2220 
2221 	/* for non-HT 20 MHz the rest doesn't matter */
2222 	if (chanreq->oper.width == NL80211_CHAN_WIDTH_20_NOHT &&
2223 	    cfg80211_chandef_identical(&chanreq->oper, &link_conf->chanreq.oper))
2224 		return 0;
2225 
2226 	/* but you cannot switch to/from it */
2227 	if (chanreq->oper.width == NL80211_CHAN_WIDTH_20_NOHT ||
2228 	    link_conf->chanreq.oper.width == NL80211_CHAN_WIDTH_20_NOHT)
2229 		return -EINVAL;
2230 
2231 	conf = rcu_dereference_protected(link_conf->chanctx_conf,
2232 					 lockdep_is_held(&local->hw.wiphy->mtx));
2233 	if (!conf)
2234 		return -EINVAL;
2235 
2236 	ctx = container_of(conf, struct ieee80211_chanctx, conf);
2237 
2238 	compat = _ieee80211_chanctx_compatible(local, link, ctx, chanreq, &tmp);
2239 	if (!compat)
2240 		return -EINVAL;
2241 
2242 	switch (ctx->replace_state) {
2243 	case IEEE80211_CHANCTX_REPLACE_NONE:
2244 		if (!ieee80211_chanctx_reserved_chanreq(local, ctx, compat,
2245 							&tmp))
2246 			return -EBUSY;
2247 		break;
2248 	case IEEE80211_CHANCTX_WILL_BE_REPLACED:
2249 		/* TODO: Perhaps the bandwidth change could be treated as a
2250 		 * reservation itself? */
2251 		return -EBUSY;
2252 	case IEEE80211_CHANCTX_REPLACES_OTHER:
2253 		/* channel context that is going to replace another channel
2254 		 * context doesn't really exist and shouldn't be assigned
2255 		 * anywhere yet */
2256 		WARN_ON(1);
2257 		break;
2258 	}
2259 
2260 	ieee80211_link_update_chanreq(link, chanreq);
2261 
2262 	ieee80211_recalc_chanctx_chantype(local, ctx);
2263 
2264 	*changed |= BSS_CHANGED_BANDWIDTH;
2265 	return 0;
2266 }
2267 
2268 void ieee80211_link_release_channel(struct ieee80211_link_data *link)
2269 {
2270 	struct ieee80211_sub_if_data *sdata = link->sdata;
2271 
2272 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
2273 		return;
2274 
2275 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
2276 
2277 	if (rcu_access_pointer(link->conf->chanctx_conf))
2278 		__ieee80211_link_release_channel(link, false);
2279 }
2280 
2281 void ieee80211_link_vlan_copy_chanctx(struct ieee80211_link_data *link)
2282 {
2283 	struct ieee80211_sub_if_data *sdata = link->sdata;
2284 	unsigned int link_id = link->link_id;
2285 	struct ieee80211_bss_conf *link_conf = link->conf;
2286 	struct ieee80211_bss_conf *ap_conf;
2287 	struct ieee80211_local *local = sdata->local;
2288 	struct ieee80211_sub_if_data *ap;
2289 	struct ieee80211_chanctx_conf *conf;
2290 
2291 	lockdep_assert_wiphy(local->hw.wiphy);
2292 
2293 	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss))
2294 		return;
2295 
2296 	ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
2297 
2298 	ap_conf = wiphy_dereference(local->hw.wiphy,
2299 				    ap->vif.link_conf[link_id]);
2300 	conf = wiphy_dereference(local->hw.wiphy,
2301 				 ap_conf->chanctx_conf);
2302 	rcu_assign_pointer(link_conf->chanctx_conf, conf);
2303 }
2304 
2305 void ieee80211_iter_chan_contexts_atomic(
2306 	struct ieee80211_hw *hw,
2307 	void (*iter)(struct ieee80211_hw *hw,
2308 		     struct ieee80211_chanctx_conf *chanctx_conf,
2309 		     void *data),
2310 	void *iter_data)
2311 {
2312 	struct ieee80211_local *local = hw_to_local(hw);
2313 	struct ieee80211_chanctx *ctx;
2314 
2315 	rcu_read_lock();
2316 	list_for_each_entry_rcu(ctx, &local->chanctx_list, list)
2317 		if (ctx->driver_present)
2318 			iter(hw, &ctx->conf, iter_data);
2319 	rcu_read_unlock();
2320 }
2321 EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic);
2322 
2323 void ieee80211_iter_chan_contexts_mtx(
2324 	struct ieee80211_hw *hw,
2325 	void (*iter)(struct ieee80211_hw *hw,
2326 		     struct ieee80211_chanctx_conf *chanctx_conf,
2327 		     void *data),
2328 	void *iter_data)
2329 {
2330 	struct ieee80211_local *local = hw_to_local(hw);
2331 	struct ieee80211_chanctx *ctx;
2332 
2333 	lockdep_assert_wiphy(hw->wiphy);
2334 
2335 	list_for_each_entry(ctx, &local->chanctx_list, list)
2336 		if (ctx->driver_present)
2337 			iter(hw, &ctx->conf, iter_data);
2338 }
2339 EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_mtx);
2340