On Fri, May 20, 2016 at 12:08:19PM +0200, Mark Kettenis wrote:
> > Date: Fri, 20 May 2016 11:19:26 +0200
> > From: Stefan Sperling <s...@stsp.name>
> > 
> > The new iwm(4) firmware (see [1]) scans 2GHz and 5 GHz bands in one go.
> > [1] http://marc.info/?l=openbsd-tech&m=146356530605833&w=2
> > 
> > Our net80211 stack isn't set up to handle this correctly.
> > With the new firmware (and diff from [1]), you'll see no scan results
> > at all if you run:
> > 
> >   ifconfig iwm0 nwid some-nwid-that-doesnt-exist-on-2ghz
> >   ifconfig iwm0 scan
> > 
> > This happens because the net80211 stack clears scan results from memory
> > before results are returned to ifconfig, and retries on a different band.
> > The driver however insists that it is already done scanning everything,
> > and does nothing (a SCAN->SCAN transition is a no-op in the driver).
> > So the second scan attempt times out, and ifconfig gets no results.
> > 
> > This diff adds a 'scan all bands' capability which the driver can advertise
> > to tell the net80211 layer that it should not retry the scan on a different
> > band. Setting this flag in the iwm(4) driver then fixes the issue.
> > 
> > (Note that the comment immediately below refers to a 'next mode' instead of
> > 'next band' because it dates from a time when a mode implied a band, as in
> > 11b -> 2GHz and 11a -> 5 GHz. Nowadays, we have 11n mode uses both bands.)
> > 
> > ok?
> 
> The name feels a bit wrong.  Perhaps IEEE80211_C_SINGLESCAN?  Anyway,
> doesn't really matter.

Let's bikeshed the flag name later. We can always change it.

There is a more serious problem with my previous diff. It breaks the
background scanning loop which is supposed to run forever if our
desired essid can't be found.

I'm getting better results with the diff below. ifconfig scan works, and
so does the scanning loop because we keep calling ieee80211_next_mode()
and ieee80211_next_scan() to keep the loop running.

It seems my initial impression that ieee80211_next_mode() clears state
which ifconfig reads was wrong.

Index: ieee80211_node.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.c,v
retrieving revision 1.102
diff -u -p -r1.102 ieee80211_node.c
--- ieee80211_node.c    18 May 2016 08:15:28 -0000      1.102
+++ ieee80211_node.c    20 May 2016 11:32:08 -0000
@@ -585,14 +585,17 @@ ieee80211_end_scan(struct ifnet *ifp)
                 * Scan the next mode if nothing has been found. This
                 * is necessary if the device supports different
                 * incompatible modes in the same channel range, like
-                * like 11b and "pure" 11G mode. This will loop
-                * forever except for user-initiated scans.
+                * like 11b and "pure" 11G mode.
+                * If the device scans all bands in one fell swoop, return
+                * current scan results to userspace regardless of mode.
+                * This will loop forever except for user-initiated scans.
                 */
-               if (ieee80211_next_mode(ifp) == IEEE80211_MODE_AUTO) {
+               if (ieee80211_next_mode(ifp) == IEEE80211_MODE_AUTO ||
+                   (ic->ic_caps & IEEE80211_C_SCANALLBAND)) {
                        if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST &&
                            ic->ic_scan_lock & IEEE80211_SCAN_RESUME) {
                                ic->ic_scan_lock = IEEE80211_SCAN_LOCKED;
-                               /* Return from an user-initiated scan */
+                               /* Return from a user-initiated scan. */
                                wakeup(&ic->ic_scan_lock);
                        } else if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST)
                                goto wakeup;
@@ -652,7 +655,7 @@ ieee80211_end_scan(struct ifnet *ifp)
 
  wakeup:
        if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST) {
-               /* Return from an user-initiated scan */
+               /* Return from a user-initiated scan. */
                wakeup(&ic->ic_scan_lock);
        }
 
Index: ieee80211_var.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_var.h,v
retrieving revision 1.71
diff -u -p -r1.71 ieee80211_var.h
--- ieee80211_var.h     25 Jan 2016 11:27:11 -0000      1.71
+++ ieee80211_var.h     20 May 2016 08:56:14 -0000
@@ -369,6 +369,7 @@ extern struct ieee80211com_head ieee8021
 #define IEEE80211_C_RSN                0x00001000      /* CAPABILITY: RSN 
avail */
 #define IEEE80211_C_MFP                0x00002000      /* CAPABILITY: MFP 
avail */
 #define IEEE80211_C_RAWCTL     0x00004000      /* CAPABILITY: raw ctl */
+#define IEEE80211_C_SCANALLBAND        0x00008000      /* CAPABILITY: scan all 
bands */
 
 /* flags for ieee80211_fix_rate() */
 #define        IEEE80211_F_DOSORT      0x00000001      /* sort rate list */

Reply via email to