ieee80211_scan_sw.c revision 171124
1/*-
2 * Copyright (c) 2002-2007 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.c 171124 2007-06-30 21:23:23Z thompsa $");
28
29/*
30 * IEEE 802.11 scanning support.
31 */
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/kernel.h>
35
36#include <sys/socket.h>
37
38#include <net/if.h>
39#include <net/if_media.h>
40#include <net/ethernet.h>
41
42#include <net80211/ieee80211_var.h>
43
44#include <net/bpf.h>
45
46struct scan_state {
47	struct ieee80211_scan_state base;	/* public state */
48
49	u_int		ss_iflags;		/* flags used internally */
50#define	ISCAN_MINDWELL 	0x0001		/* min dwell time reached */
51#define	ISCAN_DISCARD	0x0002		/* discard rx'd frames */
52#define	ISCAN_CANCEL	0x0004		/* cancel current scan */
53#define	ISCAN_START	0x0008		/* 1st time through next_scan */
54	unsigned long	ss_chanmindwell;	/* min dwell on curchan */
55	unsigned long	ss_scanend;		/* time scan must stop */
56	u_int		ss_duration;		/* duration for next scan */
57	struct callout	ss_scan_timer;		/* scan timer */
58};
59#define	SCAN_PRIVATE(ss)	((struct scan_state *) ss)
60
61/*
62 * Amount of time to go off-channel during a background
63 * scan.  This value should be large enough to catch most
64 * ap's but short enough that we can return on-channel
65 * before our listen interval expires.
66 *
67 * XXX tunable
68 * XXX check against configured listen interval
69 */
70#define	IEEE80211_SCAN_OFFCHANNEL	msecs_to_ticks(150)
71
72/*
73 * Roaming-related defaults.  RSSI thresholds are as returned by the
74 * driver (dBm).  Transmit rate thresholds are IEEE rate codes (i.e
75 * .5M units).
76 */
77#define	ROAM_RSSI_11A_DEFAULT		14	/* rssi threshold for 11a bss */
78#define	ROAM_RSSI_11B_DEFAULT		14	/* rssi threshold for 11b bss */
79#define	ROAM_RSSI_11BONLY_DEFAULT	14	/* rssi threshold for 11b-only bss */
80#define	ROAM_RATE_11A_DEFAULT		2*12	/* tx rate thresh for 11a bss */
81#define	ROAM_RATE_11B_DEFAULT		2*5	/* tx rate thresh for 11b bss */
82#define	ROAM_RATE_11BONLY_DEFAULT	2*1	/* tx rate thresh for 11b-only bss */
83
84static	void scan_restart_pwrsav(void *);
85static	void scan_curchan(struct ieee80211com *, unsigned long);
86static	void scan_mindwell(struct ieee80211com *);
87static	void scan_next(void *);
88
89MALLOC_DEFINE(M_80211_SCAN, "80211scan", "802.11 scan state");
90
91void
92ieee80211_scan_attach(struct ieee80211com *ic)
93{
94	struct scan_state *ss;
95
96	ic->ic_roaming = IEEE80211_ROAMING_AUTO;
97
98	MALLOC(ss, struct scan_state *, sizeof(struct scan_state),
99		M_80211_SCAN, M_NOWAIT | M_ZERO);
100	if (ss == NULL) {
101		ic->ic_scan = NULL;
102		return;
103	}
104	callout_init(&ss->ss_scan_timer, CALLOUT_MPSAFE);
105	ic->ic_scan = &ss->base;
106
107	ic->ic_scan_curchan = scan_curchan;
108	ic->ic_scan_mindwell = scan_mindwell;
109
110	ic->ic_bgscanidle = (IEEE80211_BGSCAN_IDLE_DEFAULT*1000)/hz;
111	ic->ic_bgscanintvl = IEEE80211_BGSCAN_INTVAL_DEFAULT*hz;
112	ic->ic_scanvalid = IEEE80211_SCAN_VALID_DEFAULT*hz;
113	ic->ic_roam.rssi11a = ROAM_RSSI_11A_DEFAULT;
114	ic->ic_roam.rssi11b = ROAM_RSSI_11B_DEFAULT;
115	ic->ic_roam.rssi11bOnly = ROAM_RSSI_11BONLY_DEFAULT;
116	ic->ic_roam.rate11a = ROAM_RATE_11A_DEFAULT;
117	ic->ic_roam.rate11b = ROAM_RATE_11B_DEFAULT;
118	ic->ic_roam.rate11bOnly = ROAM_RATE_11BONLY_DEFAULT;
119}
120
121void
122ieee80211_scan_detach(struct ieee80211com *ic)
123{
124	struct ieee80211_scan_state *ss = ic->ic_scan;
125
126	if (ss != NULL) {
127		callout_drain(&SCAN_PRIVATE(ss)->ss_scan_timer);
128		if (ss->ss_ops != NULL) {
129			ss->ss_ops->scan_detach(ss);
130			ss->ss_ops = NULL;
131		}
132		ic->ic_flags &= ~IEEE80211_F_SCAN;
133		ic->ic_scan = NULL;
134		FREE(SCAN_PRIVATE(ss), M_80211_SCAN);
135	}
136}
137
138/*
139 * Simple-minded scanner module support.
140 */
141#define	IEEE80211_SCANNER_MAX	(IEEE80211_M_MONITOR+1)
142
143static const char *scan_modnames[IEEE80211_SCANNER_MAX] = {
144	"wlan_scan_sta",	/* IEEE80211_M_IBSS */
145	"wlan_scan_sta",	/* IEEE80211_M_STA */
146	"wlan_scan_wds",	/* IEEE80211_M_WDS */
147	"wlan_scan_sta",	/* IEEE80211_M_AHDEMO */
148	"wlan_scan_4",		/* n/a */
149	"wlan_scan_5",		/* n/a */
150	"wlan_scan_ap",		/* IEEE80211_M_HOSTAP */
151	"wlan_scan_7",		/* n/a */
152	"wlan_scan_monitor",	/* IEEE80211_M_MONITOR */
153};
154static const struct ieee80211_scanner *scanners[IEEE80211_SCANNER_MAX];
155
156const struct ieee80211_scanner *
157ieee80211_scanner_get(enum ieee80211_opmode mode)
158{
159	if (mode >= IEEE80211_SCANNER_MAX)
160		return NULL;
161	if (scanners[mode] == NULL)
162		ieee80211_load_module(scan_modnames[mode]);
163	return scanners[mode];
164}
165
166void
167ieee80211_scanner_register(enum ieee80211_opmode mode,
168	const struct ieee80211_scanner *scan)
169{
170	if (mode >= IEEE80211_SCANNER_MAX)
171		return;
172	scanners[mode] = scan;
173}
174
175void
176ieee80211_scanner_unregister(enum ieee80211_opmode mode,
177	const struct ieee80211_scanner *scan)
178{
179	if (mode >= IEEE80211_SCANNER_MAX)
180		return;
181	if (scanners[mode] == scan)
182		scanners[mode] = NULL;
183}
184
185void
186ieee80211_scanner_unregister_all(const struct ieee80211_scanner *scan)
187{
188	int m;
189
190	for (m = 0; m < IEEE80211_SCANNER_MAX; m++)
191		if (scanners[m] == scan)
192			scanners[m] = NULL;
193}
194
195/*
196 * Update common scanner state to reflect the current
197 * operating mode.  This is called when the state machine
198 * is transitioned to RUN state w/o scanning--e.g. when
199 * operating in monitor mode.  The purpose of this is to
200 * ensure later callbacks find ss_ops set to properly
201 * reflect current operating mode.
202 */
203int
204ieee80211_scan_update(struct ieee80211com *ic)
205{
206	struct ieee80211_scan_state *ss = ic->ic_scan;
207	const struct ieee80211_scanner *scan;
208
209	scan = ieee80211_scanner_get(ic->ic_opmode);
210	IEEE80211_LOCK(ic);
211	if (scan == NULL) {
212		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
213		    "%s: no scanner support for mode %u\n",
214		    __func__, ic->ic_opmode);
215		/* XXX stat */
216	}
217	ss->ss_ic = ic;
218	if (ss->ss_ops != scan) {
219		/* switch scanners; detach old, attach new */
220		if (ss->ss_ops != NULL)
221			ss->ss_ops->scan_detach(ss);
222		if (scan != NULL && !scan->scan_attach(ss)) {
223			/* XXX attach failure */
224			/* XXX stat+msg */
225			ss->ss_ops = NULL;
226		} else
227			ss->ss_ops = scan;
228	}
229	IEEE80211_UNLOCK(ic);
230
231	return (scan != NULL);
232}
233
234static void
235change_channel(struct ieee80211com *ic,
236	struct ieee80211_channel *chan)
237{
238	ic->ic_curchan = chan;
239	ic->ic_set_channel(ic);
240}
241
242static char
243channel_type(const struct ieee80211_channel *c)
244{
245	if (IEEE80211_IS_CHAN_ST(c))
246		return 'S';
247	if (IEEE80211_IS_CHAN_108A(c))
248		return 'T';
249	if (IEEE80211_IS_CHAN_108G(c))
250		return 'G';
251	if (IEEE80211_IS_CHAN_HT(c))
252		return 'n';
253	if (IEEE80211_IS_CHAN_A(c))
254		return 'a';
255	if (IEEE80211_IS_CHAN_ANYG(c))
256		return 'g';
257	if (IEEE80211_IS_CHAN_B(c))
258		return 'b';
259	return 'f';
260}
261
262void
263ieee80211_scan_dump_channels(const struct ieee80211_scan_state *ss)
264{
265	struct ieee80211com *ic = ss->ss_ic;
266	const char *sep;
267	int i;
268
269	sep = "";
270	for (i = ss->ss_next; i < ss->ss_last; i++) {
271		const struct ieee80211_channel *c = ss->ss_chans[i];
272
273		printf("%s%u%c", sep, ieee80211_chan2ieee(ic, c),
274			channel_type(c));
275		sep = ", ";
276	}
277}
278
279/*
280 * Enable station power save mode and start/restart the scanning thread.
281 */
282static void
283scan_restart_pwrsav(void *arg)
284{
285	struct scan_state *ss = (struct scan_state *) arg;
286	struct ieee80211com *ic = ss->base.ss_ic;
287	int delay;
288
289	ieee80211_sta_pwrsave(ic, 1);
290	/*
291	 * Use an initial 1ms delay to insure the null
292	 * data frame has a chance to go out.
293	 * XXX 1ms is a lot, better to trigger scan
294	 * on tx complete.
295	 */
296	delay = hz/1000;
297	if (delay < 1)
298		delay = 1;
299	ic->ic_scan_start(ic);			/* notify driver */
300	ss->ss_scanend = ticks + delay + ss->ss_duration;
301	ss->ss_iflags |= ISCAN_START;
302	callout_reset(&ss->ss_scan_timer, delay, scan_next, ss);
303}
304
305/*
306 * Start/restart scanning.  If we're operating in station mode
307 * and associated notify the ap we're going into power save mode
308 * and schedule a callback to initiate the work (where there's a
309 * better context for doing the work).  Otherwise, start the scan
310 * directly.
311 */
312static int
313scan_restart(struct scan_state *ss, u_int duration)
314{
315	struct ieee80211com *ic = ss->base.ss_ic;
316	int defer = 0;
317
318	if (ss->base.ss_next == ss->base.ss_last) {
319		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
320			"%s: no channels to scan\n", __func__);
321		return 0;
322	}
323	if (ic->ic_opmode == IEEE80211_M_STA &&
324	    ic->ic_state == IEEE80211_S_RUN) {
325		if ((ic->ic_bss->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) {
326			/*
327			 * Initiate power save before going off-channel.
328			 * Note that we cannot do this directly because
329			 * of locking issues; instead we defer it to a
330			 * tasklet.
331			 */
332			ss->ss_duration = duration;
333			defer = 1;
334		}
335	}
336
337	if (!defer) {
338		ic->ic_scan_start(ic);		/* notify driver */
339		ss->ss_scanend = ticks + duration;
340		ss->ss_iflags |= ISCAN_START;
341		callout_reset(&ss->ss_scan_timer, 0, scan_next, ss);
342	} else
343		scan_restart_pwrsav(ss);
344	return 1;
345}
346
347static void
348copy_ssid(struct ieee80211com *ic, struct ieee80211_scan_state *ss,
349	int nssid, const struct ieee80211_scan_ssid ssids[])
350{
351	if (nssid > IEEE80211_SCAN_MAX_SSID) {
352		/* XXX printf */
353		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
354		    "%s: too many ssid %d, ignoring all of them\n",
355		    __func__, nssid);
356		return;
357	}
358	memcpy(ss->ss_ssid, ssids, nssid * sizeof(ssids[0]));
359	ss->ss_nssid = nssid;
360}
361
362/*
363 * Start a scan unless one is already going.
364 */
365int
366ieee80211_start_scan(struct ieee80211com *ic, int flags, u_int duration,
367	u_int nssid, const struct ieee80211_scan_ssid ssids[])
368{
369	const struct ieee80211_scanner *scan;
370	struct ieee80211_scan_state *ss = ic->ic_scan;
371
372	scan = ieee80211_scanner_get(ic->ic_opmode);
373	if (scan == NULL) {
374		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
375		    "%s: no scanner support for mode %u\n",
376		    __func__, ic->ic_opmode);
377		/* XXX stat */
378		return 0;
379	}
380
381	IEEE80211_LOCK(ic);
382	if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
383		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
384		    "%s: %s scan, duration %u, desired mode %s, %s%s%s%s\n"
385		    , __func__
386		    , flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive"
387		    , duration
388		    , ieee80211_phymode_name[ic->ic_des_mode]
389		    , flags & IEEE80211_SCAN_FLUSH ? "flush" : "append"
390		    , flags & IEEE80211_SCAN_NOPICK ? ", nopick" : ""
391		    , flags & IEEE80211_SCAN_PICK1ST ? ", pick1st" : ""
392		    , flags & IEEE80211_SCAN_ONCE ? ", once" : ""
393		);
394
395		ss->ss_ic = ic;
396		if (ss->ss_ops != scan) {
397			/* switch scanners; detach old, attach new */
398			if (ss->ss_ops != NULL)
399				ss->ss_ops->scan_detach(ss);
400			if (!scan->scan_attach(ss)) {
401				/* XXX attach failure */
402				/* XXX stat+msg */
403				ss->ss_ops = NULL;
404			} else
405				ss->ss_ops = scan;
406		}
407		if (ss->ss_ops != NULL) {
408			if ((flags & IEEE80211_SCAN_NOSSID) == 0)
409				copy_ssid(ic, ss, nssid, ssids);
410
411			/* NB: top 4 bits for internal use */
412			ss->ss_flags = flags & 0xfff;
413			if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
414				ic->ic_stats.is_scan_active++;
415			else
416				ic->ic_stats.is_scan_passive++;
417			if (flags & IEEE80211_SCAN_FLUSH)
418				ss->ss_ops->scan_flush(ss);
419
420			/* NB: flush frames rx'd before 1st channel change */
421			SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_DISCARD;
422			ss->ss_ops->scan_start(ss, ic);
423			if (scan_restart(SCAN_PRIVATE(ss), duration))
424				ic->ic_flags |= IEEE80211_F_SCAN;
425		}
426	} else {
427		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
428		    "%s: %s scan already in progress\n", __func__,
429		    ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive");
430	}
431	IEEE80211_UNLOCK(ic);
432
433	/* NB: racey, does it matter? */
434	return (ic->ic_flags & IEEE80211_F_SCAN);
435}
436
437/*
438 * Check the scan cache for an ap/channel to use; if that
439 * fails then kick off a new scan.
440 */
441int
442ieee80211_check_scan(struct ieee80211com *ic, int flags, u_int duration,
443	u_int nssid, const struct ieee80211_scan_ssid ssids[])
444{
445	struct ieee80211_scan_state *ss = ic->ic_scan;
446	int checkscanlist = 0;
447
448	/*
449	 * Check if there's a list of scan candidates already.
450	 * XXX want more than the ap we're currently associated with
451	 */
452
453	IEEE80211_LOCK(ic);
454	IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
455	    "%s: %s scan, duration %u, desired mode %s, %s%s%s%s\n"
456	    , __func__
457	    , flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive"
458	    , duration
459	    , ieee80211_phymode_name[ic->ic_des_mode]
460	    , flags & IEEE80211_SCAN_FLUSH ? "flush" : "append"
461	    , flags & IEEE80211_SCAN_NOPICK ? ", nopick" : ""
462	    , flags & IEEE80211_SCAN_PICK1ST ? ", pick1st" : ""
463	    , flags & IEEE80211_SCAN_ONCE ? ", once" : ""
464	);
465
466	if (ss->ss_ops != NULL) {
467		/* XXX verify ss_ops matches ic->ic_opmode */
468		if ((flags & IEEE80211_SCAN_NOSSID) == 0) {
469			/*
470			 * Update the ssid list and mark flags so if
471			 * we call start_scan it doesn't duplicate work.
472			 */
473			copy_ssid(ic, ss, nssid, ssids);
474			flags |= IEEE80211_SCAN_NOSSID;
475		}
476		if ((ic->ic_flags & IEEE80211_F_SCAN) == 0 &&
477		     time_before(ticks, ic->ic_lastscan + ic->ic_scanvalid)) {
478			/*
479			 * We're not currently scanning and the cache is
480			 * deemed hot enough to consult.  Lock out others
481			 * by marking IEEE80211_F_SCAN while we decide if
482			 * something is already in the scan cache we can
483			 * use.  Also discard any frames that might come
484			 * in while temporarily marked as scanning.
485			 */
486			SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_DISCARD;
487			ic->ic_flags |= IEEE80211_F_SCAN;
488			checkscanlist = 1;
489		}
490	}
491	IEEE80211_UNLOCK(ic);
492	if (checkscanlist) {
493		const struct ieee80211_scanner *scan;
494
495		scan = ieee80211_scanner_get(ic->ic_opmode);
496		if (scan == NULL) {
497			IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
498			    "%s: no scanner support for mode %u\n",
499			    __func__, ic->ic_opmode);
500			/* XXX stat */
501			return 0;
502		}
503		if (scan == ss->ss_ops && ss->ss_ops->scan_end(ss, ic)) {
504			/* found an ap, just clear the flag */
505			ic->ic_flags &= ~IEEE80211_F_SCAN;
506			return 1;
507		}
508		/* no ap, clear the flag before starting a scan */
509		ic->ic_flags &= ~IEEE80211_F_SCAN;
510	}
511	return ieee80211_start_scan(ic, flags, duration, nssid, ssids);
512}
513
514/*
515 * Restart a previous scan.  If the previous scan completed
516 * then we start again using the existing channel list.
517 */
518int
519ieee80211_bg_scan(struct ieee80211com *ic)
520{
521	struct ieee80211_scan_state *ss = ic->ic_scan;
522
523	IEEE80211_LOCK(ic);
524	if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
525		u_int duration;
526		/*
527		 * Go off-channel for a fixed interval that is large
528		 * enough to catch most ap's but short enough that
529		 * we can return on-channel before our listen interval
530		 * expires.
531		 */
532		duration = IEEE80211_SCAN_OFFCHANNEL;
533
534		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
535		    "%s: %s scan, ticks %u duration %lu\n", __func__,
536		    ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive",
537		    ticks, duration);
538
539		if (ss->ss_ops != NULL) {
540			ss->ss_ic = ic;
541			/*
542			 * A background scan does not select a new sta; it
543			 * just refreshes the scan cache.  Also, indicate
544			 * the scan logic should follow the beacon schedule:
545			 * we go off-channel and scan for a while, then
546			 * return to the bss channel to receive a beacon,
547			 * then go off-channel again.  All during this time
548			 * we notify the ap we're in power save mode.  When
549			 * the scan is complete we leave power save mode.
550			 * If any beacon indicates there are frames pending
551			 * for us then we drop out of power save mode
552			 * (and background scan) automatically by way of the
553			 * usual sta power save logic.
554			 */
555			ss->ss_flags |= IEEE80211_SCAN_NOPICK
556				     |  IEEE80211_SCAN_BGSCAN;
557			/* if previous scan completed, restart */
558			if (ss->ss_next >= ss->ss_last) {
559				ss->ss_next = 0;
560				if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
561					ic->ic_stats.is_scan_active++;
562				else
563					ic->ic_stats.is_scan_passive++;
564				ss->ss_ops->scan_restart(ss, ic);
565			}
566			/* NB: flush frames rx'd before 1st channel change */
567			SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_DISCARD;
568			ss->ss_maxdwell = duration;
569			if (scan_restart(SCAN_PRIVATE(ss), duration)) {
570				ic->ic_flags |= IEEE80211_F_SCAN;
571				ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN;
572			}
573		} else {
574			/* XXX msg+stat */
575		}
576	} else {
577		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
578		    "%s: %s scan already in progress\n", __func__,
579		    ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive");
580	}
581	IEEE80211_UNLOCK(ic);
582
583	/* NB: racey, does it matter? */
584	return (ic->ic_flags & IEEE80211_F_SCAN);
585}
586
587/*
588 * Cancel any scan currently going on.
589 */
590void
591ieee80211_cancel_scan(struct ieee80211com *ic)
592{
593	struct ieee80211_scan_state *ss = ic->ic_scan;
594
595	IEEE80211_LOCK(ic);
596	if ((ic->ic_flags & IEEE80211_F_SCAN) &&
597	    (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) == 0) {
598		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
599		    "%s: cancel %s scan\n", __func__,
600		    ss->ss_flags & IEEE80211_SCAN_ACTIVE ?
601			"active" : "passive");
602
603		/* clear bg scan NOPICK and mark cancel request */
604		ss->ss_flags &= ~IEEE80211_SCAN_NOPICK;
605		SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL;
606		/* force it to fire asap */
607		callout_reset(&SCAN_PRIVATE(ss)->ss_scan_timer,
608			0, scan_next, ss);
609	}
610	IEEE80211_UNLOCK(ic);
611}
612
613/*
614 * Public access to scan_next for drivers that manage
615 * scanning themselves (e.g. for firmware-based devices).
616 */
617void
618ieee80211_scan_next(struct ieee80211com *ic)
619{
620	/*
621	 * XXX: We might need/want to decouple context here by either:
622	 *  callout_reset(&SCAN_PRIVATE(ss)->ss_scan_timer, 0, scan_next, ss);
623	 * or using a taskqueue.  Let's see what kind of problems direct
624	 * dispatch has for now.
625	 */
626	scan_next(ic->ic_scan);
627}
628
629/*
630 * Scan curchan.  If this is an active scan and the channel
631 * is not marked passive then send probe request frame(s).
632 * Arrange for the channel change after maxdwell ticks.
633 */
634static void
635scan_curchan(struct ieee80211com *ic, unsigned long maxdwell)
636{
637	struct ieee80211_scan_state *ss = ic->ic_scan;
638
639	if ((ss->ss_flags & IEEE80211_SCAN_ACTIVE) &&
640	    (ic->ic_curchan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) {
641		struct ifnet *ifp = ic->ic_ifp;
642		int i;
643
644		/*
645		 * Send a broadcast probe request followed by
646		 * any specified directed probe requests.
647		 * XXX suppress broadcast probe req?
648		 * XXX remove dependence on ic/ic->ic_bss
649		 * XXX move to policy code?
650		 */
651		ieee80211_send_probereq(ic->ic_bss,
652			ic->ic_myaddr, ifp->if_broadcastaddr,
653			ifp->if_broadcastaddr,
654			"", 0,
655			ic->ic_opt_ie, ic->ic_opt_ie_len);
656		for (i = 0; i < ss->ss_nssid; i++)
657			ieee80211_send_probereq(ic->ic_bss,
658				ic->ic_myaddr, ifp->if_broadcastaddr,
659				ifp->if_broadcastaddr,
660				ss->ss_ssid[i].ssid,
661				ss->ss_ssid[i].len,
662				ic->ic_opt_ie, ic->ic_opt_ie_len);
663	}
664	callout_reset(&SCAN_PRIVATE(ss)->ss_scan_timer,
665		maxdwell, scan_next, ss);
666}
667
668/*
669 * Handle mindwell requirements completed; initiate a channel
670 * change to the next channel asap.
671 */
672static void
673scan_mindwell(struct ieee80211com *ic)
674{
675	struct ieee80211_scan_state *ss = ic->ic_scan;
676
677	callout_reset(&SCAN_PRIVATE(ss)->ss_scan_timer, 0, scan_next, ss);
678}
679
680/*
681 * Switch to the next channel marked for scanning.
682 */
683static void
684scan_next(void *arg)
685{
686#define	ISCAN_REP	(ISCAN_MINDWELL | ISCAN_START | ISCAN_DISCARD)
687	struct ieee80211_scan_state *ss = (struct ieee80211_scan_state *) arg;
688	struct ieee80211com *ic = ss->ss_ic;
689	struct ieee80211_channel *chan;
690	unsigned long maxdwell, scanend;
691	int scanning, scandone;
692
693	IEEE80211_LOCK(ic);
694	scanning = (ic->ic_flags & IEEE80211_F_SCAN) != 0;
695	IEEE80211_UNLOCK(ic);
696	if (!scanning)			/* canceled */
697		return;
698
699again:
700	scandone = (ss->ss_next >= ss->ss_last) ||
701		(SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) != 0;
702	scanend = SCAN_PRIVATE(ss)->ss_scanend;
703	if (!scandone &&
704	    (ss->ss_flags & IEEE80211_SCAN_GOTPICK) == 0 &&
705	    ((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_START) ||
706	     time_before(ticks + ss->ss_mindwell, scanend))) {
707		chan = ss->ss_chans[ss->ss_next++];
708
709		/*
710		 * Watch for truncation due to the scan end time.
711		 */
712		if (time_after(ticks + ss->ss_maxdwell, scanend))
713			maxdwell = scanend - ticks;
714		else
715			maxdwell = ss->ss_maxdwell;
716
717		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
718		    "%s: chan %3d%c -> %3d%c [%s, dwell min %lu max %lu]\n",
719		    __func__,
720		    ieee80211_chan2ieee(ic, ic->ic_curchan),
721		        channel_type(ic->ic_curchan),
722		    ieee80211_chan2ieee(ic, chan), channel_type(chan),
723		    (ss->ss_flags & IEEE80211_SCAN_ACTIVE) &&
724			(chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0 ?
725			"active" : "passive",
726		    ss->ss_mindwell, maxdwell);
727
728		/*
729		 * Potentially change channel and phy mode.
730		 */
731		change_channel(ic, chan);
732
733		/*
734		 * Scan curchan.  Drivers for "intelligent hardware"
735		 * override ic_scan_curchan to tell the device to do
736		 * the work.  Otherwise we manage the work outselves;
737		 * sending a probe request (as needed), and arming the
738		 * timeout to switch channels after maxdwell ticks.
739		 */
740		ic->ic_scan_curchan(ic, maxdwell);
741
742		SCAN_PRIVATE(ss)->ss_chanmindwell = ticks + ss->ss_mindwell;
743		/* clear mindwell lock and initial channel change flush */
744		SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_REP;
745	} else {
746		ic->ic_scan_end(ic);		/* notify driver */
747		/*
748		 * Record scan complete time.  Note that we also do
749		 * this when canceled so any background scan will
750		 * not be restarted for a while.
751		 */
752		if (scandone)
753			ic->ic_lastscan = ticks;
754		/* return to the bss channel */
755		if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
756		    ic->ic_curchan != ic->ic_bsschan)
757			change_channel(ic, ic->ic_bsschan);
758		/* clear internal flags and any indication of a pick */
759		SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_REP;
760		ss->ss_flags &= ~IEEE80211_SCAN_GOTPICK;
761
762		/*
763		 * If not canceled and scan completed, do post-processing.
764		 * If the callback function returns 0, then it wants to
765		 * continue/restart scanning.  Unfortunately we needed to
766		 * notify the driver to end the scan above to avoid having
767		 * rx frames alter the scan candidate list.
768		 */
769		if ((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) == 0 &&
770		    !ss->ss_ops->scan_end(ss, ic) &&
771		    (ss->ss_flags & IEEE80211_SCAN_ONCE) == 0 &&
772		    time_before(ticks + ss->ss_mindwell, scanend)) {
773			IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
774			    "%s: done, restart "
775			    "[ticks %u, dwell min %lu scanend %lu]\n",
776			    __func__,
777			    ticks, ss->ss_mindwell, scanend);
778			ss->ss_next = 0;	/* reset to begining */
779			if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
780				ic->ic_stats.is_scan_active++;
781			else
782				ic->ic_stats.is_scan_passive++;
783
784			ic->ic_scan_start(ic);	/* notify driver */
785			goto again;
786		} else {
787			/* past here, scandone is ``true'' if not in bg mode */
788			if ((ss->ss_flags & IEEE80211_SCAN_BGSCAN) == 0)
789				scandone = 1;
790
791			IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
792			    "%s: %s, "
793			    "[ticks %u, dwell min %lu scanend %lu]\n",
794			    __func__, scandone ? "done" : "stopped",
795			    ticks, ss->ss_mindwell, scanend);
796
797			/*
798			 * Clear the SCAN bit first in case frames are
799			 * pending on the station power save queue.  If
800			 * we defer this then the dispatch of the frames
801			 * may generate a request to cancel scanning.
802			 */
803			ic->ic_flags &= ~IEEE80211_F_SCAN;
804			/*
805			 * Drop out of power save mode when a scan has
806			 * completed.  If this scan was prematurely terminated
807			 * because it is a background scan then don't notify
808			 * the ap; we'll either return to scanning after we
809			 * receive the beacon frame or we'll drop out of power
810			 * save mode because the beacon indicates we have frames
811			 * waiting for us.
812			 */
813			if (scandone) {
814				ieee80211_sta_pwrsave(ic, 0);
815				if (ss->ss_next >= ss->ss_last) {
816					ieee80211_notify_scan_done(ic);
817					ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN;
818				}
819			}
820			SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_CANCEL;
821			ss->ss_flags &=
822			    ~(IEEE80211_SCAN_ONCE | IEEE80211_SCAN_PICK1ST);
823		}
824	}
825#undef ISCAN_REP
826}
827
828#ifdef IEEE80211_DEBUG
829static void
830dump_probe_beacon(uint8_t subtype, int isnew,
831	const uint8_t mac[IEEE80211_ADDR_LEN],
832	const struct ieee80211_scanparams *sp)
833{
834
835	printf("[%s] %s%s on chan %u (bss chan %u) ",
836	    ether_sprintf(mac), isnew ? "new " : "",
837	    ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT],
838	    IEEE80211_CHAN2IEEE(sp->curchan), sp->bchan);
839	ieee80211_print_essid(sp->ssid + 2, sp->ssid[1]);
840	printf("\n");
841
842	if (isnew) {
843		printf("[%s] caps 0x%x bintval %u erp 0x%x",
844			ether_sprintf(mac), sp->capinfo, sp->bintval, sp->erp);
845		if (sp->country != NULL) {
846#ifdef __FreeBSD__
847			printf(" country info %*D",
848				sp->country[1], sp->country+2, " ");
849#else
850			int i;
851			printf(" country info");
852			for (i = 0; i < sp->country[1]; i++)
853				printf(" %02x", sp->country[i+2]);
854#endif
855		}
856		printf("\n");
857	}
858}
859#endif /* IEEE80211_DEBUG */
860
861/*
862 * Process a beacon or probe response frame.
863 */
864void
865ieee80211_add_scan(struct ieee80211com *ic,
866	const struct ieee80211_scanparams *sp,
867	const struct ieee80211_frame *wh,
868	int subtype, int rssi, int noise, int rstamp)
869{
870	struct ieee80211_scan_state *ss = ic->ic_scan;
871
872	/*
873	 * Frames received during startup are discarded to avoid
874	 * using scan state setup on the initial entry to the timer
875	 * callback.  This can occur because the device may enable
876	 * rx prior to our doing the initial channel change in the
877	 * timer routine (we defer the channel change to the timer
878	 * code to simplify locking on linux).
879	 */
880	if (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_DISCARD)
881		return;
882#ifdef IEEE80211_DEBUG
883	if (ieee80211_msg_scan(ic) && (ic->ic_flags & IEEE80211_F_SCAN))
884		dump_probe_beacon(subtype, 1, wh->i_addr2, sp);
885#endif
886	if (ss->ss_ops != NULL &&
887	    ss->ss_ops->scan_add(ss, sp, wh, subtype, rssi, noise, rstamp)) {
888		/*
889		 * If we've reached the min dwell time terminate
890		 * the timer so we'll switch to the next channel.
891		 */
892		if ((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_MINDWELL) == 0 &&
893		    time_after_eq(ticks, SCAN_PRIVATE(ss)->ss_chanmindwell)) {
894			IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
895			    "%s: chan %3d%c min dwell met (%u > %lu)\n",
896			    __func__,
897			    ieee80211_chan2ieee(ic, ic->ic_curchan),
898				channel_type(ic->ic_curchan),
899			    ticks, SCAN_PRIVATE(ss)->ss_chanmindwell);
900			/*
901			 * XXX
902			 * We want to just kick the timer and still
903			 * process frames until it fires but linux
904			 * will livelock unless we discard frames.
905			 */
906#if 0
907			SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_MINDWELL;
908#else
909			SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_DISCARD;
910#endif
911			/*
912			 * NB: trigger at next clock tick or wait for the
913			 * hardware
914			 */
915			ic->ic_scan_mindwell(ic);
916		}
917	}
918}
919
920/*
921 * Timeout/age scan cache entries; called from sta timeout
922 * timer (XXX should be self-contained).
923 */
924void
925ieee80211_scan_timeout(struct ieee80211com *ic)
926{
927	struct ieee80211_scan_state *ss = ic->ic_scan;
928
929	if (ss->ss_ops != NULL)
930		ss->ss_ops->scan_age(ss);
931}
932
933/*
934 * Mark a scan cache entry after a successful associate.
935 */
936void
937ieee80211_scan_assoc_success(struct ieee80211com *ic, const uint8_t mac[])
938{
939	struct ieee80211_scan_state *ss = ic->ic_scan;
940
941	if (ss->ss_ops != NULL) {
942		IEEE80211_NOTE_MAC(ic, IEEE80211_MSG_SCAN,
943			mac, "%s",  __func__);
944		ss->ss_ops->scan_assoc_success(ss, mac);
945	}
946}
947
948/*
949 * Demerit a scan cache entry after failing to associate.
950 */
951void
952ieee80211_scan_assoc_fail(struct ieee80211com *ic,
953	const uint8_t mac[], int reason)
954{
955	struct ieee80211_scan_state *ss = ic->ic_scan;
956
957	if (ss->ss_ops != NULL) {
958		IEEE80211_NOTE_MAC(ic, IEEE80211_MSG_SCAN, mac,
959			"%s: reason %u", __func__, reason);
960		ss->ss_ops->scan_assoc_fail(ss, mac, reason);
961	}
962}
963
964/*
965 * Iterate over the contents of the scan cache.
966 */
967void
968ieee80211_scan_iterate(struct ieee80211com *ic,
969	ieee80211_scan_iter_func *f, void *arg)
970{
971	struct ieee80211_scan_state *ss = ic->ic_scan;
972
973	if (ss->ss_ops != NULL)
974		ss->ss_ops->scan_iterate(ss, f, arg);
975}
976
977/*
978 * Flush the contents of the scan cache.
979 */
980void
981ieee80211_scan_flush(struct ieee80211com *ic)
982{
983	struct ieee80211_scan_state *ss = ic->ic_scan;
984
985	if (ss->ss_ops != NULL) {
986		IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
987			"%s\n",  __func__);
988		ss->ss_ops->scan_flush(ss);
989	}
990}
991