aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-05-16 17:43:19 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-06-05 15:32:15 -0400
commit9dde64232586bd35c8454615266d209106b73c0f (patch)
tree488be8573e55453d6ef6dc88a692a42fb7e23093 /net/mac80211/mlme.c
parent10bab00afed042c1a38ed5ffb135e2aea5ce1277 (diff)
mac80211: simplify association HT parameters
Instead of passing around the entire HT information IE, extract only the HT parameters field and disable HT if the HT information IE isn't present and well- formed. 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.c26
1 files changed, 11 insertions, 15 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 0c4e26ff7d91..7c077158eb88 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -258,12 +258,11 @@ static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
258} 258}
259 259
260static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, 260static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
261 struct sk_buff *skb, const u8 *ht_oper_ie, 261 struct sk_buff *skb, u8 ap_ht_param,
262 struct ieee80211_supported_band *sband, 262 struct ieee80211_supported_band *sband,
263 struct ieee80211_channel *channel, 263 struct ieee80211_channel *channel,
264 enum ieee80211_smps_mode smps) 264 enum ieee80211_smps_mode smps)
265{ 265{
266 struct ieee80211_ht_operation *ht_oper;
267 u8 *pos; 266 u8 *pos;
268 u32 flags = channel->flags; 267 u32 flags = channel->flags;
269 u16 cap; 268 u16 cap;
@@ -271,21 +270,13 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
271 270
272 BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap)); 271 BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
273 272
274 if (!ht_oper_ie)
275 return;
276
277 if (ht_oper_ie[1] < sizeof(struct ieee80211_ht_operation))
278 return;
279
280 memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap)); 273 memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
281 ieee80211_apply_htcap_overrides(sdata, &ht_cap); 274 ieee80211_apply_htcap_overrides(sdata, &ht_cap);
282 275
283 ht_oper = (struct ieee80211_ht_operation *)(ht_oper_ie + 2);
284
285 /* determine capability flags */ 276 /* determine capability flags */
286 cap = ht_cap.cap; 277 cap = ht_cap.cap;
287 278
288 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { 279 switch (ap_ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
289 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: 280 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
290 if (flags & IEEE80211_CHAN_NO_HT40PLUS) { 281 if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
291 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; 282 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@ -509,7 +500,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
509 } 500 }
510 501
511 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 502 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
512 ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_operation_ie, 503 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
513 sband, local->oper_channel, ifmgd->ap_smps); 504 sband, local->oper_channel, ifmgd->ap_smps);
514 505
515 /* if present, add any custom non-vendor IEs that go after HT */ 506 /* if present, add any custom non-vendor IEs that go after HT */
@@ -3260,7 +3251,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3260 struct ieee80211_bss *bss = (void *)req->bss->priv; 3251 struct ieee80211_bss *bss = (void *)req->bss->priv;
3261 struct ieee80211_mgd_assoc_data *assoc_data; 3252 struct ieee80211_mgd_assoc_data *assoc_data;
3262 struct ieee80211_supported_band *sband; 3253 struct ieee80211_supported_band *sband;
3263 const u8 *ssidie; 3254 const u8 *ssidie, *ht_ie;
3264 int i, err; 3255 int i, err;
3265 3256
3266 ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); 3257 ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
@@ -3347,8 +3338,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3347 (local->hw.queues >= IEEE80211_NUM_ACS); 3338 (local->hw.queues >= IEEE80211_NUM_ACS);
3348 assoc_data->supp_rates = bss->supp_rates; 3339 assoc_data->supp_rates = bss->supp_rates;
3349 assoc_data->supp_rates_len = bss->supp_rates_len; 3340 assoc_data->supp_rates_len = bss->supp_rates_len;
3350 assoc_data->ht_operation_ie = 3341
3351 ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION); 3342 ht_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION);
3343 if (ht_ie && ht_ie[1] >= sizeof(struct ieee80211_ht_operation))
3344 assoc_data->ap_ht_param =
3345 ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param;
3346 else
3347 ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
3352 3348
3353 if (bss->wmm_used && bss->uapsd_supported && 3349 if (bss->wmm_used && bss->uapsd_supported &&
3354 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { 3350 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {