aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-11-22 08:17:23 -0500
committerJohannes Berg <johannes.berg@intel.com>2012-11-23 02:43:26 -0500
commit76c5fa0fb99e694e123f05f62382b717b857b6a9 (patch)
tree654a89d0e8aad89fde78986d495b3976a8e97dc3
parent605f1a5b5e87cf4005b56b77083ff473c846431a (diff)
mac80211: fix RX chains configuration
If the driver doesn't support 40 MHz channels, then mac80211 erroneously sets number of RX chains to one although the number of chains is independent of the support for 40 MHz channels. Fix this by checking the 40 MHz support only for the code that sets the 40 MHz channel not the complete HT code block. This also means the HT20 channel type will always be set in the changed code block so there's no need to set it in case we override the AP due to invalid IEs in the probe response/beacon. The indentation is a bit quirky, but I'm rewriting this code for VHT support so this will change again very soon. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/mlme.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 61614461e08..19969ecf930 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3219,12 +3219,10 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3219 ht_cfreq, ht_oper->primary_chan, 3219 ht_cfreq, ht_oper->primary_chan,
3220 cbss->channel->band); 3220 cbss->channel->band);
3221 ht_oper = NULL; 3221 ht_oper = NULL;
3222 } else {
3223 channel_type = NL80211_CHAN_HT20;
3224 } 3222 }
3225 } 3223 }
3226 3224
3227 if (ht_oper && sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { 3225 if (ht_oper) {
3228 /* 3226 /*
3229 * cfg80211 already verified that the channel itself can 3227 * cfg80211 already verified that the channel itself can
3230 * be used, but it didn't check that we can do the right 3228 * be used, but it didn't check that we can do the right
@@ -3237,19 +3235,26 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3237 3235
3238 channel_type = NL80211_CHAN_HT20; 3236 channel_type = NL80211_CHAN_HT20;
3239 3237
3240 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { 3238 if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
3241 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: 3239 switch (ht_oper->ht_param &
3242 if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40PLUS) 3240 IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
3243 ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; 3241 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
3244 else 3242 if (cbss->channel->flags &
3245 channel_type = NL80211_CHAN_HT40PLUS; 3243 IEEE80211_CHAN_NO_HT40PLUS)
3246 break; 3244 ifmgd->flags |=
3247 case IEEE80211_HT_PARAM_CHA_SEC_BELOW: 3245 IEEE80211_STA_DISABLE_40MHZ;
3248 if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40MINUS) 3246 else
3249 ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; 3247 channel_type = NL80211_CHAN_HT40PLUS;
3250 else 3248 break;
3251 channel_type = NL80211_CHAN_HT40MINUS; 3249 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
3252 break; 3250 if (cbss->channel->flags &
3251 IEEE80211_CHAN_NO_HT40MINUS)
3252 ifmgd->flags |=
3253 IEEE80211_STA_DISABLE_40MHZ;
3254 else
3255 channel_type = NL80211_CHAN_HT40MINUS;
3256 break;
3257 }
3253 } 3258 }
3254 3259
3255 ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, 3260 ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,