summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-07-26 17:24:39 +0200
committerJohannes Berg <johannes.berg@intel.com>2012-10-17 11:02:09 +0200
commit55de908ab292c03f1eb280f51170ddb9c6b57e31 (patch)
treebc75bb5cea581cadf6fe8b4f121cce02d07c276a /net/mac80211/mesh.c
parentmac80211: track whether to use channel contexts (diff)
downloadlinux-55de908ab292c03f1eb280f51170ddb9c6b57e31.tar.xz
linux-55de908ab292c03f1eb280f51170ddb9c6b57e31.zip
mac80211: use channel contexts
Instead of operating on a single channel only, use the new channel context infrastructure in all mac80211 code. This enables drivers that want to use the new channel context infrastructure to use multiple channels, while nothing should change for all the other drivers that don't support it. Right now this disables both TX power settings and spatial multiplexing powersave. Both need to be re-enabled on a channel context basis. Additionally, when channel contexts are used drop the connection when channel switch is received rather than trying to handle it. This will have to be improved later. [With fixes from Eliad and Emmanuel incorporated] Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mesh.c')
-rw-r--r--net/mac80211/mesh.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index ff0296c7bab8..19725e0a051a 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -97,7 +97,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
(ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)))
goto mismatch;
- ieee80211_sta_get_rates(local, ie, local->oper_channel->band,
+ ieee80211_sta_get_rates(local, ie, ieee80211_get_sdata_band(sdata),
&basic_rates);
if (sdata->vif.bss_conf.basic_rates != basic_rates)
@@ -355,12 +355,22 @@ int mesh_add_ds_params_ie(struct sk_buff *skb,
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_supported_band *sband;
- struct ieee80211_channel *chan = local->oper_channel;
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ struct ieee80211_channel *chan;
u8 *pos;
if (skb_tailroom(skb) < 3)
return -ENOMEM;
+ rcu_read_lock();
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+ if (WARN_ON(!chanctx_conf)) {
+ rcu_read_unlock();
+ return -EINVAL;
+ }
+ chan = chanctx_conf->channel;
+ rcu_read_unlock();
+
sband = local->hw.wiphy->bands[chan->band];
if (sband->band == IEEE80211_BAND_2GHZ) {
pos = skb_put(skb, 2 + 1);
@@ -376,10 +386,11 @@ int mesh_add_ht_cap_ie(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
+ enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
struct ieee80211_supported_band *sband;
u8 *pos;
- sband = local->hw.wiphy->bands[local->oper_channel->band];
+ sband = local->hw.wiphy->bands[band];
if (!sband->ht_cap.ht_supported ||
sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT)
return 0;
@@ -397,14 +408,26 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
- struct ieee80211_channel *channel = local->oper_channel;
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ struct ieee80211_channel *channel;
enum nl80211_channel_type channel_type =
- sdata->vif.bss_conf.channel_type;
- struct ieee80211_supported_band *sband =
- local->hw.wiphy->bands[channel->band];
- struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap;
+ sdata->vif.bss_conf.channel_type;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_sta_ht_cap *ht_cap;
u8 *pos;
+ rcu_read_lock();
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+ if (WARN_ON(!chanctx_conf)) {
+ rcu_read_unlock();
+ return -EINVAL;
+ }
+ channel = chanctx_conf->channel;
+ rcu_read_unlock();
+
+ sband = local->hw.wiphy->bands[channel->band];
+ ht_cap = &sband->ht_cap;
+
if (!ht_cap->ht_supported || channel_type == NL80211_CHAN_NO_HT)
return 0;
@@ -610,7 +633,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL;
sdata->vif.bss_conf.basic_rates =
ieee80211_mandatory_rates(sdata->local,
- sdata->local->oper_channel->band);
+ ieee80211_get_sdata_band(sdata));
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
BSS_CHANGED_BEACON_ENABLED |
BSS_CHANGED_HT |