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

Commit 92d85562 authored by Alexander Bondar's avatar Alexander Bondar Committed by Emmanuel Grumbach
Browse files

iwlwifi: mvm: Disable power save for monitor interface



When monitor interface is activated device power save needs
to be disabled.
Re-consider power management status on other active
interfaces when monitor interface is bound or unbound.

Signed-off-by: default avatarAlexander Bondar <alexander.bondar@intel.com>
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 1c2abf72
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -1610,7 +1610,13 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
		goto out_unlock;

	/*
	 * Setting the quota at this stage is only required for monitor
	 * Power state must be updated before quotas,
	 * otherwise fw will complain.
	 */
	mvm->bound_vif_cnt++;
	iwl_mvm_power_update_binding(mvm, vif, true);

	/* Setting the quota at this stage is only required for monitor
	 * interfaces. For the other types, the bss_info changed flow
	 * will handle quota settings.
	 */
@@ -1621,13 +1627,12 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
			goto out_remove_binding;
	}

	mvm->bound_vif_cnt++;
	iwl_mvm_power_update_binding(mvm, vif);

	goto out_unlock;

 out_remove_binding:
	iwl_mvm_binding_remove_vif(mvm, vif);
	mvm->bound_vif_cnt--;
	iwl_mvm_power_update_binding(mvm, vif, false);
 out_unlock:
	mutex_unlock(&mvm->mutex);
	if (ret)
@@ -1662,7 +1667,7 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
out_unlock:
	mvmvif->phy_ctxt = NULL;
	mvm->bound_vif_cnt--;
	iwl_mvm_power_update_binding(mvm, vif);
	iwl_mvm_power_update_binding(mvm, vif, false);

	mutex_unlock(&mvm->mutex);
}
+7 −3
Original line number Diff line number Diff line
@@ -164,7 +164,7 @@ struct iwl_mvm_power_ops {
	int (*power_update_device_mode)(struct iwl_mvm *mvm);
	int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
	void (*power_update_binding)(struct iwl_mvm *mvm,
				     struct ieee80211_vif *vif);
				     struct ieee80211_vif *vif, bool assign);
#ifdef CONFIG_IWLWIFI_DEBUGFS
	int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
				char *buf, int bufsz);
@@ -568,6 +568,9 @@ struct iwl_mvm {
	u8 last_agg_queue;

	u8 bound_vif_cnt;

	/* Indicate if device power save is allowed */
	bool ps_prevented;
};

/* Extract MVM priv from op_mode and _hw */
@@ -787,10 +790,11 @@ static inline int iwl_mvm_power_update_device_mode(struct iwl_mvm *mvm)
}

static inline void iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
						struct ieee80211_vif *vif)
						struct ieee80211_vif *vif,
						bool assign)
{
	if (mvm->pm_ops->power_update_binding)
		mvm->pm_ops->power_update_binding(mvm, vif);
		mvm->pm_ops->power_update_binding(mvm, vif, assign);
}

void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
+18 −4
Original line number Diff line number Diff line
@@ -301,7 +301,8 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
	keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
	cmd->keep_alive_seconds = cpu_to_le16(keep_alive);

	if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)
	if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
	    mvm->ps_prevented)
		return;

	cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
@@ -447,7 +448,7 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm,
				    sizeof(cmd), &cmd);
}

static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
static int _iwl_mvm_power_update_device(struct iwl_mvm *mvm, bool force_disable)
{
	struct iwl_device_power_cmd cmd = {
		.flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
@@ -456,7 +457,8 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
	if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
		return 0;

	if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)
	if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
	    force_disable)
		cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK);

#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -473,6 +475,11 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
				    &cmd);
}

static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
{
	return _iwl_mvm_power_update_device(mvm, false);
}

void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@@ -525,8 +532,15 @@ static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac,
}

static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
					  struct ieee80211_vif *vif)
					  struct ieee80211_vif *vif,
					  bool assign)
{
	if (vif->type == NL80211_IFTYPE_MONITOR) {
		int ret = _iwl_mvm_power_update_device(mvm, assign);
		mvm->ps_prevented = assign;
		WARN_ONCE(ret, "Failed to update power device state\n");
	}

	ieee80211_iterate_active_interfaces(mvm->hw,
					    IEEE80211_IFACE_ITER_NORMAL,
					    iwl_mvm_power_binding_iterator,