diff options
author | Eyal Shapira <eyal@wizery.com> | 2012-01-31 04:57:21 -0500 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2012-02-15 01:38:31 -0500 |
commit | f1d63a59635feef3481ed1972a883a5d6be7f9bb (patch) | |
tree | 835d3e246d7d310ff51d2576ffc9f1f7b1808caa | |
parent | d6bf9ada92c113e56151b6a993b9b9d5d03f1365 (diff) |
wl12xx: add support for HW dynamic PS
FW now supports dynamic PS so we don't need to use mac80211 support.
FW will go to PSM after a specified timeout with no Rx/Tx traffic.
- Changed FW API to include new PS mode (AUTO_MODE) and including timeout parameter
- The default PS mode would be dynamic PS
- Default timeout is 100ms (same as it used to be in mac80211)
- Avoid using mac80211 APIs to disable/enable dynamic PS as we're not
using mac80211 PS control anymore.
- COEX is handled by the FW while in dynamic PS so removed
handling of SOFT_GEMINI
Signed-off-by: Eyal Shapira <eyal@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
-rw-r--r-- | drivers/net/wireless/wl12xx/cmd.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/cmd.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/conf.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/event.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/ps.c | 15 |
6 files changed, 26 insertions, 26 deletions
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 88e94c5938a4..bf3c37bd1f12 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c | |||
@@ -996,7 +996,7 @@ out: | |||
996 | } | 996 | } |
997 | 997 | ||
998 | int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 998 | int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
999 | u8 ps_mode) | 999 | u8 ps_mode, u16 auto_ps_timeout) |
1000 | { | 1000 | { |
1001 | struct wl1271_cmd_ps_params *ps_params = NULL; | 1001 | struct wl1271_cmd_ps_params *ps_params = NULL; |
1002 | int ret = 0; | 1002 | int ret = 0; |
@@ -1011,6 +1011,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
1011 | 1011 | ||
1012 | ps_params->role_id = wlvif->role_id; | 1012 | ps_params->role_id = wlvif->role_id; |
1013 | ps_params->ps_mode = ps_mode; | 1013 | ps_params->ps_mode = ps_mode; |
1014 | ps_params->auto_ps_timeout = auto_ps_timeout; | ||
1014 | 1015 | ||
1015 | ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, | 1016 | ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, |
1016 | sizeof(*ps_params), 0); | 1017 | sizeof(*ps_params), 0); |
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index edd240db0dcc..83a2a2edb261 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h | |||
@@ -51,7 +51,7 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); | |||
51 | int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); | 51 | int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); |
52 | int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); | 52 | int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); |
53 | int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 53 | int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
54 | u8 ps_mode); | 54 | u8 ps_mode, u16 auto_ps_timeout); |
55 | int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, | 55 | int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, |
56 | size_t len); | 56 | size_t len); |
57 | int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id, | 57 | int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id, |
@@ -400,6 +400,7 @@ struct wl1271_tim { | |||
400 | } __packed; | 400 | } __packed; |
401 | 401 | ||
402 | enum wl1271_cmd_ps_mode { | 402 | enum wl1271_cmd_ps_mode { |
403 | STATION_AUTO_PS_MODE, /* Dynamic Power Save */ | ||
403 | STATION_ACTIVE_MODE, | 404 | STATION_ACTIVE_MODE, |
404 | STATION_POWER_SAVE_MODE | 405 | STATION_POWER_SAVE_MODE |
405 | }; | 406 | }; |
@@ -409,7 +410,7 @@ struct wl1271_cmd_ps_params { | |||
409 | 410 | ||
410 | u8 role_id; | 411 | u8 role_id; |
411 | u8 ps_mode; /* STATION_* */ | 412 | u8 ps_mode; /* STATION_* */ |
412 | u8 padding[2]; | 413 | u16 auto_ps_timeout; |
413 | } __packed; | 414 | } __packed; |
414 | 415 | ||
415 | /* HW encryption keys */ | 416 | /* HW encryption keys */ |
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index 47cf80f0b036..10e5e3df4b95 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h | |||
@@ -915,6 +915,12 @@ struct conf_conn_settings { | |||
915 | u8 psm_entry_nullfunc_retries; | 915 | u8 psm_entry_nullfunc_retries; |
916 | 916 | ||
917 | /* | 917 | /* |
918 | * Specifies the dynamic PS timeout in ms that will be used | ||
919 | * by the FW when in AUTO_PS mode | ||
920 | */ | ||
921 | u16 dynamic_ps_timeout; | ||
922 | |||
923 | /* | ||
918 | * | 924 | * |
919 | * Specifies the interval of the connection keep-alive null-func | 925 | * Specifies the interval of the connection keep-alive null-func |
920 | * frame in ms. | 926 | * frame in ms. |
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index 05cd2ce927c6..c953717f38eb 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c | |||
@@ -78,21 +78,13 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
78 | static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl, | 78 | static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl, |
79 | u8 enable) | 79 | u8 enable) |
80 | { | 80 | { |
81 | struct ieee80211_vif *vif; | ||
82 | struct wl12xx_vif *wlvif; | 81 | struct wl12xx_vif *wlvif; |
83 | 82 | ||
84 | if (enable) { | 83 | if (enable) { |
85 | /* disable dynamic PS when requested by the firmware */ | ||
86 | wl12xx_for_each_wlvif_sta(wl, wlvif) { | ||
87 | vif = wl12xx_wlvif_to_vif(wlvif); | ||
88 | ieee80211_disable_dyn_ps(vif); | ||
89 | } | ||
90 | set_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags); | 84 | set_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags); |
91 | } else { | 85 | } else { |
92 | clear_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags); | 86 | clear_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags); |
93 | wl12xx_for_each_wlvif_sta(wl, wlvif) { | 87 | wl12xx_for_each_wlvif_sta(wl, wlvif) { |
94 | vif = wl12xx_wlvif_to_vif(wlvif); | ||
95 | ieee80211_enable_dyn_ps(vif); | ||
96 | wl1271_recalc_rx_streaming(wl, wlvif); | 88 | wl1271_recalc_rx_streaming(wl, wlvif); |
97 | } | 89 | } |
98 | } | 90 | } |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 74d4abb25ab1..6b240868ac75 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | /* | 2 | /* |
2 | * This file is part of wl1271 | 3 | * This file is part of wl1271 |
3 | * | 4 | * |
@@ -240,6 +241,7 @@ static struct conf_drv_settings default_conf = { | |||
240 | .psm_entry_retries = 8, | 241 | .psm_entry_retries = 8, |
241 | .psm_exit_retries = 16, | 242 | .psm_exit_retries = 16, |
242 | .psm_entry_nullfunc_retries = 3, | 243 | .psm_entry_nullfunc_retries = 3, |
244 | .dynamic_ps_timeout = 100, | ||
243 | .keep_alive_interval = 55000, | 245 | .keep_alive_interval = 55000, |
244 | .max_listen_interval = 20, | 246 | .max_listen_interval = 20, |
245 | }, | 247 | }, |
@@ -2142,10 +2144,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, | |||
2142 | 2144 | ||
2143 | wl1271_info("down"); | 2145 | wl1271_info("down"); |
2144 | 2146 | ||
2145 | /* enable dyn ps just in case (if left on due to fw crash etc) */ | ||
2146 | if (wlvif->bss_type == BSS_TYPE_STA_BSS) | ||
2147 | ieee80211_enable_dyn_ps(vif); | ||
2148 | |||
2149 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE && | 2147 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE && |
2150 | wl->scan_vif == vif) { | 2148 | wl->scan_vif == vif) { |
2151 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 2149 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
@@ -3694,9 +3692,6 @@ sta_not_found: | |||
3694 | dev_kfree_skb(wlvif->probereq); | 3692 | dev_kfree_skb(wlvif->probereq); |
3695 | wlvif->probereq = NULL; | 3693 | wlvif->probereq = NULL; |
3696 | 3694 | ||
3697 | /* re-enable dynamic ps - just in case */ | ||
3698 | ieee80211_enable_dyn_ps(vif); | ||
3699 | |||
3700 | /* revert back to minimum rates for the current band */ | 3695 | /* revert back to minimum rates for the current band */ |
3701 | wl1271_set_band_rate(wl, wlvif); | 3696 | wl1271_set_band_rate(wl, wlvif); |
3702 | wlvif->basic_rate = | 3697 | wlvif->basic_rate = |
@@ -3827,10 +3822,9 @@ sta_not_found: | |||
3827 | /* If we want to go in PSM but we're not there yet */ | 3822 | /* If we want to go in PSM but we're not there yet */ |
3828 | if (test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags) && | 3823 | if (test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags) && |
3829 | !test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) { | 3824 | !test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) { |
3830 | enum wl1271_cmd_ps_mode mode; | ||
3831 | 3825 | ||
3832 | mode = STATION_POWER_SAVE_MODE; | 3826 | ret = wl1271_ps_set_mode(wl, wlvif, |
3833 | ret = wl1271_ps_set_mode(wl, wlvif, mode, | 3827 | STATION_AUTO_PS_MODE, |
3834 | wlvif->basic_rate, | 3828 | wlvif->basic_rate, |
3835 | true); | 3829 | true); |
3836 | if (ret < 0) | 3830 | if (ret < 0) |
@@ -4976,6 +4970,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) | |||
4976 | 4970 | ||
4977 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | | 4971 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | |
4978 | IEEE80211_HW_SUPPORTS_PS | | 4972 | IEEE80211_HW_SUPPORTS_PS | |
4973 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | | ||
4979 | IEEE80211_HW_SUPPORTS_UAPSD | | 4974 | IEEE80211_HW_SUPPORTS_UAPSD | |
4980 | IEEE80211_HW_HAS_RATE_CONTROL | | 4975 | IEEE80211_HW_HAS_RATE_CONTROL | |
4981 | IEEE80211_HW_CONNECTION_MONITOR | | 4976 | IEEE80211_HW_CONNECTION_MONITOR | |
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index a2bdacdd7e1d..60f03c4dfbe7 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c | |||
@@ -163,10 +163,12 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
163 | enum wl1271_cmd_ps_mode mode, u32 rates, bool send) | 163 | enum wl1271_cmd_ps_mode mode, u32 rates, bool send) |
164 | { | 164 | { |
165 | int ret; | 165 | int ret; |
166 | u16 timeout = wl->conf.conn.dynamic_ps_timeout; | ||
166 | 167 | ||
167 | switch (mode) { | 168 | switch (mode) { |
168 | case STATION_POWER_SAVE_MODE: | 169 | case STATION_AUTO_PS_MODE: |
169 | wl1271_debug(DEBUG_PSM, "entering psm"); | 170 | wl1271_debug(DEBUG_PSM, "entering psm (mode=%d,timeout=%u)", |
171 | mode, timeout); | ||
170 | 172 | ||
171 | ret = wl1271_acx_wake_up_conditions(wl, wlvif); | 173 | ret = wl1271_acx_wake_up_conditions(wl, wlvif); |
172 | if (ret < 0) { | 174 | if (ret < 0) { |
@@ -174,14 +176,13 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
174 | return ret; | 176 | return ret; |
175 | } | 177 | } |
176 | 178 | ||
177 | ret = wl1271_cmd_ps_mode(wl, wlvif, STATION_POWER_SAVE_MODE); | 179 | ret = wl1271_cmd_ps_mode(wl, wlvif, mode, timeout); |
178 | if (ret < 0) | 180 | if (ret < 0) |
179 | return ret; | 181 | return ret; |
180 | 182 | ||
181 | set_bit(WLVIF_FLAG_PSM, &wlvif->flags); | 183 | set_bit(WLVIF_FLAG_PSM, &wlvif->flags); |
182 | break; | 184 | break; |
183 | case STATION_ACTIVE_MODE: | 185 | case STATION_ACTIVE_MODE: |
184 | default: | ||
185 | wl1271_debug(DEBUG_PSM, "leaving psm"); | 186 | wl1271_debug(DEBUG_PSM, "leaving psm"); |
186 | 187 | ||
187 | /* disable beacon early termination */ | 188 | /* disable beacon early termination */ |
@@ -191,12 +192,16 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
191 | return ret; | 192 | return ret; |
192 | } | 193 | } |
193 | 194 | ||
194 | ret = wl1271_cmd_ps_mode(wl, wlvif, STATION_ACTIVE_MODE); | 195 | ret = wl1271_cmd_ps_mode(wl, wlvif, mode, 0); |
195 | if (ret < 0) | 196 | if (ret < 0) |
196 | return ret; | 197 | return ret; |
197 | 198 | ||
198 | clear_bit(WLVIF_FLAG_PSM, &wlvif->flags); | 199 | clear_bit(WLVIF_FLAG_PSM, &wlvif->flags); |
199 | break; | 200 | break; |
201 | case STATION_POWER_SAVE_MODE: | ||
202 | default: | ||
203 | wl1271_warning("trying to set ps to unsupported mode %d", mode); | ||
204 | ret = -EINVAL; | ||
200 | } | 205 | } |
201 | 206 | ||
202 | return ret; | 207 | return ret; |