Commit df966c93 authored by Miri Korenblit's avatar Miri Korenblit Committed by Johannes Berg

wifi: iwlwifi: mvm: exit EMLSR if secondary link is not used

Exit EMLSR mode if the secondary link is not used enough for Rx/Tx
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Link: https://msgid.link/20240506095953.99ad1d71e9b9.Ide825433488ec809773efdc36937e3089d0012df@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent bf0212fd
......@@ -15,7 +15,8 @@
HOW(EXIT_LOW_RSSI) \
HOW(EXIT_COEX) \
HOW(EXIT_BANDWIDTH) \
HOW(EXIT_CSA)
HOW(EXIT_CSA) \
HOW(EXIT_LINK_USAGE)
static const char *const iwl_mvm_esr_states_names[] = {
#define NAME_ENTRY(x) [ilog2(IWL_MVM_ESR_##x)] = #x,
......
......@@ -369,6 +369,7 @@ struct iwl_mvm_vif_link_info {
* @IWL_MVM_ESR_EXIT_BANDWIDTH: Bandwidths of primary and secondry links
* preventing the enablement of EMLSR
* @IWL_MVM_ESR_EXIT_CSA: CSA happened, so exit EMLSR
* @IWL_MVM_ESR_EXIT_LINK_USAGE: Exit EMLSR due to low tpt on secondary link
*/
enum iwl_mvm_esr_state {
IWL_MVM_ESR_BLOCKED_PREVENTION = 0x1,
......@@ -381,6 +382,7 @@ enum iwl_mvm_esr_state {
IWL_MVM_ESR_EXIT_COEX = 0x40000,
IWL_MVM_ESR_EXIT_BANDWIDTH = 0x80000,
IWL_MVM_ESR_EXIT_CSA = 0x100000,
IWL_MVM_ESR_EXIT_LINK_USAGE = 0x200000,
};
#define IWL_MVM_BLOCK_ESR_REASONS 0xffff
......
......@@ -951,12 +951,19 @@ iwl_mvm_stat_iterator_all_links(struct iwl_mvm *mvm,
}
}
#define SEC_LINK_MIN_PERC 10
#define SEC_LINK_MIN_TX 3000
#define SEC_LINK_MIN_RX 400
static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
{
struct ieee80211_vif *bss_vif = iwl_mvm_get_bss_vif(mvm);
struct iwl_mvm_vif *mvmvif;
struct iwl_mvm_sta *mvmsta;
unsigned long total_tx = 0, total_rx = 0;
unsigned long sec_link_tx = 0, sec_link_rx = 0;
u8 sec_link_tx_perc, sec_link_rx_perc;
u8 sec_link;
lockdep_assert_held(&mvm->mutex);
......@@ -973,6 +980,13 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
if (!mvmsta->mpdu_counters)
return;
/* Get the FW ID of the secondary link */
sec_link = iwl_mvm_get_other_link(bss_vif,
iwl_mvm_get_primary_link(bss_vif));
if (WARN_ON(!mvmvif->link[sec_link]))
return;
sec_link = mvmvif->link[sec_link]->fw_link_id;
/* Sum up RX and TX MPDUs from the different queues/links */
for (int q = 0; q < mvm->trans->num_rx_queues; q++) {
spin_lock_bh(&mvmsta->mpdu_counters[q].lock);
......@@ -982,6 +996,10 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
total_tx += mvmsta->mpdu_counters[q].per_link[link].tx;
total_rx += mvmsta->mpdu_counters[q].per_link[link].rx;
}
sec_link_tx += mvmsta->mpdu_counters[q].per_link[sec_link].tx;
sec_link_rx += mvmsta->mpdu_counters[q].per_link[sec_link].rx;
/*
* In EMLSR we have statistics every 5 seconds, so we can reset
* the counters upon every statistics notification.
......@@ -994,9 +1012,26 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
/* If we don't have enough MPDUs - exit EMLSR */
if (total_tx < IWL_MVM_ENTER_ESR_TPT_THRESH &&
total_rx < IWL_MVM_ENTER_ESR_TPT_THRESH)
total_rx < IWL_MVM_ENTER_ESR_TPT_THRESH) {
iwl_mvm_block_esr(mvm, bss_vif, IWL_MVM_ESR_BLOCKED_TPT,
iwl_mvm_get_primary_link(bss_vif));
return;
}
/* Calculate the percentage of the secondary link TX/RX */
sec_link_tx_perc = total_tx ? sec_link_tx * 100 / total_tx : 0;
sec_link_rx_perc = total_rx ? sec_link_rx * 100 / total_rx : 0;
/*
* The TX/RX percentage is checked only if it exceeds the required
* minimum. In addition, RX is checked only if the TX check failed.
*/
if ((total_tx > SEC_LINK_MIN_TX &&
sec_link_tx_perc < SEC_LINK_MIN_PERC) ||
(total_rx > SEC_LINK_MIN_RX &&
sec_link_rx_perc < SEC_LINK_MIN_PERC))
iwl_mvm_exit_esr(mvm, bss_vif, IWL_MVM_ESR_EXIT_LINK_USAGE,
iwl_mvm_get_primary_link(bss_vif));
}
void iwl_mvm_handle_rx_system_oper_stats(struct iwl_mvm *mvm,
......
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