Commit 54fa45dd authored by Yedidya Benshimol's avatar Yedidya Benshimol Committed by Johannes Berg
Browse files

wifi: iwlwifi: mvm: disable EMLSR when we suspend with wowlan



We can't be an EMLSR while suspended with wowlan. De-activate the
secondary link upon wowlan entring.

Set the blocking reason upon suspension and clear it upon resume.

Signed-off-by: default avatarYedidya Benshimol <yedidya.ben.shimol@intel.com>
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240416134215.6ea884b3f095.I84233cb1c79ba538defafb8ddb983c47f04a400a@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 9c28ead0
Loading
Loading
Loading
Loading
+9 −10
Original line number Diff line number Diff line
@@ -1261,22 +1261,19 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
	if (IS_ERR_OR_NULL(vif))
		return 1;

	mutex_lock(&mvm->mutex);

	primary_link = iwl_mvm_get_primary_link(vif);
	if (ieee80211_vif_is_mld(vif) && vif->cfg.assoc &&
	    mvmvif->esr_active) {
		/*
		 * Select the 'best' link. May need to revisit, it seems
		 * better to not optimize for throughput but rather
		 * range, reliability and power here - and select
		 * 2.4 GHz ...
		 */

	/* leave ESR immediately, not only async with iwl_mvm_block_esr() */
	if (ieee80211_vif_is_mld(vif)) {
		ret = ieee80211_set_active_links(vif, BIT(primary_link));
		if (ret)
			return ret;
	}

	mutex_lock(&mvm->mutex);
	/* only additionally block for consistency and to avoid concurrency */
	iwl_mvm_block_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_WOWLAN, primary_link);

	set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);

	synchronize_net();
@@ -3463,6 +3460,8 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
			goto err;
	}

	iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_WOWLAN);

	/* after the successful handshake, we're out of D3 */
	mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;

+3 −1
Original line number Diff line number Diff line
@@ -678,7 +678,9 @@ u8 iwl_mvm_get_primary_link(struct ieee80211_vif *vif)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);

	lockdep_assert_held(&mvmvif->mvm->mutex);
	/* relevant data is written with both locks held, so read with either */
	lockdep_assert(lockdep_is_held(&mvmvif->mvm->mutex) ||
		       lockdep_is_held(&mvmvif->mvm->hw->wiphy->mtx));

	if (!ieee80211_vif_is_mld(vif))
		return 0;
+2 −0
Original line number Diff line number Diff line
@@ -356,11 +356,13 @@ struct iwl_mvm_vif_link_info {
 * @IWL_MVM_ESR_BLOCKED_COEX: COEX is preventing the enablement of EMLSR
 * @IWL_MVM_ESR_BLOCKED_PREVENTION: Prevent EMLSR to avoid entering and exiting
 *	in a loop.
 * @IWL_MVM_ESR_BLOCKED_WOWLAN: WOWLAN is preventing the enablement of EMLSR
 * @IWL_MVM_ESR_EXIT_MISSED_BEACON: exited EMLSR due to missed beacons
 */
enum iwl_mvm_esr_state {
	IWL_MVM_ESR_BLOCKED_COEX	= 0x1,
	IWL_MVM_ESR_BLOCKED_PREVENTION	= 0x2,
	IWL_MVM_ESR_BLOCKED_WOWLAN	= 0x4,
	IWL_MVM_ESR_EXIT_MISSED_BEACON	= 0x10000,
};