diff options
author | Chaya Rachel Ivgi <chaya.rachel.ivgi@intel.com> | 2015-04-20 15:51:46 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2015-04-24 06:23:35 -0400 |
commit | c1041f109a788fbc45197c38aed4c46e580d9d5f (patch) | |
tree | 03da71da51c8b3e76b68398505f6acbd84f8e8fe /net/mac80211/mlme.c | |
parent | 4292504044a4fd4c5d9155dcb5c7b09ed6cbf611 (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.c | 57 |
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 | ||
4309 | static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | 4309 | static 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 | ||