mac80211: stop toggling IEEE80211_HT_CAP_SUP_WIDTH_20_40

For VHT, many more bandwidth changes are possible. As a first
step, stop toggling the IEEE80211_HT_CAP_SUP_WIDTH_20_40 flag
in the HT capabilities and instead introduce a bandwidth field
indicating the currently usable bandwidth to transmit to the
station. Of course, make all drivers use it.

To achieve this, make ieee80211_ht_cap_ie_to_sta_ht_cap() get
the station as an argument, rather than the new capabilities,
so it can set up the new bandwidth field.

If the station is a VHT station and VHT bandwidth is in use,
also set the bandwidth accordingly.

Doing this allows us to get rid of the supports_40mhz flag as
the HT capabilities now reflect the true capability instead of
the current setting.

While at it, also fix ieee80211_ht_cap_ie_to_sta_ht_cap() to not
ignore HT cap overrides when MCS TX isn't supported (not that it
really happens...)

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg
2013-02-07 11:47:44 +01:00
parent 4a34215ef7
commit e1a0c6b3a4
27 changed files with 184 additions and 158 deletions

View File

@@ -219,19 +219,20 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
mutex_lock(&local->sta_mtx);
sta = sta_info_get(sdata, bssid);
WARN_ON_ONCE(!sta);
if (WARN_ON_ONCE(!sta)) {
mutex_unlock(&local->sta_mtx);
return changed;
}
if (sta && !sta->supports_40mhz)
if (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
disable_40 = true;
if (sta && (!reconfig ||
(disable_40 != !(sta->sta.ht_cap.cap &
IEEE80211_HT_CAP_SUP_WIDTH_20_40)))) {
if (!reconfig ||
disable_40 != (sta->sta.bandwidth < IEEE80211_STA_RX_BW_40)) {
if (disable_40)
sta->sta.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
sta->sta.bandwidth = IEEE80211_STA_RX_BW_20;
else
sta->sta.ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta);
rate_control_rate_update(local, sband, sta,
IEEE80211_RC_BW_CHANGED);
@@ -2210,10 +2211,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
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;
elems.ht_cap_elem, sta);
if (elems.vht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,