@@ -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+
954958static 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
10021037void iwl_mvm_handle_rx_system_oper_stats (struct iwl_mvm * mvm ,
0 commit comments