diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/chan.c | 38 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/iface.c | 9 |
3 files changed, 45 insertions, 3 deletions
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 53f03120db55..80e55527504b 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | #include <linux/nl80211.h> | 5 | #include <linux/nl80211.h> |
6 | #include <linux/export.h> | 6 | #include <linux/export.h> |
7 | #include <linux/rtnetlink.h> | ||
7 | #include <net/cfg80211.h> | 8 | #include <net/cfg80211.h> |
8 | #include "ieee80211_i.h" | 9 | #include "ieee80211_i.h" |
9 | #include "driver-ops.h" | 10 | #include "driver-ops.h" |
@@ -197,6 +198,15 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) | |||
197 | 198 | ||
198 | ctx = container_of(conf, struct ieee80211_chanctx, conf); | 199 | ctx = container_of(conf, struct ieee80211_chanctx, conf); |
199 | 200 | ||
201 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
202 | struct ieee80211_sub_if_data *vlan; | ||
203 | |||
204 | /* for the VLAN list */ | ||
205 | ASSERT_RTNL(); | ||
206 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | ||
207 | rcu_assign_pointer(vlan->vif.chanctx_conf, NULL); | ||
208 | } | ||
209 | |||
200 | ieee80211_unassign_vif_chanctx(sdata, ctx); | 210 | ieee80211_unassign_vif_chanctx(sdata, ctx); |
201 | if (ctx->refcount == 0) | 211 | if (ctx->refcount == 0) |
202 | ieee80211_free_chanctx(local, ctx); | 212 | ieee80211_free_chanctx(local, ctx); |
@@ -316,6 +326,15 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | |||
316 | goto out; | 326 | goto out; |
317 | } | 327 | } |
318 | 328 | ||
329 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
330 | struct ieee80211_sub_if_data *vlan; | ||
331 | |||
332 | /* for the VLAN list */ | ||
333 | ASSERT_RTNL(); | ||
334 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | ||
335 | rcu_assign_pointer(vlan->vif.chanctx_conf, &ctx->conf); | ||
336 | } | ||
337 | |||
319 | ieee80211_recalc_smps_chanctx(local, ctx); | 338 | ieee80211_recalc_smps_chanctx(local, ctx); |
320 | out: | 339 | out: |
321 | mutex_unlock(&local->chanctx_mtx); | 340 | mutex_unlock(&local->chanctx_mtx); |
@@ -331,6 +350,25 @@ void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) | |||
331 | mutex_unlock(&sdata->local->chanctx_mtx); | 350 | mutex_unlock(&sdata->local->chanctx_mtx); |
332 | } | 351 | } |
333 | 352 | ||
353 | void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata) | ||
354 | { | ||
355 | struct ieee80211_local *local = sdata->local; | ||
356 | struct ieee80211_sub_if_data *ap; | ||
357 | struct ieee80211_chanctx_conf *conf; | ||
358 | |||
359 | if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss)) | ||
360 | return; | ||
361 | |||
362 | ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); | ||
363 | |||
364 | mutex_lock(&local->chanctx_mtx); | ||
365 | |||
366 | conf = rcu_dereference_protected(ap->vif.chanctx_conf, | ||
367 | lockdep_is_held(&local->chanctx_mtx)); | ||
368 | rcu_assign_pointer(sdata->vif.chanctx_conf, conf); | ||
369 | mutex_unlock(&local->chanctx_mtx); | ||
370 | } | ||
371 | |||
334 | void ieee80211_iter_chan_contexts_atomic( | 372 | void ieee80211_iter_chan_contexts_atomic( |
335 | struct ieee80211_hw *hw, | 373 | struct ieee80211_hw *hw, |
336 | void (*iter)(struct ieee80211_hw *hw, | 374 | void (*iter)(struct ieee80211_hw *hw, |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 112bb6192399..28fc9875537c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1628,6 +1628,7 @@ ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | |||
1628 | const struct cfg80211_chan_def *chandef, | 1628 | const struct cfg80211_chan_def *chandef, |
1629 | enum ieee80211_chanctx_mode mode); | 1629 | enum ieee80211_chanctx_mode mode); |
1630 | void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); | 1630 | void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); |
1631 | void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata); | ||
1631 | 1632 | ||
1632 | void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, | 1633 | void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, |
1633 | struct ieee80211_chanctx *chanctx); | 1634 | struct ieee80211_chanctx *chanctx); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 09a80b55cf5a..54fb7f9db564 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -586,11 +586,13 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
586 | 586 | ||
587 | switch (sdata->vif.type) { | 587 | switch (sdata->vif.type) { |
588 | case NL80211_IFTYPE_AP_VLAN: | 588 | case NL80211_IFTYPE_AP_VLAN: |
589 | /* no need to tell driver, but set carrier */ | 589 | /* no need to tell driver, but set carrier and chanctx */ |
590 | if (rtnl_dereference(sdata->bss->beacon)) | 590 | if (rtnl_dereference(sdata->bss->beacon)) { |
591 | ieee80211_vif_vlan_copy_chanctx(sdata); | ||
591 | netif_carrier_on(dev); | 592 | netif_carrier_on(dev); |
592 | else | 593 | } else { |
593 | netif_carrier_off(dev); | 594 | netif_carrier_off(dev); |
595 | } | ||
594 | break; | 596 | break; |
595 | case NL80211_IFTYPE_MONITOR: | 597 | case NL80211_IFTYPE_MONITOR: |
596 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { | 598 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { |
@@ -839,6 +841,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
839 | switch (sdata->vif.type) { | 841 | switch (sdata->vif.type) { |
840 | case NL80211_IFTYPE_AP_VLAN: | 842 | case NL80211_IFTYPE_AP_VLAN: |
841 | list_del(&sdata->u.vlan.list); | 843 | list_del(&sdata->u.vlan.list); |
844 | rcu_assign_pointer(sdata->vif.chanctx_conf, NULL); | ||
842 | /* no need to tell driver */ | 845 | /* no need to tell driver */ |
843 | break; | 846 | break; |
844 | case NL80211_IFTYPE_MONITOR: | 847 | case NL80211_IFTYPE_MONITOR: |