]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: iwlwifi: mld: prevent EMLSR when NAN is active
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Sun, 11 Jan 2026 17:39:16 +0000 (19:39 +0200)
committerMiri Korenblit <miriam.rachel.korenblit@intel.com>
Wed, 21 Jan 2026 12:23:02 +0000 (14:23 +0200)
EMLSR is not allowed when NAN is active. Block EMLSR when starting NAN,
and unblock EMLSR when NAN is stopped.

Reviewed-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260111193638.8baef343023a.Ie94e5f32db003ebce33bde65e0ed8c6d98673b5a@changeid
drivers/net/wireless/intel/iwlwifi/mld/iface.h
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
drivers/net/wireless/intel/iwlwifi/mld/mlo.c
drivers/net/wireless/intel/iwlwifi/mld/mlo.h
drivers/net/wireless/intel/iwlwifi/mld/nan.c

index a3573d20f214ad0b693f7d077a95cea5e15156e0..62fca166afd1ec9625e998dbd933a8a4c8892d04 100644 (file)
@@ -32,6 +32,7 @@ enum iwl_mld_cca_40mhz_wa_status {
  *      link is preventing EMLSR. This is a temporary blocking that is set when
  *      there is an indication that a non-BSS interface is to be added.
  * @IWL_MLD_EMLSR_BLOCKED_TPT: throughput is too low to make EMLSR worthwhile
+ * @IWL_MLD_EMLSR_BLOCKED_NAN: NAN is preventing EMLSR.
  */
 enum iwl_mld_emlsr_blocked {
        IWL_MLD_EMLSR_BLOCKED_PREVENTION        = 0x1,
@@ -40,6 +41,7 @@ enum iwl_mld_emlsr_blocked {
        IWL_MLD_EMLSR_BLOCKED_NON_BSS           = 0x8,
        IWL_MLD_EMLSR_BLOCKED_TMP_NON_BSS       = 0x10,
        IWL_MLD_EMLSR_BLOCKED_TPT               = 0x20,
+       IWL_MLD_EMLSR_BLOCKED_NAN               = 0x40,
 };
 
 /**
index 411a2d56e5f0098cd948b8b238816e128d39d9fa..df8221277d51bc2a8de10e07ad1ae1ae491dadee 100644 (file)
@@ -1784,6 +1784,9 @@ static int iwl_mld_move_sta_state_up(struct iwl_mld *mld,
                        /* Ensure any block due to a non-BSS link is synced */
                        iwl_mld_emlsr_check_non_bss_block(mld, 0);
 
+                       /* Ensure NAN block is synced */
+                       iwl_mld_emlsr_check_nan_block(mld, vif);
+
                        /* Block EMLSR until a certain throughput it reached */
                        if (!mld->fw_status.in_hw_restart &&
                            IWL_MLD_ENTER_EMLSR_TPT_THRESH > 0)
index 87f67ddfced479efc8dfdafb400ada2bbee94cc7..f842f5183223b2526a4788f96f61e090d55bf312 100644 (file)
@@ -12,7 +12,8 @@
        HOW(ROC)                        \
        HOW(NON_BSS)                    \
        HOW(TMP_NON_BSS)                \
-       HOW(TPT)
+       HOW(TPT)                        \
+       HOW(NAN)
 
 static const char *
 iwl_mld_get_emlsr_blocked_string(enum iwl_mld_emlsr_blocked blocked)
@@ -478,8 +479,8 @@ iwl_mld_vif_iter_update_emlsr_block(void *_data, u8 *mac,
        }
 }
 
-static int iwl_mld_update_emlsr_block(struct iwl_mld *mld, bool block,
-                                     enum iwl_mld_emlsr_blocked reason)
+int iwl_mld_update_emlsr_block(struct iwl_mld *mld, bool block,
+                              enum iwl_mld_emlsr_blocked reason)
 {
        struct iwl_mld_update_emlsr_block_data block_data = {
                .block = block,
@@ -1210,3 +1211,16 @@ void iwl_mld_stop_ignoring_tpt_updates(struct iwl_mld *mld)
                                                iwl_mld_ignore_tpt_iter,
                                                &start);
 }
+
+int iwl_mld_emlsr_check_nan_block(struct iwl_mld *mld, struct ieee80211_vif *vif)
+{
+       if (mld->nan_device_vif &&
+           ieee80211_vif_nan_started(mld->nan_device_vif))
+               return iwl_mld_block_emlsr_sync(mld, vif,
+                                               IWL_MLD_EMLSR_BLOCKED_NAN,
+                                               iwl_mld_get_primary_link(vif));
+
+       iwl_mld_unblock_emlsr(mld, vif, IWL_MLD_EMLSR_BLOCKED_NAN);
+
+       return 0;
+}
index d936589fe39dce3f3ce22373ed610294cd2274ff..ccc3a7afa0955a19b3d1e75227bbe260c42976e1 100644 (file)
@@ -150,6 +150,11 @@ void iwl_mld_emlsr_check_chan_load(struct ieee80211_hw *hw,
  */
 void iwl_mld_retry_emlsr(struct iwl_mld *mld, struct ieee80211_vif *vif);
 
+int iwl_mld_emlsr_check_nan_block(struct iwl_mld *mld, struct ieee80211_vif *vif);
+
+int iwl_mld_update_emlsr_block(struct iwl_mld *mld, bool block,
+                              enum iwl_mld_emlsr_blocked reason);
+
 struct iwl_mld_link_sel_data {
        u8 link_id;
        const struct cfg80211_chan_def *chandef;
index e7a2c1ec7494b98211aa42747a3f6a2390b2deee..d4298f44baf77df39f182820d817e45e26b85bb6 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "mld.h"
 #include "iface.h"
+#include "mlo.h"
 #include "fw/api/mac-cfg.h"
 
 #define IWL_NAN_DISOVERY_BEACON_INTERNVAL_TU 512
@@ -130,15 +131,25 @@ int iwl_mld_start_nan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
        IWL_DEBUG_MAC80211(mld, "NAN: start: bands=0x%x\n", conf->bands);
 
-       ret = iwl_mld_add_aux_sta(mld, aux_sta);
+       ret = iwl_mld_update_emlsr_block(mld, true, IWL_MLD_EMLSR_BLOCKED_NAN);
        if (ret)
                return ret;
 
+       ret = iwl_mld_add_aux_sta(mld, aux_sta);
+       if (ret)
+               goto unblock_emlsr;
+
        ret = iwl_mld_nan_config(mld, vif, conf, FW_CTXT_ACTION_ADD);
        if (ret) {
                IWL_ERR(mld, "Failed to start NAN. ret=%d\n", ret);
-               iwl_mld_remove_aux_sta(mld, vif);
+               goto remove_aux;
        }
+       return 0;
+
+remove_aux:
+       iwl_mld_remove_aux_sta(mld, vif);
+unblock_emlsr:
+       iwl_mld_update_emlsr_block(mld, false, IWL_MLD_EMLSR_BLOCKED_NAN);
 
        return ret;
 }
@@ -190,6 +201,9 @@ int iwl_mld_stop_nan(struct ieee80211_hw *hw,
        iwl_mld_cancel_notifications_of_object(mld,
                                               IWL_MLD_OBJECT_TYPE_NAN,
                                               0);
+
+       iwl_mld_update_emlsr_block(mld, false, IWL_MLD_EMLSR_BLOCKED_NAN);
+
        return 0;
 }