提交 886ca9f5 编写于 作者: A Avri Altman 提交者: Emmanuel Grumbach

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: NAvri Altman <avri.altman@intel.com>
Signed-off-by: NEmmanuel Grumbach <emmanuel.grumbach@intel.com>
上级 088070a2
...@@ -286,6 +286,27 @@ static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm, ...@@ -286,6 +286,27 @@ static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
return true; return true;
} }
static int iwl_mvm_power_get_skip_over_dtim(int dtimper, int bi)
{
int numerator;
int dtim_interval = dtimper * bi;
if (WARN_ON(!dtim_interval))
return 0;
if (dtimper == 1) {
if (bi > 100)
numerator = 408;
else
numerator = 510;
} else if (dtimper < 10) {
numerator = 612;
} else {
return 0;
}
return max(1, (numerator / dtim_interval));
}
static bool iwl_mvm_power_is_radar(struct ieee80211_vif *vif) static bool iwl_mvm_power_is_radar(struct ieee80211_vif *vif)
{ {
struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_chanctx_conf *chanctx_conf;
...@@ -308,7 +329,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, ...@@ -308,7 +329,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct iwl_mac_power_cmd *cmd) struct iwl_mac_power_cmd *cmd)
{ {
int dtimper, dtimper_msec; int dtimper, dtimper_msec, bi;
int keep_alive; int keep_alive;
bool radar_detect = false; bool radar_detect = false;
struct iwl_mvm_vif *mvmvif __maybe_unused = struct iwl_mvm_vif *mvmvif __maybe_unused =
...@@ -317,6 +338,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, ...@@ -317,6 +338,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
mvmvif->color)); mvmvif->color));
dtimper = vif->bss_conf.dtim_period; dtimper = vif->bss_conf.dtim_period;
bi = vif->bss_conf.beacon_int;
/* /*
* Regardless of power management state the driver must set * 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,7 +346,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
* immediately after association. Check that keep alive period * immediately after association. Check that keep alive period
* is at least 3 * DTIM * is at least 3 * DTIM
*/ */
dtimper_msec = dtimper * vif->bss_conf.beacon_int; dtimper_msec = dtimper * bi;
keep_alive = max_t(int, 3 * dtimper_msec, keep_alive = max_t(int, 3 * dtimper_msec,
MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC); MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC);
keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); 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,11 +374,14 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
radar_detect = iwl_mvm_power_is_radar(vif); radar_detect = iwl_mvm_power_is_radar(vif);
/* Check skip over DTIM conditions */ /* Check skip over DTIM conditions */
if (!radar_detect && (dtimper <= 10) && if (!radar_detect && (dtimper < 10) &&
(iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP || (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP ||
mvm->cur_ucode == IWL_UCODE_WOWLAN)) { mvm->cur_ucode == IWL_UCODE_WOWLAN)) {
cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); cmd->skip_dtim_periods =
cmd->skip_dtim_periods = 3; iwl_mvm_power_get_skip_over_dtim(dtimper, bi);
if (cmd->skip_dtim_periods)
cmd->flags |=
cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
} }
if (mvm->cur_ucode != IWL_UCODE_WOWLAN) { if (mvm->cur_ucode != IWL_UCODE_WOWLAN) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册