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/mac80211/mlme.c | |
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/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 45 |
1 files changed, 23 insertions, 22 deletions
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 | ||