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

Cache object: 08c75842a614a916767c7cbf3a62b1c6


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