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 /*      $NetBSD: ieee80211_proto.c,v 1.18 2005/02/26 22:45:09 perry Exp $       */
    2 /*-
    3  * Copyright (c) 2001 Atsushi Onoe
    4  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
    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  * 3. The name of the author may not be used to endorse or promote products
   16  *    derived from this software without specific prior written permission.
   17  *
   18  * Alternatively, this software may be distributed under the terms of the
   19  * GNU General Public License ("GPL") version 2 as published by the Free
   20  * Software Foundation.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 #ifdef __FreeBSD__
   36 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_proto.c,v 1.8 2004/04/02 20:22:25 sam Exp $");
   37 #else
   38 __KERNEL_RCSID(0, "$NetBSD: ieee80211_proto.c,v 1.18 2005/02/26 22:45:09 perry Exp $");
   39 #endif
   40 
   41 /*
   42  * IEEE 802.11 protocol support.
   43  */
   44 
   45 #include "opt_inet.h"
   46 
   47 #include <sys/param.h>
   48 #include <sys/systm.h>
   49 #include <sys/mbuf.h>
   50 #include <sys/malloc.h>
   51 #include <sys/kernel.h>
   52 #include <sys/socket.h>
   53 #include <sys/sockio.h>
   54 #include <sys/endian.h>
   55 #include <sys/errno.h>
   56 #ifdef __FreeBSD__
   57 #include <sys/bus.h>
   58 #endif
   59 #include <sys/proc.h>
   60 #include <sys/sysctl.h>
   61 
   62 #ifdef __FreeBSD__
   63 #include <machine/atomic.h>
   64 #endif
   65 
   66 #include <net/if.h>
   67 #include <net/if_dl.h>
   68 #include <net/if_media.h>
   69 #include <net/if_arp.h>
   70 #ifdef __FreeBSD__
   71 #include <net/ethernet.h>
   72 #else
   73 #include <net/if_ether.h>
   74 #endif
   75 #include <net/if_llc.h>
   76 
   77 #include <net80211/ieee80211_var.h>
   78 #include <net80211/ieee80211_compat.h>
   79 
   80 #include <net/bpf.h>
   81 
   82 #ifdef INET
   83 #include <netinet/in.h>
   84 #ifdef __FreeBSD__
   85 #include <netinet/if_ether.h>
   86 #else
   87 #include <net/if_ether.h>
   88 #endif
   89 #endif
   90 
   91 #include <net/route.h>
   92 
   93 #define IEEE80211_RATE2MBS(r)   (((r) & IEEE80211_RATE_VAL) / 2)
   94 
   95 const char *ieee80211_mgt_subtype_name[] = {
   96         "assoc_req",    "assoc_resp",   "reassoc_req",  "reassoc_resp",
   97         "probe_req",    "probe_resp",   "reserved#6",   "reserved#7",
   98         "beacon",       "atim",         "disassoc",     "auth",
   99         "deauth",       "reserved#13",  "reserved#14",  "reserved#15"
  100 };
  101 const char *ieee80211_state_name[IEEE80211_S_MAX] = {
  102         "INIT",         /* IEEE80211_S_INIT */
  103         "SCAN",         /* IEEE80211_S_SCAN */
  104         "AUTH",         /* IEEE80211_S_AUTH */
  105         "ASSOC",        /* IEEE80211_S_ASSOC */
  106         "RUN"           /* IEEE80211_S_RUN */
  107 };
  108 
  109 static int ieee80211_newstate(struct ieee80211com *, enum ieee80211_state, int);
  110 
  111 void
  112 ieee80211_proto_attach(struct ifnet *ifp)
  113 {
  114         struct ieee80211com *ic = (void *)ifp;
  115 
  116         ifp->if_hdrlen = sizeof(struct ieee80211_frame);
  117 
  118 #ifdef notdef
  119         ic->ic_rtsthreshold = IEEE80211_RTS_DEFAULT;
  120 #else
  121         ic->ic_rtsthreshold = IEEE80211_RTS_MAX;
  122 #endif
  123         ic->ic_fragthreshold = 2346;            /* XXX not used yet */
  124         ic->ic_fixed_rate = -1;                 /* no fixed rate */
  125         ic->ic_protmode = IEEE80211_PROT_CTSONLY;
  126 
  127 #ifdef __FreeBSD__
  128         mtx_init(&ic->ic_mgtq.ifq_mtx, ifp->if_xname, "mgmt send q", MTX_DEF);
  129 #endif
  130 
  131         /* protocol state change handler */
  132         ic->ic_newstate = ieee80211_newstate;
  133 
  134         /* initialize management frame handlers */
  135         ic->ic_recv_mgmt = ieee80211_recv_mgmt;
  136         ic->ic_send_mgmt = ieee80211_send_mgmt;
  137 }
  138 
  139 void
  140 ieee80211_proto_detach(struct ifnet *ifp)
  141 {
  142         struct ieee80211com *ic = (void *)ifp;
  143 
  144 #ifdef __FreeBSD__
  145         IF_DRAIN(&ic->ic_mgtq);
  146         mtx_destroy(&ic->ic_mgtq.ifq_mtx);
  147 #else
  148         IF_PURGE(&ic->ic_mgtq);
  149         IF_PURGE(&ic->ic_pwrsaveq);
  150 #endif
  151 }
  152 
  153 void
  154 ieee80211_print_essid(u_int8_t *essid, int len)
  155 {
  156         int i;
  157         u_int8_t *p;
  158 
  159         if (len > IEEE80211_NWID_LEN)
  160                 len = IEEE80211_NWID_LEN;
  161         /* determine printable or not */
  162         for (i = 0, p = essid; i < len; i++, p++) {
  163                 if (*p < ' ' || *p > 0x7e)
  164                         break;
  165         }
  166         if (i == len) {
  167                 printf("\"");
  168                 for (i = 0, p = essid; i < len; i++, p++)
  169                         printf("%c", *p);
  170                 printf("\"");
  171         } else {
  172                 printf("0x");
  173                 for (i = 0, p = essid; i < len; i++, p++)
  174                         printf("%02x", *p);
  175         }
  176 }
  177 
  178 void
  179 ieee80211_dump_pkt(u_int8_t *buf, int len, int rate, int rssi)
  180 {
  181         struct ieee80211_frame *wh;
  182         int i;
  183 
  184         wh = (struct ieee80211_frame *)buf;
  185         switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
  186         case IEEE80211_FC1_DIR_NODS:
  187                 printf("NODS %s", ether_sprintf(wh->i_addr2));
  188                 printf("->%s", ether_sprintf(wh->i_addr1));
  189                 printf("(%s)", ether_sprintf(wh->i_addr3));
  190                 break;
  191         case IEEE80211_FC1_DIR_TODS:
  192                 printf("TODS %s", ether_sprintf(wh->i_addr2));
  193                 printf("->%s", ether_sprintf(wh->i_addr3));
  194                 printf("(%s)", ether_sprintf(wh->i_addr1));
  195                 break;
  196         case IEEE80211_FC1_DIR_FROMDS:
  197                 printf("FRDS %s", ether_sprintf(wh->i_addr3));
  198                 printf("->%s", ether_sprintf(wh->i_addr1));
  199                 printf("(%s)", ether_sprintf(wh->i_addr2));
  200                 break;
  201         case IEEE80211_FC1_DIR_DSTODS:
  202                 printf("DSDS %s", ether_sprintf((u_int8_t *)&wh[1]));
  203                 printf("->%s", ether_sprintf(wh->i_addr3));
  204                 printf("(%s", ether_sprintf(wh->i_addr2));
  205                 printf("->%s)", ether_sprintf(wh->i_addr1));
  206                 break;
  207         }
  208         switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
  209         case IEEE80211_FC0_TYPE_DATA:
  210                 printf(" data");
  211                 break;
  212         case IEEE80211_FC0_TYPE_MGT:
  213                 printf(" %s", ieee80211_mgt_subtype_name[
  214                     (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK)
  215                     >> IEEE80211_FC0_SUBTYPE_SHIFT]);
  216                 break;
  217         default:
  218                 printf(" type#%d", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK);
  219                 break;
  220         }
  221         if (wh->i_fc[1] & IEEE80211_FC1_WEP)
  222                 printf(" WEP");
  223         if (rate >= 0)
  224                 printf(" %dM", rate / 2);
  225         if (rssi >= 0)
  226                 printf(" +%d", rssi);
  227         printf("\n");
  228         if (len > 0) {
  229                 for (i = 0; i < len; i++) {
  230                         if ((i & 1) == 0)
  231                                 printf(" ");
  232                         printf("%02x", buf[i]);
  233                 }
  234                 printf("\n");
  235         }
  236 }
  237 
  238 int
  239 ieee80211_fix_rate(struct ieee80211com *ic, struct ieee80211_node *ni, int flags)
  240 {
  241 #define RV(v)   ((v) & IEEE80211_RATE_VAL)
  242         int i, j, ignore, error;
  243         int okrate, badrate;
  244         struct ieee80211_rateset *srs, *nrs;
  245         u_int8_t r;
  246 
  247         error = 0;
  248         okrate = badrate = 0;
  249         srs = &ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
  250         nrs = &ni->ni_rates;
  251         for (i = 0; i < nrs->rs_nrates; ) {
  252                 ignore = 0;
  253                 if (flags & IEEE80211_F_DOSORT) {
  254                         /*
  255                          * Sort rates.
  256                          */
  257                         for (j = i + 1; j < nrs->rs_nrates; j++) {
  258                                 if (RV(nrs->rs_rates[i]) > RV(nrs->rs_rates[j])) {
  259                                         r = nrs->rs_rates[i];
  260                                         nrs->rs_rates[i] = nrs->rs_rates[j];
  261                                         nrs->rs_rates[j] = r;
  262                                 }
  263                         }
  264                 }
  265                 r = nrs->rs_rates[i] & IEEE80211_RATE_VAL;
  266                 badrate = r;
  267                 if (flags & IEEE80211_F_DOFRATE) {
  268                         /*
  269                          * Apply fixed rate constraint.  Note that we do
  270                          * not apply the constraint to basic rates as
  271                          * otherwise we may not be able to associate if
  272                          * the rate set we submit to the AP is invalid
  273                          * (e.g. fix rate at 36Mb/s which is not a basic
  274                          * rate for 11a operation).
  275                          */
  276                         if ((nrs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0 &&
  277                             ic->ic_fixed_rate >= 0 &&
  278                             r != RV(srs->rs_rates[ic->ic_fixed_rate]))
  279                                 ignore++;
  280                 }
  281                 if (flags & IEEE80211_F_DONEGO) {
  282                         /*
  283                          * Check against supported rates.
  284                          */
  285                         for (j = 0; j < srs->rs_nrates; j++) {
  286                                 if (r == RV(srs->rs_rates[j])) {
  287                                         /*
  288                                          * Overwrite with the supported rate
  289                                          * value so any basic rate bit is set.
  290                                          * This insures that response we send
  291                                          * to stations have the necessary basic
  292                                          * rate bit set.
  293                                          */
  294                                         nrs->rs_rates[i] = srs->rs_rates[j];
  295                                         break;
  296                                 }
  297                         }
  298                         if (j == srs->rs_nrates) {
  299                                 /*
  300                                  * A rate in the node's rate set is not
  301                                  * supported.  If this is a basic rate and we
  302                                  * are operating as an AP then this is an error.
  303                                  * Otherwise we just discard/ignore the rate.
  304                                  * Note that this is important for 11b stations
  305                                  * when they want to associate with an 11g AP.
  306                                  */
  307                                 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
  308                                     (nrs->rs_rates[i] & IEEE80211_RATE_BASIC))
  309                                         error++;
  310                                 ignore++;
  311                         }
  312                 }
  313                 if (flags & IEEE80211_F_DODEL) {
  314                         /*
  315                          * Delete unacceptable rates.
  316                          */
  317                         if (ignore) {
  318                                 nrs->rs_nrates--;
  319                                 for (j = i; j < nrs->rs_nrates; j++)
  320                                         nrs->rs_rates[j] = nrs->rs_rates[j + 1];
  321                                 nrs->rs_rates[j] = 0;
  322                                 continue;
  323                         }
  324                 }
  325                 if (!ignore) {
  326                         okrate = nrs->rs_rates[i];
  327                         ni->ni_txrate = i;
  328                 }
  329                 i++;
  330         }
  331         if (okrate == 0 || error != 0)
  332                 return badrate | IEEE80211_RATE_BASIC;
  333         else
  334                 return RV(okrate);
  335 #undef RV
  336 }
  337 
  338 static int
  339 ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int mgt)
  340 {
  341         struct ifnet *ifp = &ic->ic_if;
  342         struct ieee80211_node *ni;
  343         enum ieee80211_state ostate;
  344         ieee80211_node_critsec_decl(s);
  345         int linkstate = LINK_STATE_DOWN;
  346 
  347         ostate = ic->ic_state;
  348         IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE, ("%s: %s -> %s\n", __func__,
  349                 ieee80211_state_name[ostate], ieee80211_state_name[nstate]));
  350         ic->ic_state = nstate;                  /* state transition */
  351         ni = ic->ic_bss;                        /* NB: no reference held */
  352         switch (nstate) {
  353         case IEEE80211_S_INIT:
  354                 switch (ostate) {
  355                 case IEEE80211_S_INIT:
  356                         break;
  357                 case IEEE80211_S_RUN:
  358                         switch (ic->ic_opmode) {
  359                         case IEEE80211_M_STA:
  360                                 IEEE80211_SEND_MGMT(ic, ni,
  361                                     IEEE80211_FC0_SUBTYPE_DISASSOC,
  362                                     IEEE80211_REASON_ASSOC_LEAVE);
  363                                 break;
  364                         case IEEE80211_M_HOSTAP:
  365                                 ieee80211_node_critsec_begin(ic, s);
  366                                 TAILQ_FOREACH(ni, &ic->ic_node, ni_list) {
  367                                         if (ni->ni_associd == 0)
  368                                                 continue;
  369                                         IEEE80211_SEND_MGMT(ic, ni,
  370                                             IEEE80211_FC0_SUBTYPE_DISASSOC,
  371                                             IEEE80211_REASON_ASSOC_LEAVE);
  372                                 }
  373                                 ieee80211_node_critsec_end(ic, s);
  374                                 break;
  375                         default:
  376                                 break;
  377                         }
  378                         /* FALLTHRU */
  379                 case IEEE80211_S_ASSOC:
  380                         switch (ic->ic_opmode) {
  381                         case IEEE80211_M_STA:
  382                                 IEEE80211_SEND_MGMT(ic, ni,
  383                                     IEEE80211_FC0_SUBTYPE_DEAUTH,
  384                                     IEEE80211_REASON_AUTH_LEAVE);
  385                                 break;
  386                         case IEEE80211_M_HOSTAP:
  387                                 ieee80211_node_critsec_begin(ic, s);
  388                                 TAILQ_FOREACH(ni, &ic->ic_node, ni_list) {
  389                                         IEEE80211_SEND_MGMT(ic, ni,
  390                                             IEEE80211_FC0_SUBTYPE_DEAUTH,
  391                                             IEEE80211_REASON_AUTH_LEAVE);
  392                                 }
  393                                 ieee80211_node_critsec_end(ic, s);
  394                                 break;
  395                         default:
  396                                 break;
  397                         }
  398                         /* FALLTHRU */
  399                 case IEEE80211_S_AUTH:
  400                 case IEEE80211_S_SCAN:
  401                         ic->ic_mgt_timer = 0;
  402 #ifdef __FreeBSD__
  403                         IF_DRAIN(&ic->ic_mgtq);
  404 #else
  405                         IF_PURGE(&ic->ic_mgtq);
  406                         IF_PURGE(&ic->ic_pwrsaveq);
  407 #endif
  408                         if (ic->ic_wep_ctx != NULL) {
  409                                 free(ic->ic_wep_ctx, M_DEVBUF);
  410                                 ic->ic_wep_ctx = NULL;
  411                         }
  412                         ieee80211_free_allnodes(ic);
  413                         break;
  414                 }
  415                 break;
  416         case IEEE80211_S_SCAN:
  417                 ic->ic_flags &= ~IEEE80211_F_SIBSS;
  418                 /* initialize bss for probe request */
  419                 IEEE80211_ADDR_COPY(ni->ni_macaddr, ifp->if_broadcastaddr);
  420                 IEEE80211_ADDR_COPY(ni->ni_bssid, ifp->if_broadcastaddr);
  421                 ni->ni_rates = ic->ic_sup_rates[
  422                         ieee80211_chan2mode(ic, ni->ni_chan)];
  423                 ni->ni_associd = 0;
  424                 ni->ni_rstamp = 0;
  425                 switch (ostate) {
  426                 case IEEE80211_S_INIT:
  427                         if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
  428                             ic->ic_des_chan != IEEE80211_CHAN_ANYC) {
  429                                 /*
  430                                  * AP operation and we already have a channel;
  431                                  * bypass the scan and startup immediately.
  432                                  */
  433                                 ieee80211_create_ibss(ic, ic->ic_des_chan);
  434                         } else {
  435                                 ieee80211_begin_scan(ic);
  436                         }
  437                         break;
  438                 case IEEE80211_S_SCAN:
  439                         /* scan next */
  440                         if (ic->ic_flags & IEEE80211_F_ASCAN) {
  441                                 IEEE80211_SEND_MGMT(ic, ni,
  442                                     IEEE80211_FC0_SUBTYPE_PROBE_REQ, 0);
  443                         }
  444                         break;
  445                 case IEEE80211_S_RUN:
  446                         /* beacon miss */
  447                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE,
  448                                 ("no recent beacons from %s; rescanning\n",
  449                                 ether_sprintf(ic->ic_bss->ni_bssid)));
  450                         /* XXX this clears the scan set */
  451                         ieee80211_free_allnodes(ic);
  452                         /* FALLTHRU */
  453                 case IEEE80211_S_AUTH:
  454                 case IEEE80211_S_ASSOC:
  455                         /* timeout restart scan */
  456                         ni = ieee80211_find_node(ic, ic->ic_bss->ni_macaddr);
  457                         if (ni != NULL) {
  458                                 ni->ni_fails++;
  459                         }
  460                         ieee80211_begin_scan(ic);
  461                         break;
  462                 }
  463                 break;
  464         case IEEE80211_S_AUTH:
  465                 switch (ostate) {
  466                 case IEEE80211_S_INIT:
  467                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
  468                                 ("%s: invalid transition\n", __func__));
  469                         break;
  470                 case IEEE80211_S_SCAN:
  471                         IEEE80211_SEND_MGMT(ic, ni,
  472                             IEEE80211_FC0_SUBTYPE_AUTH, 1);
  473                         break;
  474                 case IEEE80211_S_AUTH:
  475                 case IEEE80211_S_ASSOC:
  476                         switch (mgt) {
  477                         case IEEE80211_FC0_SUBTYPE_AUTH:
  478                                 /* ??? */
  479                                 IEEE80211_SEND_MGMT(ic, ni,
  480                                     IEEE80211_FC0_SUBTYPE_AUTH, 2);
  481                                 break;
  482                         case IEEE80211_FC0_SUBTYPE_DEAUTH:
  483                                 /* ignore and retry scan on timeout */
  484                                 break;
  485                         }
  486                         break;
  487                 case IEEE80211_S_RUN:
  488                         switch (mgt) {
  489                         case IEEE80211_FC0_SUBTYPE_AUTH:
  490                                 IEEE80211_SEND_MGMT(ic, ni,
  491                                     IEEE80211_FC0_SUBTYPE_AUTH, 2);
  492                                 ic->ic_state = ostate;  /* stay RUN */
  493                                 break;
  494                         case IEEE80211_FC0_SUBTYPE_DEAUTH:
  495                                 /* try to reauth */
  496                                 IEEE80211_SEND_MGMT(ic, ni,
  497                                     IEEE80211_FC0_SUBTYPE_AUTH, 1);
  498                                 break;
  499                         }
  500                         break;
  501                 }
  502                 break;
  503         case IEEE80211_S_ASSOC:
  504                 switch (ostate) {
  505                 case IEEE80211_S_INIT:
  506                 case IEEE80211_S_SCAN:
  507                 case IEEE80211_S_ASSOC:
  508                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
  509                                 ("%s: invalid transition\n", __func__));
  510                         break;
  511                 case IEEE80211_S_AUTH:
  512                         IEEE80211_SEND_MGMT(ic, ni,
  513                             IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
  514                         break;
  515                 case IEEE80211_S_RUN:
  516                         IEEE80211_SEND_MGMT(ic, ni,
  517                             IEEE80211_FC0_SUBTYPE_REASSOC_REQ, 0);
  518                         break;
  519                 }
  520                 break;
  521         case IEEE80211_S_RUN:
  522                 linkstate = LINK_STATE_UP;
  523                 switch (ostate) {
  524                 case IEEE80211_S_INIT:
  525                 case IEEE80211_S_AUTH:
  526                 case IEEE80211_S_RUN:
  527                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
  528                                 ("%s: invalid transition\n", __func__));
  529                         break;
  530                 case IEEE80211_S_SCAN:          /* adhoc/hostap mode */
  531                 case IEEE80211_S_ASSOC:         /* infra mode */
  532                         IASSERT(ni->ni_txrate < ni->ni_rates.rs_nrates,
  533                                 ("%s: bogus xmit rate %u setup", __func__,
  534                                         ni->ni_txrate));
  535 #ifdef IEEE80211_DEBUG
  536                         if (ieee80211_msg_debug(ic)) {
  537                                 if_printf(ifp, " ");
  538                                 if (ic->ic_opmode == IEEE80211_M_STA)
  539                                         printf("associated ");
  540                                 else
  541                                         printf("synchronized ");
  542                                 printf("with %s ssid ",
  543                                     ether_sprintf(ni->ni_bssid));
  544                                 ieee80211_print_essid(ic->ic_bss->ni_essid,
  545                                     ni->ni_esslen);
  546                                 printf(" channel %d start %uMb\n",
  547                                         ieee80211_chan2ieee(ic, ni->ni_chan),
  548                                         IEEE80211_RATE2MBS(ni->ni_rates.rs_rates[ni->ni_txrate]));
  549                         }
  550 #endif
  551                         ic->ic_mgt_timer = 0;
  552                         (*ifp->if_start)(ifp);
  553                         break;
  554                 }
  555                 break;
  556         }
  557         if (ifp->if_link_state != linkstate) {
  558                 ifp->if_link_state = linkstate;
  559                 s = splnet();
  560                 rt_ifmsg(ifp);
  561                 splx(s);
  562         }
  563         return 0;
  564 }

Cache object: d3c25a5a06ce14f604a4c09b66a1177d


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