The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net80211/ieee80211_scan_sta.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    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: releng/7.4/sys/net80211/ieee80211_scan_sta.c 181802 2008-08-17 23:00:47Z sam $");
   28 
   29 /*
   30  * IEEE 802.11 station scanning support.
   31  */
   32 #include <sys/param.h>
   33 #include <sys/systm.h> 
   34 #include <sys/kernel.h>
   35 #include <sys/module.h>
   36  
   37 #include <sys/socket.h>
   38 
   39 #include <net/if.h>
   40 #include <net/if_media.h>
   41 #include <net/ethernet.h>
   42 
   43 #include <net80211/ieee80211_var.h>
   44 
   45 #include <net/bpf.h>
   46 
   47 /*
   48  * Parameters for managing cache entries:
   49  *
   50  * o a station with STA_FAILS_MAX failures is not considered
   51  *   when picking a candidate
   52  * o a station that hasn't had an update in STA_PURGE_SCANS
   53  *   (background) scans is discarded
   54  * o after STA_FAILS_AGE seconds we clear the failure count
   55  */
   56 #define STA_FAILS_MAX   2               /* assoc failures before ignored */
   57 #define STA_FAILS_AGE   (2*60)          /* time before clearing fails (secs) */
   58 #define STA_PURGE_SCANS 2               /* age for purging entries (scans) */
   59 
   60 /* XXX tunable */
   61 #define STA_RSSI_MIN    8               /* min acceptable rssi */
   62 #define STA_RSSI_MAX    40              /* max rssi for comparison */
   63 
   64 #define RSSI_LPF_LEN            10
   65 #define RSSI_DUMMY_MARKER       0x127
   66 #define RSSI_EP_MULTIPLIER      (1<<7)  /* pow2 to optimize out * and / */
   67 #define RSSI_IN(x)              ((x) * RSSI_EP_MULTIPLIER)
   68 #define LPF_RSSI(x, y, len) \
   69     ((x != RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))
   70 #define RSSI_LPF(x, y) do {                                             \
   71     if ((y) >= -20)                                                     \
   72         x = LPF_RSSI((x), RSSI_IN((y)), RSSI_LPF_LEN);                  \
   73 } while (0)
   74 #define EP_RND(x, mul) \
   75         ((((x)%(mul)) >= ((mul)/2)) ? howmany(x, mul) : (x)/(mul))
   76 #define RSSI_GET(x)     EP_RND(x, RSSI_EP_MULTIPLIER)
   77 
   78 struct sta_entry {
   79         struct ieee80211_scan_entry base;
   80         TAILQ_ENTRY(sta_entry) se_list;
   81         LIST_ENTRY(sta_entry) se_hash;
   82         uint8_t         se_fails;               /* failure to associate count */
   83         uint8_t         se_seen;                /* seen during current scan */
   84         uint8_t         se_notseen;             /* not seen in previous scans */
   85         uint8_t         se_flags;
   86         uint32_t        se_avgrssi;             /* LPF rssi state */
   87         unsigned long   se_lastupdate;          /* time of last update */
   88         unsigned long   se_lastfail;            /* time of last failure */
   89         unsigned long   se_lastassoc;           /* time of last association */
   90         u_int           se_scangen;             /* iterator scan gen# */
   91 };
   92 
   93 #define STA_HASHSIZE    32
   94 /* simple hash is enough for variation of macaddr */
   95 #define STA_HASH(addr)  \
   96         (((const uint8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % STA_HASHSIZE)
   97 
   98 struct sta_table {
   99         struct mtx      st_lock;                /* on scan table */
  100         TAILQ_HEAD(, sta_entry) st_entry;       /* all entries */
  101         LIST_HEAD(, sta_entry) st_hash[STA_HASHSIZE];
  102         struct mtx      st_scanlock;            /* on st_scangen */
  103         u_int           st_scangen;             /* gen# for iterator */
  104         int             st_newscan;
  105 };
  106 
  107 static void sta_flush_table(struct sta_table *);
  108 /*
  109  * match_bss returns a bitmask describing if an entry is suitable
  110  * for use.  If non-zero the entry was deemed not suitable and it's
  111  * contents explains why.  The following flags are or'd to to this
  112  * mask and can be used to figure out why the entry was rejected.
  113  */
  114 #define MATCH_CHANNEL   0x001   /* channel mismatch */
  115 #define MATCH_CAPINFO   0x002   /* capabilities mismatch, e.g. no ess */
  116 #define MATCH_PRIVACY   0x004   /* privacy mismatch */
  117 #define MATCH_RATE      0x008   /* rate set mismatch */
  118 #define MATCH_SSID      0x010   /* ssid mismatch */
  119 #define MATCH_BSSID     0x020   /* bssid mismatch */
  120 #define MATCH_FAILS     0x040   /* too many failed auth attempts */
  121 #define MATCH_NOTSEEN   0x080   /* not seen in recent scans */
  122 #define MATCH_RSSI      0x100   /* rssi deemed too low to use */
  123 static int match_bss(struct ieee80211com *,
  124         const struct ieee80211_scan_state *, struct sta_entry *, int);
  125 
  126 /* number of references from net80211 layer */
  127 static  int nrefs = 0;
  128 
  129 /*
  130  * Attach prior to any scanning work.
  131  */
  132 static int
  133 sta_attach(struct ieee80211_scan_state *ss)
  134 {
  135         struct sta_table *st;
  136 
  137         MALLOC(st, struct sta_table *, sizeof(struct sta_table),
  138                 M_80211_SCAN, M_NOWAIT | M_ZERO);
  139         if (st == NULL)
  140                 return 0;
  141         mtx_init(&st->st_lock, "scantable", "802.11 scan table", MTX_DEF);
  142         mtx_init(&st->st_scanlock, "scangen", "802.11 scangen", MTX_DEF);
  143         TAILQ_INIT(&st->st_entry);
  144         ss->ss_priv = st;
  145         nrefs++;                        /* NB: we assume caller locking */
  146         return 1;
  147 }
  148 
  149 /*
  150  * Cleanup any private state.
  151  */
  152 static int
  153 sta_detach(struct ieee80211_scan_state *ss)
  154 {
  155         struct sta_table *st = ss->ss_priv;
  156 
  157         if (st != NULL) {
  158                 sta_flush_table(st);
  159                 mtx_destroy(&st->st_lock);
  160                 mtx_destroy(&st->st_scanlock);
  161                 FREE(st, M_80211_SCAN);
  162                 KASSERT(nrefs > 0, ("imbalanced attach/detach"));
  163                 nrefs--;                /* NB: we assume caller locking */
  164         }
  165         return 1;
  166 }
  167 
  168 /*
  169  * Flush all per-scan state.
  170  */
  171 static int
  172 sta_flush(struct ieee80211_scan_state *ss)
  173 {
  174         struct sta_table *st = ss->ss_priv;
  175 
  176         mtx_lock(&st->st_lock);
  177         sta_flush_table(st);
  178         mtx_unlock(&st->st_lock);
  179         ss->ss_last = 0;
  180         return 0;
  181 }
  182 
  183 /*
  184  * Flush all entries in the scan cache.
  185  */
  186 static void
  187 sta_flush_table(struct sta_table *st)
  188 {
  189         struct sta_entry *se, *next;
  190 
  191         TAILQ_FOREACH_SAFE(se, &st->st_entry, se_list, next) {
  192                 TAILQ_REMOVE(&st->st_entry, se, se_list);
  193                 LIST_REMOVE(se, se_hash);
  194                 FREE(se, M_80211_SCAN);
  195         }
  196 }
  197 
  198 /*
  199  * Process a beacon or probe response frame; create an
  200  * entry in the scan cache or update any previous entry.
  201  */
  202 static int
  203 sta_add(struct ieee80211_scan_state *ss, 
  204         const struct ieee80211_scanparams *sp,
  205         const struct ieee80211_frame *wh,
  206         int subtype, int rssi, int noise, int rstamp)
  207 {
  208 #define ISPROBE(_st)    ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
  209 #define PICK1ST(_ss) \
  210         ((ss->ss_flags & (IEEE80211_SCAN_PICK1ST | IEEE80211_SCAN_GOTPICK)) == \
  211         IEEE80211_SCAN_PICK1ST)
  212         struct sta_table *st = ss->ss_priv;
  213         const uint8_t *macaddr = wh->i_addr2;
  214         struct ieee80211com *ic = ss->ss_ic;
  215         struct sta_entry *se;
  216         struct ieee80211_scan_entry *ise;
  217         int hash, offchan;
  218 
  219         hash = STA_HASH(macaddr);
  220 
  221         mtx_lock(&st->st_lock);
  222         LIST_FOREACH(se, &st->st_hash[hash], se_hash)
  223                 if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr))
  224                         goto found;
  225         MALLOC(se, struct sta_entry *, sizeof(struct sta_entry),
  226                 M_80211_SCAN, M_NOWAIT | M_ZERO);
  227         if (se == NULL) {
  228                 mtx_unlock(&st->st_lock);
  229                 return 0;
  230         }
  231         se->se_scangen = st->st_scangen-1;
  232         se->se_avgrssi = RSSI_DUMMY_MARKER;
  233         IEEE80211_ADDR_COPY(se->base.se_macaddr, macaddr);
  234         TAILQ_INSERT_TAIL(&st->st_entry, se, se_list);
  235         LIST_INSERT_HEAD(&st->st_hash[hash], se, se_hash);
  236 found:
  237         ise = &se->base;
  238         /* XXX ap beaconing multiple ssid w/ same bssid */
  239         if (sp->ssid[1] != 0 &&
  240             (ISPROBE(subtype) || ise->se_ssid[1] == 0))
  241                 memcpy(ise->se_ssid, sp->ssid, 2+sp->ssid[1]);
  242         KASSERT(sp->rates[1] <= IEEE80211_RATE_MAXSIZE,
  243                 ("rate set too large: %u", sp->rates[1]));
  244         memcpy(ise->se_rates, sp->rates, 2+sp->rates[1]);
  245         if (sp->xrates != NULL) {
  246                 /* XXX validate xrates[1] */
  247                 KASSERT(sp->xrates[1] + sp->rates[1] <= IEEE80211_RATE_MAXSIZE,
  248                         ("xrate set too large: %u", sp->xrates[1]));
  249                 memcpy(ise->se_xrates, sp->xrates, 2+sp->xrates[1]);
  250         } else
  251                 ise->se_xrates[1] = 0;
  252         IEEE80211_ADDR_COPY(ise->se_bssid, wh->i_addr3);
  253         offchan = (IEEE80211_CHAN2IEEE(sp->curchan) != sp->bchan &&
  254             ic->ic_phytype != IEEE80211_T_FH);
  255         if (!offchan) {
  256                 /*
  257                  * Record rssi data using extended precision LPF filter.
  258                  *
  259                  * NB: use only on-channel data to insure we get a good
  260                  *     estimate of the signal we'll see when associated.
  261                  */
  262                 RSSI_LPF(se->se_avgrssi, rssi);
  263                 ise->se_rssi = RSSI_GET(se->se_avgrssi);
  264                 ise->se_noise = noise;
  265         }
  266         ise->se_rstamp = rstamp;
  267         memcpy(ise->se_tstamp.data, sp->tstamp, sizeof(ise->se_tstamp));
  268         ise->se_intval = sp->bintval;
  269         ise->se_capinfo = sp->capinfo;
  270         /*
  271          * Beware of overriding se_chan for frames seen
  272          * off-channel; this can cause us to attempt an
  273          * assocation on the wrong channel.
  274          */
  275         if (offchan) {
  276                 struct ieee80211_channel *c;
  277                 /*
  278                  * Off-channel, locate the home/bss channel for the sta
  279                  * using the value broadcast in the DSPARMS ie.
  280                  */
  281                 c = ieee80211_find_channel_byieee(ic, sp->bchan,
  282                     sp->curchan->ic_flags);
  283                 if (c != NULL) {
  284                         ise->se_chan = c;
  285                 } else if (ise->se_chan == NULL) {
  286                         /* should not happen, pick something */
  287                         ise->se_chan = sp->curchan;
  288                 }
  289         } else
  290                 ise->se_chan = sp->curchan;
  291         ise->se_fhdwell = sp->fhdwell;
  292         ise->se_fhindex = sp->fhindex;
  293         ise->se_erp = sp->erp;
  294         ise->se_timoff = sp->timoff;
  295         if (sp->tim != NULL) {
  296                 const struct ieee80211_tim_ie *tim =
  297                     (const struct ieee80211_tim_ie *) sp->tim;
  298                 ise->se_dtimperiod = tim->tim_period;
  299         }
  300         /* NB: no need to setup ie ptrs; they are not (currently) used */
  301         (void) ieee80211_ies_init(&ise->se_ies, sp->ies, sp->ies_len);
  302 
  303         /* clear failure count after STA_FAIL_AGE passes */
  304         if (se->se_fails && (ticks - se->se_lastfail) > STA_FAILS_AGE*hz) {
  305                 se->se_fails = 0;
  306                 IEEE80211_NOTE_MAC(ic, IEEE80211_MSG_SCAN, macaddr,
  307                     "%s: fails %u", __func__, se->se_fails);
  308         }
  309 
  310         se->se_lastupdate = ticks;              /* update time */
  311         se->se_seen = 1;
  312         se->se_notseen = 0;
  313 
  314         mtx_unlock(&st->st_lock);
  315 
  316         /*
  317          * If looking for a quick choice and nothing's
  318          * been found check here.
  319          */
  320         if (PICK1ST(ss) && match_bss(ic, ss, se, IEEE80211_MSG_SCAN) == 0)
  321                 ss->ss_flags |= IEEE80211_SCAN_GOTPICK;
  322 
  323         return 1;
  324 #undef PICK1ST
  325 #undef ISPROBE
  326 }
  327 
  328 /*
  329  * Check if a channel is excluded by user request.
  330  */
  331 static int
  332 isexcluded(struct ieee80211com *ic, const struct ieee80211_channel *c)
  333 {
  334         return (isclr(ic->ic_chan_active, c->ic_ieee) ||
  335             (ic->ic_des_chan != IEEE80211_CHAN_ANYC &&
  336              c->ic_freq != ic->ic_des_chan->ic_freq));
  337 }
  338 
  339 static struct ieee80211_channel *
  340 find11gchannel(struct ieee80211com *ic, int i, int freq)
  341 {
  342         struct ieee80211_channel *c;
  343         int j;
  344 
  345         /*
  346          * The normal ordering in the channel list is b channel
  347          * immediately followed by g so optimize the search for
  348          * this.  We'll still do a full search just in case.
  349          */
  350         for (j = i+1; j < ic->ic_nchans; j++) {
  351                 c = &ic->ic_channels[j];
  352                 if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
  353                         return c;
  354         }
  355         for (j = 0; j < i; j++) {
  356                 c = &ic->ic_channels[j];
  357                 if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
  358                         return c;
  359         }
  360         return NULL;
  361 }
  362 static const u_int chanflags[IEEE80211_MODE_MAX] = {
  363         IEEE80211_CHAN_B,       /* IEEE80211_MODE_AUTO */
  364         IEEE80211_CHAN_A,       /* IEEE80211_MODE_11A */
  365         IEEE80211_CHAN_B,       /* IEEE80211_MODE_11B */
  366         IEEE80211_CHAN_G,       /* IEEE80211_MODE_11G */
  367         IEEE80211_CHAN_FHSS,    /* IEEE80211_MODE_FH */
  368         IEEE80211_CHAN_A,       /* IEEE80211_MODE_TURBO_A (check base channel)*/
  369         IEEE80211_CHAN_G,       /* IEEE80211_MODE_TURBO_G */
  370         IEEE80211_CHAN_ST,      /* IEEE80211_MODE_STURBO_A */
  371         IEEE80211_CHAN_A,       /* IEEE80211_MODE_11NA (check legacy) */
  372         IEEE80211_CHAN_G,       /* IEEE80211_MODE_11NG (check legacy) */
  373 };
  374 
  375 static void
  376 add_channels(struct ieee80211com *ic,
  377         struct ieee80211_scan_state *ss,
  378         enum ieee80211_phymode mode, const uint16_t freq[], int nfreq)
  379 {
  380 #define N(a)    (sizeof(a) / sizeof(a[0]))
  381         struct ieee80211_channel *c, *cg;
  382         u_int modeflags;
  383         int i;
  384 
  385         KASSERT(mode < N(chanflags), ("Unexpected mode %u", mode));
  386         modeflags = chanflags[mode];
  387         for (i = 0; i < nfreq; i++) {
  388                 if (ss->ss_last >= IEEE80211_SCAN_MAX)
  389                         break;
  390 
  391                 c = ieee80211_find_channel(ic, freq[i], modeflags);
  392                 if (c != NULL && isexcluded(ic, c))
  393                         continue;
  394                 if (mode == IEEE80211_MODE_AUTO) {
  395                         /*
  396                          * XXX special-case 11b/g channels so we select
  397                          *     the g channel if both are present or there
  398                          *     are only g channels.
  399                          */
  400                         if (c == NULL || IEEE80211_IS_CHAN_B(c)) {
  401                                 cg = find11gchannel(ic, i, freq[i]);
  402                                 if (cg != NULL)
  403                                         c = cg;
  404                         }
  405                 }
  406                 if (c == NULL)
  407                         continue;
  408 
  409                 ss->ss_chans[ss->ss_last++] = c;
  410         }
  411 #undef N
  412 }
  413 
  414 static const uint16_t rcl1[] =          /* 8 FCC channel: 52, 56, 60, 64, 36, 40, 44, 48 */
  415 { 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 };
  416 static const uint16_t rcl2[] =          /* 4 MKK channels: 34, 38, 42, 46 */
  417 { 5170, 5190, 5210, 5230 };
  418 static const uint16_t rcl3[] =          /* 2.4Ghz ch: 1,6,11,7,13 */
  419 { 2412, 2437, 2462, 2442, 2472 };
  420 static const uint16_t rcl4[] =          /* 5 FCC channel: 149, 153, 161, 165 */
  421 { 5745, 5765, 5785, 5805, 5825 };
  422 static const uint16_t rcl7[] =          /* 11 ETSI channel: 100,104,108,112,116,120,124,128,132,136,140 */
  423 { 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 };
  424 static const uint16_t rcl8[] =          /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */
  425 { 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 };
  426 static const uint16_t rcl9[] =          /* 2.4Ghz ch: 14 */
  427 { 2484 };
  428 static const uint16_t rcl10[] =         /* Added Korean channels 2312-2372 */
  429 { 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 };
  430 static const uint16_t rcl11[] =         /* Added Japan channels in 4.9/5.0 spectrum */
  431 { 5040, 5060, 5080, 4920, 4940, 4960, 4980 };
  432 #ifdef ATH_TURBO_SCAN
  433 static const uint16_t rcl5[] =          /* 3 static turbo channels */
  434 { 5210, 5250, 5290 };
  435 static const uint16_t rcl6[] =          /* 2 static turbo channels */
  436 { 5760, 5800 };
  437 static const uint16_t rcl6x[] =         /* 4 FCC3 turbo channels */
  438 { 5540, 5580, 5620, 5660 };
  439 static const uint16_t rcl12[] =         /* 2.4Ghz Turbo channel 6 */
  440 { 2437 };
  441 static const uint16_t rcl13[] =         /* dynamic Turbo channels */
  442 { 5200, 5240, 5280, 5765, 5805 };
  443 #endif /* ATH_TURBO_SCAN */
  444 
  445 struct scanlist {
  446         uint16_t        mode;
  447         uint16_t        count;
  448         const uint16_t  *list;
  449 };
  450 
  451 #define X(a)    .count = sizeof(a)/sizeof(a[0]), .list = a
  452 
  453 static const struct scanlist staScanTable[] = {
  454         { IEEE80211_MODE_11B,           X(rcl3) },
  455         { IEEE80211_MODE_11A,           X(rcl1) },
  456         { IEEE80211_MODE_11A,           X(rcl2) },
  457         { IEEE80211_MODE_11B,           X(rcl8) },
  458         { IEEE80211_MODE_11B,           X(rcl9) },
  459         { IEEE80211_MODE_11A,           X(rcl4) },
  460 #ifdef ATH_TURBO_SCAN
  461         { IEEE80211_MODE_STURBO_A,      X(rcl5) },
  462         { IEEE80211_MODE_STURBO_A,      X(rcl6) },
  463         { IEEE80211_MODE_TURBO_A,       X(rcl6x) },
  464         { IEEE80211_MODE_TURBO_A,       X(rcl13) },
  465 #endif /* ATH_TURBO_SCAN */
  466         { IEEE80211_MODE_11A,           X(rcl7) },
  467         { IEEE80211_MODE_11B,           X(rcl10) },
  468         { IEEE80211_MODE_11A,           X(rcl11) },
  469 #ifdef ATH_TURBO_SCAN
  470         { IEEE80211_MODE_TURBO_G,       X(rcl12) },
  471 #endif /* ATH_TURBO_SCAN */
  472         { .list = NULL }
  473 };
  474 
  475 static int
  476 checktable(const struct scanlist *scan, const struct ieee80211_channel *c)
  477 {
  478         int i;
  479 
  480         for (; scan->list != NULL; scan++) {
  481                 for (i = 0; i < scan->count; i++)
  482                         if (scan->list[i] == c->ic_freq) 
  483                                 return 1;
  484         }
  485         return 0;
  486 }
  487 
  488 static void
  489 sweepchannels(struct ieee80211_scan_state *ss, struct ieee80211com *ic,
  490         const struct scanlist table[])
  491 {
  492         struct ieee80211_channel *c;
  493         int i;
  494 
  495         /*
  496          * Add the channels from the ic (from HAL) that are not present
  497          * in the staScanTable.
  498          */
  499         for (i = 0; i < ic->ic_nchans; i++) {
  500                 if (ss->ss_last >= IEEE80211_SCAN_MAX)
  501                         break;
  502 
  503                 c = &ic->ic_channels[i];
  504                 /*
  505                  * Ignore dynamic turbo channels; we scan them
  506                  * in normal mode (i.e. not boosted).  Likewise
  507                  * for HT channels, they get scanned using
  508                  * legacy rates.
  509                  */
  510                 if (IEEE80211_IS_CHAN_DTURBO(c) || IEEE80211_IS_CHAN_HT(c))
  511                         continue;
  512 
  513                 /*
  514                  * If a desired mode was specified, scan only 
  515                  * channels that satisfy that constraint.
  516                  */
  517                 if (ic->ic_des_mode != IEEE80211_MODE_AUTO &&
  518                     ic->ic_des_mode != ieee80211_chan2mode(c))
  519                         continue;
  520 
  521                 /*
  522                  * Skip channels excluded by user request.
  523                  */
  524                 if (isexcluded(ic, c))
  525                         continue;
  526 
  527                 /*
  528                  * Add the channel unless it is listed in the
  529                  * fixed scan order tables.  This insures we
  530                  * don't sweep back in channels we filtered out
  531                  * above.
  532                  */
  533                 if (checktable(table, c))
  534                         continue;
  535 
  536                 /* Add channel to scanning list. */
  537                 ss->ss_chans[ss->ss_last++] = c;
  538         }
  539 }
  540 
  541 /*
  542  * Start a station-mode scan by populating the channel list.
  543  */
  544 static int
  545 sta_start(struct ieee80211_scan_state *ss, struct ieee80211com *ic)
  546 {
  547 #define N(a)    (sizeof(a)/sizeof(a[0]))
  548         struct sta_table *st = ss->ss_priv;
  549         const struct scanlist *scan;
  550         enum ieee80211_phymode mode;
  551 
  552         ss->ss_last = 0;
  553         /*
  554          * Use the table of ordered channels to construct the list
  555          * of channels for scanning.  Any channels in the ordered
  556          * list not in the master list will be discarded.
  557          */
  558         for (scan = staScanTable; scan->list != NULL; scan++) {
  559                 mode = scan->mode;
  560                 if (ic->ic_des_mode != IEEE80211_MODE_AUTO) {
  561                         /*
  562                          * If a desired mode was specified, scan only 
  563                          * channels that satisfy that constraint.
  564                          */
  565                         if (ic->ic_des_mode != mode) {
  566                                 /*
  567                                  * The scan table marks 2.4Ghz channels as b
  568                                  * so if the desired mode is 11g, then use
  569                                  * the 11b channel list but upgrade the mode.
  570                                  */
  571                                 if (ic->ic_des_mode != IEEE80211_MODE_11G ||
  572                                     mode != IEEE80211_MODE_11B)
  573                                         continue;
  574                                 mode = IEEE80211_MODE_11G;      /* upgrade */
  575                         }
  576                 } else {
  577                         /*
  578                          * This lets add_channels upgrade an 11b channel
  579                          * to 11g if available.
  580                          */
  581                         if (mode == IEEE80211_MODE_11B)
  582                                 mode = IEEE80211_MODE_AUTO;
  583                 }
  584 #ifdef IEEE80211_F_XR
  585                 /* XR does not operate on turbo channels */
  586                 if ((ic->ic_flags & IEEE80211_F_XR) &&
  587                     (mode == IEEE80211_MODE_TURBO_A ||
  588                      mode == IEEE80211_MODE_TURBO_G ||
  589                      mode == IEEE80211_MODE_STURBO_A))
  590                         continue;
  591 #endif
  592                 /*
  593                  * Add the list of the channels; any that are not
  594                  * in the master channel list will be discarded.
  595                  */
  596                 add_channels(ic, ss, mode, scan->list, scan->count);
  597         }
  598 
  599         /*
  600          * Add the channels from the ic (from HAL) that are not present
  601          * in the staScanTable.
  602          */
  603         sweepchannels(ss, ic, staScanTable);
  604 
  605         ss->ss_next = 0;
  606         /* XXX tunables */
  607         ss->ss_mindwell = msecs_to_ticks(20);           /* 20ms */
  608         ss->ss_maxdwell = msecs_to_ticks(200);          /* 200ms */
  609 
  610 #ifdef IEEE80211_DEBUG
  611         if (ieee80211_msg_scan(ic)) {
  612                 if_printf(ic->ic_ifp, "scan set ");
  613                 ieee80211_scan_dump_channels(ss);
  614                 printf(" dwell min %ld max %ld\n",
  615                         ss->ss_mindwell, ss->ss_maxdwell);
  616         }
  617 #endif /* IEEE80211_DEBUG */
  618 
  619         st->st_newscan = 1;
  620 
  621         return 0;
  622 #undef N
  623 }
  624 
  625 /*
  626  * Restart a bg scan.
  627  */
  628 static int
  629 sta_restart(struct ieee80211_scan_state *ss, struct ieee80211com *ic)
  630 {
  631         struct sta_table *st = ss->ss_priv;
  632 
  633         st->st_newscan = 1;
  634         return 0;
  635 }
  636 
  637 /*
  638  * Cancel an ongoing scan.
  639  */
  640 static int
  641 sta_cancel(struct ieee80211_scan_state *ss, struct ieee80211com *ic)
  642 {
  643         return 0;
  644 }
  645 
  646 static uint8_t
  647 maxrate(const struct ieee80211_scan_entry *se)
  648 {
  649         uint8_t rmax, r;
  650         int i;
  651 
  652         rmax = 0;
  653         for (i = 0; i < se->se_rates[1]; i++) {
  654                 r = se->se_rates[2+i] & IEEE80211_RATE_VAL;
  655                 if (r > rmax)
  656                         rmax = r;
  657         }
  658         for (i = 0; i < se->se_xrates[1]; i++) {
  659                 r = se->se_xrates[2+i] & IEEE80211_RATE_VAL;
  660                 if (r > rmax)
  661                         rmax = r;
  662         }
  663         return rmax;
  664 }
  665 
  666 /*
  667  * Compare the capabilities of two entries and decide which is
  668  * more desirable (return >0 if a is considered better).  Note
  669  * that we assume compatibility/usability has already been checked
  670  * so we don't need to (e.g. validate whether privacy is supported).
  671  * Used to select the best scan candidate for association in a BSS.
  672  */
  673 static int
  674 sta_compare(const struct sta_entry *a, const struct sta_entry *b)
  675 {
  676 #define PREFER(_a,_b,_what) do {                        \
  677         if (((_a) ^ (_b)) & (_what))                    \
  678                 return ((_a) & (_what)) ? 1 : -1;       \
  679 } while (0)
  680         uint8_t maxa, maxb;
  681         int8_t rssia, rssib;
  682         int weight;
  683 
  684         /* privacy support */
  685         PREFER(a->base.se_capinfo, b->base.se_capinfo,
  686                 IEEE80211_CAPINFO_PRIVACY);
  687 
  688         /* compare count of previous failures */
  689         weight = b->se_fails - a->se_fails;
  690         if (abs(weight) > 1)
  691                 return weight;
  692 
  693         /*
  694          * Compare rssi.  If the two are considered equivalent
  695          * then fallback to other criteria.  We threshold the
  696          * comparisons to avoid selecting an ap purely by rssi
  697          * when both values may be good but one ap is otherwise
  698          * more desirable (e.g. an 11b-only ap with stronger
  699          * signal than an 11g ap).
  700          */
  701         rssia = MIN(a->base.se_rssi, STA_RSSI_MAX);
  702         rssib = MIN(b->base.se_rssi, STA_RSSI_MAX);
  703         if (abs(rssib - rssia) < 5) {
  704                 /* best/max rate preferred if signal level close enough XXX */
  705                 maxa = maxrate(&a->base);
  706                 maxb = maxrate(&b->base);
  707                 if (maxa != maxb)
  708                         return maxa - maxb;
  709                 /* XXX use freq for channel preference */
  710                 /* for now just prefer 5Ghz band to all other bands */
  711                 if (IEEE80211_IS_CHAN_5GHZ(a->base.se_chan) &&
  712                    !IEEE80211_IS_CHAN_5GHZ(b->base.se_chan))
  713                         return 1;
  714                 if (!IEEE80211_IS_CHAN_5GHZ(a->base.se_chan) &&
  715                      IEEE80211_IS_CHAN_5GHZ(b->base.se_chan))
  716                         return -1;
  717         }
  718         /* all things being equal, use signal level */
  719         return a->base.se_rssi - b->base.se_rssi;
  720 #undef PREFER
  721 }
  722 
  723 /*
  724  * Check rate set suitability and return the best supported rate.
  725  */
  726 static int
  727 check_rate(struct ieee80211com *ic, const struct ieee80211_scan_entry *se)
  728 {
  729 #define RV(v)   ((v) & IEEE80211_RATE_VAL)
  730         const struct ieee80211_rateset *srs;
  731         int i, j, nrs, r, okrate, badrate, fixedrate;
  732         const uint8_t *rs;
  733 
  734         okrate = badrate = fixedrate = 0;
  735 
  736         srs = ieee80211_get_suprates(ic, se->se_chan);
  737         nrs = se->se_rates[1];
  738         rs = se->se_rates+2;
  739         fixedrate = IEEE80211_FIXED_RATE_NONE;
  740 again:
  741         for (i = 0; i < nrs; i++) {
  742                 r = RV(rs[i]);
  743                 badrate = r;
  744                 /*
  745                  * Check any fixed rate is included. 
  746                  */
  747                 if (r == ic->ic_fixed_rate)
  748                         fixedrate = r;
  749                 /*
  750                  * Check against our supported rates.
  751                  */
  752                 for (j = 0; j < srs->rs_nrates; j++)
  753                         if (r == RV(srs->rs_rates[j])) {
  754                                 if (r > okrate)         /* NB: track max */
  755                                         okrate = r;
  756                                 break;
  757                         }
  758 
  759                 if (j == srs->rs_nrates && (rs[i] & IEEE80211_RATE_BASIC)) {
  760                         /*
  761                          * Don't try joining a BSS, if we don't support
  762                          * one of its basic rates.
  763                          */
  764                         okrate = 0;
  765                         goto back;
  766                 }
  767         }
  768         if (rs == se->se_rates+2) {
  769                 /* scan xrates too; sort of an algol68-style for loop */
  770                 nrs = se->se_xrates[1];
  771                 rs = se->se_xrates+2;
  772                 goto again;
  773         }
  774 
  775 back:
  776         if (okrate == 0 || ic->ic_fixed_rate != fixedrate)
  777                 return badrate | IEEE80211_RATE_BASIC;
  778         else
  779                 return RV(okrate);
  780 #undef RV
  781 }
  782 
  783 static int
  784 match_ssid(const uint8_t *ie,
  785         int nssid, const struct ieee80211_scan_ssid ssids[])
  786 {
  787         int i;
  788 
  789         for (i = 0; i < nssid; i++) {
  790                 if (ie[1] == ssids[i].len &&
  791                      memcmp(ie+2, ssids[i].ssid, ie[1]) == 0)
  792                         return 1;
  793         }
  794         return 0;
  795 }
  796 
  797 /*
  798  * Test a scan candidate for suitability/compatibility.
  799  */
  800 static int
  801 match_bss(struct ieee80211com *ic,
  802         const struct ieee80211_scan_state *ss, struct sta_entry *se0,
  803         int debug)
  804 {
  805         struct ieee80211_scan_entry *se = &se0->base;
  806         uint8_t rate;
  807         int fail;
  808 
  809         fail = 0;
  810         if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, se->se_chan)))
  811                 fail |= MATCH_CHANNEL;
  812         /*
  813          * NB: normally the desired mode is used to construct
  814          * the channel list, but it's possible for the scan
  815          * cache to include entries for stations outside this
  816          * list so we check the desired mode here to weed them
  817          * out.
  818          */
  819         if (ic->ic_des_mode != IEEE80211_MODE_AUTO &&
  820             (se->se_chan->ic_flags & IEEE80211_CHAN_ALLTURBO) !=
  821             chanflags[ic->ic_des_mode])
  822                 fail |= MATCH_CHANNEL;
  823         if (ic->ic_opmode == IEEE80211_M_IBSS) {
  824                 if ((se->se_capinfo & IEEE80211_CAPINFO_IBSS) == 0)
  825                         fail |= MATCH_CAPINFO;
  826         } else {
  827                 if ((se->se_capinfo & IEEE80211_CAPINFO_ESS) == 0)
  828                         fail |= MATCH_CAPINFO;
  829         }
  830         if (ic->ic_flags & IEEE80211_F_PRIVACY) {
  831                 if ((se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0)
  832                         fail |= MATCH_PRIVACY;
  833         } else {
  834                 /* XXX does this mean privacy is supported or required? */
  835                 if (se->se_capinfo & IEEE80211_CAPINFO_PRIVACY)
  836                         fail |= MATCH_PRIVACY;
  837         }
  838         rate = check_rate(ic, se);
  839         if (rate & IEEE80211_RATE_BASIC)
  840                 fail |= MATCH_RATE;
  841         if (ss->ss_nssid != 0 &&
  842             !match_ssid(se->se_ssid, ss->ss_nssid, ss->ss_ssid))
  843                 fail |= MATCH_SSID;
  844         if ((ic->ic_flags & IEEE80211_F_DESBSSID) &&
  845             !IEEE80211_ADDR_EQ(ic->ic_des_bssid, se->se_bssid))
  846                 fail |=  MATCH_BSSID;
  847         if (se0->se_fails >= STA_FAILS_MAX)
  848                 fail |= MATCH_FAILS;
  849         /* NB: entries may be present awaiting purge, skip */
  850         if (se0->se_notseen >= STA_PURGE_SCANS)
  851                 fail |= MATCH_NOTSEEN;
  852         if (se->se_rssi < STA_RSSI_MIN)
  853                 fail |= MATCH_RSSI;
  854 #ifdef IEEE80211_DEBUG
  855         if (ieee80211_msg(ic, debug)) {
  856                 printf(" %c %s",
  857                     fail & MATCH_FAILS ? '=' :
  858                     fail & MATCH_NOTSEEN ? '^' :
  859                     fail ? '-' : '+', ether_sprintf(se->se_macaddr));
  860                 printf(" %s%c", ether_sprintf(se->se_bssid),
  861                     fail & MATCH_BSSID ? '!' : ' ');
  862                 printf(" %3d%c", ieee80211_chan2ieee(ic, se->se_chan),
  863                         fail & MATCH_CHANNEL ? '!' : ' ');
  864                 printf(" %+4d%c", se->se_rssi, fail & MATCH_RSSI ? '!' : ' ');
  865                 printf(" %2dM%c", (rate & IEEE80211_RATE_VAL) / 2,
  866                     fail & MATCH_RATE ? '!' : ' ');
  867                 printf(" %4s%c",
  868                     (se->se_capinfo & IEEE80211_CAPINFO_ESS) ? "ess" :
  869                     (se->se_capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" :
  870                     "????",
  871                     fail & MATCH_CAPINFO ? '!' : ' ');
  872                 printf(" %3s%c ",
  873                     (se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) ?
  874                     "wep" : "no",
  875                     fail & MATCH_PRIVACY ? '!' : ' ');
  876                 ieee80211_print_essid(se->se_ssid+2, se->se_ssid[1]);
  877                 printf("%s\n", fail & MATCH_SSID ? "!" : "");
  878         }
  879 #endif
  880         return fail;
  881 }
  882 
  883 static void
  884 sta_update_notseen(struct sta_table *st)
  885 {
  886         struct sta_entry *se;
  887 
  888         mtx_lock(&st->st_lock);
  889         TAILQ_FOREACH(se, &st->st_entry, se_list) {
  890                 /*
  891                  * If seen the reset and don't bump the count;
  892                  * otherwise bump the ``not seen'' count.  Note
  893                  * that this insures that stations for which we
  894                  * see frames while not scanning but not during
  895                  * this scan will not be penalized.
  896                  */
  897                 if (se->se_seen)
  898                         se->se_seen = 0;
  899                 else
  900                         se->se_notseen++;
  901         }
  902         mtx_unlock(&st->st_lock);
  903 }
  904 
  905 static void
  906 sta_dec_fails(struct sta_table *st)
  907 {
  908         struct sta_entry *se;
  909 
  910         mtx_lock(&st->st_lock);
  911         TAILQ_FOREACH(se, &st->st_entry, se_list)
  912                 if (se->se_fails)
  913                         se->se_fails--;
  914         mtx_unlock(&st->st_lock);
  915 }
  916 
  917 static struct sta_entry *
  918 select_bss(struct ieee80211_scan_state *ss, struct ieee80211com *ic, int debug)
  919 {
  920         struct sta_table *st = ss->ss_priv;
  921         struct sta_entry *se, *selbs = NULL;
  922 
  923         IEEE80211_DPRINTF(ic, debug, " %s\n",
  924             "macaddr          bssid         chan  rssi  rate flag  wep  essid");
  925         mtx_lock(&st->st_lock);
  926         TAILQ_FOREACH(se, &st->st_entry, se_list) {
  927                 if (match_bss(ic, ss, se, debug) == 0) {
  928                         if (selbs == NULL)
  929                                 selbs = se;
  930                         else if (sta_compare(se, selbs) > 0)
  931                                 selbs = se;
  932                 }
  933         }
  934         mtx_unlock(&st->st_lock);
  935 
  936         return selbs;
  937 }
  938 
  939 /*
  940  * Pick an ap or ibss network to join or find a channel
  941  * to use to start an ibss network.
  942  */
  943 static int
  944 sta_pick_bss(struct ieee80211_scan_state *ss, struct ieee80211com *ic)
  945 {
  946         struct sta_table *st = ss->ss_priv;
  947         struct sta_entry *selbs;
  948 
  949         KASSERT(ic->ic_opmode == IEEE80211_M_STA,
  950                 ("wrong mode %u", ic->ic_opmode));
  951 
  952         if (st->st_newscan) {
  953                 sta_update_notseen(st);
  954                 st->st_newscan = 0;
  955         }
  956         if (ss->ss_flags & IEEE80211_SCAN_NOPICK) {
  957                 /*
  958                  * Manual/background scan, don't select+join the
  959                  * bss, just return.  The scanning framework will
  960                  * handle notification that this has completed.
  961                  */
  962                 ss->ss_flags &= ~IEEE80211_SCAN_NOPICK;
  963                 return 1;
  964         }
  965         /*
  966          * Automatic sequencing; look for a candidate and
  967          * if found join the network.
  968          */
  969         /* NB: unlocked read should be ok */
  970         if (TAILQ_FIRST(&st->st_entry) == NULL) {
  971                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
  972                         "%s: no scan candidate\n", __func__);
  973 notfound:
  974                 /*
  975                  * If nothing suitable was found decrement
  976                  * the failure counts so entries will be
  977                  * reconsidered the next time around.  We
  978                  * really want to do this only for sta's
  979                  * where we've previously had some success.
  980                  */
  981                 sta_dec_fails(st);
  982                 st->st_newscan = 1;
  983                 return 0;                       /* restart scan */
  984         }
  985         selbs = select_bss(ss, ic, IEEE80211_MSG_SCAN);
  986         if (selbs == NULL || !ieee80211_sta_join(ic, &selbs->base))
  987                 goto notfound;
  988         return 1;                               /* terminate scan */
  989 }
  990 
  991 /*
  992  * Lookup an entry in the scan cache.  We assume we're
  993  * called from the bottom half or such that we don't need
  994  * to block the bottom half so that it's safe to return
  995  * a reference to an entry w/o holding the lock on the table.
  996  */
  997 static struct sta_entry *
  998 sta_lookup(struct sta_table *st, const uint8_t macaddr[IEEE80211_ADDR_LEN])
  999 {
 1000         struct sta_entry *se;
 1001         int hash = STA_HASH(macaddr);
 1002 
 1003         mtx_lock(&st->st_lock);
 1004         LIST_FOREACH(se, &st->st_hash[hash], se_hash)
 1005                 if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr))
 1006                         break;
 1007         mtx_unlock(&st->st_lock);
 1008 
 1009         return se;              /* NB: unlocked */
 1010 }
 1011 
 1012 static void
 1013 sta_roam_check(struct ieee80211_scan_state *ss, struct ieee80211com *ic)
 1014 {
 1015         struct ieee80211_node *ni = ic->ic_bss;
 1016         struct sta_table *st = ss->ss_priv;
 1017         struct sta_entry *se, *selbs;
 1018         uint8_t roamRate, curRate;
 1019         int8_t roamRssi, curRssi;
 1020 
 1021         se = sta_lookup(st, ni->ni_macaddr);
 1022         if (se == NULL) {
 1023                 /* XXX something is wrong */
 1024                 return;
 1025         }
 1026 
 1027         /* XXX do we need 11g too? */
 1028         if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) {
 1029                 roamRate = ic->ic_roam.rate11b;
 1030                 roamRssi = ic->ic_roam.rssi11b;
 1031         } else if (IEEE80211_IS_CHAN_B(ic->ic_bsschan)) {
 1032                 roamRate = ic->ic_roam.rate11bOnly;
 1033                 roamRssi = ic->ic_roam.rssi11bOnly;
 1034         } else {
 1035                 roamRate = ic->ic_roam.rate11a;
 1036                 roamRssi = ic->ic_roam.rssi11a;
 1037         }
 1038         /* NB: the most up to date rssi is in the node, not the scan cache */
 1039         curRssi = ic->ic_node_getrssi(ni);
 1040         if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
 1041                 curRate = ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL;
 1042                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ROAM,
 1043                     "%s: currssi %d currate %u roamrssi %d roamrate %u\n",
 1044                     __func__, curRssi, curRate, roamRssi, roamRate);
 1045         } else {
 1046                 curRate = roamRate;     /* NB: insure compare below fails */
 1047                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ROAM,
 1048                     "%s: currssi %d roamrssi %d\n", __func__, curRssi, roamRssi);
 1049         }
 1050         /*
 1051          * Check if a new ap should be used and switch.
 1052          * XXX deauth current ap
 1053          */
 1054         if (curRate < roamRate || curRssi < roamRssi) {
 1055                 if (time_after(ticks, ic->ic_lastscan + ic->ic_scanvalid)) {
 1056                         /*
 1057                          * Scan cache contents are too old; force a scan now
 1058                          * if possible so we have current state to make a
 1059                          * decision with.  We don't kick off a bg scan if
 1060                          * we're using dynamic turbo and boosted or if the
 1061                          * channel is busy.
 1062                          * XXX force immediate switch on scan complete
 1063                          */
 1064                         if (!IEEE80211_IS_CHAN_DTURBO(ic->ic_curchan) &&
 1065                             time_after(ticks, ic->ic_lastdata + ic->ic_bgscanidle))
 1066                                 ieee80211_bg_scan(ic);
 1067                         return;
 1068                 }
 1069                 se->base.se_rssi = curRssi;
 1070                 selbs = select_bss(ss, ic, IEEE80211_MSG_ROAM);
 1071                 if (selbs != NULL && selbs != se) {
 1072                         IEEE80211_DPRINTF(ic,
 1073                             IEEE80211_MSG_ROAM | IEEE80211_MSG_DEBUG,
 1074                             "%s: ROAM: curRate %u, roamRate %u, "
 1075                             "curRssi %d, roamRssi %d\n", __func__,
 1076                             curRate, roamRate, curRssi, roamRssi);
 1077                         ieee80211_sta_join(ic, &selbs->base);
 1078                 }
 1079         }
 1080 }
 1081 
 1082 /*
 1083  * Age entries in the scan cache.
 1084  * XXX also do roaming since it's convenient
 1085  */
 1086 static void
 1087 sta_age(struct ieee80211_scan_state *ss)
 1088 {
 1089         struct ieee80211com *ic = ss->ss_ic;
 1090         struct sta_table *st = ss->ss_priv;
 1091         struct sta_entry *se, *next;
 1092 
 1093         mtx_lock(&st->st_lock);
 1094         TAILQ_FOREACH_SAFE(se, &st->st_entry, se_list, next) {
 1095                 if (se->se_notseen > STA_PURGE_SCANS) {
 1096                         TAILQ_REMOVE(&st->st_entry, se, se_list);
 1097                         LIST_REMOVE(se, se_hash);
 1098                         FREE(se, M_80211_SCAN);
 1099                 }
 1100         }
 1101         mtx_unlock(&st->st_lock);
 1102         /*
 1103          * If rate control is enabled check periodically to see if
 1104          * we should roam from our current connection to one that
 1105          * might be better.  This only applies when we're operating
 1106          * in sta mode and automatic roaming is set.
 1107          * XXX defer if busy
 1108          * XXX repeater station
 1109          * XXX do when !bgscan?
 1110          */
 1111         KASSERT(ic->ic_opmode == IEEE80211_M_STA,
 1112                 ("wrong mode %u", ic->ic_opmode));
 1113         if (ic->ic_roaming == IEEE80211_ROAMING_AUTO &&
 1114             (ic->ic_flags & IEEE80211_F_BGSCAN) &&
 1115             ic->ic_state >= IEEE80211_S_RUN)
 1116                 /* XXX vap is implicit */
 1117                 sta_roam_check(ss, ic);
 1118 }
 1119 
 1120 /*
 1121  * Iterate over the entries in the scan cache, invoking
 1122  * the callback function on each one.
 1123  */
 1124 static void
 1125 sta_iterate(struct ieee80211_scan_state *ss, 
 1126         ieee80211_scan_iter_func *f, void *arg)
 1127 {
 1128         struct sta_table *st = ss->ss_priv;
 1129         struct sta_entry *se;
 1130         u_int gen;
 1131 
 1132         mtx_lock(&st->st_scanlock);
 1133         gen = st->st_scangen++;
 1134 restart:
 1135         mtx_lock(&st->st_lock);
 1136         TAILQ_FOREACH(se, &st->st_entry, se_list) {
 1137                 if (se->se_scangen != gen) {
 1138                         se->se_scangen = gen;
 1139                         /* update public state */
 1140                         se->base.se_age = ticks - se->se_lastupdate;
 1141                         mtx_unlock(&st->st_lock);
 1142                         (*f)(arg, &se->base);
 1143                         goto restart;
 1144                 }
 1145         }
 1146         mtx_unlock(&st->st_lock);
 1147 
 1148         mtx_unlock(&st->st_scanlock);
 1149 }
 1150 
 1151 static void
 1152 sta_assoc_fail(struct ieee80211_scan_state *ss,
 1153         const uint8_t macaddr[IEEE80211_ADDR_LEN], int reason)
 1154 {
 1155         struct sta_table *st = ss->ss_priv;
 1156         struct sta_entry *se;
 1157 
 1158         se = sta_lookup(st, macaddr);
 1159         if (se != NULL) {
 1160                 se->se_fails++;
 1161                 se->se_lastfail = ticks;
 1162                 IEEE80211_NOTE_MAC(ss->ss_ic, IEEE80211_MSG_SCAN,
 1163                     macaddr, "%s: reason %u fails %u",
 1164                     __func__, reason, se->se_fails);
 1165         }
 1166 }
 1167 
 1168 static void
 1169 sta_assoc_success(struct ieee80211_scan_state *ss,
 1170         const uint8_t macaddr[IEEE80211_ADDR_LEN])
 1171 {
 1172         struct sta_table *st = ss->ss_priv;
 1173         struct sta_entry *se;
 1174 
 1175         se = sta_lookup(st, macaddr);
 1176         if (se != NULL) {
 1177 #if 0
 1178                 se->se_fails = 0;
 1179                 IEEE80211_NOTE_MAC(ss->ss_ic, IEEE80211_MSG_SCAN,
 1180                     macaddr, "%s: fails %u",
 1181                     __func__, se->se_fails);
 1182 #endif
 1183                 se->se_lastassoc = ticks;
 1184         }
 1185 }
 1186 
 1187 static const struct ieee80211_scanner sta_default = {
 1188         .scan_name              = "default",
 1189         .scan_attach            = sta_attach,
 1190         .scan_detach            = sta_detach,
 1191         .scan_start             = sta_start,
 1192         .scan_restart           = sta_restart,
 1193         .scan_cancel            = sta_cancel,
 1194         .scan_end               = sta_pick_bss,
 1195         .scan_flush             = sta_flush,
 1196         .scan_add               = sta_add,
 1197         .scan_age               = sta_age,
 1198         .scan_iterate           = sta_iterate,
 1199         .scan_assoc_fail        = sta_assoc_fail,
 1200         .scan_assoc_success     = sta_assoc_success,
 1201 };
 1202 
 1203 /*
 1204  * Adhoc mode-specific support.
 1205  */
 1206 
 1207 static const uint16_t adhocWorld[] =            /* 36, 40, 44, 48 */
 1208 { 5180, 5200, 5220, 5240 };
 1209 static const uint16_t adhocFcc3[] =             /* 36, 40, 44, 48 145, 149, 153, 157, 161, 165 */
 1210 { 5180, 5200, 5220, 5240, 5725, 5745, 5765, 5785, 5805, 5825 };
 1211 static const uint16_t adhocMkk[] =              /* 34, 38, 42, 46 */
 1212 { 5170, 5190, 5210, 5230 };
 1213 static const uint16_t adhoc11b[] =              /* 10, 11 */
 1214 { 2457, 2462 };
 1215 
 1216 static const struct scanlist adhocScanTable[] = {
 1217         { IEEE80211_MODE_11B,           X(adhoc11b) },
 1218         { IEEE80211_MODE_11A,           X(adhocWorld) },
 1219         { IEEE80211_MODE_11A,           X(adhocFcc3) },
 1220         { IEEE80211_MODE_11B,           X(adhocMkk) },
 1221         { .list = NULL }
 1222 };
 1223 #undef X
 1224 
 1225 /*
 1226  * Start an adhoc-mode scan by populating the channel list.
 1227  */
 1228 static int
 1229 adhoc_start(struct ieee80211_scan_state *ss, struct ieee80211com *ic)
 1230 {
 1231 #define N(a)    (sizeof(a)/sizeof(a[0]))
 1232         struct sta_table *st = ss->ss_priv;
 1233         const struct scanlist *scan;
 1234         enum ieee80211_phymode mode;
 1235         
 1236         ss->ss_last = 0;
 1237         /*
 1238          * Use the table of ordered channels to construct the list
 1239          * of channels for scanning.  Any channels in the ordered
 1240          * list not in the master list will be discarded.
 1241          */
 1242         for (scan = adhocScanTable; scan->list != NULL; scan++) {
 1243                 mode = scan->mode;
 1244                 if (ic->ic_des_mode != IEEE80211_MODE_AUTO) {
 1245                         /*
 1246                          * If a desired mode was specified, scan only 
 1247                          * channels that satisfy that constraint.
 1248                          */
 1249                         if (ic->ic_des_mode != mode) {
 1250                                 /*
 1251                                  * The scan table marks 2.4Ghz channels as b
 1252                                  * so if the desired mode is 11g, then use
 1253                                  * the 11b channel list but upgrade the mode.
 1254                                  */
 1255                                 if (ic->ic_des_mode != IEEE80211_MODE_11G ||
 1256                                     mode != IEEE80211_MODE_11B)
 1257                                         continue;
 1258                                 mode = IEEE80211_MODE_11G;      /* upgrade */
 1259                         }
 1260                 } else {
 1261                         /*
 1262                          * This lets add_channels upgrade an 11b channel
 1263                          * to 11g if available.
 1264                          */
 1265                         if (mode == IEEE80211_MODE_11B)
 1266                                 mode = IEEE80211_MODE_AUTO;
 1267                 }
 1268 #ifdef IEEE80211_F_XR
 1269                 /* XR does not operate on turbo channels */
 1270                 if ((ic->ic_flags & IEEE80211_F_XR) &&
 1271                     (mode == IEEE80211_MODE_TURBO_A ||
 1272                      mode == IEEE80211_MODE_TURBO_G))
 1273                         continue;
 1274 #endif
 1275                 /*
 1276                  * Add the list of the channels; any that are not
 1277                  * in the master channel list will be discarded.
 1278                  */
 1279                 add_channels(ic, ss, mode, scan->list, scan->count);
 1280         }
 1281 
 1282         /*
 1283          * Add the channels from the ic (from HAL) that are not present
 1284          * in the staScanTable.
 1285          */
 1286         sweepchannels(ss, ic, adhocScanTable);
 1287 
 1288         ss->ss_next = 0;
 1289         /* XXX tunables */
 1290         ss->ss_mindwell = msecs_to_ticks(200);          /* 200ms */
 1291         ss->ss_maxdwell = msecs_to_ticks(200);          /* 200ms */
 1292 
 1293 #ifdef IEEE80211_DEBUG
 1294         if (ieee80211_msg_scan(ic)) {
 1295                 if_printf(ic->ic_ifp, "scan set ");
 1296                 ieee80211_scan_dump_channels(ss);
 1297                 printf(" dwell min %ld max %ld\n",
 1298                         ss->ss_mindwell, ss->ss_maxdwell);
 1299         }
 1300 #endif /* IEEE80211_DEBUG */
 1301 
 1302         st->st_newscan = 1;
 1303 
 1304         return 0;
 1305 #undef N
 1306 }
 1307 
 1308 /*
 1309  * Select a channel to start an adhoc network on.
 1310  * The channel list was populated with appropriate
 1311  * channels so select one that looks least occupied.
 1312  * XXX need regulatory domain constraints
 1313  */
 1314 static struct ieee80211_channel *
 1315 adhoc_pick_channel(struct ieee80211_scan_state *ss)
 1316 {
 1317         struct sta_table *st = ss->ss_priv;
 1318         struct sta_entry *se;
 1319         struct ieee80211_channel *c, *bestchan;
 1320         int i, bestrssi, maxrssi;
 1321 
 1322         bestchan = NULL;
 1323         bestrssi = -1;
 1324 
 1325         mtx_lock(&st->st_lock);
 1326         for (i = 0; i < ss->ss_last; i++) {
 1327                 c = ss->ss_chans[i];
 1328                 if (!checktable(adhocScanTable, c))
 1329                         continue;
 1330                 maxrssi = 0;
 1331                 TAILQ_FOREACH(se, &st->st_entry, se_list) {
 1332                         if (se->base.se_chan != c)
 1333                                 continue;
 1334                         if (se->base.se_rssi > maxrssi)
 1335                                 maxrssi = se->base.se_rssi;
 1336                 }
 1337                 if (bestchan == NULL || maxrssi < bestrssi)
 1338                         bestchan = c;
 1339         }
 1340         mtx_unlock(&st->st_lock);
 1341 
 1342         return bestchan;
 1343 }
 1344 
 1345 /*
 1346  * Pick an ibss network to join or find a channel
 1347  * to use to start an ibss network.
 1348  */
 1349 static int
 1350 adhoc_pick_bss(struct ieee80211_scan_state *ss, struct ieee80211com *ic)
 1351 {
 1352         struct sta_table *st = ss->ss_priv;
 1353         struct sta_entry *selbs;
 1354         struct ieee80211_channel *chan;
 1355 
 1356         KASSERT(ic->ic_opmode == IEEE80211_M_IBSS ||
 1357                 ic->ic_opmode == IEEE80211_M_AHDEMO,
 1358                 ("wrong opmode %u", ic->ic_opmode));
 1359 
 1360         if (st->st_newscan) {
 1361                 sta_update_notseen(st);
 1362                 st->st_newscan = 0;
 1363         }
 1364         if (ss->ss_flags & IEEE80211_SCAN_NOPICK) {
 1365                 /*
 1366                  * Manual/background scan, don't select+join the
 1367                  * bss, just return.  The scanning framework will
 1368                  * handle notification that this has completed.
 1369                  */
 1370                 ss->ss_flags &= ~IEEE80211_SCAN_NOPICK;
 1371                 return 1;
 1372         }
 1373         /*
 1374          * Automatic sequencing; look for a candidate and
 1375          * if found join the network.
 1376          */
 1377         /* NB: unlocked read should be ok */
 1378         if (TAILQ_FIRST(&st->st_entry) == NULL) {
 1379                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
 1380                         "%s: no scan candidate\n", __func__);
 1381 notfound:
 1382                 if (ic->ic_des_nssid) {
 1383                         /*
 1384                          * No existing adhoc network to join and we have
 1385                          * an ssid; start one up.  If no channel was
 1386                          * specified, try to select a channel.
 1387                          */
 1388                         if (ic->ic_des_chan == IEEE80211_CHAN_ANYC)
 1389                                 chan = ieee80211_ht_adjust_channel(ic,
 1390                                     adhoc_pick_channel(ss), ic->ic_flags_ext);
 1391                         else
 1392                                 chan = ic->ic_des_chan;
 1393                         if (chan != NULL) {
 1394                                 ieee80211_create_ibss(ic, chan);
 1395                                 return 1;
 1396                         }
 1397                 }
 1398                 /*
 1399                  * If nothing suitable was found decrement
 1400                  * the failure counts so entries will be
 1401                  * reconsidered the next time around.  We
 1402                  * really want to do this only for sta's
 1403                  * where we've previously had some success.
 1404                  */
 1405                 sta_dec_fails(st);
 1406                 st->st_newscan = 1;
 1407                 return 0;                       /* restart scan */
 1408         }
 1409         selbs = select_bss(ss, ic, IEEE80211_MSG_SCAN);
 1410         if (selbs == NULL || !ieee80211_sta_join(ic, &selbs->base))
 1411                 goto notfound;
 1412         return 1;                               /* terminate scan */
 1413 }
 1414 
 1415 /*
 1416  * Age entries in the scan cache.
 1417  */
 1418 static void
 1419 adhoc_age(struct ieee80211_scan_state *ss)
 1420 {
 1421         struct sta_table *st = ss->ss_priv;
 1422         struct sta_entry *se, *next;
 1423 
 1424         mtx_lock(&st->st_lock);
 1425         TAILQ_FOREACH_SAFE(se, &st->st_entry, se_list, next) {
 1426                 if (se->se_notseen > STA_PURGE_SCANS) {
 1427                         TAILQ_REMOVE(&st->st_entry, se, se_list);
 1428                         LIST_REMOVE(se, se_hash);
 1429                         FREE(se, M_80211_SCAN);
 1430                 }
 1431         }
 1432         mtx_unlock(&st->st_lock);
 1433 }
 1434 
 1435 static const struct ieee80211_scanner adhoc_default = {
 1436         .scan_name              = "default",
 1437         .scan_attach            = sta_attach,
 1438         .scan_detach            = sta_detach,
 1439         .scan_start             = adhoc_start,
 1440         .scan_restart           = sta_restart,
 1441         .scan_cancel            = sta_cancel,
 1442         .scan_end               = adhoc_pick_bss,
 1443         .scan_flush             = sta_flush,
 1444         .scan_add               = sta_add,
 1445         .scan_age               = adhoc_age,
 1446         .scan_iterate           = sta_iterate,
 1447         .scan_assoc_fail        = sta_assoc_fail,
 1448         .scan_assoc_success     = sta_assoc_success,
 1449 };
 1450 
 1451 /*
 1452  * Module glue.
 1453  */
 1454 static int
 1455 wlan_modevent(module_t mod, int type, void *unused)
 1456 {
 1457         switch (type) {
 1458         case MOD_LOAD:
 1459                 ieee80211_scanner_register(IEEE80211_M_STA, &sta_default);
 1460                 ieee80211_scanner_register(IEEE80211_M_IBSS, &adhoc_default);
 1461                 ieee80211_scanner_register(IEEE80211_M_AHDEMO, &adhoc_default);
 1462                 return 0;
 1463         case MOD_UNLOAD:
 1464         case MOD_QUIESCE:
 1465                 if (nrefs) {
 1466                         printf("wlan_scan_sta: still in use (%u dynamic refs)\n",
 1467                                 nrefs);
 1468                         return EBUSY;
 1469                 }
 1470                 if (type == MOD_UNLOAD) {
 1471                         ieee80211_scanner_unregister_all(&sta_default);
 1472                         ieee80211_scanner_unregister_all(&adhoc_default);
 1473                 }
 1474                 return 0;
 1475         }
 1476         return EINVAL;
 1477 }
 1478 
 1479 static moduledata_t wlan_mod = {
 1480         "wlan_scan_sta",
 1481         wlan_modevent,
 1482         0
 1483 };
 1484 DECLARE_MODULE(wlan_scan_sta, wlan_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
 1485 MODULE_VERSION(wlan_scan_sta, 1);
 1486 MODULE_DEPEND(wlan_scan_sta, wlan, 1, 1, 1);

Cache object: b36ac68db3f80e513369d86d501ffece


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.