diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-02-07 05:47:44 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-02-15 03:41:30 -0500 |
commit | e1a0c6b3a4b27ed5f21291d0bbee2167ec201ef5 (patch) | |
tree | 18e5c9bd022ea469e7350a52ca67ce505a7608e6 /net/mac80211/vht.c | |
parent | 4a34215ef7487b1cbd783e7cc485eb03de893bd0 (diff) |
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>
Diffstat (limited to 'net/mac80211/vht.c')
-rw-r--r-- | net/mac80211/vht.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index 1606aa165d5f..0fc9a2fb8d53 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c | |||
@@ -27,6 +27,10 @@ void ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, | |||
27 | if (!vht_cap_ie || !sband->vht_cap.vht_supported) | 27 | if (!vht_cap_ie || !sband->vht_cap.vht_supported) |
28 | return; | 28 | return; |
29 | 29 | ||
30 | /* A VHT STA must support 40 MHz */ | ||
31 | if (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) | ||
32 | return; | ||
33 | |||
30 | vht_cap->vht_supported = true; | 34 | vht_cap->vht_supported = true; |
31 | 35 | ||
32 | vht_cap->cap = le32_to_cpu(vht_cap_ie->vht_cap_info); | 36 | vht_cap->cap = le32_to_cpu(vht_cap_ie->vht_cap_info); |
@@ -34,4 +38,39 @@ void ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, | |||
34 | /* Copy peer MCS info, the driver might need them. */ | 38 | /* Copy peer MCS info, the driver might need them. */ |
35 | memcpy(&vht_cap->vht_mcs, &vht_cap_ie->supp_mcs, | 39 | memcpy(&vht_cap->vht_mcs, &vht_cap_ie->supp_mcs, |
36 | sizeof(struct ieee80211_vht_mcs_info)); | 40 | sizeof(struct ieee80211_vht_mcs_info)); |
41 | |||
42 | sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta); | ||
43 | } | ||
44 | |||
45 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta) | ||
46 | { | ||
47 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
48 | u32 cap = sta->sta.vht_cap.cap; | ||
49 | |||
50 | if (!sta->sta.vht_cap.vht_supported) | ||
51 | return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? | ||
52 | IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20; | ||
53 | |||
54 | /* TODO: handle VHT opmode notification data */ | ||
55 | |||
56 | switch (sdata->vif.bss_conf.chandef.width) { | ||
57 | default: | ||
58 | WARN_ON_ONCE(1); | ||
59 | /* fall through */ | ||
60 | case NL80211_CHAN_WIDTH_20_NOHT: | ||
61 | case NL80211_CHAN_WIDTH_20: | ||
62 | case NL80211_CHAN_WIDTH_40: | ||
63 | return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? | ||
64 | IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20; | ||
65 | case NL80211_CHAN_WIDTH_160: | ||
66 | if (cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ) | ||
67 | return IEEE80211_STA_RX_BW_160; | ||
68 | /* fall through */ | ||
69 | case NL80211_CHAN_WIDTH_80P80: | ||
70 | if (cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) | ||
71 | return IEEE80211_STA_RX_BW_160; | ||
72 | /* fall through */ | ||
73 | case NL80211_CHAN_WIDTH_80: | ||
74 | return IEEE80211_STA_RX_BW_80; | ||
75 | } | ||
37 | } | 76 | } |