1 /* $NetBSD: ieee80211.c,v 1.19 2004/06/06 05:45:29 dyoung Exp $ */ 2 /*- 3 * Copyright (c) 2001 Atsushi Onoe 4 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * Alternatively, this software may be distributed under the terms of the 19 * GNU General Public License ("GPL") version 2 as published by the Free 20 * Software Foundation. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 #ifdef __FreeBSD__ 36 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211.c,v 1.11 2004/04/02 20:19:20 sam Exp $"); 37 #else 38 __KERNEL_RCSID(0, "$NetBSD: ieee80211.c,v 1.19 2004/06/06 05:45:29 dyoung Exp $"); 39 #endif 40 41 /* 42 * IEEE 802.11 generic handler 43 */ 44 45 #include "opt_inet.h" 46 #include "bpfilter.h" 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/mbuf.h> 51 #include <sys/malloc.h> 52 #include <sys/kernel.h> 53 #include <sys/socket.h> 54 #include <sys/sockio.h> 55 #include <sys/endian.h> 56 #include <sys/errno.h> 57 #ifdef __FreeBSD__ 58 #include <sys/bus.h> 59 #endif 60 #include <sys/proc.h> 61 #include <sys/sysctl.h> 62 63 #ifdef __FreeBSD__ 64 #include <machine/atomic.h> 65 #endif 66 67 #include <net/if.h> 68 #include <net/if_dl.h> 69 #include <net/if_media.h> 70 #include <net/if_arp.h> 71 #ifdef __FreeBSD__ 72 #include <net/ethernet.h> 73 #else 74 #include <net/if_ether.h> 75 #endif 76 #include <net/if_llc.h> 77 78 #include <net80211/ieee80211_var.h> 79 #include <net80211/ieee80211_compat.h> 80 81 #include <net/bpf.h> 82 83 #ifdef INET 84 #include <netinet/in.h> 85 #ifdef __FreeBSD__ 86 #include <netinet/if_ether.h> 87 #else 88 #include <net/if_ether.h> 89 #endif 90 #endif 91 92 #ifdef IEEE80211_DEBUG 93 int ieee80211_debug = 0; 94 #ifdef __NetBSD__ 95 static int ieee80211_debug_nodenum; 96 #endif /* __NetBSD__ */ 97 98 #ifdef __FreeBSD__ 99 SYSCTL_INT(_debug, OID_AUTO, ieee80211, CTLFLAG_RW, &ieee80211_debug, 100 0, "IEEE 802.11 media debugging printfs"); 101 #endif 102 #endif 103 104 int ieee80211_inact_max = IEEE80211_INACT_MAX; 105 static int ieee80211_inact_max_nodenum; 106 107 static void ieee80211_set11gbasicrates(struct ieee80211_rateset *, 108 enum ieee80211_phymode); 109 110 static const char *ieee80211_phymode_name[] = { 111 "auto", /* IEEE80211_MODE_AUTO */ 112 "11a", /* IEEE80211_MODE_11A */ 113 "11b", /* IEEE80211_MODE_11B */ 114 "11g", /* IEEE80211_MODE_11G */ 115 "FH", /* IEEE80211_MODE_FH */ 116 "turbo", /* IEEE80211_MODE_TURBO */ 117 }; 118 119 void 120 ieee80211_ifattach(struct ifnet *ifp) 121 { 122 struct ieee80211com *ic = (void *)ifp; 123 struct ieee80211_channel *c; 124 int i; 125 126 ether_ifattach(ifp, ic->ic_myaddr); 127 #if NBPFILTER > 0 128 bpfattach2(ifp, DLT_IEEE802_11, 129 sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf); 130 #endif 131 ieee80211_crypto_attach(ifp); 132 133 /* 134 * Fill in 802.11 available channel set, mark 135 * all available channels as active, and pick 136 * a default channel if not already specified. 137 */ 138 memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail)); 139 ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO; 140 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { 141 c = &ic->ic_channels[i]; 142 if (c->ic_flags) { 143 /* 144 * Verify driver passed us valid data. 145 */ 146 if (i != ieee80211_chan2ieee(ic, c)) { 147 if_printf(ifp, "bad channel ignored; " 148 "freq %u flags %x number %u\n", 149 c->ic_freq, c->ic_flags, i); 150 c->ic_flags = 0; /* NB: remove */ 151 continue; 152 } 153 setbit(ic->ic_chan_avail, i); 154 /* 155 * Identify mode capabilities. 156 */ 157 if (IEEE80211_IS_CHAN_A(c)) 158 ic->ic_modecaps |= 1<<IEEE80211_MODE_11A; 159 if (IEEE80211_IS_CHAN_B(c)) 160 ic->ic_modecaps |= 1<<IEEE80211_MODE_11B; 161 if (IEEE80211_IS_CHAN_PUREG(c)) 162 ic->ic_modecaps |= 1<<IEEE80211_MODE_11G; 163 if (IEEE80211_IS_CHAN_FHSS(c)) 164 ic->ic_modecaps |= 1<<IEEE80211_MODE_FH; 165 if (IEEE80211_IS_CHAN_T(c)) 166 ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO; 167 } 168 } 169 /* validate ic->ic_curmode */ 170 if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0) 171 ic->ic_curmode = IEEE80211_MODE_AUTO; 172 ic->ic_des_chan = IEEE80211_CHAN_ANYC; /* any channel is ok */ 173 174 (void) ieee80211_setmode(ic, ic->ic_curmode); 175 176 if (ic->ic_lintval == 0) 177 ic->ic_lintval = 100; /* default sleep */ 178 ic->ic_bmisstimeout = 7*ic->ic_lintval; /* default 7 beacons */ 179 180 ieee80211_node_attach(ifp); 181 ieee80211_proto_attach(ifp); 182 } 183 184 void 185 ieee80211_ifdetach(struct ifnet *ifp) 186 { 187 struct ieee80211com *ic = (void *)ifp; 188 189 ieee80211_proto_detach(ifp); 190 ieee80211_crypto_detach(ifp); 191 ieee80211_node_detach(ifp); 192 #ifdef __FreeBSD__ 193 ifmedia_removeall(&ic->ic_media); 194 #else 195 ifmedia_delete_instance(&ic->ic_media, IFM_INST_ANY); 196 #endif 197 #if NBPFILTER > 0 198 bpfdetach(ifp); 199 #endif 200 ether_ifdetach(ifp); 201 } 202 203 /* 204 * Convert MHz frequency to IEEE channel number. 205 */ 206 u_int 207 ieee80211_mhz2ieee(u_int freq, u_int flags) 208 { 209 if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */ 210 if (freq == 2484) 211 return 14; 212 if (freq < 2484) 213 return (freq - 2407) / 5; 214 else 215 return 15 + ((freq - 2512) / 20); 216 } else if (flags & IEEE80211_CHAN_5GHZ) { /* 5Ghz band */ 217 return (freq - 5000) / 5; 218 } else { /* either, guess */ 219 if (freq == 2484) 220 return 14; 221 if (freq < 2484) 222 return (freq - 2407) / 5; 223 if (freq < 5000) 224 return 15 + ((freq - 2512) / 20); 225 return (freq - 5000) / 5; 226 } 227 } 228 229 /* 230 * Convert channel to IEEE channel number. 231 */ 232 u_int 233 ieee80211_chan2ieee(struct ieee80211com *ic, struct ieee80211_channel *c) 234 { 235 if (ic->ic_channels <= c && c <= &ic->ic_channels[IEEE80211_CHAN_MAX]) 236 return c - ic->ic_channels; 237 else if (c == IEEE80211_CHAN_ANYC) 238 return IEEE80211_CHAN_ANY; 239 else if (c != NULL) { 240 if_printf(&ic->ic_if, "invalid channel freq %u flags %x\n", 241 c->ic_freq, c->ic_flags); 242 return 0; /* XXX */ 243 } else { 244 if_printf(&ic->ic_if, "invalid channel (NULL)\n"); 245 return 0; /* XXX */ 246 } 247 } 248 249 /* 250 * Convert IEEE channel number to MHz frequency. 251 */ 252 u_int 253 ieee80211_ieee2mhz(u_int chan, u_int flags) 254 { 255 if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */ 256 if (chan == 14) 257 return 2484; 258 if (chan < 14) 259 return 2407 + chan*5; 260 else 261 return 2512 + ((chan-15)*20); 262 } else if (flags & IEEE80211_CHAN_5GHZ) {/* 5Ghz band */ 263 return 5000 + (chan*5); 264 } else { /* either, guess */ 265 if (chan == 14) 266 return 2484; 267 if (chan < 14) /* 0-13 */ 268 return 2407 + chan*5; 269 if (chan < 27) /* 15-26 */ 270 return 2512 + ((chan-15)*20); 271 return 5000 + (chan*5); 272 } 273 } 274 275 /* 276 * Setup the media data structures according to the channel and 277 * rate tables. This must be called by the driver after 278 * ieee80211_attach and before most anything else. 279 */ 280 void 281 ieee80211_media_init(struct ifnet *ifp, 282 ifm_change_cb_t media_change, ifm_stat_cb_t media_stat) 283 { 284 #define ADD(_ic, _s, _o) \ 285 ifmedia_add(&(_ic)->ic_media, \ 286 IFM_MAKEWORD(IFM_IEEE80211, (_s), (_o), 0), 0, NULL) 287 struct ieee80211com *ic = (void *)ifp; 288 struct ifmediareq imr; 289 int i, j, mode, rate, maxrate, mword, mopt, r; 290 struct ieee80211_rateset *rs; 291 struct ieee80211_rateset allrates; 292 293 /* 294 * Do late attach work that must wait for any subclass 295 * (i.e. driver) work such as overriding methods. 296 */ 297 ieee80211_node_lateattach(ifp); 298 299 /* 300 * Fill in media characteristics. 301 */ 302 ifmedia_init(&ic->ic_media, 0, media_change, media_stat); 303 maxrate = 0; 304 memset(&allrates, 0, sizeof(allrates)); 305 for (mode = IEEE80211_MODE_AUTO; mode < IEEE80211_MODE_MAX; mode++) { 306 static const u_int mopts[] = { 307 IFM_AUTO, 308 IFM_IEEE80211_11A, 309 IFM_IEEE80211_11B, 310 IFM_IEEE80211_11G, 311 IFM_IEEE80211_FH, 312 IFM_IEEE80211_11A | IFM_IEEE80211_TURBO, 313 }; 314 if ((ic->ic_modecaps & (1<<mode)) == 0) 315 continue; 316 mopt = mopts[mode]; 317 ADD(ic, IFM_AUTO, mopt); /* e.g. 11a auto */ 318 if (ic->ic_caps & IEEE80211_C_IBSS) 319 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_ADHOC); 320 if (ic->ic_caps & IEEE80211_C_HOSTAP) 321 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_HOSTAP); 322 if (ic->ic_caps & IEEE80211_C_AHDEMO) 323 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_ADHOC | IFM_FLAG0); 324 if (ic->ic_caps & IEEE80211_C_MONITOR) 325 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_MONITOR); 326 if (mode == IEEE80211_MODE_AUTO) 327 continue; 328 if_printf(ifp, "%s rates: ", ieee80211_phymode_name[mode]); 329 rs = &ic->ic_sup_rates[mode]; 330 for (i = 0; i < rs->rs_nrates; i++) { 331 rate = rs->rs_rates[i]; 332 mword = ieee80211_rate2media(ic, rate, mode); 333 if (mword == 0) 334 continue; 335 printf("%s%d%sMbps", (i != 0 ? " " : ""), 336 (rate & IEEE80211_RATE_VAL) / 2, 337 ((rate & 0x1) != 0 ? ".5" : "")); 338 ADD(ic, mword, mopt); 339 if (ic->ic_caps & IEEE80211_C_IBSS) 340 ADD(ic, mword, mopt | IFM_IEEE80211_ADHOC); 341 if (ic->ic_caps & IEEE80211_C_HOSTAP) 342 ADD(ic, mword, mopt | IFM_IEEE80211_HOSTAP); 343 if (ic->ic_caps & IEEE80211_C_AHDEMO) 344 ADD(ic, mword, mopt | IFM_IEEE80211_ADHOC | IFM_FLAG0); 345 if (ic->ic_caps & IEEE80211_C_MONITOR) 346 ADD(ic, mword, mopt | IFM_IEEE80211_MONITOR); 347 /* 348 * Add rate to the collection of all rates. 349 */ 350 r = rate & IEEE80211_RATE_VAL; 351 for (j = 0; j < allrates.rs_nrates; j++) 352 if (allrates.rs_rates[j] == r) 353 break; 354 if (j == allrates.rs_nrates) { 355 /* unique, add to the set */ 356 allrates.rs_rates[j] = r; 357 allrates.rs_nrates++; 358 } 359 rate = (rate & IEEE80211_RATE_VAL) / 2; 360 if (rate > maxrate) 361 maxrate = rate; 362 } 363 printf("\n"); 364 } 365 for (i = 0; i < allrates.rs_nrates; i++) { 366 mword = ieee80211_rate2media(ic, allrates.rs_rates[i], 367 IEEE80211_MODE_AUTO); 368 if (mword == 0) 369 continue; 370 mword = IFM_SUBTYPE(mword); /* remove media options */ 371 ADD(ic, mword, 0); 372 if (ic->ic_caps & IEEE80211_C_IBSS) 373 ADD(ic, mword, IFM_IEEE80211_ADHOC); 374 if (ic->ic_caps & IEEE80211_C_HOSTAP) 375 ADD(ic, mword, IFM_IEEE80211_HOSTAP); 376 if (ic->ic_caps & IEEE80211_C_AHDEMO) 377 ADD(ic, mword, IFM_IEEE80211_ADHOC | IFM_FLAG0); 378 if (ic->ic_caps & IEEE80211_C_MONITOR) 379 ADD(ic, mword, IFM_IEEE80211_MONITOR); 380 } 381 ieee80211_media_status(ifp, &imr); 382 ifmedia_set(&ic->ic_media, imr.ifm_active); 383 384 if (maxrate) 385 ifp->if_baudrate = IF_Mbps(maxrate); 386 387 if (ic->ic_max_aid == 0) 388 ic->ic_max_aid = IEEE80211_MAX_AID; 389 390 #undef ADD 391 } 392 393 static int 394 findrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate) 395 { 396 #define IEEERATE(_ic,_m,_i) \ 397 ((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL) 398 int i, nrates = ic->ic_sup_rates[mode].rs_nrates; 399 for (i = 0; i < nrates; i++) 400 if (IEEERATE(ic, mode, i) == rate) 401 return i; 402 return -1; 403 #undef IEEERATE 404 } 405 406 /* 407 * Handle a media change request. 408 */ 409 int 410 ieee80211_media_change(struct ifnet *ifp) 411 { 412 struct ieee80211com *ic = (void *)ifp; 413 struct ifmedia_entry *ime; 414 enum ieee80211_opmode newopmode; 415 enum ieee80211_phymode newphymode; 416 int i, j, newrate, error = 0; 417 418 ime = ic->ic_media.ifm_cur; 419 /* 420 * First, identify the phy mode. 421 */ 422 switch (IFM_MODE(ime->ifm_media)) { 423 case IFM_IEEE80211_11A: 424 newphymode = IEEE80211_MODE_11A; 425 break; 426 case IFM_IEEE80211_11B: 427 newphymode = IEEE80211_MODE_11B; 428 break; 429 case IFM_IEEE80211_11G: 430 newphymode = IEEE80211_MODE_11G; 431 break; 432 case IFM_IEEE80211_FH: 433 newphymode = IEEE80211_MODE_FH; 434 break; 435 case IFM_AUTO: 436 newphymode = IEEE80211_MODE_AUTO; 437 break; 438 default: 439 return EINVAL; 440 } 441 /* 442 * Turbo mode is an ``option''. Eventually it 443 * needs to be applied to 11g too. 444 */ 445 if (ime->ifm_media & IFM_IEEE80211_TURBO) { 446 if (newphymode != IEEE80211_MODE_11A) 447 return EINVAL; 448 newphymode = IEEE80211_MODE_TURBO; 449 } 450 /* 451 * Validate requested mode is available. 452 */ 453 if ((ic->ic_modecaps & (1<<newphymode)) == 0) 454 return EINVAL; 455 456 /* 457 * Next, the fixed/variable rate. 458 */ 459 i = -1; 460 if (IFM_SUBTYPE(ime->ifm_media) != IFM_AUTO) { 461 /* 462 * Convert media subtype to rate. 463 */ 464 newrate = ieee80211_media2rate(ime->ifm_media); 465 if (newrate == 0) 466 return EINVAL; 467 /* 468 * Check the rate table for the specified/current phy. 469 */ 470 if (newphymode == IEEE80211_MODE_AUTO) { 471 /* 472 * In autoselect mode search for the rate. 473 */ 474 for (j = IEEE80211_MODE_11A; 475 j < IEEE80211_MODE_MAX; j++) { 476 if ((ic->ic_modecaps & (1<<j)) == 0) 477 continue; 478 i = findrate(ic, j, newrate); 479 if (i != -1) { 480 /* lock mode too */ 481 newphymode = j; 482 break; 483 } 484 } 485 } else { 486 i = findrate(ic, newphymode, newrate); 487 } 488 if (i == -1) /* mode/rate mismatch */ 489 return EINVAL; 490 } 491 /* NB: defer rate setting to later */ 492 493 /* 494 * Deduce new operating mode but don't install it just yet. 495 */ 496 if ((ime->ifm_media & (IFM_IEEE80211_ADHOC|IFM_FLAG0)) == 497 (IFM_IEEE80211_ADHOC|IFM_FLAG0)) 498 newopmode = IEEE80211_M_AHDEMO; 499 else if (ime->ifm_media & IFM_IEEE80211_HOSTAP) 500 newopmode = IEEE80211_M_HOSTAP; 501 else if (ime->ifm_media & IFM_IEEE80211_ADHOC) 502 newopmode = IEEE80211_M_IBSS; 503 else if (ime->ifm_media & IFM_IEEE80211_MONITOR) 504 newopmode = IEEE80211_M_MONITOR; 505 else 506 newopmode = IEEE80211_M_STA; 507 508 /* 509 * Autoselect doesn't make sense when operating as an AP. 510 * If no phy mode has been selected, pick one and lock it 511 * down so rate tables can be used in forming beacon frames 512 * and the like. 513 */ 514 if (newopmode == IEEE80211_M_HOSTAP && 515 newphymode == IEEE80211_MODE_AUTO) { 516 for (j = IEEE80211_MODE_11A; j < IEEE80211_MODE_MAX; j++) 517 if (ic->ic_modecaps & (1<<j)) { 518 newphymode = j; 519 break; 520 } 521 } 522 523 /* 524 * Handle phy mode change. 525 */ 526 if (ic->ic_curmode != newphymode) { /* change phy mode */ 527 error = ieee80211_setmode(ic, newphymode); 528 if (error != 0) 529 return error; 530 error = ENETRESET; 531 } 532 533 /* 534 * Committed to changes, install the rate setting. 535 */ 536 if (ic->ic_fixed_rate != i) { 537 ic->ic_fixed_rate = i; /* set fixed tx rate */ 538 error = ENETRESET; 539 } 540 541 /* 542 * Handle operating mode change. 543 */ 544 if (ic->ic_opmode != newopmode) { 545 ic->ic_opmode = newopmode; 546 switch (newopmode) { 547 case IEEE80211_M_AHDEMO: 548 case IEEE80211_M_HOSTAP: 549 case IEEE80211_M_STA: 550 case IEEE80211_M_MONITOR: 551 ic->ic_flags &= ~IEEE80211_F_IBSSON; 552 break; 553 case IEEE80211_M_IBSS: 554 ic->ic_flags |= IEEE80211_F_IBSSON; 555 #ifdef notdef 556 if (ic->ic_curmode == IEEE80211_MODE_11G) 557 ieee80211_set11gbasicrates( 558 &ic->ic_sup_rates[newphymode], 559 IEEE80211_MODE_11B); 560 #endif 561 break; 562 } 563 error = ENETRESET; 564 } 565 #ifdef notdef 566 if (error == 0) 567 ifp->if_baudrate = ifmedia_baudrate(ime->ifm_media); 568 #endif 569 return error; 570 } 571 572 void 573 ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr) 574 { 575 struct ieee80211com *ic = (void *)ifp; 576 struct ieee80211_node *ni = NULL; 577 578 imr->ifm_status = IFM_AVALID; 579 imr->ifm_active = IFM_IEEE80211; 580 if (ic->ic_state == IEEE80211_S_RUN) 581 imr->ifm_status |= IFM_ACTIVE; 582 imr->ifm_active |= IFM_AUTO; 583 switch (ic->ic_opmode) { 584 case IEEE80211_M_STA: 585 ni = ic->ic_bss; 586 /* calculate rate subtype */ 587 imr->ifm_active |= ieee80211_rate2media(ic, 588 ni->ni_rates.rs_rates[ni->ni_txrate], ic->ic_curmode); 589 break; 590 case IEEE80211_M_IBSS: 591 imr->ifm_active |= IFM_IEEE80211_ADHOC; 592 break; 593 case IEEE80211_M_AHDEMO: 594 /* should not come here */ 595 break; 596 case IEEE80211_M_HOSTAP: 597 imr->ifm_active |= IFM_IEEE80211_HOSTAP; 598 break; 599 case IEEE80211_M_MONITOR: 600 imr->ifm_active |= IFM_IEEE80211_MONITOR; 601 break; 602 } 603 switch (ic->ic_curmode) { 604 case IEEE80211_MODE_11A: 605 imr->ifm_active |= IFM_IEEE80211_11A; 606 break; 607 case IEEE80211_MODE_11B: 608 imr->ifm_active |= IFM_IEEE80211_11B; 609 break; 610 case IEEE80211_MODE_11G: 611 imr->ifm_active |= IFM_IEEE80211_11G; 612 break; 613 case IEEE80211_MODE_FH: 614 imr->ifm_active |= IFM_IEEE80211_FH; 615 break; 616 case IEEE80211_MODE_TURBO: 617 imr->ifm_active |= IFM_IEEE80211_11A 618 | IFM_IEEE80211_TURBO; 619 break; 620 } 621 } 622 623 void 624 ieee80211_watchdog(struct ifnet *ifp) 625 { 626 struct ieee80211com *ic = (void *)ifp; 627 628 if (ic->ic_mgt_timer && --ic->ic_mgt_timer == 0) 629 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 630 if (ic->ic_inact_timer && --ic->ic_inact_timer == 0) 631 ieee80211_timeout_nodes(ic); 632 633 if (ic->ic_mgt_timer != 0 || ic->ic_inact_timer != 0) 634 ifp->if_timer = 1; 635 } 636 637 /* 638 * Mark the basic rates for the 11g rate table based on the 639 * operating mode. For real 11g we mark all the 11b rates 640 * and 6, 12, and 24 OFDM. For 11b compatibility we mark only 641 * 11b rates. There's also a pseudo 11a-mode used to mark only 642 * the basic OFDM rates. 643 */ 644 static void 645 ieee80211_set11gbasicrates(struct ieee80211_rateset *rs, enum ieee80211_phymode mode) 646 { 647 static const struct ieee80211_rateset basic[] = { 648 { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_11A */ 649 { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_11B */ 650 { 7, { 2, 4, 11, 22, 12, 24, 48 } },/* IEEE80211_MODE_11G */ 651 { 0 }, /* IEEE80211_MODE_FH */ 652 { 0 }, /* IEEE80211_MODE_TURBO */ 653 }; 654 int i, j; 655 656 for (i = 0; i < rs->rs_nrates; i++) { 657 rs->rs_rates[i] &= IEEE80211_RATE_VAL; 658 for (j = 0; j < basic[mode].rs_nrates; j++) 659 if (basic[mode].rs_rates[j] == rs->rs_rates[i]) { 660 rs->rs_rates[i] |= IEEE80211_RATE_BASIC; 661 break; 662 } 663 } 664 } 665 666 /* 667 * Set the current phy mode and recalculate the active channel 668 * set based on the available channels for this mode. Also 669 * select a new default/current channel if the current one is 670 * inappropriate for this mode. 671 */ 672 int 673 ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode) 674 { 675 #define N(a) (sizeof(a) / sizeof(a[0])) 676 static const u_int chanflags[] = { 677 0, /* IEEE80211_MODE_AUTO */ 678 IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ 679 IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ 680 IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ 681 IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ 682 IEEE80211_CHAN_T, /* IEEE80211_MODE_TURBO */ 683 }; 684 struct ieee80211_channel *c; 685 u_int modeflags; 686 int i; 687 688 /* validate new mode */ 689 if ((ic->ic_modecaps & (1<<mode)) == 0) { 690 IEEE80211_DPRINTF(("%s: mode %u not supported (caps 0x%x)\n", 691 __func__, mode, ic->ic_modecaps)); 692 return EINVAL; 693 } 694 695 /* 696 * Verify at least one channel is present in the available 697 * channel list before committing to the new mode. 698 */ 699 IASSERT(mode < N(chanflags), ("Unexpected mode %u", mode)); 700 modeflags = chanflags[mode]; 701 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { 702 c = &ic->ic_channels[i]; 703 if (mode == IEEE80211_MODE_AUTO) { 704 /* ignore turbo channels for autoselect */ 705 if ((c->ic_flags &~ IEEE80211_CHAN_TURBO) != 0) 706 break; 707 } else { 708 if ((c->ic_flags & modeflags) == modeflags) 709 break; 710 } 711 } 712 if (i > IEEE80211_CHAN_MAX) { 713 IEEE80211_DPRINTF(("%s: no channels found for mode %u\n", 714 __func__, mode)); 715 return EINVAL; 716 } 717 718 /* 719 * Calculate the active channel set. 720 */ 721 memset(ic->ic_chan_active, 0, sizeof(ic->ic_chan_active)); 722 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { 723 c = &ic->ic_channels[i]; 724 if (mode == IEEE80211_MODE_AUTO) { 725 /* take anything but pure turbo channels */ 726 if ((c->ic_flags &~ IEEE80211_CHAN_TURBO) != 0) 727 setbit(ic->ic_chan_active, i); 728 } else { 729 if ((c->ic_flags & modeflags) == modeflags) 730 setbit(ic->ic_chan_active, i); 731 } 732 } 733 /* 734 * If no current/default channel is setup or the current 735 * channel is wrong for the mode then pick the first 736 * available channel from the active list. This is likely 737 * not the right one. 738 */ 739 if (ic->ic_ibss_chan == NULL || 740 isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) { 741 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) 742 if (isset(ic->ic_chan_active, i)) { 743 ic->ic_ibss_chan = &ic->ic_channels[i]; 744 break; 745 } 746 IASSERT(ic->ic_ibss_chan != NULL && 747 isset(ic->ic_chan_active, 748 ieee80211_chan2ieee(ic, ic->ic_ibss_chan)), 749 ("Bad IBSS channel %u\n", 750 ieee80211_chan2ieee(ic, ic->ic_ibss_chan))); 751 } 752 753 /* 754 * Set/reset state flags that influence beacon contents, etc. 755 * 756 * XXX what if we have stations already associated??? 757 * XXX probably not right for autoselect? 758 */ 759 if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) 760 ic->ic_flags |= IEEE80211_F_SHPREAMBLE; 761 if (mode == IEEE80211_MODE_11G) { 762 if (ic->ic_caps & IEEE80211_C_SHSLOT) 763 ic->ic_flags |= IEEE80211_F_SHSLOT; 764 ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode], 765 IEEE80211_MODE_11G); 766 } else { 767 ic->ic_flags &= ~IEEE80211_F_SHSLOT; 768 } 769 770 ic->ic_curmode = mode; 771 return 0; 772 #undef N 773 } 774 775 /* 776 * Return the phy mode for with the specified channel so the 777 * caller can select a rate set. This is problematic and the 778 * work here assumes how things work elsewhere in this code. 779 * 780 * XXX never returns turbo modes -dcy 781 */ 782 enum ieee80211_phymode 783 ieee80211_chan2mode(struct ieee80211com *ic, struct ieee80211_channel *chan) 784 { 785 /* 786 * NB: this assumes the channel would not be supplied to us 787 * unless it was already compatible with the current mode. 788 */ 789 if (ic->ic_curmode != IEEE80211_MODE_AUTO || 790 chan == IEEE80211_CHAN_ANYC) 791 return ic->ic_curmode; 792 /* 793 * In autoselect mode; deduce a mode based on the channel 794 * characteristics. We assume that turbo-only channels 795 * are not considered when the channel set is constructed. 796 */ 797 if (IEEE80211_IS_CHAN_5GHZ(chan)) 798 return IEEE80211_MODE_11A; 799 else if (IEEE80211_IS_CHAN_FHSS(chan)) 800 return IEEE80211_MODE_FH; 801 else if (chan->ic_flags & (IEEE80211_CHAN_OFDM|IEEE80211_CHAN_DYN)) 802 return IEEE80211_MODE_11G; 803 else 804 return IEEE80211_MODE_11B; 805 } 806 807 /* 808 * convert IEEE80211 rate value to ifmedia subtype. 809 * ieee80211 rate is in unit of 0.5Mbps. 810 */ 811 int 812 ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode mode) 813 { 814 #define N(a) (sizeof(a) / sizeof(a[0])) 815 static const struct { 816 u_int m; /* rate + mode */ 817 u_int r; /* if_media rate */ 818 } rates[] = { 819 { 2 | IFM_IEEE80211_FH, IFM_IEEE80211_FH1 }, 820 { 4 | IFM_IEEE80211_FH, IFM_IEEE80211_FH2 }, 821 { 2 | IFM_IEEE80211_11B, IFM_IEEE80211_DS1 }, 822 { 4 | IFM_IEEE80211_11B, IFM_IEEE80211_DS2 }, 823 { 11 | IFM_IEEE80211_11B, IFM_IEEE80211_DS5 }, 824 { 22 | IFM_IEEE80211_11B, IFM_IEEE80211_DS11 }, 825 { 44 | IFM_IEEE80211_11B, IFM_IEEE80211_DS22 }, 826 { 12 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM6 }, 827 { 18 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM9 }, 828 { 24 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM12 }, 829 { 36 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM18 }, 830 { 48 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM24 }, 831 { 72 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM36 }, 832 { 96 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM48 }, 833 { 108 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM54 }, 834 { 2 | IFM_IEEE80211_11G, IFM_IEEE80211_DS1 }, 835 { 4 | IFM_IEEE80211_11G, IFM_IEEE80211_DS2 }, 836 { 11 | IFM_IEEE80211_11G, IFM_IEEE80211_DS5 }, 837 { 22 | IFM_IEEE80211_11G, IFM_IEEE80211_DS11 }, 838 { 12 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM6 }, 839 { 18 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM9 }, 840 { 24 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM12 }, 841 { 36 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM18 }, 842 { 48 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM24 }, 843 { 72 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM36 }, 844 { 96 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM48 }, 845 { 108 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM54 }, 846 /* NB: OFDM72 doesn't realy exist so we don't handle it */ 847 }; 848 u_int mask, i; 849 850 mask = rate & IEEE80211_RATE_VAL; 851 switch (mode) { 852 case IEEE80211_MODE_11A: 853 case IEEE80211_MODE_TURBO: 854 mask |= IFM_IEEE80211_11A; 855 break; 856 case IEEE80211_MODE_11B: 857 mask |= IFM_IEEE80211_11B; 858 break; 859 case IEEE80211_MODE_FH: 860 mask |= IFM_IEEE80211_FH; 861 break; 862 case IEEE80211_MODE_AUTO: 863 /* NB: ic may be NULL for some drivers */ 864 if (ic && ic->ic_phytype == IEEE80211_T_FH) { 865 mask |= IFM_IEEE80211_FH; 866 break; 867 } 868 /* NB: hack, 11g matches both 11b+11a rates */ 869 /* fall thru... */ 870 case IEEE80211_MODE_11G: 871 mask |= IFM_IEEE80211_11G; 872 break; 873 } 874 for (i = 0; i < N(rates); i++) 875 if (rates[i].m == mask) 876 return rates[i].r; 877 return IFM_AUTO; 878 #undef N 879 } 880 881 int 882 ieee80211_media2rate(int mword) 883 { 884 #define N(a) (sizeof(a) / sizeof(a[0])) 885 int i; 886 static const struct { 887 int subtype; 888 int rate; 889 } ieeerates[] = { 890 { IFM_AUTO, -1 }, 891 { IFM_MANUAL, 0 }, 892 { IFM_NONE, 0 }, 893 { IFM_IEEE80211_FH1, 2 }, 894 { IFM_IEEE80211_FH2, 4 }, 895 { IFM_IEEE80211_DS1, 2 }, 896 { IFM_IEEE80211_DS2, 4 }, 897 { IFM_IEEE80211_DS5, 11 }, 898 { IFM_IEEE80211_DS11, 22 }, 899 { IFM_IEEE80211_DS22, 44 }, 900 { IFM_IEEE80211_OFDM6, 12 }, 901 { IFM_IEEE80211_OFDM9, 18 }, 902 { IFM_IEEE80211_OFDM12, 24 }, 903 { IFM_IEEE80211_OFDM18, 36 }, 904 { IFM_IEEE80211_OFDM24, 48 }, 905 { IFM_IEEE80211_OFDM36, 72 }, 906 { IFM_IEEE80211_OFDM48, 96 }, 907 { IFM_IEEE80211_OFDM54, 108 }, 908 { IFM_IEEE80211_OFDM72, 144 }, 909 }; 910 for (i = 0; i < N(ieeerates); i++) { 911 if (ieeerates[i].subtype == IFM_SUBTYPE(mword)) 912 return ieeerates[i].rate; 913 } 914 return 0; 915 #undef N 916 } 917 918 #ifdef __NetBSD__ 919 /* TBD factor with sysctl_ath_verify. */ 920 static int 921 sysctl_ieee80211_verify(SYSCTLFN_ARGS) 922 { 923 int error, t; 924 struct sysctlnode node; 925 926 node = *rnode; 927 t = *(int*)rnode->sysctl_data; 928 node.sysctl_data = &t; 929 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 930 if (error || newp == NULL) 931 return (error); 932 933 IEEE80211_DPRINTF(("%s: t = %d, nodenum = %d, rnodenum = %d\n", 934 __func__, t, node.sysctl_num, rnode->sysctl_num)); 935 936 if (node.sysctl_num == ieee80211_inact_max_nodenum) { 937 if (t < 1) 938 return (EINVAL); 939 t = roundup(t, IEEE80211_INACT_WAIT) / IEEE80211_INACT_WAIT; 940 #ifdef IEEE80211_DEBUG 941 } else if (node.sysctl_num == ieee80211_debug_nodenum) { 942 if (t < 0 || t > 2) 943 return (EINVAL); 944 #endif /* IEEE80211_DEBUG */ 945 } else 946 return (EINVAL); 947 948 *(int*)rnode->sysctl_data = t; 949 950 return (0); 951 } 952 953 /* 954 * Setup sysctl(3) MIB, net.ieee80211.* 955 * 956 * TBD condition CTLFLAG_PERMANENT on being an LKM or not 957 */ 958 SYSCTL_SETUP(sysctl_ieee80211, "sysctl ieee80211 subtree setup") 959 { 960 int rc; 961 struct sysctlnode *cnode, *rnode; 962 963 if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 964 CTLFLAG_PERMANENT, CTLTYPE_NODE, "net", NULL, 965 NULL, 0, NULL, 0, CTL_NET, CTL_EOL)) != 0) 966 goto err; 967 968 if ((rc = sysctl_createv(clog, 0, &rnode, &rnode, 969 CTLFLAG_PERMANENT, CTLTYPE_NODE, "link", 970 "link-layer statistics and controls", 971 NULL, 0, NULL, 0, PF_LINK, CTL_EOL)) != 0) 972 goto err; 973 974 if ((rc = sysctl_createv(clog, 0, &rnode, &rnode, 975 CTLFLAG_PERMANENT, CTLTYPE_NODE, "ieee80211", 976 "IEEE 802.11 WLAN statistics and controls", 977 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) 978 goto err; 979 980 #ifdef IEEE80211_DEBUG 981 982 /* control debugging printfs */ 983 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 984 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 985 "debug", SYSCTL_DESCR("Enable IEEE 802.11 debugging output"), 986 sysctl_ieee80211_verify, 0, &ieee80211_debug, 0, 987 CTL_CREATE, CTL_EOL)) != 0) 988 goto err; 989 990 ieee80211_debug_nodenum = cnode->sysctl_num; 991 992 #endif /* IEEE80211_DEBUG */ 993 994 /* control inactivity timer */ 995 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 996 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 997 "maxinact", SYSCTL_DESCR("Station inactivity timeout"), 998 sysctl_ieee80211_verify, 0, &ieee80211_inact_max, 999 0, CTL_CREATE, CTL_EOL)) != 0) 1000 goto err; 1001 1002 ieee80211_inact_max_nodenum = cnode->sysctl_num; 1003 1004 return; 1005 err: 1006 printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 1007 } 1008 #endif /* __NetBSD__ */ 1009 1010 #ifdef __FreeBSD__ 1011 /* 1012 * Module glue. 1013 * 1014 * NB: the module name is "wlan" for compatibility with NetBSD. 1015 */ 1016 1017 static int 1018 ieee80211_modevent(module_t mod, int type, void *unused) 1019 { 1020 switch (type) { 1021 case MOD_LOAD: 1022 if (bootverbose) 1023 printf("wlan: <802.11 Link Layer>\n"); 1024 return 0; 1025 case MOD_UNLOAD: 1026 return 0; 1027 } 1028 return EINVAL; 1029 } 1030 1031 static moduledata_t ieee80211_mod = { 1032 "wlan", 1033 ieee80211_modevent, 1034 0 1035 }; 1036 DECLARE_MODULE(wlan, ieee80211_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 1037 MODULE_VERSION(wlan, 1); 1038 MODULE_DEPEND(wlan, rc4, 1, 1, 1); 1039 MODULE_DEPEND(wlan, ether, 1, 1, 1); 1040 #endif 1041