aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c63
1 files changed, 59 insertions, 4 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index cd5dcc3d8c2b..0a762a9ba4df 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -398,6 +398,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
398 __le16 tmp; 398 __le16 tmp;
399 u32 flags = local->hw.conf.channel->flags; 399 u32 flags = local->hw.conf.channel->flags;
400 400
401 /* determine capability flags */
402
401 switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { 403 switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
402 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: 404 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
403 if (flags & IEEE80211_CHAN_NO_HT40PLUS) { 405 if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
@@ -413,17 +415,64 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
413 break; 415 break;
414 } 416 }
415 417
416 tmp = cpu_to_le16(cap); 418 /* set SM PS mode properly */
417 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); 419 cap &= ~IEEE80211_HT_CAP_SM_PS;
420 /* new association always uses requested smps mode */
421 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
422 if (ifmgd->powersave)
423 ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC;
424 else
425 ifmgd->ap_smps = IEEE80211_SMPS_OFF;
426 } else
427 ifmgd->ap_smps = ifmgd->req_smps;
428
429 switch (ifmgd->ap_smps) {
430 case IEEE80211_SMPS_AUTOMATIC:
431 case IEEE80211_SMPS_NUM_MODES:
432 WARN_ON(1);
433 case IEEE80211_SMPS_OFF:
434 cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
435 IEEE80211_HT_CAP_SM_PS_SHIFT;
436 break;
437 case IEEE80211_SMPS_STATIC:
438 cap |= WLAN_HT_CAP_SM_PS_STATIC <<
439 IEEE80211_HT_CAP_SM_PS_SHIFT;
440 break;
441 case IEEE80211_SMPS_DYNAMIC:
442 cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
443 IEEE80211_HT_CAP_SM_PS_SHIFT;
444 break;
445 }
446
447 /* reserve and fill IE */
448
449 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
418 *pos++ = WLAN_EID_HT_CAPABILITY; 450 *pos++ = WLAN_EID_HT_CAPABILITY;
419 *pos++ = sizeof(struct ieee80211_ht_cap); 451 *pos++ = sizeof(struct ieee80211_ht_cap);
420 memset(pos, 0, sizeof(struct ieee80211_ht_cap)); 452 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
453
454 /* capability flags */
455 tmp = cpu_to_le16(cap);
421 memcpy(pos, &tmp, sizeof(u16)); 456 memcpy(pos, &tmp, sizeof(u16));
422 pos += sizeof(u16); 457 pos += sizeof(u16);
423 /* TODO: needs a define here for << 2 */ 458
459 /* AMPDU parameters */
424 *pos++ = sband->ht_cap.ampdu_factor | 460 *pos++ = sband->ht_cap.ampdu_factor |
425 (sband->ht_cap.ampdu_density << 2); 461 (sband->ht_cap.ampdu_density <<
462 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
463
464 /* MCS set */
426 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); 465 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
466 pos += sizeof(sband->ht_cap.mcs);
467
468 /* extended capabilities */
469 pos += sizeof(__le16);
470
471 /* BF capabilities */
472 pos += sizeof(__le32);
473
474 /* antenna selection */
475 pos += sizeof(u8);
427 } 476 }
428 477
429 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 478 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
@@ -932,6 +981,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
932 981
933 mutex_lock(&local->iflist_mtx); 982 mutex_lock(&local->iflist_mtx);
934 ieee80211_recalc_ps(local, -1); 983 ieee80211_recalc_ps(local, -1);
984 ieee80211_recalc_smps(local, sdata);
935 mutex_unlock(&local->iflist_mtx); 985 mutex_unlock(&local->iflist_mtx);
936 986
937 netif_start_queue(sdata->dev); 987 netif_start_queue(sdata->dev);
@@ -2327,6 +2377,11 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
2327 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED; 2377 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
2328 2378
2329 mutex_init(&ifmgd->mtx); 2379 mutex_init(&ifmgd->mtx);
2380
2381 if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
2382 ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC;
2383 else
2384 ifmgd->req_smps = IEEE80211_SMPS_OFF;
2330} 2385}
2331 2386
2332/* scan finished notification */ 2387/* scan finished notification */