Currently, we don't select a link that wasn't heared in the last 5 seconds. But if the link started to suffer from missed beacons more recent than that, we might select this link even we really shouldn't, leading to a disconnection instead of a link switch. Fix this by checking if a link was heared in the last MLO scan, if not - don't include it in the link selection. Since we do an MLO scan on missed beacons, we will not hear that link in that scan, and won't select it. Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@xxxxxxxxx> Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@xxxxxxxxx> --- drivers/net/wireless/intel/iwlwifi/mld/mlo.c | 10 +++++----- drivers/net/wireless/intel/iwlwifi/mld/scan.c | 4 +++- drivers/net/wireless/intel/iwlwifi/mld/scan.h | 5 +++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mlo.c b/drivers/net/wireless/intel/iwlwifi/mld/mlo.c index 99ba4018fb24..879fa7b77780 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mlo.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mlo.c @@ -704,10 +704,9 @@ iwl_mld_set_link_sel_data(struct iwl_mld *mld, if (WARN_ON_ONCE(!link_conf)) continue; - /* Ignore any BSS that was not seen in the last 5 seconds */ + /* Ignore any BSS that was not seen in the last MLO scan */ if (ktime_before(link_conf->bss->ts_boottime, - ktime_sub_ns(ktime_get_boottime_ns(), - (u64)5 * NSEC_PER_SEC))) + mld->scan.last_mlo_scan_time)) continue; data[n_data].link_id = link_id; @@ -819,8 +818,9 @@ static void _iwl_mld_select_links(struct iwl_mld *mld, if (!mld_vif->authorized || hweight16(usable_links) <= 1) return; - if (WARN(time_before(mld->scan.last_mlo_scan_jiffies, - jiffies - IWL_MLD_SCAN_EXPIRE_TIME), + if (WARN(ktime_before(mld->scan.last_mlo_scan_time, + ktime_sub_ns(ktime_get_boottime_ns(), + 5 * NSEC_PER_SEC)), "Last MLO scan was too long ago, can't select links\n")) return; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/scan.c b/drivers/net/wireless/intel/iwlwifi/mld/scan.c index 5f4ede92028b..7ec04318ec2f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/scan.c @@ -1794,6 +1794,9 @@ static void iwl_mld_int_mlo_scan_start(struct iwl_mld *mld, ret = _iwl_mld_single_scan_start(mld, vif, req, &ies, IWL_MLD_SCAN_INT_MLO); + if (!ret) + mld->scan.last_mlo_scan_time = ktime_get_boottime_ns(); + IWL_DEBUG_SCAN(mld, "Internal MLO scan: ret=%d\n", ret); } @@ -1922,7 +1925,6 @@ void iwl_mld_handle_scan_complete_notif(struct iwl_mld *mld, mld->scan.pass_all_sched_res = SCHED_SCAN_PASS_ALL_STATE_DISABLED; } else if (mld->scan.uid_status[uid] == IWL_MLD_SCAN_INT_MLO) { IWL_DEBUG_SCAN(mld, "Internal MLO scan completed\n"); - mld->scan.last_mlo_scan_jiffies = jiffies; /* * We limit link selection to internal MLO scans as otherwise diff --git a/drivers/net/wireless/intel/iwlwifi/mld/scan.h b/drivers/net/wireless/intel/iwlwifi/mld/scan.h index cb589e002319..3ae940d55065 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/scan.h @@ -108,7 +108,8 @@ enum iwl_mld_traffic_load { * in jiffies. * @last_start_time_jiffies: stores the last start time in jiffies * (interface up/reset/resume). - * @last_mlo_scan_jiffies: end time of the last MLO scan in jiffies. + * @last_mlo_scan_time: start time of the last MLO scan in nanoseconds since + * boot. */ struct iwl_mld_scan { /* Add here fields that need clean up on restart */ @@ -129,7 +130,7 @@ struct iwl_mld_scan { void *cmd; unsigned long last_6ghz_passive_jiffies; unsigned long last_start_time_jiffies; - unsigned long last_mlo_scan_jiffies; + unsigned long last_mlo_scan_time; }; #endif /* __iwl_mld_scan_h__ */ -- 2.34.1