diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/power.c')
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/power.c | 117 | 
1 files changed, 45 insertions, 72 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 5a92a497879..ed77e437aac 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c @@ -22,7 +22,7 @@   * USA   *   * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING.   *   * Contact Information:   *  Intel Linux Wireless <ilw@linux.intel.com> @@ -75,23 +75,48 @@  #define POWER_KEEP_ALIVE_PERIOD_SEC    25 -static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, -				struct iwl_powertable_cmd *cmd) +static void iwl_mvm_power_log(struct iwl_mvm *mvm, +			      struct iwl_powertable_cmd *cmd) +{ +	IWL_DEBUG_POWER(mvm, +			"Sending power table command for power level %d, flags = 0x%X\n", +			iwlmvm_mod_params.power_scheme, +			le16_to_cpu(cmd->flags)); +	IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", cmd->keep_alive_seconds); + +	if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { +		IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", +				le32_to_cpu(cmd->rx_data_timeout)); +		IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", +				le32_to_cpu(cmd->tx_data_timeout)); +		IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", +				cmd->lprx_rssi_threshold); +	} +} + +void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, +			     struct iwl_powertable_cmd *cmd)  {  	struct ieee80211_hw *hw = mvm->hw; -	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);  	struct ieee80211_chanctx_conf *chanctx_conf;  	struct ieee80211_channel *chan;  	int dtimper, dtimper_msec;  	int keep_alive;  	bool radar_detect = false; -	cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, -							    mvmvif->color)); -	cmd->action = cpu_to_le32(FW_CTXT_ACTION_MODIFY); +	/* +	 * Regardless of power management state the driver must set +	 * keep alive period. FW will use it for sending keep alive NDPs +	 * immediately after association. +	 */ +	cmd->keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC; -	if ((!vif->bss_conf.ps) || -	    (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)) +	if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) +		return; + +	cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); + +	if (!vif->bss_conf.ps)  		return;  	cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); @@ -110,63 +135,29 @@ static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,  	/* Check skip over DTIM conditions */  	if (!radar_detect && (dtimper <= 10) && -	    (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) { -		cmd->flags |= cpu_to_le16(POWER_FLAGS_SLEEP_OVER_DTIM_MSK); -		cmd->num_skip_dtim = 2; -	} +	    (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) +		cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);  	/* Check that keep alive period is at least 3 * DTIM */  	dtimper_msec = dtimper * vif->bss_conf.beacon_int;  	keep_alive = max_t(int, 3 * dtimper_msec, -			   MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC); +			   MSEC_PER_SEC * cmd->keep_alive_seconds);  	keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); +	cmd->keep_alive_seconds = keep_alive; -	cmd->keep_alive_seconds = cpu_to_le16(keep_alive); - -	if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) { -		/* TODO: Also for D3 (device sleep / WoWLAN) */ -		cmd->rx_data_timeout = cpu_to_le32(10); -		cmd->tx_data_timeout = cpu_to_le32(10); -	} else { -		cmd->rx_data_timeout = cpu_to_le32(50); -		cmd->tx_data_timeout = cpu_to_le32(50); -	} +	cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); +	cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);  }  int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)  {  	struct iwl_powertable_cmd cmd = {}; -	if (!iwlwifi_mod_params.power_save) { -		IWL_DEBUG_POWER(mvm, "Power management is not allowed\n"); -		return 0; -	} -  	if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)  		return 0; -	iwl_power_build_cmd(mvm, vif, &cmd); - -	IWL_DEBUG_POWER(mvm, -			"Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n", -			cmd.id_and_color, iwlmvm_mod_params.power_scheme, -			le16_to_cpu(cmd.flags)); - -	if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { -		IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", -				le16_to_cpu(cmd.keep_alive_seconds)); -		IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", -				le32_to_cpu(cmd.rx_data_timeout)); -		IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", -				le32_to_cpu(cmd.tx_data_timeout)); -		IWL_DEBUG_POWER(mvm, "Rx timeout (uAPSD) = %u usec\n", -				le32_to_cpu(cmd.rx_data_timeout_uapsd)); -		IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", -				le32_to_cpu(cmd.tx_data_timeout_uapsd)); -		IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", -				cmd.lprx_rssi_threshold); -		IWL_DEBUG_POWER(mvm, "DTIMs to skip = %u\n", cmd.num_skip_dtim); -	} +	iwl_mvm_power_build_cmd(mvm, vif, &cmd); +	iwl_mvm_power_log(mvm, &cmd);  	return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,  				    sizeof(cmd), &cmd); @@ -175,33 +166,15 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)  int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)  {  	struct iwl_powertable_cmd cmd = {}; -	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - -	if (!iwlwifi_mod_params.power_save) { -		IWL_DEBUG_POWER(mvm, "Power management is not allowed\n"); -		return 0; -	}  	if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)  		return 0; -	cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, -							    mvmvif->color)); -	cmd.action = cpu_to_le32(FW_CTXT_ACTION_MODIFY); +	if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) +		cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); -	IWL_DEBUG_POWER(mvm, -			"Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n", -			cmd.id_and_color, iwlmvm_mod_params.power_scheme, -			le16_to_cpu(cmd.flags)); +	iwl_mvm_power_log(mvm, &cmd);  	return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC,  				    sizeof(cmd), &cmd);  } - -#ifdef CONFIG_IWLWIFI_DEBUGFS -void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif, -			  struct iwl_powertable_cmd *cmd) -{ -	iwl_power_build_cmd(mvm, vif, cmd); -} -#endif /* CONFIG_IWLWIFI_DEBUGFS */  |