ACS: Handle scan start request failure with error code -EBUSY
Currently, if ACS scan request fails, states are cleared and returned. However, in case of MLO, there is a possibilty of getting return value of -EBUSY. In this case, ACS can retry the scan request after some time similary to the HT40 scan. Hence, retry the scan after 5 seconds if -EBUSY is returned. Maximum of 15 re-attempts are made before giving up. Signed-off-by: Harshitha Prem <quic_hprem@quicinc.com> Co-developed-by: Aditya Kumar Singh <quic_adisi@quicinc.com> Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
This commit is contained in:
parent
3cf7bf68f4
commit
3e52a90d34
3 changed files with 56 additions and 9 deletions
59
src/ap/acs.c
59
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;
|
||||
}
|
||||
|
@ -1382,7 +1387,7 @@ static int * acs_request_scan_add_freqs(struct hostapd_iface *iface,
|
|||
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,21 +1420,59 @@ static int acs_request_scan(struct hostapd_iface *iface)
|
|||
return -1;
|
||||
}
|
||||
|
||||
iface->scan_cb = acs_scan_complete;
|
||||
|
||||
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);
|
||||
|
||||
if (hostapd_driver_scan(iface->bss[0], ¶ms) < 0) {
|
||||
wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan");
|
||||
acs_cleanup(iface);
|
||||
ret = hostapd_driver_scan(iface->bss[0], ¶ms);
|
||||
os_free(params.freqs);
|
||||
|
||||
if (ret == -EBUSY) {
|
||||
iface->acs_num_retries++;
|
||||
if (iface->acs_num_retries >= ACS_SCAN_RETRY_MAX_COUNT) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"ACS: Failed to request initial scan (all re-attempts failed)");
|
||||
acs_fail(iface);
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_free(params.freqs);
|
||||
wpa_printf(MSG_INFO,
|
||||
"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;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan");
|
||||
acs_cleanup(iface);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (acs_request_scan(iface)) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"ACS: Failed to request re-try of initial scan");
|
||||
acs_fail(iface);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue