diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 6faa7006681a..d30c11337b04 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -808,8 +808,29 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
808 | 808 | ||
809 | /* wmm support is a must to HT */ | 809 | /* wmm support is a must to HT */ |
810 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && | 810 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && |
811 | sband->ht_info.ht_supported) { | 811 | sband->ht_info.ht_supported && bss->ht_add_ie) { |
812 | __le16 tmp = cpu_to_le16(sband->ht_info.cap); | 812 | struct ieee80211_ht_addt_info *ht_add_info = |
813 | (struct ieee80211_ht_addt_info *)bss->ht_add_ie; | ||
814 | u16 cap = sband->ht_info.cap; | ||
815 | __le16 tmp; | ||
816 | u32 flags = local->hw.conf.channel->flags; | ||
817 | |||
818 | switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) { | ||
819 | case IEEE80211_HT_IE_CHA_SEC_ABOVE: | ||
820 | if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { | ||
821 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | ||
822 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
823 | } | ||
824 | break; | ||
825 | case IEEE80211_HT_IE_CHA_SEC_BELOW: | ||
826 | if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { | ||
827 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | ||
828 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
829 | } | ||
830 | break; | ||
831 | } | ||
832 | |||
833 | tmp = cpu_to_le16(cap); | ||
813 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); | 834 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); |
814 | *pos++ = WLAN_EID_HT_CAPABILITY; | 835 | *pos++ = WLAN_EID_HT_CAPABILITY; |
815 | *pos++ = sizeof(struct ieee80211_ht_cap); | 836 | *pos++ = sizeof(struct ieee80211_ht_cap); |
@@ -2264,6 +2285,7 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss) | |||
2264 | kfree(bss->rsn_ie); | 2285 | kfree(bss->rsn_ie); |
2265 | kfree(bss->wmm_ie); | 2286 | kfree(bss->wmm_ie); |
2266 | kfree(bss->ht_ie); | 2287 | kfree(bss->ht_ie); |
2288 | kfree(bss->ht_add_ie); | ||
2267 | kfree(bss_mesh_id(bss)); | 2289 | kfree(bss_mesh_id(bss)); |
2268 | kfree(bss_mesh_cfg(bss)); | 2290 | kfree(bss_mesh_cfg(bss)); |
2269 | kfree(bss); | 2291 | kfree(bss); |
@@ -2640,6 +2662,26 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2640 | bss->ht_ie_len = 0; | 2662 | bss->ht_ie_len = 0; |
2641 | } | 2663 | } |
2642 | 2664 | ||
2665 | if (elems.ht_info_elem && | ||
2666 | (!bss->ht_add_ie || | ||
2667 | bss->ht_add_ie_len != elems.ht_info_elem_len || | ||
2668 | memcmp(bss->ht_add_ie, elems.ht_info_elem, | ||
2669 | elems.ht_info_elem_len))) { | ||
2670 | kfree(bss->ht_add_ie); | ||
2671 | bss->ht_add_ie = | ||
2672 | kmalloc(elems.ht_info_elem_len + 2, GFP_ATOMIC); | ||
2673 | if (bss->ht_add_ie) { | ||
2674 | memcpy(bss->ht_add_ie, elems.ht_info_elem - 2, | ||
2675 | elems.ht_info_elem_len + 2); | ||
2676 | bss->ht_add_ie_len = elems.ht_info_elem_len + 2; | ||
2677 | } else | ||
2678 | bss->ht_add_ie_len = 0; | ||
2679 | } else if (!elems.ht_info_elem && bss->ht_add_ie) { | ||
2680 | kfree(bss->ht_add_ie); | ||
2681 | bss->ht_add_ie = NULL; | ||
2682 | bss->ht_add_ie_len = 0; | ||
2683 | } | ||
2684 | |||
2643 | bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); | 2685 | bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); |
2644 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); | 2686 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); |
2645 | 2687 | ||