]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net80211/ieee80211_scan_sw.c
net80211: split scan_task() (#3) (into scan_start() and
[FreeBSD/FreeBSD.git] / sys / net80211 / ieee80211_scan_sw.c
1 /*-
2  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28
29 /*
30  * IEEE 802.11 scanning support.
31  */
32 #include "opt_wlan.h"
33
34 #include <sys/param.h>
35 #include <sys/systm.h> 
36 #include <sys/proc.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/condvar.h>
40  
41 #include <sys/socket.h>
42
43 #include <net/if.h>
44 #include <net/if_var.h>
45 #include <net/if_media.h>
46 #include <net/ethernet.h>
47
48 #include <net80211/ieee80211_var.h>
49
50 #include <net80211/ieee80211_scan_sw.h>
51
52 #include <net/bpf.h>
53
54 struct scan_state {
55         struct ieee80211_scan_state base;       /* public state */
56
57         u_int           ss_iflags;              /* flags used internally */
58 #define ISCAN_MINDWELL  0x0001          /* min dwell time reached */
59 #define ISCAN_DISCARD   0x0002          /* discard rx'd frames */
60 #define ISCAN_CANCEL    0x0004          /* cancel current scan */
61 #define ISCAN_ABORT     0x0008          /* end the scan immediately */
62 #define ISCAN_RUNNING   0x0010          /* scan was started */
63         unsigned long   ss_chanmindwell;        /* min dwell on curchan */
64         unsigned long   ss_scanend;             /* time scan must stop */
65         u_int           ss_duration;            /* duration for next scan */
66         struct task     ss_scan_start;          /* scan start */
67         struct timeout_task ss_scan_curchan;    /* scan execution */
68 };
69 #define SCAN_PRIVATE(ss)        ((struct scan_state *) ss)
70
71 /*
72  * Amount of time to go off-channel during a background
73  * scan.  This value should be large enough to catch most
74  * ap's but short enough that we can return on-channel
75  * before our listen interval expires.
76  *
77  * XXX tunable
78  * XXX check against configured listen interval
79  */
80 #define IEEE80211_SCAN_OFFCHANNEL       msecs_to_ticks(150)
81
82 /*
83  * Roaming-related defaults.  RSSI thresholds are as returned by the
84  * driver (.5dBm).  Transmit rate thresholds are IEEE rate codes (i.e
85  * .5M units) or MCS.
86  */
87 /* rssi thresholds */
88 #define ROAM_RSSI_11A_DEFAULT           14      /* 11a bss */
89 #define ROAM_RSSI_11B_DEFAULT           14      /* 11b bss */
90 #define ROAM_RSSI_11BONLY_DEFAULT       14      /* 11b-only bss */
91 /* transmit rate thresholds */
92 #define ROAM_RATE_11A_DEFAULT           2*12    /* 11a bss */
93 #define ROAM_RATE_11B_DEFAULT           2*5     /* 11b bss */
94 #define ROAM_RATE_11BONLY_DEFAULT       2*1     /* 11b-only bss */
95 #define ROAM_RATE_HALF_DEFAULT          2*6     /* half-width 11a/g bss */
96 #define ROAM_RATE_QUARTER_DEFAULT       2*3     /* quarter-width 11a/g bss */
97 #define ROAM_MCS_11N_DEFAULT            (1 | IEEE80211_RATE_MCS) /* 11n bss */
98
99 static  void scan_curchan(struct ieee80211_scan_state *, unsigned long);
100 static  void scan_mindwell(struct ieee80211_scan_state *);
101 static  void scan_signal(void *);
102 static  void scan_start(void *, int);
103 static  void scan_curchan_task(void *, int);
104 static  void scan_end(struct ieee80211_scan_state *, int);
105 static  void scan_done(struct ieee80211_scan_state *, int);
106
107 MALLOC_DEFINE(M_80211_SCAN, "80211scan", "802.11 scan state");
108
109 static void
110 ieee80211_swscan_detach(struct ieee80211com *ic)
111 {
112         struct ieee80211_scan_state *ss = ic->ic_scan;
113
114         if (ss != NULL) {
115                 IEEE80211_LOCK(ic);
116                 SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_ABORT;
117                 scan_signal(ss);
118                 IEEE80211_UNLOCK(ic);
119                 ieee80211_draintask(ic, &SCAN_PRIVATE(ss)->ss_scan_start);
120                 taskqueue_drain_timeout(ic->ic_tq,
121                     &SCAN_PRIVATE(ss)->ss_scan_curchan);
122                 KASSERT((ic->ic_flags & IEEE80211_F_SCAN) == 0,
123                     ("scan still running"));
124
125                 /*
126                  * For now, do the ss_ops detach here rather
127                  * than ieee80211_scan_detach().
128                  *
129                  * I'll figure out how to cleanly split things up
130                  * at a later date.
131                  */
132                 if (ss->ss_ops != NULL) {
133                         ss->ss_ops->scan_detach(ss);
134                         ss->ss_ops = NULL;
135                 }
136                 ic->ic_scan = NULL;
137                 IEEE80211_FREE(SCAN_PRIVATE(ss), M_80211_SCAN);
138         }
139 }
140
141 static void
142 ieee80211_swscan_vattach(struct ieee80211vap *vap)
143 {
144         /* nothing to do for now */
145         /*
146          * TODO: all of the vap scan calls should be methods!
147          */
148
149 }
150
151 static void
152 ieee80211_swscan_vdetach(struct ieee80211vap *vap)
153 {
154         struct ieee80211com *ic = vap->iv_ic;
155         struct ieee80211_scan_state *ss;
156
157         IEEE80211_LOCK_ASSERT(ic);
158         ss = ic->ic_scan;
159         if (ss != NULL && ss->ss_vap == vap) {
160                 if (ic->ic_flags & IEEE80211_F_SCAN) {
161                         SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_ABORT;
162                         scan_signal(ss);
163                 }
164         }
165 }
166
167 static void
168 ieee80211_swscan_set_scan_duration(struct ieee80211vap *vap, u_int duration)
169 {
170         struct ieee80211com *ic = vap->iv_ic;
171         struct ieee80211_scan_state *ss = ic->ic_scan;
172
173         IEEE80211_LOCK_ASSERT(ic);
174
175         /* NB: flush frames rx'd before 1st channel change */
176         SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_DISCARD;
177         SCAN_PRIVATE(ss)->ss_duration = duration;
178 }
179
180 /*
181  * Start a scan unless one is already going.
182  */
183 static int
184 ieee80211_swscan_start_scan_locked(const struct ieee80211_scanner *scan,
185         struct ieee80211vap *vap, int flags, u_int duration,
186         u_int mindwell, u_int maxdwell,
187         u_int nssid, const struct ieee80211_scan_ssid ssids[])
188 {
189         struct ieee80211com *ic = vap->iv_ic;
190         struct ieee80211_scan_state *ss = ic->ic_scan;
191
192         IEEE80211_LOCK_ASSERT(ic);
193
194         if (ic->ic_flags & IEEE80211_F_CSAPENDING) {
195                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
196                     "%s: scan inhibited by pending channel change\n", __func__);
197         } else if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
198                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
199                     "%s: %s scan, duration %u mindwell %u maxdwell %u, desired mode %s, %s%s%s%s%s%s\n"
200                     , __func__
201                     , flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive"
202                     , duration, mindwell, maxdwell
203                     , ieee80211_phymode_name[vap->iv_des_mode]
204                     , flags & IEEE80211_SCAN_FLUSH ? "flush" : "append"
205                     , flags & IEEE80211_SCAN_NOPICK ? ", nopick" : ""
206                     , flags & IEEE80211_SCAN_NOJOIN ? ", nojoin" : ""
207                     , flags & IEEE80211_SCAN_NOBCAST ? ", nobcast" : ""
208                     , flags & IEEE80211_SCAN_PICK1ST ? ", pick1st" : ""
209                     , flags & IEEE80211_SCAN_ONCE ? ", once" : ""
210                 );
211
212                 ieee80211_scan_update_locked(vap, scan);
213                 if (ss->ss_ops != NULL) {
214                         if ((flags & IEEE80211_SCAN_NOSSID) == 0)
215                                 ieee80211_scan_copy_ssid(vap, ss, nssid, ssids);
216
217                         /* NB: top 4 bits for internal use */
218                         ss->ss_flags = flags & 0xfff;
219                         if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
220                                 vap->iv_stats.is_scan_active++;
221                         else
222                                 vap->iv_stats.is_scan_passive++;
223                         if (flags & IEEE80211_SCAN_FLUSH)
224                                 ss->ss_ops->scan_flush(ss);
225                         if (flags & IEEE80211_SCAN_BGSCAN)
226                                 ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN;
227
228                         /* Set duration for this particular scan */
229                         ieee80211_swscan_set_scan_duration(vap, duration);
230
231                         ss->ss_next = 0;
232                         ss->ss_mindwell = mindwell;
233                         ss->ss_maxdwell = maxdwell;
234                         /* NB: scan_start must be before the scan runtask */
235                         ss->ss_ops->scan_start(ss, vap);
236 #ifdef IEEE80211_DEBUG
237                         if (ieee80211_msg_scan(vap))
238                                 ieee80211_scan_dump(ss);
239 #endif /* IEEE80211_DEBUG */
240                         ic->ic_flags |= IEEE80211_F_SCAN;
241
242                         /* Start scan task */
243                         ieee80211_runtask(ic, &SCAN_PRIVATE(ss)->ss_scan_start);
244                 }
245                 return 1;
246         } else {
247                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
248                     "%s: %s scan already in progress\n", __func__,
249                     ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive");
250         }
251         return 0;
252 }
253
254
255 /*
256  * Start a scan unless one is already going.
257  *
258  * Called without the comlock held; grab the comlock as appropriate.
259  */
260 static int
261 ieee80211_swscan_start_scan(const struct ieee80211_scanner *scan,
262     struct ieee80211vap *vap, int flags,
263     u_int duration, u_int mindwell, u_int maxdwell,
264     u_int nssid, const struct ieee80211_scan_ssid ssids[])
265 {
266         struct ieee80211com *ic = vap->iv_ic;
267         int result;
268
269         IEEE80211_UNLOCK_ASSERT(ic);
270
271         IEEE80211_LOCK(ic);
272         result = ieee80211_swscan_start_scan_locked(scan, vap, flags, duration,
273             mindwell, maxdwell, nssid, ssids);
274         IEEE80211_UNLOCK(ic);
275
276         return result;
277 }
278
279 /*
280  * Check the scan cache for an ap/channel to use; if that
281  * fails then kick off a new scan.
282  *
283  * Called with the comlock held.
284  *
285  * XXX TODO: split out!
286  */
287 static int
288 ieee80211_swscan_check_scan(const struct ieee80211_scanner *scan,
289     struct ieee80211vap *vap, int flags,
290     u_int duration, u_int mindwell, u_int maxdwell,
291     u_int nssid, const struct ieee80211_scan_ssid ssids[])
292 {
293         struct ieee80211com *ic = vap->iv_ic;
294         struct ieee80211_scan_state *ss = ic->ic_scan;
295         int result;
296
297         IEEE80211_LOCK_ASSERT(ic);
298
299         if (ss->ss_ops != NULL) {
300                 /* XXX verify ss_ops matches vap->iv_opmode */
301                 if ((flags & IEEE80211_SCAN_NOSSID) == 0) {
302                         /*
303                          * Update the ssid list and mark flags so if
304                          * we call start_scan it doesn't duplicate work.
305                          */
306                         ieee80211_scan_copy_ssid(vap, ss, nssid, ssids);
307                         flags |= IEEE80211_SCAN_NOSSID;
308                 }
309                 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0 &&
310                     (flags & IEEE80211_SCAN_FLUSH) == 0 &&
311                     time_before(ticks, ic->ic_lastscan + vap->iv_scanvalid)) {
312                         /*
313                          * We're not currently scanning and the cache is
314                          * deemed hot enough to consult.  Lock out others
315                          * by marking IEEE80211_F_SCAN while we decide if
316                          * something is already in the scan cache we can
317                          * use.  Also discard any frames that might come
318                          * in while temporarily marked as scanning.
319                          */
320                         SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_DISCARD;
321                         ic->ic_flags |= IEEE80211_F_SCAN;
322
323                         /* NB: need to use supplied flags in check */
324                         ss->ss_flags = flags & 0xff;
325                         result = ss->ss_ops->scan_end(ss, vap);
326
327                         ic->ic_flags &= ~IEEE80211_F_SCAN;
328                         SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_DISCARD;
329                         if (result) {
330                                 ieee80211_notify_scan_done(vap);
331                                 return 1;
332                         }
333                 }
334         }
335         result = ieee80211_swscan_start_scan_locked(scan, vap, flags, duration,
336             mindwell, maxdwell, nssid, ssids);
337
338         return result;
339 }
340
341 /*
342  * Restart a previous scan.  If the previous scan completed
343  * then we start again using the existing channel list.
344  */
345 static int
346 ieee80211_swscan_bg_scan(const struct ieee80211_scanner *scan,
347     struct ieee80211vap *vap, int flags)
348 {
349         struct ieee80211com *ic = vap->iv_ic;
350         struct ieee80211_scan_state *ss = ic->ic_scan;
351
352         /* XXX assert unlocked? */
353         // IEEE80211_UNLOCK_ASSERT(ic);
354
355         IEEE80211_LOCK(ic);
356         if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
357                 u_int duration;
358                 /*
359                  * Go off-channel for a fixed interval that is large
360                  * enough to catch most ap's but short enough that
361                  * we can return on-channel before our listen interval
362                  * expires.
363                  */
364                 duration = IEEE80211_SCAN_OFFCHANNEL;
365
366                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
367                     "%s: %s scan, ticks %u duration %u\n", __func__,
368                     ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive",
369                     ticks, duration);
370
371                 ieee80211_scan_update_locked(vap, scan);
372                 if (ss->ss_ops != NULL) {
373                         ss->ss_vap = vap;
374                         /*
375                          * A background scan does not select a new sta; it
376                          * just refreshes the scan cache.  Also, indicate
377                          * the scan logic should follow the beacon schedule:
378                          * we go off-channel and scan for a while, then
379                          * return to the bss channel to receive a beacon,
380                          * then go off-channel again.  All during this time
381                          * we notify the ap we're in power save mode.  When
382                          * the scan is complete we leave power save mode.
383                          * If any beacon indicates there are frames pending
384                          * for us then we drop out of power save mode
385                          * (and background scan) automatically by way of the
386                          * usual sta power save logic.
387                          */
388                         ss->ss_flags |= IEEE80211_SCAN_NOPICK
389                                      |  IEEE80211_SCAN_BGSCAN
390                                      |  flags
391                                      ;
392                         /* if previous scan completed, restart */
393                         if (ss->ss_next >= ss->ss_last) {
394                                 if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
395                                         vap->iv_stats.is_scan_active++;
396                                 else
397                                         vap->iv_stats.is_scan_passive++;
398                                 /*
399                                  * NB: beware of the scan cache being flushed;
400                                  *     if the channel list is empty use the
401                                  *     scan_start method to populate it.
402                                  */
403                                 ss->ss_next = 0;
404                                 if (ss->ss_last != 0)
405                                         ss->ss_ops->scan_restart(ss, vap);
406                                 else {
407                                         ss->ss_ops->scan_start(ss, vap);
408 #ifdef IEEE80211_DEBUG
409                                         if (ieee80211_msg_scan(vap))
410                                                 ieee80211_scan_dump(ss);
411 #endif /* IEEE80211_DEBUG */
412                                 }
413                         }
414                         ieee80211_swscan_set_scan_duration(vap, duration);
415                         ss->ss_maxdwell = duration;
416                         ic->ic_flags |= IEEE80211_F_SCAN;
417                         ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN;
418                         ieee80211_runtask(ic,
419                             &SCAN_PRIVATE(ss)->ss_scan_start);
420                 } else {
421                         /* XXX msg+stat */
422                 }
423         } else {
424                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
425                     "%s: %s scan already in progress\n", __func__,
426                     ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive");
427         }
428         IEEE80211_UNLOCK(ic);
429
430         /* NB: racey, does it matter? */
431         return (ic->ic_flags & IEEE80211_F_SCAN);
432 }
433
434 static void
435 cancel_scan(struct ieee80211vap *vap, int any, const char *func)
436 {
437         struct ieee80211com *ic = vap->iv_ic;
438         struct ieee80211_scan_state *ss = ic->ic_scan;
439
440         IEEE80211_LOCK(ic);
441         if ((ic->ic_flags & IEEE80211_F_SCAN) &&
442             (any || ss->ss_vap == vap) &&
443             (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) == 0) {
444                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
445                     "%s: cancel %s scan\n", func,
446                     ss->ss_flags & IEEE80211_SCAN_ACTIVE ?
447                         "active" : "passive");
448
449                 /* clear bg scan NOPICK and mark cancel request */
450                 ss->ss_flags &= ~IEEE80211_SCAN_NOPICK;
451                 SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL;
452                 /* wake up the scan task */
453                 scan_signal(ss);
454         } else {
455                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
456                     "%s: called; F_SCAN=%d, vap=%s, CANCEL=%d\n",
457                         func,
458                         !! (ic->ic_flags & IEEE80211_F_SCAN),
459                         (ss->ss_vap == vap ? "match" : "nomatch"),
460                         !! (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL));
461         }
462         IEEE80211_UNLOCK(ic);
463 }
464
465 /*
466  * Cancel any scan currently going on for the specified vap.
467  */
468 static void
469 ieee80211_swscan_cancel_scan(struct ieee80211vap *vap)
470 {
471         cancel_scan(vap, 0, __func__);
472 }
473
474 /*
475  * Cancel any scan currently going on.
476  */
477 static void
478 ieee80211_swscan_cancel_anyscan(struct ieee80211vap *vap)
479 {
480         cancel_scan(vap, 1, __func__);
481 }
482
483 /*
484  * Public access to scan_next for drivers that manage
485  * scanning themselves (e.g. for firmware-based devices).
486  */
487 static void
488 ieee80211_swscan_scan_next(struct ieee80211vap *vap)
489 {
490         struct ieee80211com *ic = vap->iv_ic;
491         struct ieee80211_scan_state *ss = ic->ic_scan;
492
493         IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__);
494
495         /* wake up the scan task */
496         IEEE80211_LOCK(ic);
497         scan_signal(ss);
498         IEEE80211_UNLOCK(ic);
499 }
500
501 /*
502  * Public access to scan_next for drivers that are not able to scan single
503  * channels (e.g. for firmware-based devices).
504  */
505 static void
506 ieee80211_swscan_scan_done(struct ieee80211vap *vap)
507 {
508         struct ieee80211com *ic = vap->iv_ic;
509         struct ieee80211_scan_state *ss;
510
511         IEEE80211_LOCK_ASSERT(ic);
512
513         ss = ic->ic_scan;
514         scan_signal(ss);
515 }
516
517 /*
518  * Probe the curent channel, if allowed, while scanning.
519  * If the channel is not marked passive-only then send
520  * a probe request immediately.  Otherwise mark state and
521  * listen for beacons on the channel; if we receive something
522  * then we'll transmit a probe request.
523  */
524 static void
525 ieee80211_swscan_probe_curchan(struct ieee80211vap *vap, int force)
526 {
527         struct ieee80211com *ic = vap->iv_ic;
528         struct ieee80211_scan_state *ss = ic->ic_scan;
529         struct ifnet *ifp = vap->iv_ifp;
530         int i;
531
532         /*
533          * Send directed probe requests followed by any
534          * broadcast probe request.
535          * XXX remove dependence on ic/vap->iv_bss
536          */
537         for (i = 0; i < ss->ss_nssid; i++)
538                 ieee80211_send_probereq(vap->iv_bss,
539                         vap->iv_myaddr, ifp->if_broadcastaddr,
540                         ifp->if_broadcastaddr,
541                         ss->ss_ssid[i].ssid, ss->ss_ssid[i].len);
542         if ((ss->ss_flags & IEEE80211_SCAN_NOBCAST) == 0)
543                 ieee80211_send_probereq(vap->iv_bss,
544                         vap->iv_myaddr, ifp->if_broadcastaddr,
545                         ifp->if_broadcastaddr,
546                         "", 0);
547 }
548
549 /*
550  * Scan curchan.  If this is an active scan and the channel
551  * is not marked passive then send probe request frame(s).
552  * Arrange for the channel change after maxdwell ticks.
553  */
554 static void
555 scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
556 {
557         struct ieee80211vap *vap  = ss->ss_vap;
558
559         IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
560             "%s: calling; maxdwell=%lu\n",
561             __func__,
562             maxdwell);
563         IEEE80211_LOCK(vap->iv_ic);
564         if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
565                 ieee80211_probe_curchan(vap, 0);
566         taskqueue_enqueue_timeout(vap->iv_ic->ic_tq,
567             &SCAN_PRIVATE(ss)->ss_scan_curchan, maxdwell);
568         IEEE80211_UNLOCK(vap->iv_ic);
569 }
570
571 static void
572 scan_signal(void *arg)
573 {
574         struct ieee80211_scan_state *ss = (struct ieee80211_scan_state *) arg;
575         struct scan_state *ss_priv = SCAN_PRIVATE(ss);
576         struct timeout_task *scan_task = &ss_priv->ss_scan_curchan;
577         struct ieee80211com *ic = ss->ss_ic;
578
579         IEEE80211_LOCK_ASSERT(ic);
580
581         if (ss_priv->ss_iflags & ISCAN_RUNNING) {
582                 if (taskqueue_cancel_timeout(ic->ic_tq, scan_task, NULL) == 0)
583                         taskqueue_enqueue_timeout(ic->ic_tq, scan_task, 0);
584         }
585 }
586
587 /*
588  * Handle mindwell requirements completed; initiate a channel
589  * change to the next channel asap.
590  */
591 static void
592 scan_mindwell(struct ieee80211_scan_state *ss)
593 {
594         struct ieee80211com *ic = ss->ss_ic;
595
596         IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__);
597
598         IEEE80211_LOCK(ic);
599         scan_signal(ss);
600         IEEE80211_UNLOCK(ic);
601 }
602
603 static void
604 scan_start(void *arg, int pending)
605 {
606 #define ISCAN_REP       (ISCAN_MINDWELL | ISCAN_DISCARD)
607         struct ieee80211_scan_state *ss = (struct ieee80211_scan_state *) arg;
608         struct scan_state *ss_priv = SCAN_PRIVATE(ss);
609         struct ieee80211vap *vap = ss->ss_vap;
610         struct ieee80211com *ic = ss->ss_ic;
611
612         IEEE80211_LOCK(ic);
613         if (vap == NULL || (ic->ic_flags & IEEE80211_F_SCAN) == 0 ||
614             (ss_priv->ss_iflags & ISCAN_ABORT)) {
615                 /* Cancelled before we started */
616                 scan_done(ss, 0);
617                 return;
618         }
619
620         if (ss->ss_next == ss->ss_last) {
621                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
622                         "%s: no channels to scan\n", __func__);
623                 scan_done(ss, 1);
624                 return;
625         }
626
627         if (vap->iv_opmode == IEEE80211_M_STA &&
628             vap->iv_state == IEEE80211_S_RUN) {
629                 if ((vap->iv_bss->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) {
630                         /* Enable station power save mode */
631                         vap->iv_sta_ps(vap, 1);
632                         /*
633                          * Use an 1ms delay so the null data frame has a chance
634                          * to go out.
635                          * XXX Should use M_TXCB mechanism to eliminate this.
636                          */
637                         mtx_sleep(vap, IEEE80211_LOCK_OBJ(ic), PCATCH,
638                             "sta_ps", msecs_to_ticks(1));
639                         if (ss_priv->ss_iflags & ISCAN_ABORT) {
640                                 scan_done(ss, 0);
641                                 return;
642                         }
643                 }
644         }
645
646         ss_priv->ss_scanend = ticks + ss_priv->ss_duration;
647
648         /* XXX scan state can change! Re-validate scan state! */
649
650         IEEE80211_UNLOCK(ic);
651
652         ic->ic_scan_start(ic);          /* notify driver */
653
654         scan_curchan_task(ss, 0);
655 }
656
657 static void
658 scan_curchan_task(void *arg, int pending)
659 {
660         struct ieee80211_scan_state *ss = arg;
661         struct scan_state *ss_priv = SCAN_PRIVATE(ss);
662         struct ieee80211vap *vap = ss->ss_vap;
663         struct ieee80211com *ic = ss->ss_ic;
664         struct ieee80211_channel *chan;
665         unsigned long maxdwell;
666         int scandone;
667
668         IEEE80211_LOCK(ic);
669 end:
670         scandone = (ss->ss_next >= ss->ss_last) ||
671             (ss_priv->ss_iflags & ISCAN_CANCEL) != 0;
672
673         IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
674             "%s: loop start; scandone=%d\n",
675             __func__,
676             scandone);
677
678         if (scandone || (ss->ss_flags & IEEE80211_SCAN_GOTPICK) ||
679             (ss_priv->ss_iflags & ISCAN_ABORT) ||
680              time_after(ticks + ss->ss_mindwell, ss_priv->ss_scanend)) {
681                 ss_priv->ss_iflags &= ~ISCAN_RUNNING;
682                 scan_end(ss, scandone);
683                 return;
684         } else
685                 ss_priv->ss_iflags |= ISCAN_RUNNING;
686
687         chan = ss->ss_chans[ss->ss_next++];
688
689         /*
690          * Watch for truncation due to the scan end time.
691          */
692         if (time_after(ticks + ss->ss_maxdwell, ss_priv->ss_scanend))
693                 maxdwell = ss_priv->ss_scanend - ticks;
694         else
695                 maxdwell = ss->ss_maxdwell;
696
697         IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
698             "%s: chan %3d%c -> %3d%c [%s, dwell min %lums max %lums]\n",
699             __func__,
700             ieee80211_chan2ieee(ic, ic->ic_curchan),
701             ieee80211_channel_type_char(ic->ic_curchan),
702             ieee80211_chan2ieee(ic, chan),
703             ieee80211_channel_type_char(chan),
704             (ss->ss_flags & IEEE80211_SCAN_ACTIVE) &&
705                 (chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0 ?
706                 "active" : "passive",
707             ticks_to_msecs(ss->ss_mindwell), ticks_to_msecs(maxdwell));
708
709         /*
710          * Potentially change channel and phy mode.
711          */
712         ic->ic_curchan = chan;
713         ic->ic_rt = ieee80211_get_ratetable(chan);
714         IEEE80211_UNLOCK(ic);
715         /*
716          * Perform the channel change and scan unlocked so the driver
717          * may sleep. Once set_channel returns the hardware has
718          * completed the channel change.
719          */
720         ic->ic_set_channel(ic);
721         ieee80211_radiotap_chan_change(ic);
722
723         /*
724          * Scan curchan.  Drivers for "intelligent hardware"
725          * override ic_scan_curchan to tell the device to do
726          * the work.  Otherwise we manage the work ourselves;
727          * sending a probe request (as needed), and arming the
728          * timeout to switch channels after maxdwell ticks.
729          *
730          * scan_curchan should only pause for the time required to
731          * prepare/initiate the hardware for the scan (if at all).
732          */
733         ic->ic_scan_curchan(ss, maxdwell);
734         IEEE80211_LOCK(ic);
735
736         /* XXX scan state can change! Re-validate scan state! */
737
738         ss_priv->ss_chanmindwell = ticks + ss->ss_mindwell;
739         /* clear mindwell lock and initial channel change flush */
740         ss_priv->ss_iflags &= ~ISCAN_REP;
741
742         if (ss_priv->ss_iflags & (ISCAN_CANCEL|ISCAN_ABORT))
743                 goto end;
744
745         IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: waiting\n", __func__);
746         IEEE80211_UNLOCK(ic);
747 }
748
749 static void
750 scan_end(struct ieee80211_scan_state *ss, int scandone)
751 {
752         struct scan_state *ss_priv = SCAN_PRIVATE(ss);
753         struct ieee80211vap *vap = ss->ss_vap;
754         struct ieee80211com *ic = ss->ss_ic;
755
756         IEEE80211_LOCK_ASSERT(ic);
757
758         IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: out\n", __func__);
759
760         if (ss_priv->ss_iflags & ISCAN_ABORT) {
761                 scan_done(ss, scandone);
762                 return;
763         }
764
765         IEEE80211_UNLOCK(ic);
766         ic->ic_scan_end(ic);            /* notify driver */
767         IEEE80211_LOCK(ic);
768         /* XXX scan state can change! Re-validate scan state! */
769
770         /*
771          * Since a cancellation may have occured during one of the
772          * driver calls (whilst unlocked), update scandone.
773          */
774         if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_CANCEL) != 0) {
775                 /* XXX printf? */
776                 if_printf(vap->iv_ifp,
777                     "%s: OOPS! scan cancelled during driver call (1)!\n",
778                     __func__);
779                 scandone = 1;
780         }
781
782         /*
783          * Record scan complete time.  Note that we also do
784          * this when canceled so any background scan will
785          * not be restarted for a while.
786          */
787         if (scandone)
788                 ic->ic_lastscan = ticks;
789         /* return to the bss channel */
790         if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
791             ic->ic_curchan != ic->ic_bsschan) {
792                 ieee80211_setupcurchan(ic, ic->ic_bsschan);
793                 IEEE80211_UNLOCK(ic);
794                 ic->ic_set_channel(ic);
795                 ieee80211_radiotap_chan_change(ic);
796                 IEEE80211_LOCK(ic);
797         }
798         /* clear internal flags and any indication of a pick */
799         ss_priv->ss_iflags &= ~ISCAN_REP;
800         ss->ss_flags &= ~IEEE80211_SCAN_GOTPICK;
801
802         /*
803          * If not canceled and scan completed, do post-processing.
804          * If the callback function returns 0, then it wants to
805          * continue/restart scanning.  Unfortunately we needed to
806          * notify the driver to end the scan above to avoid having
807          * rx frames alter the scan candidate list.
808          */
809         if ((ss_priv->ss_iflags & ISCAN_CANCEL) == 0 &&
810             !ss->ss_ops->scan_end(ss, vap) &&
811             (ss->ss_flags & IEEE80211_SCAN_ONCE) == 0 &&
812             time_before(ticks + ss->ss_mindwell, ss_priv->ss_scanend)) {
813                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
814                     "%s: done, restart "
815                     "[ticks %u, dwell min %lu scanend %lu]\n",
816                     __func__,
817                     ticks, ss->ss_mindwell, ss_priv->ss_scanend);
818                 ss->ss_next = 0;        /* reset to begining */
819                 if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
820                         vap->iv_stats.is_scan_active++;
821                 else
822                         vap->iv_stats.is_scan_passive++;
823
824                 ss->ss_ops->scan_restart(ss, vap);      /* XXX? */
825                 ieee80211_runtask(ic, &ss_priv->ss_scan_start);
826                 IEEE80211_UNLOCK(ic);
827                 return;
828         }
829
830         /* past here, scandone is ``true'' if not in bg mode */
831         if ((ss->ss_flags & IEEE80211_SCAN_BGSCAN) == 0)
832                 scandone = 1;
833
834         IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
835             "%s: %s, [ticks %u, dwell min %lu scanend %lu]\n",
836             __func__, scandone ? "done" : "stopped",
837             ticks, ss->ss_mindwell, ss_priv->ss_scanend);
838
839         /*
840          * Since a cancellation may have occured during one of the
841          * driver calls (whilst unlocked), update scandone.
842          */
843         if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_CANCEL) != 0) {
844                 /* XXX printf? */
845                 if_printf(vap->iv_ifp,
846                     "%s: OOPS! scan cancelled during driver call (2)!\n",
847                     __func__);
848                 scandone = 1;
849         }
850
851         scan_done(ss, scandone);
852 }
853
854 static void
855 scan_done(struct ieee80211_scan_state *ss, int scandone)
856 {
857         struct scan_state *ss_priv = SCAN_PRIVATE(ss);
858         struct ieee80211com *ic = ss->ss_ic;
859         struct ieee80211vap *vap = ss->ss_vap;
860
861         IEEE80211_LOCK_ASSERT(ic);
862
863         /*
864          * Clear the SCAN bit first in case frames are
865          * pending on the station power save queue.  If
866          * we defer this then the dispatch of the frames
867          * may generate a request to cancel scanning.
868          */
869         ic->ic_flags &= ~IEEE80211_F_SCAN;
870
871         /*
872          * Drop out of power save mode when a scan has
873          * completed.  If this scan was prematurely terminated
874          * because it is a background scan then don't notify
875          * the ap; we'll either return to scanning after we
876          * receive the beacon frame or we'll drop out of power
877          * save mode because the beacon indicates we have frames
878          * waiting for us.
879          */
880         if (scandone) {
881                 vap->iv_sta_ps(vap, 0);
882                 if (ss->ss_next >= ss->ss_last) {
883                         ieee80211_notify_scan_done(vap);
884                         ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN;
885                 }
886         }
887         ss_priv->ss_iflags &= ~(ISCAN_CANCEL|ISCAN_ABORT);
888         ss_priv->ss_scanend = 0;
889         ss->ss_flags &= ~(IEEE80211_SCAN_ONCE | IEEE80211_SCAN_PICK1ST);
890         IEEE80211_UNLOCK(ic);
891 #undef ISCAN_REP
892 }
893
894 /*
895  * Process a beacon or probe response frame.
896  */
897 static void
898 ieee80211_swscan_add_scan(struct ieee80211vap *vap,
899         struct ieee80211_channel *curchan,
900         const struct ieee80211_scanparams *sp,
901         const struct ieee80211_frame *wh,
902         int subtype, int rssi, int noise)
903 {
904         struct ieee80211com *ic = vap->iv_ic;
905         struct ieee80211_scan_state *ss = ic->ic_scan;
906
907         /* XXX locking */
908         /*
909          * Frames received during startup are discarded to avoid
910          * using scan state setup on the initial entry to the timer
911          * callback.  This can occur because the device may enable
912          * rx prior to our doing the initial channel change in the
913          * timer routine.
914          */
915         if (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_DISCARD)
916                 return;
917 #ifdef IEEE80211_DEBUG
918         if (ieee80211_msg_scan(vap) && (ic->ic_flags & IEEE80211_F_SCAN))
919                 ieee80211_scan_dump_probe_beacon(subtype, 1, wh->i_addr2, sp, rssi);
920 #endif
921         if (ss->ss_ops != NULL &&
922             ss->ss_ops->scan_add(ss, curchan, sp, wh, subtype, rssi, noise)) {
923                 /*
924                  * If we've reached the min dwell time terminate
925                  * the timer so we'll switch to the next channel.
926                  */
927                 if ((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_MINDWELL) == 0 &&
928                     time_after_eq(ticks, SCAN_PRIVATE(ss)->ss_chanmindwell)) {
929                         IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
930                             "%s: chan %3d%c min dwell met (%u > %lu)\n",
931                             __func__,
932                             ieee80211_chan2ieee(ic, ic->ic_curchan),
933                             ieee80211_channel_type_char(ic->ic_curchan),
934                             ticks, SCAN_PRIVATE(ss)->ss_chanmindwell);
935                         SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_MINDWELL;
936                         /*
937                          * NB: trigger at next clock tick or wait for the
938                          * hardware.
939                          */
940                         ic->ic_scan_mindwell(ss);
941                 }
942         }
943 }
944
945 static struct ieee80211_scan_methods swscan_methods = {
946         .sc_attach = ieee80211_swscan_attach,
947         .sc_detach = ieee80211_swscan_detach,
948         .sc_vattach = ieee80211_swscan_vattach,
949         .sc_vdetach = ieee80211_swscan_vdetach,
950         .sc_set_scan_duration = ieee80211_swscan_set_scan_duration,
951         .sc_start_scan = ieee80211_swscan_start_scan,
952         .sc_check_scan = ieee80211_swscan_check_scan,
953         .sc_bg_scan = ieee80211_swscan_bg_scan,
954         .sc_cancel_scan = ieee80211_swscan_cancel_scan,
955         .sc_cancel_anyscan = ieee80211_swscan_cancel_anyscan,
956         .sc_scan_next = ieee80211_swscan_scan_next,
957         .sc_scan_done = ieee80211_swscan_scan_done,
958         .sc_scan_probe_curchan = ieee80211_swscan_probe_curchan,
959         .sc_add_scan = ieee80211_swscan_add_scan
960 };
961
962 /*
963  * Default scan attach method.
964  */
965 void
966 ieee80211_swscan_attach(struct ieee80211com *ic)
967 {
968         struct scan_state *ss;
969
970         /*
971          * Setup the default methods
972          */
973         ic->ic_scan_methods = &swscan_methods;
974
975         /* Allocate initial scan state */
976         ss = (struct scan_state *) IEEE80211_MALLOC(sizeof(struct scan_state),
977                 M_80211_SCAN, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
978         if (ss == NULL) {
979                 ic->ic_scan = NULL;
980                 return;
981         }
982         TASK_INIT(&ss->ss_scan_start, 0, scan_start, ss);
983         TIMEOUT_TASK_INIT(ic->ic_tq, &ss->ss_scan_curchan, 0,
984             scan_curchan_task, ss);
985
986         ic->ic_scan = &ss->base;
987         ss->base.ss_ic = ic;
988
989         ic->ic_scan_curchan = scan_curchan;
990         ic->ic_scan_mindwell = scan_mindwell;
991 }