]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: iwlwifi: mvm: separate non-BSS/ROC EMLSR blocking
authorJohannes Berg <johannes.berg@intel.com>
Wed, 5 Jun 2024 11:07:36 +0000 (14:07 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 3 Aug 2024 06:59:38 +0000 (08:59 +0200)
[ Upstream commit 5f1fee9644759d07f3d3a468389c7c18027083d7 ]

If non-BSS and remain-on-channel (ROC) blocking were to occur
simultaneously, they'd step on each other's toes, unblocking
when not yet supported. Disentangle these bits, and ROC doesn't
need to use the non_bss_link() function then.

Fixes: a1efeb823084 ("wifi: iwlwifi: mvm: Block EMLSR when a p2p/softAP vif is active")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240605140556.461fcf7b95bb.Id0d21dcb739d426ff15ec068b5df8abaab58884d@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c

index dac6155ae1bd0d910b55001512d88b6c6c0d1122..259afecd1a98da42c7d72fd36895fbc478dae55b 100644 (file)
@@ -4861,6 +4861,7 @@ int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                       const struct iwl_mvm_roc_ops *ops)
 {
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+       struct ieee80211_vif *bss_vif = iwl_mvm_get_bss_vif(mvm);
        u32 lmac_id;
        int ret;
 
@@ -4873,9 +4874,12 @@ int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
         */
        flush_work(&mvm->roc_done_wk);
 
-       ret = iwl_mvm_esr_non_bss_link(mvm, vif, 0, true);
-       if (ret)
-               return ret;
+       if (!IS_ERR_OR_NULL(bss_vif)) {
+               ret = iwl_mvm_block_esr_sync(mvm, bss_vif,
+                                            IWL_MVM_ESR_BLOCKED_ROC);
+               if (ret)
+                       return ret;
+       }
 
        mutex_lock(&mvm->mutex);
 
index 0a1959bd4079997854d9f3c2c444adc2f2f945a5..6837d8afb9877f6552ca7ba5d3e27555dba3314a 100644 (file)
@@ -360,7 +360,9 @@ struct iwl_mvm_vif_link_info {
  * @IWL_MVM_ESR_BLOCKED_WOWLAN: WOWLAN is preventing the enablement of EMLSR
  * @IWL_MVM_ESR_BLOCKED_TPT: block EMLSR when there is not enough traffic
  * @IWL_MVM_ESR_BLOCKED_FW: FW didn't recommended/forced exit from EMLSR
- * @IWL_MVM_ESR_BLOCKED_NON_BSS: An active non-bssid link's preventing EMLSR
+ * @IWL_MVM_ESR_BLOCKED_NON_BSS: An active non-BSS interface's link is
+ *     preventing EMLSR
+ * @IWL_MVM_ESR_BLOCKED_ROC: remain-on-channel is preventing EMLSR
  * @IWL_MVM_ESR_EXIT_MISSED_BEACON: exited EMLSR due to missed beacons
  * @IWL_MVM_ESR_EXIT_LOW_RSSI: link is deactivated/not allowed for EMLSR
  *     due to low RSSI.
@@ -377,6 +379,7 @@ enum iwl_mvm_esr_state {
        IWL_MVM_ESR_BLOCKED_TPT         = 0x4,
        IWL_MVM_ESR_BLOCKED_FW          = 0x8,
        IWL_MVM_ESR_BLOCKED_NON_BSS     = 0x10,
+       IWL_MVM_ESR_BLOCKED_ROC         = 0x20,
        IWL_MVM_ESR_EXIT_MISSED_BEACON  = 0x10000,
        IWL_MVM_ESR_EXIT_LOW_RSSI       = 0x20000,
        IWL_MVM_ESR_EXIT_COEX           = 0x40000,
index 31bc80cdcb7d554899e1318f7f7893eb681d18c6..c0322349bfcd8840eeaa4c624aa827a0e1f417f4 100644 (file)
@@ -47,6 +47,7 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
 
 static void iwl_mvm_cleanup_roc(struct iwl_mvm *mvm)
 {
+       struct ieee80211_vif *bss_vif = iwl_mvm_get_bss_vif(mvm);
        struct ieee80211_vif *vif = mvm->p2p_device_vif;
 
        lockdep_assert_held(&mvm->mutex);
@@ -119,9 +120,9 @@ static void iwl_mvm_cleanup_roc(struct iwl_mvm *mvm)
                        iwl_mvm_rm_aux_sta(mvm);
        }
 
+       if (vif && !IS_ERR_OR_NULL(bss_vif))
+               iwl_mvm_unblock_esr(mvm, bss_vif, IWL_MVM_ESR_BLOCKED_ROC);
        mutex_unlock(&mvm->mutex);
-       if (vif)
-               iwl_mvm_esr_non_bss_link(mvm, vif, 0, false);
 }
 
 void iwl_mvm_roc_done_wk(struct work_struct *wk)