Skip to content

Commit df966c9

Browse files
Miriam-Racheljmberg-intel
authored andcommitted
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: Miri Korenblit <[email protected]> Reviewed-by: Johannes Berg <[email protected]> Link: https://msgid.link/20240506095953.99ad1d71e9b9.Ide825433488ec809773efdc36937e3089d0012df@changeid Signed-off-by: Johannes Berg <[email protected]>
1 parent bf0212f commit df966c9

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

drivers/net/wireless/intel/iwlwifi/mvm/link.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
HOW(EXIT_LOW_RSSI) \
1616
HOW(EXIT_COEX) \
1717
HOW(EXIT_BANDWIDTH) \
18-
HOW(EXIT_CSA)
18+
HOW(EXIT_CSA) \
19+
HOW(EXIT_LINK_USAGE)
1920

2021
static const char *const iwl_mvm_esr_states_names[] = {
2122
#define NAME_ENTRY(x) [ilog2(IWL_MVM_ESR_##x)] = #x,

drivers/net/wireless/intel/iwlwifi/mvm/mvm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ struct iwl_mvm_vif_link_info {
369369
* @IWL_MVM_ESR_EXIT_BANDWIDTH: Bandwidths of primary and secondry links
370370
* preventing the enablement of EMLSR
371371
* @IWL_MVM_ESR_EXIT_CSA: CSA happened, so exit EMLSR
372+
* @IWL_MVM_ESR_EXIT_LINK_USAGE: Exit EMLSR due to low tpt on secondary link
372373
*/
373374
enum iwl_mvm_esr_state {
374375
IWL_MVM_ESR_BLOCKED_PREVENTION = 0x1,
@@ -381,6 +382,7 @@ enum iwl_mvm_esr_state {
381382
IWL_MVM_ESR_EXIT_COEX = 0x40000,
382383
IWL_MVM_ESR_EXIT_BANDWIDTH = 0x80000,
383384
IWL_MVM_ESR_EXIT_CSA = 0x100000,
385+
IWL_MVM_ESR_EXIT_LINK_USAGE = 0x200000,
384386
};
385387

386388
#define IWL_MVM_BLOCK_ESR_REASONS 0xffff

drivers/net/wireless/intel/iwlwifi/mvm/rx.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,12 +951,19 @@ iwl_mvm_stat_iterator_all_links(struct iwl_mvm *mvm,
951951
}
952952
}
953953

954+
#define SEC_LINK_MIN_PERC 10
955+
#define SEC_LINK_MIN_TX 3000
956+
#define SEC_LINK_MIN_RX 400
957+
954958
static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
955959
{
956960
struct ieee80211_vif *bss_vif = iwl_mvm_get_bss_vif(mvm);
957961
struct iwl_mvm_vif *mvmvif;
958962
struct iwl_mvm_sta *mvmsta;
959963
unsigned long total_tx = 0, total_rx = 0;
964+
unsigned long sec_link_tx = 0, sec_link_rx = 0;
965+
u8 sec_link_tx_perc, sec_link_rx_perc;
966+
u8 sec_link;
960967

961968
lockdep_assert_held(&mvm->mutex);
962969

@@ -973,6 +980,13 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
973980
if (!mvmsta->mpdu_counters)
974981
return;
975982

983+
/* Get the FW ID of the secondary link */
984+
sec_link = iwl_mvm_get_other_link(bss_vif,
985+
iwl_mvm_get_primary_link(bss_vif));
986+
if (WARN_ON(!mvmvif->link[sec_link]))
987+
return;
988+
sec_link = mvmvif->link[sec_link]->fw_link_id;
989+
976990
/* Sum up RX and TX MPDUs from the different queues/links */
977991
for (int q = 0; q < mvm->trans->num_rx_queues; q++) {
978992
spin_lock_bh(&mvmsta->mpdu_counters[q].lock);
@@ -982,6 +996,10 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
982996
total_tx += mvmsta->mpdu_counters[q].per_link[link].tx;
983997
total_rx += mvmsta->mpdu_counters[q].per_link[link].rx;
984998
}
999+
1000+
sec_link_tx += mvmsta->mpdu_counters[q].per_link[sec_link].tx;
1001+
sec_link_rx += mvmsta->mpdu_counters[q].per_link[sec_link].rx;
1002+
9851003
/*
9861004
* In EMLSR we have statistics every 5 seconds, so we can reset
9871005
* the counters upon every statistics notification.
@@ -994,9 +1012,26 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
9941012

9951013
/* If we don't have enough MPDUs - exit EMLSR */
9961014
if (total_tx < IWL_MVM_ENTER_ESR_TPT_THRESH &&
997-
total_rx < IWL_MVM_ENTER_ESR_TPT_THRESH)
1015+
total_rx < IWL_MVM_ENTER_ESR_TPT_THRESH) {
9981016
iwl_mvm_block_esr(mvm, bss_vif, IWL_MVM_ESR_BLOCKED_TPT,
9991017
iwl_mvm_get_primary_link(bss_vif));
1018+
return;
1019+
}
1020+
1021+
/* Calculate the percentage of the secondary link TX/RX */
1022+
sec_link_tx_perc = total_tx ? sec_link_tx * 100 / total_tx : 0;
1023+
sec_link_rx_perc = total_rx ? sec_link_rx * 100 / total_rx : 0;
1024+
1025+
/*
1026+
* The TX/RX percentage is checked only if it exceeds the required
1027+
* minimum. In addition, RX is checked only if the TX check failed.
1028+
*/
1029+
if ((total_tx > SEC_LINK_MIN_TX &&
1030+
sec_link_tx_perc < SEC_LINK_MIN_PERC) ||
1031+
(total_rx > SEC_LINK_MIN_RX &&
1032+
sec_link_rx_perc < SEC_LINK_MIN_PERC))
1033+
iwl_mvm_exit_esr(mvm, bss_vif, IWL_MVM_ESR_EXIT_LINK_USAGE,
1034+
iwl_mvm_get_primary_link(bss_vif));
10001035
}
10011036

10021037
void iwl_mvm_handle_rx_system_oper_stats(struct iwl_mvm *mvm,

0 commit comments

Comments
 (0)