diff mbox series

[15/16] wifi: iwlwifi: mvm: disable EMLSR when we suspend with wowlan

Message ID 20240416134215.6ea884b3f095.I84233cb1c79ba538defafb8ddb983c47f04a400a@changeid
State New
Headers show
Series wifi: iwlwifi: updates - 2024-04-16 | expand

Commit Message

Korenblit, Miriam Rachel April 16, 2024, 10:54 a.m. UTC
From: Yedidya Benshimol <yedidya.ben.shimol@intel.com>

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: Yedidya Benshimol <yedidya.ben.shimol@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c   | 19 +++++++++----------
 drivers/net/wireless/intel/iwlwifi/mvm/link.c |  4 +++-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  2 ++
 3 files changed, 14 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 6763863f4354..778ea64f3f28 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -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;
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c
index 9f343d015d81..1171fc831ca8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c
@@ -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;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 050a04c185e5..2ef346c54d24 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -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,
 };