2 * mac80211 - channel management
5 #include <linux/nl80211.h>
6 #include <linux/export.h>
7 #include <linux/rtnetlink.h>
8 #include <net/cfg80211.h>
9 #include "ieee80211_i.h"
10 #include "driver-ops.h"
12 static int ieee80211_chanctx_num_assigned(struct ieee80211_local
*local
,
13 struct ieee80211_chanctx
*ctx
)
15 struct ieee80211_sub_if_data
*sdata
;
18 lockdep_assert_held(&local
->chanctx_mtx
);
20 list_for_each_entry(sdata
, &ctx
->assigned_vifs
, assigned_chanctx_list
)
26 static int ieee80211_chanctx_num_reserved(struct ieee80211_local
*local
,
27 struct ieee80211_chanctx
*ctx
)
29 struct ieee80211_sub_if_data
*sdata
;
32 lockdep_assert_held(&local
->chanctx_mtx
);
34 list_for_each_entry(sdata
, &ctx
->reserved_vifs
, reserved_chanctx_list
)
40 int ieee80211_chanctx_refcount(struct ieee80211_local
*local
,
41 struct ieee80211_chanctx
*ctx
)
43 return ieee80211_chanctx_num_assigned(local
, ctx
) +
44 ieee80211_chanctx_num_reserved(local
, ctx
);
47 static int ieee80211_num_chanctx(struct ieee80211_local
*local
)
49 struct ieee80211_chanctx
*ctx
;
52 lockdep_assert_held(&local
->chanctx_mtx
);
54 list_for_each_entry(ctx
, &local
->chanctx_list
, list
)
60 static bool ieee80211_can_create_new_chanctx(struct ieee80211_local
*local
)
62 lockdep_assert_held(&local
->chanctx_mtx
);
63 return ieee80211_num_chanctx(local
) < ieee80211_max_num_channels(local
);
66 static const struct cfg80211_chan_def
*
67 ieee80211_chanctx_reserved_chandef(struct ieee80211_local
*local
,
68 struct ieee80211_chanctx
*ctx
,
69 const struct cfg80211_chan_def
*compat
)
71 struct ieee80211_sub_if_data
*sdata
;
73 lockdep_assert_held(&local
->chanctx_mtx
);
75 list_for_each_entry(sdata
, &ctx
->reserved_vifs
,
76 reserved_chanctx_list
) {
78 compat
= &sdata
->reserved_chandef
;
80 compat
= cfg80211_chandef_compatible(&sdata
->reserved_chandef
,
89 static const struct cfg80211_chan_def
*
90 ieee80211_chanctx_non_reserved_chandef(struct ieee80211_local
*local
,
91 struct ieee80211_chanctx
*ctx
,
92 const struct cfg80211_chan_def
*compat
)
94 struct ieee80211_sub_if_data
*sdata
;
96 lockdep_assert_held(&local
->chanctx_mtx
);
98 list_for_each_entry(sdata
, &ctx
->assigned_vifs
,
99 assigned_chanctx_list
) {
100 if (sdata
->reserved_chanctx
!= NULL
)
104 compat
= &sdata
->vif
.bss_conf
.chandef
;
106 compat
= cfg80211_chandef_compatible(
107 &sdata
->vif
.bss_conf
.chandef
, compat
);
115 static const struct cfg80211_chan_def
*
116 ieee80211_chanctx_combined_chandef(struct ieee80211_local
*local
,
117 struct ieee80211_chanctx
*ctx
,
118 const struct cfg80211_chan_def
*compat
)
120 lockdep_assert_held(&local
->chanctx_mtx
);
122 compat
= ieee80211_chanctx_reserved_chandef(local
, ctx
, compat
);
126 compat
= ieee80211_chanctx_non_reserved_chandef(local
, ctx
, compat
);
134 ieee80211_chanctx_can_reserve_chandef(struct ieee80211_local
*local
,
135 struct ieee80211_chanctx
*ctx
,
136 const struct cfg80211_chan_def
*def
)
138 lockdep_assert_held(&local
->chanctx_mtx
);
140 if (ieee80211_chanctx_combined_chandef(local
, ctx
, def
))
143 if (!list_empty(&ctx
->reserved_vifs
) &&
144 ieee80211_chanctx_reserved_chandef(local
, ctx
, def
))
150 static struct ieee80211_chanctx
*
151 ieee80211_find_reservation_chanctx(struct ieee80211_local
*local
,
152 const struct cfg80211_chan_def
*chandef
,
153 enum ieee80211_chanctx_mode mode
)
155 struct ieee80211_chanctx
*ctx
;
157 lockdep_assert_held(&local
->chanctx_mtx
);
159 if (mode
== IEEE80211_CHANCTX_EXCLUSIVE
)
162 list_for_each_entry(ctx
, &local
->chanctx_list
, list
) {
163 if (ctx
->mode
== IEEE80211_CHANCTX_EXCLUSIVE
)
166 if (!ieee80211_chanctx_can_reserve_chandef(local
, ctx
,
176 static enum nl80211_chan_width
ieee80211_get_sta_bw(struct ieee80211_sta
*sta
)
178 switch (sta
->bandwidth
) {
179 case IEEE80211_STA_RX_BW_20
:
180 if (sta
->ht_cap
.ht_supported
)
181 return NL80211_CHAN_WIDTH_20
;
183 return NL80211_CHAN_WIDTH_20_NOHT
;
184 case IEEE80211_STA_RX_BW_40
:
185 return NL80211_CHAN_WIDTH_40
;
186 case IEEE80211_STA_RX_BW_80
:
187 return NL80211_CHAN_WIDTH_80
;
188 case IEEE80211_STA_RX_BW_160
:
190 * This applied for both 160 and 80+80. since we use
191 * the returned value to consider degradation of
192 * ctx->conf.min_def, we have to make sure to take
193 * the bigger one (NL80211_CHAN_WIDTH_160).
194 * Otherwise we might try degrading even when not
195 * needed, as the max required sta_bw returned (80+80)
196 * might be smaller than the configured bw (160).
198 return NL80211_CHAN_WIDTH_160
;
201 return NL80211_CHAN_WIDTH_20
;
205 static enum nl80211_chan_width
206 ieee80211_get_max_required_bw(struct ieee80211_sub_if_data
*sdata
)
208 enum nl80211_chan_width max_bw
= NL80211_CHAN_WIDTH_20_NOHT
;
209 struct sta_info
*sta
;
212 list_for_each_entry_rcu(sta
, &sdata
->local
->sta_list
, list
) {
213 if (sdata
!= sta
->sdata
&&
214 !(sta
->sdata
->bss
&& sta
->sdata
->bss
== sdata
->bss
))
220 max_bw
= max(max_bw
, ieee80211_get_sta_bw(&sta
->sta
));
227 static enum nl80211_chan_width
228 ieee80211_get_chanctx_max_required_bw(struct ieee80211_local
*local
,
229 struct ieee80211_chanctx_conf
*conf
)
231 struct ieee80211_sub_if_data
*sdata
;
232 enum nl80211_chan_width max_bw
= NL80211_CHAN_WIDTH_20_NOHT
;
235 list_for_each_entry_rcu(sdata
, &local
->interfaces
, list
) {
236 struct ieee80211_vif
*vif
= &sdata
->vif
;
237 enum nl80211_chan_width width
= NL80211_CHAN_WIDTH_20_NOHT
;
239 if (!ieee80211_sdata_running(sdata
))
242 if (rcu_access_pointer(sdata
->vif
.chanctx_conf
) != conf
)
246 case NL80211_IFTYPE_AP
:
247 case NL80211_IFTYPE_AP_VLAN
:
248 width
= ieee80211_get_max_required_bw(sdata
);
250 case NL80211_IFTYPE_P2P_DEVICE
:
252 case NL80211_IFTYPE_STATION
:
253 case NL80211_IFTYPE_ADHOC
:
254 case NL80211_IFTYPE_WDS
:
255 case NL80211_IFTYPE_MESH_POINT
:
256 width
= vif
->bss_conf
.chandef
.width
;
258 case NL80211_IFTYPE_UNSPECIFIED
:
259 case NUM_NL80211_IFTYPES
:
260 case NL80211_IFTYPE_MONITOR
:
261 case NL80211_IFTYPE_P2P_CLIENT
:
262 case NL80211_IFTYPE_P2P_GO
:
265 max_bw
= max(max_bw
, width
);
268 /* use the configured bandwidth in case of monitor interface */
269 sdata
= rcu_dereference(local
->monitor_sdata
);
270 if (sdata
&& rcu_access_pointer(sdata
->vif
.chanctx_conf
) == conf
)
271 max_bw
= max(max_bw
, conf
->def
.width
);
279 * recalc the min required chan width of the channel context, which is
280 * the max of min required widths of all the interfaces bound to this
283 void ieee80211_recalc_chanctx_min_def(struct ieee80211_local
*local
,
284 struct ieee80211_chanctx
*ctx
)
286 enum nl80211_chan_width max_bw
;
287 struct cfg80211_chan_def min_def
;
289 lockdep_assert_held(&local
->chanctx_mtx
);
291 /* don't optimize 5MHz, 10MHz, and radar_enabled confs */
292 if (ctx
->conf
.def
.width
== NL80211_CHAN_WIDTH_5
||
293 ctx
->conf
.def
.width
== NL80211_CHAN_WIDTH_10
||
294 ctx
->conf
.radar_enabled
) {
295 ctx
->conf
.min_def
= ctx
->conf
.def
;
299 max_bw
= ieee80211_get_chanctx_max_required_bw(local
, &ctx
->conf
);
301 /* downgrade chandef up to max_bw */
302 min_def
= ctx
->conf
.def
;
303 while (min_def
.width
> max_bw
)
304 ieee80211_chandef_downgrade(&min_def
);
306 if (cfg80211_chandef_identical(&ctx
->conf
.min_def
, &min_def
))
309 ctx
->conf
.min_def
= min_def
;
310 if (!ctx
->driver_present
)
313 drv_change_chanctx(local
, ctx
, IEEE80211_CHANCTX_CHANGE_MIN_WIDTH
);
316 static void ieee80211_change_chanctx(struct ieee80211_local
*local
,
317 struct ieee80211_chanctx
*ctx
,
318 const struct cfg80211_chan_def
*chandef
)
320 if (cfg80211_chandef_identical(&ctx
->conf
.def
, chandef
))
323 WARN_ON(!cfg80211_chandef_compatible(&ctx
->conf
.def
, chandef
));
325 ctx
->conf
.def
= *chandef
;
326 drv_change_chanctx(local
, ctx
, IEEE80211_CHANCTX_CHANGE_WIDTH
);
327 ieee80211_recalc_chanctx_min_def(local
, ctx
);
329 if (!local
->use_chanctx
) {
330 local
->_oper_chandef
= *chandef
;
331 ieee80211_hw_config(local
, 0);
335 static struct ieee80211_chanctx
*
336 ieee80211_find_chanctx(struct ieee80211_local
*local
,
337 const struct cfg80211_chan_def
*chandef
,
338 enum ieee80211_chanctx_mode mode
)
340 struct ieee80211_chanctx
*ctx
;
342 lockdep_assert_held(&local
->chanctx_mtx
);
344 if (mode
== IEEE80211_CHANCTX_EXCLUSIVE
)
347 list_for_each_entry(ctx
, &local
->chanctx_list
, list
) {
348 const struct cfg80211_chan_def
*compat
;
350 if (ctx
->mode
== IEEE80211_CHANCTX_EXCLUSIVE
)
353 compat
= cfg80211_chandef_compatible(&ctx
->conf
.def
, chandef
);
357 compat
= ieee80211_chanctx_reserved_chandef(local
, ctx
,
362 ieee80211_change_chanctx(local
, ctx
, compat
);
370 static bool ieee80211_is_radar_required(struct ieee80211_local
*local
)
372 struct ieee80211_sub_if_data
*sdata
;
374 lockdep_assert_held(&local
->mtx
);
377 list_for_each_entry_rcu(sdata
, &local
->interfaces
, list
) {
378 if (sdata
->radar_required
) {
388 static struct ieee80211_chanctx
*
389 ieee80211_alloc_chanctx(struct ieee80211_local
*local
,
390 const struct cfg80211_chan_def
*chandef
,
391 enum ieee80211_chanctx_mode mode
)
393 struct ieee80211_chanctx
*ctx
;
395 lockdep_assert_held(&local
->chanctx_mtx
);
397 ctx
= kzalloc(sizeof(*ctx
) + local
->hw
.chanctx_data_size
, GFP_KERNEL
);
401 INIT_LIST_HEAD(&ctx
->assigned_vifs
);
402 INIT_LIST_HEAD(&ctx
->reserved_vifs
);
403 ctx
->conf
.def
= *chandef
;
404 ctx
->conf
.rx_chains_static
= 1;
405 ctx
->conf
.rx_chains_dynamic
= 1;
407 ctx
->conf
.radar_enabled
= ieee80211_is_radar_required(local
);
408 ieee80211_recalc_chanctx_min_def(local
, ctx
);
413 static int ieee80211_add_chanctx(struct ieee80211_local
*local
,
414 struct ieee80211_chanctx
*ctx
)
419 lockdep_assert_held(&local
->mtx
);
420 lockdep_assert_held(&local
->chanctx_mtx
);
422 if (!local
->use_chanctx
)
423 local
->hw
.conf
.radar_enabled
= ctx
->conf
.radar_enabled
;
425 /* turn idle off *before* setting channel -- some drivers need that */
426 changed
= ieee80211_idle_off(local
);
428 ieee80211_hw_config(local
, changed
);
430 if (!local
->use_chanctx
) {
431 local
->_oper_chandef
= ctx
->conf
.def
;
432 ieee80211_hw_config(local
, IEEE80211_CONF_CHANGE_CHANNEL
);
434 err
= drv_add_chanctx(local
, ctx
);
436 ieee80211_recalc_idle(local
);
444 static struct ieee80211_chanctx
*
445 ieee80211_new_chanctx(struct ieee80211_local
*local
,
446 const struct cfg80211_chan_def
*chandef
,
447 enum ieee80211_chanctx_mode mode
)
449 struct ieee80211_chanctx
*ctx
;
452 lockdep_assert_held(&local
->mtx
);
453 lockdep_assert_held(&local
->chanctx_mtx
);
455 ctx
= ieee80211_alloc_chanctx(local
, chandef
, mode
);
457 return ERR_PTR(-ENOMEM
);
459 err
= ieee80211_add_chanctx(local
, ctx
);
465 list_add_rcu(&ctx
->list
, &local
->chanctx_list
);
469 static void ieee80211_del_chanctx(struct ieee80211_local
*local
,
470 struct ieee80211_chanctx
*ctx
)
472 lockdep_assert_held(&local
->chanctx_mtx
);
474 if (!local
->use_chanctx
) {
475 struct cfg80211_chan_def
*chandef
= &local
->_oper_chandef
;
476 chandef
->width
= NL80211_CHAN_WIDTH_20_NOHT
;
477 chandef
->center_freq1
= chandef
->chan
->center_freq
;
478 chandef
->center_freq2
= 0;
480 /* NOTE: Disabling radar is only valid here for
481 * single channel context. To be sure, check it ...
483 WARN_ON(local
->hw
.conf
.radar_enabled
&&
484 !list_empty(&local
->chanctx_list
));
486 local
->hw
.conf
.radar_enabled
= false;
488 ieee80211_hw_config(local
, IEEE80211_CONF_CHANGE_CHANNEL
);
490 drv_remove_chanctx(local
, ctx
);
493 ieee80211_recalc_idle(local
);
496 static void ieee80211_free_chanctx(struct ieee80211_local
*local
,
497 struct ieee80211_chanctx
*ctx
)
499 lockdep_assert_held(&local
->chanctx_mtx
);
501 WARN_ON_ONCE(ieee80211_chanctx_refcount(local
, ctx
) != 0);
503 list_del_rcu(&ctx
->list
);
504 ieee80211_del_chanctx(local
, ctx
);
505 kfree_rcu(ctx
, rcu_head
);
508 static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local
*local
,
509 struct ieee80211_chanctx
*ctx
)
511 struct ieee80211_chanctx_conf
*conf
= &ctx
->conf
;
512 struct ieee80211_sub_if_data
*sdata
;
513 const struct cfg80211_chan_def
*compat
= NULL
;
515 lockdep_assert_held(&local
->chanctx_mtx
);
518 list_for_each_entry_rcu(sdata
, &local
->interfaces
, list
) {
520 if (!ieee80211_sdata_running(sdata
))
522 if (rcu_access_pointer(sdata
->vif
.chanctx_conf
) != conf
)
526 compat
= &sdata
->vif
.bss_conf
.chandef
;
528 compat
= cfg80211_chandef_compatible(
529 &sdata
->vif
.bss_conf
.chandef
, compat
);
535 if (WARN_ON_ONCE(!compat
))
538 ieee80211_change_chanctx(local
, ctx
, compat
);
541 static void ieee80211_recalc_radar_chanctx(struct ieee80211_local
*local
,
542 struct ieee80211_chanctx
*chanctx
)
546 lockdep_assert_held(&local
->chanctx_mtx
);
547 /* for setting local->radar_detect_enabled */
548 lockdep_assert_held(&local
->mtx
);
550 radar_enabled
= ieee80211_is_radar_required(local
);
552 if (radar_enabled
== chanctx
->conf
.radar_enabled
)
555 chanctx
->conf
.radar_enabled
= radar_enabled
;
556 local
->radar_detect_enabled
= chanctx
->conf
.radar_enabled
;
558 if (!local
->use_chanctx
) {
559 local
->hw
.conf
.radar_enabled
= chanctx
->conf
.radar_enabled
;
560 ieee80211_hw_config(local
, IEEE80211_CONF_CHANGE_CHANNEL
);
563 drv_change_chanctx(local
, chanctx
, IEEE80211_CHANCTX_CHANGE_RADAR
);
566 static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data
*sdata
,
567 struct ieee80211_chanctx
*new_ctx
)
569 struct ieee80211_local
*local
= sdata
->local
;
570 struct ieee80211_chanctx_conf
*conf
;
571 struct ieee80211_chanctx
*curr_ctx
= NULL
;
574 conf
= rcu_dereference_protected(sdata
->vif
.chanctx_conf
,
575 lockdep_is_held(&local
->chanctx_mtx
));
578 curr_ctx
= container_of(conf
, struct ieee80211_chanctx
, conf
);
580 drv_unassign_vif_chanctx(local
, sdata
, curr_ctx
);
582 list_del(&sdata
->assigned_chanctx_list
);
586 ret
= drv_assign_vif_chanctx(local
, sdata
, new_ctx
);
590 conf
= &new_ctx
->conf
;
591 list_add(&sdata
->assigned_chanctx_list
,
592 &new_ctx
->assigned_vifs
);
596 rcu_assign_pointer(sdata
->vif
.chanctx_conf
, conf
);
598 sdata
->vif
.bss_conf
.idle
= !conf
;
600 if (curr_ctx
&& ieee80211_chanctx_num_assigned(local
, curr_ctx
) > 0) {
601 ieee80211_recalc_chanctx_chantype(local
, curr_ctx
);
602 ieee80211_recalc_smps_chanctx(local
, curr_ctx
);
603 ieee80211_recalc_radar_chanctx(local
, curr_ctx
);
604 ieee80211_recalc_chanctx_min_def(local
, curr_ctx
);
607 if (new_ctx
&& ieee80211_chanctx_num_assigned(local
, new_ctx
) > 0) {
608 ieee80211_recalc_txpower(sdata
);
609 ieee80211_recalc_chanctx_min_def(local
, new_ctx
);
612 if (sdata
->vif
.type
!= NL80211_IFTYPE_P2P_DEVICE
&&
613 sdata
->vif
.type
!= NL80211_IFTYPE_MONITOR
)
614 ieee80211_bss_info_change_notify(sdata
,
620 static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data
*sdata
)
622 struct ieee80211_local
*local
= sdata
->local
;
623 struct ieee80211_chanctx_conf
*conf
;
624 struct ieee80211_chanctx
*ctx
;
626 lockdep_assert_held(&local
->chanctx_mtx
);
628 conf
= rcu_dereference_protected(sdata
->vif
.chanctx_conf
,
629 lockdep_is_held(&local
->chanctx_mtx
));
633 ctx
= container_of(conf
, struct ieee80211_chanctx
, conf
);
635 if (sdata
->reserved_chanctx
)
636 ieee80211_vif_unreserve_chanctx(sdata
);
638 ieee80211_assign_vif_chanctx(sdata
, NULL
);
639 if (ieee80211_chanctx_refcount(local
, ctx
) == 0)
640 ieee80211_free_chanctx(local
, ctx
);
643 void ieee80211_recalc_smps_chanctx(struct ieee80211_local
*local
,
644 struct ieee80211_chanctx
*chanctx
)
646 struct ieee80211_sub_if_data
*sdata
;
647 u8 rx_chains_static
, rx_chains_dynamic
;
649 lockdep_assert_held(&local
->chanctx_mtx
);
651 rx_chains_static
= 1;
652 rx_chains_dynamic
= 1;
655 list_for_each_entry_rcu(sdata
, &local
->interfaces
, list
) {
656 u8 needed_static
, needed_dynamic
;
658 if (!ieee80211_sdata_running(sdata
))
661 if (rcu_access_pointer(sdata
->vif
.chanctx_conf
) !=
665 switch (sdata
->vif
.type
) {
666 case NL80211_IFTYPE_P2P_DEVICE
:
668 case NL80211_IFTYPE_STATION
:
669 if (!sdata
->u
.mgd
.associated
)
672 case NL80211_IFTYPE_AP_VLAN
:
674 case NL80211_IFTYPE_AP
:
675 case NL80211_IFTYPE_ADHOC
:
676 case NL80211_IFTYPE_WDS
:
677 case NL80211_IFTYPE_MESH_POINT
:
683 switch (sdata
->smps_mode
) {
685 WARN_ONCE(1, "Invalid SMPS mode %d\n",
688 case IEEE80211_SMPS_OFF
:
689 needed_static
= sdata
->needed_rx_chains
;
690 needed_dynamic
= sdata
->needed_rx_chains
;
692 case IEEE80211_SMPS_DYNAMIC
:
694 needed_dynamic
= sdata
->needed_rx_chains
;
696 case IEEE80211_SMPS_STATIC
:
702 rx_chains_static
= max(rx_chains_static
, needed_static
);
703 rx_chains_dynamic
= max(rx_chains_dynamic
, needed_dynamic
);
706 /* Disable SMPS for the monitor interface */
707 sdata
= rcu_dereference(local
->monitor_sdata
);
709 rcu_access_pointer(sdata
->vif
.chanctx_conf
) == &chanctx
->conf
)
710 rx_chains_dynamic
= rx_chains_static
= local
->rx_chains
;
714 if (!local
->use_chanctx
) {
715 if (rx_chains_static
> 1)
716 local
->smps_mode
= IEEE80211_SMPS_OFF
;
717 else if (rx_chains_dynamic
> 1)
718 local
->smps_mode
= IEEE80211_SMPS_DYNAMIC
;
720 local
->smps_mode
= IEEE80211_SMPS_STATIC
;
721 ieee80211_hw_config(local
, 0);
724 if (rx_chains_static
== chanctx
->conf
.rx_chains_static
&&
725 rx_chains_dynamic
== chanctx
->conf
.rx_chains_dynamic
)
728 chanctx
->conf
.rx_chains_static
= rx_chains_static
;
729 chanctx
->conf
.rx_chains_dynamic
= rx_chains_dynamic
;
730 drv_change_chanctx(local
, chanctx
, IEEE80211_CHANCTX_CHANGE_RX_CHAINS
);
733 int ieee80211_vif_use_channel(struct ieee80211_sub_if_data
*sdata
,
734 const struct cfg80211_chan_def
*chandef
,
735 enum ieee80211_chanctx_mode mode
)
737 struct ieee80211_local
*local
= sdata
->local
;
738 struct ieee80211_chanctx
*ctx
;
739 u8 radar_detect_width
= 0;
742 lockdep_assert_held(&local
->mtx
);
744 WARN_ON(sdata
->dev
&& netif_carrier_ok(sdata
->dev
));
746 mutex_lock(&local
->chanctx_mtx
);
748 ret
= cfg80211_chandef_dfs_required(local
->hw
.wiphy
,
754 radar_detect_width
= BIT(chandef
->width
);
756 sdata
->radar_required
= ret
;
758 ret
= ieee80211_check_combinations(sdata
, chandef
, mode
,
763 __ieee80211_vif_release_channel(sdata
);
765 ctx
= ieee80211_find_chanctx(local
, chandef
, mode
);
767 ctx
= ieee80211_new_chanctx(local
, chandef
, mode
);
773 sdata
->vif
.bss_conf
.chandef
= *chandef
;
775 ret
= ieee80211_assign_vif_chanctx(sdata
, ctx
);
777 /* if assign fails refcount stays the same */
778 if (ieee80211_chanctx_refcount(local
, ctx
) == 0)
779 ieee80211_free_chanctx(local
, ctx
);
783 ieee80211_recalc_smps_chanctx(local
, ctx
);
784 ieee80211_recalc_radar_chanctx(local
, ctx
);
786 mutex_unlock(&local
->chanctx_mtx
);
790 static int __ieee80211_vif_change_channel(struct ieee80211_sub_if_data
*sdata
,
791 struct ieee80211_chanctx
*ctx
,
794 struct ieee80211_local
*local
= sdata
->local
;
795 const struct cfg80211_chan_def
*chandef
= &sdata
->csa_chandef
;
796 u32 chanctx_changed
= 0;
798 if (!cfg80211_chandef_usable(sdata
->local
->hw
.wiphy
, chandef
,
799 IEEE80211_CHAN_DISABLED
))
802 if (ieee80211_chanctx_refcount(local
, ctx
) != 1)
805 if (sdata
->vif
.bss_conf
.chandef
.width
!= chandef
->width
) {
806 chanctx_changed
= IEEE80211_CHANCTX_CHANGE_WIDTH
;
807 *changed
|= BSS_CHANGED_BANDWIDTH
;
810 sdata
->vif
.bss_conf
.chandef
= *chandef
;
811 ctx
->conf
.def
= *chandef
;
813 chanctx_changed
|= IEEE80211_CHANCTX_CHANGE_CHANNEL
;
814 drv_change_chanctx(local
, ctx
, chanctx_changed
);
816 ieee80211_recalc_chanctx_chantype(local
, ctx
);
817 ieee80211_recalc_smps_chanctx(local
, ctx
);
818 ieee80211_recalc_radar_chanctx(local
, ctx
);
819 ieee80211_recalc_chanctx_min_def(local
, ctx
);
824 int ieee80211_vif_change_channel(struct ieee80211_sub_if_data
*sdata
,
827 struct ieee80211_local
*local
= sdata
->local
;
828 struct ieee80211_chanctx_conf
*conf
;
829 struct ieee80211_chanctx
*ctx
;
832 lockdep_assert_held(&local
->mtx
);
834 /* should never be called if not performing a channel switch. */
835 if (WARN_ON(!sdata
->vif
.csa_active
))
838 mutex_lock(&local
->chanctx_mtx
);
839 conf
= rcu_dereference_protected(sdata
->vif
.chanctx_conf
,
840 lockdep_is_held(&local
->chanctx_mtx
));
846 ctx
= container_of(conf
, struct ieee80211_chanctx
, conf
);
848 ret
= __ieee80211_vif_change_channel(sdata
, ctx
, changed
);
850 mutex_unlock(&local
->chanctx_mtx
);
855 __ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data
*sdata
,
858 struct ieee80211_local
*local __maybe_unused
= sdata
->local
;
859 struct ieee80211_sub_if_data
*vlan
;
860 struct ieee80211_chanctx_conf
*conf
;
862 if (WARN_ON(sdata
->vif
.type
!= NL80211_IFTYPE_AP
))
865 lockdep_assert_held(&local
->mtx
);
867 /* Check that conf exists, even when clearing this function
868 * must be called with the AP's channel context still there
869 * as it would otherwise cause VLANs to have an invalid
870 * channel context pointer for a while, possibly pointing
871 * to a channel context that has already been freed.
873 conf
= rcu_dereference_protected(sdata
->vif
.chanctx_conf
,
874 lockdep_is_held(&local
->chanctx_mtx
));
880 list_for_each_entry(vlan
, &sdata
->u
.ap
.vlans
, u
.vlan
.list
)
881 rcu_assign_pointer(vlan
->vif
.chanctx_conf
, conf
);
884 void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data
*sdata
,
887 struct ieee80211_local
*local
= sdata
->local
;
889 mutex_lock(&local
->chanctx_mtx
);
891 __ieee80211_vif_copy_chanctx_to_vlans(sdata
, clear
);
893 mutex_unlock(&local
->chanctx_mtx
);
896 int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data
*sdata
)
898 struct ieee80211_chanctx
*ctx
= sdata
->reserved_chanctx
;
900 lockdep_assert_held(&sdata
->local
->chanctx_mtx
);
905 list_del(&sdata
->reserved_chanctx_list
);
906 sdata
->reserved_chanctx
= NULL
;
908 if (ieee80211_chanctx_refcount(sdata
->local
, ctx
) == 0)
909 ieee80211_free_chanctx(sdata
->local
, ctx
);
914 int ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data
*sdata
,
915 const struct cfg80211_chan_def
*chandef
,
916 enum ieee80211_chanctx_mode mode
,
919 struct ieee80211_local
*local
= sdata
->local
;
920 struct ieee80211_chanctx_conf
*conf
;
921 struct ieee80211_chanctx
*new_ctx
, *curr_ctx
;
924 mutex_lock(&local
->chanctx_mtx
);
926 conf
= rcu_dereference_protected(sdata
->vif
.chanctx_conf
,
927 lockdep_is_held(&local
->chanctx_mtx
));
933 curr_ctx
= container_of(conf
, struct ieee80211_chanctx
, conf
);
935 new_ctx
= ieee80211_find_reservation_chanctx(local
, chandef
, mode
);
937 if (ieee80211_chanctx_refcount(local
, curr_ctx
) == 1 &&
938 (local
->hw
.flags
& IEEE80211_HW_CHANGE_RUNNING_CHANCTX
)) {
939 /* if we're the only users of the chanctx and
940 * the driver supports changing a running
941 * context, reserve our current context
944 } else if (ieee80211_can_create_new_chanctx(local
)) {
945 /* create a new context and reserve it */
946 new_ctx
= ieee80211_new_chanctx(local
, chandef
, mode
);
947 if (IS_ERR(new_ctx
)) {
948 ret
= PTR_ERR(new_ctx
);
957 list_add(&sdata
->reserved_chanctx_list
, &new_ctx
->reserved_vifs
);
958 sdata
->reserved_chanctx
= new_ctx
;
959 sdata
->reserved_chandef
= *chandef
;
960 sdata
->reserved_radar_required
= radar_required
;
962 mutex_unlock(&local
->chanctx_mtx
);
966 int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data
*sdata
,
969 struct ieee80211_local
*local
= sdata
->local
;
970 struct ieee80211_chanctx
*ctx
;
971 struct ieee80211_chanctx
*old_ctx
;
972 struct ieee80211_chanctx_conf
*conf
;
974 u32 tmp_changed
= *changed
;
976 /* TODO: need to recheck if the chandef is usable etc.? */
978 lockdep_assert_held(&local
->mtx
);
980 mutex_lock(&local
->chanctx_mtx
);
982 ctx
= sdata
->reserved_chanctx
;
988 conf
= rcu_dereference_protected(sdata
->vif
.chanctx_conf
,
989 lockdep_is_held(&local
->chanctx_mtx
));
995 old_ctx
= container_of(conf
, struct ieee80211_chanctx
, conf
);
997 if (sdata
->vif
.bss_conf
.chandef
.width
!= sdata
->reserved_chandef
.width
)
998 tmp_changed
|= BSS_CHANGED_BANDWIDTH
;
1000 sdata
->vif
.bss_conf
.chandef
= sdata
->reserved_chandef
;
1002 /* unref our reservation */
1003 sdata
->reserved_chanctx
= NULL
;
1004 sdata
->radar_required
= sdata
->reserved_radar_required
;
1005 list_del(&sdata
->reserved_chanctx_list
);
1007 if (old_ctx
== ctx
) {
1008 /* This is our own context, just change it */
1009 ret
= __ieee80211_vif_change_channel(sdata
, old_ctx
,
1014 ret
= ieee80211_assign_vif_chanctx(sdata
, ctx
);
1015 if (ieee80211_chanctx_refcount(local
, old_ctx
) == 0)
1016 ieee80211_free_chanctx(local
, old_ctx
);
1018 /* if assign fails refcount stays the same */
1019 if (ieee80211_chanctx_refcount(local
, ctx
) == 0)
1020 ieee80211_free_chanctx(local
, ctx
);
1024 if (sdata
->vif
.type
== NL80211_IFTYPE_AP
)
1025 __ieee80211_vif_copy_chanctx_to_vlans(sdata
, false);
1028 *changed
= tmp_changed
;
1030 ieee80211_recalc_chanctx_chantype(local
, ctx
);
1031 ieee80211_recalc_smps_chanctx(local
, ctx
);
1032 ieee80211_recalc_radar_chanctx(local
, ctx
);
1033 ieee80211_recalc_chanctx_min_def(local
, ctx
);
1035 mutex_unlock(&local
->chanctx_mtx
);
1039 int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data
*sdata
,
1040 const struct cfg80211_chan_def
*chandef
,
1043 struct ieee80211_local
*local
= sdata
->local
;
1044 struct ieee80211_chanctx_conf
*conf
;
1045 struct ieee80211_chanctx
*ctx
;
1048 if (!cfg80211_chandef_usable(sdata
->local
->hw
.wiphy
, chandef
,
1049 IEEE80211_CHAN_DISABLED
))
1052 mutex_lock(&local
->chanctx_mtx
);
1053 if (cfg80211_chandef_identical(chandef
, &sdata
->vif
.bss_conf
.chandef
)) {
1058 if (chandef
->width
== NL80211_CHAN_WIDTH_20_NOHT
||
1059 sdata
->vif
.bss_conf
.chandef
.width
== NL80211_CHAN_WIDTH_20_NOHT
) {
1064 conf
= rcu_dereference_protected(sdata
->vif
.chanctx_conf
,
1065 lockdep_is_held(&local
->chanctx_mtx
));
1071 ctx
= container_of(conf
, struct ieee80211_chanctx
, conf
);
1072 if (!cfg80211_chandef_compatible(&conf
->def
, chandef
)) {
1077 sdata
->vif
.bss_conf
.chandef
= *chandef
;
1079 ieee80211_recalc_chanctx_chantype(local
, ctx
);
1081 *changed
|= BSS_CHANGED_BANDWIDTH
;
1084 mutex_unlock(&local
->chanctx_mtx
);
1088 void ieee80211_vif_release_channel(struct ieee80211_sub_if_data
*sdata
)
1090 WARN_ON(sdata
->dev
&& netif_carrier_ok(sdata
->dev
));
1092 lockdep_assert_held(&sdata
->local
->mtx
);
1094 mutex_lock(&sdata
->local
->chanctx_mtx
);
1095 __ieee80211_vif_release_channel(sdata
);
1096 mutex_unlock(&sdata
->local
->chanctx_mtx
);
1099 void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data
*sdata
)
1101 struct ieee80211_local
*local
= sdata
->local
;
1102 struct ieee80211_sub_if_data
*ap
;
1103 struct ieee80211_chanctx_conf
*conf
;
1105 if (WARN_ON(sdata
->vif
.type
!= NL80211_IFTYPE_AP_VLAN
|| !sdata
->bss
))
1108 ap
= container_of(sdata
->bss
, struct ieee80211_sub_if_data
, u
.ap
);
1110 mutex_lock(&local
->chanctx_mtx
);
1112 conf
= rcu_dereference_protected(ap
->vif
.chanctx_conf
,
1113 lockdep_is_held(&local
->chanctx_mtx
));
1114 rcu_assign_pointer(sdata
->vif
.chanctx_conf
, conf
);
1115 mutex_unlock(&local
->chanctx_mtx
);
1118 void ieee80211_iter_chan_contexts_atomic(
1119 struct ieee80211_hw
*hw
,
1120 void (*iter
)(struct ieee80211_hw
*hw
,
1121 struct ieee80211_chanctx_conf
*chanctx_conf
,
1125 struct ieee80211_local
*local
= hw_to_local(hw
);
1126 struct ieee80211_chanctx
*ctx
;
1129 list_for_each_entry_rcu(ctx
, &local
->chanctx_list
, list
)
1130 if (ctx
->driver_present
)
1131 iter(hw
, &ctx
->conf
, iter_data
);
1134 EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic
);