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