Scan 6 GHz channels after change to 6 GHz-allowed regdom
Drivers will often report regdom changes in the middle of a scan if they detect during that scan that the regulatory domain has changed. If this happens and we enter a regdom that supports 6 GHz channels when the previous one didn't (this often happens in 6 GHz-capable regdoms for devices after suspend/resume), immediately trigger a 6 GHz-only scan if we were not able to connect to an AP on a legacy band. This should significantly improve connection time to 6 GHz AP after regdom has been reset. Signed-off-by: Matthew Wang <matthewmwang@chromium.org>
This commit is contained in:
parent
0b8a672253
commit
42add3c27b
9 changed files with 84 additions and 16 deletions
|
@ -305,7 +305,7 @@ static void bgscan_learn_timeout(void *eloop_ctx, void *timeout_ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "bgscan learn: Request a background scan");
|
wpa_printf(MSG_DEBUG, "bgscan learn: Request a background scan");
|
||||||
if (wpa_supplicant_trigger_scan(wpa_s, ¶ms, true)) {
|
if (wpa_supplicant_trigger_scan(wpa_s, ¶ms, true, false)) {
|
||||||
wpa_printf(MSG_DEBUG, "bgscan learn: Failed to trigger scan");
|
wpa_printf(MSG_DEBUG, "bgscan learn: Failed to trigger scan");
|
||||||
eloop_register_timeout(data->scan_interval, 0,
|
eloop_register_timeout(data->scan_interval, 0,
|
||||||
bgscan_learn_timeout, data, NULL);
|
bgscan_learn_timeout, data, NULL);
|
||||||
|
|
|
@ -49,7 +49,7 @@ static void bgscan_simple_timeout(void *eloop_ctx, void *timeout_ctx)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "bgscan simple: Request a background scan");
|
wpa_printf(MSG_DEBUG, "bgscan simple: Request a background scan");
|
||||||
if (wpa_supplicant_trigger_scan(wpa_s, ¶ms, true)) {
|
if (wpa_supplicant_trigger_scan(wpa_s, ¶ms, true, false)) {
|
||||||
wpa_printf(MSG_DEBUG, "bgscan simple: Failed to trigger scan");
|
wpa_printf(MSG_DEBUG, "bgscan simple: Failed to trigger scan");
|
||||||
eloop_register_timeout(data->scan_interval, 0,
|
eloop_register_timeout(data->scan_interval, 0,
|
||||||
bgscan_simple_timeout, data, NULL);
|
bgscan_simple_timeout, data, NULL);
|
||||||
|
|
|
@ -1727,7 +1727,7 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
|
||||||
wpa_s->last_scan_req = MANUAL_SCAN_REQ;
|
wpa_s->last_scan_req = MANUAL_SCAN_REQ;
|
||||||
if (wpa_supplicant_trigger_scan(wpa_s,
|
if (wpa_supplicant_trigger_scan(wpa_s,
|
||||||
¶ms,
|
¶ms,
|
||||||
false)) {
|
false, false)) {
|
||||||
reply = wpas_dbus_error_scan_error(
|
reply = wpas_dbus_error_scan_error(
|
||||||
message,
|
message,
|
||||||
"Scan request rejected");
|
"Scan request rejected");
|
||||||
|
@ -1753,7 +1753,8 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_s->last_scan_req = MANUAL_SCAN_REQ;
|
wpa_s->last_scan_req = MANUAL_SCAN_REQ;
|
||||||
if (wpa_supplicant_trigger_scan(wpa_s, ¶ms, !custom_ies)) {
|
if (wpa_supplicant_trigger_scan(wpa_s, ¶ms, !custom_ies,
|
||||||
|
false)) {
|
||||||
reply = wpas_dbus_error_scan_error(
|
reply = wpas_dbus_error_scan_error(
|
||||||
message, "Scan request rejected");
|
message, "Scan request rejected");
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,9 @@
|
||||||
|
|
||||||
#ifndef CONFIG_NO_SCAN_PROCESSING
|
#ifndef CONFIG_NO_SCAN_PROCESSING
|
||||||
static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
|
static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
|
||||||
int new_scan, int own_request);
|
int new_scan, int own_request,
|
||||||
|
bool trigger_6ghz_scan,
|
||||||
|
union wpa_event_data *data);
|
||||||
#endif /* CONFIG_NO_SCAN_PROCESSING */
|
#endif /* CONFIG_NO_SCAN_PROCESSING */
|
||||||
#ifdef CONFIG_OWE
|
#ifdef CONFIG_OWE
|
||||||
static void owe_trans_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
static void owe_trans_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
||||||
|
@ -2310,6 +2312,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_scan_results *scan_res = NULL;
|
struct wpa_scan_results *scan_res = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int ap = 0;
|
int ap = 0;
|
||||||
|
bool trigger_6ghz_scan;
|
||||||
#ifndef CONFIG_NO_RANDOM_POOL
|
#ifndef CONFIG_NO_RANDOM_POOL
|
||||||
size_t i, num;
|
size_t i, num;
|
||||||
#endif /* CONFIG_NO_RANDOM_POOL */
|
#endif /* CONFIG_NO_RANDOM_POOL */
|
||||||
|
@ -2319,6 +2322,11 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
|
||||||
ap = 1;
|
ap = 1;
|
||||||
#endif /* CONFIG_AP */
|
#endif /* CONFIG_AP */
|
||||||
|
|
||||||
|
trigger_6ghz_scan = wpa_s->crossed_6ghz_dom &&
|
||||||
|
wpa_s->last_scan_all_chan;
|
||||||
|
wpa_s->crossed_6ghz_dom = false;
|
||||||
|
wpa_s->last_scan_all_chan = false;
|
||||||
|
|
||||||
wpa_supplicant_notify_scanning(wpa_s, 0);
|
wpa_supplicant_notify_scanning(wpa_s, 0);
|
||||||
|
|
||||||
scan_res = wpa_supplicant_get_scan_results(wpa_s,
|
scan_res = wpa_supplicant_get_scan_results(wpa_s,
|
||||||
|
@ -2472,7 +2480,8 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
|
||||||
if (wpa_s->supp_pbc_active && !wpas_wps_partner_link_scan_done(wpa_s))
|
if (wpa_s->supp_pbc_active && !wpas_wps_partner_link_scan_done(wpa_s))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return wpas_select_network_from_last_scan(wpa_s, 1, own_request);
|
return wpas_select_network_from_last_scan(wpa_s, 1, own_request,
|
||||||
|
trigger_6ghz_scan, data);
|
||||||
|
|
||||||
scan_work_done:
|
scan_work_done:
|
||||||
wpa_scan_results_free(scan_res);
|
wpa_scan_results_free(scan_res);
|
||||||
|
@ -2485,8 +2494,44 @@ scan_work_done:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpas_trigger_6ghz_scan(struct wpa_supplicant *wpa_s,
|
||||||
|
union wpa_event_data *data)
|
||||||
|
{
|
||||||
|
struct wpa_driver_scan_params params;
|
||||||
|
unsigned int j;
|
||||||
|
|
||||||
|
wpa_dbg(wpa_s, MSG_INFO, "Triggering 6GHz-only scan");
|
||||||
|
os_memset(¶ms, 0, sizeof(params));
|
||||||
|
params.non_coloc_6ghz = wpa_s->last_scan_non_coloc_6ghz;
|
||||||
|
for (j = 0; j < data->scan_info.num_ssids; j++)
|
||||||
|
params.ssids[j] = data->scan_info.ssids[j];
|
||||||
|
params.num_ssids = data->scan_info.num_ssids;
|
||||||
|
wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, ¶ms,
|
||||||
|
true, !wpa_s->last_scan_non_coloc_6ghz, false);
|
||||||
|
if (!wpa_supplicant_trigger_scan(wpa_s, ¶ms, true, true)) {
|
||||||
|
os_free(params.freqs);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
wpa_dbg(wpa_s, MSG_INFO, "Failed to trigger 6GHz-only scan");
|
||||||
|
os_free(params.freqs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select a network from the last scan
|
||||||
|
* @wpa_s: Pointer to wpa_supplicant data
|
||||||
|
* @new_scan: Whether this function was called right after a scan has finished
|
||||||
|
* @own_request: Whether the scan was requested by this interface
|
||||||
|
* @trigger_6ghz_scan: Whether to trigger a 6ghz-only scan when applicable
|
||||||
|
* @data: Scan data from scan that finished if applicable
|
||||||
|
*
|
||||||
|
* See _wpa_supplicant_event_scan_results() for return values.
|
||||||
|
*/
|
||||||
static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
|
static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
|
||||||
int new_scan, int own_request)
|
int new_scan, int own_request,
|
||||||
|
bool trigger_6ghz_scan,
|
||||||
|
union wpa_event_data *data)
|
||||||
{
|
{
|
||||||
struct wpa_bss *selected;
|
struct wpa_bss *selected;
|
||||||
struct wpa_ssid *ssid = NULL;
|
struct wpa_ssid *ssid = NULL;
|
||||||
|
@ -2558,6 +2603,10 @@ static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
|
||||||
if (new_scan)
|
if (new_scan)
|
||||||
wpa_supplicant_rsn_preauth_scan_results(wpa_s);
|
wpa_supplicant_rsn_preauth_scan_results(wpa_s);
|
||||||
} else if (own_request) {
|
} else if (own_request) {
|
||||||
|
if (wpa_s->support_6ghz && trigger_6ghz_scan && data &&
|
||||||
|
wpas_trigger_6ghz_scan(wpa_s, data) < 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No SSID found. If SCAN results are as a result of
|
* No SSID found. If SCAN results are as a result of
|
||||||
* own scan request and not due to a scan request on
|
* own scan request and not due to a scan request on
|
||||||
|
@ -2705,7 +2754,7 @@ int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wpas_select_network_from_last_scan(wpa_s, 0, 1);
|
return wpas_select_network_from_last_scan(wpa_s, 0, 1, false, NULL);
|
||||||
#endif /* CONFIG_NO_SCAN_PROCESSING */
|
#endif /* CONFIG_NO_SCAN_PROCESSING */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2715,7 +2764,7 @@ int wpa_wps_supplicant_fast_associate(struct wpa_supplicant *wpa_s)
|
||||||
#ifdef CONFIG_NO_SCAN_PROCESSING
|
#ifdef CONFIG_NO_SCAN_PROCESSING
|
||||||
return -1;
|
return -1;
|
||||||
#else /* CONFIG_NO_SCAN_PROCESSING */
|
#else /* CONFIG_NO_SCAN_PROCESSING */
|
||||||
return wpas_select_network_from_last_scan(wpa_s, 1, 1);
|
return wpas_select_network_from_last_scan(wpa_s, 1, 1, false, NULL);
|
||||||
#endif /* CONFIG_NO_SCAN_PROCESSING */
|
#endif /* CONFIG_NO_SCAN_PROCESSING */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4796,12 +4845,17 @@ void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
|
dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
|
||||||
radio_list) {
|
radio_list) {
|
||||||
|
bool was_6ghz_enabled;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "%s: Updating hw mode",
|
wpa_printf(MSG_DEBUG, "%s: Updating hw mode",
|
||||||
ifs->ifname);
|
ifs->ifname);
|
||||||
free_hw_features(ifs);
|
free_hw_features(ifs);
|
||||||
ifs->hw.modes = wpa_drv_get_hw_feature_data(
|
ifs->hw.modes = wpa_drv_get_hw_feature_data(
|
||||||
ifs, &ifs->hw.num_modes, &ifs->hw.flags, &dfs_domain);
|
ifs, &ifs->hw.num_modes, &ifs->hw.flags, &dfs_domain);
|
||||||
|
|
||||||
|
was_6ghz_enabled = ifs->is_6ghz_enabled;
|
||||||
|
ifs->is_6ghz_enabled = wpas_is_6ghz_supported(ifs, true);
|
||||||
|
|
||||||
/* Restart PNO/sched_scan with updated channel list */
|
/* Restart PNO/sched_scan with updated channel list */
|
||||||
if (ifs->pno) {
|
if (ifs->pno) {
|
||||||
wpas_stop_pno(ifs);
|
wpas_stop_pno(ifs);
|
||||||
|
@ -4810,6 +4864,12 @@ void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s,
|
||||||
wpa_dbg(ifs, MSG_DEBUG,
|
wpa_dbg(ifs, MSG_DEBUG,
|
||||||
"Channel list changed - restart sched_scan");
|
"Channel list changed - restart sched_scan");
|
||||||
wpas_scan_restart_sched_scan(ifs);
|
wpas_scan_restart_sched_scan(ifs);
|
||||||
|
} else if (ifs->scanning && !was_6ghz_enabled &&
|
||||||
|
ifs->is_6ghz_enabled) {
|
||||||
|
/* Look for APs in the 6 GHz band */
|
||||||
|
wpa_dbg(ifs, MSG_INFO,
|
||||||
|
"Channel list changed - trigger 6 GHz-only scan");
|
||||||
|
ifs->crossed_6ghz_dom = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1033,7 +1033,7 @@ static void wpas_rrm_scan_timeout(void *eloop_ctx, void *timeout_ctx)
|
||||||
}
|
}
|
||||||
os_get_reltime(&wpa_s->beacon_rep_scan);
|
os_get_reltime(&wpa_s->beacon_rep_scan);
|
||||||
if (wpa_s->scanning || wpas_p2p_in_progress(wpa_s) ||
|
if (wpa_s->scanning || wpas_p2p_in_progress(wpa_s) ||
|
||||||
wpa_supplicant_trigger_scan(wpa_s, params, true))
|
wpa_supplicant_trigger_scan(wpa_s, params, true, false))
|
||||||
wpas_rrm_refuse_request(wpa_s);
|
wpas_rrm_refuse_request(wpa_s);
|
||||||
params->duration = prev_duration;
|
params->duration = prev_duration;
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,11 +285,12 @@ static void wpas_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
|
||||||
* shouldn't be set if the IEs have already been set with
|
* shouldn't be set if the IEs have already been set with
|
||||||
* wpa_supplicant_extra_ies(). Otherwise, wpabuf_free() will lead to a
|
* wpa_supplicant_extra_ies(). Otherwise, wpabuf_free() will lead to a
|
||||||
* double-free.
|
* double-free.
|
||||||
|
* @next: Whether or not to perform this scan as the next radio work
|
||||||
* Returns: 0 on success, -1 on failure
|
* Returns: 0 on success, -1 on failure
|
||||||
*/
|
*/
|
||||||
int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
|
int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_driver_scan_params *params,
|
struct wpa_driver_scan_params *params,
|
||||||
bool default_ies)
|
bool default_ies, bool next)
|
||||||
{
|
{
|
||||||
struct wpa_driver_scan_params *ctx;
|
struct wpa_driver_scan_params *ctx;
|
||||||
struct wpabuf *ies = NULL;
|
struct wpabuf *ies = NULL;
|
||||||
|
@ -317,9 +318,11 @@ int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
|
||||||
params->extra_ies = NULL;
|
params->extra_ies = NULL;
|
||||||
params->extra_ies_len = 0;
|
params->extra_ies_len = 0;
|
||||||
}
|
}
|
||||||
|
wpa_s->last_scan_all_chan = !params->freqs;
|
||||||
|
wpa_s->last_scan_non_coloc_6ghz = params->non_coloc_6ghz;
|
||||||
if (!ctx ||
|
if (!ctx ||
|
||||||
radio_add_work(wpa_s, 0, "scan", 0, wpas_trigger_scan_cb, ctx) < 0)
|
radio_add_work(wpa_s, 0, "scan", next, wpas_trigger_scan_cb,
|
||||||
{
|
ctx) < 0) {
|
||||||
wpa_scan_free_params(ctx);
|
wpa_scan_free_params(ctx);
|
||||||
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_FAILED "ret=-1");
|
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_FAILED "ret=-1");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1537,7 +1540,7 @@ scan:
|
||||||
wpas_p2p_scan_freqs(wpa_s, ¶ms, true);
|
wpas_p2p_scan_freqs(wpa_s, ¶ms, true);
|
||||||
#endif /* CONFIG_P2P */
|
#endif /* CONFIG_P2P */
|
||||||
|
|
||||||
ret = wpa_supplicant_trigger_scan(wpa_s, scan_params, false);
|
ret = wpa_supplicant_trigger_scan(wpa_s, scan_params, false, false);
|
||||||
|
|
||||||
if (ret && wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs &&
|
if (ret && wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs &&
|
||||||
!wpa_s->manual_scan_freqs) {
|
!wpa_s->manual_scan_freqs) {
|
||||||
|
|
|
@ -46,7 +46,7 @@ void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_driver_scan_params;
|
struct wpa_driver_scan_params;
|
||||||
int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
|
int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_driver_scan_params *params,
|
struct wpa_driver_scan_params *params,
|
||||||
bool default_ies);
|
bool default_ies, bool next);
|
||||||
struct wpa_scan_results *
|
struct wpa_scan_results *
|
||||||
wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
|
wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
|
||||||
struct scan_info *info, int new_scan);
|
struct scan_info *info, int new_scan);
|
||||||
|
|
|
@ -3093,7 +3093,7 @@ static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx)
|
||||||
params.low_priority = 1;
|
params.low_priority = 1;
|
||||||
wpa_printf(MSG_DEBUG, "SME OBSS: Request an OBSS scan");
|
wpa_printf(MSG_DEBUG, "SME OBSS: Request an OBSS scan");
|
||||||
|
|
||||||
if (wpa_supplicant_trigger_scan(wpa_s, ¶ms, true))
|
if (wpa_supplicant_trigger_scan(wpa_s, ¶ms, true, false))
|
||||||
wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan");
|
wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan");
|
||||||
else
|
else
|
||||||
wpa_s->sme.sched_obss_scan = 1;
|
wpa_s->sme.sched_obss_scan = 1;
|
||||||
|
|
|
@ -1566,6 +1566,10 @@ struct wpa_supplicant {
|
||||||
unsigned int enable_dscp_policy_capa:1;
|
unsigned int enable_dscp_policy_capa:1;
|
||||||
unsigned int connection_dscp:1;
|
unsigned int connection_dscp:1;
|
||||||
unsigned int wait_for_dscp_req:1;
|
unsigned int wait_for_dscp_req:1;
|
||||||
|
bool is_6ghz_enabled;
|
||||||
|
bool crossed_6ghz_dom;
|
||||||
|
bool last_scan_all_chan;
|
||||||
|
bool last_scan_non_coloc_6ghz;
|
||||||
bool support_6ghz;
|
bool support_6ghz;
|
||||||
|
|
||||||
struct wpa_signal_info last_signal_info;
|
struct wpa_signal_info last_signal_info;
|
||||||
|
|
Loading…
Add table
Reference in a new issue