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