aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2010-01-26 08:19:52 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-01-26 11:53:21 -0500
commit56007a028c51cbf800a6c969d6f6431d23443b99 (patch)
tree8bc0280467824ed3b5f95810444b1f8e1ebc2750 /net/mac80211/mlme.c
parentc21dbf9214bce129f92e1af05552553ff0e318ed (diff)
mac80211: wait for beacon before enabling powersave
Because DTIM information is required for powersave but is only conveyed in beacons, wait for a beacon before enabling powersave, and change the way the information is conveyed to the driver accordingly. mwl8k doesn't currently seem to implement PS but requires the DTIM period in a different way; after talking to Lennert we agreed to just have mwl8k do the parsing itself in the finalize_join work. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Lennert Buytenhek <buytenh@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1e1d16c55ee5..86c6ad1b058d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -484,6 +484,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
484 484
485 if (count == 1 && found->u.mgd.powersave && 485 if (count == 1 && found->u.mgd.powersave &&
486 found->u.mgd.associated && 486 found->u.mgd.associated &&
487 found->u.mgd.associated->beacon_ies &&
487 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL | 488 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
488 IEEE80211_STA_CONNECTION_POLL))) { 489 IEEE80211_STA_CONNECTION_POLL))) {
489 s32 beaconint_us; 490 s32 beaconint_us;
@@ -497,14 +498,22 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
497 if (beaconint_us > latency) { 498 if (beaconint_us > latency) {
498 local->ps_sdata = NULL; 499 local->ps_sdata = NULL;
499 } else { 500 } else {
500 u8 dtimper = found->vif.bss_conf.dtim_period; 501 struct ieee80211_bss *bss;
501 int maxslp = 1; 502 int maxslp = 1;
503 u8 dtimper;
502 504
503 if (dtimper > 1) 505 bss = (void *)found->u.mgd.associated->priv;
506 dtimper = bss->dtim_period;
507
508 /* If the TIM IE is invalid, pretend the value is 1 */
509 if (!dtimper)
510 dtimper = 1;
511 else if (dtimper > 1)
504 maxslp = min_t(int, dtimper, 512 maxslp = min_t(int, dtimper,
505 latency / beaconint_us); 513 latency / beaconint_us);
506 514
507 local->hw.conf.max_sleep_period = maxslp; 515 local->hw.conf.max_sleep_period = maxslp;
516 local->hw.conf.ps_dtim_period = dtimper;
508 local->ps_sdata = found; 517 local->ps_sdata = found;
509 } 518 }
510 } else { 519 } else {
@@ -702,7 +711,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
702 /* set timing information */ 711 /* set timing information */
703 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval; 712 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval;
704 sdata->vif.bss_conf.timestamp = cbss->tsf; 713 sdata->vif.bss_conf.timestamp = cbss->tsf;
705 sdata->vif.bss_conf.dtim_period = bss->dtim_period;
706 714
707 bss_info_changed |= BSS_CHANGED_BEACON_INT; 715 bss_info_changed |= BSS_CHANGED_BEACON_INT;
708 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 716 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
@@ -1168,6 +1176,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1168 int freq; 1176 int freq;
1169 struct ieee80211_bss *bss; 1177 struct ieee80211_bss *bss;
1170 struct ieee80211_channel *channel; 1178 struct ieee80211_channel *channel;
1179 bool need_ps = false;
1180
1181 if (sdata->u.mgd.associated) {
1182 bss = (void *)sdata->u.mgd.associated->priv;
1183 /* not previously set so we may need to recalc */
1184 need_ps = !bss->dtim_period;
1185 }
1171 1186
1172 if (elems->ds_params && elems->ds_params_len == 1) 1187 if (elems->ds_params && elems->ds_params_len == 1)
1173 freq = ieee80211_channel_to_frequency(elems->ds_params[0]); 1188 freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
@@ -1187,6 +1202,12 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1187 if (!sdata->u.mgd.associated) 1202 if (!sdata->u.mgd.associated)
1188 return; 1203 return;
1189 1204
1205 if (need_ps) {
1206 mutex_lock(&local->iflist_mtx);
1207 ieee80211_recalc_ps(local, -1);
1208 mutex_unlock(&local->iflist_mtx);
1209 }
1210
1190 if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) && 1211 if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) &&
1191 (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, 1212 (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
1192 ETH_ALEN) == 0)) { 1213 ETH_ALEN) == 0)) {