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
This commit is contained in:
Avinash Bhatt 2026-03-21 19:29:18 +02:00 committed by Miri Korenblit
parent 73a20e5d1e
commit 4d56037a02
3 changed files with 22 additions and 4 deletions

View File

@ -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,
};
/**

View File

@ -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;

View File

@ -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)