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.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) 2001 Atsushi Onoe
    3  * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 /*
   31  * IEEE 802.11 generic handler
   32  */
   33 #include "opt_wlan.h"
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/kernel.h>
   38 #include <sys/malloc.h>
   39 #include <sys/socket.h>
   40 #include <sys/sbuf.h>
   41 
   42 #include <machine/stdarg.h>
   43 
   44 #include <net/if.h>
   45 #include <net/if_var.h>
   46 #include <net/if_dl.h>
   47 #include <net/if_media.h>
   48 #include <net/if_types.h>
   49 #include <net/ethernet.h>
   50 
   51 #include <net80211/ieee80211_var.h>
   52 #include <net80211/ieee80211_regdomain.h>
   53 #ifdef IEEE80211_SUPPORT_SUPERG
   54 #include <net80211/ieee80211_superg.h>
   55 #endif
   56 #include <net80211/ieee80211_ratectl.h>
   57 
   58 #include <net/bpf.h>
   59 
   60 const char *ieee80211_phymode_name[IEEE80211_MODE_MAX] = {
   61         [IEEE80211_MODE_AUTO]     = "auto",
   62         [IEEE80211_MODE_11A]      = "11a",
   63         [IEEE80211_MODE_11B]      = "11b",
   64         [IEEE80211_MODE_11G]      = "11g",
   65         [IEEE80211_MODE_FH]       = "FH",
   66         [IEEE80211_MODE_TURBO_A]  = "turboA",
   67         [IEEE80211_MODE_TURBO_G]  = "turboG",
   68         [IEEE80211_MODE_STURBO_A] = "sturboA",
   69         [IEEE80211_MODE_HALF]     = "half",
   70         [IEEE80211_MODE_QUARTER]  = "quarter",
   71         [IEEE80211_MODE_11NA]     = "11na",
   72         [IEEE80211_MODE_11NG]     = "11ng",
   73 };
   74 /* map ieee80211_opmode to the corresponding capability bit */
   75 const int ieee80211_opcap[IEEE80211_OPMODE_MAX] = {
   76         [IEEE80211_M_IBSS]      = IEEE80211_C_IBSS,
   77         [IEEE80211_M_WDS]       = IEEE80211_C_WDS,
   78         [IEEE80211_M_STA]       = IEEE80211_C_STA,
   79         [IEEE80211_M_AHDEMO]    = IEEE80211_C_AHDEMO,
   80         [IEEE80211_M_HOSTAP]    = IEEE80211_C_HOSTAP,
   81         [IEEE80211_M_MONITOR]   = IEEE80211_C_MONITOR,
   82 #ifdef IEEE80211_SUPPORT_MESH
   83         [IEEE80211_M_MBSS]      = IEEE80211_C_MBSS,
   84 #endif
   85 };
   86 
   87 const uint8_t ieee80211broadcastaddr[IEEE80211_ADDR_LEN] =
   88         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
   89 
   90 static  void ieee80211_syncflag_locked(struct ieee80211com *ic, int flag);
   91 static  void ieee80211_syncflag_ht_locked(struct ieee80211com *ic, int flag);
   92 static  void ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag);
   93 static  int ieee80211_media_setup(struct ieee80211com *ic,
   94                 struct ifmedia *media, int caps, int addsta,
   95                 ifm_change_cb_t media_change, ifm_stat_cb_t media_stat);
   96 static  int media_status(enum ieee80211_opmode,
   97                 const struct ieee80211_channel *);
   98 static uint64_t ieee80211_get_counter(struct ifnet *, ift_counter);
   99 
  100 MALLOC_DEFINE(M_80211_VAP, "80211vap", "802.11 vap state");
  101 
  102 /*
  103  * Default supported rates for 802.11 operation (in IEEE .5Mb units).
  104  */
  105 #define B(r)    ((r) | IEEE80211_RATE_BASIC)
  106 static const struct ieee80211_rateset ieee80211_rateset_11a =
  107         { 8, { B(12), 18, B(24), 36, B(48), 72, 96, 108 } };
  108 static const struct ieee80211_rateset ieee80211_rateset_half =
  109         { 8, { B(6), 9, B(12), 18, B(24), 36, 48, 54 } };
  110 static const struct ieee80211_rateset ieee80211_rateset_quarter =
  111         { 8, { B(3), 4, B(6), 9, B(12), 18, 24, 27 } };
  112 static const struct ieee80211_rateset ieee80211_rateset_11b =
  113         { 4, { B(2), B(4), B(11), B(22) } };
  114 /* NB: OFDM rates are handled specially based on mode */
  115 static const struct ieee80211_rateset ieee80211_rateset_11g =
  116         { 12, { B(2), B(4), B(11), B(22), 12, 18, 24, 36, 48, 72, 96, 108 } };
  117 #undef B
  118 
  119 /*
  120  * Fill in 802.11 available channel set, mark
  121  * all available channels as active, and pick
  122  * a default channel if not already specified.
  123  */
  124 void
  125 ieee80211_chan_init(struct ieee80211com *ic)
  126 {
  127 #define DEFAULTRATES(m, def) do { \
  128         if (ic->ic_sup_rates[m].rs_nrates == 0) \
  129                 ic->ic_sup_rates[m] = def; \
  130 } while (0)
  131         struct ieee80211_channel *c;
  132         int i;
  133 
  134         KASSERT(0 < ic->ic_nchans && ic->ic_nchans <= IEEE80211_CHAN_MAX,
  135                 ("invalid number of channels specified: %u", ic->ic_nchans));
  136         memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
  137         memset(ic->ic_modecaps, 0, sizeof(ic->ic_modecaps));
  138         setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO);
  139         for (i = 0; i < ic->ic_nchans; i++) {
  140                 c = &ic->ic_channels[i];
  141                 KASSERT(c->ic_flags != 0, ("channel with no flags"));
  142                 /*
  143                  * Help drivers that work only with frequencies by filling
  144                  * in IEEE channel #'s if not already calculated.  Note this
  145                  * mimics similar work done in ieee80211_setregdomain when
  146                  * changing regulatory state.
  147                  */
  148                 if (c->ic_ieee == 0)
  149                         c->ic_ieee = ieee80211_mhz2ieee(c->ic_freq,c->ic_flags);
  150                 if (IEEE80211_IS_CHAN_HT40(c) && c->ic_extieee == 0)
  151                         c->ic_extieee = ieee80211_mhz2ieee(c->ic_freq +
  152                             (IEEE80211_IS_CHAN_HT40U(c) ? 20 : -20),
  153                             c->ic_flags);
  154                 /* default max tx power to max regulatory */
  155                 if (c->ic_maxpower == 0)
  156                         c->ic_maxpower = 2*c->ic_maxregpower;
  157                 setbit(ic->ic_chan_avail, c->ic_ieee);
  158                 /*
  159                  * Identify mode capabilities.
  160                  */
  161                 if (IEEE80211_IS_CHAN_A(c))
  162                         setbit(ic->ic_modecaps, IEEE80211_MODE_11A);
  163                 if (IEEE80211_IS_CHAN_B(c))
  164                         setbit(ic->ic_modecaps, IEEE80211_MODE_11B);
  165                 if (IEEE80211_IS_CHAN_ANYG(c))
  166                         setbit(ic->ic_modecaps, IEEE80211_MODE_11G);
  167                 if (IEEE80211_IS_CHAN_FHSS(c))
  168                         setbit(ic->ic_modecaps, IEEE80211_MODE_FH);
  169                 if (IEEE80211_IS_CHAN_108A(c))
  170                         setbit(ic->ic_modecaps, IEEE80211_MODE_TURBO_A);
  171                 if (IEEE80211_IS_CHAN_108G(c))
  172                         setbit(ic->ic_modecaps, IEEE80211_MODE_TURBO_G);
  173                 if (IEEE80211_IS_CHAN_ST(c))
  174                         setbit(ic->ic_modecaps, IEEE80211_MODE_STURBO_A);
  175                 if (IEEE80211_IS_CHAN_HALF(c))
  176                         setbit(ic->ic_modecaps, IEEE80211_MODE_HALF);
  177                 if (IEEE80211_IS_CHAN_QUARTER(c))
  178                         setbit(ic->ic_modecaps, IEEE80211_MODE_QUARTER);
  179                 if (IEEE80211_IS_CHAN_HTA(c))
  180                         setbit(ic->ic_modecaps, IEEE80211_MODE_11NA);
  181                 if (IEEE80211_IS_CHAN_HTG(c))
  182                         setbit(ic->ic_modecaps, IEEE80211_MODE_11NG);
  183         }
  184         /* initialize candidate channels to all available */
  185         memcpy(ic->ic_chan_active, ic->ic_chan_avail,
  186                 sizeof(ic->ic_chan_avail));
  187 
  188         /* sort channel table to allow lookup optimizations */
  189         ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
  190 
  191         /* invalidate any previous state */
  192         ic->ic_bsschan = IEEE80211_CHAN_ANYC;
  193         ic->ic_prevchan = NULL;
  194         ic->ic_csa_newchan = NULL;
  195         /* arbitrarily pick the first channel */
  196         ic->ic_curchan = &ic->ic_channels[0];
  197         ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan);
  198 
  199         /* fillin well-known rate sets if driver has not specified */
  200         DEFAULTRATES(IEEE80211_MODE_11B,         ieee80211_rateset_11b);
  201         DEFAULTRATES(IEEE80211_MODE_11G,         ieee80211_rateset_11g);
  202         DEFAULTRATES(IEEE80211_MODE_11A,         ieee80211_rateset_11a);
  203         DEFAULTRATES(IEEE80211_MODE_TURBO_A,     ieee80211_rateset_11a);
  204         DEFAULTRATES(IEEE80211_MODE_TURBO_G,     ieee80211_rateset_11g);
  205         DEFAULTRATES(IEEE80211_MODE_STURBO_A,    ieee80211_rateset_11a);
  206         DEFAULTRATES(IEEE80211_MODE_HALF,        ieee80211_rateset_half);
  207         DEFAULTRATES(IEEE80211_MODE_QUARTER,     ieee80211_rateset_quarter);
  208         DEFAULTRATES(IEEE80211_MODE_11NA,        ieee80211_rateset_11a);
  209         DEFAULTRATES(IEEE80211_MODE_11NG,        ieee80211_rateset_11g);
  210 
  211         /*
  212          * Setup required information to fill the mcsset field, if driver did
  213          * not. Assume a 2T2R setup for historic reasons.
  214          */
  215         if (ic->ic_rxstream == 0)
  216                 ic->ic_rxstream = 2;
  217         if (ic->ic_txstream == 0)
  218                 ic->ic_txstream = 2;
  219 
  220         /*
  221          * Set auto mode to reset active channel state and any desired channel.
  222          */
  223         (void) ieee80211_setmode(ic, IEEE80211_MODE_AUTO);
  224 #undef DEFAULTRATES
  225 }
  226 
  227 static void
  228 null_update_mcast(struct ieee80211com *ic)
  229 {
  230 
  231         ic_printf(ic, "need multicast update callback\n");
  232 }
  233 
  234 static void
  235 null_update_promisc(struct ieee80211com *ic)
  236 {
  237 
  238         ic_printf(ic, "need promiscuous mode update callback\n");
  239 }
  240 
  241 static void
  242 null_update_chw(struct ieee80211com *ic)
  243 {
  244 
  245         ic_printf(ic, "%s: need callback\n", __func__);
  246 }
  247 
  248 int
  249 ic_printf(struct ieee80211com *ic, const char * fmt, ...)
  250 {
  251         va_list ap;
  252         int retval;
  253 
  254         retval = printf("%s: ", ic->ic_name);
  255         va_start(ap, fmt);
  256         retval += vprintf(fmt, ap);
  257         va_end(ap);
  258         return (retval);
  259 }
  260 
  261 static LIST_HEAD(, ieee80211com) ic_head = LIST_HEAD_INITIALIZER(ic_head);
  262 static struct mtx ic_list_mtx;
  263 MTX_SYSINIT(ic_list, &ic_list_mtx, "ieee80211com list", MTX_DEF);
  264 
  265 static int
  266 sysctl_ieee80211coms(SYSCTL_HANDLER_ARGS)
  267 {
  268         struct ieee80211com *ic;
  269         struct sbuf sb;
  270         char *sp;
  271         int error;
  272 
  273         error = sysctl_wire_old_buffer(req, 0);
  274         if (error)
  275                 return (error);
  276         sbuf_new_for_sysctl(&sb, NULL, 8, req);
  277         sbuf_clear_flags(&sb, SBUF_INCLUDENUL);
  278         sp = "";
  279         mtx_lock(&ic_list_mtx);
  280         LIST_FOREACH(ic, &ic_head, ic_next) {
  281                 sbuf_printf(&sb, "%s%s", sp, ic->ic_name);
  282                 sp = " ";
  283         }
  284         mtx_unlock(&ic_list_mtx);
  285         error = sbuf_finish(&sb);
  286         sbuf_delete(&sb);
  287         return (error);
  288 }
  289 
  290 SYSCTL_PROC(_net_wlan, OID_AUTO, devices,
  291     CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
  292     sysctl_ieee80211coms, "A", "names of available 802.11 devices");
  293 
  294 /*
  295  * Attach/setup the common net80211 state.  Called by
  296  * the driver on attach to prior to creating any vap's.
  297  */
  298 void
  299 ieee80211_ifattach(struct ieee80211com *ic)
  300 {
  301 
  302         IEEE80211_LOCK_INIT(ic, ic->ic_name);
  303         IEEE80211_TX_LOCK_INIT(ic, ic->ic_name);
  304         TAILQ_INIT(&ic->ic_vaps);
  305 
  306         /* Create a taskqueue for all state changes */
  307         ic->ic_tq = taskqueue_create("ic_taskq", M_WAITOK | M_ZERO,
  308             taskqueue_thread_enqueue, &ic->ic_tq);
  309         taskqueue_start_threads(&ic->ic_tq, 1, PI_NET, "%s net80211 taskq",
  310             ic->ic_name);
  311         ic->ic_ierrors = counter_u64_alloc(M_WAITOK);
  312         ic->ic_oerrors = counter_u64_alloc(M_WAITOK);
  313         /*
  314          * Fill in 802.11 available channel set, mark all
  315          * available channels as active, and pick a default
  316          * channel if not already specified.
  317          */
  318         ieee80211_chan_init(ic);
  319 
  320         ic->ic_update_mcast = null_update_mcast;
  321         ic->ic_update_promisc = null_update_promisc;
  322         ic->ic_update_chw = null_update_chw;
  323 
  324         ic->ic_hash_key = arc4random();
  325         ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT;
  326         ic->ic_lintval = ic->ic_bintval;
  327         ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;
  328 
  329         ieee80211_crypto_attach(ic);
  330         ieee80211_node_attach(ic);
  331         ieee80211_power_attach(ic);
  332         ieee80211_proto_attach(ic);
  333 #ifdef IEEE80211_SUPPORT_SUPERG
  334         ieee80211_superg_attach(ic);
  335 #endif
  336         ieee80211_ht_attach(ic);
  337         ieee80211_scan_attach(ic);
  338         ieee80211_regdomain_attach(ic);
  339         ieee80211_dfs_attach(ic);
  340 
  341         ieee80211_sysctl_attach(ic);
  342 
  343         mtx_lock(&ic_list_mtx);
  344         LIST_INSERT_HEAD(&ic_head, ic, ic_next);
  345         mtx_unlock(&ic_list_mtx);
  346 }
  347 
  348 /*
  349  * Detach net80211 state on device detach.  Tear down
  350  * all vap's and reclaim all common state prior to the
  351  * device state going away.  Note we may call back into
  352  * driver; it must be prepared for this.
  353  */
  354 void
  355 ieee80211_ifdetach(struct ieee80211com *ic)
  356 {
  357         struct ieee80211vap *vap;
  358 
  359         /*
  360          * We use this as an indicator that ifattach never had a chance to be
  361          * called, e.g. early driver attach failed and ifdetach was called
  362          * during subsequent detach.  Never fear, for we have nothing to do
  363          * here.
  364          */
  365         if (ic->ic_tq == NULL)
  366                 return;
  367 
  368         mtx_lock(&ic_list_mtx);
  369         LIST_REMOVE(ic, ic_next);
  370         mtx_unlock(&ic_list_mtx);
  371 
  372         taskqueue_drain(taskqueue_thread, &ic->ic_restart_task);
  373 
  374         /*
  375          * The VAP is responsible for setting and clearing
  376          * the VIMAGE context.
  377          */
  378         while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL) {
  379                 ieee80211_com_vdetach(vap);
  380                 ieee80211_vap_destroy(vap);
  381         }
  382         ieee80211_waitfor_parent(ic);
  383 
  384         ieee80211_sysctl_detach(ic);
  385         ieee80211_dfs_detach(ic);
  386         ieee80211_regdomain_detach(ic);
  387         ieee80211_scan_detach(ic);
  388 #ifdef IEEE80211_SUPPORT_SUPERG
  389         ieee80211_superg_detach(ic);
  390 #endif
  391         ieee80211_ht_detach(ic);
  392         /* NB: must be called before ieee80211_node_detach */
  393         ieee80211_proto_detach(ic);
  394         ieee80211_crypto_detach(ic);
  395         ieee80211_power_detach(ic);
  396         ieee80211_node_detach(ic);
  397 
  398         counter_u64_free(ic->ic_ierrors);
  399         counter_u64_free(ic->ic_oerrors);
  400 
  401         taskqueue_free(ic->ic_tq);
  402         IEEE80211_TX_LOCK_DESTROY(ic);
  403         IEEE80211_LOCK_DESTROY(ic);
  404 }
  405 
  406 struct ieee80211com *
  407 ieee80211_find_com(const char *name)
  408 {
  409         struct ieee80211com *ic;
  410 
  411         mtx_lock(&ic_list_mtx);
  412         LIST_FOREACH(ic, &ic_head, ic_next)
  413                 if (strcmp(ic->ic_name, name) == 0)
  414                         break;
  415         mtx_unlock(&ic_list_mtx);
  416 
  417         return (ic);
  418 }
  419 
  420 void
  421 ieee80211_iterate_coms(ieee80211_com_iter_func *f, void *arg)
  422 {
  423         struct ieee80211com *ic;
  424 
  425         mtx_lock(&ic_list_mtx);
  426         LIST_FOREACH(ic, &ic_head, ic_next)
  427                 (*f)(arg, ic);
  428         mtx_unlock(&ic_list_mtx);
  429 }
  430 
  431 /*
  432  * Default reset method for use with the ioctl support.  This
  433  * method is invoked after any state change in the 802.11
  434  * layer that should be propagated to the hardware but not
  435  * require re-initialization of the 802.11 state machine (e.g
  436  * rescanning for an ap).  We always return ENETRESET which
  437  * should cause the driver to re-initialize the device. Drivers
  438  * can override this method to implement more optimized support.
  439  */
  440 static int
  441 default_reset(struct ieee80211vap *vap, u_long cmd)
  442 {
  443         return ENETRESET;
  444 }
  445 
  446 /*
  447  * Add underlying device errors to vap errors.
  448  */
  449 static uint64_t
  450 ieee80211_get_counter(struct ifnet *ifp, ift_counter cnt)
  451 {
  452         struct ieee80211vap *vap = ifp->if_softc;
  453         struct ieee80211com *ic = vap->iv_ic;
  454         uint64_t rv;
  455 
  456         rv = if_get_counter_default(ifp, cnt);
  457         switch (cnt) {
  458         case IFCOUNTER_OERRORS:
  459                 rv += counter_u64_fetch(ic->ic_oerrors);
  460                 break;
  461         case IFCOUNTER_IERRORS:
  462                 rv += counter_u64_fetch(ic->ic_ierrors);
  463                 break;
  464         default:
  465                 break;
  466         }
  467 
  468         return (rv);
  469 }
  470 
  471 /*
  472  * Prepare a vap for use.  Drivers use this call to
  473  * setup net80211 state in new vap's prior attaching
  474  * them with ieee80211_vap_attach (below).
  475  */
  476 int
  477 ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
  478     const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode,
  479     int flags, const uint8_t bssid[IEEE80211_ADDR_LEN])
  480 {
  481         struct ifnet *ifp;
  482 
  483         ifp = if_alloc(IFT_ETHER);
  484         if (ifp == NULL) {
  485                 ic_printf(ic, "%s: unable to allocate ifnet\n",
  486                     __func__);
  487                 return ENOMEM;
  488         }
  489         if_initname(ifp, name, unit);
  490         ifp->if_softc = vap;                    /* back pointer */
  491         ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
  492         ifp->if_transmit = ieee80211_vap_transmit;
  493         ifp->if_qflush = ieee80211_vap_qflush;
  494         ifp->if_ioctl = ieee80211_ioctl;
  495         ifp->if_init = ieee80211_init;
  496         ifp->if_get_counter = ieee80211_get_counter;
  497 
  498         vap->iv_ifp = ifp;
  499         vap->iv_ic = ic;
  500         vap->iv_flags = ic->ic_flags;           /* propagate common flags */
  501         vap->iv_flags_ext = ic->ic_flags_ext;
  502         vap->iv_flags_ven = ic->ic_flags_ven;
  503         vap->iv_caps = ic->ic_caps &~ IEEE80211_C_OPMODE;
  504         vap->iv_htcaps = ic->ic_htcaps;
  505         vap->iv_htextcaps = ic->ic_htextcaps;
  506         vap->iv_opmode = opmode;
  507         vap->iv_caps |= ieee80211_opcap[opmode];
  508         IEEE80211_ADDR_COPY(vap->iv_myaddr, ic->ic_macaddr);
  509         switch (opmode) {
  510         case IEEE80211_M_WDS:
  511                 /*
  512                  * WDS links must specify the bssid of the far end.
  513                  * For legacy operation this is a static relationship.
  514                  * For non-legacy operation the station must associate
  515                  * and be authorized to pass traffic.  Plumbing the
  516                  * vap to the proper node happens when the vap
  517                  * transitions to RUN state.
  518                  */
  519                 IEEE80211_ADDR_COPY(vap->iv_des_bssid, bssid);
  520                 vap->iv_flags |= IEEE80211_F_DESBSSID;
  521                 if (flags & IEEE80211_CLONE_WDSLEGACY)
  522                         vap->iv_flags_ext |= IEEE80211_FEXT_WDSLEGACY;
  523                 break;
  524 #ifdef IEEE80211_SUPPORT_TDMA
  525         case IEEE80211_M_AHDEMO:
  526                 if (flags & IEEE80211_CLONE_TDMA) {
  527                         /* NB: checked before clone operation allowed */
  528                         KASSERT(ic->ic_caps & IEEE80211_C_TDMA,
  529                             ("not TDMA capable, ic_caps 0x%x", ic->ic_caps));
  530                         /*
  531                          * Propagate TDMA capability to mark vap; this
  532                          * cannot be removed and is used to distinguish
  533                          * regular ahdemo operation from ahdemo+tdma.
  534                          */
  535                         vap->iv_caps |= IEEE80211_C_TDMA;
  536                 }
  537                 break;
  538 #endif
  539         default:
  540                 break;
  541         }
  542         /* auto-enable s/w beacon miss support */
  543         if (flags & IEEE80211_CLONE_NOBEACONS)
  544                 vap->iv_flags_ext |= IEEE80211_FEXT_SWBMISS;
  545         /* auto-generated or user supplied MAC address */
  546         if (flags & (IEEE80211_CLONE_BSSID|IEEE80211_CLONE_MACADDR))
  547                 vap->iv_flags_ext |= IEEE80211_FEXT_UNIQMAC;
  548         /*
  549          * Enable various functionality by default if we're
  550          * capable; the driver can override us if it knows better.
  551          */
  552         if (vap->iv_caps & IEEE80211_C_WME)
  553                 vap->iv_flags |= IEEE80211_F_WME;
  554         if (vap->iv_caps & IEEE80211_C_BURST)
  555                 vap->iv_flags |= IEEE80211_F_BURST;
  556         /* NB: bg scanning only makes sense for station mode right now */
  557         if (vap->iv_opmode == IEEE80211_M_STA &&
  558             (vap->iv_caps & IEEE80211_C_BGSCAN))
  559                 vap->iv_flags |= IEEE80211_F_BGSCAN;
  560         vap->iv_flags |= IEEE80211_F_DOTH;      /* XXX no cap, just ena */
  561         /* NB: DFS support only makes sense for ap mode right now */
  562         if (vap->iv_opmode == IEEE80211_M_HOSTAP &&
  563             (vap->iv_caps & IEEE80211_C_DFS))
  564                 vap->iv_flags_ext |= IEEE80211_FEXT_DFS;
  565 
  566         vap->iv_des_chan = IEEE80211_CHAN_ANYC;         /* any channel is ok */
  567         vap->iv_bmissthreshold = IEEE80211_HWBMISS_DEFAULT;
  568         vap->iv_dtim_period = IEEE80211_DTIM_DEFAULT;
  569         /*
  570          * Install a default reset method for the ioctl support;
  571          * the driver can override this.
  572          */
  573         vap->iv_reset = default_reset;
  574 
  575         ieee80211_sysctl_vattach(vap);
  576         ieee80211_crypto_vattach(vap);
  577         ieee80211_node_vattach(vap);
  578         ieee80211_power_vattach(vap);
  579         ieee80211_proto_vattach(vap);
  580 #ifdef IEEE80211_SUPPORT_SUPERG
  581         ieee80211_superg_vattach(vap);
  582 #endif
  583         ieee80211_ht_vattach(vap);
  584         ieee80211_scan_vattach(vap);
  585         ieee80211_regdomain_vattach(vap);
  586         ieee80211_radiotap_vattach(vap);
  587         ieee80211_ratectl_set(vap, IEEE80211_RATECTL_NONE);
  588 
  589         return 0;
  590 }
  591 
  592 /*
  593  * Activate a vap.  State should have been prepared with a
  594  * call to ieee80211_vap_setup and by the driver.  On return
  595  * from this call the vap is ready for use.
  596  */
  597 int
  598 ieee80211_vap_attach(struct ieee80211vap *vap, ifm_change_cb_t media_change,
  599     ifm_stat_cb_t media_stat, const uint8_t macaddr[IEEE80211_ADDR_LEN])
  600 {
  601         struct ifnet *ifp = vap->iv_ifp;
  602         struct ieee80211com *ic = vap->iv_ic;
  603         struct ifmediareq imr;
  604         int maxrate;
  605 
  606         IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
  607             "%s: %s parent %s flags 0x%x flags_ext 0x%x\n",
  608             __func__, ieee80211_opmode_name[vap->iv_opmode],
  609             ic->ic_name, vap->iv_flags, vap->iv_flags_ext);
  610 
  611         /*
  612          * Do late attach work that cannot happen until after
  613          * the driver has had a chance to override defaults.
  614          */
  615         ieee80211_node_latevattach(vap);
  616         ieee80211_power_latevattach(vap);
  617 
  618         maxrate = ieee80211_media_setup(ic, &vap->iv_media, vap->iv_caps,
  619             vap->iv_opmode == IEEE80211_M_STA, media_change, media_stat);
  620         ieee80211_media_status(ifp, &imr);
  621         /* NB: strip explicit mode; we're actually in autoselect */
  622         ifmedia_set(&vap->iv_media,
  623             imr.ifm_active &~ (IFM_MMASK | IFM_IEEE80211_TURBO));
  624         if (maxrate)
  625                 ifp->if_baudrate = IF_Mbps(maxrate);
  626 
  627         ether_ifattach(ifp, macaddr);
  628         IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp));
  629         /* hook output method setup by ether_ifattach */
  630         vap->iv_output = ifp->if_output;
  631         ifp->if_output = ieee80211_output;
  632         /* NB: if_mtu set by ether_ifattach to ETHERMTU */
  633 
  634         IEEE80211_LOCK(ic);
  635         TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
  636         ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
  637 #ifdef IEEE80211_SUPPORT_SUPERG
  638         ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
  639 #endif
  640         ieee80211_syncflag_locked(ic, IEEE80211_F_PCF);
  641         ieee80211_syncflag_locked(ic, IEEE80211_F_BURST);
  642         ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT);
  643         ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
  644         IEEE80211_UNLOCK(ic);
  645 
  646         return 1;
  647 }
  648 
  649 /*
  650  * Tear down vap state and reclaim the ifnet.
  651  * The driver is assumed to have prepared for
  652  * this; e.g. by turning off interrupts for the
  653  * underlying device.
  654  */
  655 void
  656 ieee80211_vap_detach(struct ieee80211vap *vap)
  657 {
  658         struct ieee80211com *ic = vap->iv_ic;
  659         struct ifnet *ifp = vap->iv_ifp;
  660 
  661         CURVNET_SET(ifp->if_vnet);
  662 
  663         IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s parent %s\n",
  664             __func__, ieee80211_opmode_name[vap->iv_opmode], ic->ic_name);
  665 
  666         /* NB: bpfdetach is called by ether_ifdetach and claims all taps */
  667         ether_ifdetach(ifp);
  668 
  669         ieee80211_stop(vap);
  670 
  671         /*
  672          * Flush any deferred vap tasks.
  673          */
  674         ieee80211_draintask(ic, &vap->iv_nstate_task);
  675         ieee80211_draintask(ic, &vap->iv_swbmiss_task);
  676 
  677         /* XXX band-aid until ifnet handles this for us */
  678         taskqueue_drain(taskqueue_swi, &ifp->if_linktask);
  679 
  680         IEEE80211_LOCK(ic);
  681         KASSERT(vap->iv_state == IEEE80211_S_INIT , ("vap still running"));
  682         TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next);
  683         ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
  684 #ifdef IEEE80211_SUPPORT_SUPERG
  685         ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
  686 #endif
  687         ieee80211_syncflag_locked(ic, IEEE80211_F_PCF);
  688         ieee80211_syncflag_locked(ic, IEEE80211_F_BURST);
  689         ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT);
  690         ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
  691         /* NB: this handles the bpfdetach done below */
  692         ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF);
  693         if (vap->iv_ifflags & IFF_PROMISC)
  694                 ieee80211_promisc(vap, false);
  695         if (vap->iv_ifflags & IFF_ALLMULTI)
  696                 ieee80211_allmulti(vap, false);
  697         IEEE80211_UNLOCK(ic);
  698 
  699         ifmedia_removeall(&vap->iv_media);
  700 
  701         ieee80211_radiotap_vdetach(vap);
  702         ieee80211_regdomain_vdetach(vap);
  703         ieee80211_scan_vdetach(vap);
  704 #ifdef IEEE80211_SUPPORT_SUPERG
  705         ieee80211_superg_vdetach(vap);
  706 #endif
  707         ieee80211_ht_vdetach(vap);
  708         /* NB: must be before ieee80211_node_vdetach */
  709         ieee80211_proto_vdetach(vap);
  710         ieee80211_crypto_vdetach(vap);
  711         ieee80211_power_vdetach(vap);
  712         ieee80211_node_vdetach(vap);
  713         ieee80211_sysctl_vdetach(vap);
  714 
  715         if_free(ifp);
  716 
  717         CURVNET_RESTORE();
  718 }
  719 
  720 /*
  721  * Count number of vaps in promisc, and issue promisc on
  722  * parent respectively.
  723  */
  724 void
  725 ieee80211_promisc(struct ieee80211vap *vap, bool on)
  726 {
  727         struct ieee80211com *ic = vap->iv_ic;
  728 
  729         IEEE80211_LOCK_ASSERT(ic);
  730 
  731         if (on) {
  732                 if (++ic->ic_promisc == 1)
  733                         ieee80211_runtask(ic, &ic->ic_promisc_task);
  734         } else {
  735                 KASSERT(ic->ic_promisc > 0, ("%s: ic %p not promisc",
  736                     __func__, ic));
  737                 if (--ic->ic_promisc == 0)
  738                         ieee80211_runtask(ic, &ic->ic_promisc_task);
  739         }
  740 }
  741 
  742 /*
  743  * Count number of vaps in allmulti, and issue allmulti on
  744  * parent respectively.
  745  */
  746 void
  747 ieee80211_allmulti(struct ieee80211vap *vap, bool on)
  748 {
  749         struct ieee80211com *ic = vap->iv_ic;
  750 
  751         IEEE80211_LOCK_ASSERT(ic);
  752 
  753         if (on) {
  754                 if (++ic->ic_allmulti == 1)
  755                         ieee80211_runtask(ic, &ic->ic_mcast_task);
  756         } else {
  757                 KASSERT(ic->ic_allmulti > 0, ("%s: ic %p not allmulti",
  758                     __func__, ic));
  759                 if (--ic->ic_allmulti == 0)
  760                         ieee80211_runtask(ic, &ic->ic_mcast_task);
  761         }
  762 }
  763 
  764 /*
  765  * Synchronize flag bit state in the com structure
  766  * according to the state of all vap's.  This is used,
  767  * for example, to handle state changes via ioctls.
  768  */
  769 static void
  770 ieee80211_syncflag_locked(struct ieee80211com *ic, int flag)
  771 {
  772         struct ieee80211vap *vap;
  773         int bit;
  774 
  775         IEEE80211_LOCK_ASSERT(ic);
  776 
  777         bit = 0;
  778         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
  779                 if (vap->iv_flags & flag) {
  780                         bit = 1;
  781                         break;
  782                 }
  783         if (bit)
  784                 ic->ic_flags |= flag;
  785         else
  786                 ic->ic_flags &= ~flag;
  787 }
  788 
  789 void
  790 ieee80211_syncflag(struct ieee80211vap *vap, int flag)
  791 {
  792         struct ieee80211com *ic = vap->iv_ic;
  793 
  794         IEEE80211_LOCK(ic);
  795         if (flag < 0) {
  796                 flag = -flag;
  797                 vap->iv_flags &= ~flag;
  798         } else
  799                 vap->iv_flags |= flag;
  800         ieee80211_syncflag_locked(ic, flag);
  801         IEEE80211_UNLOCK(ic);
  802 }
  803 
  804 /*
  805  * Synchronize flags_ht bit state in the com structure
  806  * according to the state of all vap's.  This is used,
  807  * for example, to handle state changes via ioctls.
  808  */
  809 static void
  810 ieee80211_syncflag_ht_locked(struct ieee80211com *ic, int flag)
  811 {
  812         struct ieee80211vap *vap;
  813         int bit;
  814 
  815         IEEE80211_LOCK_ASSERT(ic);
  816 
  817         bit = 0;
  818         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
  819                 if (vap->iv_flags_ht & flag) {
  820                         bit = 1;
  821                         break;
  822                 }
  823         if (bit)
  824                 ic->ic_flags_ht |= flag;
  825         else
  826                 ic->ic_flags_ht &= ~flag;
  827 }
  828 
  829 void
  830 ieee80211_syncflag_ht(struct ieee80211vap *vap, int flag)
  831 {
  832         struct ieee80211com *ic = vap->iv_ic;
  833 
  834         IEEE80211_LOCK(ic);
  835         if (flag < 0) {
  836                 flag = -flag;
  837                 vap->iv_flags_ht &= ~flag;
  838         } else
  839                 vap->iv_flags_ht |= flag;
  840         ieee80211_syncflag_ht_locked(ic, flag);
  841         IEEE80211_UNLOCK(ic);
  842 }
  843 
  844 /*
  845  * Synchronize flags_ext bit state in the com structure
  846  * according to the state of all vap's.  This is used,
  847  * for example, to handle state changes via ioctls.
  848  */
  849 static void
  850 ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag)
  851 {
  852         struct ieee80211vap *vap;
  853         int bit;
  854 
  855         IEEE80211_LOCK_ASSERT(ic);
  856 
  857         bit = 0;
  858         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
  859                 if (vap->iv_flags_ext & flag) {
  860                         bit = 1;
  861                         break;
  862                 }
  863         if (bit)
  864                 ic->ic_flags_ext |= flag;
  865         else
  866                 ic->ic_flags_ext &= ~flag;
  867 }
  868 
  869 void
  870 ieee80211_syncflag_ext(struct ieee80211vap *vap, int flag)
  871 {
  872         struct ieee80211com *ic = vap->iv_ic;
  873 
  874         IEEE80211_LOCK(ic);
  875         if (flag < 0) {
  876                 flag = -flag;
  877                 vap->iv_flags_ext &= ~flag;
  878         } else
  879                 vap->iv_flags_ext |= flag;
  880         ieee80211_syncflag_ext_locked(ic, flag);
  881         IEEE80211_UNLOCK(ic);
  882 }
  883 
  884 static __inline int
  885 mapgsm(u_int freq, u_int flags)
  886 {
  887         freq *= 10;
  888         if (flags & IEEE80211_CHAN_QUARTER)
  889                 freq += 5;
  890         else if (flags & IEEE80211_CHAN_HALF)
  891                 freq += 10;
  892         else
  893                 freq += 20;
  894         /* NB: there is no 907/20 wide but leave room */
  895         return (freq - 906*10) / 5;
  896 }
  897 
  898 static __inline int
  899 mappsb(u_int freq, u_int flags)
  900 {
  901         return 37 + ((freq * 10) + ((freq % 5) == 2 ? 5 : 0) - 49400) / 5;
  902 }
  903 
  904 /*
  905  * Convert MHz frequency to IEEE channel number.
  906  */
  907 int
  908 ieee80211_mhz2ieee(u_int freq, u_int flags)
  909 {
  910 #define IS_FREQ_IN_PSB(_freq) ((_freq) > 4940 && (_freq) < 4990)
  911         if (flags & IEEE80211_CHAN_GSM)
  912                 return mapgsm(freq, flags);
  913         if (flags & IEEE80211_CHAN_2GHZ) {      /* 2GHz band */
  914                 if (freq == 2484)
  915                         return 14;
  916                 if (freq < 2484)
  917                         return ((int) freq - 2407) / 5;
  918                 else
  919                         return 15 + ((freq - 2512) / 20);
  920         } else if (flags & IEEE80211_CHAN_5GHZ) {       /* 5Ghz band */
  921                 if (freq <= 5000) {
  922                         /* XXX check regdomain? */
  923                         if (IS_FREQ_IN_PSB(freq))
  924                                 return mappsb(freq, flags);
  925                         return (freq - 4000) / 5;
  926                 } else
  927                         return (freq - 5000) / 5;
  928         } else {                                /* either, guess */
  929                 if (freq == 2484)
  930                         return 14;
  931                 if (freq < 2484) {
  932                         if (907 <= freq && freq <= 922)
  933                                 return mapgsm(freq, flags);
  934                         return ((int) freq - 2407) / 5;
  935                 }
  936                 if (freq < 5000) {
  937                         if (IS_FREQ_IN_PSB(freq))
  938                                 return mappsb(freq, flags);
  939                         else if (freq > 4900)
  940                                 return (freq - 4000) / 5;
  941                         else
  942                                 return 15 + ((freq - 2512) / 20);
  943                 }
  944                 return (freq - 5000) / 5;
  945         }
  946 #undef IS_FREQ_IN_PSB
  947 }
  948 
  949 /*
  950  * Convert channel to IEEE channel number.
  951  */
  952 int
  953 ieee80211_chan2ieee(struct ieee80211com *ic, const struct ieee80211_channel *c)
  954 {
  955         if (c == NULL) {
  956                 ic_printf(ic, "invalid channel (NULL)\n");
  957                 return 0;               /* XXX */
  958         }
  959         return (c == IEEE80211_CHAN_ANYC ?  IEEE80211_CHAN_ANY : c->ic_ieee);
  960 }
  961 
  962 /*
  963  * Convert IEEE channel number to MHz frequency.
  964  */
  965 u_int
  966 ieee80211_ieee2mhz(u_int chan, u_int flags)
  967 {
  968         if (flags & IEEE80211_CHAN_GSM)
  969                 return 907 + 5 * (chan / 10);
  970         if (flags & IEEE80211_CHAN_2GHZ) {      /* 2GHz band */
  971                 if (chan == 14)
  972                         return 2484;
  973                 if (chan < 14)
  974                         return 2407 + chan*5;
  975                 else
  976                         return 2512 + ((chan-15)*20);
  977         } else if (flags & IEEE80211_CHAN_5GHZ) {/* 5Ghz band */
  978                 if (flags & (IEEE80211_CHAN_HALF|IEEE80211_CHAN_QUARTER)) {
  979                         chan -= 37;
  980                         return 4940 + chan*5 + (chan % 5 ? 2 : 0);
  981                 }
  982                 return 5000 + (chan*5);
  983         } else {                                /* either, guess */
  984                 /* XXX can't distinguish PSB+GSM channels */
  985                 if (chan == 14)
  986                         return 2484;
  987                 if (chan < 14)                  /* 0-13 */
  988                         return 2407 + chan*5;
  989                 if (chan < 27)                  /* 15-26 */
  990                         return 2512 + ((chan-15)*20);
  991                 return 5000 + (chan*5);
  992         }
  993 }
  994 
  995 static __inline void
  996 set_extchan(struct ieee80211_channel *c)
  997 {
  998 
  999         /*
 1000          * IEEE Std 802.11-2012, page 1738, subclause 20.3.15.4:
 1001          * "the secondary channel number shall be 'N + [1,-1] * 4'
 1002          */
 1003         if (c->ic_flags & IEEE80211_CHAN_HT40U)
 1004                 c->ic_extieee = c->ic_ieee + 4;
 1005         else if (c->ic_flags & IEEE80211_CHAN_HT40D)
 1006                 c->ic_extieee = c->ic_ieee - 4;
 1007         else
 1008                 c->ic_extieee = 0;
 1009 }
 1010 
 1011 static int
 1012 addchan(struct ieee80211_channel chans[], int maxchans, int *nchans,
 1013     uint8_t ieee, uint16_t freq, int8_t maxregpower, uint32_t flags)
 1014 {
 1015         struct ieee80211_channel *c;
 1016 
 1017         if (*nchans >= maxchans)
 1018                 return (ENOBUFS);
 1019 
 1020         c = &chans[(*nchans)++];
 1021         c->ic_ieee = ieee;
 1022         c->ic_freq = freq != 0 ? freq : ieee80211_ieee2mhz(ieee, flags);
 1023         c->ic_maxregpower = maxregpower;
 1024         c->ic_maxpower = 2 * maxregpower;
 1025         c->ic_flags = flags;
 1026         set_extchan(c);
 1027 
 1028         return (0);
 1029 }
 1030 
 1031 static int
 1032 copychan_prev(struct ieee80211_channel chans[], int maxchans, int *nchans,
 1033     uint32_t flags)
 1034 {
 1035         struct ieee80211_channel *c;
 1036 
 1037         KASSERT(*nchans > 0, ("channel list is empty\n"));
 1038 
 1039         if (*nchans >= maxchans)
 1040                 return (ENOBUFS);
 1041 
 1042         c = &chans[(*nchans)++];
 1043         c[0] = c[-1];
 1044         c->ic_flags = flags;
 1045         set_extchan(c);
 1046 
 1047         return (0);
 1048 }
 1049 
 1050 static void
 1051 getflags_2ghz(const uint8_t bands[], uint32_t flags[], int ht40)
 1052 {
 1053         int nmodes;
 1054 
 1055         nmodes = 0;
 1056         if (isset(bands, IEEE80211_MODE_11B))
 1057                 flags[nmodes++] = IEEE80211_CHAN_B;
 1058         if (isset(bands, IEEE80211_MODE_11G))
 1059                 flags[nmodes++] = IEEE80211_CHAN_G;
 1060         if (isset(bands, IEEE80211_MODE_11NG))
 1061                 flags[nmodes++] = IEEE80211_CHAN_G | IEEE80211_CHAN_HT20;
 1062         if (ht40) {
 1063                 flags[nmodes++] = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U;
 1064                 flags[nmodes++] = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D;
 1065         }
 1066         flags[nmodes] = 0;
 1067 }
 1068 
 1069 static void
 1070 getflags_5ghz(const uint8_t bands[], uint32_t flags[], int ht40)
 1071 {
 1072         int nmodes;
 1073 
 1074         nmodes = 0;
 1075         if (isset(bands, IEEE80211_MODE_11A))
 1076                 flags[nmodes++] = IEEE80211_CHAN_A;
 1077         if (isset(bands, IEEE80211_MODE_11NA))
 1078                 flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
 1079         if (ht40) {
 1080                 flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U;
 1081                 flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D;
 1082         }
 1083         flags[nmodes] = 0;
 1084 }
 1085 
 1086 static void
 1087 getflags(const uint8_t bands[], uint32_t flags[], int ht40)
 1088 {
 1089 
 1090         flags[0] = 0;
 1091         if (isset(bands, IEEE80211_MODE_11A) ||
 1092             isset(bands, IEEE80211_MODE_11NA)) {
 1093                 if (isset(bands, IEEE80211_MODE_11B) ||
 1094                     isset(bands, IEEE80211_MODE_11G) ||
 1095                     isset(bands, IEEE80211_MODE_11NG))
 1096                         return;
 1097 
 1098                 getflags_5ghz(bands, flags, ht40);
 1099         } else
 1100                 getflags_2ghz(bands, flags, ht40);
 1101 }
 1102 
 1103 /*
 1104  * Add one 20 MHz channel into specified channel list.
 1105  */
 1106 int
 1107 ieee80211_add_channel(struct ieee80211_channel chans[], int maxchans,
 1108     int *nchans, uint8_t ieee, uint16_t freq, int8_t maxregpower,
 1109     uint32_t chan_flags, const uint8_t bands[])
 1110 {
 1111         uint32_t flags[IEEE80211_MODE_MAX];
 1112         int i, error;
 1113 
 1114         getflags(bands, flags, 0);
 1115         KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__));
 1116 
 1117         error = addchan(chans, maxchans, nchans, ieee, freq, maxregpower,
 1118             flags[0] | chan_flags);
 1119         for (i = 1; flags[i] != 0 && error == 0; i++) {
 1120                 error = copychan_prev(chans, maxchans, nchans,
 1121                     flags[i] | chan_flags);
 1122         }
 1123 
 1124         return (error);
 1125 }
 1126 
 1127 static struct ieee80211_channel *
 1128 findchannel(struct ieee80211_channel chans[], int nchans, uint16_t freq,
 1129     uint32_t flags)
 1130 {
 1131         struct ieee80211_channel *c;
 1132         int i;
 1133 
 1134         flags &= IEEE80211_CHAN_ALLTURBO;
 1135         /* brute force search */
 1136         for (i = 0; i < nchans; i++) {
 1137                 c = &chans[i];
 1138                 if (c->ic_freq == freq &&
 1139                     (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)
 1140                         return c;
 1141         }
 1142         return NULL;
 1143 }
 1144 
 1145 /*
 1146  * Add 40 MHz channel pair into specified channel list.
 1147  */
 1148 int
 1149 ieee80211_add_channel_ht40(struct ieee80211_channel chans[], int maxchans,
 1150     int *nchans, uint8_t ieee, int8_t maxregpower, uint32_t flags)
 1151 {
 1152         struct ieee80211_channel *cent, *extc;
 1153         uint16_t freq;
 1154         int error;
 1155 
 1156         freq = ieee80211_ieee2mhz(ieee, flags);
 1157 
 1158         /*
 1159          * Each entry defines an HT40 channel pair; find the
 1160          * center channel, then the extension channel above.
 1161          */
 1162         flags |= IEEE80211_CHAN_HT20;
 1163         cent = findchannel(chans, *nchans, freq, flags);
 1164         if (cent == NULL)
 1165                 return (EINVAL);
 1166 
 1167         extc = findchannel(chans, *nchans, freq + 20, flags);
 1168         if (extc == NULL)
 1169                 return (ENOENT);
 1170 
 1171         flags &= ~IEEE80211_CHAN_HT;
 1172         error = addchan(chans, maxchans, nchans, cent->ic_ieee, cent->ic_freq,
 1173             maxregpower, flags | IEEE80211_CHAN_HT40U);
 1174         if (error != 0)
 1175                 return (error);
 1176 
 1177         error = addchan(chans, maxchans, nchans, extc->ic_ieee, extc->ic_freq,
 1178             maxregpower, flags | IEEE80211_CHAN_HT40D);
 1179 
 1180         return (error);
 1181 }
 1182 
 1183 /*
 1184  * Adds channels into specified channel list (ieee[] array must be sorted).
 1185  * Channels are already sorted.
 1186  */
 1187 static int
 1188 add_chanlist(struct ieee80211_channel chans[], int maxchans, int *nchans,
 1189     const uint8_t ieee[], int nieee, uint32_t flags[])
 1190 {
 1191         uint16_t freq;
 1192         int i, j, error;
 1193 
 1194         for (i = 0; i < nieee; i++) {
 1195                 freq = ieee80211_ieee2mhz(ieee[i], flags[0]);
 1196                 for (j = 0; flags[j] != 0; j++) {
 1197                         if (flags[j] & IEEE80211_CHAN_HT40D)
 1198                                 if (i == 0 || ieee[i] < ieee[0] + 4 ||
 1199                                     freq - 20 !=
 1200                                     ieee80211_ieee2mhz(ieee[i] - 4, flags[j]))
 1201                                         continue;
 1202                         if (flags[j] & IEEE80211_CHAN_HT40U)
 1203                                 if (i == nieee - 1 ||
 1204                                     ieee[i] + 4 > ieee[nieee - 1] ||
 1205                                     freq + 20 !=
 1206                                     ieee80211_ieee2mhz(ieee[i] + 4, flags[j]))
 1207                                         continue;
 1208 
 1209                         if (j == 0) {
 1210                                 error = addchan(chans, maxchans, nchans,
 1211                                     ieee[i], freq, 0, flags[j]);
 1212                         } else {
 1213                                 error = copychan_prev(chans, maxchans, nchans,
 1214                                     flags[j]);
 1215                         }
 1216                         if (error != 0)
 1217                                 return (error);
 1218                 }
 1219         }
 1220 
 1221         return (0);
 1222 }
 1223 
 1224 int
 1225 ieee80211_add_channel_list_2ghz(struct ieee80211_channel chans[], int maxchans,
 1226     int *nchans, const uint8_t ieee[], int nieee, const uint8_t bands[],
 1227     int ht40)
 1228 {
 1229         uint32_t flags[IEEE80211_MODE_MAX];
 1230 
 1231         getflags_2ghz(bands, flags, ht40);
 1232         KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__));
 1233 
 1234         return (add_chanlist(chans, maxchans, nchans, ieee, nieee, flags));
 1235 }
 1236 
 1237 int
 1238 ieee80211_add_channels_default_2ghz(struct ieee80211_channel chans[],
 1239     int maxchans, int *nchans, const uint8_t bands[], int ht40)
 1240 {
 1241         const uint8_t default_chan_list[] =
 1242             { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
 1243 
 1244         return (ieee80211_add_channel_list_2ghz(chans, maxchans, nchans,
 1245             default_chan_list, nitems(default_chan_list), bands, ht40));
 1246 }
 1247 
 1248 int
 1249 ieee80211_add_channel_list_5ghz(struct ieee80211_channel chans[], int maxchans,
 1250     int *nchans, const uint8_t ieee[], int nieee, const uint8_t bands[],
 1251     int ht40)
 1252 {
 1253         uint32_t flags[IEEE80211_MODE_MAX];
 1254 
 1255         getflags_5ghz(bands, flags, ht40);
 1256         KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__));
 1257 
 1258         return (add_chanlist(chans, maxchans, nchans, ieee, nieee, flags));
 1259 }
 1260 
 1261 /*
 1262  * Locate a channel given a frequency+flags.  We cache
 1263  * the previous lookup to optimize switching between two
 1264  * channels--as happens with dynamic turbo.
 1265  */
 1266 struct ieee80211_channel *
 1267 ieee80211_find_channel(struct ieee80211com *ic, int freq, int flags)
 1268 {
 1269         struct ieee80211_channel *c;
 1270 
 1271         flags &= IEEE80211_CHAN_ALLTURBO;
 1272         c = ic->ic_prevchan;
 1273         if (c != NULL && c->ic_freq == freq &&
 1274             (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)
 1275                 return c;
 1276         /* brute force search */
 1277         return (findchannel(ic->ic_channels, ic->ic_nchans, freq, flags));
 1278 }
 1279 
 1280 /*
 1281  * Locate a channel given a channel number+flags.  We cache
 1282  * the previous lookup to optimize switching between two
 1283  * channels--as happens with dynamic turbo.
 1284  */
 1285 struct ieee80211_channel *
 1286 ieee80211_find_channel_byieee(struct ieee80211com *ic, int ieee, int flags)
 1287 {
 1288         struct ieee80211_channel *c;
 1289         int i;
 1290 
 1291         flags &= IEEE80211_CHAN_ALLTURBO;
 1292         c = ic->ic_prevchan;
 1293         if (c != NULL && c->ic_ieee == ieee &&
 1294             (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)
 1295                 return c;
 1296         /* brute force search */
 1297         for (i = 0; i < ic->ic_nchans; i++) {
 1298                 c = &ic->ic_channels[i];
 1299                 if (c->ic_ieee == ieee &&
 1300                     (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)
 1301                         return c;
 1302         }
 1303         return NULL;
 1304 }
 1305 
 1306 /*
 1307  * Lookup a channel suitable for the given rx status.
 1308  *
 1309  * This is used to find a channel for a frame (eg beacon, probe
 1310  * response) based purely on the received PHY information.
 1311  *
 1312  * For now it tries to do it based on R_FREQ / R_IEEE.
 1313  * This is enough for 11bg and 11a (and thus 11ng/11na)
 1314  * but it will not be enough for GSM, PSB channels and the
 1315  * like.  It also doesn't know about legacy-turbog and
 1316  * legacy-turbo modes, which some offload NICs actually
 1317  * support in weird ways.
 1318  *
 1319  * Takes the ic and rxstatus; returns the channel or NULL
 1320  * if not found.
 1321  *
 1322  * XXX TODO: Add support for that when the need arises.
 1323  */
 1324 struct ieee80211_channel *
 1325 ieee80211_lookup_channel_rxstatus(struct ieee80211vap *vap,
 1326     const struct ieee80211_rx_stats *rxs)
 1327 {
 1328         struct ieee80211com *ic = vap->iv_ic;
 1329         uint32_t flags;
 1330         struct ieee80211_channel *c;
 1331 
 1332         if (rxs == NULL)
 1333                 return (NULL);
 1334 
 1335         /*
 1336          * Strictly speaking we only use freq for now,
 1337          * however later on we may wish to just store
 1338          * the ieee for verification.
 1339          */
 1340         if ((rxs->r_flags & IEEE80211_R_FREQ) == 0)
 1341                 return (NULL);
 1342         if ((rxs->r_flags & IEEE80211_R_IEEE) == 0)
 1343                 return (NULL);
 1344 
 1345         /*
 1346          * If the rx status contains a valid ieee/freq, then
 1347          * ensure we populate the correct channel information
 1348          * in rxchan before passing it up to the scan infrastructure.
 1349          * Offload NICs will pass up beacons from all channels
 1350          * during background scans.
 1351          */
 1352 
 1353         /* Determine a band */
 1354         /* XXX should be done by the driver? */
 1355         if (rxs->c_freq < 3000) {
 1356                 flags = IEEE80211_CHAN_G;
 1357         } else {
 1358                 flags = IEEE80211_CHAN_A;
 1359         }
 1360 
 1361         /* Channel lookup */
 1362         c = ieee80211_find_channel(ic, rxs->c_freq, flags);
 1363 
 1364         IEEE80211_DPRINTF(vap, IEEE80211_MSG_INPUT,
 1365             "%s: freq=%d, ieee=%d, flags=0x%08x; c=%p\n",
 1366             __func__,
 1367             (int) rxs->c_freq,
 1368             (int) rxs->c_ieee,
 1369             flags,
 1370             c);
 1371 
 1372         return (c);
 1373 }
 1374 
 1375 static void
 1376 addmedia(struct ifmedia *media, int caps, int addsta, int mode, int mword)
 1377 {
 1378 #define ADD(_ic, _s, _o) \
 1379         ifmedia_add(media, \
 1380                 IFM_MAKEWORD(IFM_IEEE80211, (_s), (_o), 0), 0, NULL)
 1381         static const u_int mopts[IEEE80211_MODE_MAX] = {
 1382             [IEEE80211_MODE_AUTO]       = IFM_AUTO,
 1383             [IEEE80211_MODE_11A]        = IFM_IEEE80211_11A,
 1384             [IEEE80211_MODE_11B]        = IFM_IEEE80211_11B,
 1385             [IEEE80211_MODE_11G]        = IFM_IEEE80211_11G,
 1386             [IEEE80211_MODE_FH]         = IFM_IEEE80211_FH,
 1387             [IEEE80211_MODE_TURBO_A]    = IFM_IEEE80211_11A|IFM_IEEE80211_TURBO,
 1388             [IEEE80211_MODE_TURBO_G]    = IFM_IEEE80211_11G|IFM_IEEE80211_TURBO,
 1389             [IEEE80211_MODE_STURBO_A]   = IFM_IEEE80211_11A|IFM_IEEE80211_TURBO,
 1390             [IEEE80211_MODE_HALF]       = IFM_IEEE80211_11A,    /* XXX */
 1391             [IEEE80211_MODE_QUARTER]    = IFM_IEEE80211_11A,    /* XXX */
 1392             [IEEE80211_MODE_11NA]       = IFM_IEEE80211_11NA,
 1393             [IEEE80211_MODE_11NG]       = IFM_IEEE80211_11NG,
 1394         };
 1395         u_int mopt;
 1396 
 1397         mopt = mopts[mode];
 1398         if (addsta)
 1399                 ADD(ic, mword, mopt);   /* STA mode has no cap */
 1400         if (caps & IEEE80211_C_IBSS)
 1401                 ADD(media, mword, mopt | IFM_IEEE80211_ADHOC);
 1402         if (caps & IEEE80211_C_HOSTAP)
 1403                 ADD(media, mword, mopt | IFM_IEEE80211_HOSTAP);
 1404         if (caps & IEEE80211_C_AHDEMO)
 1405                 ADD(media, mword, mopt | IFM_IEEE80211_ADHOC | IFM_FLAG0);
 1406         if (caps & IEEE80211_C_MONITOR)
 1407                 ADD(media, mword, mopt | IFM_IEEE80211_MONITOR);
 1408         if (caps & IEEE80211_C_WDS)
 1409                 ADD(media, mword, mopt | IFM_IEEE80211_WDS);
 1410         if (caps & IEEE80211_C_MBSS)
 1411                 ADD(media, mword, mopt | IFM_IEEE80211_MBSS);
 1412 #undef ADD
 1413 }
 1414 
 1415 /*
 1416  * Setup the media data structures according to the channel and
 1417  * rate tables.
 1418  */
 1419 static int
 1420 ieee80211_media_setup(struct ieee80211com *ic,
 1421         struct ifmedia *media, int caps, int addsta,
 1422         ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
 1423 {
 1424         int i, j, rate, maxrate, mword, r;
 1425         enum ieee80211_phymode mode;
 1426         const struct ieee80211_rateset *rs;
 1427         struct ieee80211_rateset allrates;
 1428 
 1429         /*
 1430          * Fill in media characteristics.
 1431          */
 1432         ifmedia_init(media, 0, media_change, media_stat);
 1433         maxrate = 0;
 1434         /*
 1435          * Add media for legacy operating modes.
 1436          */
 1437         memset(&allrates, 0, sizeof(allrates));
 1438         for (mode = IEEE80211_MODE_AUTO; mode < IEEE80211_MODE_11NA; mode++) {
 1439                 if (isclr(ic->ic_modecaps, mode))
 1440                         continue;
 1441                 addmedia(media, caps, addsta, mode, IFM_AUTO);
 1442                 if (mode == IEEE80211_MODE_AUTO)
 1443                         continue;
 1444                 rs = &ic->ic_sup_rates[mode];
 1445                 for (i = 0; i < rs->rs_nrates; i++) {
 1446                         rate = rs->rs_rates[i];
 1447                         mword = ieee80211_rate2media(ic, rate, mode);
 1448                         if (mword == 0)
 1449                                 continue;
 1450                         addmedia(media, caps, addsta, mode, mword);
 1451                         /*
 1452                          * Add legacy rate to the collection of all rates.
 1453                          */
 1454                         r = rate & IEEE80211_RATE_VAL;
 1455                         for (j = 0; j < allrates.rs_nrates; j++)
 1456                                 if (allrates.rs_rates[j] == r)
 1457                                         break;
 1458                         if (j == allrates.rs_nrates) {
 1459                                 /* unique, add to the set */
 1460                                 allrates.rs_rates[j] = r;
 1461                                 allrates.rs_nrates++;
 1462                         }
 1463                         rate = (rate & IEEE80211_RATE_VAL) / 2;
 1464                         if (rate > maxrate)
 1465                                 maxrate = rate;
 1466                 }
 1467         }
 1468         for (i = 0; i < allrates.rs_nrates; i++) {
 1469                 mword = ieee80211_rate2media(ic, allrates.rs_rates[i],
 1470                                 IEEE80211_MODE_AUTO);
 1471                 if (mword == 0)
 1472                         continue;
 1473                 /* NB: remove media options from mword */
 1474                 addmedia(media, caps, addsta,
 1475                     IEEE80211_MODE_AUTO, IFM_SUBTYPE(mword));
 1476         }
 1477         /*
 1478          * Add HT/11n media.  Note that we do not have enough
 1479          * bits in the media subtype to express the MCS so we
 1480          * use a "placeholder" media subtype and any fixed MCS
 1481          * must be specified with a different mechanism.
 1482          */
 1483         for (; mode <= IEEE80211_MODE_11NG; mode++) {
 1484                 if (isclr(ic->ic_modecaps, mode))
 1485                         continue;
 1486                 addmedia(media, caps, addsta, mode, IFM_AUTO);
 1487                 addmedia(media, caps, addsta, mode, IFM_IEEE80211_MCS);
 1488         }
 1489         if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA) ||
 1490             isset(ic->ic_modecaps, IEEE80211_MODE_11NG)) {
 1491                 addmedia(media, caps, addsta,
 1492                     IEEE80211_MODE_AUTO, IFM_IEEE80211_MCS);
 1493                 i = ic->ic_txstream * 8 - 1;
 1494                 if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) &&
 1495                     (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40))
 1496                         rate = ieee80211_htrates[i].ht40_rate_400ns;
 1497                 else if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40))
 1498                         rate = ieee80211_htrates[i].ht40_rate_800ns;
 1499                 else if ((ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20))
 1500                         rate = ieee80211_htrates[i].ht20_rate_400ns;
 1501                 else
 1502                         rate = ieee80211_htrates[i].ht20_rate_800ns;
 1503                 if (rate > maxrate)
 1504                         maxrate = rate;
 1505         }
 1506         return maxrate;
 1507 }
 1508 
 1509 /* XXX inline or eliminate? */
 1510 const struct ieee80211_rateset *
 1511 ieee80211_get_suprates(struct ieee80211com *ic, const struct ieee80211_channel *c)
 1512 {
 1513         /* XXX does this work for 11ng basic rates? */
 1514         return &ic->ic_sup_rates[ieee80211_chan2mode(c)];
 1515 }
 1516 
 1517 void
 1518 ieee80211_announce(struct ieee80211com *ic)
 1519 {
 1520         int i, rate, mword;
 1521         enum ieee80211_phymode mode;
 1522         const struct ieee80211_rateset *rs;
 1523 
 1524         /* NB: skip AUTO since it has no rates */
 1525         for (mode = IEEE80211_MODE_AUTO+1; mode < IEEE80211_MODE_11NA; mode++) {
 1526                 if (isclr(ic->ic_modecaps, mode))
 1527                         continue;
 1528                 ic_printf(ic, "%s rates: ", ieee80211_phymode_name[mode]);
 1529                 rs = &ic->ic_sup_rates[mode];
 1530                 for (i = 0; i < rs->rs_nrates; i++) {
 1531                         mword = ieee80211_rate2media(ic, rs->rs_rates[i], mode);
 1532                         if (mword == 0)
 1533                                 continue;
 1534                         rate = ieee80211_media2rate(mword);
 1535                         printf("%s%d%sMbps", (i != 0 ? " " : ""),
 1536                             rate / 2, ((rate & 0x1) != 0 ? ".5" : ""));
 1537                 }
 1538                 printf("\n");
 1539         }
 1540         ieee80211_ht_announce(ic);
 1541 }
 1542 
 1543 void
 1544 ieee80211_announce_channels(struct ieee80211com *ic)
 1545 {
 1546         const struct ieee80211_channel *c;
 1547         char type;
 1548         int i, cw;
 1549 
 1550         printf("Chan  Freq  CW  RegPwr  MinPwr  MaxPwr\n");
 1551         for (i = 0; i < ic->ic_nchans; i++) {
 1552                 c = &ic->ic_channels[i];
 1553                 if (IEEE80211_IS_CHAN_ST(c))
 1554                         type = 'S';
 1555                 else if (IEEE80211_IS_CHAN_108A(c))
 1556                         type = 'T';
 1557                 else if (IEEE80211_IS_CHAN_108G(c))
 1558                         type = 'G';
 1559                 else if (IEEE80211_IS_CHAN_HT(c))
 1560                         type = 'n';
 1561                 else if (IEEE80211_IS_CHAN_A(c))
 1562                         type = 'a';
 1563                 else if (IEEE80211_IS_CHAN_ANYG(c))
 1564                         type = 'g';
 1565                 else if (IEEE80211_IS_CHAN_B(c))
 1566                         type = 'b';
 1567                 else
 1568                         type = 'f';
 1569                 if (IEEE80211_IS_CHAN_HT40(c) || IEEE80211_IS_CHAN_TURBO(c))
 1570                         cw = 40;
 1571                 else if (IEEE80211_IS_CHAN_HALF(c))
 1572                         cw = 10;
 1573                 else if (IEEE80211_IS_CHAN_QUARTER(c))
 1574                         cw = 5;
 1575                 else
 1576                         cw = 20;
 1577                 printf("%4d  %4d%c %2d%c %6d  %4d.%d  %4d.%d\n"
 1578                         , c->ic_ieee, c->ic_freq, type
 1579                         , cw
 1580                         , IEEE80211_IS_CHAN_HT40U(c) ? '+' :
 1581                           IEEE80211_IS_CHAN_HT40D(c) ? '-' : ' '
 1582                         , c->ic_maxregpower
 1583                         , c->ic_minpower / 2, c->ic_minpower & 1 ? 5 : 0
 1584                         , c->ic_maxpower / 2, c->ic_maxpower & 1 ? 5 : 0
 1585                 );
 1586         }
 1587 }
 1588 
 1589 static int
 1590 media2mode(const struct ifmedia_entry *ime, uint32_t flags, uint16_t *mode)
 1591 {
 1592         switch (IFM_MODE(ime->ifm_media)) {
 1593         case IFM_IEEE80211_11A:
 1594                 *mode = IEEE80211_MODE_11A;
 1595                 break;
 1596         case IFM_IEEE80211_11B:
 1597                 *mode = IEEE80211_MODE_11B;
 1598                 break;
 1599         case IFM_IEEE80211_11G:
 1600                 *mode = IEEE80211_MODE_11G;
 1601                 break;
 1602         case IFM_IEEE80211_FH:
 1603                 *mode = IEEE80211_MODE_FH;
 1604                 break;
 1605         case IFM_IEEE80211_11NA:
 1606                 *mode = IEEE80211_MODE_11NA;
 1607                 break;
 1608         case IFM_IEEE80211_11NG:
 1609                 *mode = IEEE80211_MODE_11NG;
 1610                 break;
 1611         case IFM_AUTO:
 1612                 *mode = IEEE80211_MODE_AUTO;
 1613                 break;
 1614         default:
 1615                 return 0;
 1616         }
 1617         /*
 1618          * Turbo mode is an ``option''.
 1619          * XXX does not apply to AUTO
 1620          */
 1621         if (ime->ifm_media & IFM_IEEE80211_TURBO) {
 1622                 if (*mode == IEEE80211_MODE_11A) {
 1623                         if (flags & IEEE80211_F_TURBOP)
 1624                                 *mode = IEEE80211_MODE_TURBO_A;
 1625                         else
 1626                                 *mode = IEEE80211_MODE_STURBO_A;
 1627                 } else if (*mode == IEEE80211_MODE_11G)
 1628                         *mode = IEEE80211_MODE_TURBO_G;
 1629                 else
 1630                         return 0;
 1631         }
 1632         /* XXX HT40 +/- */
 1633         return 1;
 1634 }
 1635 
 1636 /*
 1637  * Handle a media change request on the vap interface.
 1638  */
 1639 int
 1640 ieee80211_media_change(struct ifnet *ifp)
 1641 {
 1642         struct ieee80211vap *vap = ifp->if_softc;
 1643         struct ifmedia_entry *ime = vap->iv_media.ifm_cur;
 1644         uint16_t newmode;
 1645 
 1646         if (!media2mode(ime, vap->iv_flags, &newmode))
 1647                 return EINVAL;
 1648         if (vap->iv_des_mode != newmode) {
 1649                 vap->iv_des_mode = newmode;
 1650                 /* XXX kick state machine if up+running */
 1651         }
 1652         return 0;
 1653 }
 1654 
 1655 /*
 1656  * Common code to calculate the media status word
 1657  * from the operating mode and channel state.
 1658  */
 1659 static int
 1660 media_status(enum ieee80211_opmode opmode, const struct ieee80211_channel *chan)
 1661 {
 1662         int status;
 1663 
 1664         status = IFM_IEEE80211;
 1665         switch (opmode) {
 1666         case IEEE80211_M_STA:
 1667                 break;
 1668         case IEEE80211_M_IBSS:
 1669                 status |= IFM_IEEE80211_ADHOC;
 1670                 break;
 1671         case IEEE80211_M_HOSTAP:
 1672                 status |= IFM_IEEE80211_HOSTAP;
 1673                 break;
 1674         case IEEE80211_M_MONITOR:
 1675                 status |= IFM_IEEE80211_MONITOR;
 1676                 break;
 1677         case IEEE80211_M_AHDEMO:
 1678                 status |= IFM_IEEE80211_ADHOC | IFM_FLAG0;
 1679                 break;
 1680         case IEEE80211_M_WDS:
 1681                 status |= IFM_IEEE80211_WDS;
 1682                 break;
 1683         case IEEE80211_M_MBSS:
 1684                 status |= IFM_IEEE80211_MBSS;
 1685                 break;
 1686         }
 1687         if (IEEE80211_IS_CHAN_HTA(chan)) {
 1688                 status |= IFM_IEEE80211_11NA;
 1689         } else if (IEEE80211_IS_CHAN_HTG(chan)) {
 1690                 status |= IFM_IEEE80211_11NG;
 1691         } else if (IEEE80211_IS_CHAN_A(chan)) {
 1692                 status |= IFM_IEEE80211_11A;
 1693         } else if (IEEE80211_IS_CHAN_B(chan)) {
 1694                 status |= IFM_IEEE80211_11B;
 1695         } else if (IEEE80211_IS_CHAN_ANYG(chan)) {
 1696                 status |= IFM_IEEE80211_11G;
 1697         } else if (IEEE80211_IS_CHAN_FHSS(chan)) {
 1698                 status |= IFM_IEEE80211_FH;
 1699         }
 1700         /* XXX else complain? */
 1701 
 1702         if (IEEE80211_IS_CHAN_TURBO(chan))
 1703                 status |= IFM_IEEE80211_TURBO;
 1704 #if 0
 1705         if (IEEE80211_IS_CHAN_HT20(chan))
 1706                 status |= IFM_IEEE80211_HT20;
 1707         if (IEEE80211_IS_CHAN_HT40(chan))
 1708                 status |= IFM_IEEE80211_HT40;
 1709 #endif
 1710         return status;
 1711 }
 1712 
 1713 void
 1714 ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr)
 1715 {
 1716         struct ieee80211vap *vap = ifp->if_softc;
 1717         struct ieee80211com *ic = vap->iv_ic;
 1718         enum ieee80211_phymode mode;
 1719 
 1720         imr->ifm_status = IFM_AVALID;
 1721         /*
 1722          * NB: use the current channel's mode to lock down a xmit
 1723          * rate only when running; otherwise we may have a mismatch
 1724          * in which case the rate will not be convertible.
 1725          */
 1726         if (vap->iv_state == IEEE80211_S_RUN ||
 1727             vap->iv_state == IEEE80211_S_SLEEP) {
 1728                 imr->ifm_status |= IFM_ACTIVE;
 1729                 mode = ieee80211_chan2mode(ic->ic_curchan);
 1730         } else
 1731                 mode = IEEE80211_MODE_AUTO;
 1732         imr->ifm_active = media_status(vap->iv_opmode, ic->ic_curchan);
 1733         /*
 1734          * Calculate a current rate if possible.
 1735          */
 1736         if (vap->iv_txparms[mode].ucastrate != IEEE80211_FIXED_RATE_NONE) {
 1737                 /*
 1738                  * A fixed rate is set, report that.
 1739                  */
 1740                 imr->ifm_active |= ieee80211_rate2media(ic,
 1741                         vap->iv_txparms[mode].ucastrate, mode);
 1742         } else if (vap->iv_opmode == IEEE80211_M_STA) {
 1743                 /*
 1744                  * In station mode report the current transmit rate.
 1745                  */
 1746                 imr->ifm_active |= ieee80211_rate2media(ic,
 1747                         vap->iv_bss->ni_txrate, mode);
 1748         } else
 1749                 imr->ifm_active |= IFM_AUTO;
 1750         if (imr->ifm_status & IFM_ACTIVE)
 1751                 imr->ifm_current = imr->ifm_active;
 1752 }
 1753 
 1754 /*
 1755  * Set the current phy mode and recalculate the active channel
 1756  * set based on the available channels for this mode.  Also
 1757  * select a new default/current channel if the current one is
 1758  * inappropriate for this mode.
 1759  */
 1760 int
 1761 ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode)
 1762 {
 1763         /*
 1764          * Adjust basic rates in 11b/11g supported rate set.
 1765          * Note that if operating on a hal/quarter rate channel
 1766          * this is a noop as those rates sets are different
 1767          * and used instead.
 1768          */
 1769         if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11B)
 1770                 ieee80211_setbasicrates(&ic->ic_sup_rates[mode], mode);
 1771 
 1772         ic->ic_curmode = mode;
 1773         ieee80211_reset_erp(ic);        /* reset ERP state */
 1774 
 1775         return 0;
 1776 }
 1777 
 1778 /*
 1779  * Return the phy mode for with the specified channel.
 1780  */
 1781 enum ieee80211_phymode
 1782 ieee80211_chan2mode(const struct ieee80211_channel *chan)
 1783 {
 1784 
 1785         if (IEEE80211_IS_CHAN_HTA(chan))
 1786                 return IEEE80211_MODE_11NA;
 1787         else if (IEEE80211_IS_CHAN_HTG(chan))
 1788                 return IEEE80211_MODE_11NG;
 1789         else if (IEEE80211_IS_CHAN_108G(chan))
 1790                 return IEEE80211_MODE_TURBO_G;
 1791         else if (IEEE80211_IS_CHAN_ST(chan))
 1792                 return IEEE80211_MODE_STURBO_A;
 1793         else if (IEEE80211_IS_CHAN_TURBO(chan))
 1794                 return IEEE80211_MODE_TURBO_A;
 1795         else if (IEEE80211_IS_CHAN_HALF(chan))
 1796                 return IEEE80211_MODE_HALF;
 1797         else if (IEEE80211_IS_CHAN_QUARTER(chan))
 1798                 return IEEE80211_MODE_QUARTER;
 1799         else if (IEEE80211_IS_CHAN_A(chan))
 1800                 return IEEE80211_MODE_11A;
 1801         else if (IEEE80211_IS_CHAN_ANYG(chan))
 1802                 return IEEE80211_MODE_11G;
 1803         else if (IEEE80211_IS_CHAN_B(chan))
 1804                 return IEEE80211_MODE_11B;
 1805         else if (IEEE80211_IS_CHAN_FHSS(chan))
 1806                 return IEEE80211_MODE_FH;
 1807 
 1808         /* NB: should not get here */
 1809         printf("%s: cannot map channel to mode; freq %u flags 0x%x\n",
 1810                 __func__, chan->ic_freq, chan->ic_flags);
 1811         return IEEE80211_MODE_11B;
 1812 }
 1813 
 1814 struct ratemedia {
 1815         u_int   match;  /* rate + mode */
 1816         u_int   media;  /* if_media rate */
 1817 };
 1818 
 1819 static int
 1820 findmedia(const struct ratemedia rates[], int n, u_int match)
 1821 {
 1822         int i;
 1823 
 1824         for (i = 0; i < n; i++)
 1825                 if (rates[i].match == match)
 1826                         return rates[i].media;
 1827         return IFM_AUTO;
 1828 }
 1829 
 1830 /*
 1831  * Convert IEEE80211 rate value to ifmedia subtype.
 1832  * Rate is either a legacy rate in units of 0.5Mbps
 1833  * or an MCS index.
 1834  */
 1835 int
 1836 ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode mode)
 1837 {
 1838         static const struct ratemedia rates[] = {
 1839                 {   2 | IFM_IEEE80211_FH, IFM_IEEE80211_FH1 },
 1840                 {   4 | IFM_IEEE80211_FH, IFM_IEEE80211_FH2 },
 1841                 {   2 | IFM_IEEE80211_11B, IFM_IEEE80211_DS1 },
 1842                 {   4 | IFM_IEEE80211_11B, IFM_IEEE80211_DS2 },
 1843                 {  11 | IFM_IEEE80211_11B, IFM_IEEE80211_DS5 },
 1844                 {  22 | IFM_IEEE80211_11B, IFM_IEEE80211_DS11 },
 1845                 {  44 | IFM_IEEE80211_11B, IFM_IEEE80211_DS22 },
 1846                 {  12 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM6 },
 1847                 {  18 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM9 },
 1848                 {  24 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM12 },
 1849                 {  36 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM18 },
 1850                 {  48 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM24 },
 1851                 {  72 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM36 },
 1852                 {  96 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM48 },
 1853                 { 108 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM54 },
 1854                 {   2 | IFM_IEEE80211_11G, IFM_IEEE80211_DS1 },
 1855                 {   4 | IFM_IEEE80211_11G, IFM_IEEE80211_DS2 },
 1856                 {  11 | IFM_IEEE80211_11G, IFM_IEEE80211_DS5 },
 1857                 {  22 | IFM_IEEE80211_11G, IFM_IEEE80211_DS11 },
 1858                 {  12 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM6 },
 1859                 {  18 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM9 },
 1860                 {  24 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM12 },
 1861                 {  36 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM18 },
 1862                 {  48 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM24 },
 1863                 {  72 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM36 },
 1864                 {  96 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM48 },
 1865                 { 108 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM54 },
 1866                 {   6 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM3 },
 1867                 {   9 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM4 },
 1868                 {  54 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM27 },
 1869                 /* NB: OFDM72 doesn't really exist so we don't handle it */
 1870         };
 1871         static const struct ratemedia htrates[] = {
 1872                 {   0, IFM_IEEE80211_MCS },
 1873                 {   1, IFM_IEEE80211_MCS },
 1874                 {   2, IFM_IEEE80211_MCS },
 1875                 {   3, IFM_IEEE80211_MCS },
 1876                 {   4, IFM_IEEE80211_MCS },
 1877                 {   5, IFM_IEEE80211_MCS },
 1878                 {   6, IFM_IEEE80211_MCS },
 1879                 {   7, IFM_IEEE80211_MCS },
 1880                 {   8, IFM_IEEE80211_MCS },
 1881                 {   9, IFM_IEEE80211_MCS },
 1882                 {  10, IFM_IEEE80211_MCS },
 1883                 {  11, IFM_IEEE80211_MCS },
 1884                 {  12, IFM_IEEE80211_MCS },
 1885                 {  13, IFM_IEEE80211_MCS },
 1886                 {  14, IFM_IEEE80211_MCS },
 1887                 {  15, IFM_IEEE80211_MCS },
 1888                 {  16, IFM_IEEE80211_MCS },
 1889                 {  17, IFM_IEEE80211_MCS },
 1890                 {  18, IFM_IEEE80211_MCS },
 1891                 {  19, IFM_IEEE80211_MCS },
 1892                 {  20, IFM_IEEE80211_MCS },
 1893                 {  21, IFM_IEEE80211_MCS },
 1894                 {  22, IFM_IEEE80211_MCS },
 1895                 {  23, IFM_IEEE80211_MCS },
 1896                 {  24, IFM_IEEE80211_MCS },
 1897                 {  25, IFM_IEEE80211_MCS },
 1898                 {  26, IFM_IEEE80211_MCS },
 1899                 {  27, IFM_IEEE80211_MCS },
 1900                 {  28, IFM_IEEE80211_MCS },
 1901                 {  29, IFM_IEEE80211_MCS },
 1902                 {  30, IFM_IEEE80211_MCS },
 1903                 {  31, IFM_IEEE80211_MCS },
 1904                 {  32, IFM_IEEE80211_MCS },
 1905                 {  33, IFM_IEEE80211_MCS },
 1906                 {  34, IFM_IEEE80211_MCS },
 1907                 {  35, IFM_IEEE80211_MCS },
 1908                 {  36, IFM_IEEE80211_MCS },
 1909                 {  37, IFM_IEEE80211_MCS },
 1910                 {  38, IFM_IEEE80211_MCS },
 1911                 {  39, IFM_IEEE80211_MCS },
 1912                 {  40, IFM_IEEE80211_MCS },
 1913                 {  41, IFM_IEEE80211_MCS },
 1914                 {  42, IFM_IEEE80211_MCS },
 1915                 {  43, IFM_IEEE80211_MCS },
 1916                 {  44, IFM_IEEE80211_MCS },
 1917                 {  45, IFM_IEEE80211_MCS },
 1918                 {  46, IFM_IEEE80211_MCS },
 1919                 {  47, IFM_IEEE80211_MCS },
 1920                 {  48, IFM_IEEE80211_MCS },
 1921                 {  49, IFM_IEEE80211_MCS },
 1922                 {  50, IFM_IEEE80211_MCS },
 1923                 {  51, IFM_IEEE80211_MCS },
 1924                 {  52, IFM_IEEE80211_MCS },
 1925                 {  53, IFM_IEEE80211_MCS },
 1926                 {  54, IFM_IEEE80211_MCS },
 1927                 {  55, IFM_IEEE80211_MCS },
 1928                 {  56, IFM_IEEE80211_MCS },
 1929                 {  57, IFM_IEEE80211_MCS },
 1930                 {  58, IFM_IEEE80211_MCS },
 1931                 {  59, IFM_IEEE80211_MCS },
 1932                 {  60, IFM_IEEE80211_MCS },
 1933                 {  61, IFM_IEEE80211_MCS },
 1934                 {  62, IFM_IEEE80211_MCS },
 1935                 {  63, IFM_IEEE80211_MCS },
 1936                 {  64, IFM_IEEE80211_MCS },
 1937                 {  65, IFM_IEEE80211_MCS },
 1938                 {  66, IFM_IEEE80211_MCS },
 1939                 {  67, IFM_IEEE80211_MCS },
 1940                 {  68, IFM_IEEE80211_MCS },
 1941                 {  69, IFM_IEEE80211_MCS },
 1942                 {  70, IFM_IEEE80211_MCS },
 1943                 {  71, IFM_IEEE80211_MCS },
 1944                 {  72, IFM_IEEE80211_MCS },
 1945                 {  73, IFM_IEEE80211_MCS },
 1946                 {  74, IFM_IEEE80211_MCS },
 1947                 {  75, IFM_IEEE80211_MCS },
 1948                 {  76, IFM_IEEE80211_MCS },
 1949         };
 1950         int m;
 1951 
 1952         /*
 1953          * Check 11n rates first for match as an MCS.
 1954          */
 1955         if (mode == IEEE80211_MODE_11NA) {
 1956                 if (rate & IEEE80211_RATE_MCS) {
 1957                         rate &= ~IEEE80211_RATE_MCS;
 1958                         m = findmedia(htrates, nitems(htrates), rate);
 1959                         if (m != IFM_AUTO)
 1960                                 return m | IFM_IEEE80211_11NA;
 1961                 }
 1962         } else if (mode == IEEE80211_MODE_11NG) {
 1963                 /* NB: 12 is ambiguous, it will be treated as an MCS */
 1964                 if (rate & IEEE80211_RATE_MCS) {
 1965                         rate &= ~IEEE80211_RATE_MCS;
 1966                         m = findmedia(htrates, nitems(htrates), rate);
 1967                         if (m != IFM_AUTO)
 1968                                 return m | IFM_IEEE80211_11NG;
 1969                 }
 1970         }
 1971         rate &= IEEE80211_RATE_VAL;
 1972         switch (mode) {
 1973         case IEEE80211_MODE_11A:
 1974         case IEEE80211_MODE_HALF:               /* XXX good 'nuf */
 1975         case IEEE80211_MODE_QUARTER:
 1976         case IEEE80211_MODE_11NA:
 1977         case IEEE80211_MODE_TURBO_A:
 1978         case IEEE80211_MODE_STURBO_A:
 1979                 return findmedia(rates, nitems(rates),
 1980                     rate | IFM_IEEE80211_11A);
 1981         case IEEE80211_MODE_11B:
 1982                 return findmedia(rates, nitems(rates),
 1983                     rate | IFM_IEEE80211_11B);
 1984         case IEEE80211_MODE_FH:
 1985                 return findmedia(rates, nitems(rates),
 1986                     rate | IFM_IEEE80211_FH);
 1987         case IEEE80211_MODE_AUTO:
 1988                 /* NB: ic may be NULL for some drivers */
 1989                 if (ic != NULL && ic->ic_phytype == IEEE80211_T_FH)
 1990                         return findmedia(rates, nitems(rates),
 1991                             rate | IFM_IEEE80211_FH);
 1992                 /* NB: hack, 11g matches both 11b+11a rates */
 1993                 /* fall thru... */
 1994         case IEEE80211_MODE_11G:
 1995         case IEEE80211_MODE_11NG:
 1996         case IEEE80211_MODE_TURBO_G:
 1997                 return findmedia(rates, nitems(rates), rate | IFM_IEEE80211_11G);
 1998         }
 1999         return IFM_AUTO;
 2000 }
 2001 
 2002 int
 2003 ieee80211_media2rate(int mword)
 2004 {
 2005         static const int ieeerates[] = {
 2006                 -1,             /* IFM_AUTO */
 2007                 0,              /* IFM_MANUAL */
 2008                 0,              /* IFM_NONE */
 2009                 2,              /* IFM_IEEE80211_FH1 */
 2010                 4,              /* IFM_IEEE80211_FH2 */
 2011                 2,              /* IFM_IEEE80211_DS1 */
 2012                 4,              /* IFM_IEEE80211_DS2 */
 2013                 11,             /* IFM_IEEE80211_DS5 */
 2014                 22,             /* IFM_IEEE80211_DS11 */
 2015                 44,             /* IFM_IEEE80211_DS22 */
 2016                 12,             /* IFM_IEEE80211_OFDM6 */
 2017                 18,             /* IFM_IEEE80211_OFDM9 */
 2018                 24,             /* IFM_IEEE80211_OFDM12 */
 2019                 36,             /* IFM_IEEE80211_OFDM18 */
 2020                 48,             /* IFM_IEEE80211_OFDM24 */
 2021                 72,             /* IFM_IEEE80211_OFDM36 */
 2022                 96,             /* IFM_IEEE80211_OFDM48 */
 2023                 108,            /* IFM_IEEE80211_OFDM54 */
 2024                 144,            /* IFM_IEEE80211_OFDM72 */
 2025                 0,              /* IFM_IEEE80211_DS354k */
 2026                 0,              /* IFM_IEEE80211_DS512k */
 2027                 6,              /* IFM_IEEE80211_OFDM3 */
 2028                 9,              /* IFM_IEEE80211_OFDM4 */
 2029                 54,             /* IFM_IEEE80211_OFDM27 */
 2030                 -1,             /* IFM_IEEE80211_MCS */
 2031         };
 2032         return IFM_SUBTYPE(mword) < nitems(ieeerates) ?
 2033                 ieeerates[IFM_SUBTYPE(mword)] : 0;
 2034 }
 2035 
 2036 /*
 2037  * The following hash function is adapted from "Hash Functions" by Bob Jenkins
 2038  * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
 2039  */
 2040 #define mix(a, b, c)                                                    \
 2041 do {                                                                    \
 2042         a -= b; a -= c; a ^= (c >> 13);                                 \
 2043         b -= c; b -= a; b ^= (a << 8);                                  \
 2044         c -= a; c -= b; c ^= (b >> 13);                                 \
 2045         a -= b; a -= c; a ^= (c >> 12);                                 \
 2046         b -= c; b -= a; b ^= (a << 16);                                 \
 2047         c -= a; c -= b; c ^= (b >> 5);                                  \
 2048         a -= b; a -= c; a ^= (c >> 3);                                  \
 2049         b -= c; b -= a; b ^= (a << 10);                                 \
 2050         c -= a; c -= b; c ^= (b >> 15);                                 \
 2051 } while (/*CONSTCOND*/0)
 2052 
 2053 uint32_t
 2054 ieee80211_mac_hash(const struct ieee80211com *ic,
 2055         const uint8_t addr[IEEE80211_ADDR_LEN])
 2056 {
 2057         uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = ic->ic_hash_key;
 2058 
 2059         b += addr[5] << 8;
 2060         b += addr[4];
 2061         a += addr[3] << 24;
 2062         a += addr[2] << 16;
 2063         a += addr[1] << 8;
 2064         a += addr[0];
 2065 
 2066         mix(a, b, c);
 2067 
 2068         return c;
 2069 }
 2070 #undef mix
 2071 
 2072 char
 2073 ieee80211_channel_type_char(const struct ieee80211_channel *c)
 2074 {
 2075         if (IEEE80211_IS_CHAN_ST(c))
 2076                 return 'S';
 2077         if (IEEE80211_IS_CHAN_108A(c))
 2078                 return 'T';
 2079         if (IEEE80211_IS_CHAN_108G(c))
 2080                 return 'G';
 2081         if (IEEE80211_IS_CHAN_HT(c))
 2082                 return 'n';
 2083         if (IEEE80211_IS_CHAN_A(c))
 2084                 return 'a';
 2085         if (IEEE80211_IS_CHAN_ANYG(c))
 2086                 return 'g';
 2087         if (IEEE80211_IS_CHAN_B(c))
 2088                 return 'b';
 2089         return 'f';
 2090 }

Cache object: 2abb2b9e891ecf6de8733292a03d7648


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