aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-02-07 17:33:32 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-15 03:41:35 -0500
commit08e6effa1187cc5f401a1cc286ce84f0a581b35a (patch)
tree3d48812d1ee8d43a42603c7f528927d56929516a /net/mac80211
parentbee7f58699a406a4210ba9e0367bae7ac666abd0 (diff)
mac80211: disable HT/VHT if AP has no HT/VHT capability
Having HT/VHT operation IEs but not capability IEs leads to a strange situation where we configure the channel to an HT or VHT bandwidth and then can't actually use it. Prevent this by checking that the HT and VHT capability IEs are present as well as the operation IEs; if not, disable HT and/or VHT. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/mlme.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f2c6f7794f35..03f278880dba 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3589,16 +3589,22 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3589 3589
3590 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && 3590 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
3591 sband->ht_cap.ht_supported) { 3591 sband->ht_cap.ht_supported) {
3592 const u8 *ht_oper_ie; 3592 const u8 *ht_oper_ie, *ht_cap;
3593 3593
3594 ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION); 3594 ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION);
3595 if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper)) 3595 if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper))
3596 ht_oper = (void *)(ht_oper_ie + 2); 3596 ht_oper = (void *)(ht_oper_ie + 2);
3597
3598 ht_cap = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_CAPABILITY);
3599 if (!ht_cap || ht_cap[1] < sizeof(struct ieee80211_ht_cap)) {
3600 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3601 ht_oper = NULL;
3602 }
3597 } 3603 }
3598 3604
3599 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && 3605 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
3600 sband->vht_cap.vht_supported) { 3606 sband->vht_cap.vht_supported) {
3601 const u8 *vht_oper_ie; 3607 const u8 *vht_oper_ie, *vht_cap;
3602 3608
3603 vht_oper_ie = ieee80211_bss_get_ie(cbss, 3609 vht_oper_ie = ieee80211_bss_get_ie(cbss,
3604 WLAN_EID_VHT_OPERATION); 3610 WLAN_EID_VHT_OPERATION);
@@ -3611,6 +3617,12 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3611 ifmgd->flags |= IEEE80211_STA_DISABLE_HT; 3617 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3612 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 3618 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
3613 } 3619 }
3620
3621 vht_cap = ieee80211_bss_get_ie(cbss, WLAN_EID_VHT_CAPABILITY);
3622 if (!vht_cap || vht_cap[1] < sizeof(struct ieee80211_vht_cap)) {
3623 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
3624 vht_oper = NULL;
3625 }
3614 } 3626 }
3615 3627
3616 ifmgd->flags |= ieee80211_determine_chantype(sdata, sband, 3628 ifmgd->flags |= ieee80211_determine_chantype(sdata, sband,