1 /* $NetBSD: ieee80211.c,v 1.9 2004/01/13 23:37: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.8 2003/09/14 22:32:18 sam Exp $"); 37 #else 38 __KERNEL_RCSID(0, "$NetBSD: ieee80211.c,v 1.9 2004/01/13 23:37: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 __FreeBSD__ 95 SYSCTL_INT(_debug, OID_AUTO, ieee80211, CTLFLAG_RW, &ieee80211_debug, 96 0, "IEEE 802.11 media debugging printfs"); 97 #endif 98 #endif 99 100 static void ieee80211_set11gbasicrates(struct ieee80211_rateset *, 101 enum ieee80211_phymode); 102 103 static const char * 104 ieee80211_phymode_name(enum ieee80211_phymode mode) 105 { 106 int i; 107 struct { 108 enum ieee80211_phymode mode; 109 const char *name; 110 } modenames[] = { 111 { IEEE80211_MODE_AUTO, "auto" }, 112 { IEEE80211_MODE_11A, "11a" }, 113 { IEEE80211_MODE_11B, "11b" }, 114 { IEEE80211_MODE_11G, "11g" }, 115 { IEEE80211_MODE_FH, "FH" }, 116 { IEEE80211_MODE_TURBO, "turbo" } 117 }; 118 for (i = 0; i < sizeof(modenames) / sizeof(modenames[0]); i++) { 119 if (mode == modenames[i].mode) 120 return modenames[i].name; 121 } 122 return "<unknown>"; 123 } 124 125 void 126 ieee80211_ifattach(struct ifnet *ifp) 127 { 128 struct ieee80211com *ic = (void *)ifp; 129 struct ieee80211_channel *c; 130 int i; 131 132 ether_ifattach(ifp, ic->ic_myaddr); 133 #if NBPFILTER > 0 134 bpfattach2(ifp, DLT_IEEE802_11, 135 sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf); 136 #endif 137 ieee80211_crypto_attach(ifp); 138 139 /* 140 * Fill in 802.11 available channel set, mark 141 * all available channels as active, and pick 142 * a default channel if not already specified. 143 */ 144 memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail)); 145 ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO; 146 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { 147 c = &ic->ic_channels[i]; 148 if (c->ic_flags) { 149 /* 150 * Verify driver passed us valid data. 151 */ 152 if (i != ieee80211_chan2ieee(ic, c)) { 153 if_printf(ifp, "bad channel ignored; " 154 "freq %u flags %x number %u\n", 155 c->ic_freq, c->ic_flags, i); 156 c->ic_flags = 0; /* NB: remove */ 157 continue; 158 } 159 setbit(ic->ic_chan_avail, i); 160 /* 161 * Identify mode capabilities. 162 */ 163 if (IEEE80211_IS_CHAN_A(c)) 164 ic->ic_modecaps |= 1<<IEEE80211_MODE_11A; 165 if (IEEE80211_IS_CHAN_B(c)) 166 ic->ic_modecaps |= 1<<IEEE80211_MODE_11B; 167 if (IEEE80211_IS_CHAN_PUREG(c)) 168 ic->ic_modecaps |= 1<<IEEE80211_MODE_11G; 169 if (IEEE80211_IS_CHAN_FHSS(c)) 170 ic->ic_modecaps |= 1<<IEEE80211_MODE_FH; 171 if (IEEE80211_IS_CHAN_T(c)) 172 ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO; 173 } 174 } 175 /* validate ic->ic_curmode */ 176 if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0) 177 ic->ic_curmode = IEEE80211_MODE_AUTO; 178 179 (void) ieee80211_setmode(ic, ic->ic_curmode); 180 181 ic->ic_des_chan = IEEE80211_CHAN_ANYC; /* any channel is ok */ 182 if (ic->ic_lintval == 0) 183 ic->ic_lintval = 100; /* default sleep */ 184 ic->ic_bmisstimeout = 7*ic->ic_lintval; /* default 7 beacons */ 185 186 ieee80211_node_attach(ifp); 187 ieee80211_proto_attach(ifp); 188 } 189 190 void 191 ieee80211_ifdetach(struct ifnet *ifp) 192 { 193 struct ieee80211com *ic = (void *)ifp; 194 195 ieee80211_proto_detach(ifp); 196 ieee80211_crypto_detach(ifp); 197 ieee80211_node_detach(ifp); 198 #ifdef __FreeBSD__ 199 ifmedia_removeall(&ic->ic_media); 200 #else 201 ifmedia_delete_instance(&ic->ic_media, IFM_INST_ANY); 202 #endif 203 #if NBPFILTER > 0 204 bpfdetach(ifp); 205 #endif 206 ether_ifdetach(ifp); 207 } 208 209 /* 210 * Convert MHz frequency to IEEE channel number. 211 */ 212 u_int 213 ieee80211_mhz2ieee(u_int freq, u_int flags) 214 { 215 if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */ 216 if (freq == 2484) 217 return 14; 218 if (freq < 2484) 219 return (freq - 2407) / 5; 220 else 221 return 15 + ((freq - 2512) / 20); 222 } else if (flags & IEEE80211_CHAN_5GHZ) { /* 5Ghz band */ 223 return (freq - 5000) / 5; 224 } else { /* either, guess */ 225 if (freq == 2484) 226 return 14; 227 if (freq < 2484) 228 return (freq - 2407) / 5; 229 if (freq < 5000) 230 return 15 + ((freq - 2512) / 20); 231 return (freq - 5000) / 5; 232 } 233 } 234 235 /* 236 * Convert channel to IEEE channel number. 237 */ 238 u_int 239 ieee80211_chan2ieee(struct ieee80211com *ic, struct ieee80211_channel *c) 240 { 241 if (ic->ic_channels <= c && c <= &ic->ic_channels[IEEE80211_CHAN_MAX]) 242 return c - ic->ic_channels; 243 else if (c == IEEE80211_CHAN_ANYC) 244 return IEEE80211_CHAN_ANY; 245 else if (c != NULL) { 246 if_printf(&ic->ic_if, "invalid channel freq %u flags %x\n", 247 c->ic_freq, c->ic_flags); 248 return 0; /* XXX */ 249 } else { 250 if_printf(&ic->ic_if, "invalid channel (NULL)\n"); 251 return 0; /* XXX */ 252 } 253 } 254 255 /* 256 * Convert IEEE channel number to MHz frequency. 257 */ 258 u_int 259 ieee80211_ieee2mhz(u_int chan, u_int flags) 260 { 261 if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */ 262 if (chan == 14) 263 return 2484; 264 if (chan < 14) 265 return 2407 + chan*5; 266 else 267 return 2512 + ((chan-15)*20); 268 } else if (flags & IEEE80211_CHAN_5GHZ) {/* 5Ghz band */ 269 return 5000 + (chan*5); 270 } else { /* either, guess */ 271 if (chan == 14) 272 return 2484; 273 if (chan < 14) /* 0-13 */ 274 return 2407 + chan*5; 275 if (chan < 27) /* 15-26 */ 276 return 2512 + ((chan-15)*20); 277 return 5000 + (chan*5); 278 } 279 } 280 281 /* 282 * Setup the media data structures according to the channel and 283 * rate tables. This must be called by the driver after 284 * ieee80211_attach and before most anything else. 285 */ 286 void 287 ieee80211_media_init(struct ifnet *ifp, 288 ifm_change_cb_t media_change, ifm_stat_cb_t media_stat) 289 { 290 #define ADD(_ic, _s, _o) \ 291 ifmedia_add(&(_ic)->ic_media, \ 292 IFM_MAKEWORD(IFM_IEEE80211, (_s), (_o), 0), 0, NULL) 293 struct ieee80211com *ic = (void *)ifp; 294 struct ifmediareq imr; 295 int i, j, mode, rate, maxrate, mword, mopt, r; 296 struct ieee80211_rateset *rs; 297 struct ieee80211_rateset allrates; 298 299 /* 300 * Do late attach work that must wait for any subclass 301 * (i.e. driver) work such as overriding methods. 302 */ 303 ieee80211_node_lateattach(ifp); 304 305 /* 306 * Fill in media characteristics. 307 */ 308 ifmedia_init(&ic->ic_media, 0, media_change, media_stat); 309 maxrate = 0; 310 memset(&allrates, 0, sizeof(allrates)); 311 for (mode = IEEE80211_MODE_AUTO; mode < IEEE80211_MODE_MAX; mode++) { 312 static const u_int mopts[] = { 313 IFM_AUTO, 314 IFM_IEEE80211_11A, 315 IFM_IEEE80211_11B, 316 IFM_IEEE80211_11G, 317 IFM_IEEE80211_FH, 318 IFM_IEEE80211_11A | IFM_IEEE80211_TURBO, 319 }; 320 if ((ic->ic_modecaps & (1<<mode)) == 0) 321 continue; 322 mopt = mopts[mode]; 323 ADD(ic, IFM_AUTO, mopt); /* e.g. 11a auto */ 324 if (ic->ic_caps & IEEE80211_C_IBSS) 325 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_ADHOC); 326 if (ic->ic_caps & IEEE80211_C_HOSTAP) 327 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_HOSTAP); 328 if (ic->ic_caps & IEEE80211_C_AHDEMO) 329 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_ADHOC | IFM_FLAG0); 330 if (ic->ic_caps & IEEE80211_C_MONITOR) 331 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_MONITOR); 332 if (mode == IEEE80211_MODE_AUTO) 333 continue; 334 if_printf(ifp, "%s rates: ", ieee80211_phymode_name(mode)); 335 rs = &ic->ic_sup_rates[mode]; 336 for (i = 0; i < rs->rs_nrates; i++) { 337 rate = rs->rs_rates[i]; 338 mword = ieee80211_rate2media(ic, rate, mode); 339 if (mword == 0) 340 continue; 341 printf("%s%d%sMbps", (i != 0 ? " " : ""), 342 (rate & IEEE80211_RATE_VAL) / 2, 343 ((rate & 0x1) != 0 ? ".5" : "")); 344 ADD(ic, mword, mopt); 345 if (ic->ic_caps & IEEE80211_C_IBSS) 346 ADD(ic, mword, mopt | IFM_IEEE80211_ADHOC); 347 if (ic->ic_caps & IEEE80211_C_HOSTAP) 348 ADD(ic, mword, mopt | IFM_IEEE80211_HOSTAP); 349 if (ic->ic_caps & IEEE80211_C_AHDEMO) 350 ADD(ic, mword, mopt | IFM_IEEE80211_ADHOC | IFM_FLAG0); 351 if (ic->ic_caps & IEEE80211_C_MONITOR) 352 ADD(ic, mword, mopt | IFM_IEEE80211_MONITOR); 353 /* 354 * Add rate to the collection of all rates. 355 */ 356 r = rate & IEEE80211_RATE_VAL; 357 for (j = 0; j < allrates.rs_nrates; j++) 358 if (allrates.rs_rates[j] == r) 359 break; 360 if (j == allrates.rs_nrates) { 361 /* unique, add to the set */ 362 allrates.rs_rates[j] = r; 363 allrates.rs_nrates++; 364 } 365 rate = (rate & IEEE80211_RATE_VAL) / 2; 366 if (rate > maxrate) 367 maxrate = rate; 368 } 369 printf("\n"); 370 } 371 for (i = 0; i < allrates.rs_nrates; i++) { 372 mword = ieee80211_rate2media(ic, allrates.rs_rates[i], 373 IEEE80211_MODE_AUTO); 374 if (mword == 0) 375 continue; 376 mword = IFM_SUBTYPE(mword); /* remove media options */ 377 ADD(ic, mword, 0); 378 if (ic->ic_caps & IEEE80211_C_IBSS) 379 ADD(ic, mword, IFM_IEEE80211_ADHOC); 380 if (ic->ic_caps & IEEE80211_C_HOSTAP) 381 ADD(ic, mword, IFM_IEEE80211_HOSTAP); 382 if (ic->ic_caps & IEEE80211_C_AHDEMO) 383 ADD(ic, mword, IFM_IEEE80211_ADHOC | IFM_FLAG0); 384 if (ic->ic_caps & IEEE80211_C_MONITOR) 385 ADD(ic, mword, IFM_IEEE80211_MONITOR); 386 } 387 ieee80211_media_status(ifp, &imr); 388 ifmedia_set(&ic->ic_media, imr.ifm_active); 389 390 if (maxrate) 391 ifp->if_baudrate = IF_Mbps(maxrate); 392 393 if (ic->ic_max_aid == 0) 394 ic->ic_max_aid = IEEE80211_MAX_AID; 395 396 #undef ADD 397 } 398 399 static int 400 findrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate) 401 { 402 #define IEEERATE(_ic,_m,_i) \ 403 ((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL) 404 int i, nrates = ic->ic_sup_rates[mode].rs_nrates; 405 for (i = 0; i < nrates; i++) 406 if (IEEERATE(ic, mode, i) == rate) 407 return i; 408 return -1; 409 #undef IEEERATE 410 } 411 412 /* 413 * Handle a media change request. 414 */ 415 int 416 ieee80211_media_change(struct ifnet *ifp) 417 { 418 struct ieee80211com *ic = (void *)ifp; 419 struct ifmedia_entry *ime; 420 enum ieee80211_opmode newopmode; 421 enum ieee80211_phymode newphymode; 422 int i, j, newrate, error = 0; 423 424 ime = ic->ic_media.ifm_cur; 425 /* 426 * First, identify the phy mode. 427 */ 428 switch (IFM_MODE(ime->ifm_media)) { 429 case IFM_IEEE80211_11A: 430 newphymode = IEEE80211_MODE_11A; 431 break; 432 case IFM_IEEE80211_11B: 433 newphymode = IEEE80211_MODE_11B; 434 break; 435 case IFM_IEEE80211_11G: 436 newphymode = IEEE80211_MODE_11G; 437 break; 438 case IFM_IEEE80211_FH: 439 newphymode = IEEE80211_MODE_FH; 440 break; 441 case IFM_AUTO: 442 newphymode = IEEE80211_MODE_AUTO; 443 break; 444 default: 445 return EINVAL; 446 } 447 /* 448 * Turbo mode is an ``option''. Eventually it 449 * needs to be applied to 11g too. 450 */ 451 if (ime->ifm_media & IFM_IEEE80211_TURBO) { 452 if (newphymode != IEEE80211_MODE_11A) 453 return EINVAL; 454 newphymode = IEEE80211_MODE_TURBO; 455 } 456 /* 457 * Validate requested mode is available. 458 */ 459 if ((ic->ic_modecaps & (1<<newphymode)) == 0) 460 return EINVAL; 461 462 /* 463 * Next, the fixed/variable rate. 464 */ 465 i = -1; 466 if (IFM_SUBTYPE(ime->ifm_media) != IFM_AUTO) { 467 /* 468 * Convert media subtype to rate. 469 */ 470 newrate = ieee80211_media2rate(ime->ifm_media); 471 if (newrate == 0) 472 return EINVAL; 473 /* 474 * Check the rate table for the specified/current phy. 475 */ 476 if (newphymode == IEEE80211_MODE_AUTO) { 477 /* 478 * In autoselect mode search for the rate. 479 */ 480 for (j = IEEE80211_MODE_11A; 481 j < IEEE80211_MODE_MAX; j++) { 482 if ((ic->ic_modecaps & (1<<j)) == 0) 483 continue; 484 i = findrate(ic, j, newrate); 485 if (i != -1) { 486 /* lock mode too */ 487 newphymode = j; 488 break; 489 } 490 } 491 } else { 492 i = findrate(ic, newphymode, newrate); 493 } 494 if (i == -1) /* mode/rate mismatch */ 495 return EINVAL; 496 } 497 /* NB: defer rate setting to later */ 498 499 /* 500 * Deduce new operating mode but don't install it just yet. 501 */ 502 if ((ime->ifm_media & (IFM_IEEE80211_ADHOC|IFM_FLAG0)) == 503 (IFM_IEEE80211_ADHOC|IFM_FLAG0)) 504 newopmode = IEEE80211_M_AHDEMO; 505 else if (ime->ifm_media & IFM_IEEE80211_HOSTAP) 506 newopmode = IEEE80211_M_HOSTAP; 507 else if (ime->ifm_media & IFM_IEEE80211_ADHOC) 508 newopmode = IEEE80211_M_IBSS; 509 else if (ime->ifm_media & IFM_IEEE80211_MONITOR) 510 newopmode = IEEE80211_M_MONITOR; 511 else 512 newopmode = IEEE80211_M_STA; 513 514 /* 515 * Autoselect doesn't make sense when operating as an AP. 516 * If no phy mode has been selected, pick one and lock it 517 * down so rate tables can be used in forming beacon frames 518 * and the like. 519 */ 520 if (newopmode == IEEE80211_M_HOSTAP && 521 newphymode == IEEE80211_MODE_AUTO) { 522 for (j = IEEE80211_MODE_11A; j < IEEE80211_MODE_MAX; j++) 523 if (ic->ic_modecaps & (1<<j)) { 524 newphymode = j; 525 break; 526 } 527 } 528 529 /* 530 * Handle phy mode change. 531 */ 532 if (ic->ic_curmode != newphymode) { /* change phy mode */ 533 error = ieee80211_setmode(ic, newphymode); 534 if (error != 0) 535 return error; 536 error = ENETRESET; 537 } 538 539 /* 540 * Committed to changes, install the rate setting. 541 */ 542 if (ic->ic_fixed_rate != i) { 543 ic->ic_fixed_rate = i; /* set fixed tx rate */ 544 error = ENETRESET; 545 } 546 547 /* 548 * Handle operating mode change. 549 */ 550 if (ic->ic_opmode != newopmode) { 551 ic->ic_opmode = newopmode; 552 switch (newopmode) { 553 case IEEE80211_M_AHDEMO: 554 case IEEE80211_M_HOSTAP: 555 case IEEE80211_M_STA: 556 case IEEE80211_M_MONITOR: 557 ic->ic_flags &= ~IEEE80211_F_IBSSON; 558 break; 559 case IEEE80211_M_IBSS: 560 ic->ic_flags |= IEEE80211_F_IBSSON; 561 #ifdef notdef 562 if (ic->ic_curmode == IEEE80211_MODE_11G) 563 ieee80211_set11gbasicrates( 564 &ic->ic_suprates[newphymode], 565 IEEE80211_MODE_11B); 566 #endif 567 break; 568 } 569 error = ENETRESET; 570 } 571 #ifdef notdef 572 if (error == 0) 573 ifp->if_baudrate = ifmedia_baudrate(ime->ifm_media); 574 #endif 575 return error; 576 } 577 578 void 579 ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr) 580 { 581 struct ieee80211com *ic = (void *)ifp; 582 struct ieee80211_node *ni = NULL; 583 584 imr->ifm_status = IFM_AVALID; 585 imr->ifm_active = IFM_IEEE80211; 586 if (ic->ic_state == IEEE80211_S_RUN) 587 imr->ifm_status |= IFM_ACTIVE; 588 imr->ifm_active |= IFM_AUTO; 589 switch (ic->ic_opmode) { 590 case IEEE80211_M_STA: 591 ni = ic->ic_bss; 592 /* calculate rate subtype */ 593 imr->ifm_active |= ieee80211_rate2media(ic, 594 ni->ni_rates.rs_rates[ni->ni_txrate], ic->ic_curmode); 595 break; 596 case IEEE80211_M_IBSS: 597 imr->ifm_active |= IFM_IEEE80211_ADHOC; 598 break; 599 case IEEE80211_M_AHDEMO: 600 /* should not come here */ 601 break; 602 case IEEE80211_M_HOSTAP: 603 imr->ifm_active |= IFM_IEEE80211_HOSTAP; 604 break; 605 case IEEE80211_M_MONITOR: 606 imr->ifm_active |= IFM_IEEE80211_MONITOR; 607 break; 608 } 609 switch (ic->ic_curmode) { 610 case IEEE80211_MODE_11A: 611 imr->ifm_active |= IFM_IEEE80211_11A; 612 break; 613 case IEEE80211_MODE_11B: 614 imr->ifm_active |= IFM_IEEE80211_11B; 615 break; 616 case IEEE80211_MODE_11G: 617 imr->ifm_active |= IFM_IEEE80211_11G; 618 break; 619 case IEEE80211_MODE_FH: 620 imr->ifm_active |= IFM_IEEE80211_FH; 621 break; 622 case IEEE80211_MODE_TURBO: 623 imr->ifm_active |= IFM_IEEE80211_11A 624 | IFM_IEEE80211_TURBO; 625 break; 626 } 627 } 628 629 void 630 ieee80211_watchdog(struct ifnet *ifp) 631 { 632 struct ieee80211com *ic = (void *)ifp; 633 634 if (ic->ic_mgt_timer && --ic->ic_mgt_timer == 0) 635 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 636 if (ic->ic_inact_timer && --ic->ic_inact_timer == 0) 637 ieee80211_timeout_nodes(ic); 638 639 if (ic->ic_mgt_timer != 0 || ic->ic_inact_timer != 0) 640 ifp->if_timer = 1; 641 } 642 643 /* 644 * Mark the basic rates for the 11g rate table based on the 645 * operating mode. For real 11g we mark all the 11b rates 646 * and 6, 12, and 24 OFDM. For 11b compatibility we mark only 647 * 11b rates. There's also a pseudo 11a-mode used to mark only 648 * the basic OFDM rates. 649 */ 650 static void 651 ieee80211_set11gbasicrates(struct ieee80211_rateset *rs, enum ieee80211_phymode mode) 652 { 653 static const struct ieee80211_rateset basic[] = { 654 { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_11A */ 655 { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_11B */ 656 { 7, { 2, 4, 11, 22, 12, 24, 48 } },/* IEEE80211_MODE_11G */ 657 { 0 }, /* IEEE80211_MODE_FH */ 658 { 0 }, /* IEEE80211_MODE_TURBO */ 659 }; 660 int i, j; 661 662 for (i = 0; i < rs->rs_nrates; i++) { 663 rs->rs_rates[i] &= IEEE80211_RATE_VAL; 664 for (j = 0; j < basic[mode].rs_nrates; j++) 665 if (basic[mode].rs_rates[j] == rs->rs_rates[i]) { 666 rs->rs_rates[i] |= IEEE80211_RATE_BASIC; 667 break; 668 } 669 } 670 } 671 672 /* 673 * Set the current phy mode and recalculate the active channel 674 * set based on the available channels for this mode. Also 675 * select a new default/current channel if the current one is 676 * inappropriate for this mode. 677 */ 678 int 679 ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode) 680 { 681 #define N(a) (sizeof(a) / sizeof(a[0])) 682 static const u_int chanflags[] = { 683 0, /* IEEE80211_MODE_AUTO */ 684 IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ 685 IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ 686 IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ 687 IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ 688 IEEE80211_CHAN_T, /* IEEE80211_MODE_TURBO */ 689 }; 690 struct ieee80211_channel *c; 691 u_int modeflags; 692 int i; 693 694 /* validate new mode */ 695 if ((ic->ic_modecaps & (1<<mode)) == 0) { 696 IEEE80211_DPRINTF(("%s: mode %u not supported (caps 0x%x)\n", 697 __func__, mode, ic->ic_modecaps)); 698 return EINVAL; 699 } 700 701 /* 702 * Verify at least one channel is present in the available 703 * channel list before committing to the new mode. 704 */ 705 IASSERT(mode < N(chanflags), ("Unexpected mode %u\n", mode)); 706 modeflags = chanflags[mode]; 707 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { 708 c = &ic->ic_channels[i]; 709 if (mode == IEEE80211_MODE_AUTO) { 710 /* ignore turbo channels for autoselect */ 711 if ((c->ic_flags &~ IEEE80211_CHAN_TURBO) != 0) 712 break; 713 } else { 714 if ((c->ic_flags & modeflags) == modeflags) 715 break; 716 } 717 } 718 if (i > IEEE80211_CHAN_MAX) { 719 IEEE80211_DPRINTF(("%s: no channels found for mode %u\n", 720 __func__, mode)); 721 return EINVAL; 722 } 723 724 /* 725 * Calculate the active channel set. 726 */ 727 memset(ic->ic_chan_active, 0, sizeof(ic->ic_chan_active)); 728 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { 729 c = &ic->ic_channels[i]; 730 if (mode == IEEE80211_MODE_AUTO) { 731 /* take anything but pure turbo channels */ 732 if ((c->ic_flags &~ IEEE80211_CHAN_TURBO) != 0) 733 setbit(ic->ic_chan_active, i); 734 } else { 735 if ((c->ic_flags & modeflags) == modeflags) 736 setbit(ic->ic_chan_active, i); 737 } 738 } 739 /* 740 * If no current/default channel is setup or the current 741 * channel is wrong for the mode then pick the first 742 * available channel from the active list. This is likely 743 * not the right one. 744 */ 745 if (ic->ic_ibss_chan == NULL || 746 isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) { 747 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) 748 if (isset(ic->ic_chan_active, i)) { 749 ic->ic_ibss_chan = &ic->ic_channels[i]; 750 break; 751 } 752 IASSERT(ic->ic_ibss_chan != NULL && 753 isset(ic->ic_chan_active, 754 ieee80211_chan2ieee(ic, ic->ic_ibss_chan)), 755 ("Bad IBSS channel %u\n", 756 ieee80211_chan2ieee(ic, ic->ic_ibss_chan))); 757 } 758 759 /* 760 * Set/reset state flags that influence beacon contents, etc. 761 * 762 * XXX what if we have stations already associated??? 763 * XXX probably not right for autoselect? 764 */ 765 if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) 766 ic->ic_flags |= IEEE80211_F_SHPREAMBLE; 767 if (mode == IEEE80211_MODE_11G) { 768 if (ic->ic_caps & IEEE80211_C_SHSLOT) 769 ic->ic_flags |= IEEE80211_F_SHSLOT; 770 ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode], 771 IEEE80211_MODE_11G); 772 } else { 773 ic->ic_flags &= ~IEEE80211_F_SHSLOT; 774 } 775 776 ic->ic_curmode = mode; 777 return 0; 778 #undef N 779 } 780 781 /* 782 * Return the phy mode for with the specified channel so the 783 * caller can select a rate set. This is problematic and the 784 * work here assumes how things work elsewhere in this code. 785 * 786 * XXX never returns turbo modes -dcy 787 */ 788 enum ieee80211_phymode 789 ieee80211_chan2mode(struct ieee80211com *ic, struct ieee80211_channel *chan) 790 { 791 /* 792 * NB: this assumes the channel would not be supplied to us 793 * unless it was already compatible with the current mode. 794 */ 795 if (ic->ic_curmode != IEEE80211_MODE_AUTO) 796 return ic->ic_curmode; 797 /* 798 * In autoselect mode; deduce a mode based on the channel 799 * characteristics. We assume that turbo-only channels 800 * are not considered when the channel set is constructed. 801 */ 802 if (IEEE80211_IS_CHAN_5GHZ(chan)) 803 return IEEE80211_MODE_11A; 804 else if (IEEE80211_IS_CHAN_FHSS(chan)) 805 return IEEE80211_MODE_FH; 806 else if (chan->ic_flags & (IEEE80211_CHAN_OFDM|IEEE80211_CHAN_DYN)) 807 return IEEE80211_MODE_11G; 808 else 809 return IEEE80211_MODE_11B; 810 } 811 812 /* 813 * convert IEEE80211 rate value to ifmedia subtype. 814 * ieee80211 rate is in unit of 0.5Mbps. 815 */ 816 int 817 ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode mode) 818 { 819 #define N(a) (sizeof(a) / sizeof(a[0])) 820 static const struct { 821 u_int m; /* rate + mode */ 822 u_int r; /* if_media rate */ 823 } rates[] = { 824 { 2 | IFM_IEEE80211_FH, IFM_IEEE80211_FH1 }, 825 { 4 | IFM_IEEE80211_FH, IFM_IEEE80211_FH2 }, 826 { 2 | IFM_IEEE80211_11B, IFM_IEEE80211_DS1 }, 827 { 4 | IFM_IEEE80211_11B, IFM_IEEE80211_DS2 }, 828 { 11 | IFM_IEEE80211_11B, IFM_IEEE80211_DS5 }, 829 { 22 | IFM_IEEE80211_11B, IFM_IEEE80211_DS11 }, 830 { 44 | IFM_IEEE80211_11B, IFM_IEEE80211_DS22 }, 831 { 12 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM6 }, 832 { 18 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM9 }, 833 { 24 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM12 }, 834 { 36 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM18 }, 835 { 48 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM24 }, 836 { 72 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM36 }, 837 { 96 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM48 }, 838 { 108 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM54 }, 839 { 2 | IFM_IEEE80211_11G, IFM_IEEE80211_DS1 }, 840 { 4 | IFM_IEEE80211_11G, IFM_IEEE80211_DS2 }, 841 { 11 | IFM_IEEE80211_11G, IFM_IEEE80211_DS5 }, 842 { 22 | IFM_IEEE80211_11G, IFM_IEEE80211_DS11 }, 843 { 12 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM6 }, 844 { 18 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM9 }, 845 { 24 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM12 }, 846 { 36 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM18 }, 847 { 48 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM24 }, 848 { 72 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM36 }, 849 { 96 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM48 }, 850 { 108 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM54 }, 851 /* NB: OFDM72 doesn't realy exist so we don't handle it */ 852 }; 853 u_int mask, i; 854 855 mask = rate & IEEE80211_RATE_VAL; 856 switch (mode) { 857 case IEEE80211_MODE_11A: 858 case IEEE80211_MODE_TURBO: 859 mask |= IFM_IEEE80211_11A; 860 break; 861 case IEEE80211_MODE_11B: 862 mask |= IFM_IEEE80211_11B; 863 break; 864 case IEEE80211_MODE_FH: 865 mask |= IFM_IEEE80211_FH; 866 break; 867 case IEEE80211_MODE_11G: 868 mask |= IFM_IEEE80211_11G; 869 break; 870 case IEEE80211_MODE_AUTO: 871 switch (ic->ic_phytype) { 872 case IEEE80211_T_FH: 873 mask |= IFM_IEEE80211_FH; 874 break; 875 case IEEE80211_T_DS: 876 mask |= IFM_IEEE80211_11B; 877 break; 878 case IEEE80211_T_OFDM: 879 case IEEE80211_T_TURBO: 880 mask |= IFM_IEEE80211_11G; 881 break; 882 } 883 } 884 for (i = 0; i < N(rates); i++) 885 if (rates[i].m == mask) 886 return rates[i].r; 887 return IFM_AUTO; 888 #undef N 889 } 890 891 int 892 ieee80211_media2rate(int mword) 893 { 894 #define N(a) (sizeof(a) / sizeof(a[0])) 895 int i; 896 static const struct { 897 int subtype; 898 int rate; 899 } ieeerates[] = { 900 { IFM_AUTO, -1 }, 901 { IFM_MANUAL, 0 }, 902 { IFM_NONE, 0 }, 903 { IFM_IEEE80211_FH1, 2 }, 904 { IFM_IEEE80211_FH2, 4 }, 905 { IFM_IEEE80211_DS1, 2 }, 906 { IFM_IEEE80211_DS2, 4 }, 907 { IFM_IEEE80211_DS5, 11 }, 908 { IFM_IEEE80211_DS11, 22 }, 909 { IFM_IEEE80211_DS22, 44 }, 910 { IFM_IEEE80211_OFDM6, 12 }, 911 { IFM_IEEE80211_OFDM9, 18 }, 912 { IFM_IEEE80211_OFDM12, 24 }, 913 { IFM_IEEE80211_OFDM18, 36 }, 914 { IFM_IEEE80211_OFDM24, 48 }, 915 { IFM_IEEE80211_OFDM36, 72 }, 916 { IFM_IEEE80211_OFDM48, 96 }, 917 { IFM_IEEE80211_OFDM54, 108 }, 918 { IFM_IEEE80211_OFDM72, 144 }, 919 }; 920 for (i = 0; i < N(ieeerates); i++) { 921 if (ieeerates[i].subtype == IFM_SUBTYPE(mword)) 922 return ieeerates[i].rate; 923 } 924 return 0; 925 #undef N 926 } 927 928 #ifdef __FreeBSD__ 929 /* 930 * Module glue. 931 * 932 * NB: the module name is "wlan" for compatibility with NetBSD. 933 */ 934 935 static int 936 ieee80211_modevent(module_t mod, int type, void *unused) 937 { 938 switch (type) { 939 case MOD_LOAD: 940 if (bootverbose) 941 printf("wlan: <802.11 Link Layer>\n"); 942 return 0; 943 case MOD_UNLOAD: 944 return 0; 945 } 946 return EINVAL; 947 } 948 949 static moduledata_t ieee80211_mod = { 950 "wlan", 951 ieee80211_modevent, 952 0 953 }; 954 DECLARE_MODULE(wlan, ieee80211_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 955 MODULE_VERSION(wlan, 1); 956 MODULE_DEPEND(wlan, rc4, 1, 1, 1); 957 #endif 958