diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2010-01-26 08:19:52 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-26 11:53:21 -0500 |
commit | 56007a028c51cbf800a6c969d6f6431d23443b99 (patch) | |
tree | 8bc0280467824ed3b5f95810444b1f8e1ebc2750 /drivers | |
parent | c21dbf9214bce129f92e1af05552553ff0e318ed (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 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-power.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mwl8k.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_main.c | 25 |
4 files changed, 17 insertions, 27 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 8599444bef01..9e3ca0641451 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -319,7 +319,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) | |||
319 | priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; | 319 | priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; |
320 | 320 | ||
321 | if (priv->vif) | 321 | if (priv->vif) |
322 | dtimper = priv->vif->bss_conf.dtim_period; | 322 | dtimper = priv->hw->conf.ps_dtim_period; |
323 | else | 323 | else |
324 | dtimper = 1; | 324 | dtimper = 1; |
325 | 325 | ||
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 68546ca0ba37..f0f08f3919cc 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -3881,12 +3881,16 @@ static void mwl8k_finalize_join_worker(struct work_struct *work) | |||
3881 | struct mwl8k_priv *priv = | 3881 | struct mwl8k_priv *priv = |
3882 | container_of(work, struct mwl8k_priv, finalize_join_worker); | 3882 | container_of(work, struct mwl8k_priv, finalize_join_worker); |
3883 | struct sk_buff *skb = priv->beacon_skb; | 3883 | struct sk_buff *skb = priv->beacon_skb; |
3884 | struct mwl8k_vif *mwl8k_vif; | 3884 | struct ieee80211_mgmt *mgmt = (void *)skb->data; |
3885 | int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable); | ||
3886 | const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM, | ||
3887 | mgmt->u.beacon.variable, len); | ||
3888 | int dtim_period = 1; | ||
3889 | |||
3890 | if (tim && tim[1] >= 2) | ||
3891 | dtim_period = tim[3]; | ||
3885 | 3892 | ||
3886 | mwl8k_vif = mwl8k_first_vif(priv); | 3893 | mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period); |
3887 | if (mwl8k_vif != NULL) | ||
3888 | mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, | ||
3889 | mwl8k_vif->vif->bss_conf.dtim_period); | ||
3890 | 3894 | ||
3891 | dev_kfree_skb(skb); | 3895 | dev_kfree_skb(skb); |
3892 | priv->beacon_skb = NULL; | 3896 | priv->beacon_skb = NULL; |
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h index 6301578d1565..37c61c19cae5 100644 --- a/drivers/net/wireless/wl12xx/wl1251.h +++ b/drivers/net/wireless/wl12xx/wl1251.h | |||
@@ -341,9 +341,6 @@ struct wl1251 { | |||
341 | /* Are we currently scanning */ | 341 | /* Are we currently scanning */ |
342 | bool scanning; | 342 | bool scanning; |
343 | 343 | ||
344 | /* Our association ID */ | ||
345 | u16 aid; | ||
346 | |||
347 | /* Default key (for WEP) */ | 344 | /* Default key (for WEP) */ |
348 | u32 default_key; | 345 | u32 default_key; |
349 | 346 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index 595f0f94d16e..a717dde4822e 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c | |||
@@ -617,10 +617,13 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) | |||
617 | 617 | ||
618 | wl->psm_requested = true; | 618 | wl->psm_requested = true; |
619 | 619 | ||
620 | wl->dtim_period = conf->ps_dtim_period; | ||
621 | |||
622 | ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int, | ||
623 | wl->dtim_period); | ||
624 | |||
620 | /* | 625 | /* |
621 | * We enter PSM only if we're already associated. | 626 | * mac80211 enables PSM only if we're already associated. |
622 | * If we're not, we'll enter it when joining an SSID, | ||
623 | * through the bss_info_changed() hook. | ||
624 | */ | 627 | */ |
625 | ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); | 628 | ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); |
626 | if (ret < 0) | 629 | if (ret < 0) |
@@ -943,7 +946,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, | |||
943 | struct ieee80211_bss_conf *bss_conf, | 946 | struct ieee80211_bss_conf *bss_conf, |
944 | u32 changed) | 947 | u32 changed) |
945 | { | 948 | { |
946 | enum wl1251_cmd_ps_mode mode; | ||
947 | struct wl1251 *wl = hw->priv; | 949 | struct wl1251 *wl = hw->priv; |
948 | struct sk_buff *beacon, *skb; | 950 | struct sk_buff *beacon, *skb; |
949 | int ret; | 951 | int ret; |
@@ -984,11 +986,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, | |||
984 | if (changed & BSS_CHANGED_ASSOC) { | 986 | if (changed & BSS_CHANGED_ASSOC) { |
985 | if (bss_conf->assoc) { | 987 | if (bss_conf->assoc) { |
986 | wl->beacon_int = bss_conf->beacon_int; | 988 | wl->beacon_int = bss_conf->beacon_int; |
987 | wl->dtim_period = bss_conf->dtim_period; | ||
988 | |||
989 | ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int, | ||
990 | wl->dtim_period); | ||
991 | wl->aid = bss_conf->aid; | ||
992 | 989 | ||
993 | skb = ieee80211_pspoll_get(wl->hw, wl->vif); | 990 | skb = ieee80211_pspoll_get(wl->hw, wl->vif); |
994 | if (!skb) | 991 | if (!skb) |
@@ -1001,17 +998,9 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1001 | if (ret < 0) | 998 | if (ret < 0) |
1002 | goto out_sleep; | 999 | goto out_sleep; |
1003 | 1000 | ||
1004 | ret = wl1251_acx_aid(wl, wl->aid); | 1001 | ret = wl1251_acx_aid(wl, bss_conf->aid); |
1005 | if (ret < 0) | 1002 | if (ret < 0) |
1006 | goto out_sleep; | 1003 | goto out_sleep; |
1007 | |||
1008 | /* If we want to go in PSM but we're not there yet */ | ||
1009 | if (wl->psm_requested && !wl->psm) { | ||
1010 | mode = STATION_POWER_SAVE_MODE; | ||
1011 | ret = wl1251_ps_set_mode(wl, mode); | ||
1012 | if (ret < 0) | ||
1013 | goto out_sleep; | ||
1014 | } | ||
1015 | } else { | 1004 | } else { |
1016 | /* use defaults when not associated */ | 1005 | /* use defaults when not associated */ |
1017 | wl->beacon_int = WL1251_DEFAULT_BEACON_INT; | 1006 | wl->beacon_int = WL1251_DEFAULT_BEACON_INT; |