aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvri Altman <avri.altman@intel.com>2014-10-02 13:46:16 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-11-23 12:59:19 -0500
commit886ca9f5dd1129df2ca31ab2f43299658568cbbe (patch)
tree7a77601d68af122b1f6ee78c2721fa7612e1aeda
parent088070a2f6575402d3dd82e1c5a4a8e1941805f6 (diff)
iwlwifi: mvm: New skip over dtim policy
Our firmware scheduler suffers from false wake-up on 500 time units. that is if the dtim interval exceeds 500 time units, the fw wakes up, understands that the next wake-up event is still ahead, and if this event is more than 10msec in the future - goes back to sleep, otherwise - stay awake. For example, say that the beacon interval is 101 and the dtim period is 5, the dtim interval is 101 x 5 = 505, and we will stay awake for those extra 5msec. So on the one hand the dtim interval should be congruent to the beacon interval times the dtim period, and on the other should minimize the false wake-ups event. This change applies only to D0/D3 power modes. Signed-off-by: Avri Altman <avri.altman@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 5b85b0cc7a2a..cb653ac10412 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -286,6 +286,27 @@ static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
286 return true; 286 return true;
287} 287}
288 288
289static int iwl_mvm_power_get_skip_over_dtim(int dtimper, int bi)
290{
291 int numerator;
292 int dtim_interval = dtimper * bi;
293
294 if (WARN_ON(!dtim_interval))
295 return 0;
296
297 if (dtimper == 1) {
298 if (bi > 100)
299 numerator = 408;
300 else
301 numerator = 510;
302 } else if (dtimper < 10) {
303 numerator = 612;
304 } else {
305 return 0;
306 }
307 return max(1, (numerator / dtim_interval));
308}
309
289static bool iwl_mvm_power_is_radar(struct ieee80211_vif *vif) 310static bool iwl_mvm_power_is_radar(struct ieee80211_vif *vif)
290{ 311{
291 struct ieee80211_chanctx_conf *chanctx_conf; 312 struct ieee80211_chanctx_conf *chanctx_conf;
@@ -308,7 +329,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
308 struct ieee80211_vif *vif, 329 struct ieee80211_vif *vif,
309 struct iwl_mac_power_cmd *cmd) 330 struct iwl_mac_power_cmd *cmd)
310{ 331{
311 int dtimper, dtimper_msec; 332 int dtimper, dtimper_msec, bi;
312 int keep_alive; 333 int keep_alive;
313 bool radar_detect = false; 334 bool radar_detect = false;
314 struct iwl_mvm_vif *mvmvif __maybe_unused = 335 struct iwl_mvm_vif *mvmvif __maybe_unused =
@@ -317,6 +338,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
317 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, 338 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
318 mvmvif->color)); 339 mvmvif->color));
319 dtimper = vif->bss_conf.dtim_period; 340 dtimper = vif->bss_conf.dtim_period;
341 bi = vif->bss_conf.beacon_int;
320 342
321 /* 343 /*
322 * Regardless of power management state the driver must set 344 * Regardless of power management state the driver must set
@@ -324,7 +346,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
324 * immediately after association. Check that keep alive period 346 * immediately after association. Check that keep alive period
325 * is at least 3 * DTIM 347 * is at least 3 * DTIM
326 */ 348 */
327 dtimper_msec = dtimper * vif->bss_conf.beacon_int; 349 dtimper_msec = dtimper * bi;
328 keep_alive = max_t(int, 3 * dtimper_msec, 350 keep_alive = max_t(int, 3 * dtimper_msec,
329 MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC); 351 MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC);
330 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); 352 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
@@ -352,11 +374,14 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
352 radar_detect = iwl_mvm_power_is_radar(vif); 374 radar_detect = iwl_mvm_power_is_radar(vif);
353 375
354 /* Check skip over DTIM conditions */ 376 /* Check skip over DTIM conditions */
355 if (!radar_detect && (dtimper <= 10) && 377 if (!radar_detect && (dtimper < 10) &&
356 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP || 378 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP ||
357 mvm->cur_ucode == IWL_UCODE_WOWLAN)) { 379 mvm->cur_ucode == IWL_UCODE_WOWLAN)) {
358 cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); 380 cmd->skip_dtim_periods =
359 cmd->skip_dtim_periods = 3; 381 iwl_mvm_power_get_skip_over_dtim(dtimper, bi);
382 if (cmd->skip_dtim_periods)
383 cmd->flags |=
384 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
360 } 385 }
361 386
362 if (mvm->cur_ucode != IWL_UCODE_WOWLAN) { 387 if (mvm->cur_ucode != IWL_UCODE_WOWLAN) {