summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mld/iface.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mld/mac80211.c21
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mld/mlo.c3
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)