mirror of
https://github.com/torvalds/linux.git
synced 2024-12-21 02:21:36 +00:00
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>
This commit is contained in:
parent
d6bf9ada92
commit
f1d63a5963
@ -996,7 +996,7 @@ out:
|
||||
}
|
||||
|
||||
int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
u8 ps_mode)
|
||||
u8 ps_mode, u16 auto_ps_timeout)
|
||||
{
|
||||
struct wl1271_cmd_ps_params *ps_params = NULL;
|
||||
int ret = 0;
|
||||
@ -1011,6 +1011,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
|
||||
ps_params->role_id = wlvif->role_id;
|
||||
ps_params->ps_mode = ps_mode;
|
||||
ps_params->auto_ps_timeout = auto_ps_timeout;
|
||||
|
||||
ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
|
||||
sizeof(*ps_params), 0);
|
||||
|
@ -51,7 +51,7 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
|
||||
int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
|
||||
int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
|
||||
int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
u8 ps_mode);
|
||||
u8 ps_mode, u16 auto_ps_timeout);
|
||||
int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
|
||||
size_t len);
|
||||
int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
|
||||
@ -400,6 +400,7 @@ struct wl1271_tim {
|
||||
} __packed;
|
||||
|
||||
enum wl1271_cmd_ps_mode {
|
||||
STATION_AUTO_PS_MODE, /* Dynamic Power Save */
|
||||
STATION_ACTIVE_MODE,
|
||||
STATION_POWER_SAVE_MODE
|
||||
};
|
||||
@ -409,7 +410,7 @@ struct wl1271_cmd_ps_params {
|
||||
|
||||
u8 role_id;
|
||||
u8 ps_mode; /* STATION_* */
|
||||
u8 padding[2];
|
||||
u16 auto_ps_timeout;
|
||||
} __packed;
|
||||
|
||||
/* HW encryption keys */
|
||||
|
@ -914,6 +914,12 @@ struct conf_conn_settings {
|
||||
*/
|
||||
u8 psm_entry_nullfunc_retries;
|
||||
|
||||
/*
|
||||
* Specifies the dynamic PS timeout in ms that will be used
|
||||
* by the FW when in AUTO_PS mode
|
||||
*/
|
||||
u16 dynamic_ps_timeout;
|
||||
|
||||
/*
|
||||
*
|
||||
* Specifies the interval of the connection keep-alive null-func
|
||||
|
@ -78,21 +78,13 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl,
|
||||
u8 enable)
|
||||
{
|
||||
struct ieee80211_vif *vif;
|
||||
struct wl12xx_vif *wlvif;
|
||||
|
||||
if (enable) {
|
||||
/* disable dynamic PS when requested by the firmware */
|
||||
wl12xx_for_each_wlvif_sta(wl, wlvif) {
|
||||
vif = wl12xx_wlvif_to_vif(wlvif);
|
||||
ieee80211_disable_dyn_ps(vif);
|
||||
}
|
||||
set_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags);
|
||||
} else {
|
||||
clear_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags);
|
||||
wl12xx_for_each_wlvif_sta(wl, wlvif) {
|
||||
vif = wl12xx_wlvif_to_vif(wlvif);
|
||||
ieee80211_enable_dyn_ps(vif);
|
||||
wl1271_recalc_rx_streaming(wl, wlvif);
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* This file is part of wl1271
|
||||
*
|
||||
@ -240,6 +241,7 @@ static struct conf_drv_settings default_conf = {
|
||||
.psm_entry_retries = 8,
|
||||
.psm_exit_retries = 16,
|
||||
.psm_entry_nullfunc_retries = 3,
|
||||
.dynamic_ps_timeout = 100,
|
||||
.keep_alive_interval = 55000,
|
||||
.max_listen_interval = 20,
|
||||
},
|
||||
@ -2142,10 +2144,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
|
||||
|
||||
wl1271_info("down");
|
||||
|
||||
/* enable dyn ps just in case (if left on due to fw crash etc) */
|
||||
if (wlvif->bss_type == BSS_TYPE_STA_BSS)
|
||||
ieee80211_enable_dyn_ps(vif);
|
||||
|
||||
if (wl->scan.state != WL1271_SCAN_STATE_IDLE &&
|
||||
wl->scan_vif == vif) {
|
||||
wl->scan.state = WL1271_SCAN_STATE_IDLE;
|
||||
@ -3694,9 +3692,6 @@ sta_not_found:
|
||||
dev_kfree_skb(wlvif->probereq);
|
||||
wlvif->probereq = NULL;
|
||||
|
||||
/* re-enable dynamic ps - just in case */
|
||||
ieee80211_enable_dyn_ps(vif);
|
||||
|
||||
/* revert back to minimum rates for the current band */
|
||||
wl1271_set_band_rate(wl, wlvif);
|
||||
wlvif->basic_rate =
|
||||
@ -3827,10 +3822,9 @@ sta_not_found:
|
||||
/* If we want to go in PSM but we're not there yet */
|
||||
if (test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags) &&
|
||||
!test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) {
|
||||
enum wl1271_cmd_ps_mode mode;
|
||||
|
||||
mode = STATION_POWER_SAVE_MODE;
|
||||
ret = wl1271_ps_set_mode(wl, wlvif, mode,
|
||||
ret = wl1271_ps_set_mode(wl, wlvif,
|
||||
STATION_AUTO_PS_MODE,
|
||||
wlvif->basic_rate,
|
||||
true);
|
||||
if (ret < 0)
|
||||
@ -4976,6 +4970,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
|
||||
|
||||
wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
|
||||
IEEE80211_HW_SUPPORTS_PS |
|
||||
IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
|
||||
IEEE80211_HW_SUPPORTS_UAPSD |
|
||||
IEEE80211_HW_HAS_RATE_CONTROL |
|
||||
IEEE80211_HW_CONNECTION_MONITOR |
|
||||
|
@ -163,10 +163,12 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
enum wl1271_cmd_ps_mode mode, u32 rates, bool send)
|
||||
{
|
||||
int ret;
|
||||
u16 timeout = wl->conf.conn.dynamic_ps_timeout;
|
||||
|
||||
switch (mode) {
|
||||
case STATION_POWER_SAVE_MODE:
|
||||
wl1271_debug(DEBUG_PSM, "entering psm");
|
||||
case STATION_AUTO_PS_MODE:
|
||||
wl1271_debug(DEBUG_PSM, "entering psm (mode=%d,timeout=%u)",
|
||||
mode, timeout);
|
||||
|
||||
ret = wl1271_acx_wake_up_conditions(wl, wlvif);
|
||||
if (ret < 0) {
|
||||
@ -174,14 +176,13 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wl1271_cmd_ps_mode(wl, wlvif, STATION_POWER_SAVE_MODE);
|
||||
ret = wl1271_cmd_ps_mode(wl, wlvif, mode, timeout);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
set_bit(WLVIF_FLAG_PSM, &wlvif->flags);
|
||||
break;
|
||||
case STATION_ACTIVE_MODE:
|
||||
default:
|
||||
wl1271_debug(DEBUG_PSM, "leaving psm");
|
||||
|
||||
/* disable beacon early termination */
|
||||
@ -191,12 +192,16 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wl1271_cmd_ps_mode(wl, wlvif, STATION_ACTIVE_MODE);
|
||||
ret = wl1271_cmd_ps_mode(wl, wlvif, mode, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
clear_bit(WLVIF_FLAG_PSM, &wlvif->flags);
|
||||
break;
|
||||
case STATION_POWER_SAVE_MODE:
|
||||
default:
|
||||
wl1271_warning("trying to set ps to unsupported mode %d", mode);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user