|
@@ -602,9 +602,55 @@ static void ieee80211n_scan_channels_5g(struct hostapd_iface *iface,
|
|
|
}
|
|
|
|
|
|
|
|
|
+static void ap_ht40_scan_retry(void *eloop_data, void *user_data)
|
|
|
+{
|
|
|
+#define HT2040_COEX_SCAN_RETRY 15
|
|
|
+ struct hostapd_iface *iface = eloop_data;
|
|
|
+ struct wpa_driver_scan_params params;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ os_memset(¶ms, 0, sizeof(params));
|
|
|
+ if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
|
|
|
+ ieee80211n_scan_channels_2g4(iface, ¶ms);
|
|
|
+ else
|
|
|
+ ieee80211n_scan_channels_5g(iface, ¶ms);
|
|
|
+
|
|
|
+ ret = hostapd_driver_scan(iface->bss[0], ¶ms);
|
|
|
+ iface->num_ht40_scan_tries++;
|
|
|
+ os_free(params.freqs);
|
|
|
+
|
|
|
+ if (ret == -EBUSY &&
|
|
|
+ iface->num_ht40_scan_tries < HT2040_COEX_SCAN_RETRY) {
|
|
|
+ wpa_printf(MSG_ERROR,
|
|
|
+ "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again (attempt %d)",
|
|
|
+ ret, strerror(-ret), iface->num_ht40_scan_tries);
|
|
|
+ eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ret == 0) {
|
|
|
+ iface->scan_cb = ieee80211n_check_scan;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ wpa_printf(MSG_DEBUG,
|
|
|
+ "Failed to request a scan in device, bringing up in HT20 mode");
|
|
|
+ iface->conf->secondary_channel = 0;
|
|
|
+ iface->conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
|
|
|
+ hostapd_setup_interface_complete(iface, 0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void hostapd_stop_setup_timers(struct hostapd_iface *iface)
|
|
|
+{
|
|
|
+ eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
|
|
|
{
|
|
|
struct wpa_driver_scan_params params;
|
|
|
+ int ret;
|
|
|
|
|
|
if (!iface->conf->secondary_channel)
|
|
|
return 0; /* HT40 not used */
|
|
@@ -617,13 +663,26 @@ static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
|
|
|
ieee80211n_scan_channels_2g4(iface, ¶ms);
|
|
|
else
|
|
|
ieee80211n_scan_channels_5g(iface, ¶ms);
|
|
|
- if (hostapd_driver_scan(iface->bss[0], ¶ms) < 0) {
|
|
|
- wpa_printf(MSG_ERROR, "Failed to request a scan of "
|
|
|
- "neighboring BSSes");
|
|
|
- os_free(params.freqs);
|
|
|
+
|
|
|
+ ret = hostapd_driver_scan(iface->bss[0], ¶ms);
|
|
|
+ os_free(params.freqs);
|
|
|
+
|
|
|
+ if (ret == -EBUSY) {
|
|
|
+ wpa_printf(MSG_ERROR,
|
|
|
+ "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again",
|
|
|
+ ret, strerror(-ret));
|
|
|
+ iface->num_ht40_scan_tries = 1;
|
|
|
+ eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL);
|
|
|
+ eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ret < 0) {
|
|
|
+ wpa_printf(MSG_ERROR,
|
|
|
+ "Failed to request a scan of neighboring BSSes ret=%d (%s)",
|
|
|
+ ret, strerror(-ret));
|
|
|
return -1;
|
|
|
}
|
|
|
- os_free(params.freqs);
|
|
|
|
|
|
iface->scan_cb = ieee80211n_check_scan;
|
|
|
return 1;
|