diff options
author | Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com> | 2011-07-07 22:12:01 +0200 |
---|---|---|
committer | Philippe LANGLAIS <philippe.langlais@stericsson.com> | 2011-10-12 13:44:49 +0200 |
commit | 7fe82611337427cea5c6eae91df202b8a2985252 (patch) | |
tree | 77381f020e952e1e1cda7a61d79c0418d106bd70 | |
parent | 033b8d2a992e339e2dfdeb83144efa41695e4068 (diff) |
cw1200: Dynamic power save is offloaded to the firmware.
Signed-off-by: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
Change-Id: Iff214651c82fe1f7203f3ce016e7646e41cccc35
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/27071
Reviewed-by: Bartosz MARKOWSKI <bartosz.markowski@tieto.com>
Tested-by: Bartosz MARKOWSKI <bartosz.markowski@tieto.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/33478
Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com>
-rw-r--r-- | drivers/staging/cw1200/debug.c | 15 | ||||
-rw-r--r-- | drivers/staging/cw1200/main.c | 1 | ||||
-rw-r--r-- | drivers/staging/cw1200/scan.c | 4 | ||||
-rw-r--r-- | drivers/staging/cw1200/sta.c | 19 | ||||
-rw-r--r-- | drivers/staging/cw1200/wsm.c | 5 | ||||
-rw-r--r-- | drivers/staging/cw1200/wsm.h | 10 |
6 files changed, 41 insertions, 13 deletions
diff --git a/drivers/staging/cw1200/debug.c b/drivers/staging/cw1200/debug.c index 13c4570372f..612c74a7174 100644 --- a/drivers/staging/cw1200/debug.c +++ b/drivers/staging/cw1200/debug.c @@ -153,6 +153,18 @@ static int cw1200_status_show(struct seq_file *seq, void *v) priv->edca.params[i].maxReceiveLifetime); } if (priv->join_status == CW1200_JOIN_STATUS_STA) { + static const char *pmMode = "unknown"; + switch (priv->powersave_mode.pmMode) { + case WSM_PSM_ACTIVE: + pmMode = "off"; + break; + case WSM_PSM_PS: + pmMode = "on"; + break; + case WSM_PSM_FAST_PS: + pmMode = "dynamic"; + break; + } seq_printf(seq, "Preamble: %s\n", cw1200_debug_preamble[ priv->association_mode.preambleType]); @@ -166,8 +178,7 @@ static int cw1200_status_show(struct seq_file *seq, void *v) priv->bss_params.aid); seq_printf(seq, "Rates: 0x%.8X\n", priv->bss_params.operationalRateSet); - seq_printf(seq, "Powersave: %s\n", - priv->powersave_mode.pmMode ? "off" : "on"); + seq_printf(seq, "Powersave: %s\n", pmMode); } seq_printf(seq, "HT: %s\n", cw1200_is_ht(&priv->ht_info) ? "on" : "off"); diff --git a/drivers/staging/cw1200/main.c b/drivers/staging/cw1200/main.c index 7aef0ea1c60..f809ebc7584 100644 --- a/drivers/staging/cw1200/main.c +++ b/drivers/staging/cw1200/main.c @@ -242,6 +242,7 @@ struct ieee80211_hw *cw1200_init_common(size_t priv_data_len) hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_SUPPORTS_DYNAMIC_PS | /* IEEE80211_HW_SUPPORTS_UAPSD | */ IEEE80211_HW_CONNECTION_MONITOR | IEEE80211_HW_SUPPORTS_CQM_RSSI | diff --git a/drivers/staging/cw1200/scan.c b/drivers/staging/cw1200/scan.c index 71268291181..6e5b89c5635 100644 --- a/drivers/staging/cw1200/scan.c +++ b/drivers/staging/cw1200/scan.c @@ -88,7 +88,7 @@ int cw1200_hw_scan(struct ieee80211_hw *hw, wsm_lock_tx(priv); if (priv->join_status == CW1200_JOIN_STATUS_STA && - priv->powersave_mode.pmMode != WSM_PSM_PS) { + !(priv->powersave_mode.pmMode & WSM_PSM_PS)) { struct wsm_set_pm pm = priv->powersave_mode; pm.pmMode = WSM_PSM_PS; WARN_ON(wsm_set_pm(priv, &pm)); @@ -139,7 +139,7 @@ void cw1200_scan_work(struct work_struct *work) WARN_ON(wsm_set_output_power(priv, priv->output_power * 10)); if (priv->join_status == CW1200_JOIN_STATUS_STA && - priv->powersave_mode.pmMode != WSM_PSM_PS) + !(priv->powersave_mode.pmMode & WSM_PSM_PS)) WARN_ON(wsm_set_pm(priv, &priv->powersave_mode)); if (priv->scan.req) diff --git a/drivers/staging/cw1200/sta.c b/drivers/staging/cw1200/sta.c index a5b0f0ea759..fb5576f688a 100644 --- a/drivers/staging/cw1200/sta.c +++ b/drivers/staging/cw1200/sta.c @@ -285,9 +285,22 @@ int cw1200_config(struct ieee80211_hw *dev, u32 changed) } if (changed & IEEE80211_CONF_CHANGE_PS) { - priv->powersave_mode.pmMode = - (conf->flags & IEEE80211_CONF_PS) ? - WSM_PSM_PS : WSM_PSM_ACTIVE; + if (!(conf->flags & IEEE80211_CONF_PS)) + priv->powersave_mode.pmMode = WSM_PSM_ACTIVE; + else if (conf->dynamic_ps_timeout <= 0) + priv->powersave_mode.pmMode = WSM_PSM_PS; + else + priv->powersave_mode.pmMode = WSM_PSM_FAST_PS; + + /* Firmware requires that value for this 1-byte field must + * be specified in units of 500us. Values above the 128ms + * threshold are not supported. */ + if (conf->dynamic_ps_timeout >= 0x80) + priv->powersave_mode.fastPsmIdlePeriod = 0xFF; + else + priv->powersave_mode.fastPsmIdlePeriod = + conf->dynamic_ps_timeout << 1; + if (priv->join_status == CW1200_JOIN_STATUS_STA) WARN_ON(wsm_set_pm(priv, &priv->powersave_mode)); } diff --git a/drivers/staging/cw1200/wsm.c b/drivers/staging/cw1200/wsm.c index c562f982477..e8662fa6054 100644 --- a/drivers/staging/cw1200/wsm.c +++ b/drivers/staging/cw1200/wsm.c @@ -654,7 +654,10 @@ int wsm_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg) wsm_cmd_lock(priv); - WSM_PUT32(buf, arg->pmMode); + WSM_PUT8(buf, arg->pmMode); + WSM_PUT8(buf, arg->fastPsmIdlePeriod); + WSM_PUT8(buf, arg->apPsmChangePeriod); + WSM_PUT8(buf, arg->minAutoPsPollPeriod); ret = wsm_cmd_send(priv, buf, NULL, 0x0010, WSM_CMD_TIMEOUT); diff --git a/drivers/staging/cw1200/wsm.h b/drivers/staging/cw1200/wsm.h index 4d446e9b924..d8db64da9b3 100644 --- a/drivers/staging/cw1200/wsm.h +++ b/drivers/staging/cw1200/wsm.h @@ -133,16 +133,16 @@ struct cw1200_common; #define WSM_PSM_ACTIVE (0) /* 802.11 PS mode */ -#define WSM_PSM_PS (1) +#define WSM_PSM_PS BIT(0) + +/* Dynamic aka Fast power save */ +#define WSM_PSM_FAST_PS (BIT(0) | BIT(7)) /* Undetermined */ /* Note : Undetermined status is reported when the */ /* NULL data frame used to advertise the PM mode to */ /* the AP at Pre or Post Background Scan is not Acknowledged */ -#define WSM_PSM_UNKNOWN (2) - -/* Use this flag to enable the fast power-saving mode */ -#define WSM_PM_F_FAST_PSM_ENABLE (0x80) +#define WSM_PSM_UNKNOWN BIT(1) /* Queue IDs */ /* best effort/legacy */ |