Commit 4c561a02 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

iwlwifi: use sleep interval succession

Some concerns were raised about the automatic adjustment
of sleep intervals to all the same, potentially high,
value, and I can imagine the hardware behaving better
when we don't ask too much of it.

So let's convert to use a succession of sleep levels
when requesting to go to deeper sleeps (which can only
happen with large DTIM intervals), using the succession
values from power level three, which have the benefit of
also having been tested extensively already.

As a result, the automatic sleep level adjustment will
now be mostly equivalent to power level three, except
for the RX/TX timeouts and possibly using smaller sleep
vectors to account for networking latency.
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 31513be8
...@@ -216,8 +216,27 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, ...@@ -216,8 +216,27 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv,
struct iwl_powertable_cmd *cmd, struct iwl_powertable_cmd *cmd,
int dynps_ms, int wakeup_period) int dynps_ms, int wakeup_period)
{ {
/*
* These are the original power level 3 sleep successions. The
* device may behave better with such succession and was also
* only tested with that. Just like the original sleep commands,
* also adjust the succession here to the wakeup_period below.
* The ranges are the same as for the sleep commands, 0-2, 3-9
* and >10, which is selected based on the DTIM interval for
* the sleep index but here we use the wakeup period since that
* is what we need to do for the latency requirements.
*/
static const u8 slp_succ_r0[IWL_POWER_VEC_SIZE] = { 2, 2, 2, 2, 2 };
static const u8 slp_succ_r1[IWL_POWER_VEC_SIZE] = { 2, 4, 6, 7, 9 };
static const u8 slp_succ_r2[IWL_POWER_VEC_SIZE] = { 2, 7, 9, 9, 0xFF };
const u8 *slp_succ = slp_succ_r0;
int i; int i;
if (wakeup_period > IWL_DTIM_RANGE_0_MAX)
slp_succ = slp_succ_r1;
if (wakeup_period > IWL_DTIM_RANGE_1_MAX)
slp_succ = slp_succ_r2;
memset(cmd, 0, sizeof(*cmd)); memset(cmd, 0, sizeof(*cmd));
cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK | cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK |
...@@ -230,7 +249,8 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, ...@@ -230,7 +249,8 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv,
cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms); cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms);
for (i = 0; i < IWL_POWER_VEC_SIZE; i++) for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
cmd->sleep_interval[i] = cpu_to_le32(wakeup_period); cmd->sleep_interval[i] =
cpu_to_le32(min_t(int, slp_succ[i], wakeup_period));
IWL_DEBUG_POWER(priv, "Automatic sleep command\n"); IWL_DEBUG_POWER(priv, "Automatic sleep command\n");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment