summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorChaya Rachel Ivgi <chaya.rachel.ivgi@intel.com>2015-04-20 15:51:46 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-04-24 06:23:35 -0400
commitc1041f109a788fbc45197c38aed4c46e580d9d5f (patch)
tree03da71da51c8b3e76b68398505f6acbd84f8e8fe /net/mac80211/mlme.c
parent4292504044a4fd4c5d9155dcb5c7b09ed6cbf611 (diff)
mac80211: fix ignored HT/VHT override configs
HT and VHT override configurations were ignored during association and applied only when first beacon recived, or not applied at all. Fix the code to apply HT/VHT overrides during association. This is a bit tricky since the channel was already configured during authentication and we don't want to reconfigure it unless there's really a change. Signed-off-by: Chaya Rachel Ivgi <chaya.rachel.ivgi@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c57
1 files changed, 36 insertions, 21 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 26053bf2faa8..3294666f599c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4307,15 +4307,15 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
4307} 4307}
4308 4308
4309static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, 4309static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
4310 struct cfg80211_bss *cbss, bool assoc) 4310 struct cfg80211_bss *cbss, bool assoc,
4311 bool override)
4311{ 4312{
4312 struct ieee80211_local *local = sdata->local; 4313 struct ieee80211_local *local = sdata->local;
4313 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 4314 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
4314 struct ieee80211_bss *bss = (void *)cbss->priv; 4315 struct ieee80211_bss *bss = (void *)cbss->priv;
4315 struct sta_info *new_sta = NULL; 4316 struct sta_info *new_sta = NULL;
4316 struct ieee80211_supported_band *sband; 4317 struct ieee80211_supported_band *sband;
4317 struct ieee80211_sta_ht_cap sta_ht_cap; 4318 bool have_sta = false;
4318 bool have_sta = false, is_override = false;
4319 int err; 4319 int err;
4320 4320
4321 sband = local->hw.wiphy->bands[cbss->channel->band]; 4321 sband = local->hw.wiphy->bands[cbss->channel->band];
@@ -4335,14 +4335,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
4335 return -ENOMEM; 4335 return -ENOMEM;
4336 } 4336 }
4337 4337
4338 memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap)); 4338 if (new_sta || override) {
4339 ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);
4340
4341 is_override = (sta_ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) !=
4342 (sband->ht_cap.cap &
4343 IEEE80211_HT_CAP_SUP_WIDTH_20_40);
4344
4345 if (new_sta || is_override) {
4346 err = ieee80211_prep_channel(sdata, cbss); 4339 err = ieee80211_prep_channel(sdata, cbss);
4347 if (err) { 4340 if (err) {
4348 if (new_sta) 4341 if (new_sta)
@@ -4552,7 +4545,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
4552 4545
4553 sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); 4546 sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
4554 4547
4555 err = ieee80211_prep_connection(sdata, req->bss, false); 4548 err = ieee80211_prep_connection(sdata, req->bss, false, false);
4556 if (err) 4549 if (err)
4557 goto err_clear; 4550 goto err_clear;
4558 4551
@@ -4624,6 +4617,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4624 struct ieee80211_supported_band *sband; 4617 struct ieee80211_supported_band *sband;
4625 const u8 *ssidie, *ht_ie, *vht_ie; 4618 const u8 *ssidie, *ht_ie, *vht_ie;
4626 int i, err; 4619 int i, err;
4620 bool override = false;
4627 4621
4628 assoc_data = kzalloc(sizeof(*assoc_data) + req->ie_len, GFP_KERNEL); 4622 assoc_data = kzalloc(sizeof(*assoc_data) + req->ie_len, GFP_KERNEL);
4629 if (!assoc_data) 4623 if (!assoc_data)
@@ -4728,14 +4722,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4728 } 4722 }
4729 } 4723 }
4730 4724
4731 if (req->flags & ASSOC_REQ_DISABLE_HT) {
4732 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
4733 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
4734 }
4735
4736 if (req->flags & ASSOC_REQ_DISABLE_VHT)
4737 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
4738
4739 /* Also disable HT if we don't support it or the AP doesn't use WMM */ 4725 /* Also disable HT if we don't support it or the AP doesn't use WMM */
4740 sband = local->hw.wiphy->bands[req->bss->channel->band]; 4726 sband = local->hw.wiphy->bands[req->bss->channel->band];
4741 if (!sband->ht_cap.ht_supported || 4727 if (!sband->ht_cap.ht_supported ||
@@ -4847,7 +4833,36 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4847 ifmgd->dtim_period = 0; 4833 ifmgd->dtim_period = 0;
4848 ifmgd->have_beacon = false; 4834 ifmgd->have_beacon = false;
4849 4835
4850 err = ieee80211_prep_connection(sdata, req->bss, true); 4836 /* override HT/VHT configuration only if the AP and we support it */
4837 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
4838 struct ieee80211_sta_ht_cap sta_ht_cap;
4839
4840 if (req->flags & ASSOC_REQ_DISABLE_HT)
4841 override = true;
4842
4843 memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap));
4844 ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);
4845
4846 /* check for 40 MHz disable override */
4847 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_40MHZ) &&
4848 sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
4849 !(sta_ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
4850 override = true;
4851
4852 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
4853 req->flags & ASSOC_REQ_DISABLE_VHT)
4854 override = true;
4855 }
4856
4857 if (req->flags & ASSOC_REQ_DISABLE_HT) {
4858 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
4859 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
4860 }
4861
4862 if (req->flags & ASSOC_REQ_DISABLE_VHT)
4863 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
4864
4865 err = ieee80211_prep_connection(sdata, req->bss, true, override);
4851 if (err) 4866 if (err)
4852 goto err_clear; 4867 goto err_clear;
4853 4868