aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEyal Shapira <eyal@wizery.com>2012-01-31 04:57:21 -0500
committerLuciano Coelho <coelho@ti.com>2012-02-15 01:38:31 -0500
commitf1d63a59635feef3481ed1972a883a5d6be7f9bb (patch)
tree835d3e246d7d310ff51d2576ffc9f1f7b1808caa
parentd6bf9ada92c113e56151b6a993b9b9d5d03f1365 (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.c3
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h5
-rw-r--r--drivers/net/wireless/wl12xx/conf.h6
-rw-r--r--drivers/net/wireless/wl12xx/event.c8
-rw-r--r--drivers/net/wireless/wl12xx/main.c15
-rw-r--r--drivers/net/wireless/wl12xx/ps.c15
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
998int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, 998int 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);
51int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); 51int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
52int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); 52int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
53int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, 53int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
54 u8 ps_mode); 54 u8 ps_mode, u16 auto_ps_timeout);
55int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, 55int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
56 size_t len); 56 size_t len);
57int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id, 57int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
@@ -400,6 +400,7 @@ struct wl1271_tim {
400} __packed; 400} __packed;
401 401
402enum wl1271_cmd_ps_mode { 402enum 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)
78static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl, 78static 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;