diff options
| author | Avinash Bhatt <avinash.bhatt@intel.com> | 2026-03-21 19:29:18 +0200 |
|---|---|---|
| committer | Miri Korenblit <miriam.rachel.korenblit@intel.com> | 2026-03-25 11:31:58 +0200 |
| commit | 4d56037a02bda77844f98bfbb2b91e324f86bd7f (patch) | |
| tree | 9bc3091d85497f3ad3434a7c66c87607f5af79fe /drivers | |
| parent | 73a20e5d1ed8cd1328674689221ee8df2104aec5 (diff) | |
wifi: iwlwifi: mld: block EMLSR during TDLS connections
TDLS (Tunneled Direct Link Setup) requires single-link operation
for direct peer-to-peer communication, which is incompatible with
EMLSR (Enhanced Multi-Link Single Radio) mode where the radio
switches between multiple links.
Block EMLSR when the first TDLS peer is added and unblock when
the last TDLS peer is removed. The block/unblock APIs handle
exiting EMLSR and triggering link selection automatically.
Signed-off-by: Avinash Bhatt <avinash.bhatt@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260321192637.c1376b0259dd.I016587eb1570f7a7a64c0c95e0636e955a640350@changeid
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mld/iface.h | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 21 | ||||
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mld/mlo.c | 3 |
3 files changed, 22 insertions, 4 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/iface.h b/drivers/net/wireless/intel/iwlwifi/mld/iface.h index 3e106c93f0db..0857ae28be8e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/iface.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/iface.h @@ -33,6 +33,7 @@ enum iwl_mld_cca_40mhz_wa_status { * 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. + * @IWL_MLD_EMLSR_BLOCKED_TDLS: TDLS connection is preventing EMLSR. */ enum iwl_mld_emlsr_blocked { IWL_MLD_EMLSR_BLOCKED_PREVENTION = 0x1, @@ -42,6 +43,7 @@ enum iwl_mld_emlsr_blocked { IWL_MLD_EMLSR_BLOCKED_TMP_NON_BSS = 0x10, IWL_MLD_EMLSR_BLOCKED_TPT = 0x20, IWL_MLD_EMLSR_BLOCKED_NAN = 0x40, + IWL_MLD_EMLSR_BLOCKED_TDLS = 0x80, }; /** diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c index 9dec981a2bc5..e3aec814aa0d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c @@ -1759,10 +1759,19 @@ static int iwl_mld_move_sta_state_up(struct iwl_mld *mld, if (ret) return ret; - /* just added first TDLS STA, so disable PM */ - if (sta->tdls && tdls_count == 0) + /* just added first TDLS STA, so disable PM and block EMLSR */ + if (sta->tdls && tdls_count == 0) { iwl_mld_update_mac_power(mld, vif, false); + /* TDLS requires single-link operation with + * direct peer communication. + * Block and exit EMLSR when TDLS is established. + */ + iwl_mld_block_emlsr(mld, vif, + IWL_MLD_EMLSR_BLOCKED_TDLS, + iwl_mld_get_primary_link(vif)); + } + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) mld_vif->ap_sta = sta; @@ -1898,8 +1907,14 @@ static int iwl_mld_move_sta_state_down(struct iwl_mld *mld, iwl_mld_remove_sta(mld, sta); if (sta->tdls && iwl_mld_tdls_sta_count(mld) == 0) { - /* just removed last TDLS STA, so enable PM */ + /* just removed last TDLS STA, so enable PM + * and unblock EMLSR + */ iwl_mld_update_mac_power(mld, vif, false); + + /* Unblock EMLSR when TDLS connection is torn down */ + iwl_mld_unblock_emlsr(mld, vif, + IWL_MLD_EMLSR_BLOCKED_TDLS); } } else { return -EINVAL; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mlo.c b/drivers/net/wireless/intel/iwlwifi/mld/mlo.c index f693f92e42b4..9362e02d9e76 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mlo.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mlo.c @@ -13,7 +13,8 @@ HOW(NON_BSS) \ HOW(TMP_NON_BSS) \ HOW(TPT) \ - HOW(NAN) + HOW(NAN) \ + HOW(TDLS) static const char * iwl_mld_get_emlsr_blocked_string(enum iwl_mld_emlsr_blocked blocked) |
