wifi: work around some scan failures at startup
authorDan Williams <dcbw@redhat.com>
Wed, 2 May 2012 22:16:35 +0000 (17:16 -0500)
committerDan Williams <dcbw@redhat.com>
Fri, 4 May 2012 18:48:54 +0000 (13:48 -0500)
mac80211 drivers don't like being asked to scan when they are already
scanning, and it's pretty impossible to not race with internal
supplicant scanning.  NM requests a scan immediately after the
supplicant interface gets created, and that scan request usually
succeeds.  But since the supplicant's scan request method returns
when the kernel *starts* the scan, not when the scan is finished,
a second scan that NM would immediately request in
request_wireless_scan() would often fail as the card was already
scanning.

The second scan was requested immediately becuase the SCAN_INTERVAL_MIN
was zero, which was set to zero to intentionally request two scans
to work around drivers that would fail the first scan because they
are stupid.

Well, let's just penalize stupid drivers by *possibly* making the
initial connection take a few more seconds due to the change of
SCAN_INTERVAL_MIN.  But what we're really doing here is not asking
for the second scan right after the first one is requested, since
that will almost always fail for most drivers, but request the
second one after the supplicant says the scan is done.

Second, if for some reason the supplicant reports that the scan failed,
don't make the next scan take longer; just queue it up without backing
off so we can retry the scan sooner.

src/nm-device-wifi.c

index f44eb3b..ad1cfe3 100644 (file)
@@ -68,7 +68,7 @@ static gboolean impl_device_get_access_points (NMDeviceWifi *device,
 
 
 /* All of these are in seconds */
-#define SCAN_INTERVAL_MIN 0
+#define SCAN_INTERVAL_MIN 3
 #define SCAN_INTERVAL_STEP 20
 #define SCAN_INTERVAL_MAX 120
 
@@ -1724,8 +1724,7 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface,
                    nm_device_get_iface (NM_DEVICE (self)),
                    success ? "successful" : "failed");
 
-       if (check_scanning_allowed (self))
-               schedule_scan (self, TRUE);
+       schedule_scan (self, success);
 
        /* Ensure that old APs get removed, which otherwise only
         * happens when there are new BSSes.