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

Cache object: 5457bb3c7f985de67a26eadf67913cf9


[ 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.