diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index 80eafadc389d4cd272c940b2f5262204155bc518..823535cdf15044f407f3b6ed2a191eb2198c70a6 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -942,6 +942,12 @@ struct conf_conn_settings { */ u16 dynamic_ps_timeout; + /* + * Specifies whether dynamic PS should be disabled and PSM forced. + * This is required for certain WiFi certification tests. + */ + u8 forced_ps; + /* * * Specifies the interval of the connection keep-alive null-func diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index 15353fac070700b3a2516e6423b0124ace95a3fd..02da445ea98a8e4d9eaff5351caf429d645f9bb0 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -358,7 +358,7 @@ static ssize_t dynamic_ps_timeout_write(struct file *file, */ wl12xx_for_each_wlvif_sta(wl, wlvif) { - if (test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags)) + if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) wl1271_ps_set_mode(wl, wlvif, STATION_AUTO_PS_MODE); } diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index fa61dfd2084c222e7b4dbcf36b28c7029319d9bb..b828149a1655db6f73ee47d9606ddb79f336073c 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -247,6 +247,7 @@ static struct conf_drv_settings default_conf = { .psm_exit_retries = 16, .psm_entry_nullfunc_retries = 3, .dynamic_ps_timeout = 100, + .forced_ps = false, .keep_alive_interval = 55000, .max_listen_interval = 20, }, @@ -2510,17 +2511,29 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, if ((conf->flags & IEEE80211_CONF_PS) && test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) && - !test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags)) { + !test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) { - wl1271_debug(DEBUG_PSM, "auto ps enabled"); + int ps_mode; + char *ps_mode_str; + + if (wl->conf.conn.forced_ps) { + ps_mode = STATION_POWER_SAVE_MODE; + ps_mode_str = "forced"; + } else { + ps_mode = STATION_AUTO_PS_MODE; + ps_mode_str = "auto"; + } + + wl1271_debug(DEBUG_PSM, "%s ps enabled", ps_mode_str); + + ret = wl1271_ps_set_mode(wl, wlvif, ps_mode); - ret = wl1271_ps_set_mode(wl, wlvif, - STATION_AUTO_PS_MODE); if (ret < 0) - wl1271_warning("enter auto ps failed %d", ret); + wl1271_warning("enter %s ps failed %d", + ps_mode_str, ret); } else if (!(conf->flags & IEEE80211_CONF_PS) && - test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags)) { + test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) { wl1271_debug(DEBUG_PSM, "auto ps disabled"); diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index d1979223ad28677dc234901242cf00f604860129..23d67501c50a36f1fd26af309435a7b840799dc1 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c @@ -56,7 +56,7 @@ void wl1271_elp_work(struct work_struct *work) if (wlvif->bss_type == BSS_TYPE_AP_BSS) goto out; - if (!test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags) && + if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) && test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) goto out; } @@ -84,7 +84,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) if (wlvif->bss_type == BSS_TYPE_AP_BSS) return; - if (!test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags) && + if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) && test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) return; } @@ -167,6 +167,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, switch (mode) { case STATION_AUTO_PS_MODE: + case STATION_POWER_SAVE_MODE: wl1271_debug(DEBUG_PSM, "entering psm (mode=%d,timeout=%u)", mode, timeout); @@ -182,7 +183,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (ret < 0) return ret; - set_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags); + set_bit(WLVIF_FLAG_IN_PS, &wlvif->flags); /* enable beacon early termination. Not relevant for 5GHz */ if (wlvif->band == IEEE80211_BAND_2GHZ) { @@ -205,9 +206,8 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (ret < 0) return ret; - clear_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags); + clear_bit(WLVIF_FLAG_IN_PS, &wlvif->flags); break; - case STATION_POWER_SAVE_MODE: default: wl1271_warning("trying to set ps to unsupported mode %d", mode); ret = -EINVAL; diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 9baed6be6a31815336cbea83ee7cca87b14a9315..61c58c13fa906dfec39cbc744cc5afab71c10347 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -254,7 +254,7 @@ enum wl12xx_vif_flags { WLVIF_FLAG_STA_ASSOCIATED, WLVIF_FLAG_IBSS_JOINED, WLVIF_FLAG_AP_STARTED, - WLVIF_FLAG_IN_AUTO_PS, + WLVIF_FLAG_IN_PS, WLVIF_FLAG_STA_STATE_SENT, WLVIF_FLAG_RX_STREAMING_STARTED, WLVIF_FLAG_PSPOLL_FAILURE,