[PATCH] AP MLD: Break the mutual ACS deferral between partner links
Nilanka de Silva
nilankadsilva at gmail.com
Tue Sep 22 09:27:12 PDT 2026
hostapd_driver_scan() refuses to start an ACS scan while any ML partner
link's interface is in HAPD_IFACE_ACS state. When two links of the same
MLD are configured with channel=0 they enter that state at the same
time, each sees the other "in ACS", and both return -EBUSY. acs.c retries
every ACS_SCAN_RETRY_INTERVAL until ACS_SCAN_RETRY_MAX_COUNT, then one
link fails ("ACS: Failed to request initial scan (all re-attempts
failed)") and is disabled, leaving a single-link MLD. Nothing ever
breaks the tie, because the state check does not distinguish a partner
that is scanning from a partner that is also waiting to scan.
Observed on MT7996 (one wiphy, 5 GHz + 6 GHz AP MLD links): both links
log "ACS in progress in a partner link - try to scan later" and "Failed
to request acs scan ret=-16 (Resource busy)" in lock step for the whole
retry window. The behaviour is the same under different regulatory
domains (NL, SA); a separate non-MLD BSS on the same wiphy completes ACS
normally.
Only defer while the partner really has a scan in flight (scan_cb set).
When both links are still waiting to start, let the link with the lowest
mld_link_id go first so the two ACS runs serialise.
Tested on MT7996 with both MLD links on ACS: the second link logs
"Partner link 1 starts ACS first - try to scan later", the first link
completes ACS, then the second runs its own; both links are up about
50 s after start, on a reload and on a cold boot.
Signed-off-by: Nilanka de Silva <nilankadsilva at gmail.com>
---
src/ap/ap_drv_ops.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index 0b83a67..5ab76d9 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -837,12 +837,28 @@ int hostapd_driver_scan(struct hostapd_data *hapd,
h_hapd = h_iface->bss[0];
- if (hostapd_is_ml_partner(hapd, h_hapd) &&
- h_hapd->iface->state == HAPD_IFACE_ACS) {
+ if (!hostapd_is_ml_partner(hapd, h_hapd) ||
+ h_hapd->iface->state != HAPD_IFACE_ACS)
+ continue;
+
+ /* The partner has a scan in flight: wait for it. */
+ if (h_hapd->iface->scan_cb) {
wpa_printf(MSG_INFO,
"ACS in progress in a partner link - try to scan later");
return -EBUSY;
}
+
+ /*
+ * Both links are still waiting to start their ACS scan:
+ * let the lowest link id go first so the scans serialise
+ * instead of deferring to each other forever.
+ */
+ if (h_hapd->mld_link_id < hapd->mld_link_id) {
+ wpa_printf(MSG_INFO,
+ "Partner link %d starts ACS first - try to scan later",
+ h_hapd->mld_link_id);
+ return -EBUSY;
+ }
}
}
#endif /* CONFIG_IEEE80211BE */
--
2.54.0 (Apple Git-157)
More information about the Hostap
mailing list