mac80211: assign VLAN channel contexts
Make AP_VLAN type interfaces track the AP master channel context so they have one assigned for the various lookups. Don't give them their own refcount etc. since they're just slaves to the AP master. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Родитель
2d4072a547
Коммит
4d76d21bd7
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <linux/nl80211.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include "ieee80211_i.h"
|
||||
#include "driver-ops.h"
|
||||
|
@ -197,6 +198,15 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
|
|||
|
||||
ctx = container_of(conf, struct ieee80211_chanctx, conf);
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
||||
struct ieee80211_sub_if_data *vlan;
|
||||
|
||||
/* for the VLAN list */
|
||||
ASSERT_RTNL();
|
||||
list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
|
||||
rcu_assign_pointer(vlan->vif.chanctx_conf, NULL);
|
||||
}
|
||||
|
||||
ieee80211_unassign_vif_chanctx(sdata, ctx);
|
||||
if (ctx->refcount == 0)
|
||||
ieee80211_free_chanctx(local, ctx);
|
||||
|
@ -316,6 +326,15 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
||||
struct ieee80211_sub_if_data *vlan;
|
||||
|
||||
/* for the VLAN list */
|
||||
ASSERT_RTNL();
|
||||
list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
|
||||
rcu_assign_pointer(vlan->vif.chanctx_conf, &ctx->conf);
|
||||
}
|
||||
|
||||
ieee80211_recalc_smps_chanctx(local, ctx);
|
||||
out:
|
||||
mutex_unlock(&local->chanctx_mtx);
|
||||
|
@ -331,6 +350,25 @@ void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
|
|||
mutex_unlock(&sdata->local->chanctx_mtx);
|
||||
}
|
||||
|
||||
void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_sub_if_data *ap;
|
||||
struct ieee80211_chanctx_conf *conf;
|
||||
|
||||
if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss))
|
||||
return;
|
||||
|
||||
ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
|
||||
|
||||
mutex_lock(&local->chanctx_mtx);
|
||||
|
||||
conf = rcu_dereference_protected(ap->vif.chanctx_conf,
|
||||
lockdep_is_held(&local->chanctx_mtx));
|
||||
rcu_assign_pointer(sdata->vif.chanctx_conf, conf);
|
||||
mutex_unlock(&local->chanctx_mtx);
|
||||
}
|
||||
|
||||
void ieee80211_iter_chan_contexts_atomic(
|
||||
struct ieee80211_hw *hw,
|
||||
void (*iter)(struct ieee80211_hw *hw,
|
||||
|
|
|
@ -1628,6 +1628,7 @@ ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
|
|||
const struct cfg80211_chan_def *chandef,
|
||||
enum ieee80211_chanctx_mode mode);
|
||||
void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata);
|
||||
|
||||
void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *chanctx);
|
||||
|
|
|
@ -586,11 +586,13 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
|
|||
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
/* no need to tell driver, but set carrier */
|
||||
if (rtnl_dereference(sdata->bss->beacon))
|
||||
/* no need to tell driver, but set carrier and chanctx */
|
||||
if (rtnl_dereference(sdata->bss->beacon)) {
|
||||
ieee80211_vif_vlan_copy_chanctx(sdata);
|
||||
netif_carrier_on(dev);
|
||||
else
|
||||
} else {
|
||||
netif_carrier_off(dev);
|
||||
}
|
||||
break;
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
|
||||
|
@ -839,6 +841,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
|||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
list_del(&sdata->u.vlan.list);
|
||||
rcu_assign_pointer(sdata->vif.chanctx_conf, NULL);
|
||||
/* no need to tell driver */
|
||||
break;
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
|
|
Загрузка…
Ссылка в новой задаче