Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6449126 authored by Johannes Berg's avatar Johannes Berg Committed by Luca Coelho
Browse files

iwlwifi: mvm: correct skip-over-DTIM implementation



The formula used in D0i3 should also be used in D3, instead of
the hardcoded value.

Additionally, the formula is actually wrong - if the calculation
yields 0 then 1 should be used instead of disabling entirely.
Also need to add 1 since the firmware needs 3 to skip 2, etc.

To make all this clearer, centralize the calculation into a
single function.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent bb35dc14
Loading
Loading
Loading
Loading
+46 −28
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
 *
 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
 * Copyright(c) 2015        Intel Deutschland GmbH
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
@@ -33,6 +34,7 @@
 *
 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
 * Copyright(c) 2015        Intel Deutschland GmbH
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -306,13 +308,50 @@ static bool iwl_mvm_power_is_radar(struct ieee80211_vif *vif)
	return radar_detect;
}

static void iwl_mvm_power_config_skip_dtim(struct iwl_mvm *mvm,
					   struct ieee80211_vif *vif,
					   struct iwl_mac_power_cmd *cmd,
					   bool host_awake)
{
	int dtimper = vif->bss_conf.dtim_period ?: 1;
	int skip;

	/* disable, in case we're supposed to override */
	cmd->skip_dtim_periods = 0;
	cmd->flags &= ~cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);

	if (iwl_mvm_power_is_radar(vif))
		return;

	if (dtimper >= 10)
		return;

	/* TODO: check that multicast wake lock is off */

	if (host_awake) {
		if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_LP)
			return;
		skip = 2;
	} else {
		int dtimper_tu = dtimper * vif->bss_conf.beacon_int;

		if (WARN_ON(!dtimper_tu))
			return;
		/* configure skip over dtim up to 306TU - 314 msec */
		skip = max_t(u8, 1, 306 / dtimper_tu);
	}

	/* the firmware really expects "look at every X DTIMs", so add 1 */
	cmd->skip_dtim_periods = 1 + skip;
	cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
}

static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
				    struct ieee80211_vif *vif,
				    struct iwl_mac_power_cmd *cmd)
{
	int dtimper, bi;
	int keep_alive;
	bool radar_detect = false;
	struct iwl_mvm_vif *mvmvif __maybe_unused =
		iwl_mvm_vif_from_mac80211(vif);

@@ -350,16 +389,8 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
		cmd->lprx_rssi_threshold = POWER_LPRX_RSSI_THRESHOLD;
	}

	/* Check if radar detection is required on current channel */
	radar_detect = iwl_mvm_power_is_radar(vif);

	/* Check skip over DTIM conditions */
	if (!radar_detect && (dtimper < 10) &&
	    (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP ||
	     mvm->cur_ucode == IWL_UCODE_WOWLAN)) {
		cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
		cmd->skip_dtim_periods = 3;
	}
	iwl_mvm_power_config_skip_dtim(mvm, vif, cmd,
				       mvm->cur_ucode != IWL_UCODE_WOWLAN);

	if (mvm->cur_ucode != IWL_UCODE_WOWLAN) {
		cmd->rx_data_timeout =
@@ -964,24 +995,11 @@ int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
		return 0;

	iwl_mvm_power_build_cmd(mvm, vif, &cmd);
	if (enable) {
		/* configure skip over dtim up to 306TU - 314 msec */
		int dtimper = vif->bss_conf.dtim_period ?: 1;
		int dtimper_tu = dtimper * vif->bss_conf.beacon_int;
		bool radar_detect = iwl_mvm_power_is_radar(vif);

		if (WARN_ON(!dtimper_tu))
			return 0;
	/* when enabling D0i3, override the skip-over-dtim configuration */
	if (enable)
		iwl_mvm_power_config_skip_dtim(mvm, vif, &cmd, false);

		/* Check skip over DTIM conditions */
		/* TODO: check that multicast wake lock is off */
		if (!radar_detect && (dtimper < 10)) {
			cmd.skip_dtim_periods = 306 / dtimper_tu;
			if (cmd.skip_dtim_periods)
				cmd.flags |= cpu_to_le16(
					POWER_FLAGS_SKIP_OVER_DTIM_MSK);
		}
	}
	iwl_mvm_power_log(mvm, &cmd);
#ifdef CONFIG_IWLWIFI_DEBUGFS
	memcpy(&mvmvif->mac_pwr_cmd, &cmd, sizeof(cmd));