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