diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-10-09 06:13:49 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-10-31 19:00:06 -0400 |
commit | d9fe60dea7779d412b34679f1177c5ca1940ea8d (patch) | |
tree | a51e16b013f7c1d16ded502cb32c03872bcbfcaa /net | |
parent | 40333e4fb476014cdd939d27e20eb54573172b32 (diff) |
802.11: clean up/fix HT support
This patch cleans up a number of things:
* the unusable definition of the HT capabilities/HT information
information elements
* variable names that are hard to understand
* mac80211: move ieee80211_handle_ht to ht.c and remove the unused
enable_ht parameter
* mac80211: fix bug with MCS rate 32 in ieee80211_handle_ht
* mac80211: fix bug with casting the result of ieee80211_bss_get_ie
to an information element _contents_ rather than the
whole element, add size checking (another out-of-bounds
access bug fixed!)
* mac80211: remove some unused return values in favour of BUG_ON
checking
* a few minor other things
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 7 | ||||
-rw-r--r-- | net/mac80211/ht.c | 151 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 16 | ||||
-rw-r--r-- | net/mac80211/main.c | 94 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 45 | ||||
-rw-r--r-- | net/mac80211/util.c | 4 | ||||
-rw-r--r-- | net/mac80211/wext.c | 4 |
7 files changed, 167 insertions, 154 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index cf3fd5d60665..a5dea617aab3 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -633,10 +633,9 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
633 | sta->sta.supp_rates[local->oper_channel->band] = rates; | 633 | sta->sta.supp_rates[local->oper_channel->band] = rates; |
634 | } | 634 | } |
635 | 635 | ||
636 | if (params->ht_capa) { | 636 | if (params->ht_capa) |
637 | ieee80211_ht_cap_ie_to_ht_info(params->ht_capa, | 637 | ieee80211_ht_cap_ie_to_sta_ht_cap(params->ht_capa, |
638 | &sta->sta.ht_info); | 638 | &sta->sta.ht_cap); |
639 | } | ||
640 | 639 | ||
641 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { | 640 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { |
642 | switch (params->plink_action) { | 641 | switch (params->plink_action) { |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index b854483cf23f..e2d121bf2745 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -20,37 +20,33 @@ | |||
20 | #include "sta_info.h" | 20 | #include "sta_info.h" |
21 | #include "wme.h" | 21 | #include "wme.h" |
22 | 22 | ||
23 | int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, | 23 | void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_ht_cap *ht_cap_ie, |
24 | struct ieee80211_ht_info *ht_info) | 24 | struct ieee80211_sta_ht_cap *ht_cap) |
25 | { | 25 | { |
26 | 26 | ||
27 | if (ht_info == NULL) | 27 | BUG_ON(!ht_cap); |
28 | return -EINVAL; | ||
29 | 28 | ||
30 | memset(ht_info, 0, sizeof(*ht_info)); | 29 | memset(ht_cap, 0, sizeof(*ht_cap)); |
31 | 30 | ||
32 | if (ht_cap_ie) { | 31 | if (ht_cap_ie) { |
33 | u8 ampdu_info = ht_cap_ie->ampdu_params_info; | 32 | u8 ampdu_info = ht_cap_ie->ampdu_params_info; |
34 | 33 | ||
35 | ht_info->ht_supported = 1; | 34 | ht_cap->ht_supported = true; |
36 | ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info); | 35 | ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info); |
37 | ht_info->ampdu_factor = | 36 | ht_cap->ampdu_factor = |
38 | ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR; | 37 | ampdu_info & IEEE80211_HT_AMPDU_PARM_FACTOR; |
39 | ht_info->ampdu_density = | 38 | ht_cap->ampdu_density = |
40 | (ampdu_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2; | 39 | (ampdu_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2; |
41 | memcpy(ht_info->supp_mcs_set, ht_cap_ie->supp_mcs_set, 16); | 40 | memcpy(&ht_cap->mcs, &ht_cap_ie->mcs, sizeof(ht_cap->mcs)); |
42 | } else | 41 | } else |
43 | ht_info->ht_supported = 0; | 42 | ht_cap->ht_supported = false; |
44 | |||
45 | return 0; | ||
46 | } | 43 | } |
47 | 44 | ||
48 | int ieee80211_ht_addt_info_ie_to_ht_bss_info( | 45 | void ieee80211_ht_info_ie_to_ht_bss_info( |
49 | struct ieee80211_ht_addt_info *ht_add_info_ie, | 46 | struct ieee80211_ht_info *ht_add_info_ie, |
50 | struct ieee80211_ht_bss_info *bss_info) | 47 | struct ieee80211_ht_bss_info *bss_info) |
51 | { | 48 | { |
52 | if (bss_info == NULL) | 49 | BUG_ON(!bss_info); |
53 | return -EINVAL; | ||
54 | 50 | ||
55 | memset(bss_info, 0, sizeof(*bss_info)); | 51 | memset(bss_info, 0, sizeof(*bss_info)); |
56 | 52 | ||
@@ -62,8 +58,119 @@ int ieee80211_ht_addt_info_ie_to_ht_bss_info( | |||
62 | bss_info->bss_cap = ht_add_info_ie->ht_param; | 58 | bss_info->bss_cap = ht_add_info_ie->ht_param; |
63 | bss_info->bss_op_mode = (u8)(op_mode & 0xff); | 59 | bss_info->bss_op_mode = (u8)(op_mode & 0xff); |
64 | } | 60 | } |
61 | } | ||
62 | |||
63 | /* | ||
64 | * ieee80211_handle_ht should be called only after the operating band | ||
65 | * has been determined as ht configuration depends on the hw's | ||
66 | * HT abilities for a specific band. | ||
67 | */ | ||
68 | u32 ieee80211_handle_ht(struct ieee80211_local *local, | ||
69 | struct ieee80211_sta_ht_cap *req_ht_cap, | ||
70 | struct ieee80211_ht_bss_info *req_bss_cap) | ||
71 | { | ||
72 | struct ieee80211_conf *conf = &local->hw.conf; | ||
73 | struct ieee80211_supported_band *sband; | ||
74 | struct ieee80211_sta_ht_cap ht_cap; | ||
75 | struct ieee80211_ht_bss_info ht_bss_conf; | ||
76 | u32 changed = 0; | ||
77 | int i; | ||
78 | u8 max_tx_streams; | ||
79 | u8 tx_mcs_set_cap; | ||
80 | bool enable_ht = true; | ||
81 | |||
82 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
83 | |||
84 | memset(&ht_cap, 0, sizeof(ht_cap)); | ||
85 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); | ||
86 | |||
87 | /* HT is not supported */ | ||
88 | if (!sband->ht_cap.ht_supported) | ||
89 | enable_ht = false; | ||
90 | |||
91 | /* disable HT */ | ||
92 | if (!enable_ht) { | ||
93 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | ||
94 | changed |= BSS_CHANGED_HT; | ||
95 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
96 | conf->ht_cap.ht_supported = false; | ||
97 | return changed; | ||
98 | } | ||
99 | |||
100 | |||
101 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) | ||
102 | changed |= BSS_CHANGED_HT; | ||
103 | |||
104 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | ||
105 | ht_cap.ht_supported = true; | ||
106 | |||
107 | ht_cap.cap = req_ht_cap->cap & sband->ht_cap.cap; | ||
108 | ht_cap.cap &= ~IEEE80211_HT_CAP_SM_PS; | ||
109 | ht_cap.cap |= sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS; | ||
110 | |||
111 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | ||
112 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | ||
113 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | ||
114 | |||
115 | ht_cap.ampdu_factor = req_ht_cap->ampdu_factor; | ||
116 | ht_cap.ampdu_density = req_ht_cap->ampdu_density; | ||
117 | |||
118 | /* own MCS TX capabilities */ | ||
119 | tx_mcs_set_cap = sband->ht_cap.mcs.tx_params; | ||
120 | |||
121 | /* | ||
122 | * configure supported Tx MCS according to requested MCS | ||
123 | * (based in most cases on Rx capabilities of peer) and self | ||
124 | * Tx MCS capabilities (as defined by low level driver HW | ||
125 | * Tx capabilities) | ||
126 | */ | ||
127 | |||
128 | /* can we TX with MCS rates? */ | ||
129 | if (!(tx_mcs_set_cap & IEEE80211_HT_MCS_TX_DEFINED)) | ||
130 | goto check_changed; | ||
131 | |||
132 | /* Counting from 0, therefore +1 */ | ||
133 | if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_RX_DIFF) | ||
134 | max_tx_streams = | ||
135 | ((tx_mcs_set_cap & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) | ||
136 | >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1; | ||
137 | else | ||
138 | max_tx_streams = IEEE80211_HT_MCS_TX_MAX_STREAMS; | ||
139 | |||
140 | /* | ||
141 | * 802.11n D5.0 20.3.5 / 20.6 says: | ||
142 | * - indices 0 to 7 and 32 are single spatial stream | ||
143 | * - 8 to 31 are multiple spatial streams using equal modulation | ||
144 | * [8..15 for two streams, 16..23 for three and 24..31 for four] | ||
145 | * - remainder are multiple spatial streams using unequal modulation | ||
146 | */ | ||
147 | for (i = 0; i < max_tx_streams; i++) | ||
148 | ht_cap.mcs.rx_mask[i] = | ||
149 | sband->ht_cap.mcs.rx_mask[i] & | ||
150 | req_ht_cap->mcs.rx_mask[i]; | ||
151 | |||
152 | if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION) | ||
153 | for (i = IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE; | ||
154 | i < IEEE80211_HT_MCS_MASK_LEN; i++) | ||
155 | ht_cap.mcs.rx_mask[i] = | ||
156 | sband->ht_cap.mcs.rx_mask[i] & | ||
157 | req_ht_cap->mcs.rx_mask[i]; | ||
158 | |||
159 | /* handle MCS rate 32 too */ | ||
160 | if (sband->ht_cap.mcs.rx_mask[32/8] & | ||
161 | req_ht_cap->mcs.rx_mask[32/8] & 1) | ||
162 | ht_cap.mcs.rx_mask[32/8] |= 1; | ||
163 | |||
164 | check_changed: | ||
165 | /* if bss configuration changed store the new one */ | ||
166 | if (memcmp(&conf->ht_cap, &ht_cap, sizeof(ht_cap)) || | ||
167 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | ||
168 | changed |= BSS_CHANGED_HT; | ||
169 | memcpy(&conf->ht_cap, &ht_cap, sizeof(ht_cap)); | ||
170 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | ||
171 | } | ||
65 | 172 | ||
66 | return 0; | 173 | return changed; |
67 | } | 174 | } |
68 | 175 | ||
69 | static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, | 176 | static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, |
@@ -794,7 +901,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
794 | * check if configuration can support the BA policy | 901 | * check if configuration can support the BA policy |
795 | * and if buffer size does not exceeds max value */ | 902 | * and if buffer size does not exceeds max value */ |
796 | if (((ba_policy != 1) | 903 | if (((ba_policy != 1) |
797 | && (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA))) | 904 | && (!(conf->ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) |
798 | || (buf_size > IEEE80211_MAX_AMPDU_BUF)) { | 905 | || (buf_size > IEEE80211_MAX_AMPDU_BUF)) { |
799 | status = WLAN_STATUS_INVALID_QOS_PARAM; | 906 | status = WLAN_STATUS_INVALID_QOS_PARAM; |
800 | #ifdef CONFIG_MAC80211_HT_DEBUG | 907 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -812,7 +919,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
812 | 919 | ||
813 | sband = local->hw.wiphy->bands[conf->channel->band]; | 920 | sband = local->hw.wiphy->bands[conf->channel->band]; |
814 | buf_size = IEEE80211_MIN_AMPDU_BUF; | 921 | buf_size = IEEE80211_MIN_AMPDU_BUF; |
815 | buf_size = buf_size << sband->ht_info.ampdu_factor; | 922 | buf_size = buf_size << sband->ht_cap.ampdu_factor; |
816 | } | 923 | } |
817 | 924 | ||
818 | 925 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f49cb9e8bb42..ae4ca3e8b443 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -817,7 +817,7 @@ struct ieee802_11_elems { | |||
817 | u8 *wmm_info; | 817 | u8 *wmm_info; |
818 | u8 *wmm_param; | 818 | u8 *wmm_param; |
819 | struct ieee80211_ht_cap *ht_cap_elem; | 819 | struct ieee80211_ht_cap *ht_cap_elem; |
820 | struct ieee80211_ht_addt_info *ht_info_elem; | 820 | struct ieee80211_ht_info *ht_info_elem; |
821 | u8 *mesh_config; | 821 | u8 *mesh_config; |
822 | u8 *mesh_id; | 822 | u8 *mesh_id; |
823 | u8 *peer_link; | 823 | u8 *peer_link; |
@@ -880,9 +880,6 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | |||
880 | int ieee80211_hw_config(struct ieee80211_local *local); | 880 | int ieee80211_hw_config(struct ieee80211_local *local); |
881 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); | 881 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); |
882 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); | 882 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); |
883 | u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | ||
884 | struct ieee80211_ht_info *req_ht_cap, | ||
885 | struct ieee80211_ht_bss_info *req_bss_cap); | ||
886 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 883 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
887 | u32 changed); | 884 | u32 changed); |
888 | void ieee80211_configure_filter(struct ieee80211_local *local); | 885 | void ieee80211_configure_filter(struct ieee80211_local *local); |
@@ -963,11 +960,14 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); | |||
963 | int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); | 960 | int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); |
964 | 961 | ||
965 | /* HT */ | 962 | /* HT */ |
966 | int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, | 963 | void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_ht_cap *ht_cap_ie, |
967 | struct ieee80211_ht_info *ht_info); | 964 | struct ieee80211_sta_ht_cap *ht_cap); |
968 | int ieee80211_ht_addt_info_ie_to_ht_bss_info( | 965 | void ieee80211_ht_info_ie_to_ht_bss_info( |
969 | struct ieee80211_ht_addt_info *ht_add_info_ie, | 966 | struct ieee80211_ht_info *ht_add_info_ie, |
970 | struct ieee80211_ht_bss_info *bss_info); | 967 | struct ieee80211_ht_bss_info *bss_info); |
968 | u32 ieee80211_handle_ht(struct ieee80211_local *local, | ||
969 | struct ieee80211_sta_ht_cap *req_ht_cap, | ||
970 | struct ieee80211_ht_bss_info *req_bss_cap); | ||
971 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); | 971 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); |
972 | 972 | ||
973 | void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, | 973 | void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c427954fe8e8..07f812755e55 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -232,100 +232,6 @@ int ieee80211_hw_config(struct ieee80211_local *local) | |||
232 | return ret; | 232 | return ret; |
233 | } | 233 | } |
234 | 234 | ||
235 | /** | ||
236 | * ieee80211_handle_ht should be used only after legacy configuration | ||
237 | * has been determined namely band, as ht configuration depends upon | ||
238 | * the hardware's HT abilities for a _specific_ band. | ||
239 | */ | ||
240 | u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | ||
241 | struct ieee80211_ht_info *req_ht_cap, | ||
242 | struct ieee80211_ht_bss_info *req_bss_cap) | ||
243 | { | ||
244 | struct ieee80211_conf *conf = &local->hw.conf; | ||
245 | struct ieee80211_supported_band *sband; | ||
246 | struct ieee80211_ht_info ht_conf; | ||
247 | struct ieee80211_ht_bss_info ht_bss_conf; | ||
248 | u32 changed = 0; | ||
249 | int i; | ||
250 | u8 max_tx_streams = IEEE80211_HT_CAP_MAX_STREAMS; | ||
251 | u8 tx_mcs_set_cap; | ||
252 | |||
253 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
254 | |||
255 | memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); | ||
256 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); | ||
257 | |||
258 | /* HT is not supported */ | ||
259 | if (!sband->ht_info.ht_supported) { | ||
260 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
261 | goto out; | ||
262 | } | ||
263 | |||
264 | /* disable HT */ | ||
265 | if (!enable_ht) { | ||
266 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | ||
267 | changed |= BSS_CHANGED_HT; | ||
268 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
269 | conf->ht_conf.ht_supported = 0; | ||
270 | goto out; | ||
271 | } | ||
272 | |||
273 | |||
274 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) | ||
275 | changed |= BSS_CHANGED_HT; | ||
276 | |||
277 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | ||
278 | ht_conf.ht_supported = 1; | ||
279 | |||
280 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; | ||
281 | ht_conf.cap &= ~(IEEE80211_HT_CAP_SM_PS); | ||
282 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_SM_PS; | ||
283 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | ||
284 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | ||
285 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | ||
286 | |||
287 | ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; | ||
288 | ht_conf.ampdu_density = req_ht_cap->ampdu_density; | ||
289 | |||
290 | /* Bits 96-100 */ | ||
291 | tx_mcs_set_cap = sband->ht_info.supp_mcs_set[12]; | ||
292 | |||
293 | /* configure suppoerted Tx MCS according to requested MCS | ||
294 | * (based in most cases on Rx capabilities of peer) and self | ||
295 | * Tx MCS capabilities (as defined by low level driver HW | ||
296 | * Tx capabilities) */ | ||
297 | if (!(tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_DEFINED)) | ||
298 | goto check_changed; | ||
299 | |||
300 | /* Counting from 0 therfore + 1 */ | ||
301 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_RX_DIFF) | ||
302 | max_tx_streams = ((tx_mcs_set_cap & | ||
303 | IEEE80211_HT_CAP_MCS_TX_STREAMS) >> 2) + 1; | ||
304 | |||
305 | for (i = 0; i < max_tx_streams; i++) | ||
306 | ht_conf.supp_mcs_set[i] = | ||
307 | sband->ht_info.supp_mcs_set[i] & | ||
308 | req_ht_cap->supp_mcs_set[i]; | ||
309 | |||
310 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_UEQM) | ||
311 | for (i = IEEE80211_SUPP_MCS_SET_UEQM; | ||
312 | i < IEEE80211_SUPP_MCS_SET_LEN; i++) | ||
313 | ht_conf.supp_mcs_set[i] = | ||
314 | sband->ht_info.supp_mcs_set[i] & | ||
315 | req_ht_cap->supp_mcs_set[i]; | ||
316 | |||
317 | check_changed: | ||
318 | /* if bss configuration changed store the new one */ | ||
319 | if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || | ||
320 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | ||
321 | changed |= BSS_CHANGED_HT; | ||
322 | memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); | ||
323 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | ||
324 | } | ||
325 | out: | ||
326 | return changed; | ||
327 | } | ||
328 | |||
329 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 235 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
330 | u32 changed) | 236 | u32 changed) |
331 | { | 237 | { |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 829995e740a7..196dd39f6286 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -236,7 +236,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
236 | struct ieee80211_local *local = sdata->local; | 236 | struct ieee80211_local *local = sdata->local; |
237 | struct sk_buff *skb; | 237 | struct sk_buff *skb; |
238 | struct ieee80211_mgmt *mgmt; | 238 | struct ieee80211_mgmt *mgmt; |
239 | u8 *pos, *ies, *ht_add_ie; | 239 | u8 *pos, *ies, *ht_ie; |
240 | int i, len, count, rates_len, supp_rates_len; | 240 | int i, len, count, rates_len, supp_rates_len; |
241 | u16 capab; | 241 | u16 capab; |
242 | struct ieee80211_bss *bss; | 242 | struct ieee80211_bss *bss; |
@@ -393,24 +393,25 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
393 | 393 | ||
394 | /* wmm support is a must to HT */ | 394 | /* wmm support is a must to HT */ |
395 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && | 395 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && |
396 | sband->ht_info.ht_supported && | 396 | sband->ht_cap.ht_supported && |
397 | (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) { | 397 | (ht_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_INFORMATION)) && |
398 | struct ieee80211_ht_addt_info *ht_add_info = | 398 | ht_ie[1] >= sizeof(struct ieee80211_ht_info)) { |
399 | (struct ieee80211_ht_addt_info *)ht_add_ie; | 399 | struct ieee80211_ht_info *ht_info = |
400 | u16 cap = sband->ht_info.cap; | 400 | (struct ieee80211_ht_info *)(ht_ie + 2); |
401 | u16 cap = sband->ht_cap.cap; | ||
401 | __le16 tmp; | 402 | __le16 tmp; |
402 | u32 flags = local->hw.conf.channel->flags; | 403 | u32 flags = local->hw.conf.channel->flags; |
403 | 404 | ||
404 | switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) { | 405 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
405 | case IEEE80211_HT_IE_CHA_SEC_ABOVE: | 406 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
406 | if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { | 407 | if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { |
407 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | 408 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
408 | cap &= ~IEEE80211_HT_CAP_SGI_40; | 409 | cap &= ~IEEE80211_HT_CAP_SGI_40; |
409 | } | 410 | } |
410 | break; | 411 | break; |
411 | case IEEE80211_HT_IE_CHA_SEC_BELOW: | 412 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: |
412 | if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { | 413 | if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { |
413 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | 414 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
414 | cap &= ~IEEE80211_HT_CAP_SGI_40; | 415 | cap &= ~IEEE80211_HT_CAP_SGI_40; |
415 | } | 416 | } |
416 | break; | 417 | break; |
@@ -424,9 +425,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
424 | memcpy(pos, &tmp, sizeof(u16)); | 425 | memcpy(pos, &tmp, sizeof(u16)); |
425 | pos += sizeof(u16); | 426 | pos += sizeof(u16); |
426 | /* TODO: needs a define here for << 2 */ | 427 | /* TODO: needs a define here for << 2 */ |
427 | *pos++ = sband->ht_info.ampdu_factor | | 428 | *pos++ = sband->ht_cap.ampdu_factor | |
428 | (sband->ht_info.ampdu_density << 2); | 429 | (sband->ht_cap.ampdu_density << 2); |
429 | memcpy(pos, sband->ht_info.supp_mcs_set, 16); | 430 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); |
430 | } | 431 | } |
431 | 432 | ||
432 | kfree(ifsta->assocreq_ies); | 433 | kfree(ifsta->assocreq_ies); |
@@ -730,7 +731,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
730 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { | 731 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { |
731 | changed |= BSS_CHANGED_HT; | 732 | changed |= BSS_CHANGED_HT; |
732 | sdata->bss_conf.assoc_ht = 1; | 733 | sdata->bss_conf.assoc_ht = 1; |
733 | sdata->bss_conf.ht_conf = &conf->ht_conf; | 734 | sdata->bss_conf.ht_cap = &conf->ht_cap; |
734 | sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; | 735 | sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; |
735 | } | 736 | } |
736 | 737 | ||
@@ -850,7 +851,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
850 | changed |= BSS_CHANGED_HT; | 851 | changed |= BSS_CHANGED_HT; |
851 | 852 | ||
852 | sdata->bss_conf.assoc_ht = 0; | 853 | sdata->bss_conf.assoc_ht = 0; |
853 | sdata->bss_conf.ht_conf = NULL; | 854 | sdata->bss_conf.ht_cap = NULL; |
854 | sdata->bss_conf.ht_bss_conf = NULL; | 855 | sdata->bss_conf.ht_bss_conf = NULL; |
855 | 856 | ||
856 | ieee80211_led_assoc(local, 0); | 857 | ieee80211_led_assoc(local, 0); |
@@ -1335,11 +1336,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1335 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && | 1336 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && |
1336 | (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | 1337 | (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { |
1337 | struct ieee80211_ht_bss_info bss_info; | 1338 | struct ieee80211_ht_bss_info bss_info; |
1338 | ieee80211_ht_cap_ie_to_ht_info( | 1339 | ieee80211_ht_cap_ie_to_sta_ht_cap( |
1339 | elems.ht_cap_elem, &sta->sta.ht_info); | 1340 | elems.ht_cap_elem, &sta->sta.ht_cap); |
1340 | ieee80211_ht_addt_info_ie_to_ht_bss_info( | 1341 | ieee80211_ht_info_ie_to_ht_bss_info( |
1341 | elems.ht_info_elem, &bss_info); | 1342 | elems.ht_info_elem, &bss_info); |
1342 | ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info); | 1343 | ieee80211_handle_ht(local, &sta->sta.ht_cap, &bss_info); |
1343 | } | 1344 | } |
1344 | 1345 | ||
1345 | rate_control_rate_init(sta); | 1346 | rate_control_rate_init(sta); |
@@ -1696,9 +1697,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1696 | elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { | 1697 | elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { |
1697 | struct ieee80211_ht_bss_info bss_info; | 1698 | struct ieee80211_ht_bss_info bss_info; |
1698 | 1699 | ||
1699 | ieee80211_ht_addt_info_ie_to_ht_bss_info( | 1700 | ieee80211_ht_info_ie_to_ht_bss_info( |
1700 | elems.ht_info_elem, &bss_info); | 1701 | elems.ht_info_elem, &bss_info); |
1701 | changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf, | 1702 | changed |= ieee80211_handle_ht(local, &conf->ht_cap, |
1702 | &bss_info); | 1703 | &bss_info); |
1703 | } | 1704 | } |
1704 | 1705 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 1b605457017e..9941a60a2327 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -532,8 +532,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len, | |||
532 | if (elen >= sizeof(struct ieee80211_ht_cap)) | 532 | if (elen >= sizeof(struct ieee80211_ht_cap)) |
533 | elems->ht_cap_elem = (void *)pos; | 533 | elems->ht_cap_elem = (void *)pos; |
534 | break; | 534 | break; |
535 | case WLAN_EID_HT_EXTRA_INFO: | 535 | case WLAN_EID_HT_INFORMATION: |
536 | if (elen >= sizeof(struct ieee80211_ht_addt_info)) | 536 | if (elen >= sizeof(struct ieee80211_ht_info)) |
537 | elems->ht_info_elem = (void *)pos; | 537 | elems->ht_info_elem = (void *)pos; |
538 | break; | 538 | break; |
539 | case WLAN_EID_MESH_ID: | 539 | case WLAN_EID_MESH_ID: |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 29c41040c8c9..a3af15141244 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -147,7 +147,7 @@ static int ieee80211_ioctl_giwname(struct net_device *dev, | |||
147 | sband = local->hw.wiphy->bands[IEEE80211_BAND_5GHZ]; | 147 | sband = local->hw.wiphy->bands[IEEE80211_BAND_5GHZ]; |
148 | if (sband) { | 148 | if (sband) { |
149 | is_a = 1; | 149 | is_a = 1; |
150 | is_ht |= sband->ht_info.ht_supported; | 150 | is_ht |= sband->ht_cap.ht_supported; |
151 | } | 151 | } |
152 | 152 | ||
153 | sband = local->hw.wiphy->bands[IEEE80211_BAND_2GHZ]; | 153 | sband = local->hw.wiphy->bands[IEEE80211_BAND_2GHZ]; |
@@ -160,7 +160,7 @@ static int ieee80211_ioctl_giwname(struct net_device *dev, | |||
160 | if (sband->bitrates[i].bitrate == 60) | 160 | if (sband->bitrates[i].bitrate == 60) |
161 | is_g = 1; | 161 | is_g = 1; |
162 | } | 162 | } |
163 | is_ht |= sband->ht_info.ht_supported; | 163 | is_ht |= sband->ht_cap.ht_supported; |
164 | } | 164 | } |
165 | 165 | ||
166 | strcpy(name, "IEEE 802.11"); | 166 | strcpy(name, "IEEE 802.11"); |