aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/chan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/chan.c')
-rw-r--r--net/mac80211/chan.c38
1 files changed, 38 insertions, 0 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
353void 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
334void ieee80211_iter_chan_contexts_atomic( 372void 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,