1 /* 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * Alternatively, this software may be distributed under the terms of the 18 * GNU General Public License ("GPL") version 2 as published by the Free 19 * Software Foundation. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 * $FreeBSD: src/sys/net80211/ieee80211_proto.c,v 1.17.2.9 2006/03/13 03:10:31 sam Exp $ 33 * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_proto.c,v 1.12 2007/04/26 12:59:14 sephe Exp $ 34 */ 35 36 /* 37 * IEEE 802.11 protocol support. 38 */ 39 40 #include "opt_inet.h" 41 42 #include <sys/param.h> 43 #include <sys/kernel.h> 44 #include <sys/systm.h> 45 #include <sys/serialize.h> 46 47 #include <sys/socket.h> 48 49 #include <net/if.h> 50 #include <net/if_arp.h> 51 #include <net/if_media.h> 52 #include <net/ethernet.h> /* XXX for ether_sprintf */ 53 54 #include <netproto/802_11/ieee80211_var.h> 55 56 /* XXX tunables */ 57 #define AGGRESSIVE_MODE_SWITCH_HYSTERESIS 3 /* pkts / 100ms */ 58 #define HIGH_PRI_SWITCH_THRESH 10 /* pkts / 100ms */ 59 60 #define IEEE80211_RATE2MBS(r) (((r) & IEEE80211_RATE_VAL) / 2) 61 62 const char *ieee80211_mgt_subtype_name[] = IEEE80211_MGT_SUBTYPE_NAMES; 63 const char *ieee80211_ctl_subtype_name[] = IEEE80211_CTL_SUBTYPE_NAMES; 64 const char *ieee80211_state_name[IEEE80211_S_MAX] = { 65 "INIT", /* IEEE80211_S_INIT */ 66 "SCAN", /* IEEE80211_S_SCAN */ 67 "AUTH", /* IEEE80211_S_AUTH */ 68 "ASSOC", /* IEEE80211_S_ASSOC */ 69 "RUN" /* IEEE80211_S_RUN */ 70 }; 71 const char *ieee80211_wme_acnames[] = { 72 "WME_AC_BE", 73 "WME_AC_BK", 74 "WME_AC_VI", 75 "WME_AC_VO", 76 "WME_UPSD", 77 }; 78 79 static int ieee80211_newstate(struct ieee80211com *, enum ieee80211_state, int); 80 81 void 82 ieee80211_proto_attach(struct ieee80211com *ic) 83 { 84 struct ifnet *ifp = ic->ic_ifp; 85 86 /* XXX room for crypto */ 87 ifp->if_hdrlen = sizeof(struct ieee80211_qosframe_addr4); 88 89 ic->ic_rtsthreshold = IEEE80211_RTS_DEFAULT; 90 ic->ic_fragthreshold = IEEE80211_FRAG_DEFAULT; 91 ic->ic_fixed_rate = IEEE80211_FIXED_RATE_NONE; 92 ic->ic_bmiss_max = IEEE80211_BMISS_MAX; 93 callout_init(&ic->ic_swbmiss); 94 ic->ic_mcast_rate = IEEE80211_MCAST_RATE_DEFAULT; 95 ic->ic_protmode = IEEE80211_PROT_CTSONLY; 96 ic->ic_roaming = IEEE80211_ROAMING_AUTO; 97 98 ic->ic_wme.wme_hipri_switch_hysteresis = 99 AGGRESSIVE_MODE_SWITCH_HYSTERESIS; 100 101 /* protocol state change handler */ 102 ic->ic_newstate = ieee80211_newstate; 103 104 /* initialize management frame handlers */ 105 ic->ic_recv_mgmt = ieee80211_recv_mgmt; 106 ic->ic_send_mgmt = ieee80211_send_mgmt; 107 } 108 109 void 110 ieee80211_proto_detach(struct ieee80211com *ic) 111 { 112 113 /* 114 * This should not be needed as we detach when reseting 115 * the state but be conservative here since the 116 * authenticator may do things like spawn kernel threads. 117 */ 118 if (ic->ic_auth->ia_detach) 119 ic->ic_auth->ia_detach(ic); 120 121 ieee80211_drain_mgtq(&ic->ic_mgtq); 122 123 /* 124 * Detach any ACL'ator. 125 */ 126 if (ic->ic_acl != NULL) 127 ic->ic_acl->iac_detach(ic); 128 } 129 130 /* 131 * Simple-minded authenticator module support. 132 */ 133 134 #define IEEE80211_AUTH_MAX (IEEE80211_AUTH_WPA+1) 135 /* XXX well-known names */ 136 static const char *auth_modnames[IEEE80211_AUTH_MAX] = { 137 "wlan_internal", /* IEEE80211_AUTH_NONE */ 138 "wlan_internal", /* IEEE80211_AUTH_OPEN */ 139 "wlan_internal", /* IEEE80211_AUTH_SHARED */ 140 "wlan_xauth", /* IEEE80211_AUTH_8021X */ 141 "wlan_internal", /* IEEE80211_AUTH_AUTO */ 142 "wlan_xauth", /* IEEE80211_AUTH_WPA */ 143 }; 144 static const struct ieee80211_authenticator *authenticators[IEEE80211_AUTH_MAX]; 145 146 static const struct ieee80211_authenticator auth_internal = { 147 .ia_name = "wlan_internal", 148 .ia_attach = NULL, 149 .ia_detach = NULL, 150 .ia_node_join = NULL, 151 .ia_node_leave = NULL, 152 }; 153 154 /* 155 * Setup internal authenticators once; they are never unregistered. 156 */ 157 static void 158 ieee80211_auth_setup(void) 159 { 160 ieee80211_authenticator_register(IEEE80211_AUTH_OPEN, &auth_internal); 161 ieee80211_authenticator_register(IEEE80211_AUTH_SHARED, &auth_internal); 162 ieee80211_authenticator_register(IEEE80211_AUTH_AUTO, &auth_internal); 163 } 164 SYSINIT(wlan_auth, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_auth_setup, NULL); 165 166 const struct ieee80211_authenticator * 167 ieee80211_authenticator_get(int auth) 168 { 169 if (auth >= IEEE80211_AUTH_MAX) 170 return NULL; 171 if (authenticators[auth] == NULL) 172 ieee80211_load_module(auth_modnames[auth]); 173 return authenticators[auth]; 174 } 175 176 void 177 ieee80211_authenticator_register(int type, 178 const struct ieee80211_authenticator *auth) 179 { 180 if (type >= IEEE80211_AUTH_MAX) 181 return; 182 authenticators[type] = auth; 183 } 184 185 void 186 ieee80211_authenticator_unregister(int type) 187 { 188 189 if (type >= IEEE80211_AUTH_MAX) 190 return; 191 authenticators[type] = NULL; 192 } 193 194 /* 195 * Very simple-minded ACL module support. 196 */ 197 /* XXX just one for now */ 198 static const struct ieee80211_aclator *acl = NULL; 199 200 void 201 ieee80211_aclator_register(const struct ieee80211_aclator *iac) 202 { 203 kprintf("wlan: %s acl policy registered\n", iac->iac_name); 204 acl = iac; 205 } 206 207 void 208 ieee80211_aclator_unregister(const struct ieee80211_aclator *iac) 209 { 210 if (acl == iac) 211 acl = NULL; 212 kprintf("wlan: %s acl policy unregistered\n", iac->iac_name); 213 } 214 215 const struct ieee80211_aclator * 216 ieee80211_aclator_get(const char *name) 217 { 218 if (acl == NULL) 219 ieee80211_load_module("wlan_acl"); 220 return acl != NULL && strcmp(acl->iac_name, name) == 0 ? acl : NULL; 221 } 222 223 void 224 ieee80211_print_essid(const uint8_t *essid, int len) 225 { 226 const uint8_t *p; 227 int i; 228 229 if (len > IEEE80211_NWID_LEN) 230 len = IEEE80211_NWID_LEN; 231 /* determine printable or not */ 232 for (i = 0, p = essid; i < len; i++, p++) { 233 if (*p < ' ' || *p > 0x7e) 234 break; 235 } 236 if (i == len) { 237 kprintf("\""); 238 for (i = 0, p = essid; i < len; i++, p++) 239 kprintf("%c", *p); 240 kprintf("\""); 241 } else { 242 kprintf("0x"); 243 for (i = 0, p = essid; i < len; i++, p++) 244 kprintf("%02x", *p); 245 } 246 } 247 248 void 249 ieee80211_print_rateset(const struct ieee80211_rateset *rs) 250 { 251 int i; 252 253 for (i = 0; i < rs->rs_nrates; ++i) { 254 kprintf("%d%s ", IEEE80211_RS_RATE(rs, i), 255 (rs->rs_rates[i] & IEEE80211_RATE_BASIC) ? "*" : ""); 256 } 257 } 258 259 void 260 ieee80211_dump_pkt(const uint8_t *buf, int len, int rate, int rssi) 261 { 262 const struct ieee80211_frame *wh; 263 int i; 264 265 wh = (const struct ieee80211_frame *)buf; 266 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { 267 case IEEE80211_FC1_DIR_NODS: 268 kprintf("NODS %6D", wh->i_addr2, ":"); 269 kprintf("->%6D", wh->i_addr1, ":"); 270 kprintf("(%6D)", wh->i_addr3, ":"); 271 break; 272 case IEEE80211_FC1_DIR_TODS: 273 kprintf("TODS %6D", wh->i_addr2, ":"); 274 kprintf("->%6D", wh->i_addr3, ":"); 275 kprintf("(%6D)", wh->i_addr1, ":"); 276 break; 277 case IEEE80211_FC1_DIR_FROMDS: 278 kprintf("FRDS %6D", wh->i_addr3, ":"); 279 kprintf("->%6D", wh->i_addr1, ":"); 280 kprintf("(%6D)", wh->i_addr2, ":"); 281 break; 282 case IEEE80211_FC1_DIR_DSTODS: 283 kprintf("DSDS %6D", (const uint8_t *)&wh[1], ":"); 284 kprintf("->%6D", wh->i_addr3, ":"); 285 kprintf("(%6D", wh->i_addr2, ":"); 286 kprintf("->%6D)", wh->i_addr1, ":"); 287 break; 288 } 289 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { 290 case IEEE80211_FC0_TYPE_DATA: 291 kprintf(" data"); 292 break; 293 case IEEE80211_FC0_TYPE_MGT: 294 kprintf(" %s", ieee80211_mgt_subtype_name[ 295 (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) 296 >> IEEE80211_FC0_SUBTYPE_SHIFT]); 297 break; 298 default: 299 kprintf(" type#%d", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK); 300 break; 301 } 302 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 303 int i; 304 kprintf(" WEP [IV"); 305 for (i = 0; i < IEEE80211_WEP_IVLEN; i++) 306 kprintf(" %.02x", buf[sizeof(*wh)+i]); 307 kprintf(" KID %u]", buf[sizeof(*wh)+i] >> 6); 308 } 309 if (rate >= 0) 310 kprintf(" %dM", rate / 2); 311 if (rssi >= 0) 312 kprintf(" +%d", rssi); 313 kprintf("\n"); 314 if (len > 0) { 315 for (i = 0; i < len; i++) { 316 if ((i & 1) == 0) 317 kprintf(" "); 318 kprintf("%02x", buf[i]); 319 } 320 kprintf("\n"); 321 } 322 } 323 324 int 325 ieee80211_fix_rate(struct ieee80211_node *ni, int flags, int join) 326 { 327 #define RV(v) ((v) & IEEE80211_RATE_VAL) 328 struct ieee80211com *ic = ni->ni_ic; 329 int i, j, ignore, error, nbasicrates; 330 int okrate, badrate, fixedrate; 331 const struct ieee80211_rateset *srs; 332 struct ieee80211_rateset *nrs; 333 uint8_t r; 334 335 /* 336 * If the fixed rate check was requested but no 337 * fixed has been defined then just remove it. 338 */ 339 if ((flags & IEEE80211_F_DOFRATE) && 340 ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) 341 flags &= ~IEEE80211_F_DOFRATE; 342 error = 0; 343 okrate = badrate = fixedrate = 0; 344 nbasicrates = 0; 345 srs = &ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)]; 346 nrs = &ni->ni_rates; 347 for (i = 0; i < nrs->rs_nrates; ) { 348 ignore = 0; 349 if (flags & IEEE80211_F_DOSORT) { 350 /* 351 * Sort rates. 352 */ 353 for (j = i + 1; j < nrs->rs_nrates; j++) { 354 if (RV(nrs->rs_rates[i]) > RV(nrs->rs_rates[j])) { 355 r = nrs->rs_rates[i]; 356 nrs->rs_rates[i] = nrs->rs_rates[j]; 357 nrs->rs_rates[j] = r; 358 } 359 } 360 361 /* 362 * Remove duplicated rate 363 */ 364 if (i > 0 && 365 IEEE80211_RS_RATE(nrs, i) == 366 IEEE80211_RS_RATE(nrs, i - 1)) { 367 ignore = 1; 368 goto delit; 369 } 370 } 371 r = nrs->rs_rates[i] & IEEE80211_RATE_VAL; 372 badrate = r; 373 if (flags & IEEE80211_F_DOFRATE) { 374 /* 375 * Check any fixed rate is included. 376 */ 377 if (r == RV(srs->rs_rates[ic->ic_fixed_rate])) 378 fixedrate = r; 379 } 380 if (flags & (IEEE80211_F_DONEGO | IEEE80211_F_DODEL)) { 381 /* 382 * Check against supported rates. 383 */ 384 for (j = 0; j < srs->rs_nrates; j++) { 385 if (r == RV(srs->rs_rates[j])) { 386 /* 387 * Overwrite with the supported rate 388 * value so any basic rate bit is set. 389 */ 390 if ((flags & IEEE80211_F_DONEGO) && 391 !join) { 392 nrs->rs_rates[i] = 393 srs->rs_rates[j]; 394 395 if (nrs->rs_rates[i] & 396 IEEE80211_RATE_BASIC) 397 nbasicrates++; 398 } 399 break; 400 } 401 } 402 if (j == srs->rs_nrates) { 403 /* 404 * A rate in the node's rate set is not 405 * supported. If this is a basic rate and 406 * we are operating as an STA then this is 407 * an error. 408 */ 409 if ((flags & IEEE80211_F_DONEGO) && join && 410 (nrs->rs_rates[i] & IEEE80211_RATE_BASIC)) 411 error++; 412 ignore++; 413 } 414 } 415 if (flags & IEEE80211_F_DODEL) { 416 delit: 417 /* 418 * Delete unacceptable rates. 419 */ 420 if (ignore) { 421 nrs->rs_nrates--; 422 for (j = i; j < nrs->rs_nrates; j++) 423 nrs->rs_rates[j] = nrs->rs_rates[j + 1]; 424 nrs->rs_rates[j] = 0; 425 continue; 426 } 427 } 428 if (!ignore) 429 okrate = nrs->rs_rates[i]; 430 i++; 431 } 432 433 /* 434 * Prevent STA from associating, if it does not support 435 * all of the rates in the basic rate set. 436 */ 437 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 438 (flags & IEEE80211_F_DONEGO) && !join && 439 ic->ic_nbasicrates > nbasicrates) 440 error++; 441 442 if (okrate == 0 || error != 0 || 443 ((flags & IEEE80211_F_DOFRATE) && fixedrate == 0)) 444 return badrate | IEEE80211_RATE_BASIC; 445 else 446 return RV(okrate); 447 #undef RV 448 } 449 450 /* 451 * Reset 11g-related state. 452 */ 453 void 454 ieee80211_reset_erp(struct ieee80211com *ic) 455 { 456 ic->ic_flags &= ~IEEE80211_F_USEPROT; 457 ic->ic_nonerpsta = 0; 458 ic->ic_longslotsta = 0; 459 /* 460 * Short slot time is enabled only when operating in 11g 461 * and not in an IBSS. We must also honor whether or not 462 * the driver is capable of doing it. 463 */ 464 ieee80211_set_shortslottime(ic, 465 ic->ic_curmode == IEEE80211_MODE_11A || 466 (ic->ic_curmode == IEEE80211_MODE_11G && 467 ic->ic_opmode == IEEE80211_M_HOSTAP && 468 (ic->ic_caps & IEEE80211_C_SHSLOT))); 469 /* 470 * Set short preamble and ERP barker-preamble flags. 471 */ 472 ieee80211_set_shortpreamble(ic, 473 ic->ic_curmode == IEEE80211_MODE_11A || 474 (ic->ic_caps & IEEE80211_C_SHPREAMBLE)); 475 } 476 477 /* 478 * Set the short slot time state and notify the driver. 479 */ 480 void 481 ieee80211_set_shortslottime(struct ieee80211com *ic, int onoff) 482 { 483 if (onoff) 484 ic->ic_flags |= IEEE80211_F_SHSLOT; 485 else 486 ic->ic_flags &= ~IEEE80211_F_SHSLOT; 487 488 /* Notify driver */ 489 if (ic->ic_updateslot != NULL) 490 ic->ic_updateslot(ic->ic_ifp); 491 } 492 493 /* 494 * Set the short preamble state and notify driver. 495 */ 496 void 497 ieee80211_set_shortpreamble(struct ieee80211com *ic, int onoff) 498 { 499 if (onoff) { 500 ic->ic_flags |= IEEE80211_F_SHPREAMBLE; 501 ic->ic_flags &= ~IEEE80211_F_USEBARKER; 502 } else { 503 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; 504 ic->ic_flags |= IEEE80211_F_USEBARKER; 505 } 506 507 /* Notify driver */ 508 if (ic->ic_update_preamble != NULL) 509 ic->ic_update_preamble(ic->ic_ifp); 510 } 511 512 /* 513 * Check if the specified rate set supports ERP. 514 * NB: the rate set is assumed to be sorted. 515 */ 516 int 517 ieee80211_iserp_rateset(struct ieee80211com *ic, 518 const struct ieee80211_rateset *rs) 519 { 520 #define N(a) (sizeof(a) / sizeof(a[0])) 521 static const int rates[] = { 2, 4, 11, 22, 12, 24, 48 }; 522 int i, j; 523 524 if (rs->rs_nrates < N(rates)) 525 return 0; 526 for (i = 0; i < N(rates); i++) { 527 for (j = 0; j < rs->rs_nrates; j++) { 528 int r = rs->rs_rates[j] & IEEE80211_RATE_VAL; 529 if (rates[i] == r) 530 goto next; 531 if (r > rates[i]) 532 return 0; 533 } 534 return 0; 535 next: 536 ; 537 } 538 return 1; 539 #undef N 540 } 541 542 /* 543 * Mark the basic rates for the 11g rate table based on the 544 * operating mode. For real 11g we mark all the 11b rates 545 * and 6, 12, and 24 OFDM. For 11b compatibility we mark only 546 * 11b rates. There's also a pseudo 11a-mode used to mark only 547 * the basic OFDM rates. 548 */ 549 void 550 ieee80211_set_basicrates(struct ieee80211_rateset *rs, 551 enum ieee80211_phymode mode, int pureg) 552 { 553 static const struct ieee80211_rateset basic[] = { 554 [IEEE80211_MODE_AUTO] = { 0 }, 555 [IEEE80211_MODE_11A] = { 3, { 12, 24, 48 } }, 556 [IEEE80211_MODE_11B] = { 2, { 2, 4 } }, 557 [IEEE80211_MODE_11G] = { 4, { 2, 4, 11, 22 } }, 558 [IEEE80211_MODE_FH] = { 0 }, 559 [IEEE80211_MODE_TURBO_A] = { 3, { 12, 24, 48 } }, 560 [IEEE80211_MODE_TURBO_G] = { 4, { 2, 4, 11, 22 } } 561 }; 562 static const struct ieee80211_rateset basic_pureg = 563 { 7, { 2, 4, 11, 22, 12, 24, 48 } }; 564 const struct ieee80211_rateset *basic_rs; 565 int i, j; 566 567 KASSERT(mode < IEEE80211_MODE_MAX, ("invalid phymode %u\n", mode)); 568 569 if ((mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_TURBO_G) && 570 pureg) 571 basic_rs = &basic_pureg; 572 else 573 basic_rs = &basic[mode]; 574 575 for (i = 0; i < rs->rs_nrates; i++) { 576 rs->rs_rates[i] &= IEEE80211_RATE_VAL; 577 for (j = 0; j < basic_rs->rs_nrates; j++) { 578 if (basic_rs->rs_rates[j] == rs->rs_rates[i]) { 579 rs->rs_rates[i] |= IEEE80211_RATE_BASIC; 580 break; 581 } 582 } 583 } 584 } 585 586 int 587 ieee80211_copy_basicrates(struct ieee80211_rateset *to, 588 const struct ieee80211_rateset *from) 589 { 590 int i, nbasicrates = 0; 591 592 for (i = 0; i < to->rs_nrates; ++i) { 593 int j; 594 595 to->rs_rates[i] &= IEEE80211_RATE_VAL; 596 for (j = 0; j < from->rs_nrates; ++j) { 597 if ((from->rs_rates[j] & IEEE80211_RATE_BASIC) && 598 IEEE80211_RS_RATE(from, j) == to->rs_rates[i]) { 599 to->rs_rates[i] |= IEEE80211_RATE_BASIC; 600 ++nbasicrates; 601 break; 602 } 603 } 604 } 605 return nbasicrates; 606 } 607 608 /* 609 * WME protocol support. The following parameters come from the spec. 610 */ 611 typedef struct phyParamType { 612 uint8_t aifsn; 613 uint8_t logcwmin; 614 uint8_t logcwmax; 615 uint16_t txopLimit; 616 uint8_t acm; 617 } paramType; 618 619 static const struct phyParamType phyParamForAC_BE[IEEE80211_MODE_MAX] = { 620 { 3, 4, 6 }, /* IEEE80211_MODE_AUTO */ 621 { 3, 4, 6 }, /* IEEE80211_MODE_11A */ 622 { 3, 5, 7 }, /* IEEE80211_MODE_11B */ 623 { 3, 4, 6 }, /* IEEE80211_MODE_11G */ 624 { 3, 5, 7 }, /* IEEE80211_MODE_FH */ 625 { 2, 3, 5 }, /* IEEE80211_MODE_TURBO_A */ 626 { 2, 3, 5 }, /* IEEE80211_MODE_TURBO_G */ 627 }; 628 static const struct phyParamType phyParamForAC_BK[IEEE80211_MODE_MAX] = { 629 { 7, 4, 10 }, /* IEEE80211_MODE_AUTO */ 630 { 7, 4, 10 }, /* IEEE80211_MODE_11A */ 631 { 7, 5, 10 }, /* IEEE80211_MODE_11B */ 632 { 7, 4, 10 }, /* IEEE80211_MODE_11G */ 633 { 7, 5, 10 }, /* IEEE80211_MODE_FH */ 634 { 7, 3, 10 }, /* IEEE80211_MODE_TURBO_A */ 635 { 7, 3, 10 }, /* IEEE80211_MODE_TURBO_G */ 636 }; 637 static const struct phyParamType phyParamForAC_VI[IEEE80211_MODE_MAX] = { 638 { 1, 3, 4, 94 }, /* IEEE80211_MODE_AUTO */ 639 { 1, 3, 4, 94 }, /* IEEE80211_MODE_11A */ 640 { 1, 4, 5, 188 }, /* IEEE80211_MODE_11B */ 641 { 1, 3, 4, 94 }, /* IEEE80211_MODE_11G */ 642 { 1, 4, 5, 188 }, /* IEEE80211_MODE_FH */ 643 { 1, 2, 3, 94 }, /* IEEE80211_MODE_TURBO_A */ 644 { 1, 2, 3, 94 }, /* IEEE80211_MODE_TURBO_G */ 645 }; 646 static const struct phyParamType phyParamForAC_VO[IEEE80211_MODE_MAX] = { 647 { 1, 2, 3, 47 }, /* IEEE80211_MODE_AUTO */ 648 { 1, 2, 3, 47 }, /* IEEE80211_MODE_11A */ 649 { 1, 3, 4, 102 }, /* IEEE80211_MODE_11B */ 650 { 1, 2, 3, 47 }, /* IEEE80211_MODE_11G */ 651 { 1, 3, 4, 102 }, /* IEEE80211_MODE_FH */ 652 { 1, 2, 2, 47 }, /* IEEE80211_MODE_TURBO_A */ 653 { 1, 2, 2, 47 }, /* IEEE80211_MODE_TURBO_G */ 654 }; 655 656 static const struct phyParamType bssPhyParamForAC_BE[IEEE80211_MODE_MAX] = { 657 { 3, 4, 10 }, /* IEEE80211_MODE_AUTO */ 658 { 3, 4, 10 }, /* IEEE80211_MODE_11A */ 659 { 3, 5, 10 }, /* IEEE80211_MODE_11B */ 660 { 3, 4, 10 }, /* IEEE80211_MODE_11G */ 661 { 3, 5, 10 }, /* IEEE80211_MODE_FH */ 662 { 2, 3, 10 }, /* IEEE80211_MODE_TURBO_A */ 663 { 2, 3, 10 }, /* IEEE80211_MODE_TURBO_G */ 664 }; 665 static const struct phyParamType bssPhyParamForAC_VI[IEEE80211_MODE_MAX] = { 666 { 2, 3, 4, 94 }, /* IEEE80211_MODE_AUTO */ 667 { 2, 3, 4, 94 }, /* IEEE80211_MODE_11A */ 668 { 2, 4, 5, 188 }, /* IEEE80211_MODE_11B */ 669 { 2, 3, 4, 94 }, /* IEEE80211_MODE_11G */ 670 { 2, 4, 5, 188 }, /* IEEE80211_MODE_FH */ 671 { 2, 2, 3, 94 }, /* IEEE80211_MODE_TURBO_A */ 672 { 2, 2, 3, 94 }, /* IEEE80211_MODE_TURBO_G */ 673 }; 674 static const struct phyParamType bssPhyParamForAC_VO[IEEE80211_MODE_MAX] = { 675 { 2, 2, 3, 47 }, /* IEEE80211_MODE_AUTO */ 676 { 2, 2, 3, 47 }, /* IEEE80211_MODE_11A */ 677 { 2, 3, 4, 102 }, /* IEEE80211_MODE_11B */ 678 { 2, 2, 3, 47 }, /* IEEE80211_MODE_11G */ 679 { 2, 3, 4, 102 }, /* IEEE80211_MODE_FH */ 680 { 1, 2, 2, 47 }, /* IEEE80211_MODE_TURBO_A */ 681 { 1, 2, 2, 47 }, /* IEEE80211_MODE_TURBO_G */ 682 }; 683 684 void 685 ieee80211_wme_initparams(struct ieee80211com *ic) 686 { 687 struct ieee80211_wme_state *wme = &ic->ic_wme; 688 const paramType *pPhyParam, *pBssPhyParam; 689 struct wmeParams *wmep; 690 int i; 691 692 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 693 return; 694 695 for (i = 0; i < WME_NUM_AC; i++) { 696 switch (i) { 697 case WME_AC_BK: 698 pPhyParam = &phyParamForAC_BK[ic->ic_curmode]; 699 pBssPhyParam = &phyParamForAC_BK[ic->ic_curmode]; 700 break; 701 case WME_AC_VI: 702 pPhyParam = &phyParamForAC_VI[ic->ic_curmode]; 703 pBssPhyParam = &bssPhyParamForAC_VI[ic->ic_curmode]; 704 break; 705 case WME_AC_VO: 706 pPhyParam = &phyParamForAC_VO[ic->ic_curmode]; 707 pBssPhyParam = &bssPhyParamForAC_VO[ic->ic_curmode]; 708 break; 709 case WME_AC_BE: 710 default: 711 pPhyParam = &phyParamForAC_BE[ic->ic_curmode]; 712 pBssPhyParam = &bssPhyParamForAC_BE[ic->ic_curmode]; 713 break; 714 } 715 716 wmep = &wme->wme_wmeChanParams.cap_wmeParams[i]; 717 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 718 wmep->wmep_acm = pPhyParam->acm; 719 wmep->wmep_aifsn = pPhyParam->aifsn; 720 wmep->wmep_logcwmin = pPhyParam->logcwmin; 721 wmep->wmep_logcwmax = pPhyParam->logcwmax; 722 wmep->wmep_txopLimit = pPhyParam->txopLimit; 723 } else { 724 wmep->wmep_acm = pBssPhyParam->acm; 725 wmep->wmep_aifsn = pBssPhyParam->aifsn; 726 wmep->wmep_logcwmin = pBssPhyParam->logcwmin; 727 wmep->wmep_logcwmax = pBssPhyParam->logcwmax; 728 wmep->wmep_txopLimit = pBssPhyParam->txopLimit; 729 730 } 731 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME, 732 "%s: %s chan [acm %u aifsn %u log2(cwmin) %u " 733 "log2(cwmax) %u txpoLimit %u]\n", __func__ 734 , ieee80211_wme_acnames[i] 735 , wmep->wmep_acm 736 , wmep->wmep_aifsn 737 , wmep->wmep_logcwmin 738 , wmep->wmep_logcwmax 739 , wmep->wmep_txopLimit 740 ); 741 742 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i]; 743 wmep->wmep_acm = pBssPhyParam->acm; 744 wmep->wmep_aifsn = pBssPhyParam->aifsn; 745 wmep->wmep_logcwmin = pBssPhyParam->logcwmin; 746 wmep->wmep_logcwmax = pBssPhyParam->logcwmax; 747 wmep->wmep_txopLimit = pBssPhyParam->txopLimit; 748 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME, 749 "%s: %s bss [acm %u aifsn %u log2(cwmin) %u " 750 "log2(cwmax) %u txpoLimit %u]\n", __func__ 751 , ieee80211_wme_acnames[i] 752 , wmep->wmep_acm 753 , wmep->wmep_aifsn 754 , wmep->wmep_logcwmin 755 , wmep->wmep_logcwmax 756 , wmep->wmep_txopLimit 757 ); 758 } 759 /* NB: check ic_bss to avoid NULL deref on initial attach */ 760 if (ic->ic_bss != NULL) { 761 /* 762 * Calculate agressive mode switching threshold based 763 * on beacon interval. This doesn't need locking since 764 * we're only called before entering the RUN state at 765 * which point we start sending beacon frames. 766 */ 767 wme->wme_hipri_switch_thresh = 768 (HIGH_PRI_SWITCH_THRESH * ic->ic_bss->ni_intval) / 100; 769 ieee80211_wme_updateparams(ic); 770 } 771 } 772 773 /* 774 * Update WME parameters for ourself and the BSS. 775 */ 776 void 777 ieee80211_wme_updateparams(struct ieee80211com *ic) 778 { 779 static const paramType phyParam[IEEE80211_MODE_MAX] = { 780 { 2, 4, 10, 64 }, /* IEEE80211_MODE_AUTO */ 781 { 2, 4, 10, 64 }, /* IEEE80211_MODE_11A */ 782 { 2, 5, 10, 64 }, /* IEEE80211_MODE_11B */ 783 { 2, 4, 10, 64 }, /* IEEE80211_MODE_11G */ 784 { 2, 5, 10, 64 }, /* IEEE80211_MODE_FH */ 785 { 1, 3, 10, 64 }, /* IEEE80211_MODE_TURBO_A */ 786 { 1, 3, 10, 64 }, /* IEEE80211_MODE_TURBO_G */ 787 }; 788 struct ieee80211_wme_state *wme = &ic->ic_wme; 789 const struct wmeParams *wmep; 790 struct wmeParams *chanp, *bssp; 791 int i; 792 793 ASSERT_SERIALIZED(ic->ic_ifp->if_serializer); 794 795 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 796 return; 797 798 /* set up the channel access parameters for the physical device */ 799 for (i = 0; i < WME_NUM_AC; i++) { 800 chanp = &wme->wme_chanParams.cap_wmeParams[i]; 801 wmep = &wme->wme_wmeChanParams.cap_wmeParams[i]; 802 chanp->wmep_aifsn = wmep->wmep_aifsn; 803 chanp->wmep_logcwmin = wmep->wmep_logcwmin; 804 chanp->wmep_logcwmax = wmep->wmep_logcwmax; 805 chanp->wmep_txopLimit = wmep->wmep_txopLimit; 806 807 chanp = &wme->wme_bssChanParams.cap_wmeParams[i]; 808 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i]; 809 chanp->wmep_aifsn = wmep->wmep_aifsn; 810 chanp->wmep_logcwmin = wmep->wmep_logcwmin; 811 chanp->wmep_logcwmax = wmep->wmep_logcwmax; 812 chanp->wmep_txopLimit = wmep->wmep_txopLimit; 813 } 814 815 /* 816 * This implements agressive mode as found in certain 817 * vendors' AP's. When there is significant high 818 * priority (VI/VO) traffic in the BSS throttle back BE 819 * traffic by using conservative parameters. Otherwise 820 * BE uses agressive params to optimize performance of 821 * legacy/non-QoS traffic. 822 */ 823 if ((ic->ic_opmode == IEEE80211_M_HOSTAP && 824 (wme->wme_flags & WME_F_AGGRMODE) != 0) || 825 (ic->ic_opmode == IEEE80211_M_STA && 826 (ic->ic_bss->ni_flags & IEEE80211_NODE_QOS) == 0) || 827 (ic->ic_flags & IEEE80211_F_WME) == 0) { 828 chanp = &wme->wme_chanParams.cap_wmeParams[WME_AC_BE]; 829 bssp = &wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE]; 830 831 chanp->wmep_aifsn = bssp->wmep_aifsn = 832 phyParam[ic->ic_curmode].aifsn; 833 chanp->wmep_logcwmin = bssp->wmep_logcwmin = 834 phyParam[ic->ic_curmode].logcwmin; 835 chanp->wmep_logcwmax = bssp->wmep_logcwmax = 836 phyParam[ic->ic_curmode].logcwmax; 837 chanp->wmep_txopLimit = bssp->wmep_txopLimit = 838 (ic->ic_flags & IEEE80211_F_BURST) ? 839 phyParam[ic->ic_curmode].txopLimit : 0; 840 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME, 841 "%s: %s [acm %u aifsn %u log2(cwmin) %u " 842 "log2(cwmax) %u txpoLimit %u]\n", __func__ 843 , ieee80211_wme_acnames[WME_AC_BE] 844 , chanp->wmep_acm 845 , chanp->wmep_aifsn 846 , chanp->wmep_logcwmin 847 , chanp->wmep_logcwmax 848 , chanp->wmep_txopLimit 849 ); 850 } 851 852 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 853 ic->ic_sta_assoc < 2 && (wme->wme_flags & WME_F_AGGRMODE) != 0) { 854 static const uint8_t logCwMin[IEEE80211_MODE_MAX] = { 855 3, /* IEEE80211_MODE_AUTO */ 856 3, /* IEEE80211_MODE_11A */ 857 4, /* IEEE80211_MODE_11B */ 858 3, /* IEEE80211_MODE_11G */ 859 4, /* IEEE80211_MODE_FH */ 860 3, /* IEEE80211_MODE_TURBO_A */ 861 3, /* IEEE80211_MODE_TURBO_G */ 862 }; 863 chanp = &wme->wme_chanParams.cap_wmeParams[WME_AC_BE]; 864 bssp = &wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE]; 865 866 chanp->wmep_logcwmin = bssp->wmep_logcwmin = 867 logCwMin[ic->ic_curmode]; 868 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME, 869 "%s: %s log2(cwmin) %u\n", __func__ 870 , ieee80211_wme_acnames[WME_AC_BE] 871 , chanp->wmep_logcwmin 872 ); 873 } 874 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { /* XXX ibss? */ 875 /* 876 * Arrange for a beacon update and bump the parameter 877 * set number so associated stations load the new values. 878 */ 879 wme->wme_bssChanParams.cap_info = 880 (wme->wme_bssChanParams.cap_info+1) & WME_QOSINFO_COUNT; 881 ic->ic_flags |= IEEE80211_F_WMEUPDATE; 882 } 883 884 wme->wme_update(ic); 885 886 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME, 887 "%s: WME params updated, cap_info 0x%x\n", __func__, 888 ic->ic_opmode == IEEE80211_M_STA ? 889 wme->wme_wmeChanParams.cap_info : 890 wme->wme_bssChanParams.cap_info); 891 } 892 893 void 894 ieee80211_beacon_miss(struct ieee80211com *ic) 895 { 896 897 if (ic->ic_flags & IEEE80211_F_SCAN) { 898 /* XXX check ic_curchan != ic_bsschan? */ 899 return; 900 } 901 IEEE80211_DPRINTF(ic, 902 IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, 903 "%s\n", "beacon miss"); 904 905 /* 906 * Our handling is only meaningful for stations that are 907 * associated; any other conditions else will be handled 908 * through different means (e.g. the tx timeout on mgt frames). 909 */ 910 if (ic->ic_opmode != IEEE80211_M_STA || ic->ic_state != IEEE80211_S_RUN) 911 return; 912 913 if (++ic->ic_bmiss_count < ic->ic_bmiss_max) { 914 /* 915 * Send a directed probe req before falling back to a scan; 916 * if we receive a response ic_bmiss_count will be reset. 917 * Some cards mistakenly report beacon miss so this avoids 918 * the expensive scan if the ap is still there. 919 */ 920 ieee80211_send_probereq(ic->ic_bss, ic->ic_myaddr, 921 ic->ic_bss->ni_bssid, ic->ic_bss->ni_bssid, 922 ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen, 923 ic->ic_opt_ie, ic->ic_opt_ie_len); 924 return; 925 } 926 ic->ic_bmiss_count = 0; 927 ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); 928 } 929 930 /* 931 * Software beacon miss handling. Check if any beacons 932 * were received in the last period. If not post a 933 * beacon miss; otherwise reset the counter. 934 */ 935 static void 936 ieee80211_swbmiss(void *arg) 937 { 938 struct ieee80211com *ic = arg; 939 struct ifnet *ifp = ic->ic_ifp; 940 941 ifnet_serialize_all(ifp); 942 943 if (ic->ic_swbmiss_count == 0) { 944 ieee80211_beacon_miss(ic); 945 if (ic->ic_bmiss_count == 0) /* don't re-arm timer */ 946 goto back; 947 } else 948 ic->ic_swbmiss_count = 0; 949 callout_reset(&ic->ic_swbmiss, ic->ic_swbmiss_period, 950 ieee80211_swbmiss, ic); 951 952 back: 953 ifnet_deserialize_all(ifp); 954 } 955 956 static void 957 sta_disconnect(void *arg, struct ieee80211_node *ni) 958 { 959 struct ieee80211com *ic = arg; 960 961 if (ni->ni_associd != 0) { 962 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DISASSOC, 963 IEEE80211_REASON_ASSOC_LEAVE); 964 ieee80211_node_leave(ic, ni); 965 } else if (ni->ni_flags & IEEE80211_NODE_AREF) { 966 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 967 IEEE80211_REASON_ASSOC_LEAVE); 968 ieee80211_node_leave(ic, ni); 969 } 970 } 971 972 void 973 ieee80211_reset_state(struct ieee80211com *ic, 974 enum ieee80211_state cur_state) 975 { 976 struct ieee80211_node *ni; 977 978 IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE, 979 "%s reset internal state machine (%s)\n", 980 __func__, ieee80211_state_name[cur_state]); 981 982 ni = ic->ic_bss; 983 KASSERT(ni != NULL, ("empty ic_bss\n")); 984 985 switch (cur_state) { 986 case IEEE80211_S_INIT: 987 break; 988 case IEEE80211_S_RUN: 989 switch (ic->ic_opmode) { 990 case IEEE80211_M_STA: 991 /* 992 * Avoid sending disassoc to self. This could happen 993 * when operational mode is switched directly from 994 * HOSTAP/IBSS to STA. 995 */ 996 if (!IEEE80211_ADDR_EQ(ic->ic_myaddr, ni->ni_macaddr)) { 997 IEEE80211_SEND_MGMT(ic, ni, 998 IEEE80211_FC0_SUBTYPE_DISASSOC, 999 IEEE80211_REASON_ASSOC_LEAVE); 1000 ieee80211_sta_leave(ic, ni); 1001 } 1002 break; 1003 case IEEE80211_M_HOSTAP: 1004 ieee80211_iterate_nodes(&ic->ic_sta, 1005 sta_disconnect, ic); 1006 break; 1007 default: 1008 break; 1009 } 1010 break; 1011 case IEEE80211_S_ASSOC: 1012 switch (ic->ic_opmode) { 1013 case IEEE80211_M_STA: 1014 /* 1015 * Avoid sending deauth to self. 1016 */ 1017 if (!IEEE80211_ADDR_EQ(ic->ic_myaddr, ni->ni_macaddr)) { 1018 IEEE80211_SEND_MGMT(ic, ni, 1019 IEEE80211_FC0_SUBTYPE_DEAUTH, 1020 IEEE80211_REASON_AUTH_LEAVE); 1021 } 1022 break; 1023 default: 1024 break; 1025 } 1026 break; 1027 case IEEE80211_S_SCAN: 1028 ieee80211_cancel_scan(ic); 1029 /* FALL THROUGH */ 1030 case IEEE80211_S_AUTH: 1031 break; 1032 } 1033 1034 ieee80211_drain_mgtq(&ic->ic_mgtq); 1035 ieee80211_reset_bss(ic); 1036 } 1037 1038 static int 1039 ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1040 { 1041 struct ifnet *ifp = ic->ic_ifp; 1042 struct ieee80211_node *ni; 1043 enum ieee80211_state ostate; 1044 1045 ostate = ic->ic_state; 1046 IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE, "%s: %s -> %s\n", __func__, 1047 ieee80211_state_name[ostate], ieee80211_state_name[nstate]); 1048 ic->ic_state = nstate; /* state transition */ 1049 ni = ic->ic_bss; /* NB: no reference held */ 1050 if (ic->ic_flags_ext & IEEE80211_FEXT_SWBMISS) 1051 callout_stop(&ic->ic_swbmiss); 1052 switch (nstate) { 1053 case IEEE80211_S_INIT: 1054 ieee80211_reset_state(ic, ostate); 1055 ic->ic_mgt_timer = 0; 1056 1057 if (ic->ic_auth->ia_detach != NULL) 1058 ic->ic_auth->ia_detach(ic); 1059 break; 1060 1061 case IEEE80211_S_SCAN: 1062 switch (ostate) { 1063 case IEEE80211_S_INIT: 1064 if ((ic->ic_opmode == IEEE80211_M_HOSTAP || 1065 ic->ic_opmode == IEEE80211_M_IBSS || 1066 ic->ic_opmode == IEEE80211_M_AHDEMO) && 1067 ic->ic_des_chan != IEEE80211_CHAN_ANYC) { 1068 /* 1069 * AP operation and we already have a channel; 1070 * bypass the scan and startup immediately. 1071 */ 1072 ieee80211_create_ibss(ic, ic->ic_des_chan); 1073 } else { 1074 ieee80211_begin_scan(ic, arg); 1075 } 1076 break; 1077 case IEEE80211_S_SCAN: 1078 /* 1079 * Scan next. If doing an active scan probe 1080 * for the requested ap (if any). 1081 */ 1082 if (ic->ic_flags & IEEE80211_F_ASCAN) 1083 ieee80211_probe_curchan(ic, 0); 1084 break; 1085 case IEEE80211_S_RUN: 1086 /* beacon miss */ 1087 IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE, 1088 "no recent beacons from %6D; rescanning\n", 1089 ic->ic_bss->ni_bssid, ":"); 1090 ieee80211_sta_leave(ic, ni); 1091 ic->ic_flags &= ~IEEE80211_F_SIBSS; /* XXX */ 1092 /* FALLTHRU */ 1093 case IEEE80211_S_AUTH: 1094 case IEEE80211_S_ASSOC: 1095 /* timeout restart scan */ 1096 ni = ieee80211_find_node(&ic->ic_scan, 1097 ic->ic_bss->ni_macaddr); 1098 if (ni != NULL) { 1099 ni->ni_fails++; 1100 ieee80211_unref_node(&ni); 1101 } 1102 if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) 1103 ieee80211_begin_scan(ic, arg); 1104 break; 1105 } 1106 break; 1107 case IEEE80211_S_AUTH: 1108 switch (ostate) { 1109 case IEEE80211_S_INIT: 1110 case IEEE80211_S_SCAN: 1111 IEEE80211_SEND_MGMT(ic, ni, 1112 IEEE80211_FC0_SUBTYPE_AUTH, 1); 1113 break; 1114 case IEEE80211_S_AUTH: 1115 case IEEE80211_S_ASSOC: 1116 switch (arg) { 1117 case IEEE80211_FC0_SUBTYPE_AUTH: 1118 /* ??? */ 1119 IEEE80211_SEND_MGMT(ic, ni, 1120 IEEE80211_FC0_SUBTYPE_AUTH, 2); 1121 break; 1122 case IEEE80211_FC0_SUBTYPE_DEAUTH: 1123 /* ignore and retry scan on timeout */ 1124 break; 1125 } 1126 break; 1127 case IEEE80211_S_RUN: 1128 switch (arg) { 1129 case IEEE80211_FC0_SUBTYPE_AUTH: 1130 IEEE80211_SEND_MGMT(ic, ni, 1131 IEEE80211_FC0_SUBTYPE_AUTH, 2); 1132 ic->ic_state = ostate; /* stay RUN */ 1133 break; 1134 case IEEE80211_FC0_SUBTYPE_DEAUTH: 1135 ieee80211_sta_leave(ic, ni); 1136 if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) { 1137 /* try to reauth */ 1138 IEEE80211_SEND_MGMT(ic, ni, 1139 IEEE80211_FC0_SUBTYPE_AUTH, 1); 1140 } 1141 break; 1142 } 1143 break; 1144 } 1145 break; 1146 case IEEE80211_S_ASSOC: 1147 switch (ostate) { 1148 case IEEE80211_S_INIT: 1149 case IEEE80211_S_SCAN: 1150 case IEEE80211_S_ASSOC: 1151 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 1152 "%s: invalid transition\n", __func__); 1153 break; 1154 case IEEE80211_S_AUTH: 1155 IEEE80211_SEND_MGMT(ic, ni, 1156 IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0); 1157 break; 1158 case IEEE80211_S_RUN: 1159 ieee80211_sta_leave(ic, ni); 1160 if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) { 1161 IEEE80211_SEND_MGMT(ic, ni, 1162 IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 1); 1163 } 1164 break; 1165 } 1166 break; 1167 case IEEE80211_S_RUN: 1168 if (ic->ic_flags & IEEE80211_F_WPA) { 1169 /* XXX validate prerequisites */ 1170 } 1171 switch (ostate) { 1172 case IEEE80211_S_INIT: 1173 if (ic->ic_opmode == IEEE80211_M_MONITOR) 1174 break; 1175 /* fall thru... */ 1176 case IEEE80211_S_AUTH: 1177 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 1178 "%s: invalid transition\n", __func__); 1179 /* fall thru... */ 1180 case IEEE80211_S_RUN: 1181 break; 1182 case IEEE80211_S_SCAN: /* adhoc/hostap mode */ 1183 case IEEE80211_S_ASSOC: /* infra mode */ 1184 KASSERT(ni->ni_txrate < ni->ni_rates.rs_nrates, 1185 ("%s: bogus xmit rate %u setup\n", __func__, 1186 ni->ni_txrate)); 1187 #ifdef IEEE80211_DEBUG 1188 if (ieee80211_msg_debug(ic)) { 1189 if (ic->ic_opmode == IEEE80211_M_STA) 1190 if_printf(ifp, "associated "); 1191 else 1192 if_printf(ifp, "synchronized "); 1193 kprintf("with %6D ssid ", ni->ni_bssid, ":"); 1194 ieee80211_print_essid(ic->ic_bss->ni_essid, 1195 ni->ni_esslen); 1196 kprintf(" channel %d start %uMb\n", 1197 ieee80211_chan2ieee(ic, ic->ic_curchan), 1198 IEEE80211_RATE2MBS(ni->ni_rates.rs_rates[ni->ni_txrate])); 1199 } 1200 #endif 1201 ic->ic_mgt_timer = 0; 1202 if (ic->ic_opmode == IEEE80211_M_STA) 1203 ieee80211_notify_node_join(ic, ni, 1204 arg == IEEE80211_FC0_SUBTYPE_ASSOC_RESP); 1205 ifp->if_start(ifp); /* XXX not authorized yet */ 1206 break; 1207 } 1208 if (ostate != IEEE80211_S_RUN && 1209 ic->ic_opmode == IEEE80211_M_STA && 1210 (ic->ic_flags_ext & IEEE80211_FEXT_SWBMISS)) { 1211 /* 1212 * Start s/w beacon miss timer for devices w/o 1213 * hardware support. We fudge a bit here since 1214 * we're doing this in software. 1215 */ 1216 ic->ic_swbmiss_period = IEEE80211_TU_TO_TICKS( 1217 2 * ic->ic_bmissthreshold * ni->ni_intval); 1218 ic->ic_swbmiss_count = 0; 1219 callout_reset(&ic->ic_swbmiss, ic->ic_swbmiss_period, 1220 ieee80211_swbmiss, ic); 1221 } 1222 /* 1223 * Start/stop the authenticator when operating as an 1224 * AP. We delay until here to allow configuration to 1225 * happen out of order. 1226 */ 1227 if (ic->ic_opmode == IEEE80211_M_HOSTAP && /* XXX IBSS/AHDEMO */ 1228 ic->ic_auth->ia_attach != NULL) { 1229 /* XXX check failure */ 1230 ic->ic_auth->ia_attach(ic); 1231 } else if (ic->ic_auth->ia_detach != NULL) { 1232 ic->ic_auth->ia_detach(ic); 1233 } 1234 /* 1235 * When 802.1x is not in use mark the port authorized 1236 * at this point so traffic can flow. 1237 */ 1238 if (ni->ni_authmode != IEEE80211_AUTH_8021X) 1239 ieee80211_node_authorize(ni); 1240 /* 1241 * Enable inactivity processing. 1242 * XXX 1243 */ 1244 ic->ic_scan.nt_inact_timer = IEEE80211_INACT_WAIT; 1245 ic->ic_sta.nt_inact_timer = IEEE80211_INACT_WAIT; 1246 break; 1247 } 1248 return 0; 1249 } 1250