From: Harshitha Prem <quic_hprem@xxxxxxxxxxx> Currently, if ACS scan request fails, states are cleared and returned. However, in case of multi link opertion, there is a possibilty of getting return value of -EBUSY. In this case, ACS can retry the scan request after some time same like HT-40 scan. Hence, add changes to retry the scan after 5 seconds if -EBUSY is returned. Max 15 re-attempts would be made post which no further attempts would be made. Signed-off-by: Harshitha Prem <quic_hprem@xxxxxxxxxxx> Co-developed-by: Aditya Kumar Singh <quic_adisi@xxxxxxxxxxx> Signed-off-by: Aditya Kumar Singh <quic_adisi@xxxxxxxxxxx> --- src/ap/acs.c | 62 +++++++++++++++++++++++++++++++++++++++--------- src/ap/acs.h | 3 +++ src/ap/hostapd.h | 1 + 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/ap/acs.c b/src/ap/acs.c index 28b0ba71cc7b..24804e8ec8b2 100644 --- a/src/ap/acs.c +++ b/src/ap/acs.c @@ -12,6 +12,7 @@ #include "utils/common.h" #include "utils/list.h" +#include "utils/eloop.h" #include "common/ieee802_11_defs.h" #include "common/hw_features_common.h" #include "common/wpa_ctrl.h" @@ -307,6 +308,7 @@ static const struct bw_item *bw_desc[] = { static int acs_request_scan(struct hostapd_iface *iface); static int acs_survey_is_sufficient(struct freq_survey *survey); +static void acs_scan_retry(void *eloop_data, void *user_data); static void acs_clean_chan_surveys(struct hostapd_channel_data *chan) @@ -352,6 +354,8 @@ void acs_cleanup(struct hostapd_iface *iface) iface->chans_surveyed = 0; iface->acs_num_completed_scans = 0; + iface->acs_num_retries = 0; + eloop_cancel_timeout(acs_scan_retry, iface, NULL); } @@ -1317,6 +1321,7 @@ static void acs_scan_complete(struct hostapd_iface *iface) int err; iface->scan_cb = NULL; + iface->acs_num_retries = 0; wpa_printf(MSG_DEBUG, "ACS: Using survey based algorithm (acs_num_scans=%d)", iface->conf->acs_num_scans); @@ -1329,7 +1334,7 @@ static void acs_scan_complete(struct hostapd_iface *iface) if (++iface->acs_num_completed_scans < iface->conf->acs_num_scans) { err = acs_request_scan(iface); - if (err) { + if (err && err != -EBUSY) { wpa_printf(MSG_ERROR, "ACS: Failed to request scan"); goto fail; } @@ -1378,11 +1383,10 @@ static int * acs_request_scan_add_freqs(struct hostapd_iface *iface, return freq; } - static int acs_request_scan(struct hostapd_iface *iface) { struct wpa_driver_scan_params params; - int i, *freq; + int i, *freq, ret; int num_channels; struct hostapd_hw_modes *mode; @@ -1415,24 +1419,60 @@ static int acs_request_scan(struct hostapd_iface *iface) return -1; } - iface->scan_cb = acs_scan_complete; - - wpa_printf(MSG_DEBUG, "ACS: Scanning %d / %d", - iface->acs_num_completed_scans + 1, - iface->conf->acs_num_scans); + if (!iface->acs_num_retries) + wpa_printf(MSG_DEBUG, "ACS: Scanning %d / %d", + iface->acs_num_completed_scans + 1, + iface->conf->acs_num_scans); + else + wpa_printf(MSG_DEBUG, "ACS: Re-try Scanning attempt %d (%d / %d)", + iface->acs_num_retries, + iface->acs_num_completed_scans + 1, + iface->conf->acs_num_scans); + + ret = hostapd_driver_scan(iface->bss[0], ¶ms); + os_free(params.freqs); - if (hostapd_driver_scan(iface->bss[0], ¶ms) < 0) { + if (ret == -EBUSY) { + iface->acs_num_retries++; + wpa_printf(MSG_ERROR, "Failed to request acs scan ret=%d (%s) - try to scan after %d seconds", + ret, strerror(-ret), ACS_SCAN_RETRY_INTERVAL); + eloop_cancel_timeout(acs_scan_retry, iface, NULL); + eloop_register_timeout(ACS_SCAN_RETRY_INTERVAL, 0, + acs_scan_retry, iface, NULL); + return 0; + } else if (ret < 0) { wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan"); acs_cleanup(iface); - os_free(params.freqs); return -1; } - os_free(params.freqs); + iface->scan_cb = acs_scan_complete; + return 0; } +static void acs_scan_retry(void *eloop_data, void *user_data) +{ + struct hostapd_iface *iface = eloop_data; + int ret; + + if (iface->acs_num_retries >= ACS_SCAN_RETRY_MAX_COUNT) { + wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan (all re-attempts failed)"); + goto acs_fail; + } + + ret = acs_request_scan(iface); + if (!ret) + return; + + wpa_printf(MSG_ERROR, "ACS: Failed to request re-try of initial scan"); + +acs_fail: + acs_fail(iface); +} + + enum hostapd_chan_status acs_init(struct hostapd_iface *iface) { int err; diff --git a/src/ap/acs.h b/src/ap/acs.h index ec84f0ee97f3..8be3de5b5f78 100644 --- a/src/ap/acs.h +++ b/src/ap/acs.h @@ -15,6 +15,9 @@ enum hostapd_chan_status acs_init(struct hostapd_iface *iface); void acs_cleanup(struct hostapd_iface *iface); +#define ACS_SCAN_RETRY_MAX_COUNT 15 +#define ACS_SCAN_RETRY_INTERVAL 5 + #else /* CONFIG_ACS */ static inline enum hostapd_chan_status acs_init(struct hostapd_iface *iface) diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 1d1943ac52ec..7454cdab179d 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -682,6 +682,7 @@ struct hostapd_iface { #ifdef CONFIG_ACS unsigned int acs_num_completed_scans; + unsigned int acs_num_retries; #endif /* CONFIG_ACS */ void (*scan_cb)(struct hostapd_iface *iface); -- 2.34.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap