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