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