aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-03-28 10:58:37 +0200
committerJohn W. Linville <linville@tuxdriver.com>2012-04-10 14:54:08 -0400
commit64f68e5d15bee47e0d6d0c57a1cf52cedd9b3527 (patch)
treee000cea46fd57d876d725224d2b51b74cec35572 /net/mac80211/mlme.c
parentmac80211: set HT channel before association (diff)
downloadlinux-dev-64f68e5d15bee47e0d6d0c57a1cf52cedd9b3527.tar.xz
linux-dev-64f68e5d15bee47e0d6d0c57a1cf52cedd9b3527.zip
mac80211: remove channel type argument from rate_update
The channel type argument to the rate_update() callback isn't really the correct way to give the rate control algorithm about the desired RX bandwidth of the peer. Remove this argument, and instead update the STA capabilities with 20/40 appropriately. The SMPS update done by this callback works in the same way, so this makes the callback cleaner. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 30259a73195c..9cc5dda68219 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -180,21 +180,38 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta;
u32 changed = 0;
u16 ht_opmode;
- enum nl80211_channel_type channel_type;
+ bool disable_40 = false;
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
- channel_type = local->hw.conf.channel_type;
- if (WARN_ON_ONCE(channel_type == NL80211_CHAN_NO_HT))
- return 0;
-
- channel_type = ieee80211_get_tx_channel_type(local, channel_type);
+ switch (sdata->vif.bss_conf.channel_type) {
+ case NL80211_CHAN_HT40PLUS:
+ if (local->hw.conf.channel->flags & IEEE80211_CHAN_NO_HT40PLUS)
+ disable_40 = true;
+ break;
+ case NL80211_CHAN_HT40MINUS:
+ if (local->hw.conf.channel->flags & IEEE80211_CHAN_NO_HT40MINUS)
+ disable_40 = true;
+ break;
+ default:
+ break;
+ }
/* This can change during the lifetime of the BSS */
if (!(ht_oper->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
- channel_type = NL80211_CHAN_HT20;
+ disable_40 = true;
- if (!reconfig || (sdata->u.mgd.tx_chantype != channel_type)) {
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get(sdata, bssid);
+
+ WARN_ON_ONCE(!sta);
+
+ if (sta && !sta->supports_40mhz)
+ disable_40 = true;
+
+ if (sta && (!reconfig ||
+ (disable_40 != !!(sta->sta.ht_cap.cap &
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40)))) {
if (reconfig) {
/*
* Whenever the AP announces the HT mode changed
@@ -211,20 +228,19 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
drv_flush(local, false);
}
- rcu_read_lock();
- sta = sta_info_get(sdata, bssid);
- if (sta)
- rate_control_rate_update(local, sband, sta,
- IEEE80211_RC_HT_CHANGED,
- channel_type);
- rcu_read_unlock();
+ if (disable_40)
+ sta->sta.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ else
+ sta->sta.ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
- sdata->u.mgd.tx_chantype = channel_type;
+ rate_control_rate_update(local, sband, sta,
+ IEEE80211_RC_HT_CHANGED);
if (reconfig)
ieee80211_wake_queues_by_reason(&sdata->local->hw,
IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
}
+ mutex_unlock(&local->sta_mtx);
ht_opmode = le16_to_cpu(ht_oper->operation_mode);
@@ -2006,6 +2022,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
elems.ht_cap_elem, &sta->sta.ht_cap);
+ sta->supports_40mhz =
+ sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
rate_control_rate_init(sta);
if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED)