wifi: iwlwifi: mvm: disable EMLSR when we suspend with wowlan
authorYedidya Benshimol <yedidya.ben.shimol@intel.com>
Tue, 16 Apr 2024 10:54:10 +0000 (13:54 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 19 Apr 2024 08:16:34 +0000 (10:16 +0200)
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>
Link: https://msgid.link/20240416134215.6ea884b3f095.I84233cb1c79ba538defafb8ddb983c47f04a400a@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
drivers/net/wireless/intel/iwlwifi/mvm/link.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h

index 6763863f435416b87603834b9eeb50908f7f6e4a..778ea64f3f288d9acf49f56ffeeca2235cb644db 100644 (file)
@@ -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;
 
index 9f343d015d8126c2c142ee624db21c1fb3b57e7a..1171fc831ca8011260f900f8291061b78c90ad05 100644 (file)
@@ -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;
index 050a04c185e508b08eb81a7a4162780fc7c18b75..2ef346c54d240966894f364c163b547a61684a55 100644 (file)
@@ -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,
 };