ieee80211_scan_sw.c revision 298392
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 298392 2016-04-21 06:19:33Z 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#define	ISCAN_RUNNING		0x0010		/* scan was started */
63
64	unsigned long		ss_chanmindwell;  /* min dwell on curchan */
65	unsigned long		ss_scanend;	/* time scan must stop */
66	u_int			ss_duration;	/* duration for next scan */
67	struct task		ss_scan_start;	/* scan start */
68	struct timeout_task	ss_scan_curchan;  /* scan execution */
69};
70#define	SCAN_PRIVATE(ss)	((struct scan_state *) ss)
71
72/*
73 * Amount of time to go off-channel during a background
74 * scan.  This value should be large enough to catch most
75 * ap's but short enough that we can return on-channel
76 * before our listen interval expires.
77 *
78 * XXX tunable
79 * XXX check against configured listen interval
80 */
81#define	IEEE80211_SCAN_OFFCHANNEL	msecs_to_ticks(150)
82
83/*
84 * Roaming-related defaults.  RSSI thresholds are as returned by the
85 * driver (.5dBm).  Transmit rate thresholds are IEEE rate codes (i.e
86 * .5M units) or MCS.
87 */
88/* rssi thresholds */
89#define	ROAM_RSSI_11A_DEFAULT		14	/* 11a bss */
90#define	ROAM_RSSI_11B_DEFAULT		14	/* 11b bss */
91#define	ROAM_RSSI_11BONLY_DEFAULT	14	/* 11b-only bss */
92/* transmit rate thresholds */
93#define	ROAM_RATE_11A_DEFAULT		2*12	/* 11a bss */
94#define	ROAM_RATE_11B_DEFAULT		2*5	/* 11b bss */
95#define	ROAM_RATE_11BONLY_DEFAULT	2*1	/* 11b-only bss */
96#define	ROAM_RATE_HALF_DEFAULT		2*6	/* half-width 11a/g bss */
97#define	ROAM_RATE_QUARTER_DEFAULT	2*3	/* quarter-width 11a/g bss */
98#define	ROAM_MCS_11N_DEFAULT		(1 | IEEE80211_RATE_MCS) /* 11n bss */
99
100static	void scan_curchan(struct ieee80211_scan_state *, unsigned long);
101static	void scan_mindwell(struct ieee80211_scan_state *);
102static	void scan_signal(struct ieee80211_scan_state *, int);
103static	void scan_signal_locked(struct ieee80211_scan_state *, int);
104static	void scan_start(void *, int);
105static	void scan_curchan_task(void *, int);
106static	void scan_end(struct ieee80211_scan_state *, int);
107static	void scan_done(struct ieee80211_scan_state *, int);
108
109MALLOC_DEFINE(M_80211_SCAN, "80211scan", "802.11 scan state");
110
111static void
112ieee80211_swscan_detach(struct ieee80211com *ic)
113{
114	struct ieee80211_scan_state *ss = ic->ic_scan;
115
116	if (ss != NULL) {
117		scan_signal(ss, ISCAN_ABORT);
118		ieee80211_draintask(ic, &SCAN_PRIVATE(ss)->ss_scan_start);
119		taskqueue_drain_timeout(ic->ic_tq,
120		    &SCAN_PRIVATE(ss)->ss_scan_curchan);
121		KASSERT((ic->ic_flags & IEEE80211_F_SCAN) == 0,
122		    ("scan still running"));
123
124		/*
125		 * For now, do the ss_ops detach here rather
126		 * than ieee80211_scan_detach().
127		 *
128		 * I'll figure out how to cleanly split things up
129		 * at a later date.
130		 */
131		if (ss->ss_ops != NULL) {
132			ss->ss_ops->scan_detach(ss);
133			ss->ss_ops = NULL;
134		}
135		ic->ic_scan = NULL;
136		IEEE80211_FREE(SCAN_PRIVATE(ss), M_80211_SCAN);
137	}
138}
139
140static void
141ieee80211_swscan_vattach(struct ieee80211vap *vap)
142{
143	/* nothing to do for now */
144	/*
145	 * TODO: all of the vap scan calls should be methods!
146	 */
147
148}
149
150static void
151ieee80211_swscan_vdetach(struct ieee80211vap *vap)
152{
153	struct ieee80211com *ic = vap->iv_ic;
154	struct ieee80211_scan_state *ss = ic->ic_scan;
155
156	IEEE80211_LOCK_ASSERT(ic);
157
158	if (ss != NULL && ss->ss_vap == vap &&
159	    (ic->ic_flags & IEEE80211_F_SCAN))
160		scan_signal_locked(ss, ISCAN_ABORT);
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_start);
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		    ieee80211_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,
415			    &SCAN_PRIVATE(ss)->ss_scan_start);
416		} else {
417			/* XXX msg+stat */
418		}
419	} else {
420		IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
421		    "%s: %s scan already in progress\n", __func__,
422		    ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive");
423	}
424	IEEE80211_UNLOCK(ic);
425
426	/* NB: racey, does it matter? */
427	return (ic->ic_flags & IEEE80211_F_SCAN);
428}
429
430static void
431cancel_scan(struct ieee80211vap *vap, int any, const char *func)
432{
433	struct ieee80211com *ic = vap->iv_ic;
434	struct ieee80211_scan_state *ss = ic->ic_scan;
435
436	IEEE80211_LOCK(ic);
437	if ((ic->ic_flags & IEEE80211_F_SCAN) &&
438	    (any || ss->ss_vap == vap) &&
439	    (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) == 0) {
440		IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
441		    "%s: cancel %s scan\n", func,
442		    ss->ss_flags & IEEE80211_SCAN_ACTIVE ?
443			"active" : "passive");
444
445		/* clear bg scan NOPICK */
446		ss->ss_flags &= ~IEEE80211_SCAN_NOPICK;
447		/* mark cancel request and wake up the scan task */
448		scan_signal_locked(ss, ISCAN_CANCEL);
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 * Manually switch to the next channel in the channel list.
480 * Provided for drivers that manage scanning themselves
481 * (e.g. for firmware-based devices).
482 */
483static void
484ieee80211_swscan_scan_next(struct ieee80211vap *vap)
485{
486	struct ieee80211_scan_state *ss = vap->iv_ic->ic_scan;
487
488	IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__);
489
490	/* wake up the scan task */
491	scan_signal(ss, 0);
492}
493
494/*
495 * Manually stop a scan that is currently running.
496 * Provided for drivers that are not able to scan single channels
497 * (e.g. for firmware-based devices).
498 */
499static void
500ieee80211_swscan_scan_done(struct ieee80211vap *vap)
501{
502	struct ieee80211com *ic = vap->iv_ic;
503	struct ieee80211_scan_state *ss = ic->ic_scan;
504
505	IEEE80211_LOCK_ASSERT(ic);
506
507	scan_signal_locked(ss, 0);
508}
509
510/*
511 * Probe the current channel, if allowed, while scanning.
512 * If the channel is not marked passive-only then send
513 * a probe request immediately.  Otherwise mark state and
514 * listen for beacons on the channel; if we receive something
515 * then we'll transmit a probe request.
516 */
517static void
518ieee80211_swscan_probe_curchan(struct ieee80211vap *vap, int force)
519{
520	struct ieee80211com *ic = vap->iv_ic;
521	struct ieee80211_scan_state *ss = ic->ic_scan;
522	struct ifnet *ifp = vap->iv_ifp;
523	int i;
524
525	/*
526	 * Send directed probe requests followed by any
527	 * broadcast probe request.
528	 * XXX remove dependence on ic/vap->iv_bss
529	 */
530	for (i = 0; i < ss->ss_nssid; i++)
531		ieee80211_send_probereq(vap->iv_bss,
532			vap->iv_myaddr, ifp->if_broadcastaddr,
533			ifp->if_broadcastaddr,
534			ss->ss_ssid[i].ssid, ss->ss_ssid[i].len);
535	if ((ss->ss_flags & IEEE80211_SCAN_NOBCAST) == 0)
536		ieee80211_send_probereq(vap->iv_bss,
537			vap->iv_myaddr, ifp->if_broadcastaddr,
538			ifp->if_broadcastaddr,
539			"", 0);
540}
541
542/*
543 * Scan curchan.  If this is an active scan and the channel
544 * is not marked passive then send probe request frame(s).
545 * Arrange for the channel change after maxdwell ticks.
546 */
547static void
548scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
549{
550	struct ieee80211vap *vap  = ss->ss_vap;
551	struct ieee80211com *ic = ss->ss_ic;
552
553	IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
554	    "%s: calling; maxdwell=%lu\n",
555	    __func__,
556	    maxdwell);
557	IEEE80211_LOCK(ic);
558	if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
559		ieee80211_probe_curchan(vap, 0);
560	taskqueue_enqueue_timeout(ic->ic_tq,
561	    &SCAN_PRIVATE(ss)->ss_scan_curchan, maxdwell);
562	IEEE80211_UNLOCK(ic);
563}
564
565static void
566scan_signal(struct ieee80211_scan_state *ss, int iflags)
567{
568	struct ieee80211com *ic = ss->ss_ic;
569
570	IEEE80211_UNLOCK_ASSERT(ic);
571
572	IEEE80211_LOCK(ic);
573	scan_signal_locked(ss, iflags);
574	IEEE80211_UNLOCK(ic);
575}
576
577static void
578scan_signal_locked(struct ieee80211_scan_state *ss, int iflags)
579{
580	struct scan_state *ss_priv = SCAN_PRIVATE(ss);
581	struct timeout_task *scan_task = &ss_priv->ss_scan_curchan;
582	struct ieee80211com *ic = ss->ss_ic;
583
584	IEEE80211_LOCK_ASSERT(ic);
585
586	ss_priv->ss_iflags |= iflags;
587	if (ss_priv->ss_iflags & ISCAN_RUNNING) {
588		if (taskqueue_cancel_timeout(ic->ic_tq, scan_task, NULL) == 0)
589			taskqueue_enqueue_timeout(ic->ic_tq, scan_task, 0);
590	}
591}
592
593/*
594 * Handle mindwell requirements completed; initiate a channel
595 * change to the next channel asap.
596 */
597static void
598scan_mindwell(struct ieee80211_scan_state *ss)
599{
600
601	IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN, "%s: called\n",
602	    __func__);
603
604	scan_signal(ss, 0);
605}
606
607static void
608scan_start(void *arg, int pending)
609{
610#define	ISCAN_REP	(ISCAN_MINDWELL | ISCAN_DISCARD)
611	struct ieee80211_scan_state *ss = (struct ieee80211_scan_state *) arg;
612	struct scan_state *ss_priv = SCAN_PRIVATE(ss);
613	struct ieee80211vap *vap = ss->ss_vap;
614	struct ieee80211com *ic = ss->ss_ic;
615
616	IEEE80211_LOCK(ic);
617	if (vap == NULL || (ic->ic_flags & IEEE80211_F_SCAN) == 0 ||
618	    (ss_priv->ss_iflags & ISCAN_ABORT)) {
619		/* Cancelled before we started */
620		scan_done(ss, 0);
621		return;
622	}
623
624	if (ss->ss_next == ss->ss_last) {
625		IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
626			"%s: no channels to scan\n", __func__);
627		scan_done(ss, 1);
628		return;
629	}
630
631	if (vap->iv_opmode == IEEE80211_M_STA &&
632	    vap->iv_state == IEEE80211_S_RUN) {
633		if ((vap->iv_bss->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) {
634			/* Enable station power save mode */
635			vap->iv_sta_ps(vap, 1);
636			/* Wait until null data frame will be ACK'ed */
637			mtx_sleep(vap, IEEE80211_LOCK_OBJ(ic), PCATCH,
638			    "sta_ps", msecs_to_ticks(10));
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
657static void
658scan_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 ieee80211com *ic = ss->ss_ic;
663	struct ieee80211_channel *chan;
664	unsigned long maxdwell;
665	int scandone;
666
667	IEEE80211_LOCK(ic);
668end:
669	scandone = (ss->ss_next >= ss->ss_last) ||
670	    (ss_priv->ss_iflags & ISCAN_CANCEL) != 0;
671
672	IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN,
673	    "%s: loop start; scandone=%d\n",
674	    __func__,
675	    scandone);
676
677	if (scandone || (ss->ss_flags & IEEE80211_SCAN_GOTPICK) ||
678	    (ss_priv->ss_iflags & ISCAN_ABORT) ||
679	     ieee80211_time_after(ticks + ss->ss_mindwell, ss_priv->ss_scanend)) {
680		ss_priv->ss_iflags &= ~ISCAN_RUNNING;
681		scan_end(ss, scandone);
682		return;
683	} else
684		ss_priv->ss_iflags |= ISCAN_RUNNING;
685
686	chan = ss->ss_chans[ss->ss_next++];
687
688	/*
689	 * Watch for truncation due to the scan end time.
690	 */
691	if (ieee80211_time_after(ticks + ss->ss_maxdwell, ss_priv->ss_scanend))
692		maxdwell = ss_priv->ss_scanend - ticks;
693	else
694		maxdwell = ss->ss_maxdwell;
695
696	IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN,
697	    "%s: chan %3d%c -> %3d%c [%s, dwell min %lums max %lums]\n",
698	    __func__,
699	    ieee80211_chan2ieee(ic, ic->ic_curchan),
700	    ieee80211_channel_type_char(ic->ic_curchan),
701	    ieee80211_chan2ieee(ic, chan),
702	    ieee80211_channel_type_char(chan),
703	    (ss->ss_flags & IEEE80211_SCAN_ACTIVE) &&
704		(chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0 ?
705		"active" : "passive",
706	    ticks_to_msecs(ss->ss_mindwell), ticks_to_msecs(maxdwell));
707
708	/*
709	 * Potentially change channel and phy mode.
710	 */
711	ic->ic_curchan = chan;
712	ic->ic_rt = ieee80211_get_ratetable(chan);
713	IEEE80211_UNLOCK(ic);
714	/*
715	 * Perform the channel change and scan unlocked so the driver
716	 * may sleep. Once set_channel returns the hardware has
717	 * completed the channel change.
718	 */
719	ic->ic_set_channel(ic);
720	ieee80211_radiotap_chan_change(ic);
721
722	/*
723	 * Scan curchan.  Drivers for "intelligent hardware"
724	 * override ic_scan_curchan to tell the device to do
725	 * the work.  Otherwise we manage the work ourselves;
726	 * sending a probe request (as needed), and arming the
727	 * timeout to switch channels after maxdwell ticks.
728	 *
729	 * scan_curchan should only pause for the time required to
730	 * prepare/initiate the hardware for the scan (if at all).
731	 */
732	ic->ic_scan_curchan(ss, maxdwell);
733	IEEE80211_LOCK(ic);
734
735	/* XXX scan state can change! Re-validate scan state! */
736
737	ss_priv->ss_chanmindwell = ticks + ss->ss_mindwell;
738	/* clear mindwell lock and initial channel change flush */
739	ss_priv->ss_iflags &= ~ISCAN_REP;
740
741	if (ss_priv->ss_iflags & (ISCAN_CANCEL|ISCAN_ABORT)) {
742		taskqueue_cancel_timeout(ic->ic_tq, &ss_priv->ss_scan_curchan,
743		    NULL);
744		goto end;
745	}
746
747	IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN, "%s: waiting\n",
748	    __func__);
749	IEEE80211_UNLOCK(ic);
750}
751
752static void
753scan_end(struct ieee80211_scan_state *ss, int scandone)
754{
755	struct scan_state *ss_priv = SCAN_PRIVATE(ss);
756	struct ieee80211vap *vap = ss->ss_vap;
757	struct ieee80211com *ic = ss->ss_ic;
758
759	IEEE80211_LOCK_ASSERT(ic);
760
761	IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: out\n", __func__);
762
763	if (ss_priv->ss_iflags & ISCAN_ABORT) {
764		scan_done(ss, scandone);
765		return;
766	}
767
768	IEEE80211_UNLOCK(ic);
769	ic->ic_scan_end(ic);		/* notify driver */
770	IEEE80211_LOCK(ic);
771	/* XXX scan state can change! Re-validate scan state! */
772
773	/*
774	 * Since a cancellation may have occured during one of the
775	 * driver calls (whilst unlocked), update scandone.
776	 */
777	if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_CANCEL) != 0) {
778		/* XXX printf? */
779		if_printf(vap->iv_ifp,
780		    "%s: OOPS! scan cancelled during driver call (1)!\n",
781		    __func__);
782		scandone = 1;
783	}
784
785	/*
786	 * Record scan complete time.  Note that we also do
787	 * this when canceled so any background scan will
788	 * not be restarted for a while.
789	 */
790	if (scandone)
791		ic->ic_lastscan = ticks;
792	/* return to the bss channel */
793	if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
794	    ic->ic_curchan != ic->ic_bsschan) {
795		ieee80211_setupcurchan(ic, ic->ic_bsschan);
796		IEEE80211_UNLOCK(ic);
797		ic->ic_set_channel(ic);
798		ieee80211_radiotap_chan_change(ic);
799		IEEE80211_LOCK(ic);
800	}
801	/* clear internal flags and any indication of a pick */
802	ss_priv->ss_iflags &= ~ISCAN_REP;
803	ss->ss_flags &= ~IEEE80211_SCAN_GOTPICK;
804
805	/*
806	 * If not canceled and scan completed, do post-processing.
807	 * If the callback function returns 0, then it wants to
808	 * continue/restart scanning.  Unfortunately we needed to
809	 * notify the driver to end the scan above to avoid having
810	 * rx frames alter the scan candidate list.
811	 */
812	if ((ss_priv->ss_iflags & ISCAN_CANCEL) == 0 &&
813	    !ss->ss_ops->scan_end(ss, vap) &&
814	    (ss->ss_flags & IEEE80211_SCAN_ONCE) == 0 &&
815	    ieee80211_time_before(ticks + ss->ss_mindwell, ss_priv->ss_scanend)) {
816		IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
817		    "%s: done, restart "
818		    "[ticks %u, dwell min %lu scanend %lu]\n",
819		    __func__,
820		    ticks, ss->ss_mindwell, ss_priv->ss_scanend);
821		ss->ss_next = 0;	/* reset to begining */
822		if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
823			vap->iv_stats.is_scan_active++;
824		else
825			vap->iv_stats.is_scan_passive++;
826
827		ss->ss_ops->scan_restart(ss, vap);	/* XXX? */
828		ieee80211_runtask(ic, &ss_priv->ss_scan_start);
829		IEEE80211_UNLOCK(ic);
830		return;
831	}
832
833	/* past here, scandone is ``true'' if not in bg mode */
834	if ((ss->ss_flags & IEEE80211_SCAN_BGSCAN) == 0)
835		scandone = 1;
836
837	IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
838	    "%s: %s, [ticks %u, dwell min %lu scanend %lu]\n",
839	    __func__, scandone ? "done" : "stopped",
840	    ticks, ss->ss_mindwell, ss_priv->ss_scanend);
841
842	/*
843	 * Since a cancellation may have occured during one of the
844	 * driver calls (whilst unlocked), update scandone.
845	 */
846	if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_CANCEL) != 0) {
847		/* XXX printf? */
848		if_printf(vap->iv_ifp,
849		    "%s: OOPS! scan cancelled during driver call (2)!\n",
850		    __func__);
851		scandone = 1;
852	}
853
854	scan_done(ss, scandone);
855}
856
857static void
858scan_done(struct ieee80211_scan_state *ss, int scandone)
859{
860	struct scan_state *ss_priv = SCAN_PRIVATE(ss);
861	struct ieee80211com *ic = ss->ss_ic;
862	struct ieee80211vap *vap = ss->ss_vap;
863
864	IEEE80211_LOCK_ASSERT(ic);
865
866	/*
867	 * Clear the SCAN bit first in case frames are
868	 * pending on the station power save queue.  If
869	 * we defer this then the dispatch of the frames
870	 * may generate a request to cancel scanning.
871	 */
872	ic->ic_flags &= ~IEEE80211_F_SCAN;
873
874	/*
875	 * Drop out of power save mode when a scan has
876	 * completed.  If this scan was prematurely terminated
877	 * because it is a background scan then don't notify
878	 * the ap; we'll either return to scanning after we
879	 * receive the beacon frame or we'll drop out of power
880	 * save mode because the beacon indicates we have frames
881	 * waiting for us.
882	 */
883	if (scandone) {
884		vap->iv_sta_ps(vap, 0);
885		if (ss->ss_next >= ss->ss_last) {
886			ieee80211_notify_scan_done(vap);
887			ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN;
888		}
889	}
890	ss_priv->ss_iflags &= ~(ISCAN_CANCEL|ISCAN_ABORT);
891	ss_priv->ss_scanend = 0;
892	ss->ss_flags &= ~(IEEE80211_SCAN_ONCE | IEEE80211_SCAN_PICK1ST);
893	IEEE80211_UNLOCK(ic);
894#undef ISCAN_REP
895}
896
897/*
898 * Process a beacon or probe response frame.
899 */
900static void
901ieee80211_swscan_add_scan(struct ieee80211vap *vap,
902	struct ieee80211_channel *curchan,
903	const struct ieee80211_scanparams *sp,
904	const struct ieee80211_frame *wh,
905	int subtype, int rssi, int noise)
906{
907	struct ieee80211com *ic = vap->iv_ic;
908	struct ieee80211_scan_state *ss = ic->ic_scan;
909
910	/* XXX locking */
911	/*
912	 * Frames received during startup are discarded to avoid
913	 * using scan state setup on the initial entry to the timer
914	 * callback.  This can occur because the device may enable
915	 * rx prior to our doing the initial channel change in the
916	 * timer routine.
917	 */
918	if (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_DISCARD)
919		return;
920#ifdef IEEE80211_DEBUG
921	if (ieee80211_msg_scan(vap) && (ic->ic_flags & IEEE80211_F_SCAN))
922		ieee80211_scan_dump_probe_beacon(subtype, 1, wh->i_addr2, sp, rssi);
923#endif
924	if (ss->ss_ops != NULL &&
925	    ss->ss_ops->scan_add(ss, curchan, sp, wh, subtype, rssi, noise)) {
926		/*
927		 * If we've reached the min dwell time terminate
928		 * the timer so we'll switch to the next channel.
929		 */
930		if ((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_MINDWELL) == 0 &&
931		    ieee80211_time_after_eq(ticks, SCAN_PRIVATE(ss)->ss_chanmindwell)) {
932			IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
933			    "%s: chan %3d%c min dwell met (%u > %lu)\n",
934			    __func__,
935			    ieee80211_chan2ieee(ic, ic->ic_curchan),
936			    ieee80211_channel_type_char(ic->ic_curchan),
937			    ticks, SCAN_PRIVATE(ss)->ss_chanmindwell);
938			SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_MINDWELL;
939			/*
940			 * NB: trigger at next clock tick or wait for the
941			 * hardware.
942			 */
943			ic->ic_scan_mindwell(ss);
944		}
945	}
946}
947
948static struct ieee80211_scan_methods swscan_methods = {
949	.sc_attach = ieee80211_swscan_attach,
950	.sc_detach = ieee80211_swscan_detach,
951	.sc_vattach = ieee80211_swscan_vattach,
952	.sc_vdetach = ieee80211_swscan_vdetach,
953	.sc_set_scan_duration = ieee80211_swscan_set_scan_duration,
954	.sc_start_scan = ieee80211_swscan_start_scan,
955	.sc_check_scan = ieee80211_swscan_check_scan,
956	.sc_bg_scan = ieee80211_swscan_bg_scan,
957	.sc_cancel_scan = ieee80211_swscan_cancel_scan,
958	.sc_cancel_anyscan = ieee80211_swscan_cancel_anyscan,
959	.sc_scan_next = ieee80211_swscan_scan_next,
960	.sc_scan_done = ieee80211_swscan_scan_done,
961	.sc_scan_probe_curchan = ieee80211_swscan_probe_curchan,
962	.sc_add_scan = ieee80211_swscan_add_scan
963};
964
965/*
966 * Default scan attach method.
967 */
968void
969ieee80211_swscan_attach(struct ieee80211com *ic)
970{
971	struct scan_state *ss;
972
973	/*
974	 * Setup the default methods
975	 */
976	ic->ic_scan_methods = &swscan_methods;
977
978	/* Allocate initial scan state */
979	ss = (struct scan_state *) IEEE80211_MALLOC(sizeof(struct scan_state),
980		M_80211_SCAN, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
981	if (ss == NULL) {
982		ic->ic_scan = NULL;
983		return;
984	}
985	TASK_INIT(&ss->ss_scan_start, 0, scan_start, ss);
986	TIMEOUT_TASK_INIT(ic->ic_tq, &ss->ss_scan_curchan, 0,
987	    scan_curchan_task, ss);
988
989	ic->ic_scan = &ss->base;
990	ss->base.ss_ic = ic;
991
992	ic->ic_scan_curchan = scan_curchan;
993	ic->ic_scan_mindwell = scan_mindwell;
994}
995