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: 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>
This commit is contained in:
committed by
Johannes Berg
parent
332ff43251
commit
76f9864d7a
@@ -1,6 +1,6 @@
|
|||||||
// 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,
|
|||||||
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,
|
|||||||
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;
|
||||||
|
else
|
||||||
|
mvmvif->esr_disable_reason |= IWL_MVM_ESR_DISABLE_COEX;
|
||||||
|
|
||||||
/* Nothing to do */
|
iwl_mvm_recalc_esr(mvm, vif);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -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,
|
|||||||
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,
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
* @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 {
|
|||||||
* @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 {
|
|||||||
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 {
|
|||||||
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,
|
|||||||
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,
|
|||||||
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__ */
|
||||||
|
Reference in New Issue
Block a user