mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-09 12:33:18 -04:00
wifi: iwlwifi: mld: don't check the TPT counters when scanning
If there is an ongoing scan that lasts long, the MPDU counters may not increase enough due the device being busy with scanning and not because we are in a low throughput scenario. In that case we don't want to block EMLSR. Instead, stop checking the counters from the moment we started scanning, and when the scan ends - clear the counters and schedule a check in 5 seconds, as usual. Note that this is only done for regular scan since MLO scan is too short to affect the counters, and scheduled scan is mainly used when we are not connected. Also note that we only stop checking whether to block EMLSR, and not if to unblock. Reviewed-by: Johannes Berg <johannes.berg@intel.com> Link: https://patch.msgid.link/20250505215512.330ea440d19c.Ib10dae0b7a0cb0e10c59a9edf5ff7af0f065ac60@changeid Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
This commit is contained in:
@@ -1322,13 +1322,22 @@ iwl_mld_mac80211_hw_scan(struct ieee80211_hw *hw,
|
||||
struct ieee80211_scan_request *hw_req)
|
||||
{
|
||||
struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(!hw_req->req.n_channels ||
|
||||
hw_req->req.n_channels >
|
||||
mld->fw->ucode_capa.n_scan_channels))
|
||||
return -EINVAL;
|
||||
|
||||
return iwl_mld_regular_scan_start(mld, vif, &hw_req->req, &hw_req->ies);
|
||||
ret = iwl_mld_regular_scan_start(mld, vif, &hw_req->req, &hw_req->ies);
|
||||
if (!ret) {
|
||||
/* We will be busy with scanning, so the counters may not reflect the
|
||||
* reality. Stop checking the counters until the scan ends
|
||||
*/
|
||||
iwl_mld_start_ignoring_tpt_updates(mld);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1344,8 +1353,11 @@ iwl_mld_mac80211_cancel_hw_scan(struct ieee80211_hw *hw,
|
||||
* cancel scan before ieee80211_scan_work() could run.
|
||||
* To handle that, simply return if the scan is not running.
|
||||
*/
|
||||
if (mld->scan.status & IWL_MLD_SCAN_REGULAR)
|
||||
if (mld->scan.status & IWL_MLD_SCAN_REGULAR) {
|
||||
iwl_mld_scan_stop(mld, IWL_MLD_SCAN_REGULAR, true);
|
||||
/* Scan is over, we can check again the tpt counters */
|
||||
iwl_mld_stop_ignoring_tpt_updates(mld);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -1170,3 +1170,69 @@ void iwl_mld_retry_emlsr(struct iwl_mld *mld, struct ieee80211_vif *vif)
|
||||
|
||||
iwl_mld_int_mlo_scan(mld, vif);
|
||||
}
|
||||
|
||||
static void iwl_mld_ignore_tpt_iter(void *data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
|
||||
struct iwl_mld *mld = mld_vif->mld;
|
||||
struct iwl_mld_sta *mld_sta;
|
||||
bool *start = (void *)data;
|
||||
|
||||
/* check_tpt_wk is only used when TPT block isn't set */
|
||||
if (mld_vif->emlsr.blocked_reasons & IWL_MLD_EMLSR_BLOCKED_TPT ||
|
||||
!IWL_MLD_AUTO_EML_ENABLE || !mld_vif->ap_sta)
|
||||
return;
|
||||
|
||||
mld_sta = iwl_mld_sta_from_mac80211(mld_vif->ap_sta);
|
||||
|
||||
/* We only count for the AP sta in a MLO connection */
|
||||
if (!mld_sta->mpdu_counters)
|
||||
return;
|
||||
|
||||
if (*start) {
|
||||
wiphy_delayed_work_cancel(mld_vif->mld->wiphy,
|
||||
&mld_vif->emlsr.check_tpt_wk);
|
||||
IWL_DEBUG_EHT(mld, "TPT check disabled\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clear the counters so we start from the beginning */
|
||||
for (int q = 0; q < mld->trans->info.num_rxqs; q++) {
|
||||
struct iwl_mld_per_q_mpdu_counter *queue_counter =
|
||||
&mld_sta->mpdu_counters[q];
|
||||
|
||||
spin_lock_bh(&queue_counter->lock);
|
||||
|
||||
memset(queue_counter->per_link, 0,
|
||||
sizeof(queue_counter->per_link));
|
||||
|
||||
spin_unlock_bh(&queue_counter->lock);
|
||||
}
|
||||
|
||||
/* Schedule the check in 5 seconds */
|
||||
wiphy_delayed_work_queue(mld_vif->mld->wiphy,
|
||||
&mld_vif->emlsr.check_tpt_wk,
|
||||
round_jiffies_relative(IWL_MLD_TPT_COUNT_WINDOW));
|
||||
IWL_DEBUG_EHT(mld, "TPT check enabled\n");
|
||||
}
|
||||
|
||||
void iwl_mld_start_ignoring_tpt_updates(struct iwl_mld *mld)
|
||||
{
|
||||
bool start = true;
|
||||
|
||||
ieee80211_iterate_active_interfaces_mtx(mld->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mld_ignore_tpt_iter,
|
||||
&start);
|
||||
}
|
||||
|
||||
void iwl_mld_stop_ignoring_tpt_updates(struct iwl_mld *mld)
|
||||
{
|
||||
bool start = false;
|
||||
|
||||
ieee80211_iterate_active_interfaces_mtx(mld->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mld_ignore_tpt_iter,
|
||||
&start);
|
||||
}
|
||||
|
||||
@@ -167,4 +167,7 @@ bool iwl_mld_bt_allows_emlsr(struct iwl_mld *mld,
|
||||
bool entry_criteria);
|
||||
#endif
|
||||
|
||||
void iwl_mld_start_ignoring_tpt_updates(struct iwl_mld *mld);
|
||||
void iwl_mld_stop_ignoring_tpt_updates(struct iwl_mld *mld);
|
||||
|
||||
#endif /* __iwl_mld_mlo_h__ */
|
||||
|
||||
@@ -1920,6 +1920,9 @@ void iwl_mld_handle_scan_complete_notif(struct iwl_mld *mld,
|
||||
IWL_DEBUG_SCAN(mld, "Scan link is no longer valid\n");
|
||||
|
||||
ieee80211_scan_completed(mld->hw, &info);
|
||||
|
||||
/* Scan is over, we can check again the tpt counters */
|
||||
iwl_mld_stop_ignoring_tpt_updates(mld);
|
||||
} else if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_SCHED) {
|
||||
ieee80211_sched_scan_stopped(mld->hw);
|
||||
mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED;
|
||||
|
||||
Reference in New Issue
Block a user