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@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Link: https://patch.msgid.link/20250309073442.8f950497219e.I51306021fe9231a8184e89c23707be47d3c05241@changeid
[replace cast with ULL constant]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
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;
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(),
+ 5ULL * NSEC_PER_SEC)),
"Last MLO scan was too long ago, can't select links\n"))
return;
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);
}
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
* 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 */
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__ */