Files
openwrt_deco_e4r/package/hostapd/patches/641-retry-20-40-MHz-co-ex-scan.patch

140 lines
4.3 KiB
Diff

diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index cc310e0..e182517 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -1120,6 +1120,7 @@ void hostapd_interface_deinit(struct hostapd_iface *iface)
#ifdef CONFIG_IEEE80211N
#ifdef NEED_AP_MLME
+ hostapd_stop_setup_timers(iface);
eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL);
#endif /* NEED_AP_MLME */
#endif /* CONFIG_IEEE80211N */
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index d9ab505..7f50c5e 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -286,6 +286,7 @@ struct hostapd_iface {
/* Latched with the actual secondary channel information and will be
* used while juggling between HT20 and HT40 modes. */
int secondary_ch;
+ int num_ht40_scan_tries;
};
/**
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index 30ba0f1..0cc0a73 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -563,9 +563,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(&params, 0, sizeof(params));
+ if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
+ ieee80211n_scan_channels_2g4(iface, &params);
+ else
+ ieee80211n_scan_channels_5g(iface, &params);
+
+ ret = hostapd_driver_scan(iface->bss[0], &params);
+ 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 || iface->conf->noscan)
return 0; /* HT40 not used */
@@ -577,13 +623,26 @@ static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
ieee80211n_scan_channels_2g4(iface, &params);
else
ieee80211n_scan_channels_5g(iface, &params);
- if (hostapd_driver_scan(iface->bss[0], &params) < 0) {
- wpa_printf(MSG_ERROR, "Failed to request a scan of "
- "neighboring BSSes");
- os_free(params.freqs);
+
+ ret = hostapd_driver_scan(iface->bss[0], &params);
+ 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;
diff --git a/src/ap/hw_features.h b/src/ap/hw_features.h
index abadcd1..cd1a55d 100644
--- a/src/ap/hw_features.h
+++ b/src/ap/hw_features.h
@@ -28,6 +28,7 @@ int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq);
int hostapd_check_ht_capab(struct hostapd_iface *iface);
int hostapd_prepare_rates(struct hostapd_iface *iface,
struct hostapd_hw_modes *mode);
+void hostapd_stop_setup_timers(struct hostapd_iface *iface);
#else /* NEED_AP_MLME */
static inline void
hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
@@ -66,6 +67,10 @@ static inline int hostapd_prepare_rates(struct hostapd_iface *iface,
return 0;
}
+static inline void hostapd_stop_setup_timers(struct hostapd_iface *iface)
+{
+}
+
#endif /* NEED_AP_MLME */
#endif /* HW_FEATURES_H */