summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>2024-02-15 13:54:49 +0200
committeriwlwifi publisher <>2024-04-17 12:55:37 +0000
commit3665478becaaa48b86a2239d30ec5556e61243d4 (patch)
tree787fdd6858d3ce771051c767b15052a69e8ceca5
parentbd0a32f30793906e64e6be70d0eab8242e6b2633 (diff)
downloadbackport-iwlwifi-3665478becaaa48b86a2239d30ec5556e61243d4.tar.gz
wifi: iwlwifi: mvm: Add helper functions to update ESR status
There are reasons for which we need to exit esr, but not to block it completely, and there are reasons for which we need to block esr. For both reason types we have the enum iwl_mvm_esr_state, when the blocking reasons are stored in the `mvmvif::esr_disable_reason` bitmap. This change introduces the APIs to use in the different cases: - iwl_mvm_exit_esr - will exit from eSR mode. - iwl_mvm_block_esr - will update the bitmap and exit esr, to be used for the blocking reasons only. - iwl_mvm_unblock_esr - will update the bitmap. To be used for the blocking reasons only. type=feature ticket=none Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Change-Id: I552926065521f5f848c37b0bd845494bd7865fb7 Reviewed-on: https://gerritwcs.ir.intel.com/c/iwlwifi-stack-dev/+/94725 automatic-review: iil_jenkins iil_jenkins <EC.GER.UNIX.IIL.JENKINS@INTEL.COM> tested: iil_jenkins iil_jenkins <EC.GER.UNIX.IIL.JENKINS@INTEL.COM> Reviewed-by: Johannes Berg <johannes.berg@intel.com> x-iwlwifi-stack-dev: b639914bcf5350a04982dc9e53ff7d0f055fa5bc
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/coex.c33
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/link.c71
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c24
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h25
-rw-r--r--versions2
5 files changed, 99 insertions, 56 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
index 407aa74c76..08e1e12531 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
@@ -253,28 +253,6 @@ static void iwl_mvm_bt_coex_tcm_based_ci(struct iwl_mvm *mvm,
swap(data->primary, data->secondary);
}
-static void iwl_mvm_bt_coex_enable_esr(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif, bool enable)
-{
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-
- lockdep_assert_held(&mvm->mutex);
-
- if (!vif->cfg.assoc || !ieee80211_vif_is_mld(vif))
- return;
-
- /* Done already */
- if ((mvmvif->esr_disable_reason & IWL_MVM_ESR_DISABLE_COEX) == !enable)
- return;
-
- if (enable)
- mvmvif->esr_disable_reason &= ~IWL_MVM_ESR_DISABLE_COEX;
- else
- mvmvif->esr_disable_reason |= IWL_MVM_ESR_DISABLE_COEX;
-
- iwl_mvm_recalc_esr(mvm, vif);
-}
-
/*
* This function receives the LB link id and checks if eSR should be
* enabled or disabled (due to BT coex)
@@ -320,7 +298,7 @@ iwl_mvm_bt_coex_calculate_esr_mode(struct iwl_mvm *mvm,
if (!link_rssi)
wifi_loss_rate = mvm->last_bt_notif.wifi_loss_mid_high_rssi;
- else if (!(mvmvif->esr_disable_reason & IWL_MVM_ESR_DISABLE_COEX))
+ else if (!(mvmvif->esr_disable_reason & IWL_MVM_ESR_BLOCKED_COEX))
/* RSSI needs to get really low to disable eSR... */
wifi_loss_rate =
link_rssi <= -IWL_MVM_BT_COEX_DISABLE_ESR_THRESH ?
@@ -348,7 +326,12 @@ void iwl_mvm_bt_coex_update_link_esr(struct iwl_mvm *mvm,
enable = iwl_mvm_bt_coex_calculate_esr_mode(mvm, vif, link_id);
- iwl_mvm_bt_coex_enable_esr(mvm, vif, enable);
+ if (enable)
+ iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_COEX);
+ else
+ /* In case we decided to exit eSR - stay with the primary */
+ iwl_mvm_block_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_COEX,
+ iwl_mvm_get_primary_link(vif));
}
static void iwl_mvm_bt_notif_per_link(struct iwl_mvm *mvm,
@@ -534,7 +517,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
/* When BT is off this will be 0 */
if (data->notif->wifi_loss_low_rssi == BT_OFF)
- iwl_mvm_bt_coex_enable_esr(mvm, vif, true);
+ iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_COEX);
for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++)
iwl_mvm_bt_notif_per_link(mvm, vif, data, link_id);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c
index 1f53a447a0..07c0ff4014 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c
@@ -559,7 +559,7 @@ bool iwl_mvm_mld_valid_link_pair(struct ieee80211_vif *vif,
/* BT Coex effects eSR mode only if one of the link is on LB */
if (a->band == NL80211_BAND_2GHZ || b->band == NL80211_BAND_2GHZ)
- return !(mvmvif->esr_disable_reason & IWL_MVM_ESR_DISABLE_COEX);
+ return !(mvmvif->esr_disable_reason & IWL_MVM_ESR_BLOCKED_COEX);
return true;
}
@@ -687,3 +687,72 @@ u8 iwl_mvm_get_primary_link(struct ieee80211_vif *vif)
return __ffs(vif->active_links);
}
+
+/* API to exit eSR mode */
+void iwl_mvm_exit_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+ enum iwl_mvm_esr_state reason,
+ u8 link_to_keep)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ u16 new_active_links;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ /* Nothing to do */
+ if (!mvmvif->esr_active)
+ return;
+
+ if (WARN_ON(!ieee80211_vif_is_mld(vif) || !mvmvif->authorized))
+ return;
+
+ if (WARN_ON(!(vif->active_links & BIT(link_to_keep))))
+ link_to_keep = __ffs(vif->active_links);
+
+ new_active_links = BIT(link_to_keep);
+ IWL_DEBUG_INFO(mvm,
+ "Exiting EMLSR. Reason = %d. Current active links=0x%x, new active links = 0x%x\n",
+ reason, vif->active_links, new_active_links);
+
+ ieee80211_set_active_links_async(vif, new_active_links);
+}
+
+#define IWL_MVM_BLOCK_ESR_REASONS IWL_MVM_ESR_BLOCKED_COEX
+
+void iwl_mvm_block_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+ enum iwl_mvm_esr_state reason,
+ u8 link_to_keep)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+ lockdep_assert_held(&mvm->mutex);
+
+ /* This should be called only with disable reasons */
+ if (WARN_ON(!(reason & IWL_MVM_BLOCK_ESR_REASONS)))
+ return;
+
+ if (!(mvmvif->esr_disable_reason & reason))
+ IWL_DEBUG_INFO(mvm, "Blocking EMSLR mode. reason = %d\n",
+ reason);
+
+ mvmvif->esr_disable_reason |= reason;
+
+ iwl_mvm_exit_esr(mvm, vif, reason, link_to_keep);
+}
+
+void iwl_mvm_unblock_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+ enum iwl_mvm_esr_state reason)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+ lockdep_assert_held(&mvm->mutex);
+
+ /* This should be called only with disable reasons */
+ if (WARN_ON(!(reason & IWL_MVM_BLOCK_ESR_REASONS)))
+ return;
+
+ if (mvmvif->esr_disable_reason & reason)
+ IWL_DEBUG_INFO(mvm, "Unblocking EMSLR mode. reason = %d\n",
+ reason);
+
+ mvmvif->esr_disable_reason &= ~reason;
+}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
index b76d483a61..3ce376b007 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
@@ -1169,28 +1169,6 @@ iwl_mvm_mld_change_sta_links(struct ieee80211_hw *hw,
return ret;
}
-void iwl_mvm_recalc_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
-{
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
- bool enable = !mvmvif->esr_disable_reason;
- u16 new_active_links;
-
- /* Nothing to do */
- if (mvmvif->esr_active == enable)
- return;
-
- /* The next link selection will enter eSR if possible */
- if (enable)
- return;
-
- /*
- * Find the primary link, as we want to switch to it and drop the
- * secondary one.
- */
- new_active_links = BIT(iwl_mvm_get_primary_link(vif));
- ieee80211_set_active_links_async(vif, new_active_links);
-}
-
bool iwl_mvm_esr_allowed_on_vif(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
@@ -1212,7 +1190,7 @@ bool iwl_mvm_esr_allowed_on_vif(struct iwl_mvm *mvm,
!(ext_capa->eml_capabilities & IEEE80211_EML_CAP_EMLSR_SUPP))
return false;
- return !(mvmvif->esr_disable_reason & ~IWL_MVM_ESR_DISABLE_COEX);
+ return !(mvmvif->esr_disable_reason & ~IWL_MVM_ESR_BLOCKED_COEX);
}
/*
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 768caadd9e..4490e09f37 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -348,11 +348,17 @@ struct iwl_mvm_vif_link_info {
};
/**
- * enum iwl_mvm_esr_disable_reason - reasons for which we can't enable EMLSR
- * @IWL_MVM_ESR_DISABLE_COEX: COEX is preventing the enablement of EMLSR
+ * enum iwl_mvm_esr_state - defines reasons for which the EMLSR is exited or
+ * blocked.
+ * The low 16 bits are used for blocking reasons, and the 16 higher bits
+ * are used for exit reasons.
+ * For the blocking reasons - use iwl_mvm_(un)block_esr(), and for the exit
+ * reasons - use iwl_mvm_exit_esr().
+ *
+ * @IWL_MVM_ESR_BLOCKED_COEX: COEX is preventing the enablement of EMLSR
*/
-enum iwl_mvm_esr_disable_reason {
- IWL_MVM_ESR_DISABLE_COEX = BIT(0),
+enum iwl_mvm_esr_state {
+ IWL_MVM_ESR_BLOCKED_COEX = BIT(0),
};
/**
@@ -388,7 +394,7 @@ enum iwl_mvm_esr_disable_reason {
* @deflink: default link data for use in non-MLO
* @link: link data for each link in MLO
* @esr_active: indicates eSR mode is active
- * @esr_disable_reason: a bitmap of enum iwl_mvm_esr_disable_reason
+ * @esr_disable_reason: a bitmap of &enum iwl_mvm_esr_state
* @pm_enabled: indicates powersave is enabled
* @primary_link: primary link in eSR. Valid only for an associated MLD vif,
* and in eSR mode. Valid only for a STA.
@@ -2875,8 +2881,15 @@ int iwl_mvm_roc_add_cmd(struct iwl_mvm *mvm,
int duration, u32 activity);
/* EMLSR */
-void iwl_mvm_recalc_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
bool iwl_mvm_esr_allowed_on_vif(struct iwl_mvm *mvm,
struct ieee80211_vif *vif);
+void iwl_mvm_block_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+ enum iwl_mvm_esr_state reason,
+ u8 link_to_keep);
+void iwl_mvm_unblock_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+ enum iwl_mvm_esr_state reason);
+void iwl_mvm_exit_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+ enum iwl_mvm_esr_state reason,
+ u8 link_to_keep);
#endif /* __IWL_MVM_H__ */
diff --git a/versions b/versions
index e59961da8b..efa18b630e 100644
--- a/versions
+++ b/versions
@@ -2,4 +2,4 @@ BACKPORTS_VERSION="(see git)"
BACKPORTED_KERNEL_VERSION="(see git)"
BACKPORTED_KERNEL_NAME="iwlwifi"
BACKPORTS_BUILD_TSTAMP=__DATE__ \" \" __TIME__
-BACKPORTS_GIT_TRACKED="iwlwifi-stack-public:master:11927:4d865533"
+BACKPORTS_GIT_TRACKED="iwlwifi-stack-public:master:11928:b639914b"