Commit 76f9864d authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by Johannes Berg

wifi: iwlwifi: mvm: introduce esr_disable_reason

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: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240416134215.94c3590c6f27.I6a190da5025d0523ef483ffac0c64e26675041e6@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 332ff432
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause // 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 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
*/ */
#include <linux/ieee80211.h> #include <linux/ieee80211.h>
...@@ -257,7 +257,6 @@ static void iwl_mvm_bt_coex_enable_esr(struct iwl_mvm *mvm, ...@@ -257,7 +257,6 @@ static void iwl_mvm_bt_coex_enable_esr(struct iwl_mvm *mvm,
struct ieee80211_vif *vif, bool enable) struct ieee80211_vif *vif, bool enable)
{ {
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int link_id;
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
...@@ -265,30 +264,15 @@ static void iwl_mvm_bt_coex_enable_esr(struct iwl_mvm *mvm, ...@@ -265,30 +264,15 @@ static void iwl_mvm_bt_coex_enable_esr(struct iwl_mvm *mvm,
return; return;
/* Done already */ /* Done already */
if (mvmvif->bt_coex_esr_disabled == !enable) if ((mvmvif->esr_disable_reason & IWL_MVM_ESR_DISABLE_COEX) == !enable)
return; return;
mvmvif->bt_coex_esr_disabled = !enable; if (enable)
mvmvif->esr_disable_reason &= ~IWL_MVM_ESR_DISABLE_COEX;
/* Nothing to do */ else
if (mvmvif->esr_active == enable) mvmvif->esr_disable_reason |= IWL_MVM_ESR_DISABLE_COEX;
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, iwl_mvm_recalc_esr(mvm, vif);
vif->active_links & BIT(link_id));
} }
/* /*
...@@ -336,7 +320,7 @@ iwl_mvm_bt_coex_calculate_esr_mode(struct iwl_mvm *mvm, ...@@ -336,7 +320,7 @@ iwl_mvm_bt_coex_calculate_esr_mode(struct iwl_mvm *mvm,
if (!link_rssi) if (!link_rssi)
wifi_loss_rate = mvm->last_bt_notif.wifi_loss_mid_high_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... */ /* RSSI needs to get really low to disable eSR... */
wifi_loss_rate = wifi_loss_rate =
link_rssi <= -IWL_MVM_BT_COEX_DISABLE_ESR_THRESH ? link_rssi <= -IWL_MVM_BT_COEX_DISABLE_ESR_THRESH ?
......
...@@ -1258,6 +1258,33 @@ int iwl_mvm_mld_get_primary_link(struct iwl_mvm *mvm, ...@@ -1258,6 +1258,33 @@ int iwl_mvm_mld_get_primary_link(struct iwl_mvm *mvm,
return data[1].link_id; 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 * This function receives a bitmap of usable links and check if we can enter
* eSR on those links. * eSR on those links.
...@@ -1300,7 +1327,7 @@ static bool iwl_mvm_can_enter_esr(struct iwl_mvm *mvm, ...@@ -1300,7 +1327,7 @@ static bool iwl_mvm_can_enter_esr(struct iwl_mvm *mvm,
primary_link); primary_link);
// Mark eSR as disabled for the next time // Mark eSR as disabled for the next time
if (!ret) if (!ret)
mvmvif->bt_coex_esr_disabled = true; mvmvif->esr_disable_reason |= IWL_MVM_ESR_DISABLE_COEX;
break; break;
} }
......
...@@ -345,6 +345,14 @@ struct iwl_mvm_vif_link_info { ...@@ -345,6 +345,14 @@ struct iwl_mvm_vif_link_info {
struct iwl_mvm_link_bf_data bf_data; 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 * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context
* @mvm: pointer back to the mvm struct * @mvm: pointer back to the mvm struct
...@@ -360,7 +368,6 @@ struct iwl_mvm_vif_link_info { ...@@ -360,7 +368,6 @@ struct iwl_mvm_vif_link_info {
* @pm_enabled - indicate if MAC power management is allowed * @pm_enabled - indicate if MAC power management is allowed
* @monitor_active: indicates that monitor context is configured, and that the * @monitor_active: indicates that monitor context is configured, and that the
* interface should get quota etc. * 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 * @low_latency: bit flags for low latency
* see enum &iwl_mvm_low_latency_cause for causes. * see enum &iwl_mvm_low_latency_cause for causes.
* @low_latency_actual: boolean, indicates low latency is set, * @low_latency_actual: boolean, indicates low latency is set,
...@@ -379,6 +386,7 @@ struct iwl_mvm_vif_link_info { ...@@ -379,6 +386,7 @@ struct iwl_mvm_vif_link_info {
* @deflink: default link data for use in non-MLO * @deflink: default link data for use in non-MLO
* @link: link data for each link in MLO * @link: link data for each link in MLO
* @esr_active: indicates eSR mode is active * @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 * @pm_enabled: indicates powersave is enabled
*/ */
struct iwl_mvm_vif { struct iwl_mvm_vif {
...@@ -393,7 +401,6 @@ struct iwl_mvm_vif { ...@@ -393,7 +401,6 @@ struct iwl_mvm_vif {
bool pm_enabled; bool pm_enabled;
bool monitor_active; bool monitor_active;
bool esr_active; bool esr_active;
bool bt_coex_esr_disabled;
u8 low_latency: 6; u8 low_latency: 6;
u8 low_latency_actual: 1; u8 low_latency_actual: 1;
...@@ -401,6 +408,7 @@ struct iwl_mvm_vif { ...@@ -401,6 +408,7 @@ struct iwl_mvm_vif {
u8 authorized:1; u8 authorized:1;
bool ps_disabled; bool ps_disabled;
u32 esr_disable_reason;
u32 ap_beacon_time; u32 ap_beacon_time;
bool bf_enabled; bool bf_enabled;
bool ba_enabled; bool ba_enabled;
...@@ -1587,7 +1595,7 @@ static inline int iwl_mvm_max_active_links(struct iwl_mvm *mvm, ...@@ -1587,7 +1595,7 @@ static inline int iwl_mvm_max_active_links(struct iwl_mvm *mvm,
return mvm->fw->ucode_capa.num_beacons; return mvm->fw->ucode_capa.num_beacons;
if ((iwl_mvm_is_esr_supported(trans) && 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_TYPE(trans->hw_rf_id) == IWL_CFG_RF_TYPE_FM &&
CSR_HW_RFID_IS_CDB(trans->hw_rf_id)))) CSR_HW_RFID_IS_CDB(trans->hw_rf_id))))
return IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM; return IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM;
...@@ -2808,4 +2816,8 @@ int iwl_mvm_roc_add_cmd(struct iwl_mvm *mvm, ...@@ -2808,4 +2816,8 @@ int iwl_mvm_roc_add_cmd(struct iwl_mvm *mvm,
struct ieee80211_channel *channel, struct ieee80211_channel *channel,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
int duration, u32 activity); int duration, u32 activity);
/* EMLSR */
void iwl_mvm_recalc_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
#endif /* __IWL_MVM_H__ */ #endif /* __IWL_MVM_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment