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_proto.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-2008 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: releng/8.2/sys/net80211/ieee80211_proto.c 206780 2010-04-17 23:48:07Z weongyo $");
   29 
   30 /*
   31  * IEEE 802.11 protocol support.
   32  */
   33 
   34 #include "opt_inet.h"
   35 #include "opt_wlan.h"
   36 
   37 #include <sys/param.h>
   38 #include <sys/kernel.h>
   39 #include <sys/systm.h>
   40 
   41 #include <sys/socket.h>
   42 #include <sys/sockio.h>
   43 
   44 #include <net/if.h>
   45 #include <net/if_media.h>
   46 #include <net/ethernet.h>               /* XXX for ether_sprintf */
   47 
   48 #include <net80211/ieee80211_var.h>
   49 #include <net80211/ieee80211_adhoc.h>
   50 #include <net80211/ieee80211_sta.h>
   51 #include <net80211/ieee80211_hostap.h>
   52 #include <net80211/ieee80211_wds.h>
   53 #ifdef IEEE80211_SUPPORT_MESH
   54 #include <net80211/ieee80211_mesh.h>
   55 #endif
   56 #include <net80211/ieee80211_monitor.h>
   57 #include <net80211/ieee80211_input.h>
   58 
   59 /* XXX tunables */
   60 #define AGGRESSIVE_MODE_SWITCH_HYSTERESIS       3       /* pkts / 100ms */
   61 #define HIGH_PRI_SWITCH_THRESH                  10      /* pkts / 100ms */
   62 
   63 const char *ieee80211_mgt_subtype_name[] = {
   64         "assoc_req",    "assoc_resp",   "reassoc_req",  "reassoc_resp",
   65         "probe_req",    "probe_resp",   "reserved#6",   "reserved#7",
   66         "beacon",       "atim",         "disassoc",     "auth",
   67         "deauth",       "action",       "reserved#14",  "reserved#15"
   68 };
   69 const char *ieee80211_ctl_subtype_name[] = {
   70         "reserved#0",   "reserved#1",   "reserved#2",   "reserved#3",
   71         "reserved#3",   "reserved#5",   "reserved#6",   "reserved#7",
   72         "reserved#8",   "reserved#9",   "ps_poll",      "rts",
   73         "cts",          "ack",          "cf_end",       "cf_end_ack"
   74 };
   75 const char *ieee80211_opmode_name[IEEE80211_OPMODE_MAX] = {
   76         "IBSS",         /* IEEE80211_M_IBSS */
   77         "STA",          /* IEEE80211_M_STA */
   78         "WDS",          /* IEEE80211_M_WDS */
   79         "AHDEMO",       /* IEEE80211_M_AHDEMO */
   80         "HOSTAP",       /* IEEE80211_M_HOSTAP */
   81         "MONITOR",      /* IEEE80211_M_MONITOR */
   82         "MBSS"          /* IEEE80211_M_MBSS */
   83 };
   84 const char *ieee80211_state_name[IEEE80211_S_MAX] = {
   85         "INIT",         /* IEEE80211_S_INIT */
   86         "SCAN",         /* IEEE80211_S_SCAN */
   87         "AUTH",         /* IEEE80211_S_AUTH */
   88         "ASSOC",        /* IEEE80211_S_ASSOC */
   89         "CAC",          /* IEEE80211_S_CAC */
   90         "RUN",          /* IEEE80211_S_RUN */
   91         "CSA",          /* IEEE80211_S_CSA */
   92         "SLEEP",        /* IEEE80211_S_SLEEP */
   93 };
   94 const char *ieee80211_wme_acnames[] = {
   95         "WME_AC_BE",
   96         "WME_AC_BK",
   97         "WME_AC_VI",
   98         "WME_AC_VO",
   99         "WME_UPSD",
  100 };
  101 
  102 static void beacon_miss(void *, int);
  103 static void beacon_swmiss(void *, int);
  104 static void parent_updown(void *, int);
  105 static void update_mcast(void *, int);
  106 static void update_promisc(void *, int);
  107 static void update_channel(void *, int);
  108 static void ieee80211_newstate_cb(void *, int);
  109 static int ieee80211_new_state_locked(struct ieee80211vap *,
  110         enum ieee80211_state, int);
  111 
  112 static int
  113 null_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
  114         const struct ieee80211_bpf_params *params)
  115 {
  116         struct ifnet *ifp = ni->ni_ic->ic_ifp;
  117 
  118         if_printf(ifp, "missing ic_raw_xmit callback, drop frame\n");
  119         m_freem(m);
  120         return ENETDOWN;
  121 }
  122 
  123 void
  124 ieee80211_proto_attach(struct ieee80211com *ic)
  125 {
  126         struct ifnet *ifp = ic->ic_ifp;
  127 
  128         /* override the 802.3 setting */
  129         ifp->if_hdrlen = ic->ic_headroom
  130                 + sizeof(struct ieee80211_qosframe_addr4)
  131                 + IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN
  132                 + IEEE80211_WEP_EXTIVLEN;
  133         /* XXX no way to recalculate on ifdetach */
  134         if (ALIGN(ifp->if_hdrlen) > max_linkhdr) {
  135                 /* XXX sanity check... */
  136                 max_linkhdr = ALIGN(ifp->if_hdrlen);
  137                 max_hdr = max_linkhdr + max_protohdr;
  138                 max_datalen = MHLEN - max_hdr;
  139         }
  140         ic->ic_protmode = IEEE80211_PROT_CTSONLY;
  141 
  142         TASK_INIT(&ic->ic_parent_task, 0, parent_updown, ifp);
  143         TASK_INIT(&ic->ic_mcast_task, 0, update_mcast, ic);
  144         TASK_INIT(&ic->ic_promisc_task, 0, update_promisc, ic);
  145         TASK_INIT(&ic->ic_chan_task, 0, update_channel, ic);
  146         TASK_INIT(&ic->ic_bmiss_task, 0, beacon_miss, ic);
  147 
  148         ic->ic_wme.wme_hipri_switch_hysteresis =
  149                 AGGRESSIVE_MODE_SWITCH_HYSTERESIS;
  150 
  151         /* initialize management frame handlers */
  152         ic->ic_send_mgmt = ieee80211_send_mgmt;
  153         ic->ic_raw_xmit = null_raw_xmit;
  154 
  155         ieee80211_adhoc_attach(ic);
  156         ieee80211_sta_attach(ic);
  157         ieee80211_wds_attach(ic);
  158         ieee80211_hostap_attach(ic);
  159 #ifdef IEEE80211_SUPPORT_MESH
  160         ieee80211_mesh_attach(ic);
  161 #endif
  162         ieee80211_monitor_attach(ic);
  163 }
  164 
  165 void
  166 ieee80211_proto_detach(struct ieee80211com *ic)
  167 {
  168         ieee80211_monitor_detach(ic);
  169 #ifdef IEEE80211_SUPPORT_MESH
  170         ieee80211_mesh_detach(ic);
  171 #endif
  172         ieee80211_hostap_detach(ic);
  173         ieee80211_wds_detach(ic);
  174         ieee80211_adhoc_detach(ic);
  175         ieee80211_sta_detach(ic);
  176 }
  177 
  178 static void
  179 null_update_beacon(struct ieee80211vap *vap, int item)
  180 {
  181 }
  182 
  183 void
  184 ieee80211_proto_vattach(struct ieee80211vap *vap)
  185 {
  186         struct ieee80211com *ic = vap->iv_ic;
  187         struct ifnet *ifp = vap->iv_ifp;
  188         int i;
  189 
  190         /* override the 802.3 setting */
  191         ifp->if_hdrlen = ic->ic_ifp->if_hdrlen;
  192 
  193         vap->iv_rtsthreshold = IEEE80211_RTS_DEFAULT;
  194         vap->iv_fragthreshold = IEEE80211_FRAG_DEFAULT;
  195         vap->iv_bmiss_max = IEEE80211_BMISS_MAX;
  196         callout_init(&vap->iv_swbmiss, CALLOUT_MPSAFE);
  197         callout_init(&vap->iv_mgtsend, CALLOUT_MPSAFE);
  198         TASK_INIT(&vap->iv_nstate_task, 0, ieee80211_newstate_cb, vap);
  199         TASK_INIT(&vap->iv_swbmiss_task, 0, beacon_swmiss, vap);
  200         /*
  201          * Install default tx rate handling: no fixed rate, lowest
  202          * supported rate for mgmt and multicast frames.  Default
  203          * max retry count.  These settings can be changed by the
  204          * driver and/or user applications.
  205          */
  206         for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_MAX; i++) {
  207                 const struct ieee80211_rateset *rs = &ic->ic_sup_rates[i];
  208 
  209                 vap->iv_txparms[i].ucastrate = IEEE80211_FIXED_RATE_NONE;
  210                 if (i == IEEE80211_MODE_11NA || i == IEEE80211_MODE_11NG) {
  211                         vap->iv_txparms[i].mgmtrate = 0 | IEEE80211_RATE_MCS;
  212                         vap->iv_txparms[i].mcastrate = 0 | IEEE80211_RATE_MCS;
  213                 } else {
  214                         vap->iv_txparms[i].mgmtrate =
  215                             rs->rs_rates[0] & IEEE80211_RATE_VAL;
  216                         vap->iv_txparms[i].mcastrate = 
  217                             rs->rs_rates[0] & IEEE80211_RATE_VAL;
  218                 }
  219                 vap->iv_txparms[i].maxretry = IEEE80211_TXMAX_DEFAULT;
  220         }
  221         vap->iv_roaming = IEEE80211_ROAMING_AUTO;
  222 
  223         vap->iv_update_beacon = null_update_beacon;
  224         vap->iv_deliver_data = ieee80211_deliver_data;
  225 
  226         /* attach support for operating mode */
  227         ic->ic_vattach[vap->iv_opmode](vap);
  228 }
  229 
  230 void
  231 ieee80211_proto_vdetach(struct ieee80211vap *vap)
  232 {
  233 #define FREEAPPIE(ie) do { \
  234         if (ie != NULL) \
  235                 free(ie, M_80211_NODE_IE); \
  236 } while (0)
  237         /*
  238          * Detach operating mode module.
  239          */
  240         if (vap->iv_opdetach != NULL)
  241                 vap->iv_opdetach(vap);
  242         /*
  243          * This should not be needed as we detach when reseting
  244          * the state but be conservative here since the
  245          * authenticator may do things like spawn kernel threads.
  246          */
  247         if (vap->iv_auth->ia_detach != NULL)
  248                 vap->iv_auth->ia_detach(vap);
  249         /*
  250          * Detach any ACL'ator.
  251          */
  252         if (vap->iv_acl != NULL)
  253                 vap->iv_acl->iac_detach(vap);
  254 
  255         FREEAPPIE(vap->iv_appie_beacon);
  256         FREEAPPIE(vap->iv_appie_probereq);
  257         FREEAPPIE(vap->iv_appie_proberesp);
  258         FREEAPPIE(vap->iv_appie_assocreq);
  259         FREEAPPIE(vap->iv_appie_assocresp);
  260         FREEAPPIE(vap->iv_appie_wpa);
  261 #undef FREEAPPIE
  262 }
  263 
  264 /*
  265  * Simple-minded authenticator module support.
  266  */
  267 
  268 #define IEEE80211_AUTH_MAX      (IEEE80211_AUTH_WPA+1)
  269 /* XXX well-known names */
  270 static const char *auth_modnames[IEEE80211_AUTH_MAX] = {
  271         "wlan_internal",        /* IEEE80211_AUTH_NONE */
  272         "wlan_internal",        /* IEEE80211_AUTH_OPEN */
  273         "wlan_internal",        /* IEEE80211_AUTH_SHARED */
  274         "wlan_xauth",           /* IEEE80211_AUTH_8021X  */
  275         "wlan_internal",        /* IEEE80211_AUTH_AUTO */
  276         "wlan_xauth",           /* IEEE80211_AUTH_WPA */
  277 };
  278 static const struct ieee80211_authenticator *authenticators[IEEE80211_AUTH_MAX];
  279 
  280 static const struct ieee80211_authenticator auth_internal = {
  281         .ia_name                = "wlan_internal",
  282         .ia_attach              = NULL,
  283         .ia_detach              = NULL,
  284         .ia_node_join           = NULL,
  285         .ia_node_leave          = NULL,
  286 };
  287 
  288 /*
  289  * Setup internal authenticators once; they are never unregistered.
  290  */
  291 static void
  292 ieee80211_auth_setup(void)
  293 {
  294         ieee80211_authenticator_register(IEEE80211_AUTH_OPEN, &auth_internal);
  295         ieee80211_authenticator_register(IEEE80211_AUTH_SHARED, &auth_internal);
  296         ieee80211_authenticator_register(IEEE80211_AUTH_AUTO, &auth_internal);
  297 }
  298 SYSINIT(wlan_auth, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_auth_setup, NULL);
  299 
  300 const struct ieee80211_authenticator *
  301 ieee80211_authenticator_get(int auth)
  302 {
  303         if (auth >= IEEE80211_AUTH_MAX)
  304                 return NULL;
  305         if (authenticators[auth] == NULL)
  306                 ieee80211_load_module(auth_modnames[auth]);
  307         return authenticators[auth];
  308 }
  309 
  310 void
  311 ieee80211_authenticator_register(int type,
  312         const struct ieee80211_authenticator *auth)
  313 {
  314         if (type >= IEEE80211_AUTH_MAX)
  315                 return;
  316         authenticators[type] = auth;
  317 }
  318 
  319 void
  320 ieee80211_authenticator_unregister(int type)
  321 {
  322 
  323         if (type >= IEEE80211_AUTH_MAX)
  324                 return;
  325         authenticators[type] = NULL;
  326 }
  327 
  328 /*
  329  * Very simple-minded ACL module support.
  330  */
  331 /* XXX just one for now */
  332 static  const struct ieee80211_aclator *acl = NULL;
  333 
  334 void
  335 ieee80211_aclator_register(const struct ieee80211_aclator *iac)
  336 {
  337         printf("wlan: %s acl policy registered\n", iac->iac_name);
  338         acl = iac;
  339 }
  340 
  341 void
  342 ieee80211_aclator_unregister(const struct ieee80211_aclator *iac)
  343 {
  344         if (acl == iac)
  345                 acl = NULL;
  346         printf("wlan: %s acl policy unregistered\n", iac->iac_name);
  347 }
  348 
  349 const struct ieee80211_aclator *
  350 ieee80211_aclator_get(const char *name)
  351 {
  352         if (acl == NULL)
  353                 ieee80211_load_module("wlan_acl");
  354         return acl != NULL && strcmp(acl->iac_name, name) == 0 ? acl : NULL;
  355 }
  356 
  357 void
  358 ieee80211_print_essid(const uint8_t *essid, int len)
  359 {
  360         const uint8_t *p;
  361         int i;
  362 
  363         if (len > IEEE80211_NWID_LEN)
  364                 len = IEEE80211_NWID_LEN;
  365         /* determine printable or not */
  366         for (i = 0, p = essid; i < len; i++, p++) {
  367                 if (*p < ' ' || *p > 0x7e)
  368                         break;
  369         }
  370         if (i == len) {
  371                 printf("\"");
  372                 for (i = 0, p = essid; i < len; i++, p++)
  373                         printf("%c", *p);
  374                 printf("\"");
  375         } else {
  376                 printf("0x");
  377                 for (i = 0, p = essid; i < len; i++, p++)
  378                         printf("%02x", *p);
  379         }
  380 }
  381 
  382 void
  383 ieee80211_dump_pkt(struct ieee80211com *ic,
  384         const uint8_t *buf, int len, int rate, int rssi)
  385 {
  386         const struct ieee80211_frame *wh;
  387         int i;
  388 
  389         wh = (const struct ieee80211_frame *)buf;
  390         switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
  391         case IEEE80211_FC1_DIR_NODS:
  392                 printf("NODS %s", ether_sprintf(wh->i_addr2));
  393                 printf("->%s", ether_sprintf(wh->i_addr1));
  394                 printf("(%s)", ether_sprintf(wh->i_addr3));
  395                 break;
  396         case IEEE80211_FC1_DIR_TODS:
  397                 printf("TODS %s", ether_sprintf(wh->i_addr2));
  398                 printf("->%s", ether_sprintf(wh->i_addr3));
  399                 printf("(%s)", ether_sprintf(wh->i_addr1));
  400                 break;
  401         case IEEE80211_FC1_DIR_FROMDS:
  402                 printf("FRDS %s", ether_sprintf(wh->i_addr3));
  403                 printf("->%s", ether_sprintf(wh->i_addr1));
  404                 printf("(%s)", ether_sprintf(wh->i_addr2));
  405                 break;
  406         case IEEE80211_FC1_DIR_DSTODS:
  407                 printf("DSDS %s", ether_sprintf((const uint8_t *)&wh[1]));
  408                 printf("->%s", ether_sprintf(wh->i_addr3));
  409                 printf("(%s", ether_sprintf(wh->i_addr2));
  410                 printf("->%s)", ether_sprintf(wh->i_addr1));
  411                 break;
  412         }
  413         switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
  414         case IEEE80211_FC0_TYPE_DATA:
  415                 printf(" data");
  416                 break;
  417         case IEEE80211_FC0_TYPE_MGT:
  418                 printf(" %s", ieee80211_mgt_subtype_name[
  419                     (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK)
  420                     >> IEEE80211_FC0_SUBTYPE_SHIFT]);
  421                 break;
  422         default:
  423                 printf(" type#%d", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK);
  424                 break;
  425         }
  426         if (IEEE80211_QOS_HAS_SEQ(wh)) {
  427                 const struct ieee80211_qosframe *qwh = 
  428                         (const struct ieee80211_qosframe *)buf;
  429                 printf(" QoS [TID %u%s]", qwh->i_qos[0] & IEEE80211_QOS_TID,
  430                         qwh->i_qos[0] & IEEE80211_QOS_ACKPOLICY ? " ACM" : "");
  431         }
  432         if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
  433                 int off;
  434 
  435                 off = ieee80211_anyhdrspace(ic, wh);
  436                 printf(" WEP [IV %.02x %.02x %.02x",
  437                         buf[off+0], buf[off+1], buf[off+2]);
  438                 if (buf[off+IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV)
  439                         printf(" %.02x %.02x %.02x",
  440                                 buf[off+4], buf[off+5], buf[off+6]);
  441                 printf(" KID %u]", buf[off+IEEE80211_WEP_IVLEN] >> 6);
  442         }
  443         if (rate >= 0)
  444                 printf(" %dM", rate / 2);
  445         if (rssi >= 0)
  446                 printf(" +%d", rssi);
  447         printf("\n");
  448         if (len > 0) {
  449                 for (i = 0; i < len; i++) {
  450                         if ((i & 1) == 0)
  451                                 printf(" ");
  452                         printf("%02x", buf[i]);
  453                 }
  454                 printf("\n");
  455         }
  456 }
  457 
  458 static __inline int
  459 findrix(const struct ieee80211_rateset *rs, int r)
  460 {
  461         int i;
  462 
  463         for (i = 0; i < rs->rs_nrates; i++)
  464                 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == r)
  465                         return i;
  466         return -1;
  467 }
  468 
  469 int
  470 ieee80211_fix_rate(struct ieee80211_node *ni,
  471         struct ieee80211_rateset *nrs, int flags)
  472 {
  473 #define RV(v)   ((v) & IEEE80211_RATE_VAL)
  474         struct ieee80211vap *vap = ni->ni_vap;
  475         struct ieee80211com *ic = ni->ni_ic;
  476         int i, j, rix, error;
  477         int okrate, badrate, fixedrate, ucastrate;
  478         const struct ieee80211_rateset *srs;
  479         uint8_t r;
  480 
  481         error = 0;
  482         okrate = badrate = 0;
  483         ucastrate = vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)].ucastrate;
  484         if (ucastrate != IEEE80211_FIXED_RATE_NONE) {
  485                 /*
  486                  * Workaround awkwardness with fixed rate.  We are called
  487                  * to check both the legacy rate set and the HT rate set
  488                  * but we must apply any legacy fixed rate check only to the
  489                  * legacy rate set and vice versa.  We cannot tell what type
  490                  * of rate set we've been given (legacy or HT) but we can
  491                  * distinguish the fixed rate type (MCS have 0x80 set).
  492                  * So to deal with this the caller communicates whether to
  493                  * check MCS or legacy rate using the flags and we use the
  494                  * type of any fixed rate to avoid applying an MCS to a
  495                  * legacy rate and vice versa.
  496                  */
  497                 if (ucastrate & 0x80) {
  498                         if (flags & IEEE80211_F_DOFRATE)
  499                                 flags &= ~IEEE80211_F_DOFRATE;
  500                 } else if ((ucastrate & 0x80) == 0) {
  501                         if (flags & IEEE80211_F_DOFMCS)
  502                                 flags &= ~IEEE80211_F_DOFMCS;
  503                 }
  504                 /* NB: required to make MCS match below work */
  505                 ucastrate &= IEEE80211_RATE_VAL;
  506         }
  507         fixedrate = IEEE80211_FIXED_RATE_NONE;
  508         /*
  509          * XXX we are called to process both MCS and legacy rates;
  510          * we must use the appropriate basic rate set or chaos will
  511          * ensue; for now callers that want MCS must supply
  512          * IEEE80211_F_DOBRS; at some point we'll need to split this
  513          * function so there are two variants, one for MCS and one
  514          * for legacy rates.
  515          */
  516         if (flags & IEEE80211_F_DOBRS)
  517                 srs = (const struct ieee80211_rateset *)
  518                     ieee80211_get_suphtrates(ic, ni->ni_chan);
  519         else
  520                 srs = ieee80211_get_suprates(ic, ni->ni_chan);
  521         for (i = 0; i < nrs->rs_nrates; ) {
  522                 if (flags & IEEE80211_F_DOSORT) {
  523                         /*
  524                          * Sort rates.
  525                          */
  526                         for (j = i + 1; j < nrs->rs_nrates; j++) {
  527                                 if (RV(nrs->rs_rates[i]) > RV(nrs->rs_rates[j])) {
  528                                         r = nrs->rs_rates[i];
  529                                         nrs->rs_rates[i] = nrs->rs_rates[j];
  530                                         nrs->rs_rates[j] = r;
  531                                 }
  532                         }
  533                 }
  534                 r = nrs->rs_rates[i] & IEEE80211_RATE_VAL;
  535                 badrate = r;
  536                 /*
  537                  * Check for fixed rate.
  538                  */
  539                 if (r == ucastrate)
  540                         fixedrate = r;
  541                 /*
  542                  * Check against supported rates.
  543                  */
  544                 rix = findrix(srs, r);
  545                 if (flags & IEEE80211_F_DONEGO) {
  546                         if (rix < 0) {
  547                                 /*
  548                                  * A rate in the node's rate set is not
  549                                  * supported.  If this is a basic rate and we
  550                                  * are operating as a STA then this is an error.
  551                                  * Otherwise we just discard/ignore the rate.
  552                                  */
  553                                 if ((flags & IEEE80211_F_JOIN) &&
  554                                     (nrs->rs_rates[i] & IEEE80211_RATE_BASIC))
  555                                         error++;
  556                         } else if ((flags & IEEE80211_F_JOIN) == 0) {
  557                                 /*
  558                                  * Overwrite with the supported rate
  559                                  * value so any basic rate bit is set.
  560                                  */
  561                                 nrs->rs_rates[i] = srs->rs_rates[rix];
  562                         }
  563                 }
  564                 if ((flags & IEEE80211_F_DODEL) && rix < 0) {
  565                         /*
  566                          * Delete unacceptable rates.
  567                          */
  568                         nrs->rs_nrates--;
  569                         for (j = i; j < nrs->rs_nrates; j++)
  570                                 nrs->rs_rates[j] = nrs->rs_rates[j + 1];
  571                         nrs->rs_rates[j] = 0;
  572                         continue;
  573                 }
  574                 if (rix >= 0)
  575                         okrate = nrs->rs_rates[i];
  576                 i++;
  577         }
  578         if (okrate == 0 || error != 0 ||
  579             ((flags & (IEEE80211_F_DOFRATE|IEEE80211_F_DOFMCS)) &&
  580              fixedrate != ucastrate)) {
  581                 IEEE80211_NOTE(vap, IEEE80211_MSG_XRATE | IEEE80211_MSG_11N, ni,
  582                     "%s: flags 0x%x okrate %d error %d fixedrate 0x%x "
  583                     "ucastrate %x\n", __func__, fixedrate, ucastrate, flags);
  584                 return badrate | IEEE80211_RATE_BASIC;
  585         } else
  586                 return RV(okrate);
  587 #undef RV
  588 }
  589 
  590 /*
  591  * Reset 11g-related state.
  592  */
  593 void
  594 ieee80211_reset_erp(struct ieee80211com *ic)
  595 {
  596         ic->ic_flags &= ~IEEE80211_F_USEPROT;
  597         ic->ic_nonerpsta = 0;
  598         ic->ic_longslotsta = 0;
  599         /*
  600          * Short slot time is enabled only when operating in 11g
  601          * and not in an IBSS.  We must also honor whether or not
  602          * the driver is capable of doing it.
  603          */
  604         ieee80211_set_shortslottime(ic,
  605                 IEEE80211_IS_CHAN_A(ic->ic_curchan) ||
  606                 IEEE80211_IS_CHAN_HT(ic->ic_curchan) ||
  607                 (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) &&
  608                 ic->ic_opmode == IEEE80211_M_HOSTAP &&
  609                 (ic->ic_caps & IEEE80211_C_SHSLOT)));
  610         /*
  611          * Set short preamble and ERP barker-preamble flags.
  612          */
  613         if (IEEE80211_IS_CHAN_A(ic->ic_curchan) ||
  614             (ic->ic_caps & IEEE80211_C_SHPREAMBLE)) {
  615                 ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
  616                 ic->ic_flags &= ~IEEE80211_F_USEBARKER;
  617         } else {
  618                 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
  619                 ic->ic_flags |= IEEE80211_F_USEBARKER;
  620         }
  621 }
  622 
  623 /*
  624  * Set the short slot time state and notify the driver.
  625  */
  626 void
  627 ieee80211_set_shortslottime(struct ieee80211com *ic, int onoff)
  628 {
  629         if (onoff)
  630                 ic->ic_flags |= IEEE80211_F_SHSLOT;
  631         else
  632                 ic->ic_flags &= ~IEEE80211_F_SHSLOT;
  633         /* notify driver */
  634         if (ic->ic_updateslot != NULL)
  635                 ic->ic_updateslot(ic->ic_ifp);
  636 }
  637 
  638 /*
  639  * Check if the specified rate set supports ERP.
  640  * NB: the rate set is assumed to be sorted.
  641  */
  642 int
  643 ieee80211_iserp_rateset(const struct ieee80211_rateset *rs)
  644 {
  645 #define N(a)    (sizeof(a) / sizeof(a[0]))
  646         static const int rates[] = { 2, 4, 11, 22, 12, 24, 48 };
  647         int i, j;
  648 
  649         if (rs->rs_nrates < N(rates))
  650                 return 0;
  651         for (i = 0; i < N(rates); i++) {
  652                 for (j = 0; j < rs->rs_nrates; j++) {
  653                         int r = rs->rs_rates[j] & IEEE80211_RATE_VAL;
  654                         if (rates[i] == r)
  655                                 goto next;
  656                         if (r > rates[i])
  657                                 return 0;
  658                 }
  659                 return 0;
  660         next:
  661                 ;
  662         }
  663         return 1;
  664 #undef N
  665 }
  666 
  667 /*
  668  * Mark the basic rates for the rate table based on the
  669  * operating mode.  For real 11g we mark all the 11b rates
  670  * and 6, 12, and 24 OFDM.  For 11b compatibility we mark only
  671  * 11b rates.  There's also a pseudo 11a-mode used to mark only
  672  * the basic OFDM rates.
  673  */
  674 static void
  675 setbasicrates(struct ieee80211_rateset *rs,
  676     enum ieee80211_phymode mode, int add)
  677 {
  678         static const struct ieee80211_rateset basic[IEEE80211_MODE_MAX] = {
  679             [IEEE80211_MODE_11A]        = { 3, { 12, 24, 48 } },
  680             [IEEE80211_MODE_11B]        = { 2, { 2, 4 } },
  681                                             /* NB: mixed b/g */
  682             [IEEE80211_MODE_11G]        = { 4, { 2, 4, 11, 22 } },
  683             [IEEE80211_MODE_TURBO_A]    = { 3, { 12, 24, 48 } },
  684             [IEEE80211_MODE_TURBO_G]    = { 4, { 2, 4, 11, 22 } },
  685             [IEEE80211_MODE_STURBO_A]   = { 3, { 12, 24, 48 } },
  686             [IEEE80211_MODE_HALF]       = { 3, { 6, 12, 24 } },
  687             [IEEE80211_MODE_QUARTER]    = { 3, { 3, 6, 12 } },
  688             [IEEE80211_MODE_11NA]       = { 3, { 12, 24, 48 } },
  689                                             /* NB: mixed b/g */
  690             [IEEE80211_MODE_11NG]       = { 4, { 2, 4, 11, 22 } },
  691         };
  692         int i, j;
  693 
  694         for (i = 0; i < rs->rs_nrates; i++) {
  695                 if (!add)
  696                         rs->rs_rates[i] &= IEEE80211_RATE_VAL;
  697                 for (j = 0; j < basic[mode].rs_nrates; j++)
  698                         if (basic[mode].rs_rates[j] == rs->rs_rates[i]) {
  699                                 rs->rs_rates[i] |= IEEE80211_RATE_BASIC;
  700                                 break;
  701                         }
  702         }
  703 }
  704 
  705 /*
  706  * Set the basic rates in a rate set.
  707  */
  708 void
  709 ieee80211_setbasicrates(struct ieee80211_rateset *rs,
  710     enum ieee80211_phymode mode)
  711 {
  712         setbasicrates(rs, mode, 0);
  713 }
  714 
  715 /*
  716  * Add basic rates to a rate set.
  717  */
  718 void
  719 ieee80211_addbasicrates(struct ieee80211_rateset *rs,
  720     enum ieee80211_phymode mode)
  721 {
  722         setbasicrates(rs, mode, 1);
  723 }
  724 
  725 /*
  726  * WME protocol support.
  727  *
  728  * The default 11a/b/g/n parameters come from the WiFi Alliance WMM
  729  * System Interopability Test Plan (v1.4, Appendix F) and the 802.11n
  730  * Draft 2.0 Test Plan (Appendix D).
  731  *
  732  * Static/Dynamic Turbo mode settings come from Atheros.
  733  */
  734 typedef struct phyParamType {
  735         uint8_t         aifsn;
  736         uint8_t         logcwmin;
  737         uint8_t         logcwmax;
  738         uint16_t        txopLimit;
  739         uint8_t         acm;
  740 } paramType;
  741 
  742 static const struct phyParamType phyParamForAC_BE[IEEE80211_MODE_MAX] = {
  743         [IEEE80211_MODE_AUTO]   = { 3, 4,  6,  0, 0 },
  744         [IEEE80211_MODE_11A]    = { 3, 4,  6,  0, 0 },
  745         [IEEE80211_MODE_11B]    = { 3, 4,  6,  0, 0 },
  746         [IEEE80211_MODE_11G]    = { 3, 4,  6,  0, 0 },
  747         [IEEE80211_MODE_FH]     = { 3, 4,  6,  0, 0 },
  748         [IEEE80211_MODE_TURBO_A]= { 2, 3,  5,  0, 0 },
  749         [IEEE80211_MODE_TURBO_G]= { 2, 3,  5,  0, 0 },
  750         [IEEE80211_MODE_STURBO_A]={ 2, 3,  5,  0, 0 },
  751         [IEEE80211_MODE_HALF]   = { 3, 4,  6,  0, 0 },
  752         [IEEE80211_MODE_QUARTER]= { 3, 4,  6,  0, 0 },
  753         [IEEE80211_MODE_11NA]   = { 3, 4,  6,  0, 0 },
  754         [IEEE80211_MODE_11NG]   = { 3, 4,  6,  0, 0 },
  755 };
  756 static const struct phyParamType phyParamForAC_BK[IEEE80211_MODE_MAX] = {
  757         [IEEE80211_MODE_AUTO]   = { 7, 4, 10,  0, 0 },
  758         [IEEE80211_MODE_11A]    = { 7, 4, 10,  0, 0 },
  759         [IEEE80211_MODE_11B]    = { 7, 4, 10,  0, 0 },
  760         [IEEE80211_MODE_11G]    = { 7, 4, 10,  0, 0 },
  761         [IEEE80211_MODE_FH]     = { 7, 4, 10,  0, 0 },
  762         [IEEE80211_MODE_TURBO_A]= { 7, 3, 10,  0, 0 },
  763         [IEEE80211_MODE_TURBO_G]= { 7, 3, 10,  0, 0 },
  764         [IEEE80211_MODE_STURBO_A]={ 7, 3, 10,  0, 0 },
  765         [IEEE80211_MODE_HALF]   = { 7, 4, 10,  0, 0 },
  766         [IEEE80211_MODE_QUARTER]= { 7, 4, 10,  0, 0 },
  767         [IEEE80211_MODE_11NA]   = { 7, 4, 10,  0, 0 },
  768         [IEEE80211_MODE_11NG]   = { 7, 4, 10,  0, 0 },
  769 };
  770 static const struct phyParamType phyParamForAC_VI[IEEE80211_MODE_MAX] = {
  771         [IEEE80211_MODE_AUTO]   = { 1, 3, 4,  94, 0 },
  772         [IEEE80211_MODE_11A]    = { 1, 3, 4,  94, 0 },
  773         [IEEE80211_MODE_11B]    = { 1, 3, 4, 188, 0 },
  774         [IEEE80211_MODE_11G]    = { 1, 3, 4,  94, 0 },
  775         [IEEE80211_MODE_FH]     = { 1, 3, 4, 188, 0 },
  776         [IEEE80211_MODE_TURBO_A]= { 1, 2, 3,  94, 0 },
  777         [IEEE80211_MODE_TURBO_G]= { 1, 2, 3,  94, 0 },
  778         [IEEE80211_MODE_STURBO_A]={ 1, 2, 3,  94, 0 },
  779         [IEEE80211_MODE_HALF]   = { 1, 3, 4,  94, 0 },
  780         [IEEE80211_MODE_QUARTER]= { 1, 3, 4,  94, 0 },
  781         [IEEE80211_MODE_11NA]   = { 1, 3, 4,  94, 0 },
  782         [IEEE80211_MODE_11NG]   = { 1, 3, 4,  94, 0 },
  783 };
  784 static const struct phyParamType phyParamForAC_VO[IEEE80211_MODE_MAX] = {
  785         [IEEE80211_MODE_AUTO]   = { 1, 2, 3,  47, 0 },
  786         [IEEE80211_MODE_11A]    = { 1, 2, 3,  47, 0 },
  787         [IEEE80211_MODE_11B]    = { 1, 2, 3, 102, 0 },
  788         [IEEE80211_MODE_11G]    = { 1, 2, 3,  47, 0 },
  789         [IEEE80211_MODE_FH]     = { 1, 2, 3, 102, 0 },
  790         [IEEE80211_MODE_TURBO_A]= { 1, 2, 2,  47, 0 },
  791         [IEEE80211_MODE_TURBO_G]= { 1, 2, 2,  47, 0 },
  792         [IEEE80211_MODE_STURBO_A]={ 1, 2, 2,  47, 0 },
  793         [IEEE80211_MODE_HALF]   = { 1, 2, 3,  47, 0 },
  794         [IEEE80211_MODE_QUARTER]= { 1, 2, 3,  47, 0 },
  795         [IEEE80211_MODE_11NA]   = { 1, 2, 3,  47, 0 },
  796         [IEEE80211_MODE_11NG]   = { 1, 2, 3,  47, 0 },
  797 };
  798 
  799 static const struct phyParamType bssPhyParamForAC_BE[IEEE80211_MODE_MAX] = {
  800         [IEEE80211_MODE_AUTO]   = { 3, 4, 10,  0, 0 },
  801         [IEEE80211_MODE_11A]    = { 3, 4, 10,  0, 0 },
  802         [IEEE80211_MODE_11B]    = { 3, 4, 10,  0, 0 },
  803         [IEEE80211_MODE_11G]    = { 3, 4, 10,  0, 0 },
  804         [IEEE80211_MODE_FH]     = { 3, 4, 10,  0, 0 },
  805         [IEEE80211_MODE_TURBO_A]= { 2, 3, 10,  0, 0 },
  806         [IEEE80211_MODE_TURBO_G]= { 2, 3, 10,  0, 0 },
  807         [IEEE80211_MODE_STURBO_A]={ 2, 3, 10,  0, 0 },
  808         [IEEE80211_MODE_HALF]   = { 3, 4, 10,  0, 0 },
  809         [IEEE80211_MODE_QUARTER]= { 3, 4, 10,  0, 0 },
  810         [IEEE80211_MODE_11NA]   = { 3, 4, 10,  0, 0 },
  811         [IEEE80211_MODE_11NG]   = { 3, 4, 10,  0, 0 },
  812 };
  813 static const struct phyParamType bssPhyParamForAC_VI[IEEE80211_MODE_MAX] = {
  814         [IEEE80211_MODE_AUTO]   = { 2, 3, 4,  94, 0 },
  815         [IEEE80211_MODE_11A]    = { 2, 3, 4,  94, 0 },
  816         [IEEE80211_MODE_11B]    = { 2, 3, 4, 188, 0 },
  817         [IEEE80211_MODE_11G]    = { 2, 3, 4,  94, 0 },
  818         [IEEE80211_MODE_FH]     = { 2, 3, 4, 188, 0 },
  819         [IEEE80211_MODE_TURBO_A]= { 2, 2, 3,  94, 0 },
  820         [IEEE80211_MODE_TURBO_G]= { 2, 2, 3,  94, 0 },
  821         [IEEE80211_MODE_STURBO_A]={ 2, 2, 3,  94, 0 },
  822         [IEEE80211_MODE_HALF]   = { 2, 3, 4,  94, 0 },
  823         [IEEE80211_MODE_QUARTER]= { 2, 3, 4,  94, 0 },
  824         [IEEE80211_MODE_11NA]   = { 2, 3, 4,  94, 0 },
  825         [IEEE80211_MODE_11NG]   = { 2, 3, 4,  94, 0 },
  826 };
  827 static const struct phyParamType bssPhyParamForAC_VO[IEEE80211_MODE_MAX] = {
  828         [IEEE80211_MODE_AUTO]   = { 2, 2, 3,  47, 0 },
  829         [IEEE80211_MODE_11A]    = { 2, 2, 3,  47, 0 },
  830         [IEEE80211_MODE_11B]    = { 2, 2, 3, 102, 0 },
  831         [IEEE80211_MODE_11G]    = { 2, 2, 3,  47, 0 },
  832         [IEEE80211_MODE_FH]     = { 2, 2, 3, 102, 0 },
  833         [IEEE80211_MODE_TURBO_A]= { 1, 2, 2,  47, 0 },
  834         [IEEE80211_MODE_TURBO_G]= { 1, 2, 2,  47, 0 },
  835         [IEEE80211_MODE_STURBO_A]={ 1, 2, 2,  47, 0 },
  836         [IEEE80211_MODE_HALF]   = { 2, 2, 3,  47, 0 },
  837         [IEEE80211_MODE_QUARTER]= { 2, 2, 3,  47, 0 },
  838         [IEEE80211_MODE_11NA]   = { 2, 2, 3,  47, 0 },
  839         [IEEE80211_MODE_11NG]   = { 2, 2, 3,  47, 0 },
  840 };
  841 
  842 static void
  843 _setifsparams(struct wmeParams *wmep, const paramType *phy)
  844 {
  845         wmep->wmep_aifsn = phy->aifsn;
  846         wmep->wmep_logcwmin = phy->logcwmin;    
  847         wmep->wmep_logcwmax = phy->logcwmax;            
  848         wmep->wmep_txopLimit = phy->txopLimit;
  849 }
  850 
  851 static void
  852 setwmeparams(struct ieee80211vap *vap, const char *type, int ac,
  853         struct wmeParams *wmep, const paramType *phy)
  854 {
  855         wmep->wmep_acm = phy->acm;
  856         _setifsparams(wmep, phy);
  857 
  858         IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME,
  859             "set %s (%s) [acm %u aifsn %u logcwmin %u logcwmax %u txop %u]\n",
  860             ieee80211_wme_acnames[ac], type,
  861             wmep->wmep_acm, wmep->wmep_aifsn, wmep->wmep_logcwmin,
  862             wmep->wmep_logcwmax, wmep->wmep_txopLimit);
  863 }
  864 
  865 static void
  866 ieee80211_wme_initparams_locked(struct ieee80211vap *vap)
  867 {
  868         struct ieee80211com *ic = vap->iv_ic;
  869         struct ieee80211_wme_state *wme = &ic->ic_wme;
  870         const paramType *pPhyParam, *pBssPhyParam;
  871         struct wmeParams *wmep;
  872         enum ieee80211_phymode mode;
  873         int i;
  874 
  875         IEEE80211_LOCK_ASSERT(ic);
  876 
  877         if ((ic->ic_caps & IEEE80211_C_WME) == 0 || ic->ic_nrunning > 1)
  878                 return;
  879 
  880         /*
  881          * Select mode; we can be called early in which case we
  882          * always use auto mode.  We know we'll be called when
  883          * entering the RUN state with bsschan setup properly
  884          * so state will eventually get set correctly
  885          */
  886         if (ic->ic_bsschan != IEEE80211_CHAN_ANYC)
  887                 mode = ieee80211_chan2mode(ic->ic_bsschan);
  888         else
  889                 mode = IEEE80211_MODE_AUTO;
  890         for (i = 0; i < WME_NUM_AC; i++) {
  891                 switch (i) {
  892                 case WME_AC_BK:
  893                         pPhyParam = &phyParamForAC_BK[mode];
  894                         pBssPhyParam = &phyParamForAC_BK[mode];
  895                         break;
  896                 case WME_AC_VI:
  897                         pPhyParam = &phyParamForAC_VI[mode];
  898                         pBssPhyParam = &bssPhyParamForAC_VI[mode];
  899                         break;
  900                 case WME_AC_VO:
  901                         pPhyParam = &phyParamForAC_VO[mode];
  902                         pBssPhyParam = &bssPhyParamForAC_VO[mode];
  903                         break;
  904                 case WME_AC_BE:
  905                 default:
  906                         pPhyParam = &phyParamForAC_BE[mode];
  907                         pBssPhyParam = &bssPhyParamForAC_BE[mode];
  908                         break;
  909                 }
  910                 wmep = &wme->wme_wmeChanParams.cap_wmeParams[i];
  911                 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
  912                         setwmeparams(vap, "chan", i, wmep, pPhyParam);
  913                 } else {
  914                         setwmeparams(vap, "chan", i, wmep, pBssPhyParam);
  915                 }       
  916                 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i];
  917                 setwmeparams(vap, "bss ", i, wmep, pBssPhyParam);
  918         }
  919         /* NB: check ic_bss to avoid NULL deref on initial attach */
  920         if (vap->iv_bss != NULL) {
  921                 /*
  922                  * Calculate agressive mode switching threshold based
  923                  * on beacon interval.  This doesn't need locking since
  924                  * we're only called before entering the RUN state at
  925                  * which point we start sending beacon frames.
  926                  */
  927                 wme->wme_hipri_switch_thresh =
  928                         (HIGH_PRI_SWITCH_THRESH * vap->iv_bss->ni_intval) / 100;
  929                 wme->wme_flags &= ~WME_F_AGGRMODE;
  930                 ieee80211_wme_updateparams(vap);
  931         }
  932 }
  933 
  934 void
  935 ieee80211_wme_initparams(struct ieee80211vap *vap)
  936 {
  937         struct ieee80211com *ic = vap->iv_ic;
  938 
  939         IEEE80211_LOCK(ic);
  940         ieee80211_wme_initparams_locked(vap);
  941         IEEE80211_UNLOCK(ic);
  942 }
  943 
  944 /*
  945  * Update WME parameters for ourself and the BSS.
  946  */
  947 void
  948 ieee80211_wme_updateparams_locked(struct ieee80211vap *vap)
  949 {
  950         static const paramType aggrParam[IEEE80211_MODE_MAX] = {
  951             [IEEE80211_MODE_AUTO]       = { 2, 4, 10, 64, 0 },
  952             [IEEE80211_MODE_11A]        = { 2, 4, 10, 64, 0 },
  953             [IEEE80211_MODE_11B]        = { 2, 5, 10, 64, 0 },
  954             [IEEE80211_MODE_11G]        = { 2, 4, 10, 64, 0 },
  955             [IEEE80211_MODE_FH]         = { 2, 5, 10, 64, 0 },
  956             [IEEE80211_MODE_TURBO_A]    = { 1, 3, 10, 64, 0 },
  957             [IEEE80211_MODE_TURBO_G]    = { 1, 3, 10, 64, 0 },
  958             [IEEE80211_MODE_STURBO_A]   = { 1, 3, 10, 64, 0 },
  959             [IEEE80211_MODE_HALF]       = { 2, 4, 10, 64, 0 },
  960             [IEEE80211_MODE_QUARTER]    = { 2, 4, 10, 64, 0 },
  961             [IEEE80211_MODE_11NA]       = { 2, 4, 10, 64, 0 },  /* XXXcheck*/
  962             [IEEE80211_MODE_11NG]       = { 2, 4, 10, 64, 0 },  /* XXXcheck*/
  963         };
  964         struct ieee80211com *ic = vap->iv_ic;
  965         struct ieee80211_wme_state *wme = &ic->ic_wme;
  966         const struct wmeParams *wmep;
  967         struct wmeParams *chanp, *bssp;
  968         enum ieee80211_phymode mode;
  969         int i;
  970 
  971         /*
  972          * Set up the channel access parameters for the physical
  973          * device.  First populate the configured settings.
  974          */
  975         for (i = 0; i < WME_NUM_AC; i++) {
  976                 chanp = &wme->wme_chanParams.cap_wmeParams[i];
  977                 wmep = &wme->wme_wmeChanParams.cap_wmeParams[i];
  978                 chanp->wmep_aifsn = wmep->wmep_aifsn;
  979                 chanp->wmep_logcwmin = wmep->wmep_logcwmin;
  980                 chanp->wmep_logcwmax = wmep->wmep_logcwmax;
  981                 chanp->wmep_txopLimit = wmep->wmep_txopLimit;
  982 
  983                 chanp = &wme->wme_bssChanParams.cap_wmeParams[i];
  984                 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i];
  985                 chanp->wmep_aifsn = wmep->wmep_aifsn;
  986                 chanp->wmep_logcwmin = wmep->wmep_logcwmin;
  987                 chanp->wmep_logcwmax = wmep->wmep_logcwmax;
  988                 chanp->wmep_txopLimit = wmep->wmep_txopLimit;
  989         }
  990 
  991         /*
  992          * Select mode; we can be called early in which case we
  993          * always use auto mode.  We know we'll be called when
  994          * entering the RUN state with bsschan setup properly
  995          * so state will eventually get set correctly
  996          */
  997         if (ic->ic_bsschan != IEEE80211_CHAN_ANYC)
  998                 mode = ieee80211_chan2mode(ic->ic_bsschan);
  999         else
 1000                 mode = IEEE80211_MODE_AUTO;
 1001 
 1002         /*
 1003          * This implements agressive mode as found in certain
 1004          * vendors' AP's.  When there is significant high
 1005          * priority (VI/VO) traffic in the BSS throttle back BE
 1006          * traffic by using conservative parameters.  Otherwise
 1007          * BE uses agressive params to optimize performance of
 1008          * legacy/non-QoS traffic.
 1009          */
 1010         if ((vap->iv_opmode == IEEE80211_M_HOSTAP &&
 1011              (wme->wme_flags & WME_F_AGGRMODE) != 0) ||
 1012             (vap->iv_opmode == IEEE80211_M_STA &&
 1013              (vap->iv_bss->ni_flags & IEEE80211_NODE_QOS) == 0) ||
 1014             (vap->iv_flags & IEEE80211_F_WME) == 0) {
 1015                 chanp = &wme->wme_chanParams.cap_wmeParams[WME_AC_BE];
 1016                 bssp = &wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE];
 1017 
 1018                 chanp->wmep_aifsn = bssp->wmep_aifsn = aggrParam[mode].aifsn;
 1019                 chanp->wmep_logcwmin = bssp->wmep_logcwmin =
 1020                     aggrParam[mode].logcwmin;
 1021                 chanp->wmep_logcwmax = bssp->wmep_logcwmax =
 1022                     aggrParam[mode].logcwmax;
 1023                 chanp->wmep_txopLimit = bssp->wmep_txopLimit =
 1024                     (vap->iv_flags & IEEE80211_F_BURST) ?
 1025                         aggrParam[mode].txopLimit : 0;          
 1026                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME,
 1027                     "update %s (chan+bss) [acm %u aifsn %u logcwmin %u "
 1028                     "logcwmax %u txop %u]\n", ieee80211_wme_acnames[WME_AC_BE],
 1029                     chanp->wmep_acm, chanp->wmep_aifsn, chanp->wmep_logcwmin,
 1030                     chanp->wmep_logcwmax, chanp->wmep_txopLimit);
 1031         }
 1032         
 1033         if (vap->iv_opmode == IEEE80211_M_HOSTAP &&
 1034             ic->ic_sta_assoc < 2 && (wme->wme_flags & WME_F_AGGRMODE) != 0) {
 1035                 static const uint8_t logCwMin[IEEE80211_MODE_MAX] = {
 1036                     [IEEE80211_MODE_AUTO]       = 3,
 1037                     [IEEE80211_MODE_11A]        = 3,
 1038                     [IEEE80211_MODE_11B]        = 4,
 1039                     [IEEE80211_MODE_11G]        = 3,
 1040                     [IEEE80211_MODE_FH]         = 4,
 1041                     [IEEE80211_MODE_TURBO_A]    = 3,
 1042                     [IEEE80211_MODE_TURBO_G]    = 3,
 1043                     [IEEE80211_MODE_STURBO_A]   = 3,
 1044                     [IEEE80211_MODE_HALF]       = 3,
 1045                     [IEEE80211_MODE_QUARTER]    = 3,
 1046                     [IEEE80211_MODE_11NA]       = 3,
 1047                     [IEEE80211_MODE_11NG]       = 3,
 1048                 };
 1049                 chanp = &wme->wme_chanParams.cap_wmeParams[WME_AC_BE];
 1050                 bssp = &wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE];
 1051 
 1052                 chanp->wmep_logcwmin = bssp->wmep_logcwmin = logCwMin[mode];
 1053                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME,
 1054                     "update %s (chan+bss) logcwmin %u\n",
 1055                     ieee80211_wme_acnames[WME_AC_BE], chanp->wmep_logcwmin);
 1056         }       
 1057         if (vap->iv_opmode == IEEE80211_M_HOSTAP) {     /* XXX ibss? */
 1058                 /*
 1059                  * Arrange for a beacon update and bump the parameter
 1060                  * set number so associated stations load the new values.
 1061                  */
 1062                 wme->wme_bssChanParams.cap_info =
 1063                         (wme->wme_bssChanParams.cap_info+1) & WME_QOSINFO_COUNT;
 1064                 ieee80211_beacon_notify(vap, IEEE80211_BEACON_WME);
 1065         }
 1066 
 1067         wme->wme_update(ic);
 1068 
 1069         IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME,
 1070             "%s: WME params updated, cap_info 0x%x\n", __func__,
 1071             vap->iv_opmode == IEEE80211_M_STA ?
 1072                 wme->wme_wmeChanParams.cap_info :
 1073                 wme->wme_bssChanParams.cap_info);
 1074 }
 1075 
 1076 void
 1077 ieee80211_wme_updateparams(struct ieee80211vap *vap)
 1078 {
 1079         struct ieee80211com *ic = vap->iv_ic;
 1080 
 1081         if (ic->ic_caps & IEEE80211_C_WME) {
 1082                 IEEE80211_LOCK(ic);
 1083                 ieee80211_wme_updateparams_locked(vap);
 1084                 IEEE80211_UNLOCK(ic);
 1085         }
 1086 }
 1087 
 1088 static void
 1089 parent_updown(void *arg, int npending)
 1090 {
 1091         struct ifnet *parent = arg;
 1092 
 1093         parent->if_ioctl(parent, SIOCSIFFLAGS, NULL);
 1094 }
 1095 
 1096 static void
 1097 update_mcast(void *arg, int npending)
 1098 {
 1099         struct ieee80211com *ic = arg;
 1100         struct ifnet *parent = ic->ic_ifp;
 1101 
 1102         ic->ic_update_mcast(parent);
 1103 }
 1104 
 1105 static void
 1106 update_promisc(void *arg, int npending)
 1107 {
 1108         struct ieee80211com *ic = arg;
 1109         struct ifnet *parent = ic->ic_ifp;
 1110 
 1111         ic->ic_update_promisc(parent);
 1112 }
 1113 
 1114 static void
 1115 update_channel(void *arg, int npending)
 1116 {
 1117         struct ieee80211com *ic = arg;
 1118 
 1119         ic->ic_set_channel(ic);
 1120         ieee80211_radiotap_chan_change(ic);
 1121 }
 1122 
 1123 /*
 1124  * Block until the parent is in a known state.  This is
 1125  * used after any operations that dispatch a task (e.g.
 1126  * to auto-configure the parent device up/down).
 1127  */
 1128 void
 1129 ieee80211_waitfor_parent(struct ieee80211com *ic)
 1130 {
 1131         taskqueue_block(ic->ic_tq);
 1132         ieee80211_draintask(ic, &ic->ic_parent_task);
 1133         ieee80211_draintask(ic, &ic->ic_mcast_task);
 1134         ieee80211_draintask(ic, &ic->ic_promisc_task);
 1135         ieee80211_draintask(ic, &ic->ic_chan_task);
 1136         ieee80211_draintask(ic, &ic->ic_bmiss_task);
 1137         taskqueue_unblock(ic->ic_tq);
 1138 }
 1139 
 1140 /*
 1141  * Start a vap running.  If this is the first vap to be
 1142  * set running on the underlying device then we
 1143  * automatically bring the device up.
 1144  */
 1145 void
 1146 ieee80211_start_locked(struct ieee80211vap *vap)
 1147 {
 1148         struct ifnet *ifp = vap->iv_ifp;
 1149         struct ieee80211com *ic = vap->iv_ic;
 1150         struct ifnet *parent = ic->ic_ifp;
 1151 
 1152         IEEE80211_LOCK_ASSERT(ic);
 1153 
 1154         IEEE80211_DPRINTF(vap,
 1155                 IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
 1156                 "start running, %d vaps running\n", ic->ic_nrunning);
 1157 
 1158         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 1159                 /*
 1160                  * Mark us running.  Note that it's ok to do this first;
 1161                  * if we need to bring the parent device up we defer that
 1162                  * to avoid dropping the com lock.  We expect the device
 1163                  * to respond to being marked up by calling back into us
 1164                  * through ieee80211_start_all at which point we'll come
 1165                  * back in here and complete the work.
 1166                  */
 1167                 ifp->if_drv_flags |= IFF_DRV_RUNNING;
 1168                 /*
 1169                  * We are not running; if this we are the first vap
 1170                  * to be brought up auto-up the parent if necessary.
 1171                  */
 1172                 if (ic->ic_nrunning++ == 0 &&
 1173                     (parent->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 1174                         IEEE80211_DPRINTF(vap,
 1175                             IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
 1176                             "%s: up parent %s\n", __func__, parent->if_xname);
 1177                         parent->if_flags |= IFF_UP;
 1178                         ieee80211_runtask(ic, &ic->ic_parent_task);
 1179                         return;
 1180                 }
 1181         }
 1182         /*
 1183          * If the parent is up and running, then kick the
 1184          * 802.11 state machine as appropriate.
 1185          */
 1186         if ((parent->if_drv_flags & IFF_DRV_RUNNING) &&
 1187             vap->iv_roaming != IEEE80211_ROAMING_MANUAL) {
 1188                 if (vap->iv_opmode == IEEE80211_M_STA) {
 1189 #if 0
 1190                         /* XXX bypasses scan too easily; disable for now */
 1191                         /*
 1192                          * Try to be intelligent about clocking the state
 1193                          * machine.  If we're currently in RUN state then
 1194                          * we should be able to apply any new state/parameters
 1195                          * simply by re-associating.  Otherwise we need to
 1196                          * re-scan to select an appropriate ap.
 1197                          */ 
 1198                         if (vap->iv_state >= IEEE80211_S_RUN)
 1199                                 ieee80211_new_state_locked(vap,
 1200                                     IEEE80211_S_ASSOC, 1);
 1201                         else
 1202 #endif
 1203                                 ieee80211_new_state_locked(vap,
 1204                                     IEEE80211_S_SCAN, 0);
 1205                 } else {
 1206                         /*
 1207                          * For monitor+wds mode there's nothing to do but
 1208                          * start running.  Otherwise if this is the first
 1209                          * vap to be brought up, start a scan which may be
 1210                          * preempted if the station is locked to a particular
 1211                          * channel.
 1212                          */
 1213                         vap->iv_flags_ext |= IEEE80211_FEXT_REINIT;
 1214                         if (vap->iv_opmode == IEEE80211_M_MONITOR ||
 1215                             vap->iv_opmode == IEEE80211_M_WDS)
 1216                                 ieee80211_new_state_locked(vap,
 1217                                     IEEE80211_S_RUN, -1);
 1218                         else
 1219                                 ieee80211_new_state_locked(vap,
 1220                                     IEEE80211_S_SCAN, 0);
 1221                 }
 1222         }
 1223 }
 1224 
 1225 /*
 1226  * Start a single vap.
 1227  */
 1228 void
 1229 ieee80211_init(void *arg)
 1230 {
 1231         struct ieee80211vap *vap = arg;
 1232 
 1233         IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
 1234             "%s\n", __func__);
 1235 
 1236         IEEE80211_LOCK(vap->iv_ic);
 1237         ieee80211_start_locked(vap);
 1238         IEEE80211_UNLOCK(vap->iv_ic);
 1239 }
 1240 
 1241 /*
 1242  * Start all runnable vap's on a device.
 1243  */
 1244 void
 1245 ieee80211_start_all(struct ieee80211com *ic)
 1246 {
 1247         struct ieee80211vap *vap;
 1248 
 1249         IEEE80211_LOCK(ic);
 1250         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 1251                 struct ifnet *ifp = vap->iv_ifp;
 1252                 if (IFNET_IS_UP_RUNNING(ifp))   /* NB: avoid recursion */
 1253                         ieee80211_start_locked(vap);
 1254         }
 1255         IEEE80211_UNLOCK(ic);
 1256 }
 1257 
 1258 /*
 1259  * Stop a vap.  We force it down using the state machine
 1260  * then mark it's ifnet not running.  If this is the last
 1261  * vap running on the underlying device then we close it
 1262  * too to insure it will be properly initialized when the
 1263  * next vap is brought up.
 1264  */
 1265 void
 1266 ieee80211_stop_locked(struct ieee80211vap *vap)
 1267 {
 1268         struct ieee80211com *ic = vap->iv_ic;
 1269         struct ifnet *ifp = vap->iv_ifp;
 1270         struct ifnet *parent = ic->ic_ifp;
 1271 
 1272         IEEE80211_LOCK_ASSERT(ic);
 1273 
 1274         IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
 1275             "stop running, %d vaps running\n", ic->ic_nrunning);
 1276 
 1277         ieee80211_new_state_locked(vap, IEEE80211_S_INIT, -1);
 1278         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 1279                 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;  /* mark us stopped */
 1280                 if (--ic->ic_nrunning == 0 &&
 1281                     (parent->if_drv_flags & IFF_DRV_RUNNING)) {
 1282                         IEEE80211_DPRINTF(vap,
 1283                             IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
 1284                             "down parent %s\n", parent->if_xname);
 1285                         parent->if_flags &= ~IFF_UP;
 1286                         ieee80211_runtask(ic, &ic->ic_parent_task);
 1287                 }
 1288         }
 1289 }
 1290 
 1291 void
 1292 ieee80211_stop(struct ieee80211vap *vap)
 1293 {
 1294         struct ieee80211com *ic = vap->iv_ic;
 1295 
 1296         IEEE80211_LOCK(ic);
 1297         ieee80211_stop_locked(vap);
 1298         IEEE80211_UNLOCK(ic);
 1299 }
 1300 
 1301 /*
 1302  * Stop all vap's running on a device.
 1303  */
 1304 void
 1305 ieee80211_stop_all(struct ieee80211com *ic)
 1306 {
 1307         struct ieee80211vap *vap;
 1308 
 1309         IEEE80211_LOCK(ic);
 1310         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 1311                 struct ifnet *ifp = vap->iv_ifp;
 1312                 if (IFNET_IS_UP_RUNNING(ifp))   /* NB: avoid recursion */
 1313                         ieee80211_stop_locked(vap);
 1314         }
 1315         IEEE80211_UNLOCK(ic);
 1316 
 1317         ieee80211_waitfor_parent(ic);
 1318 }
 1319 
 1320 /*
 1321  * Stop all vap's running on a device and arrange
 1322  * for those that were running to be resumed.
 1323  */
 1324 void
 1325 ieee80211_suspend_all(struct ieee80211com *ic)
 1326 {
 1327         struct ieee80211vap *vap;
 1328 
 1329         IEEE80211_LOCK(ic);
 1330         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 1331                 struct ifnet *ifp = vap->iv_ifp;
 1332                 if (IFNET_IS_UP_RUNNING(ifp)) { /* NB: avoid recursion */
 1333                         vap->iv_flags_ext |= IEEE80211_FEXT_RESUME;
 1334                         ieee80211_stop_locked(vap);
 1335                 }
 1336         }
 1337         IEEE80211_UNLOCK(ic);
 1338 
 1339         ieee80211_waitfor_parent(ic);
 1340 }
 1341 
 1342 /*
 1343  * Start all vap's marked for resume.
 1344  */
 1345 void
 1346 ieee80211_resume_all(struct ieee80211com *ic)
 1347 {
 1348         struct ieee80211vap *vap;
 1349 
 1350         IEEE80211_LOCK(ic);
 1351         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 1352                 struct ifnet *ifp = vap->iv_ifp;
 1353                 if (!IFNET_IS_UP_RUNNING(ifp) &&
 1354                     (vap->iv_flags_ext & IEEE80211_FEXT_RESUME)) {
 1355                         vap->iv_flags_ext &= ~IEEE80211_FEXT_RESUME;
 1356                         ieee80211_start_locked(vap);
 1357                 }
 1358         }
 1359         IEEE80211_UNLOCK(ic);
 1360 }
 1361 
 1362 void
 1363 ieee80211_beacon_miss(struct ieee80211com *ic)
 1364 {
 1365         IEEE80211_LOCK(ic);
 1366         if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
 1367                 /* Process in a taskq, the handler may reenter the driver */
 1368                 ieee80211_runtask(ic, &ic->ic_bmiss_task);
 1369         }
 1370         IEEE80211_UNLOCK(ic);
 1371 }
 1372 
 1373 static void
 1374 beacon_miss(void *arg, int npending)
 1375 {
 1376         struct ieee80211com *ic = arg;
 1377         struct ieee80211vap *vap;
 1378 
 1379         /* XXX locking */
 1380         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 1381                 /*
 1382                  * We only pass events through for sta vap's in RUN state;
 1383                  * may be too restrictive but for now this saves all the
 1384                  * handlers duplicating these checks.
 1385                  */
 1386                 if (vap->iv_opmode == IEEE80211_M_STA &&
 1387                     vap->iv_state >= IEEE80211_S_RUN &&
 1388                     vap->iv_bmiss != NULL)
 1389                         vap->iv_bmiss(vap);
 1390         }
 1391 }
 1392 
 1393 static void
 1394 beacon_swmiss(void *arg, int npending)
 1395 {
 1396         struct ieee80211vap *vap = arg;
 1397 
 1398         if (vap->iv_state != IEEE80211_S_RUN)
 1399                 return;
 1400 
 1401         /* XXX Call multiple times if npending > zero? */
 1402         vap->iv_bmiss(vap);
 1403 }
 1404 
 1405 /*
 1406  * Software beacon miss handling.  Check if any beacons
 1407  * were received in the last period.  If not post a
 1408  * beacon miss; otherwise reset the counter.
 1409  */
 1410 void
 1411 ieee80211_swbmiss(void *arg)
 1412 {
 1413         struct ieee80211vap *vap = arg;
 1414         struct ieee80211com *ic = vap->iv_ic;
 1415 
 1416         /* XXX sleep state? */
 1417         KASSERT(vap->iv_state == IEEE80211_S_RUN,
 1418             ("wrong state %d", vap->iv_state));
 1419 
 1420         if (ic->ic_flags & IEEE80211_F_SCAN) {
 1421                 /*
 1422                  * If scanning just ignore and reset state.  If we get a
 1423                  * bmiss after coming out of scan because we haven't had
 1424                  * time to receive a beacon then we should probe the AP
 1425                  * before posting a real bmiss (unless iv_bmiss_max has
 1426                  * been artifiically lowered).  A cleaner solution might
 1427                  * be to disable the timer on scan start/end but to handle
 1428                  * case of multiple sta vap's we'd need to disable the
 1429                  * timers of all affected vap's.
 1430                  */
 1431                 vap->iv_swbmiss_count = 0;
 1432         } else if (vap->iv_swbmiss_count == 0) {
 1433                 if (vap->iv_bmiss != NULL)
 1434                         ieee80211_runtask(ic, &vap->iv_swbmiss_task);
 1435         } else
 1436                 vap->iv_swbmiss_count = 0;
 1437         callout_reset(&vap->iv_swbmiss, vap->iv_swbmiss_period,
 1438                 ieee80211_swbmiss, vap);
 1439 }
 1440 
 1441 /*
 1442  * Start an 802.11h channel switch.  We record the parameters,
 1443  * mark the operation pending, notify each vap through the
 1444  * beacon update mechanism so it can update the beacon frame
 1445  * contents, and then switch vap's to CSA state to block outbound
 1446  * traffic.  Devices that handle CSA directly can use the state
 1447  * switch to do the right thing so long as they call
 1448  * ieee80211_csa_completeswitch when it's time to complete the
 1449  * channel change.  Devices that depend on the net80211 layer can
 1450  * use ieee80211_beacon_update to handle the countdown and the
 1451  * channel switch.
 1452  */
 1453 void
 1454 ieee80211_csa_startswitch(struct ieee80211com *ic,
 1455         struct ieee80211_channel *c, int mode, int count)
 1456 {
 1457         struct ieee80211vap *vap;
 1458 
 1459         IEEE80211_LOCK_ASSERT(ic);
 1460 
 1461         ic->ic_csa_newchan = c;
 1462         ic->ic_csa_mode = mode;
 1463         ic->ic_csa_count = count;
 1464         ic->ic_flags |= IEEE80211_F_CSAPENDING;
 1465         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 1466                 if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
 1467                     vap->iv_opmode == IEEE80211_M_IBSS ||
 1468                     vap->iv_opmode == IEEE80211_M_MBSS)
 1469                         ieee80211_beacon_notify(vap, IEEE80211_BEACON_CSA);
 1470                 /* switch to CSA state to block outbound traffic */
 1471                 if (vap->iv_state == IEEE80211_S_RUN)
 1472                         ieee80211_new_state_locked(vap, IEEE80211_S_CSA, 0);
 1473         }
 1474         ieee80211_notify_csa(ic, c, mode, count);
 1475 }
 1476 
 1477 static void
 1478 csa_completeswitch(struct ieee80211com *ic)
 1479 {
 1480         struct ieee80211vap *vap;
 1481 
 1482         ic->ic_csa_newchan = NULL;
 1483         ic->ic_flags &= ~IEEE80211_F_CSAPENDING;
 1484 
 1485         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
 1486                 if (vap->iv_state == IEEE80211_S_CSA)
 1487                         ieee80211_new_state_locked(vap, IEEE80211_S_RUN, 0);
 1488 }
 1489 
 1490 /*
 1491  * Complete an 802.11h channel switch started by ieee80211_csa_startswitch.
 1492  * We clear state and move all vap's in CSA state to RUN state
 1493  * so they can again transmit.
 1494  */
 1495 void
 1496 ieee80211_csa_completeswitch(struct ieee80211com *ic)
 1497 {
 1498         IEEE80211_LOCK_ASSERT(ic);
 1499 
 1500         KASSERT(ic->ic_flags & IEEE80211_F_CSAPENDING, ("csa not pending"));
 1501 
 1502         ieee80211_setcurchan(ic, ic->ic_csa_newchan);
 1503         csa_completeswitch(ic);
 1504 }
 1505 
 1506 /*
 1507  * Cancel an 802.11h channel switch started by ieee80211_csa_startswitch.
 1508  * We clear state and move all vap's in CSA state to RUN state
 1509  * so they can again transmit.
 1510  */
 1511 void
 1512 ieee80211_csa_cancelswitch(struct ieee80211com *ic)
 1513 {
 1514         IEEE80211_LOCK_ASSERT(ic);
 1515 
 1516         csa_completeswitch(ic);
 1517 }
 1518 
 1519 /*
 1520  * Complete a DFS CAC started by ieee80211_dfs_cac_start.
 1521  * We clear state and move all vap's in CAC state to RUN state.
 1522  */
 1523 void
 1524 ieee80211_cac_completeswitch(struct ieee80211vap *vap0)
 1525 {
 1526         struct ieee80211com *ic = vap0->iv_ic;
 1527         struct ieee80211vap *vap;
 1528 
 1529         IEEE80211_LOCK(ic);
 1530         /*
 1531          * Complete CAC state change for lead vap first; then
 1532          * clock all the other vap's waiting.
 1533          */
 1534         KASSERT(vap0->iv_state == IEEE80211_S_CAC,
 1535             ("wrong state %d", vap0->iv_state));
 1536         ieee80211_new_state_locked(vap0, IEEE80211_S_RUN, 0);
 1537 
 1538         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
 1539                 if (vap->iv_state == IEEE80211_S_CAC)
 1540                         ieee80211_new_state_locked(vap, IEEE80211_S_RUN, 0);
 1541         IEEE80211_UNLOCK(ic);
 1542 }
 1543 
 1544 /*
 1545  * Force all vap's other than the specified vap to the INIT state
 1546  * and mark them as waiting for a scan to complete.  These vaps
 1547  * will be brought up when the scan completes and the scanning vap
 1548  * reaches RUN state by wakeupwaiting.
 1549  */
 1550 static void
 1551 markwaiting(struct ieee80211vap *vap0)
 1552 {
 1553         struct ieee80211com *ic = vap0->iv_ic;
 1554         struct ieee80211vap *vap;
 1555 
 1556         IEEE80211_LOCK_ASSERT(ic);
 1557 
 1558         /*
 1559          * A vap list entry can not disappear since we are running on the
 1560          * taskqueue and a vap destroy will queue and drain another state
 1561          * change task.
 1562          */
 1563         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 1564                 if (vap == vap0)
 1565                         continue;
 1566                 if (vap->iv_state != IEEE80211_S_INIT) {
 1567                         /* NB: iv_newstate may drop the lock */
 1568                         vap->iv_newstate(vap, IEEE80211_S_INIT, 0);
 1569                         vap->iv_flags_ext |= IEEE80211_FEXT_SCANWAIT;
 1570                 }
 1571         }
 1572 }
 1573 
 1574 /*
 1575  * Wakeup all vap's waiting for a scan to complete.  This is the
 1576  * companion to markwaiting (above) and is used to coordinate
 1577  * multiple vaps scanning.
 1578  * This is called from the state taskqueue.
 1579  */
 1580 static void
 1581 wakeupwaiting(struct ieee80211vap *vap0)
 1582 {
 1583         struct ieee80211com *ic = vap0->iv_ic;
 1584         struct ieee80211vap *vap;
 1585 
 1586         IEEE80211_LOCK_ASSERT(ic);
 1587 
 1588         /*
 1589          * A vap list entry can not disappear since we are running on the
 1590          * taskqueue and a vap destroy will queue and drain another state
 1591          * change task.
 1592          */
 1593         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 1594                 if (vap == vap0)
 1595                         continue;
 1596                 if (vap->iv_flags_ext & IEEE80211_FEXT_SCANWAIT) {
 1597                         vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANWAIT;
 1598                         /* NB: sta's cannot go INIT->RUN */
 1599                         /* NB: iv_newstate may drop the lock */
 1600                         vap->iv_newstate(vap,
 1601                             vap->iv_opmode == IEEE80211_M_STA ?
 1602                                 IEEE80211_S_SCAN : IEEE80211_S_RUN, 0);
 1603                 }
 1604         }
 1605 }
 1606 
 1607 /*
 1608  * Handle post state change work common to all operating modes.
 1609  */
 1610 static void
 1611 ieee80211_newstate_cb(void *xvap, int npending)
 1612 {
 1613         struct ieee80211vap *vap = xvap;
 1614         struct ieee80211com *ic = vap->iv_ic;
 1615         enum ieee80211_state nstate, ostate;
 1616         int arg, rc;
 1617 
 1618         IEEE80211_LOCK(ic);
 1619         nstate = vap->iv_nstate;
 1620         arg = vap->iv_nstate_arg;
 1621 
 1622         if (vap->iv_flags_ext & IEEE80211_FEXT_REINIT) {
 1623                 /*
 1624                  * We have been requested to drop back to the INIT before
 1625                  * proceeding to the new state.
 1626                  */
 1627                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
 1628                     "%s: %s -> %s arg %d\n", __func__,
 1629                     ieee80211_state_name[vap->iv_state],
 1630                     ieee80211_state_name[IEEE80211_S_INIT], arg);
 1631                 vap->iv_newstate(vap, IEEE80211_S_INIT, arg);
 1632                 vap->iv_flags_ext &= ~IEEE80211_FEXT_REINIT;
 1633         }
 1634 
 1635         ostate = vap->iv_state;
 1636         if (nstate == IEEE80211_S_SCAN && ostate != IEEE80211_S_INIT) {
 1637                 /*
 1638                  * SCAN was forced; e.g. on beacon miss.  Force other running
 1639                  * vap's to INIT state and mark them as waiting for the scan to
 1640                  * complete.  This insures they don't interfere with our
 1641                  * scanning.  Since we are single threaded the vaps can not
 1642                  * transition again while we are executing.
 1643                  *
 1644                  * XXX not always right, assumes ap follows sta
 1645                  */
 1646                 markwaiting(vap);
 1647         }
 1648         IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
 1649             "%s: %s -> %s arg %d\n", __func__,
 1650             ieee80211_state_name[ostate], ieee80211_state_name[nstate], arg);
 1651 
 1652         rc = vap->iv_newstate(vap, nstate, arg);
 1653         vap->iv_flags_ext &= ~IEEE80211_FEXT_STATEWAIT;
 1654         if (rc != 0) {
 1655                 /* State transition failed */
 1656                 KASSERT(rc != EINPROGRESS, ("iv_newstate was deferred"));
 1657                 KASSERT(nstate != IEEE80211_S_INIT,
 1658                     ("INIT state change failed"));
 1659                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
 1660                     "%s: %s returned error %d\n", __func__,
 1661                     ieee80211_state_name[nstate], rc);
 1662                 goto done;
 1663         }
 1664 
 1665         /* No actual transition, skip post processing */
 1666         if (ostate == nstate)
 1667                 goto done;
 1668 
 1669         if (nstate == IEEE80211_S_RUN) {
 1670                 /*
 1671                  * OACTIVE may be set on the vap if the upper layer
 1672                  * tried to transmit (e.g. IPv6 NDP) before we reach
 1673                  * RUN state.  Clear it and restart xmit.
 1674                  *
 1675                  * Note this can also happen as a result of SLEEP->RUN
 1676                  * (i.e. coming out of power save mode).
 1677                  */
 1678                 vap->iv_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 1679                 if_start(vap->iv_ifp);
 1680 
 1681                 /* bring up any vaps waiting on us */
 1682                 wakeupwaiting(vap);
 1683         } else if (nstate == IEEE80211_S_INIT) {
 1684                 /*
 1685                  * Flush the scan cache if we did the last scan (XXX?)
 1686                  * and flush any frames on send queues from this vap.
 1687                  * Note the mgt q is used only for legacy drivers and
 1688                  * will go away shortly.
 1689                  */
 1690                 ieee80211_scan_flush(vap);
 1691 
 1692                 /* XXX NB: cast for altq */
 1693                 ieee80211_flush_ifq((struct ifqueue *)&ic->ic_ifp->if_snd, vap);
 1694         }
 1695 done:
 1696         IEEE80211_UNLOCK(ic);
 1697 }
 1698 
 1699 /*
 1700  * Public interface for initiating a state machine change.
 1701  * This routine single-threads the request and coordinates
 1702  * the scheduling of multiple vaps for the purpose of selecting
 1703  * an operating channel.  Specifically the following scenarios
 1704  * are handled:
 1705  * o only one vap can be selecting a channel so on transition to
 1706  *   SCAN state if another vap is already scanning then
 1707  *   mark the caller for later processing and return without
 1708  *   doing anything (XXX? expectations by caller of synchronous operation)
 1709  * o only one vap can be doing CAC of a channel so on transition to
 1710  *   CAC state if another vap is already scanning for radar then
 1711  *   mark the caller for later processing and return without
 1712  *   doing anything (XXX? expectations by caller of synchronous operation)
 1713  * o if another vap is already running when a request is made
 1714  *   to SCAN then an operating channel has been chosen; bypass
 1715  *   the scan and just join the channel
 1716  *
 1717  * Note that the state change call is done through the iv_newstate
 1718  * method pointer so any driver routine gets invoked.  The driver
 1719  * will normally call back into operating mode-specific
 1720  * ieee80211_newstate routines (below) unless it needs to completely
 1721  * bypass the state machine (e.g. because the firmware has it's
 1722  * own idea how things should work).  Bypassing the net80211 layer
 1723  * is usually a mistake and indicates lack of proper integration
 1724  * with the net80211 layer.
 1725  */
 1726 static int
 1727 ieee80211_new_state_locked(struct ieee80211vap *vap,
 1728         enum ieee80211_state nstate, int arg)
 1729 {
 1730         struct ieee80211com *ic = vap->iv_ic;
 1731         struct ieee80211vap *vp;
 1732         enum ieee80211_state ostate;
 1733         int nrunning, nscanning;
 1734 
 1735         IEEE80211_LOCK_ASSERT(ic);
 1736 
 1737         if (vap->iv_flags_ext & IEEE80211_FEXT_STATEWAIT) {
 1738                 if (vap->iv_nstate == IEEE80211_S_INIT) {
 1739                         /*
 1740                          * XXX The vap is being stopped, do no allow any other
 1741                          * state changes until this is completed.
 1742                          */
 1743                         return -1;
 1744                 } else if (vap->iv_state != vap->iv_nstate) {
 1745 #if 0
 1746                         /* Warn if the previous state hasn't completed. */
 1747                         IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
 1748                             "%s: pending %s -> %s transition lost\n", __func__,
 1749                             ieee80211_state_name[vap->iv_state],
 1750                             ieee80211_state_name[vap->iv_nstate]);
 1751 #else
 1752                         /* XXX temporarily enable to identify issues */
 1753                         if_printf(vap->iv_ifp,
 1754                             "%s: pending %s -> %s transition lost\n",
 1755                             __func__, ieee80211_state_name[vap->iv_state],
 1756                             ieee80211_state_name[vap->iv_nstate]);
 1757 #endif
 1758                 }
 1759         }
 1760 
 1761         nrunning = nscanning = 0;
 1762         /* XXX can track this state instead of calculating */
 1763         TAILQ_FOREACH(vp, &ic->ic_vaps, iv_next) {
 1764                 if (vp != vap) {
 1765                         if (vp->iv_state >= IEEE80211_S_RUN)
 1766                                 nrunning++;
 1767                         /* XXX doesn't handle bg scan */
 1768                         /* NB: CAC+AUTH+ASSOC treated like SCAN */
 1769                         else if (vp->iv_state > IEEE80211_S_INIT)
 1770                                 nscanning++;
 1771                 }
 1772         }
 1773         ostate = vap->iv_state;
 1774         IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
 1775             "%s: %s -> %s (nrunning %d nscanning %d)\n", __func__,
 1776             ieee80211_state_name[ostate], ieee80211_state_name[nstate],
 1777             nrunning, nscanning);
 1778         switch (nstate) {
 1779         case IEEE80211_S_SCAN:
 1780                 if (ostate == IEEE80211_S_INIT) {
 1781                         /*
 1782                          * INIT -> SCAN happens on initial bringup.
 1783                          */
 1784                         KASSERT(!(nscanning && nrunning),
 1785                             ("%d scanning and %d running", nscanning, nrunning));
 1786                         if (nscanning) {
 1787                                 /*
 1788                                  * Someone is scanning, defer our state
 1789                                  * change until the work has completed.
 1790                                  */
 1791                                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
 1792                                     "%s: defer %s -> %s\n",
 1793                                     __func__, ieee80211_state_name[ostate],
 1794                                     ieee80211_state_name[nstate]);
 1795                                 vap->iv_flags_ext |= IEEE80211_FEXT_SCANWAIT;
 1796                                 return 0;
 1797                         }
 1798                         if (nrunning) {
 1799                                 /*
 1800                                  * Someone is operating; just join the channel
 1801                                  * they have chosen.
 1802                                  */
 1803                                 /* XXX kill arg? */
 1804                                 /* XXX check each opmode, adhoc? */
 1805                                 if (vap->iv_opmode == IEEE80211_M_STA)
 1806                                         nstate = IEEE80211_S_SCAN;
 1807                                 else
 1808                                         nstate = IEEE80211_S_RUN;
 1809 #ifdef IEEE80211_DEBUG
 1810                                 if (nstate != IEEE80211_S_SCAN) {
 1811                                         IEEE80211_DPRINTF(vap,
 1812                                             IEEE80211_MSG_STATE,
 1813                                             "%s: override, now %s -> %s\n",
 1814                                             __func__,
 1815                                             ieee80211_state_name[ostate],
 1816                                             ieee80211_state_name[nstate]);
 1817                                 }
 1818 #endif
 1819                         }
 1820                 }
 1821                 break;
 1822         case IEEE80211_S_RUN:
 1823                 if (vap->iv_opmode == IEEE80211_M_WDS &&
 1824                     (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY) &&
 1825                     nscanning) {
 1826                         /*
 1827                          * Legacy WDS with someone else scanning; don't
 1828                          * go online until that completes as we should
 1829                          * follow the other vap to the channel they choose.
 1830                          */
 1831                         IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
 1832                              "%s: defer %s -> %s (legacy WDS)\n", __func__,
 1833                              ieee80211_state_name[ostate],
 1834                              ieee80211_state_name[nstate]);
 1835                         vap->iv_flags_ext |= IEEE80211_FEXT_SCANWAIT;
 1836                         return 0;
 1837                 }
 1838                 if (vap->iv_opmode == IEEE80211_M_HOSTAP &&
 1839                     IEEE80211_IS_CHAN_DFS(ic->ic_bsschan) &&
 1840                     (vap->iv_flags_ext & IEEE80211_FEXT_DFS) &&
 1841                     !IEEE80211_IS_CHAN_CACDONE(ic->ic_bsschan)) {
 1842                         /*
 1843                          * This is a DFS channel, transition to CAC state
 1844                          * instead of RUN.  This allows us to initiate
 1845                          * Channel Availability Check (CAC) as specified
 1846                          * by 11h/DFS.
 1847                          */
 1848                         nstate = IEEE80211_S_CAC;
 1849                         IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
 1850                              "%s: override %s -> %s (DFS)\n", __func__,
 1851                              ieee80211_state_name[ostate],
 1852                              ieee80211_state_name[nstate]);
 1853                 }
 1854                 break;
 1855         case IEEE80211_S_INIT:
 1856                 /* cancel any scan in progress */
 1857                 ieee80211_cancel_scan(vap);
 1858                 if (ostate == IEEE80211_S_INIT ) {
 1859                         /* XXX don't believe this */
 1860                         /* INIT -> INIT. nothing to do */
 1861                         vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANWAIT;
 1862                 }
 1863                 /* fall thru... */
 1864         default:
 1865                 break;
 1866         }
 1867         /* defer the state change to a thread */
 1868         vap->iv_nstate = nstate;
 1869         vap->iv_nstate_arg = arg;
 1870         vap->iv_flags_ext |= IEEE80211_FEXT_STATEWAIT;
 1871         ieee80211_runtask(ic, &vap->iv_nstate_task);
 1872         return EINPROGRESS;
 1873 }
 1874 
 1875 int
 1876 ieee80211_new_state(struct ieee80211vap *vap,
 1877         enum ieee80211_state nstate, int arg)
 1878 {
 1879         struct ieee80211com *ic = vap->iv_ic;
 1880         int rc;
 1881 
 1882         IEEE80211_LOCK(ic);
 1883         rc = ieee80211_new_state_locked(vap, nstate, arg);
 1884         IEEE80211_UNLOCK(ic);
 1885         return rc;
 1886 }

Cache object: 533ec5e37109ff8267cde9e35718c73a


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