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 enum nl80211_chan_width
ieee80211_get_sta_bw(struct ieee80211_sta
*sta
)
14 switch (sta
->bandwidth
) {
15 case IEEE80211_STA_RX_BW_20
:
16 if (sta
->ht_cap
.ht_supported
)
17 return NL80211_CHAN_WIDTH_20
;
19 return NL80211_CHAN_WIDTH_20_NOHT
;
20 case IEEE80211_STA_RX_BW_40
:
21 return NL80211_CHAN_WIDTH_40
;
22 case IEEE80211_STA_RX_BW_80
:
23 return NL80211_CHAN_WIDTH_80
;
24 case IEEE80211_STA_RX_BW_160
:
26 * This applied for both 160 and 80+80. since we use
27 * the returned value to consider degradation of
28 * ctx->conf.min_def, we have to make sure to take
29 * the bigger one (NL80211_CHAN_WIDTH_160).
30 * Otherwise we might try degrading even when not
31 * needed, as the max required sta_bw returned (80+80)
32 * might be smaller than the configured bw (160).
34 return NL80211_CHAN_WIDTH_160
;
37 return NL80211_CHAN_WIDTH_20
;
41 static enum nl80211_chan_width
42 ieee80211_get_max_required_bw(struct ieee80211_sub_if_data
*sdata
)
44 enum nl80211_chan_width max_bw
= NL80211_CHAN_WIDTH_20_NOHT
;
48 list_for_each_entry_rcu(sta
, &sdata
->local
->sta_list
, list
) {
49 if (sdata
!= sta
->sdata
&&
50 !(sta
->sdata
->bss
&& sta
->sdata
->bss
== sdata
->bss
))
56 max_bw
= max(max_bw
, ieee80211_get_sta_bw(&sta
->sta
));
63 static enum nl80211_chan_width
64 ieee80211_get_chanctx_max_required_bw(struct ieee80211_local
*local
,
65 struct ieee80211_chanctx_conf
*conf
)
67 struct ieee80211_sub_if_data
*sdata
;
68 enum nl80211_chan_width max_bw
= NL80211_CHAN_WIDTH_20_NOHT
;
71 list_for_each_entry_rcu(sdata
, &local
->interfaces
, list
) {
72 struct ieee80211_vif
*vif
= &sdata
->vif
;
73 enum nl80211_chan_width width
= NL80211_CHAN_WIDTH_20_NOHT
;
75 if (!ieee80211_sdata_running(sdata
))
78 if (rcu_access_pointer(sdata
->vif
.chanctx_conf
) != conf
)
82 case NL80211_IFTYPE_AP
:
83 case NL80211_IFTYPE_AP_VLAN
:
84 width
= ieee80211_get_max_required_bw(sdata
);
86 case NL80211_IFTYPE_P2P_DEVICE
:
88 case NL80211_IFTYPE_STATION
:
89 case NL80211_IFTYPE_ADHOC
:
90 case NL80211_IFTYPE_WDS
:
91 case NL80211_IFTYPE_MESH_POINT
:
92 width
= vif
->bss_conf
.chandef
.width
;
94 case NL80211_IFTYPE_UNSPECIFIED
:
95 case NUM_NL80211_IFTYPES
:
96 case NL80211_IFTYPE_MONITOR
:
97 case NL80211_IFTYPE_P2P_CLIENT
:
98 case NL80211_IFTYPE_P2P_GO
:
101 max_bw
= max(max_bw
, width
);
109 * recalc the min required chan width of the channel context, which is
110 * the max of min required widths of all the interfaces bound to this
113 void ieee80211_recalc_chanctx_min_def(struct ieee80211_local
*local
,
114 struct ieee80211_chanctx
*ctx
)
116 enum nl80211_chan_width max_bw
;
117 struct cfg80211_chan_def min_def
;
119 lockdep_assert_held(&local
->chanctx_mtx
);
121 /* don't optimize 5MHz, 10MHz, and radar_enabled confs */
122 if (ctx
->conf
.def
.width
== NL80211_CHAN_WIDTH_5
||
123 ctx
->conf
.def
.width
== NL80211_CHAN_WIDTH_10
||
124 ctx
->conf
.radar_enabled
) {
125 ctx
->conf
.min_def
= ctx
->conf
.def
;
129 max_bw
= ieee80211_get_chanctx_max_required_bw(local
, &ctx
->conf
);
131 /* downgrade chandef up to max_bw */
132 min_def
= ctx
->conf
.def
;
133 while (min_def
.width
> max_bw
)
134 ieee80211_chandef_downgrade(&min_def
);
136 if (cfg80211_chandef_identical(&ctx
->conf
.min_def
, &min_def
))
139 ctx
->conf
.min_def
= min_def
;
140 if (!ctx
->driver_present
)
143 drv_change_chanctx(local
, ctx
, IEEE80211_CHANCTX_CHANGE_MIN_WIDTH
);
146 static void ieee80211_change_chanctx(struct ieee80211_local
*local
,
147 struct ieee80211_chanctx
*ctx
,
148 const struct cfg80211_chan_def
*chandef
)
150 if (cfg80211_chandef_identical(&ctx
->conf
.def
, chandef
))
153 WARN_ON(!cfg80211_chandef_compatible(&ctx
->conf
.def
, chandef
));
155 ctx
->conf
.def
= *chandef
;
156 drv_change_chanctx(local
, ctx
, IEEE80211_CHANCTX_CHANGE_WIDTH
);
157 ieee80211_recalc_chanctx_min_def(local
, ctx
);
159 if (!local
->use_chanctx
) {
160 local
->_oper_chandef
= *chandef
;
161 ieee80211_hw_config(local
, 0);
165 static struct ieee80211_chanctx
*
166 ieee80211_find_chanctx(struct ieee80211_local
*local
,
167 const struct cfg80211_chan_def
*chandef
,
168 enum ieee80211_chanctx_mode mode
)
170 struct ieee80211_chanctx
*ctx
;
172 lockdep_assert_held(&local
->chanctx_mtx
);
174 if (mode
== IEEE80211_CHANCTX_EXCLUSIVE
)
177 list_for_each_entry(ctx
, &local
->chanctx_list
, list
) {
178 const struct cfg80211_chan_def
*compat
;
180 if (ctx
->mode
== IEEE80211_CHANCTX_EXCLUSIVE
)
183 compat
= cfg80211_chandef_compatible(&ctx
->conf
.def
, chandef
);
187 ieee80211_change_chanctx(local
, ctx
, compat
);
195 static bool ieee80211_is_radar_required(struct ieee80211_local
*local
)
197 struct ieee80211_sub_if_data
*sdata
;
200 list_for_each_entry_rcu(sdata
, &local
->interfaces
, list
) {
201 if (sdata
->radar_required
) {
211 static struct ieee80211_chanctx
*
212 ieee80211_new_chanctx(struct ieee80211_local
*local
,
213 const struct cfg80211_chan_def
*chandef
,
214 enum ieee80211_chanctx_mode mode
)
216 struct ieee80211_chanctx
*ctx
;
220 lockdep_assert_held(&local
->chanctx_mtx
);
222 ctx
= kzalloc(sizeof(*ctx
) + local
->hw
.chanctx_data_size
, GFP_KERNEL
);
224 return ERR_PTR(-ENOMEM
);
226 ctx
->conf
.def
= *chandef
;
227 ctx
->conf
.rx_chains_static
= 1;
228 ctx
->conf
.rx_chains_dynamic
= 1;
230 ctx
->conf
.radar_enabled
= ieee80211_is_radar_required(local
);
231 ieee80211_recalc_chanctx_min_def(local
, ctx
);
232 if (!local
->use_chanctx
)
233 local
->hw
.conf
.radar_enabled
= ctx
->conf
.radar_enabled
;
235 /* we hold the mutex to prevent idle from changing */
236 lockdep_assert_held(&local
->mtx
);
237 /* turn idle off *before* setting channel -- some drivers need that */
238 changed
= ieee80211_idle_off(local
);
240 ieee80211_hw_config(local
, changed
);
242 if (!local
->use_chanctx
) {
243 local
->_oper_chandef
= *chandef
;
244 ieee80211_hw_config(local
, 0);
246 err
= drv_add_chanctx(local
, ctx
);
249 ieee80211_recalc_idle(local
);
254 /* and keep the mutex held until the new chanctx is on the list */
255 list_add_rcu(&ctx
->list
, &local
->chanctx_list
);
260 static void ieee80211_free_chanctx(struct ieee80211_local
*local
,
261 struct ieee80211_chanctx
*ctx
)
263 bool check_single_channel
= false;
264 lockdep_assert_held(&local
->chanctx_mtx
);
266 WARN_ON_ONCE(ctx
->refcount
!= 0);
268 if (!local
->use_chanctx
) {
269 struct cfg80211_chan_def
*chandef
= &local
->_oper_chandef
;
270 chandef
->width
= NL80211_CHAN_WIDTH_20_NOHT
;
271 chandef
->center_freq1
= chandef
->chan
->center_freq
;
272 chandef
->center_freq2
= 0;
274 /* NOTE: Disabling radar is only valid here for
275 * single channel context. To be sure, check it ...
277 if (local
->hw
.conf
.radar_enabled
)
278 check_single_channel
= true;
279 local
->hw
.conf
.radar_enabled
= false;
281 ieee80211_hw_config(local
, 0);
283 drv_remove_chanctx(local
, ctx
);
286 list_del_rcu(&ctx
->list
);
287 kfree_rcu(ctx
, rcu_head
);
289 /* throw a warning if this wasn't the only channel context. */
290 WARN_ON(check_single_channel
&& !list_empty(&local
->chanctx_list
));
292 ieee80211_recalc_idle(local
);
295 static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data
*sdata
,
296 struct ieee80211_chanctx
*ctx
)
298 struct ieee80211_local
*local
= sdata
->local
;
301 lockdep_assert_held(&local
->chanctx_mtx
);
303 ret
= drv_assign_vif_chanctx(local
, sdata
, ctx
);
307 rcu_assign_pointer(sdata
->vif
.chanctx_conf
, &ctx
->conf
);
310 ieee80211_recalc_txpower(sdata
);
311 ieee80211_recalc_chanctx_min_def(local
, ctx
);
312 sdata
->vif
.bss_conf
.idle
= false;
314 if (sdata
->vif
.type
!= NL80211_IFTYPE_P2P_DEVICE
&&
315 sdata
->vif
.type
!= NL80211_IFTYPE_MONITOR
)
316 ieee80211_bss_info_change_notify(sdata
, BSS_CHANGED_IDLE
);
321 static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local
*local
,
322 struct ieee80211_chanctx
*ctx
)
324 struct ieee80211_chanctx_conf
*conf
= &ctx
->conf
;
325 struct ieee80211_sub_if_data
*sdata
;
326 const struct cfg80211_chan_def
*compat
= NULL
;
328 lockdep_assert_held(&local
->chanctx_mtx
);
331 list_for_each_entry_rcu(sdata
, &local
->interfaces
, list
) {
333 if (!ieee80211_sdata_running(sdata
))
335 if (rcu_access_pointer(sdata
->vif
.chanctx_conf
) != conf
)
339 compat
= &sdata
->vif
.bss_conf
.chandef
;
341 compat
= cfg80211_chandef_compatible(
342 &sdata
->vif
.bss_conf
.chandef
, compat
);
348 if (WARN_ON_ONCE(!compat
))
351 ieee80211_change_chanctx(local
, ctx
, compat
);
354 static void ieee80211_recalc_radar_chanctx(struct ieee80211_local
*local
,
355 struct ieee80211_chanctx
*chanctx
)
359 lockdep_assert_held(&local
->chanctx_mtx
);
360 /* for setting local->radar_detect_enabled */
361 lockdep_assert_held(&local
->mtx
);
363 radar_enabled
= ieee80211_is_radar_required(local
);
365 if (radar_enabled
== chanctx
->conf
.radar_enabled
)
368 chanctx
->conf
.radar_enabled
= radar_enabled
;
369 local
->radar_detect_enabled
= chanctx
->conf
.radar_enabled
;
371 if (!local
->use_chanctx
) {
372 local
->hw
.conf
.radar_enabled
= chanctx
->conf
.radar_enabled
;
373 ieee80211_hw_config(local
, IEEE80211_CONF_CHANGE_CHANNEL
);
376 drv_change_chanctx(local
, chanctx
, IEEE80211_CHANCTX_CHANGE_RADAR
);
379 static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data
*sdata
,
380 struct ieee80211_chanctx
*ctx
)
382 struct ieee80211_local
*local
= sdata
->local
;
384 lockdep_assert_held(&local
->chanctx_mtx
);
387 rcu_assign_pointer(sdata
->vif
.chanctx_conf
, NULL
);
389 sdata
->vif
.bss_conf
.idle
= true;
391 if (sdata
->vif
.type
!= NL80211_IFTYPE_P2P_DEVICE
&&
392 sdata
->vif
.type
!= NL80211_IFTYPE_MONITOR
)
393 ieee80211_bss_info_change_notify(sdata
, BSS_CHANGED_IDLE
);
395 drv_unassign_vif_chanctx(local
, sdata
, ctx
);
397 if (ctx
->refcount
> 0) {
398 ieee80211_recalc_chanctx_chantype(sdata
->local
, ctx
);
399 ieee80211_recalc_smps_chanctx(local
, ctx
);
400 ieee80211_recalc_radar_chanctx(local
, ctx
);
401 ieee80211_recalc_chanctx_min_def(local
, ctx
);
405 static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data
*sdata
)
407 struct ieee80211_local
*local
= sdata
->local
;
408 struct ieee80211_chanctx_conf
*conf
;
409 struct ieee80211_chanctx
*ctx
;
411 lockdep_assert_held(&local
->chanctx_mtx
);
413 conf
= rcu_dereference_protected(sdata
->vif
.chanctx_conf
,
414 lockdep_is_held(&local
->chanctx_mtx
));
418 ctx
= container_of(conf
, struct ieee80211_chanctx
, conf
);
420 ieee80211_unassign_vif_chanctx(sdata
, ctx
);
421 if (ctx
->refcount
== 0)
422 ieee80211_free_chanctx(local
, ctx
);
425 void ieee80211_recalc_smps_chanctx(struct ieee80211_local
*local
,
426 struct ieee80211_chanctx
*chanctx
)
428 struct ieee80211_sub_if_data
*sdata
;
429 u8 rx_chains_static
, rx_chains_dynamic
;
431 lockdep_assert_held(&local
->chanctx_mtx
);
433 rx_chains_static
= 1;
434 rx_chains_dynamic
= 1;
437 list_for_each_entry_rcu(sdata
, &local
->interfaces
, list
) {
438 u8 needed_static
, needed_dynamic
;
440 if (!ieee80211_sdata_running(sdata
))
443 if (rcu_access_pointer(sdata
->vif
.chanctx_conf
) !=
447 switch (sdata
->vif
.type
) {
448 case NL80211_IFTYPE_P2P_DEVICE
:
450 case NL80211_IFTYPE_STATION
:
451 if (!sdata
->u
.mgd
.associated
)
454 case NL80211_IFTYPE_AP_VLAN
:
456 case NL80211_IFTYPE_AP
:
457 case NL80211_IFTYPE_ADHOC
:
458 case NL80211_IFTYPE_WDS
:
459 case NL80211_IFTYPE_MESH_POINT
:
465 switch (sdata
->smps_mode
) {
467 WARN_ONCE(1, "Invalid SMPS mode %d\n",
470 case IEEE80211_SMPS_OFF
:
471 needed_static
= sdata
->needed_rx_chains
;
472 needed_dynamic
= sdata
->needed_rx_chains
;
474 case IEEE80211_SMPS_DYNAMIC
:
476 needed_dynamic
= sdata
->needed_rx_chains
;
478 case IEEE80211_SMPS_STATIC
:
484 rx_chains_static
= max(rx_chains_static
, needed_static
);
485 rx_chains_dynamic
= max(rx_chains_dynamic
, needed_dynamic
);
489 if (!local
->use_chanctx
) {
490 if (rx_chains_static
> 1)
491 local
->smps_mode
= IEEE80211_SMPS_OFF
;
492 else if (rx_chains_dynamic
> 1)
493 local
->smps_mode
= IEEE80211_SMPS_DYNAMIC
;
495 local
->smps_mode
= IEEE80211_SMPS_STATIC
;
496 ieee80211_hw_config(local
, 0);
499 if (rx_chains_static
== chanctx
->conf
.rx_chains_static
&&
500 rx_chains_dynamic
== chanctx
->conf
.rx_chains_dynamic
)
503 chanctx
->conf
.rx_chains_static
= rx_chains_static
;
504 chanctx
->conf
.rx_chains_dynamic
= rx_chains_dynamic
;
505 drv_change_chanctx(local
, chanctx
, IEEE80211_CHANCTX_CHANGE_RX_CHAINS
);
508 int ieee80211_vif_use_channel(struct ieee80211_sub_if_data
*sdata
,
509 const struct cfg80211_chan_def
*chandef
,
510 enum ieee80211_chanctx_mode mode
)
512 struct ieee80211_local
*local
= sdata
->local
;
513 struct ieee80211_chanctx
*ctx
;
516 lockdep_assert_held(&local
->mtx
);
518 WARN_ON(sdata
->dev
&& netif_carrier_ok(sdata
->dev
));
520 mutex_lock(&local
->chanctx_mtx
);
521 __ieee80211_vif_release_channel(sdata
);
523 ctx
= ieee80211_find_chanctx(local
, chandef
, mode
);
525 ctx
= ieee80211_new_chanctx(local
, chandef
, mode
);
531 sdata
->vif
.bss_conf
.chandef
= *chandef
;
533 ret
= ieee80211_assign_vif_chanctx(sdata
, ctx
);
535 /* if assign fails refcount stays the same */
536 if (ctx
->refcount
== 0)
537 ieee80211_free_chanctx(local
, ctx
);
541 ieee80211_recalc_smps_chanctx(local
, ctx
);
542 ieee80211_recalc_radar_chanctx(local
, ctx
);
544 mutex_unlock(&local
->chanctx_mtx
);
548 int ieee80211_vif_change_channel(struct ieee80211_sub_if_data
*sdata
,
551 struct ieee80211_local
*local
= sdata
->local
;
552 struct ieee80211_chanctx_conf
*conf
;
553 struct ieee80211_chanctx
*ctx
;
554 const struct cfg80211_chan_def
*chandef
= &sdata
->csa_chandef
;
556 u32 chanctx_changed
= 0;
558 lockdep_assert_held(&local
->mtx
);
560 /* should never be called if not performing a channel switch. */
561 if (WARN_ON(!sdata
->vif
.csa_active
))
564 if (!cfg80211_chandef_usable(sdata
->local
->hw
.wiphy
, chandef
,
565 IEEE80211_CHAN_DISABLED
))
568 mutex_lock(&local
->chanctx_mtx
);
569 conf
= rcu_dereference_protected(sdata
->vif
.chanctx_conf
,
570 lockdep_is_held(&local
->chanctx_mtx
));
576 ctx
= container_of(conf
, struct ieee80211_chanctx
, conf
);
577 if (ctx
->refcount
!= 1) {
582 if (sdata
->vif
.bss_conf
.chandef
.width
!= chandef
->width
) {
583 chanctx_changed
= IEEE80211_CHANCTX_CHANGE_WIDTH
;
584 *changed
|= BSS_CHANGED_BANDWIDTH
;
587 sdata
->vif
.bss_conf
.chandef
= *chandef
;
588 ctx
->conf
.def
= *chandef
;
590 chanctx_changed
|= IEEE80211_CHANCTX_CHANGE_CHANNEL
;
591 drv_change_chanctx(local
, ctx
, chanctx_changed
);
593 ieee80211_recalc_chanctx_chantype(local
, ctx
);
594 ieee80211_recalc_smps_chanctx(local
, ctx
);
595 ieee80211_recalc_radar_chanctx(local
, ctx
);
596 ieee80211_recalc_chanctx_min_def(local
, ctx
);
600 mutex_unlock(&local
->chanctx_mtx
);
604 int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data
*sdata
,
605 const struct cfg80211_chan_def
*chandef
,
608 struct ieee80211_local
*local
= sdata
->local
;
609 struct ieee80211_chanctx_conf
*conf
;
610 struct ieee80211_chanctx
*ctx
;
613 if (!cfg80211_chandef_usable(sdata
->local
->hw
.wiphy
, chandef
,
614 IEEE80211_CHAN_DISABLED
))
617 mutex_lock(&local
->chanctx_mtx
);
618 if (cfg80211_chandef_identical(chandef
, &sdata
->vif
.bss_conf
.chandef
)) {
623 if (chandef
->width
== NL80211_CHAN_WIDTH_20_NOHT
||
624 sdata
->vif
.bss_conf
.chandef
.width
== NL80211_CHAN_WIDTH_20_NOHT
) {
629 conf
= rcu_dereference_protected(sdata
->vif
.chanctx_conf
,
630 lockdep_is_held(&local
->chanctx_mtx
));
636 ctx
= container_of(conf
, struct ieee80211_chanctx
, conf
);
637 if (!cfg80211_chandef_compatible(&conf
->def
, chandef
)) {
642 sdata
->vif
.bss_conf
.chandef
= *chandef
;
644 ieee80211_recalc_chanctx_chantype(local
, ctx
);
646 *changed
|= BSS_CHANGED_BANDWIDTH
;
649 mutex_unlock(&local
->chanctx_mtx
);
653 void ieee80211_vif_release_channel(struct ieee80211_sub_if_data
*sdata
)
655 WARN_ON(sdata
->dev
&& netif_carrier_ok(sdata
->dev
));
657 lockdep_assert_held(&sdata
->local
->mtx
);
659 mutex_lock(&sdata
->local
->chanctx_mtx
);
660 __ieee80211_vif_release_channel(sdata
);
661 mutex_unlock(&sdata
->local
->chanctx_mtx
);
664 void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data
*sdata
)
666 struct ieee80211_local
*local
= sdata
->local
;
667 struct ieee80211_sub_if_data
*ap
;
668 struct ieee80211_chanctx_conf
*conf
;
670 if (WARN_ON(sdata
->vif
.type
!= NL80211_IFTYPE_AP_VLAN
|| !sdata
->bss
))
673 ap
= container_of(sdata
->bss
, struct ieee80211_sub_if_data
, u
.ap
);
675 mutex_lock(&local
->chanctx_mtx
);
677 conf
= rcu_dereference_protected(ap
->vif
.chanctx_conf
,
678 lockdep_is_held(&local
->chanctx_mtx
));
679 rcu_assign_pointer(sdata
->vif
.chanctx_conf
, conf
);
680 mutex_unlock(&local
->chanctx_mtx
);
683 void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data
*sdata
,
686 struct ieee80211_local
*local
= sdata
->local
;
687 struct ieee80211_sub_if_data
*vlan
;
688 struct ieee80211_chanctx_conf
*conf
;
692 if (WARN_ON(sdata
->vif
.type
!= NL80211_IFTYPE_AP
))
695 mutex_lock(&local
->chanctx_mtx
);
698 * Check that conf exists, even when clearing this function
699 * must be called with the AP's channel context still there
700 * as it would otherwise cause VLANs to have an invalid
701 * channel context pointer for a while, possibly pointing
702 * to a channel context that has already been freed.
704 conf
= rcu_dereference_protected(sdata
->vif
.chanctx_conf
,
705 lockdep_is_held(&local
->chanctx_mtx
));
711 list_for_each_entry(vlan
, &sdata
->u
.ap
.vlans
, u
.vlan
.list
)
712 rcu_assign_pointer(vlan
->vif
.chanctx_conf
, conf
);
714 mutex_unlock(&local
->chanctx_mtx
);
717 void ieee80211_iter_chan_contexts_atomic(
718 struct ieee80211_hw
*hw
,
719 void (*iter
)(struct ieee80211_hw
*hw
,
720 struct ieee80211_chanctx_conf
*chanctx_conf
,
724 struct ieee80211_local
*local
= hw_to_local(hw
);
725 struct ieee80211_chanctx
*ctx
;
728 list_for_each_entry_rcu(ctx
, &local
->chanctx_list
, list
)
729 if (ctx
->driver_present
)
730 iter(hw
, &ctx
->conf
, iter_data
);
733 EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic
);