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