aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-09-11 08:34:12 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-10-17 05:02:09 -0400
commit04ecd2578e712c301fa1369d2a8f298a2b4b146a (patch)
tree81fc8135db27831f4456b61c3aeb5d332848b449 /net/mac80211/mlme.c
parent55de908ab292c03f1eb280f51170ddb9c6b57e31 (diff)
mac80211: track needed RX chains for channel contexts
On each channel that the device is operating on, it may need to listen using one or more chains depending on the SMPS settings of the interfaces using it. The previous channel context changes completely removed this ability (before, it was available as the SMPS mode). Add per-context tracking of the required static and dynamic RX chains and notify the driver on changes. To achieve this, track the chains and SMPS mode used on each virtual interface and update the channel context whenever this changes. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4add50063161..f3f338541b01 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -543,7 +543,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
543 543
544 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 544 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
545 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, 545 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
546 sband, chan, ifmgd->ap_smps); 546 sband, chan, sdata->smps_mode);
547 547
548 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) 548 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
549 ieee80211_add_vht_ie(sdata, skb, sband); 549 ieee80211_add_vht_ie(sdata, skb, sband);
@@ -1392,7 +1392,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1392 ieee80211_recalc_ps(local, -1); 1392 ieee80211_recalc_ps(local, -1);
1393 mutex_unlock(&local->iflist_mtx); 1393 mutex_unlock(&local->iflist_mtx);
1394 1394
1395 ieee80211_recalc_smps(local); 1395 ieee80211_recalc_smps(sdata);
1396 ieee80211_recalc_ps_vif(sdata); 1396 ieee80211_recalc_ps_vif(sdata);
1397 1397
1398 netif_tx_start_all_queues(sdata->dev); 1398 netif_tx_start_all_queues(sdata->dev);
@@ -3157,6 +3157,10 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3157 } 3157 }
3158 3158
3159 if (ht_oper) { 3159 if (ht_oper) {
3160 const u8 *ht_cap_ie;
3161 const struct ieee80211_ht_cap *ht_cap;
3162 u8 chains = 1;
3163
3160 channel_type = NL80211_CHAN_HT20; 3164 channel_type = NL80211_CHAN_HT20;
3161 3165
3162 if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { 3166 if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
@@ -3170,8 +3174,22 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3170 break; 3174 break;
3171 } 3175 }
3172 } 3176 }
3177
3178 ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
3179 cbss->information_elements,
3180 cbss->len_information_elements);
3181 if (ht_cap_ie && ht_cap_ie[1] >= sizeof(*ht_cap)) {
3182 ht_cap = (void *)(ht_cap_ie + 2);
3183 chains = ieee80211_mcs_to_chains(&ht_cap->mcs);
3184 }
3185 sdata->needed_rx_chains = min(chains, local->rx_chains);
3186 } else {
3187 sdata->needed_rx_chains = 1;
3173 } 3188 }
3174 3189
3190 /* will change later if needed */
3191 sdata->smps_mode = IEEE80211_SMPS_OFF;
3192
3175 ieee80211_vif_release_channel(sdata); 3193 ieee80211_vif_release_channel(sdata);
3176 return ieee80211_vif_use_channel(sdata, cbss->channel, channel_type, 3194 return ieee80211_vif_use_channel(sdata, cbss->channel, channel_type,
3177 IEEE80211_CHANCTX_SHARED); 3195 IEEE80211_CHANCTX_SHARED);
@@ -3485,11 +3503,11 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3485 3503
3486 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) { 3504 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
3487 if (ifmgd->powersave) 3505 if (ifmgd->powersave)
3488 ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC; 3506 sdata->smps_mode = IEEE80211_SMPS_DYNAMIC;
3489 else 3507 else
3490 ifmgd->ap_smps = IEEE80211_SMPS_OFF; 3508 sdata->smps_mode = IEEE80211_SMPS_OFF;
3491 } else 3509 } else
3492 ifmgd->ap_smps = ifmgd->req_smps; 3510 sdata->smps_mode = ifmgd->req_smps;
3493 3511
3494 assoc_data->capability = req->bss->capability; 3512 assoc_data->capability = req->bss->capability;
3495 assoc_data->wmm = bss->wmm_used && 3513 assoc_data->wmm = bss->wmm_used &&