update madwifi
[linux-2.6/zen-sources.git] / drivers / net / wireless / madwifi / net80211 / ieee80211_scan_ap.c
blob2e1aaf30fb6dbb93c9e80a3e70f9f987964e2adf
1 /*-
2 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
3 * Copyright (c) 2005 Matt Mackall <mpm@selenic.com>
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU General Public License ("GPL") version 2 as published by the Free
19 * Software Foundation.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * $Id: ieee80211_scan_ap.c 3627 2008-05-14 19:11:57Z mentor $
34 #ifndef EXPORT_SYMTAB
35 #define EXPORT_SYMTAB
36 #endif
39 * IEEE 802.11 ap scanning support.
41 #ifndef AUTOCONF_INCLUDED
42 #include <linux/config.h>
43 #endif
44 #include <linux/version.h>
45 #include <linux/module.h>
46 #include <linux/skbuff.h>
47 #include <linux/netdevice.h>
48 #include <linux/init.h>
49 #include <linux/delay.h>
51 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
52 /* Copied from Linux lib/sort.c */
53 static void u32_swap(void *a, void *b, int size)
55 u32 t = *(u32 *)a;
56 *(u32 *)a = *(u32 *)b;
57 *(u32 *)b = t;
60 static void generic_swap(void *a, void *b, int size)
62 char t;
64 do {
65 t = *(char *)a;
66 *(char *)a++ = *(char *)b;
67 *(char *)b++ = t;
68 } while (--size > 0);
71 /**
72 * sort - sort an array of elements
73 * @base: pointer to data to sort
74 * @num: number of elements
75 * @size: size of each element
76 * @cmp: pointer to comparison function
77 * @swap: pointer to swap function or NULL
79 * This function does a heapsort on the given array. You may provide a
80 * swap function optimized to your element type.
82 * Sorting time is O(n log n) both on average and worst-case. While
83 * qsort is about 20% faster on average, it suffers from exploitable
84 * O(n*n) worst-case behavior and extra memory requirements that make
85 * it less suitable for kernel use.
88 void sort(void *base, size_t num, size_t size,
89 int (*cmp)(const void *, const void *),
90 void (*swap)(void *, void *, int size))
92 /* pre-scale counters for performance */
93 int i = (num/2 - 1) * size, n = num * size, c, r;
95 if (!swap)
96 swap = (size == 4 ? u32_swap : generic_swap);
98 /* heapify */
99 for ( ; i >= 0; i -= size) {
100 for (r = i; r * 2 + size < n; r = c) {
101 c = r * 2 + size;
102 if (c < n - size && cmp(base + c, base + c + size) < 0)
103 c += size;
104 if (cmp(base + r, base + c) >= 0)
105 break;
106 swap(base + r, base + c, size);
110 /* sort */
111 for (i = n - size; i > 0; i -= size) {
112 swap(base, base + i, size);
113 for (r = 0; r * 2 + size < i; r = c) {
114 c = r * 2 + size;
115 if (c < i - size && cmp(base + c, base + c + size) < 0)
116 c += size;
117 if (cmp(base + r, base + c) >= 0)
118 break;
119 swap(base + r, base + c, size);
123 #else
124 #include <linux/sort.h>
125 #endif
127 #include "if_media.h"
129 #include <net80211/ieee80211_var.h>
131 #define AP_PURGE_SCANS 2 /* age for purging entries (scans) */
132 #define RSSI_LPF_LEN 10
133 #define RSSI_EP_MULTIPLIER (1 << 7) /* pow2 to optimize out * and / */
134 #define RSSI_IN(x) ((x) * RSSI_EP_MULTIPLIER)
135 #define LPF_RSSI(x, y, len) (((x) * ((len) - 1) + (y)) / (len))
136 #define RSSI_LPF(x, y) do { \
137 if ((y) >= -20) \
138 x = LPF_RSSI((x), RSSI_IN((y)), RSSI_LPF_LEN); \
139 } while (0)
140 #define EP_RND(x, mul) \
141 ((((x)%(mul)) >= ((mul)/2)) ? howmany(x, mul) : (x)/(mul))
142 #define RSSI_GET(x) EP_RND(x, RSSI_EP_MULTIPLIER)
143 #define AP_HASHSIZE 32
144 /* simple hash is enough for variation of macaddr */
145 #define AP_HASH(addr) \
146 (((const u_int8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % AP_HASHSIZE)
147 #define SCAN_AP_LOCK_INIT(_st, _name) \
148 spin_lock_init(&(_st)->as_lock)
149 #define SCAN_AP_LOCK_DESTROY(_st)
150 #define SCAN_AP_LOCK_IRQ(_st) do { \
151 unsigned long __stlockflags; \
152 spin_lock_irqsave(&(_st)->as_lock, __stlockflags);
153 #define SCAN_AP_UNLOCK_IRQ(_st) \
154 spin_unlock_irqrestore(&(_st)->as_lock, __stlockflags); \
155 } while (0)
156 #define SCAN_AP_UNLOCK_IRQ_EARLY(_st) \
157 spin_unlock_irqrestore(&(_st)->as_lock, __stlockflags);
159 #define SCAN_AP_GEN_LOCK_INIT(_st, _name) \
160 spin_lock_init(&(_st)->as_scanlock)
161 #define SCAN_AP_GEN_LOCK_DESTROY(_st)
162 #define SCAN_AP_GEN_LOCK(_st) spin_lock(&(_st)->as_scanlock);
163 #define SCAN_AP_GEN_UNLOCK(_st) spin_unlock(&(_st)->as_scanlock);
165 struct scan_entry {
166 struct ieee80211_scan_entry base;
167 TAILQ_ENTRY(scan_entry) se_list;
168 LIST_ENTRY(scan_entry) se_hash;
169 u_int8_t se_seen; /* seen during current scan */
170 u_int8_t se_notseen; /* not seen in previous scans */
171 u_int32_t se_avgrssi; /* LPF rssi state */
172 unsigned long se_lastupdate; /* time of last update */
173 unsigned long se_lastfail; /* time of last failure */
174 unsigned long se_lastassoc; /* time of last association */
175 u_int se_scangen; /* iterator scan gen# */
178 struct ap_state {
179 unsigned int as_vap_desired_mode; /* Used for channel selection,
180 * vap->iv_des_mode */
181 unsigned int as_required_mode; /* Used for channel selection,
182 * filtered version of
183 * as_vap_desired_mode */
184 int as_maxrssi[IEEE80211_CHAN_MAX]; /* Used for channel selection */
186 /* These fields are just for scan caching for returning responses to
187 * wireless extensions. i.e. show peers, APs, etc. */
188 spinlock_t as_lock; /* on scan table */
189 int as_newscan; /* trigger for updating
190 * seen/not-seen for aging */
191 TAILQ_HEAD(, scan_entry) as_entry; /* all entries */
192 ATH_LIST_HEAD(, scan_entry) as_hash[AP_HASHSIZE];
193 spinlock_t as_scanlock; /* on as_scangen */
194 u_int as_scangen; /* gen# for iterator */
196 struct IEEE80211_TQ_STRUCT as_actiontq; /* tasklet for "action" */
197 struct ieee80211_scan_entry as_selbss; /* selected bss for action tasklet */
198 int (*as_action)(struct ieee80211vap *, const struct ieee80211_scan_entry *);
201 static int ap_flush(struct ieee80211_scan_state *);
202 static void action_tasklet(IEEE80211_TQUEUE_ARG);
203 static struct ieee80211_channel *find11gchannel(struct ieee80211com *ic,
204 int i, int freq);
206 static const u_int chanflags[] = {
207 IEEE80211_CHAN_B, /* IEEE80211_MODE_AUTO */
208 IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */
209 IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */
210 IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */
211 IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */
212 IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode
213 * look for AP in
214 * normal channel
216 IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */
217 IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */
220 static const u_int16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64,
221 * 36, 40, 44, 48 */
222 { 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 };
223 static const u_int16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */
224 { 5170, 5190, 5210, 5230 };
225 static const u_int16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */
226 { 2412, 2437, 2462, 2442, 2472 };
227 static const u_int16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */
228 { 5745, 5765, 5785, 5805, 5825 };
229 static const u_int16_t rcl7[] = /* 11 ETSI channel: 100, 104, 108, 112,
230 * 116, 120, 124, 128,
231 * 132, 136, 140 */
232 { 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 };
233 static const u_int16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */
234 { 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 };
235 static const u_int16_t rcl9[] = /* 2.4Ghz ch: 14 */
236 { 2484 };
237 static const u_int16_t rcl10[] = /* Added Korean channels 2312-2372 */
238 { 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 };
239 static const u_int16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */
240 { 5040, 5060, 5080, 4920, 4940, 4960, 4980 };
241 #ifdef ATH_TURBO_SCAN
242 static const u_int16_t rcl5[] = /* 3 static turbo channels */
243 { 5210, 5250, 5290 };
244 static const u_int16_t rcl6[] = /* 2 static turbo channels */
245 { 5760, 5800 };
246 static const u_int16_t rcl6x[] = /* 4 FCC3 turbo channels */
247 { 5540, 5580, 5620, 5660 };
248 static const u_int16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */
249 { 2437 };
250 static const u_int16_t rcl13[] = /* dynamic Turbo channels */
251 { 5200, 5240, 5280, 5765, 5805 };
252 #endif /* ATH_TURBO_SCAN */
254 struct scanlist {
255 u_int16_t mode;
256 u_int16_t count;
257 const u_int16_t *list;
260 #define IEEE80211_MODE_TURBO_STATIC_A IEEE80211_MODE_MAX
261 #define X(a) .count = ARRAY_SIZE(a), .list = a
263 static const struct scanlist staScanTable[] = {
264 { IEEE80211_MODE_11B, X(rcl3) },
265 { IEEE80211_MODE_11A, X(rcl1) },
266 { IEEE80211_MODE_11A, X(rcl2) },
267 { IEEE80211_MODE_11B, X(rcl8) },
268 { IEEE80211_MODE_11B, X(rcl9) },
269 { IEEE80211_MODE_11A, X(rcl4) },
270 #ifdef ATH_TURBO_SCAN
271 { IEEE80211_MODE_TURBO_STATIC_A, X(rcl5) },
272 { IEEE80211_MODE_TURBO_STATIC_A, X(rcl6) },
273 { IEEE80211_MODE_TURBO_A, X(rcl6x) },
274 { IEEE80211_MODE_TURBO_A, X(rcl13) },
275 #endif /* ATH_TURBO_SCAN */
276 { IEEE80211_MODE_11A, X(rcl7) },
277 { IEEE80211_MODE_11B, X(rcl10) },
278 { IEEE80211_MODE_11A, X(rcl11) },
279 #ifdef ATH_TURBO_SCAN
280 { IEEE80211_MODE_TURBO_G, X(rcl12) },
281 #endif /* ATH_TURBO_SCAN */
282 { .list = NULL }
285 #undef X
286 /* This function must be invoked with locks acquired */
287 static void
288 add_channels(struct ieee80211com *ic,
289 struct ieee80211_scan_state *ss,
290 enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq)
292 struct ieee80211_channel *c, *cg;
293 u_int modeflags;
294 int i;
296 KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode));
297 modeflags = chanflags[mode];
298 for (i = 0; i < nfreq; i++) {
299 c = ieee80211_find_channel(ic, freq[i], modeflags);
300 if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee))
301 continue;
302 if (mode == IEEE80211_MODE_AUTO) {
303 /* XXX special-case 11b/g channels so we select
304 * the g channel if both are present. */
305 if (IEEE80211_IS_CHAN_B(c) &&
306 (cg = find11gchannel(ic, i, c->ic_freq)) != NULL)
307 c = cg;
309 if (ss->ss_last >= IEEE80211_SCAN_MAX)
310 break;
311 ss->ss_chans[ss->ss_last++] = c;
315 /* This function must be invoked with locks acquired */
316 static int
317 checktable(const struct scanlist *scan, const struct ieee80211_channel *c)
319 int i;
321 for (; scan->list != NULL; scan++) {
322 for (i = 0; i < scan->count; i++)
323 if (scan->list[i] == c->ic_freq)
324 return 1;
326 return 0;
330 * Attach prior to any scanning work.
332 static int
333 ap_attach(struct ieee80211_scan_state *ss)
335 struct ap_state *as;
337 _MOD_INC_USE(THIS_MODULE, return 0);
339 MALLOC(as, struct ap_state *, sizeof(struct ap_state),
340 M_80211_SCAN, M_NOWAIT | M_ZERO);
341 if (as == NULL)
342 return 0;
343 SCAN_AP_LOCK_INIT(as, "scan_ap");
344 SCAN_AP_GEN_LOCK_INIT(as, "scan_ap_gen");
345 TAILQ_INIT(&as->as_entry);
346 IEEE80211_INIT_TQUEUE(&as->as_actiontq, action_tasklet, ss);
347 ss->ss_priv = as;
348 ap_flush(ss);
349 return 1;
353 * Cleanup any private state.
355 static int
356 ap_detach(struct ieee80211_scan_state *ss)
358 struct ap_state *as = ss->ss_priv;
360 if (as != NULL) {
361 ap_flush(ss);
362 IEEE80211_CANCEL_TQUEUE(&as->as_actiontq);
363 FREE(as, M_80211_SCAN);
366 _MOD_DEC_USE(THIS_MODULE);
367 return 1;
371 * Flush all per-scan state.
373 static int
374 ap_flush(struct ieee80211_scan_state *ss)
376 struct ap_state *as = ss->ss_priv;
377 struct scan_entry *se, *next;
379 SCAN_AP_LOCK_IRQ(as);
380 memset(as->as_maxrssi, 0, sizeof(as->as_maxrssi));
381 TAILQ_FOREACH_SAFE(se, &as->as_entry, se_list, next) {
382 TAILQ_REMOVE(&as->as_entry, se, se_list);
383 LIST_REMOVE(se, se_hash);
384 FREE(se, M_80211_SCAN);
386 ss->ss_last = 0; /* ensure no channel will be picked */
387 SCAN_AP_UNLOCK_IRQ(as);
388 return 0;
391 /* This function must be invoked with locks acquired */
392 static void
393 saveie(u_int8_t **iep, const u_int8_t *ie)
395 if (ie == NULL)
396 *iep = NULL;
397 else
398 ieee80211_saveie(iep, ie);
401 /* This function must be invoked with locks acquired */
402 static struct ieee80211_channel *
403 find11gchannel(struct ieee80211com *ic, int i, int freq)
405 struct ieee80211_channel *c;
406 int j;
408 /* The normal ordering in the channel list is b channel
409 * immediately followed by g so optimize the search for
410 * this. We'll still do a full search just in case. */
411 for (j = i + 1; j < ic->ic_nchans; j++) {
412 c = &ic->ic_channels[j];
413 if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c))
414 return c;
416 for (j = 0; j < i; j++) {
417 c = &ic->ic_channels[j];
418 if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c))
419 return c;
421 return NULL;
425 * Start an ap scan by populating the channel list.
427 static int
428 ap_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
430 struct ap_state *as = ss->ss_priv;
431 struct ieee80211com *ic = NULL;
432 const struct scanlist *sl = NULL;
433 struct ieee80211_channel *c = NULL;
434 int i;
435 unsigned int mode = 0;
437 SCAN_AP_LOCK_IRQ(as);
438 ic = vap->iv_ic;
439 /* Determine mode flags to match, or leave zero for auto mode */
440 as->as_vap_desired_mode = vap->iv_des_mode;
441 as->as_required_mode = 0;
442 if (as->as_vap_desired_mode != IEEE80211_MODE_AUTO) {
443 as->as_required_mode = chanflags[as->as_vap_desired_mode];
444 if ((vap->iv_ath_cap & IEEE80211_ATHC_TURBOP) &&
445 (as->as_required_mode != IEEE80211_CHAN_ST)) {
446 /* Fixup for dynamic turbo flags */
447 if (as->as_vap_desired_mode == IEEE80211_MODE_11G)
448 as->as_required_mode = IEEE80211_CHAN_108G;
449 else
450 as->as_required_mode = IEEE80211_CHAN_108A;
454 ss->ss_last = 0;
455 /* Use the table of ordered channels to construct the list
456 * of channels for scanning. Any channels in the ordered
457 * list not in the master list will be discarded. */
458 for (sl = staScanTable; sl->list != NULL; sl++) {
459 mode = sl->mode;
461 /* The scan table marks 2.4Ghz channels as b
462 * so if the desired mode is 11g, then use
463 * the 11b channel list but upgrade the mode. */
464 if (as->as_vap_desired_mode &&
465 (as->as_vap_desired_mode != mode) &&
466 (as->as_vap_desired_mode == IEEE80211_MODE_11G) &&
467 (mode == IEEE80211_MODE_11B))
468 mode = IEEE80211_MODE_11G;
470 /* If we are in "AUTO" mode, upgrade the mode to auto.
471 * This lets add_channels upgrade an 11b channel to
472 * 11g if available. */
473 if (!as->as_vap_desired_mode && (mode == IEEE80211_MODE_11B))
474 mode = IEEE80211_MODE_AUTO;
476 /* Add the list of the channels; any that are not
477 * in the master channel list will be discarded. */
478 add_channels(ic, ss, mode, sl->list, sl->count);
481 /* Add the channels from the ic (from HAL) that are not present
482 * in the staScanTable, assuming they pass the sanity checks... */
483 for (i = 0; i < ic->ic_nchans; i++) {
484 c = &ic->ic_channels[i];
486 /* XR is not supported on turbo channels */
487 if (IEEE80211_IS_CHAN_TURBO(c) && vap->iv_flags & IEEE80211_F_XR)
488 continue;
490 /* Dynamic channels are scanned in base mode */
491 if (!as->as_required_mode && !IEEE80211_IS_CHAN_ST(c))
492 continue;
494 /* Use any 11g channel instead of 11b one. */
495 if (vap->iv_des_mode == IEEE80211_MODE_AUTO &&
496 IEEE80211_IS_CHAN_B(c) &&
497 find11gchannel(ic, i, c->ic_freq))
498 continue;
500 /* Do not add channels already put into the scan list by the
501 * scan table - these have already been filtered by mode
502 * and for whether they are in the active channel list. */
503 if (checktable(staScanTable, c))
504 continue;
506 /* Make sure the channel is active */
507 if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee))
508 continue;
510 /* Don't overrun */
511 if (ss->ss_last >= IEEE80211_SCAN_MAX)
512 break;
514 ss->ss_chans[ss->ss_last++] = c;
516 ss->ss_next = 0;
517 /* XXX tunables */
518 ss->ss_mindwell = msecs_to_jiffies(200); /* 200ms */
519 ss->ss_maxdwell = msecs_to_jiffies(300); /* 300ms */
521 #ifdef IEEE80211_DEBUG
522 if (ieee80211_msg_scan(vap)) {
523 printk("%s: scan set ", vap->iv_dev->name);
524 ieee80211_scan_dump_channels(ss);
525 printk(" dwell min %ld max %ld\n",
526 ss->ss_mindwell, ss->ss_maxdwell);
528 #endif /* IEEE80211_DEBUG */
530 as->as_newscan = 1;
531 SCAN_AP_UNLOCK_IRQ(as);
532 return 0;
536 * Restart a bg scan.
538 static int
539 ap_restart(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
541 struct ap_state *as = ss->ss_priv;
542 as->as_newscan = 1;
543 return 0;
547 * Cancel an ongoing scan.
549 static int
550 ap_cancel(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
552 struct ap_state *as = ss->ss_priv;
553 IEEE80211_CANCEL_TQUEUE(&as->as_actiontq);
554 return 0;
558 * Record max rssi on channel.
560 static int
561 ap_add(struct ieee80211_scan_state *ss, const struct ieee80211_scanparams *sp,
562 const struct ieee80211_frame *wh, int subtype, int rssi, u_int64_t rtsf)
564 struct ap_state *as = ss->ss_priv;
565 const u_int8_t *macaddr = wh->i_addr2;
566 struct ieee80211vap *vap = ss->ss_vap;
567 struct ieee80211com *ic = vap->iv_ic;
568 struct scan_entry *se = NULL;
569 struct ieee80211_scan_entry *ise = NULL;
570 int hash = AP_HASH(macaddr);
571 int chan;
573 /* This section provides scan results to wireless extensions */
574 SCAN_AP_LOCK_IRQ(as);
576 chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
577 /* This is the only information used for channel selection by AP */
578 if (rssi > as->as_maxrssi[chan])
579 as->as_maxrssi[chan] = rssi;
580 LIST_FOREACH(se, &as->as_hash[hash], se_hash)
581 if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr) &&
582 (sp->ssid[1] == se->base.se_ssid[1]) &&
583 !memcmp(se->base.se_ssid + 2, sp->ssid + 2,
584 se->base.se_ssid[1]))
585 goto found;
587 MALLOC(se, struct scan_entry *, sizeof(struct scan_entry),
588 M_80211_SCAN, M_NOWAIT | M_ZERO);
590 if (se == NULL) {
591 SCAN_AP_UNLOCK_IRQ_EARLY(as);
592 return 0;
595 se->se_scangen = as->as_scangen-1;
596 IEEE80211_ADDR_COPY(se->base.se_macaddr, macaddr);
597 TAILQ_INSERT_TAIL(&as->as_entry, se, se_list);
598 LIST_INSERT_HEAD(&as->as_hash[hash], se, se_hash);
600 found:
601 ise = &se->base;
603 /* XXX: AP beaconing multiple SSID w/ same BSSID */
604 if ((sp->ssid[1] != 0) &&
605 ((subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) ||
606 (ise->se_ssid[1] == 0)))
607 memcpy(ise->se_ssid, sp->ssid, 2 + sp->ssid[1]);
609 memcpy(ise->se_rates, sp->rates,
610 IEEE80211_SANITISE_RATESIZE(2 + sp->rates[1]));
611 if (sp->xrates != NULL) {
612 memcpy(ise->se_xrates, sp->xrates,
613 IEEE80211_SANITISE_RATESIZE(2 + sp->xrates[1]));
614 } else
615 ise->se_xrates[1] = 0;
617 IEEE80211_ADDR_COPY(ise->se_bssid, wh->i_addr3);
619 /* Record RSSI data using extended precision LPF filter.*/
620 if (se->se_lastupdate == 0) /* First sample */
621 se->se_avgrssi = RSSI_IN(rssi);
622 else /* Avg. w/ previous samples */
623 RSSI_LPF(se->se_avgrssi, rssi);
624 se->base.se_rssi = RSSI_GET(se->se_avgrssi);
626 ise->se_rtsf = rtsf;
627 memcpy(ise->se_tstamp.data, sp->tstamp, sizeof(ise->se_tstamp));
628 ise->se_intval = sp->bintval;
629 ise->se_capinfo = sp->capinfo;
630 ise->se_chan = ic->ic_curchan;
631 ise->se_fhdwell = sp->fhdwell;
632 ise->se_fhindex = sp->fhindex;
633 ise->se_erp = sp->erp;
634 ise->se_timoff = sp->timoff;
636 if (sp->tim != NULL) {
637 const struct ieee80211_tim_ie *tim =
638 (const struct ieee80211_tim_ie *)sp->tim;
639 ise->se_dtimperiod = tim->tim_period;
642 saveie(&ise->se_wme_ie, sp->wme);
643 saveie(&ise->se_wpa_ie, sp->wpa);
644 saveie(&ise->se_rsn_ie, sp->rsn);
645 saveie(&ise->se_ath_ie, sp->ath);
647 se->se_lastupdate = jiffies; /* update time */
648 se->se_seen = 1;
649 se->se_notseen = 0;
651 SCAN_AP_UNLOCK_IRQ(as);
653 return 1;
656 struct pc_params {
657 struct ieee80211vap *vap;
658 struct ieee80211_scan_state *ss;
659 int flags;
662 struct channel {
663 struct ieee80211_channel *chan;
664 int orig;
665 struct pc_params *params;
668 /* This function must be invoked with locks acquired */
669 static int
670 pc_cmp_radar(struct ieee80211_channel *a, struct ieee80211_channel *b)
672 /* a is better than b (return < 0) when b is marked while a is not */
673 return !!IEEE80211_IS_CHAN_RADAR(a) - !!IEEE80211_IS_CHAN_RADAR(b);
676 /* This function must be invoked with locks acquired */
677 static int
678 pc_cmp_keepmode(struct pc_params *params, struct ieee80211_channel *a,
679 struct ieee80211_channel *b)
681 struct ieee80211com *ic = params->vap->iv_ic;
682 struct ieee80211_channel *cur = ic->ic_bsschan;
684 if (!(params->flags & IEEE80211_SCAN_KEEPMODE))
685 return 0;
687 /* a is better than b (return < 0) when (a, cur) have the same mode
688 * and (b, cur) do not. */
689 return
690 !!IEEE80211_ARE_CHANS_SAME_MODE(b, cur) -
691 !!IEEE80211_ARE_CHANS_SAME_MODE(a, cur);
694 /* This function must be invoked with locks acquired */
695 static int
696 pc_cmp_sc(struct ieee80211com *ic, struct ieee80211_channel *a,
697 struct ieee80211_channel *b)
699 /* a is better than b (return < 0) when a has more chan nodes than b */
700 return
701 ic->ic_chan_nodes[b->ic_ieee] -
702 ic->ic_chan_nodes[a->ic_ieee];
705 /* This function must be invoked with locks acquired */
706 static int
707 pc_cmp_rssi(struct ap_state *as, struct ieee80211_channel *a,
708 struct ieee80211_channel *b)
710 /* a is better than b (return < 0) when a has rssi less than b */
711 return
712 as->as_maxrssi[a->ic_ieee] -
713 as->as_maxrssi[b->ic_ieee];
716 /* This function must be invoked with locks acquired */
717 static int
718 pc_cmp_samechan(struct ieee80211com *ic, struct ieee80211_channel *a,
719 struct ieee80211_channel *b)
721 struct ieee80211_channel *ic_bsschan = ic->ic_bsschan;
722 if (ic_bsschan == IEEE80211_CHAN_ANYC)
723 return 0;
724 /* a is better than b (return < 0) when a is current (and b is not) */
725 return (b == ic_bsschan) - (a == ic_bsschan);
728 /* This function must be invoked with locks acquired */
729 static int
730 pc_cmp_orig(struct channel *a, struct channel *b)
732 return a->orig - b->orig;
735 /* This function must be invoked with locks acquired */
736 static int
737 pc_cmp(const void *_a, const void *_b)
739 struct ieee80211_channel *a = ((struct channel *)_a)->chan;
740 struct ieee80211_channel *b = ((struct channel *)_b)->chan;
741 struct pc_params *params = ((struct channel *)_a)->params;
742 struct ieee80211com *ic = params->vap->iv_ic;
743 int res;
745 #define EVALUATE_CRITERION(name, ...) do { \
746 if ((res = pc_cmp_##name(__VA_ARGS__)) != 0) \
747 return res; \
748 } while (0)
750 EVALUATE_CRITERION(radar, a, b);
751 EVALUATE_CRITERION(keepmode, params, a, b);
752 EVALUATE_CRITERION(sc, ic, a, b);
753 /* XXX: rssi useless? pick_channel evaluates it anyway */
754 EVALUATE_CRITERION(rssi, params->ss->ss_priv, a, b);
755 EVALUATE_CRITERION(samechan, ic, a, b);
756 EVALUATE_CRITERION(orig, (struct channel *)_a, (struct channel *)_b);
758 #undef EVALUATE_CRITERION
759 return res;
762 /* This function must be invoked with locks acquired */
763 static void
764 pc_swap(void *a, void *b, int n)
766 struct ieee80211_channel *t = ((struct channel *)a)->chan;
767 int i;
769 ((struct channel *)a)->chan = ((struct channel *)b)->chan;
770 ((struct channel *)b)->chan = t;
772 i = ((struct channel *)a)->orig;
773 ((struct channel *)a)->orig = ((struct channel *)b)->orig;
774 ((struct channel *)b)->orig = i;
776 /* (struct channel *)x->params doesn't have to be swapped, because it
777 * is the same across all channels */
780 /* Pick a quiet channel to use for ap operation.
781 * Must be invoked while we hold the locks. */
782 static struct ieee80211_channel *
783 pick_channel(struct ieee80211_scan_state *ss, struct ieee80211vap *vap,
784 u_int32_t flags)
786 struct ieee80211com *ic = vap->iv_ic;
787 unsigned int i, best_rssi;
788 int ss_last = ss->ss_last;
789 struct ieee80211_channel *best;
790 struct ap_state *as = ss->ss_priv;
791 struct channel chans[ss_last]; /* actually ss_last-1 is required */
792 struct channel *c = NULL;
793 struct pc_params params = { vap, ss, flags };
794 int benefit = 0;
795 int sta_assoc = 0;
797 for (i = 0; i < ss_last; i++) {
798 chans[i].chan = ss->ss_chans[i];
799 chans[i].orig = i;
800 chans[i].params = &params;
803 sort(chans, ss_last, sizeof(*chans), pc_cmp, pc_swap);
805 #ifdef IEEE80211_DEBUG
806 for (i = 0; i < ss_last; i++) {
807 int chan = ieee80211_chan2ieee(ic, chans[i].chan);
808 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: channel %u, "
809 "rssi %d, radar %d, cn %d, km %d\n",
810 __func__, chan, as->as_maxrssi[chan],
811 IEEE80211_IS_CHAN_RADAR(chans[i].chan),
812 ic->ic_chan_nodes[chans[i].chan->ic_ieee],
813 !!IEEE80211_ARE_CHANS_SAME_MODE(chans[i].chan,
814 ic->ic_bsschan));
816 #endif /* IEEE80211_DEBUG */
818 best = NULL;
819 best_rssi = 0xff; /* If signal is bigger than 0xff, we'd be melting. */
821 for (i = 0; i < ss_last; i++) {
822 c = &chans[i];
823 benefit = best_rssi - as->as_maxrssi[c->chan->ic_ieee];
824 sta_assoc = ic->ic_sta_assoc;
826 /* Don't switch... */
827 if (benefit <= 0)
828 continue;
830 /* Verify channel is not marked for non-occupancy */
831 if (IEEE80211_IS_CHAN_RADAR(c->chan))
832 continue;
834 /* Do not select 802.11a ST if mode is specified and is not
835 * 802.11a ST */
836 if (as->as_required_mode &&
837 IEEE80211_IS_CHAN_STURBO(c->chan) &&
838 (as->as_vap_desired_mode != IEEE80211_MODE_TURBO_STATIC_A))
839 continue;
841 /* Verify mode matches any fixed mode specified */
842 if ((c->chan->ic_flags & as->as_required_mode) !=
843 as->as_required_mode)
844 continue;
846 if ((ic->ic_bsschan != NULL) &&
847 (ic->ic_bsschan != IEEE80211_CHAN_ANYC)) {
849 /* Make sure the channels are the same mode */
850 if ((flags & IEEE80211_SCAN_KEEPMODE) &&
851 !IEEE80211_ARE_CHANS_SAME_MODE(c->chan,
852 ic->ic_bsschan))
853 /* break the loop as the subsequent chans won't be
854 * better */
855 break;
858 if (sta_assoc != 0) {
859 int sl = ic->ic_cn_total -
860 ic->ic_chan_nodes[c->chan->ic_ieee]; /* count */
861 if (ic->ic_sc_algorithm == IEEE80211_SC_LOOSE) {
862 int sl_max = ic->ic_sc_sldg * benefit;
863 sl = 1000 * sl / sta_assoc; /* permil */
864 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
865 "%s: chan %d, dB gained: %d, "
866 "STAs lost: %d permil (max %d)\n",
867 __func__, c->chan->ic_ieee,
868 benefit, sl, sl_max);
869 if (sl > sl_max)
870 continue;
871 } else if (((ic->ic_sc_algorithm ==
872 IEEE80211_SC_TIGHT) ||
873 (ic->ic_sc_algorithm ==
874 IEEE80211_SC_STRICT)) &&
875 (sl > 0)) {
876 /* Break the loop as the subsequent chans
877 * won't be better. */
878 break;
881 best = c->chan;
882 best_rssi = as->as_maxrssi[best->ic_ieee];
885 if (best != NULL) {
886 i = best->ic_ieee;
887 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
888 "%s: best: channel %u rssi %d\n",
889 __func__, i, as->as_maxrssi[i]);
891 return best;
894 static int
895 ap_end(struct ieee80211_scan_state *ss, struct ieee80211vap *vap,
896 int (*action)(struct ieee80211vap *,
897 const struct ieee80211_scan_entry *),
898 u_int32_t flags)
900 struct ap_state *as = ss->ss_priv;
901 struct ieee80211_channel *bestchan = NULL;
902 struct ieee80211com *ic = NULL;
903 int res = 1;
905 SCAN_AP_LOCK_IRQ(as);
907 KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP,
908 ("wrong opmode %u", vap->iv_opmode));
910 ic = vap->iv_ic;
911 bestchan = pick_channel(ss, vap, flags);
912 if (bestchan == NULL) {
913 if (ss->ss_last > 0) {
914 /* no suitable channel, should not happen */
915 printk(KERN_ERR "%s: %s: no suitable channel! "
916 "(should not happen)\n",
917 DEV_NAME(vap->iv_dev), __func__);
919 res = 1; /* Do NOT restart scan */
920 } else {
921 struct ieee80211_scan_entry se;
922 /* XXX: notify all VAPs? */
923 /* if this is a dynamic turbo frequency , start with normal
924 * mode first */
925 if (IEEE80211_IS_CHAN_TURBO(bestchan) &&
926 !IEEE80211_IS_CHAN_STURBO(bestchan)) {
927 if ((bestchan = ieee80211_find_channel(ic,
928 bestchan->ic_freq, bestchan->ic_flags &
929 ~IEEE80211_CHAN_TURBO)) == NULL) {
930 /* should never happen ?? */
931 SCAN_AP_UNLOCK_IRQ_EARLY(as);
932 return 0;
935 memset(&se, 0, sizeof(se));
936 se.se_chan = bestchan;
938 as->as_action = ss->ss_ops->scan_default;
939 if (action)
940 as->as_action = action;
941 as->as_selbss = se;
943 /* Must defer action to avoid possible recursive call through
944 * 80211 state machine, which would result in recursive
945 * locking. */
946 IEEE80211_SCHEDULE_TQUEUE(&as->as_actiontq);
947 res = 1;
949 SCAN_AP_UNLOCK_IRQ(as);
950 return res;
953 static void
954 ap_age(struct ieee80211_scan_state *ss)
956 struct ap_state *as = ss->ss_priv;
957 struct scan_entry *se, *next;
959 SCAN_AP_LOCK_IRQ(as);
960 TAILQ_FOREACH_SAFE(se, &as->as_entry, se_list, next) {
961 if (se->se_notseen > AP_PURGE_SCANS) {
962 TAILQ_REMOVE(&as->as_entry, se, se_list);
963 LIST_REMOVE(se, se_hash);
964 FREE(se, M_80211_SCAN);
967 SCAN_AP_UNLOCK_IRQ(as);
970 static int
971 ap_iterate(struct ieee80211_scan_state *ss,
972 ieee80211_scan_iter_func *f, void *arg)
974 struct ap_state *as = ss->ss_priv;
975 struct scan_entry *se;
976 u_int gen;
977 int res = 0;
979 SCAN_AP_GEN_LOCK(as);
980 gen = as->as_scangen++;
981 restart:
982 SCAN_AP_LOCK_IRQ(as);
983 TAILQ_FOREACH(se, &as->as_entry, se_list) {
984 if (se->se_scangen != gen) {
985 se->se_scangen = gen;
986 /* update public state */
987 se->base.se_age = jiffies - se->se_lastupdate;
988 SCAN_AP_UNLOCK_IRQ_EARLY(as);
990 res = (*f)(arg, &se->base);
992 /* We probably ran out of buffer space. */
993 if (res != 0)
994 goto done;
996 goto restart;
1000 SCAN_AP_UNLOCK_IRQ(as);
1002 done:
1003 SCAN_AP_GEN_UNLOCK(as);
1005 return res;
1008 static void
1009 ap_assoc_success(struct ieee80211_scan_state *ss,
1010 const u_int8_t macaddr[IEEE80211_ADDR_LEN])
1012 /* should not be called */
1015 static void
1016 ap_assoc_fail(struct ieee80211_scan_state *ss,
1017 const u_int8_t macaddr[IEEE80211_ADDR_LEN], int reason)
1019 /* should not be called */
1023 * Default action to execute when a scan entry is found for ap
1024 * mode. Return 1 on success, 0 on failure
1026 static int
1027 ap_default_action(struct ieee80211vap *vap,
1028 const struct ieee80211_scan_entry *se)
1030 ieee80211_create_ibss(vap, se->se_chan);
1032 return 1;
1035 static void
1036 action_tasklet(IEEE80211_TQUEUE_ARG data)
1038 struct ieee80211_scan_state *ss = (struct ieee80211_scan_state *)data;
1039 struct ap_state *as = (struct ap_state *)ss->ss_priv;
1040 struct ieee80211vap *vap = ss->ss_vap;
1041 SCAN_AP_LOCK_IRQ(as);
1042 if (as->as_newscan) {
1043 struct scan_entry *se;
1044 TAILQ_FOREACH(se, &as->as_entry, se_list) {
1046 * If seen then reset and don't bump the count;
1047 * otherwise bump the ``not seen'' count. Note
1048 * that this ensures that stations for which we
1049 * see frames while not scanning but not during
1050 * this scan will not be penalized.
1052 if (se->se_seen)
1053 se->se_seen = 0;
1054 else
1055 se->se_notseen++;
1057 as->as_newscan = 0;
1059 SCAN_AP_UNLOCK_IRQ(as);
1061 (*ss->ss_ops->scan_default)(vap, &as->as_selbss);
1065 * Module glue.
1067 MODULE_AUTHOR("Errno Consulting, Sam Leffler");
1068 MODULE_DESCRIPTION("802.11 wireless support: default ap scanner");
1069 #ifdef MODULE_LICENSE
1070 MODULE_LICENSE("Dual BSD/GPL");
1071 #endif
1073 static const struct ieee80211_scanner ap_default = {
1074 .scan_name = "default",
1075 .scan_attach = ap_attach,
1076 .scan_detach = ap_detach,
1077 .scan_start = ap_start,
1078 .scan_restart = ap_restart,
1079 .scan_cancel = ap_cancel,
1080 .scan_end = ap_end,
1081 .scan_flush = ap_flush,
1082 .scan_add = ap_add,
1083 .scan_age = ap_age,
1084 .scan_iterate = ap_iterate,
1085 .scan_assoc_success = ap_assoc_success,
1086 .scan_assoc_fail = ap_assoc_fail,
1087 .scan_default = ap_default_action,
1091 static int __init
1092 init_scanner_ap(void)
1094 ieee80211_scanner_register(IEEE80211_M_HOSTAP, &ap_default);
1095 return 0;
1097 module_init(init_scanner_ap);
1099 static void __exit
1100 exit_scanner_ap(void)
1102 ieee80211_scanner_unregister_all(&ap_default);
1104 module_exit(exit_scanner_ap);