diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-power.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 0b16841f45f4..081a7ea40c6c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -216,8 +216,27 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, | |||
216 | struct iwl_powertable_cmd *cmd, | 216 | struct iwl_powertable_cmd *cmd, |
217 | int dynps_ms, int wakeup_period) | 217 | int dynps_ms, int wakeup_period) |
218 | { | 218 | { |
219 | /* | ||
220 | * These are the original power level 3 sleep successions. The | ||
221 | * device may behave better with such succession and was also | ||
222 | * only tested with that. Just like the original sleep commands, | ||
223 | * also adjust the succession here to the wakeup_period below. | ||
224 | * The ranges are the same as for the sleep commands, 0-2, 3-9 | ||
225 | * and >10, which is selected based on the DTIM interval for | ||
226 | * the sleep index but here we use the wakeup period since that | ||
227 | * is what we need to do for the latency requirements. | ||
228 | */ | ||
229 | static const u8 slp_succ_r0[IWL_POWER_VEC_SIZE] = { 2, 2, 2, 2, 2 }; | ||
230 | static const u8 slp_succ_r1[IWL_POWER_VEC_SIZE] = { 2, 4, 6, 7, 9 }; | ||
231 | static const u8 slp_succ_r2[IWL_POWER_VEC_SIZE] = { 2, 7, 9, 9, 0xFF }; | ||
232 | const u8 *slp_succ = slp_succ_r0; | ||
219 | int i; | 233 | int i; |
220 | 234 | ||
235 | if (wakeup_period > IWL_DTIM_RANGE_0_MAX) | ||
236 | slp_succ = slp_succ_r1; | ||
237 | if (wakeup_period > IWL_DTIM_RANGE_1_MAX) | ||
238 | slp_succ = slp_succ_r2; | ||
239 | |||
221 | memset(cmd, 0, sizeof(*cmd)); | 240 | memset(cmd, 0, sizeof(*cmd)); |
222 | 241 | ||
223 | cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK | | 242 | cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK | |
@@ -230,7 +249,8 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, | |||
230 | cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms); | 249 | cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms); |
231 | 250 | ||
232 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) | 251 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) |
233 | cmd->sleep_interval[i] = cpu_to_le32(wakeup_period); | 252 | cmd->sleep_interval[i] = |
253 | cpu_to_le32(min_t(int, slp_succ[i], wakeup_period)); | ||
234 | 254 | ||
235 | IWL_DEBUG_POWER(priv, "Automatic sleep command\n"); | 255 | IWL_DEBUG_POWER(priv, "Automatic sleep command\n"); |
236 | } | 256 | } |