Commit f1d63a59 authored by Eyal Shapira's avatar Eyal Shapira Committed by Luciano Coelho
Browse files

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: default avatarEyal Shapira <eyal@wizery.com>
Signed-off-by: default avatarEliad Peller <eliad@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent d6bf9ada
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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);
+3 −2
Original line number Diff line number Diff line
@@ -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 */
+6 −0
Original line number Diff line number Diff line
@@ -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
+0 −8
Original line number Diff line number Diff line
@@ -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);
		}
	}
+5 −10
Original line number Diff line number Diff line

/*
 * 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 |
Loading