wifi: iwlwifi: mvm: introduce esr_disable_reason
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Tue, 16 Apr 2024 10:53:56 +0000 (13:53 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 19 Apr 2024 08:16:32 +0000 (10:16 +0200)
This will maintain a bitmap of reasons for which we want to avoid
enabling EMLSR.
For now, we have a single reason: BT coexistence, but we will add soon
more reasons. Make it a bitmap to make it easier to manage.

Since we'll impact the parameters that impact the enablement /
disablement of EMLSR from several places, introduce a generic function
that takes into account the current state and execute the decision that
must be taken.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240416134215.94c3590c6f27.I6a190da5025d0523ef483ffac0c64e26675041e6@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/coex.c
drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h

index acbd46747b7b86b5c76add862f87efe9ee9d13e5..41afd5d50d812e4abac0f7e3d8181550dbc9a748 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2013-2014, 2018-2020, 2022-2023 Intel Corporation
+ * Copyright (C) 2013-2014, 2018-2020, 2022-2024 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  */
 #include <linux/ieee80211.h>
@@ -257,7 +257,6 @@ 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);
-       int link_id;
 
        lockdep_assert_held(&mvm->mutex);
 
@@ -265,30 +264,15 @@ static void iwl_mvm_bt_coex_enable_esr(struct iwl_mvm *mvm,
                return;
 
        /* Done already */
-       if (mvmvif->bt_coex_esr_disabled == !enable)
+       if ((mvmvif->esr_disable_reason & IWL_MVM_ESR_DISABLE_COEX) == !enable)
                return;
 
-       mvmvif->bt_coex_esr_disabled = !enable;
-
-       /* Nothing to do */
-       if (mvmvif->esr_active == enable)
-               return;
-
-       if (enable) {
-               /* Try to re-enable eSR*/
-               iwl_mvm_mld_select_links(mvm, vif, false);
-               return;
-       }
-
-       /*
-        * Find the primary link, as we want to switch to it and drop the
-        * secondary one.
-        */
-       link_id = iwl_mvm_mld_get_primary_link(mvm, vif, vif->active_links);
-       WARN_ON(link_id < 0);
+       if (enable)
+               mvmvif->esr_disable_reason &= ~IWL_MVM_ESR_DISABLE_COEX;
+       else
+               mvmvif->esr_disable_reason |= IWL_MVM_ESR_DISABLE_COEX;
 
-       ieee80211_set_active_links_async(vif,
-                                        vif->active_links & BIT(link_id));
+       iwl_mvm_recalc_esr(mvm, vif);
 }
 
 /*
@@ -336,7 +320,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->bt_coex_esr_disabled)
+       else if (!(mvmvif->esr_disable_reason & IWL_MVM_ESR_DISABLE_COEX))
                 /* RSSI needs to get really low to disable eSR... */
                wifi_loss_rate =
                        link_rssi <= -IWL_MVM_BT_COEX_DISABLE_ESR_THRESH ?
index 32ccc3b883b2c8a87d8e135fd241c1a4dd487790..7a2a18f8b86e2f03b87f164da5a186cd420c8314 100644 (file)
@@ -1258,6 +1258,33 @@ int iwl_mvm_mld_get_primary_link(struct iwl_mvm *mvm,
        return data[1].link_id;
 }
 
+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;
+       int link_id;
+
+       /* Nothing to do */
+       if (mvmvif->esr_active == enable)
+               return;
+
+       if (enable) {
+               /* Try to re-enable eSR */
+               iwl_mvm_mld_select_links(mvm, vif, false);
+               return;
+       }
+
+       /*
+        * Find the primary link, as we want to switch to it and drop the
+        * secondary one.
+        */
+       link_id = iwl_mvm_mld_get_primary_link(mvm, vif, vif->active_links);
+       WARN_ON(link_id < 0);
+
+       ieee80211_set_active_links_async(vif,
+                                        vif->active_links & BIT(link_id));
+}
+
 /*
  * This function receives a bitmap of usable links and check if we can enter
  * eSR on those links.
@@ -1300,7 +1327,7 @@ static bool iwl_mvm_can_enter_esr(struct iwl_mvm *mvm,
                                                         primary_link);
                // Mark eSR as disabled for the next time
                if (!ret)
-                       mvmvif->bt_coex_esr_disabled = true;
+                       mvmvif->esr_disable_reason |= IWL_MVM_ESR_DISABLE_COEX;
                break;
        }
 
index a3f42dec97d2d89ebb7d103f3ccd2ddcef843749..0dd83e0171ba544a25d6d8fee5e2fbf93006829c 100644 (file)
@@ -345,6 +345,14 @@ struct iwl_mvm_vif_link_info {
        struct iwl_mvm_link_bf_data bf_data;
 };
 
+/**
+ * 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_disable_reason {
+       IWL_MVM_ESR_DISABLE_COEX        = BIT(0),
+};
+
 /**
  * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context
  * @mvm: pointer back to the mvm struct
@@ -360,7 +368,6 @@ struct iwl_mvm_vif_link_info {
  * @pm_enabled - indicate if MAC power management is allowed
  * @monitor_active: indicates that monitor context is configured, and that the
  *     interface should get quota etc.
- * @bt_coex_esr_disabled: indicates if esr is disabled due to bt coex
  * @low_latency: bit flags for low latency
  *     see enum &iwl_mvm_low_latency_cause for causes.
  * @low_latency_actual: boolean, indicates low latency is set,
@@ -379,6 +386,7 @@ struct iwl_mvm_vif_link_info {
  * @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
  * @pm_enabled: indicates powersave is enabled
  */
 struct iwl_mvm_vif {
@@ -393,7 +401,6 @@ struct iwl_mvm_vif {
        bool pm_enabled;
        bool monitor_active;
        bool esr_active;
-       bool bt_coex_esr_disabled;
 
        u8 low_latency: 6;
        u8 low_latency_actual: 1;
@@ -401,6 +408,7 @@ struct iwl_mvm_vif {
        u8 authorized:1;
        bool ps_disabled;
 
+       u32 esr_disable_reason;
        u32 ap_beacon_time;
        bool bf_enabled;
        bool ba_enabled;
@@ -1587,7 +1595,7 @@ static inline int iwl_mvm_max_active_links(struct iwl_mvm *mvm,
                return mvm->fw->ucode_capa.num_beacons;
 
        if ((iwl_mvm_is_esr_supported(trans) &&
-            !mvmvif->bt_coex_esr_disabled) ||
+            !mvmvif->esr_disable_reason) ||
            ((CSR_HW_RFID_TYPE(trans->hw_rf_id) == IWL_CFG_RF_TYPE_FM &&
             CSR_HW_RFID_IS_CDB(trans->hw_rf_id))))
                return IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM;
@@ -2808,4 +2816,8 @@ int iwl_mvm_roc_add_cmd(struct iwl_mvm *mvm,
                        struct ieee80211_channel *channel,
                        struct ieee80211_vif *vif,
                        int duration, u32 activity);
+
+/* EMLSR */
+void iwl_mvm_recalc_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
+
 #endif /* __IWL_MVM_H__ */