[PATCH v4] Add a workaround for Broadcom wl driver's first failing scan

Kalle Valo kalle.valo
Thu Mar 24 13:58:04 PDT 2011


With broadcom's "wl" driver the first scan after ifup always fails with
EINVAL. (Apparently it also doesn't send scan results ready signals, but
let's forget it for now.) With connman's five minute scan interval it
meant that it would take five minutes from boot until a wireless connection
was established.

Add a workaround to wext driver which will rerun the scan if first scan
fails EINVAL. But not without problems. First of all, scan parameters are
lost when the workaround is enabled. So in some cases the first scan is
not what was requested. Secondly, with this method the first scan results
are returned during 'inactive' state. I didn't notice anything broken
because of this but nevertheless it's wrong.
---
 src/drivers/driver_wext.c |   13 +++++++++++++
 src/drivers/driver_wext.h |    1 +
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c
index e731101..3cb007c 100644
--- a/src/drivers/driver_wext.c
+++ b/src/drivers/driver_wext.c
@@ -647,6 +647,7 @@ static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi,
 	if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
 		wpa_printf(MSG_DEBUG, "WEXT: Interface up");
 		drv->if_disabled = 0;
+		drv->scans = 0;
 		wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
 	}
 
@@ -1005,6 +1006,8 @@ int wpa_driver_wext_scan(void *priv, struct wpa_driver_scan_params *params)
 		ret = -1;
 	}
 
+	drv->scans++;
+
 	/* Not all drivers generate "scan completed" wireless event, so try to
 	 * read results after a timeout. */
 	timeout = 5;
@@ -1029,6 +1032,7 @@ int wpa_driver_wext_scan(void *priv, struct wpa_driver_scan_params *params)
 static u8 * wpa_driver_wext_giwscan(struct wpa_driver_wext_data *drv,
 				    size_t *len)
 {
+	struct wpa_driver_scan_params params;
 	struct iwreq iwr;
 	u8 *res_buf;
 	size_t res_buf_len;
@@ -1055,6 +1059,15 @@ static u8 * wpa_driver_wext_giwscan(struct wpa_driver_wext_data *drv,
 			wpa_printf(MSG_DEBUG, "Scan results did not fit - "
 				   "trying larger buffer (%lu bytes)",
 				   (unsigned long) res_buf_len);
+		} if (errno == EINVAL && drv->scans == 1) {
+			/*
+			 * Broadcom's wl driver is buggy and the first scan
+			 * after ifup always fail with EINVAL. Rerun the
+			 * scan to get scan results.
+			 */
+			os_memset(&params, 0, sizeof(params));
+			wpa_driver_wext_scan(drv, &params);
+			return NULL;
 		} else {
 			perror("ioctl[SIOCGIWSCAN]");
 			os_free(res_buf);
diff --git a/src/drivers/driver_wext.h b/src/drivers/driver_wext.h
index 89c13eb..6c25f86 100644
--- a/src/drivers/driver_wext.h
+++ b/src/drivers/driver_wext.h
@@ -45,6 +45,7 @@ struct wpa_driver_wext_data {
 
 	char mlmedev[IFNAMSIZ + 1];
 
+	int scans;
 	int scan_complete_events;
 
 	int cfg80211; /* whether driver is using cfg80211 */




More information about the Hostap mailing list