1 /* $OpenBSD: ieee80211.c,v 1.89 2024/02/15 15:40:56 stsp Exp $ */ 2 /* $NetBSD: ieee80211.c,v 1.19 2004/06/06 05:45:29 dyoung Exp $ */ 3 4 /*- 5 * Copyright (c) 2001 Atsushi Onoe 6 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * IEEE 802.11 generic handler 34 */ 35 36 #include "bpfilter.h" 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/mbuf.h> 41 #include <sys/kernel.h> 42 #include <sys/socket.h> 43 #include <sys/sockio.h> 44 #include <sys/endian.h> 45 #include <sys/errno.h> 46 #include <sys/sysctl.h> 47 #ifdef __HAIKU__ 48 #include <sys/task.h> 49 #endif 50 51 #include <net/if.h> 52 #include <net/if_dl.h> 53 #include <net/if_media.h> 54 55 #if NBPFILTER > 0 56 #include <net/bpf.h> 57 #endif 58 59 #include <netinet/in.h> 60 #include <netinet/if_ether.h> 61 62 #include <net80211/ieee80211_var.h> 63 #include <net80211/ieee80211_priv.h> 64 65 #ifdef IEEE80211_DEBUG 66 int ieee80211_debug = 0; 67 #endif 68 69 int ieee80211_cache_size = IEEE80211_CACHE_SIZE; 70 71 void ieee80211_setbasicrates(struct ieee80211com *); 72 int ieee80211_findrate(struct ieee80211com *, enum ieee80211_phymode, int); 73 void ieee80211_configure_ampdu_tx(struct ieee80211com *, int); 74 75 void 76 ieee80211_begin_bgscan(struct ifnet *ifp) 77 { 78 struct ieee80211com *ic = (void *)ifp; 79 80 if ((ic->ic_flags & IEEE80211_F_BGSCAN) || 81 ic->ic_state != IEEE80211_S_RUN || ic->ic_mgt_timer != 0) 82 return; 83 84 if ((ic->ic_flags & IEEE80211_F_RSNON) && !ic->ic_bss->ni_port_valid) 85 return; 86 87 if (ic->ic_bgscan_start != NULL && ic->ic_bgscan_start(ic) == 0) { 88 /* 89 * Free the nodes table to ensure we get an up-to-date view 90 * of APs around us. In particular, we need to kick out the 91 * AP we are associated to. Otherwise, our current AP might 92 * stay cached if it is turned off while we are scanning, and 93 * we could end up picking a now non-existent AP over and over. 94 */ 95 ieee80211_free_allnodes(ic, 0 /* keep ic->ic_bss */); 96 97 ic->ic_flags |= IEEE80211_F_BGSCAN; 98 if (ifp->if_flags & IFF_DEBUG) 99 printf("%s: begin background scan\n", ifp->if_xname); 100 101 /* Driver calls ieee80211_end_scan() when done. */ 102 } 103 } 104 105 void 106 ieee80211_bgscan_timeout(void *arg) 107 { 108 struct ifnet *ifp = arg; 109 110 ieee80211_begin_bgscan(ifp); 111 } 112 113 void 114 ieee80211_channel_init(struct ifnet *ifp) 115 { 116 struct ieee80211com *ic = (void *)ifp; 117 struct ieee80211_channel *c; 118 int i; 119 120 /* 121 * Fill in 802.11 available channel set, mark 122 * all available channels as active, and pick 123 * a default channel if not already specified. 124 */ 125 memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail)); 126 ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO; 127 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { 128 c = &ic->ic_channels[i]; 129 if (c->ic_flags) { 130 /* 131 * Verify driver passed us valid data. 132 */ 133 if (i != ieee80211_chan2ieee(ic, c)) { 134 printf("%s: bad channel ignored; " 135 "freq %u flags %x number %u\n", 136 ifp->if_xname, c->ic_freq, c->ic_flags, 137 i); 138 c->ic_flags = 0; /* NB: remove */ 139 continue; 140 } 141 setbit(ic->ic_chan_avail, i); 142 /* 143 * Identify mode capabilities. 144 */ 145 if (IEEE80211_IS_CHAN_A(c)) 146 ic->ic_modecaps |= 1<<IEEE80211_MODE_11A; 147 if (IEEE80211_IS_CHAN_B(c)) 148 ic->ic_modecaps |= 1<<IEEE80211_MODE_11B; 149 if (IEEE80211_IS_CHAN_PUREG(c)) 150 ic->ic_modecaps |= 1<<IEEE80211_MODE_11G; 151 if (IEEE80211_IS_CHAN_N(c)) 152 ic->ic_modecaps |= 1<<IEEE80211_MODE_11N; 153 if (IEEE80211_IS_CHAN_AC(c)) 154 ic->ic_modecaps |= 1<<IEEE80211_MODE_11AC; 155 } 156 } 157 /* validate ic->ic_curmode */ 158 if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0) 159 ic->ic_curmode = IEEE80211_MODE_AUTO; 160 ic->ic_des_chan = IEEE80211_CHAN_ANYC; /* any channel is ok */ 161 } 162 163 void 164 ieee80211_ifattach(struct ifnet *ifp) 165 { 166 struct ieee80211com *ic = (void *)ifp; 167 168 #ifdef __FreeBSD_version 169 ether_ifattach(ifp, ic->ic_myaddr); 170 #else 171 memcpy(((struct arpcom *)ifp)->ac_enaddr, ic->ic_myaddr, 172 ETHER_ADDR_LEN); 173 ether_ifattach(ifp); 174 #endif 175 176 ifp->if_output = ieee80211_output; 177 178 #if NBPFILTER > 0 179 bpfattach(&ic->ic_rawbpf, ifp, DLT_IEEE802_11, 180 sizeof(struct ieee80211_frame_addr4)); 181 #endif 182 ieee80211_crypto_attach(ifp); 183 184 ieee80211_channel_init(ifp); 185 186 /* IEEE 802.11 defines a MTU >= 2290 */ 187 ifp->if_capabilities |= IFCAP_VLAN_MTU; 188 189 ieee80211_setbasicrates(ic); 190 (void)ieee80211_setmode(ic, ic->ic_curmode); 191 192 if (ic->ic_lintval == 0) 193 ic->ic_lintval = 100; /* default sleep */ 194 ic->ic_bmissthres = IEEE80211_BEACON_MISS_THRES; 195 ic->ic_dtim_period = 1; /* all TIMs are DTIMs */ 196 197 ieee80211_node_attach(ifp); 198 ieee80211_proto_attach(ifp); 199 200 #ifndef __FreeBSD_version 201 if_addgroup(ifp, "wlan"); 202 ifp->if_priority = IF_WIRELESS_DEFAULT_PRIORITY; 203 #endif 204 205 task_set(&ic->ic_rtm_80211info_task, ieee80211_rtm_80211info_task, ic); 206 ieee80211_set_link_state(ic, LINK_STATE_DOWN); 207 208 timeout_set(&ic->ic_bgscan_timeout, ieee80211_bgscan_timeout, ifp); 209 } 210 211 void 212 ieee80211_ifdetach(struct ifnet *ifp) 213 { 214 struct ieee80211com *ic = (void *)ifp; 215 216 task_del(systq, &ic->ic_rtm_80211info_task); 217 timeout_del(&ic->ic_bgscan_timeout); 218 219 #ifndef __HAIKU__ 220 /* 221 * Undo pseudo-driver changes. Pseudo-driver detach hooks could 222 * call back into the driver, e.g. via ioctl. So deactivate the 223 * interface before freeing net80211-specific data structures. 224 */ 225 if_deactivate(ifp); 226 #endif 227 228 ieee80211_proto_detach(ifp); 229 ieee80211_crypto_detach(ifp); 230 ieee80211_node_detach(ifp); 231 #ifndef __HAIKU__ 232 ifmedia_delete_instance(&ic->ic_media, IFM_INST_ANY); 233 #endif 234 ether_ifdetach(ifp); 235 } 236 237 /* 238 * Convert MHz frequency to IEEE channel number. 239 */ 240 u_int 241 ieee80211_mhz2ieee(u_int freq, u_int flags) 242 { 243 if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */ 244 if (freq == 2484) 245 return 14; 246 if (freq < 2484) 247 return (freq - 2407) / 5; 248 else 249 return 15 + ((freq - 2512) / 20); 250 } else if (flags & IEEE80211_CHAN_5GHZ) { /* 5GHz band */ 251 return (freq - 5000) / 5; 252 } else { /* either, guess */ 253 if (freq == 2484) 254 return 14; 255 if (freq < 2484) 256 return (freq - 2407) / 5; 257 if (freq < 5000) 258 return 15 + ((freq - 2512) / 20); 259 return (freq - 5000) / 5; 260 } 261 } 262 263 /* 264 * Convert channel to IEEE channel number. 265 */ 266 u_int 267 ieee80211_chan2ieee(struct ieee80211com *ic, const struct ieee80211_channel *c) 268 { 269 struct ifnet *ifp = &ic->ic_if; 270 if (ic->ic_channels <= c && c <= &ic->ic_channels[IEEE80211_CHAN_MAX]) 271 return c - ic->ic_channels; 272 else if (c == IEEE80211_CHAN_ANYC) 273 return IEEE80211_CHAN_ANY; 274 275 panic("%s: bogus channel pointer", ifp->if_xname); 276 } 277 278 /* 279 * Convert IEEE channel number to MHz frequency. 280 */ 281 u_int 282 ieee80211_ieee2mhz(u_int chan, u_int flags) 283 { 284 if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */ 285 if (chan == 14) 286 return 2484; 287 if (chan < 14) 288 return 2407 + chan*5; 289 else 290 return 2512 + ((chan-15)*20); 291 } else if (flags & IEEE80211_CHAN_5GHZ) {/* 5GHz band */ 292 return 5000 + (chan*5); 293 } else { /* either, guess */ 294 if (chan == 14) 295 return 2484; 296 if (chan < 14) /* 0-13 */ 297 return 2407 + chan*5; 298 if (chan < 27) /* 15-26 */ 299 return 2512 + ((chan-15)*20); 300 return 5000 + (chan*5); 301 } 302 } 303 304 void 305 ieee80211_configure_ampdu_tx(struct ieee80211com *ic, int enable) 306 { 307 if ((ic->ic_caps & IEEE80211_C_TX_AMPDU) == 0) 308 return; 309 310 /* Sending AMPDUs requires QoS support. */ 311 if ((ic->ic_caps & IEEE80211_C_QOS) == 0) 312 return; 313 314 if (enable) 315 ic->ic_flags |= IEEE80211_F_QOS; 316 else 317 ic->ic_flags &= ~IEEE80211_F_QOS; 318 } 319 320 /* 321 * Setup the media data structures according to the channel and 322 * rate tables. This must be called by the driver after 323 * ieee80211_attach and before most anything else. 324 */ 325 void 326 ieee80211_media_init(struct ifnet *ifp, 327 ifm_change_cb_t media_change, ifm_stat_cb_t media_stat) 328 { 329 #define ADD(_ic, _s, _o) \ 330 ifmedia_add(&(_ic)->ic_media, \ 331 IFM_MAKEWORD(IFM_IEEE80211, (_s), (_o), 0), 0, NULL) 332 struct ieee80211com *ic = (void *)ifp; 333 struct ifmediareq imr; 334 int i, j, mode, rate, maxrate, r; 335 uint64_t mword, mopt; 336 const struct ieee80211_rateset *rs; 337 struct ieee80211_rateset allrates; 338 339 /* 340 * Do late attach work that must wait for any subclass 341 * (i.e. driver) work such as overriding methods. 342 */ 343 ieee80211_node_lateattach(ifp); 344 345 /* 346 * Fill in media characteristics. 347 */ 348 ifmedia_init(&ic->ic_media, 0, media_change, media_stat); 349 maxrate = 0; 350 memset(&allrates, 0, sizeof(allrates)); 351 for (mode = IEEE80211_MODE_AUTO; mode <= IEEE80211_MODE_11G; mode++) { 352 static const uint64_t mopts[] = { 353 IFM_AUTO, 354 IFM_IEEE80211_11A, 355 IFM_IEEE80211_11B, 356 IFM_IEEE80211_11G, 357 }; 358 if ((ic->ic_modecaps & (1<<mode)) == 0) 359 continue; 360 mopt = mopts[mode]; 361 ADD(ic, IFM_AUTO, mopt); /* e.g. 11a auto */ 362 #ifndef IEEE80211_STA_ONLY 363 if (ic->ic_caps & IEEE80211_C_IBSS) 364 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_IBSS); 365 if (ic->ic_caps & IEEE80211_C_HOSTAP) 366 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_HOSTAP); 367 if (ic->ic_caps & IEEE80211_C_AHDEMO) 368 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_ADHOC); 369 #endif 370 if (ic->ic_caps & IEEE80211_C_MONITOR) 371 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_MONITOR); 372 if (mode == IEEE80211_MODE_AUTO) 373 continue; 374 rs = &ic->ic_sup_rates[mode]; 375 for (i = 0; i < rs->rs_nrates; i++) { 376 rate = rs->rs_rates[i]; 377 mword = ieee80211_rate2media(ic, rate, mode); 378 if (mword == 0) 379 continue; 380 ADD(ic, mword, mopt); 381 #ifndef IEEE80211_STA_ONLY 382 if (ic->ic_caps & IEEE80211_C_IBSS) 383 ADD(ic, mword, mopt | IFM_IEEE80211_IBSS); 384 if (ic->ic_caps & IEEE80211_C_HOSTAP) 385 ADD(ic, mword, mopt | IFM_IEEE80211_HOSTAP); 386 if (ic->ic_caps & IEEE80211_C_AHDEMO) 387 ADD(ic, mword, mopt | IFM_IEEE80211_ADHOC); 388 #endif 389 if (ic->ic_caps & IEEE80211_C_MONITOR) 390 ADD(ic, mword, mopt | IFM_IEEE80211_MONITOR); 391 /* 392 * Add rate to the collection of all rates. 393 */ 394 r = rate & IEEE80211_RATE_VAL; 395 for (j = 0; j < allrates.rs_nrates; j++) 396 if (allrates.rs_rates[j] == r) 397 break; 398 if (j == allrates.rs_nrates) { 399 /* unique, add to the set */ 400 allrates.rs_rates[j] = r; 401 allrates.rs_nrates++; 402 } 403 rate = (rate & IEEE80211_RATE_VAL) / 2; 404 if (rate > maxrate) 405 maxrate = rate; 406 } 407 } 408 for (i = 0; i < allrates.rs_nrates; i++) { 409 mword = ieee80211_rate2media(ic, allrates.rs_rates[i], 410 IEEE80211_MODE_AUTO); 411 if (mword == 0) 412 continue; 413 mword = IFM_SUBTYPE(mword); /* remove media options */ 414 ADD(ic, mword, 0); 415 #ifndef IEEE80211_STA_ONLY 416 if (ic->ic_caps & IEEE80211_C_IBSS) 417 ADD(ic, mword, IFM_IEEE80211_IBSS); 418 if (ic->ic_caps & IEEE80211_C_HOSTAP) 419 ADD(ic, mword, IFM_IEEE80211_HOSTAP); 420 if (ic->ic_caps & IEEE80211_C_AHDEMO) 421 ADD(ic, mword, IFM_IEEE80211_ADHOC); 422 #endif 423 if (ic->ic_caps & IEEE80211_C_MONITOR) 424 ADD(ic, mword, IFM_IEEE80211_MONITOR); 425 } 426 427 if (ic->ic_modecaps & (1 << IEEE80211_MODE_11N)) { 428 #ifdef __FreeBSD_version 429 // TODO: this probably isn't correct! 430 mopt = IFM_IEEE80211_11NA | IFM_IEEE80211_11NG; 431 #else 432 mopt = IFM_IEEE80211_11N; 433 #endif 434 ADD(ic, IFM_AUTO, mopt); 435 #ifndef IEEE80211_STA_ONLY 436 if (ic->ic_caps & IEEE80211_C_IBSS) 437 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_IBSS); 438 if (ic->ic_caps & IEEE80211_C_HOSTAP) 439 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_HOSTAP); 440 #endif 441 if (ic->ic_caps & IEEE80211_C_MONITOR) 442 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_MONITOR); 443 for (i = 0; i < IEEE80211_HT_NUM_MCS; i++) { 444 if (!isset(ic->ic_sup_mcs, i)) 445 continue; 446 #ifdef __FreeBSD_version 447 ADD(ic, IFM_IEEE80211_MCS, mopt); 448 #else 449 ADD(ic, IFM_IEEE80211_HT_MCS0 + i, mopt); 450 #ifndef IEEE80211_STA_ONLY 451 if (ic->ic_caps & IEEE80211_C_IBSS) 452 ADD(ic, IFM_IEEE80211_HT_MCS0 + i, 453 mopt | IFM_IEEE80211_IBSS); 454 if (ic->ic_caps & IEEE80211_C_HOSTAP) 455 ADD(ic, IFM_IEEE80211_HT_MCS0 + i, 456 mopt | IFM_IEEE80211_HOSTAP); 457 #endif 458 if (ic->ic_caps & IEEE80211_C_MONITOR) 459 ADD(ic, IFM_IEEE80211_HT_MCS0 + i, 460 mopt | IFM_IEEE80211_MONITOR); 461 #endif 462 } 463 ic->ic_flags |= IEEE80211_F_HTON; /* enable 11n by default */ 464 ieee80211_configure_ampdu_tx(ic, 1); 465 } 466 467 if (ic->ic_modecaps & (1 << IEEE80211_MODE_11AC)) { 468 #ifdef __FreeBSD_version 469 // TODO: this probably isn't correct! 470 mopt = IFM_IEEE80211_VHT2G | IFM_IEEE80211_VHT5G; 471 #else 472 mopt = IFM_IEEE80211_11AC; 473 #endif 474 ADD(ic, IFM_AUTO, mopt); 475 #ifndef IEEE80211_STA_ONLY 476 if (ic->ic_caps & IEEE80211_C_IBSS) 477 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_IBSS); 478 if (ic->ic_caps & IEEE80211_C_HOSTAP) 479 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_HOSTAP); 480 #endif 481 if (ic->ic_caps & IEEE80211_C_MONITOR) 482 ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_MONITOR); 483 for (i = 0; i < IEEE80211_VHT_NUM_MCS; i++) { 484 #if 0 485 /* TODO: Obtain VHT MCS information from VHT CAP IE. */ 486 if (!vht_mcs_supported) 487 continue; 488 #endif 489 #ifdef __FreeBSD_version 490 ADD(ic, IFM_IEEE80211_VHT, mopt); 491 #else 492 ADD(ic, IFM_IEEE80211_VHT_MCS0 + i, mopt); 493 #ifndef IEEE80211_STA_ONLY 494 if (ic->ic_caps & IEEE80211_C_IBSS) 495 ADD(ic, IFM_IEEE80211_VHT_MCS0 + i, 496 mopt | IFM_IEEE80211_IBSS); 497 if (ic->ic_caps & IEEE80211_C_HOSTAP) 498 ADD(ic, IFM_IEEE80211_VHT_MCS0 + i, 499 mopt | IFM_IEEE80211_HOSTAP); 500 #endif 501 if (ic->ic_caps & IEEE80211_C_MONITOR) 502 ADD(ic, IFM_IEEE80211_VHT_MCS0 + i, 503 mopt | IFM_IEEE80211_MONITOR); 504 #endif 505 } 506 ic->ic_flags |= IEEE80211_F_VHTON; /* enable 11ac by default */ 507 ic->ic_flags |= IEEE80211_F_HTON; /* 11ac implies 11n */ 508 if (ic->ic_caps & IEEE80211_C_QOS) 509 ic->ic_flags |= IEEE80211_F_QOS; 510 } 511 512 ieee80211_media_status(ifp, &imr); 513 ifmedia_set(&ic->ic_media, imr.ifm_active); 514 515 if (maxrate) 516 ifp->if_baudrate = IF_Mbps(maxrate); 517 518 #undef ADD 519 } 520 521 int 522 ieee80211_findrate(struct ieee80211com *ic, enum ieee80211_phymode mode, 523 int rate) 524 { 525 #define IEEERATE(_ic,_m,_i) \ 526 ((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL) 527 int i, nrates = ic->ic_sup_rates[mode].rs_nrates; 528 for (i = 0; i < nrates; i++) 529 if (IEEERATE(ic, mode, i) == rate) 530 return i; 531 return -1; 532 #undef IEEERATE 533 } 534 535 /* 536 * Handle a media change request. 537 */ 538 int 539 ieee80211_media_change(struct ifnet *ifp) 540 { 541 struct ieee80211com *ic = (void *)ifp; 542 struct ifmedia_entry *ime; 543 enum ieee80211_opmode newopmode; 544 enum ieee80211_phymode newphymode; 545 int i, j, newrate, error = 0; 546 547 ime = ic->ic_media.ifm_cur; 548 /* 549 * First, identify the phy mode. 550 */ 551 switch (IFM_MODE(ime->ifm_media)) { 552 case IFM_IEEE80211_11A: 553 newphymode = IEEE80211_MODE_11A; 554 break; 555 case IFM_IEEE80211_11B: 556 newphymode = IEEE80211_MODE_11B; 557 break; 558 case IFM_IEEE80211_11G: 559 newphymode = IEEE80211_MODE_11G; 560 break; 561 #ifdef __FreeBSD_version 562 case IFM_IEEE80211_11NA: 563 case IFM_IEEE80211_11NG: 564 #else 565 case IFM_IEEE80211_11N: 566 #endif 567 newphymode = IEEE80211_MODE_11N; 568 break; 569 #ifdef __FreeBSD_version 570 case IFM_IEEE80211_VHT5G: 571 case IFM_IEEE80211_VHT2G: 572 #else 573 case IFM_IEEE80211_11AC: 574 #endif 575 newphymode = IEEE80211_MODE_11AC; 576 break; 577 case IFM_AUTO: 578 newphymode = IEEE80211_MODE_AUTO; 579 break; 580 default: 581 return EINVAL; 582 } 583 584 /* 585 * Validate requested mode is available. 586 */ 587 if ((ic->ic_modecaps & (1<<newphymode)) == 0) 588 return EINVAL; 589 590 /* 591 * Next, the fixed/variable rate. 592 */ 593 i = -1; 594 #ifdef __FreeBSD_version 595 if (IFM_SUBTYPE(ime->ifm_media) == IFM_IEEE80211_VHT) { 596 #else 597 if (IFM_SUBTYPE(ime->ifm_media) >= IFM_IEEE80211_VHT_MCS0 && 598 IFM_SUBTYPE(ime->ifm_media) <= IFM_IEEE80211_VHT_MCS9) { 599 #endif 600 if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11AC)) == 0) 601 return EINVAL; 602 if (newphymode != IEEE80211_MODE_AUTO && 603 newphymode != IEEE80211_MODE_11AC) 604 return EINVAL; 605 i = ieee80211_media2mcs(ime->ifm_media); 606 /* TODO: Obtain VHT MCS information from VHT CAP IE. */ 607 if (i == -1 /* || !vht_mcs_supported */) 608 return EINVAL; 609 #ifdef __FreeBSD_version 610 } else if (IFM_SUBTYPE(ime->ifm_media) == IFM_IEEE80211_MCS) { 611 #else 612 } else if (IFM_SUBTYPE(ime->ifm_media) >= IFM_IEEE80211_HT_MCS0 && 613 IFM_SUBTYPE(ime->ifm_media) <= IFM_IEEE80211_HT_MCS76) { 614 #endif 615 if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11N)) == 0) 616 return EINVAL; 617 if (newphymode != IEEE80211_MODE_AUTO && 618 newphymode != IEEE80211_MODE_11N) 619 return EINVAL; 620 i = ieee80211_media2mcs(ime->ifm_media); 621 if (i == -1 || isclr(ic->ic_sup_mcs, i)) 622 return EINVAL; 623 } else if (IFM_SUBTYPE(ime->ifm_media) != IFM_AUTO) { 624 /* 625 * Convert media subtype to rate. 626 */ 627 newrate = ieee80211_media2rate(ime->ifm_media); 628 if (newrate == 0) 629 return EINVAL; 630 /* 631 * Check the rate table for the specified/current phy. 632 */ 633 if (newphymode == IEEE80211_MODE_AUTO) { 634 /* 635 * In autoselect mode search for the rate. 636 */ 637 for (j = IEEE80211_MODE_11A; 638 j < IEEE80211_MODE_MAX; j++) { 639 if ((ic->ic_modecaps & (1<<j)) == 0) 640 continue; 641 i = ieee80211_findrate(ic, j, newrate); 642 if (i != -1) { 643 /* lock mode too */ 644 newphymode = j; 645 break; 646 } 647 } 648 } else { 649 i = ieee80211_findrate(ic, newphymode, newrate); 650 } 651 if (i == -1) /* mode/rate mismatch */ 652 return EINVAL; 653 } 654 /* NB: defer rate setting to later */ 655 656 /* 657 * Deduce new operating mode but don't install it just yet. 658 */ 659 #ifndef IEEE80211_STA_ONLY 660 if (ime->ifm_media & IFM_IEEE80211_ADHOC) 661 newopmode = IEEE80211_M_AHDEMO; 662 else if (ime->ifm_media & IFM_IEEE80211_HOSTAP) 663 newopmode = IEEE80211_M_HOSTAP; 664 else if (ime->ifm_media & IFM_IEEE80211_IBSS) 665 newopmode = IEEE80211_M_IBSS; 666 else 667 #endif 668 if (ime->ifm_media & IFM_IEEE80211_MONITOR) 669 newopmode = IEEE80211_M_MONITOR; 670 else 671 newopmode = IEEE80211_M_STA; 672 673 #ifndef IEEE80211_STA_ONLY 674 /* 675 * Autoselect doesn't make sense when operating as an AP. 676 * If no phy mode has been selected, pick one and lock it 677 * down so rate tables can be used in forming beacon frames 678 * and the like. 679 */ 680 if (newopmode == IEEE80211_M_HOSTAP && 681 newphymode == IEEE80211_MODE_AUTO) { 682 if (ic->ic_modecaps & (1 << IEEE80211_MODE_11AC)) 683 newphymode = IEEE80211_MODE_11AC; 684 else if (ic->ic_modecaps & (1 << IEEE80211_MODE_11N)) 685 newphymode = IEEE80211_MODE_11N; 686 else if (ic->ic_modecaps & (1 << IEEE80211_MODE_11A)) 687 newphymode = IEEE80211_MODE_11A; 688 else if (ic->ic_modecaps & (1 << IEEE80211_MODE_11G)) 689 newphymode = IEEE80211_MODE_11G; 690 else 691 newphymode = IEEE80211_MODE_11B; 692 } 693 #endif 694 695 /* 696 * Handle phy mode change. 697 */ 698 if (ic->ic_curmode != newphymode) { /* change phy mode */ 699 error = ieee80211_setmode(ic, newphymode); 700 if (error != 0) 701 return error; 702 error = ENETRESET; 703 } 704 705 /* 706 * Committed to changes, install the MCS/rate setting. 707 */ 708 ic->ic_flags &= ~(IEEE80211_F_HTON | IEEE80211_F_VHTON); 709 ieee80211_configure_ampdu_tx(ic, 0); 710 if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11AC)) && 711 (newphymode == IEEE80211_MODE_AUTO || 712 newphymode == IEEE80211_MODE_11AC)) { 713 ic->ic_flags |= IEEE80211_F_VHTON; 714 ic->ic_flags |= IEEE80211_F_HTON; 715 ieee80211_configure_ampdu_tx(ic, 1); 716 } else if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11N)) && 717 (newphymode == IEEE80211_MODE_AUTO || 718 newphymode == IEEE80211_MODE_11N)) { 719 ic->ic_flags |= IEEE80211_F_HTON; 720 ieee80211_configure_ampdu_tx(ic, 1); 721 } 722 if ((ic->ic_flags & (IEEE80211_F_HTON | IEEE80211_F_VHTON)) == 0) { 723 ic->ic_fixed_mcs = -1; 724 if (ic->ic_fixed_rate != i) { 725 ic->ic_fixed_rate = i; /* set fixed tx rate */ 726 error = ENETRESET; 727 } 728 } else { 729 ic->ic_fixed_rate = -1; 730 if (ic->ic_fixed_mcs != i) { 731 ic->ic_fixed_mcs = i; /* set fixed mcs */ 732 error = ENETRESET; 733 } 734 } 735 736 /* 737 * Handle operating mode change. 738 */ 739 if (ic->ic_opmode != newopmode) { 740 ic->ic_opmode = newopmode; 741 #ifndef IEEE80211_STA_ONLY 742 switch (newopmode) { 743 case IEEE80211_M_AHDEMO: 744 case IEEE80211_M_HOSTAP: 745 case IEEE80211_M_STA: 746 case IEEE80211_M_MONITOR: 747 ic->ic_flags &= ~IEEE80211_F_IBSSON; 748 break; 749 case IEEE80211_M_IBSS: 750 ic->ic_flags |= IEEE80211_F_IBSSON; 751 break; 752 } 753 #endif 754 /* 755 * Yech, slot time may change depending on the 756 * operating mode so reset it to be sure everything 757 * is setup appropriately. 758 */ 759 ieee80211_reset_erp(ic); 760 error = ENETRESET; 761 } 762 #ifdef notdef 763 if (error == 0) 764 ifp->if_baudrate = ifmedia_baudrate(ime->ifm_media); 765 #endif 766 return error; 767 } 768 769 void 770 ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr) 771 { 772 struct ieee80211com *ic = (void *)ifp; 773 const struct ieee80211_node *ni = NULL; 774 775 imr->ifm_status = IFM_AVALID; 776 imr->ifm_active = IFM_IEEE80211; 777 if (ic->ic_state == IEEE80211_S_RUN && 778 (ic->ic_opmode != IEEE80211_M_STA || 779 !(ic->ic_flags & IEEE80211_F_RSNON) || 780 ic->ic_bss->ni_port_valid)) 781 imr->ifm_status |= IFM_ACTIVE; 782 imr->ifm_active |= IFM_AUTO; 783 switch (ic->ic_opmode) { 784 case IEEE80211_M_STA: 785 ni = ic->ic_bss; 786 if (ic->ic_curmode == IEEE80211_MODE_11N || 787 ic->ic_curmode == IEEE80211_MODE_11AC) 788 imr->ifm_active |= ieee80211_mcs2media(ic, 789 ni->ni_txmcs, ic->ic_curmode); 790 else if (ni->ni_flags & IEEE80211_NODE_VHT) /* in MODE_AUTO */ 791 imr->ifm_active |= ieee80211_mcs2media(ic, 792 ni->ni_txmcs, IEEE80211_MODE_11AC); 793 else if (ni->ni_flags & IEEE80211_NODE_HT) /* in MODE_AUTO */ 794 imr->ifm_active |= ieee80211_mcs2media(ic, 795 ni->ni_txmcs, IEEE80211_MODE_11N); 796 else 797 /* calculate rate subtype */ 798 imr->ifm_active |= ieee80211_rate2media(ic, 799 ni->ni_rates.rs_rates[ni->ni_txrate], 800 ic->ic_curmode); 801 break; 802 #ifndef IEEE80211_STA_ONLY 803 case IEEE80211_M_IBSS: 804 imr->ifm_active |= IFM_IEEE80211_IBSS; 805 break; 806 case IEEE80211_M_AHDEMO: 807 imr->ifm_active |= IFM_IEEE80211_ADHOC; 808 break; 809 case IEEE80211_M_HOSTAP: 810 imr->ifm_active |= IFM_IEEE80211_HOSTAP; 811 break; 812 #endif 813 case IEEE80211_M_MONITOR: 814 imr->ifm_active |= IFM_IEEE80211_MONITOR; 815 break; 816 default: 817 break; 818 } 819 switch (ic->ic_curmode) { 820 case IEEE80211_MODE_11A: 821 imr->ifm_active |= IFM_IEEE80211_11A; 822 break; 823 case IEEE80211_MODE_11B: 824 imr->ifm_active |= IFM_IEEE80211_11B; 825 break; 826 case IEEE80211_MODE_11G: 827 imr->ifm_active |= IFM_IEEE80211_11G; 828 break; 829 case IEEE80211_MODE_11N: 830 #ifdef __FreeBSD_version 831 imr->ifm_active |= IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? IFM_IEEE80211_11NA : IFM_IEEE80211_11NG; 832 #else 833 imr->ifm_active |= IFM_IEEE80211_11N; 834 #endif 835 break; 836 case IEEE80211_MODE_11AC: 837 #ifdef __FreeBSD_version 838 imr->ifm_active |= IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? IFM_IEEE80211_VHT5G : IFM_IEEE80211_VHT2G; 839 #else 840 imr->ifm_active |= IFM_IEEE80211_11AC; 841 #endif 842 break; 843 } 844 } 845 846 void 847 ieee80211_watchdog(struct ifnet *ifp) 848 { 849 struct ieee80211com *ic = (void *)ifp; 850 851 if (ic->ic_mgt_timer && --ic->ic_mgt_timer == 0) { 852 if (ic->ic_opmode == IEEE80211_M_STA && 853 (ic->ic_state == IEEE80211_S_AUTH || 854 ic->ic_state == IEEE80211_S_ASSOC)) { 855 struct ieee80211_node *ni; 856 if (ifp->if_flags & IFF_DEBUG) 857 printf("%s: %s timed out for %s\n", 858 ifp->if_xname, 859 ic->ic_state == IEEE80211_S_ASSOC ? 860 "association" : "authentication", 861 ether_sprintf(ic->ic_bss->ni_macaddr)); 862 ni = ieee80211_find_node(ic, ic->ic_bss->ni_macaddr); 863 if (ni) 864 ni->ni_fails++; 865 if (ISSET(ic->ic_flags, IEEE80211_F_AUTO_JOIN)) 866 ieee80211_deselect_ess(ic); 867 } 868 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 869 } 870 871 if (ic->ic_mgt_timer != 0) 872 ifp->if_timer = 1; 873 } 874 875 const struct ieee80211_rateset ieee80211_std_rateset_11a = 876 { 8, { 12, 18, 24, 36, 48, 72, 96, 108 } }; 877 878 const struct ieee80211_rateset ieee80211_std_rateset_11b = 879 { 4, { 2, 4, 11, 22 } }; 880 881 const struct ieee80211_rateset ieee80211_std_rateset_11g = 882 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } }; 883 884 const struct ieee80211_ht_rateset ieee80211_std_ratesets_11n[] = { 885 /* MCS 0-7, 20MHz channel, no SGI */ 886 { 8, { 13, 26, 39, 52, 78, 104, 117, 130 }, 887 0x000000ff, 0, 7, 0, 0}, 888 889 /* MCS 0-7, 20MHz channel, SGI */ 890 { 8, { 14, 29, 43, 58, 87, 116, 130, 144 }, 891 0x000000ff, 0, 7, 0, 1 }, 892 893 /* MCS 8-15, 20MHz channel, no SGI */ 894 { 8, { 26, 52, 78, 104, 156, 208, 234, 260 }, 895 0x0000ff00, 8, 15, 0, 0 }, 896 897 /* MCS 8-15, 20MHz channel, SGI */ 898 { 8, { 29, 58, 87, 116, 173, 231, 261, 289 }, 899 0x0000ff00, 8, 15, 0, 1 }, 900 901 /* MCS 16-23, 20MHz channel, no SGI */ 902 { 8, { 39, 78, 117, 156, 234, 312, 351, 390 }, 903 0x00ff0000, 16, 23, 0, 0 }, 904 905 /* MCS 16-23, 20MHz channel, SGI */ 906 { 8, { 43, 87, 130, 173, 260, 347, 390, 433 }, 907 0x00ff0000, 16, 23, 0, 1 }, 908 909 /* MCS 24-31, 20MHz channel, no SGI */ 910 { 8, { 52, 104, 156, 208, 312, 416, 468, 520 }, 911 0xff000000, 24, 31, 0, 0 }, 912 913 /* MCS 24-31, 20MHz channel, SGI */ 914 { 8, { 58, 116, 173, 231, 347, 462, 520, 578 }, 915 0xff000000, 24, 31, 0, 1 }, 916 917 /* MCS 0-7, 40MHz channel, no SGI */ 918 { 8, { 27, 54, 81, 108, 162, 216, 243, 270 }, 919 0x000000ff, 0, 7, 1, 0 }, 920 921 /* MCS 0-7, 40MHz channel, SGI */ 922 { 8, { 30, 60, 90, 120, 180, 240, 270, 300 }, 923 0x000000ff, 0, 7, 1, 1 }, 924 925 /* MCS 8-15, 40MHz channel, no SGI */ 926 { 8, { 54, 108, 192, 216, 324, 432, 486, 540 }, 927 0x0000ff00, 8, 15, 1, 0 }, 928 929 /* MCS 8-15, 40MHz channel, SGI */ 930 { 8, { 60, 120, 180, 240, 360, 480, 540, 600 }, 931 0x0000ff00, 8, 15, 1, 1 }, 932 933 /* MCS 16-23, 40MHz channel, no SGI */ 934 { 8, { 81, 162, 243, 324, 486, 648, 729, 810 }, 935 0x00ff0000, 16, 23, 1, 0 }, 936 937 /* MCS 16-23, 40MHz channel, SGI */ 938 { 8, { 90, 180, 270, 360, 540, 720, 810, 900 }, 939 0x00ff0000, 16, 23, 1, 1 }, 940 941 /* MCS 24-31, 40MHz channel, no SGI */ 942 { 8, { 108, 216, 324, 432, 324, 864, 972, 1080 }, 943 0xff000000, 24, 31, 1, 0 }, 944 945 /* MCS 24-31, 40MHz channel, SGI */ 946 { 8, { 120, 240, 360, 480, 520, 960, 1080, 1200 }, 947 0xff000000, 24, 31, 1, 1 }, 948 }; 949 950 const struct ieee80211_vht_rateset ieee80211_std_ratesets_11ac[] = { 951 /* MCS 0-8 (MCS 9 N/A), 1 SS, 20MHz channel, no SGI */ 952 { 0, 9, { 13, 26, 39, 52, 78, 104, 117, 130, 156 }, 953 1, 0, 0, 0 }, 954 955 /* MCS 0-8 (MCS 9 N/A), 1 SS, 20MHz channel, SGI */ 956 { 1, 9, { 14, 29, 43, 58, 87, 116, 130, 144, 174 }, 957 1, 0, 0, 1 }, 958 959 /* MCS 0-8 (MCS 9 N/A), 2 SS, 20MHz channel, no SGI */ 960 { 2, 9, { 26, 52, 78, 104, 156, 208, 234, 260, 312 }, 961 2, 0, 0, 0 }, 962 963 /* MCS 0-8 (MCS 9 N/A), 2 SS, 20MHz channel, SGI */ 964 { 3, 9, { 29, 58, 87, 116, 173, 231, 261, 289, 347 }, 965 2, 0, 0, 1 }, 966 967 /* MCS 0-9, 1 SS, 40MHz channel, no SGI */ 968 { 4, 10, { 27, 54, 81, 108, 162, 216, 243, 270, 324, 360 }, 969 1, 1, 0, 0 }, 970 971 /* MCS 0-9, 1 SS, 40MHz channel, SGI */ 972 { 5, 10, { 30, 60, 90, 120, 180, 240, 270, 300, 360, 400 }, 973 1, 1, 0, 1 }, 974 975 /* MCS 0-9, 2 SS, 40MHz channel, no SGI */ 976 { 6, 10, { 54, 108, 162, 216, 324, 432, 486, 540, 648, 720 }, 977 2, 1, 0, 0 }, 978 979 /* MCS 0-9, 2 SS, 40MHz channel, SGI */ 980 { 7, 10, { 60, 120, 180, 240, 360, 480, 540, 600, 720, 800 }, 981 2, 1, 0, 1 }, 982 983 /* MCS 0-9, 1 SS, 80MHz channel, no SGI */ 984 { 8, 10, { 59, 117, 176, 234, 351, 468, 527, 585, 702, 780 }, 985 1, 0, 1, 0 }, 986 987 /* MCS 0-9, 1 SS, 80MHz channel, SGI */ 988 { 9, 10, { 65, 130, 195, 260, 390, 520, 585, 650, 780, 867 }, 989 1, 0, 1, 1 }, 990 991 /* MCS 0-9, 2 SS, 80MHz channel, no SGI */ 992 { 10, 10, { 117, 234, 351, 468, 702, 936, 1053, 1404, 1560 }, 993 2, 0, 1, 0 }, 994 995 /* MCS 0-9, 2 SS, 80MHz channel, SGI */ 996 { 11, 10, { 130, 260, 390, 520, 780, 1040, 1170, 1300, 1560, 1734 }, 997 2, 0, 1, 1 }, 998 }; 999 1000 /* 1001 * Mark the basic rates for the 11g rate table based on the 1002 * operating mode. For real 11g we mark all the 11b rates 1003 * and 6, 12, and 24 OFDM. For 11b compatibility we mark only 1004 * 11b rates. There's also a pseudo 11a-mode used to mark only 1005 * the basic OFDM rates. 1006 */ 1007 void 1008 ieee80211_setbasicrates(struct ieee80211com *ic) 1009 { 1010 static const struct ieee80211_rateset basic[] = { 1011 { 0 }, /* IEEE80211_MODE_AUTO */ 1012 { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_11A */ 1013 { 2, { 2, 4 } }, /* IEEE80211_MODE_11B */ 1014 { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_11G */ 1015 { 0 }, /* IEEE80211_MODE_11N */ 1016 { 0 }, /* IEEE80211_MODE_11AC */ 1017 }; 1018 enum ieee80211_phymode mode; 1019 struct ieee80211_rateset *rs; 1020 int i, j; 1021 1022 for (mode = 0; mode < IEEE80211_MODE_MAX; mode++) { 1023 rs = &ic->ic_sup_rates[mode]; 1024 for (i = 0; i < rs->rs_nrates; i++) { 1025 rs->rs_rates[i] &= IEEE80211_RATE_VAL; 1026 for (j = 0; j < basic[mode].rs_nrates; j++) { 1027 if (basic[mode].rs_rates[j] == 1028 rs->rs_rates[i]) { 1029 rs->rs_rates[i] |= 1030 IEEE80211_RATE_BASIC; 1031 break; 1032 } 1033 } 1034 } 1035 } 1036 } 1037 1038 int 1039 ieee80211_min_basic_rate(struct ieee80211com *ic) 1040 { 1041 struct ieee80211_rateset *rs = &ic->ic_bss->ni_rates; 1042 int i, min, rval; 1043 1044 min = -1; 1045 1046 for (i = 0; i < rs->rs_nrates; i++) { 1047 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0) 1048 continue; 1049 rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL); 1050 if (min == -1) 1051 min = rval; 1052 else if (rval < min) 1053 min = rval; 1054 } 1055 1056 /* Default to 1 Mbit/s on 2GHz and 6 Mbit/s on 5GHz. */ 1057 if (min == -1) 1058 min = IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ? 2 : 12; 1059 1060 return min; 1061 } 1062 1063 int 1064 ieee80211_max_basic_rate(struct ieee80211com *ic) 1065 { 1066 struct ieee80211_rateset *rs = &ic->ic_bss->ni_rates; 1067 int i, max, rval; 1068 1069 /* Default to 1 Mbit/s on 2GHz and 6 Mbit/s on 5GHz. */ 1070 max = IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ? 2 : 12; 1071 1072 for (i = 0; i < rs->rs_nrates; i++) { 1073 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0) 1074 continue; 1075 rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL); 1076 if (rval > max) 1077 max = rval; 1078 } 1079 1080 return max; 1081 } 1082 1083 /* 1084 * Set the current phy mode and recalculate the active channel 1085 * set based on the available channels for this mode. Also 1086 * select a new default/current channel if the current one is 1087 * inappropriate for this mode. 1088 */ 1089 int 1090 ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode) 1091 { 1092 struct ifnet *ifp = &ic->ic_if; 1093 static const u_int chanflags[] = { 1094 0, /* IEEE80211_MODE_AUTO */ 1095 IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ 1096 IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ 1097 IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ 1098 IEEE80211_CHAN_HT, /* IEEE80211_MODE_11N */ 1099 IEEE80211_CHAN_VHT, /* IEEE80211_MODE_11AC */ 1100 }; 1101 const struct ieee80211_channel *c; 1102 u_int modeflags; 1103 int i; 1104 1105 /* validate new mode */ 1106 if ((ic->ic_modecaps & (1<<mode)) == 0) { 1107 DPRINTF(("mode %u not supported (caps 0x%x)\n", 1108 mode, ic->ic_modecaps)); 1109 return EINVAL; 1110 } 1111 1112 /* 1113 * Verify at least one channel is present in the available 1114 * channel list before committing to the new mode. 1115 */ 1116 if (mode >= nitems(chanflags)) 1117 panic("%s: unexpected mode %u", __func__, mode); 1118 modeflags = chanflags[mode]; 1119 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { 1120 c = &ic->ic_channels[i]; 1121 if (mode == IEEE80211_MODE_AUTO) { 1122 if (c->ic_flags != 0) 1123 break; 1124 } else if ((c->ic_flags & modeflags) == modeflags) 1125 break; 1126 } 1127 if (i > IEEE80211_CHAN_MAX) { 1128 DPRINTF(("no channels found for mode %u\n", mode)); 1129 return EINVAL; 1130 } 1131 1132 /* 1133 * Calculate the active channel set. 1134 */ 1135 memset(ic->ic_chan_active, 0, sizeof(ic->ic_chan_active)); 1136 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) { 1137 c = &ic->ic_channels[i]; 1138 if (mode == IEEE80211_MODE_AUTO) { 1139 if (c->ic_flags != 0) 1140 setbit(ic->ic_chan_active, i); 1141 } else if ((c->ic_flags & modeflags) == modeflags) 1142 setbit(ic->ic_chan_active, i); 1143 } 1144 /* 1145 * If no current/default channel is setup or the current 1146 * channel is wrong for the mode then pick the first 1147 * available channel from the active list. This is likely 1148 * not the right one. 1149 */ 1150 if (ic->ic_ibss_chan == NULL || isclr(ic->ic_chan_active, 1151 ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) { 1152 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) 1153 if (isset(ic->ic_chan_active, i)) { 1154 ic->ic_ibss_chan = &ic->ic_channels[i]; 1155 break; 1156 } 1157 if ((ic->ic_ibss_chan == NULL) || isclr(ic->ic_chan_active, 1158 ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) 1159 panic("Bad IBSS channel %u", 1160 ieee80211_chan2ieee(ic, ic->ic_ibss_chan)); 1161 } 1162 1163 /* 1164 * Reset the scan state for the new mode. This avoids scanning 1165 * of invalid channels, ie. 5GHz channels in 11b mode. 1166 */ 1167 ieee80211_reset_scan(ifp); 1168 1169 ic->ic_curmode = mode; 1170 ieee80211_reset_erp(ic); /* reset ERP state */ 1171 1172 return 0; 1173 } 1174 1175 enum ieee80211_phymode 1176 ieee80211_next_mode(struct ifnet *ifp) 1177 { 1178 struct ieee80211com *ic = (void *)ifp; 1179 uint16_t mode; 1180 1181 /* 1182 * Indicate a wrap-around if we're running in a fixed, user-specified 1183 * phy mode. 1184 */ 1185 if (IFM_SUBTYPE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO) 1186 return (IEEE80211_MODE_AUTO); 1187 1188 /* 1189 * Always scan in AUTO mode if the driver scans all bands. 1190 * The current mode might have changed during association 1191 * so we must reset it here. 1192 */ 1193 if (ic->ic_caps & IEEE80211_C_SCANALLBAND) { 1194 ieee80211_setmode(ic, IEEE80211_MODE_AUTO); 1195 return (ic->ic_curmode); 1196 } 1197 1198 /* 1199 * Get the next supported mode; effectively, this alternates between 1200 * the 11a (5GHz) and 11b/g (2GHz) modes. What matters is that each 1201 * supported channel gets scanned. 1202 */ 1203 for (mode = ic->ic_curmode + 1; mode <= IEEE80211_MODE_MAX; mode++) { 1204 /* 1205 * Skip over 11n mode. Its set of channels is the superset 1206 * of all channels supported by the other modes. 1207 */ 1208 if (mode == IEEE80211_MODE_11N) 1209 continue; 1210 /* 1211 * Skip over 11ac mode. Its set of channels is the set 1212 * of all channels supported by 11a. 1213 */ 1214 if (mode == IEEE80211_MODE_11AC) 1215 continue; 1216 1217 /* Start over if we have already tried all modes. */ 1218 if (mode == IEEE80211_MODE_MAX) { 1219 mode = IEEE80211_MODE_AUTO; 1220 break; 1221 } 1222 1223 if (ic->ic_modecaps & (1 << mode)) 1224 break; 1225 } 1226 1227 if (mode != ic->ic_curmode) 1228 ieee80211_setmode(ic, mode); 1229 1230 return (ic->ic_curmode); 1231 } 1232 1233 /* 1234 * Return the phy mode for with the specified channel so the 1235 * caller can select a rate set. This is problematic and the 1236 * work here assumes how things work elsewhere in this code. 1237 * 1238 * Because the result of this function is ultimately used to select a 1239 * rate from the rate set of the returned mode, it must return one of the 1240 * legacy 11a/b/g modes; 11n and 11ac modes use MCS instead of rate sets. 1241 */ 1242 enum ieee80211_phymode 1243 ieee80211_chan2mode(struct ieee80211com *ic, 1244 const struct ieee80211_channel *chan) 1245 { 1246 /* 1247 * Are we fixed in 11a/b/g mode? 1248 * NB: this assumes the channel would not be supplied to us 1249 * unless it was already compatible with the current mode. 1250 */ 1251 if (ic->ic_curmode == IEEE80211_MODE_11A || 1252 ic->ic_curmode == IEEE80211_MODE_11B || 1253 ic->ic_curmode == IEEE80211_MODE_11G) 1254 return ic->ic_curmode; 1255 1256 /* If no channel was provided, return the most suitable legacy mode. */ 1257 if (chan == IEEE80211_CHAN_ANYC) { 1258 switch (ic->ic_curmode) { 1259 case IEEE80211_MODE_AUTO: 1260 case IEEE80211_MODE_11N: 1261 if (ic->ic_modecaps & (1 << IEEE80211_MODE_11A)) 1262 return IEEE80211_MODE_11A; 1263 if (ic->ic_modecaps & (1 << IEEE80211_MODE_11G)) 1264 return IEEE80211_MODE_11G; 1265 return IEEE80211_MODE_11B; 1266 case IEEE80211_MODE_11AC: 1267 return IEEE80211_MODE_11A; 1268 default: 1269 return ic->ic_curmode; 1270 } 1271 } 1272 1273 /* Deduce a legacy mode based on the channel characteristics. */ 1274 if (IEEE80211_IS_CHAN_5GHZ(chan)) 1275 return IEEE80211_MODE_11A; 1276 else if (chan->ic_flags & (IEEE80211_CHAN_OFDM|IEEE80211_CHAN_DYN)) 1277 return IEEE80211_MODE_11G; 1278 else 1279 return IEEE80211_MODE_11B; 1280 } 1281 1282 /* 1283 * Convert IEEE80211 MCS index to ifmedia subtype. 1284 */ 1285 uint64_t 1286 ieee80211_mcs2media(struct ieee80211com *ic, int mcs, 1287 enum ieee80211_phymode mode) 1288 { 1289 switch (mode) { 1290 case IEEE80211_MODE_11A: 1291 case IEEE80211_MODE_11B: 1292 case IEEE80211_MODE_11G: 1293 /* these modes use rates, not MCS */ 1294 panic("%s: unexpected mode %d", __func__, mode); 1295 break; 1296 #ifndef __FreeBSD_version /* can't be converted to FreeBSD IFM */ 1297 case IEEE80211_MODE_11N: 1298 if (mcs >= 0 && mcs < IEEE80211_HT_NUM_MCS) 1299 return (IFM_IEEE80211_11N | 1300 (IFM_IEEE80211_HT_MCS0 + mcs)); 1301 break; 1302 case IEEE80211_MODE_11AC: 1303 if (mcs >= 0 && mcs < IEEE80211_VHT_NUM_MCS) 1304 return (IFM_IEEE80211_11AC | 1305 (IFM_IEEE80211_VHT_MCS0 + mcs)); 1306 break; 1307 #endif 1308 case IEEE80211_MODE_AUTO: 1309 break; 1310 } 1311 1312 return IFM_AUTO; 1313 } 1314 1315 /* 1316 * Convert ifmedia subtype to IEEE80211 MCS index. 1317 */ 1318 int 1319 ieee80211_media2mcs(uint64_t mword) 1320 { 1321 uint64_t subtype; 1322 1323 subtype = IFM_SUBTYPE(mword); 1324 1325 if (subtype == IFM_AUTO) 1326 return -1; 1327 else if (subtype == IFM_MANUAL || subtype == IFM_NONE) 1328 return 0; 1329 1330 #ifndef __FreeBSD_version 1331 if (subtype >= IFM_IEEE80211_HT_MCS0 && 1332 subtype <= IFM_IEEE80211_HT_MCS76) 1333 return (int)(subtype - IFM_IEEE80211_HT_MCS0); 1334 1335 if (subtype >= IFM_IEEE80211_VHT_MCS0 && 1336 subtype <= IFM_IEEE80211_VHT_MCS9) 1337 return (int)(subtype - IFM_IEEE80211_VHT_MCS0); 1338 #endif 1339 1340 return -1; 1341 } 1342 1343 /* 1344 * convert IEEE80211 rate value to ifmedia subtype. 1345 * ieee80211 rate is in unit of 0.5Mbps. 1346 */ 1347 uint64_t 1348 ieee80211_rate2media(struct ieee80211com *ic, int rate, 1349 enum ieee80211_phymode mode) 1350 { 1351 static const struct { 1352 uint64_t m; /* rate + mode */ 1353 uint64_t r; /* if_media rate */ 1354 } rates[] = { 1355 { 2 | IFM_IEEE80211_11B, IFM_IEEE80211_DS1 }, 1356 { 4 | IFM_IEEE80211_11B, IFM_IEEE80211_DS2 }, 1357 { 11 | IFM_IEEE80211_11B, IFM_IEEE80211_DS5 }, 1358 { 22 | IFM_IEEE80211_11B, IFM_IEEE80211_DS11 }, 1359 { 44 | IFM_IEEE80211_11B, IFM_IEEE80211_DS22 }, 1360 { 12 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM6 }, 1361 { 18 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM9 }, 1362 { 24 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM12 }, 1363 { 36 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM18 }, 1364 { 48 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM24 }, 1365 { 72 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM36 }, 1366 { 96 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM48 }, 1367 { 108 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM54 }, 1368 { 2 | IFM_IEEE80211_11G, IFM_IEEE80211_DS1 }, 1369 { 4 | IFM_IEEE80211_11G, IFM_IEEE80211_DS2 }, 1370 { 11 | IFM_IEEE80211_11G, IFM_IEEE80211_DS5 }, 1371 { 22 | IFM_IEEE80211_11G, IFM_IEEE80211_DS11 }, 1372 { 12 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM6 }, 1373 { 18 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM9 }, 1374 { 24 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM12 }, 1375 { 36 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM18 }, 1376 { 48 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM24 }, 1377 { 72 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM36 }, 1378 { 96 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM48 }, 1379 { 108 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM54 }, 1380 /* NB: OFDM72 doesn't really exist so we don't handle it */ 1381 }; 1382 uint64_t mask; 1383 int i; 1384 1385 mask = rate & IEEE80211_RATE_VAL; 1386 switch (mode) { 1387 case IEEE80211_MODE_11A: 1388 mask |= IFM_IEEE80211_11A; 1389 break; 1390 case IEEE80211_MODE_11B: 1391 mask |= IFM_IEEE80211_11B; 1392 break; 1393 case IEEE80211_MODE_AUTO: 1394 /* NB: hack, 11g matches both 11b+11a rates */ 1395 /* FALLTHROUGH */ 1396 case IEEE80211_MODE_11G: 1397 mask |= IFM_IEEE80211_11G; 1398 break; 1399 case IEEE80211_MODE_11N: 1400 case IEEE80211_MODE_11AC: 1401 /* 11n/11ac uses MCS, not rates. */ 1402 panic("%s: unexpected mode %d", __func__, mode); 1403 break; 1404 } 1405 for (i = 0; i < nitems(rates); i++) 1406 if (rates[i].m == mask) 1407 return rates[i].r; 1408 return IFM_AUTO; 1409 } 1410 1411 int 1412 ieee80211_media2rate(uint64_t mword) 1413 { 1414 int i; 1415 static const struct { 1416 uint64_t subtype; 1417 int rate; 1418 } ieeerates[] = { 1419 { IFM_AUTO, -1 }, 1420 { IFM_MANUAL, 0 }, 1421 { IFM_NONE, 0 }, 1422 { IFM_IEEE80211_DS1, 2 }, 1423 { IFM_IEEE80211_DS2, 4 }, 1424 { IFM_IEEE80211_DS5, 11 }, 1425 { IFM_IEEE80211_DS11, 22 }, 1426 { IFM_IEEE80211_DS22, 44 }, 1427 { IFM_IEEE80211_OFDM6, 12 }, 1428 { IFM_IEEE80211_OFDM9, 18 }, 1429 { IFM_IEEE80211_OFDM12, 24 }, 1430 { IFM_IEEE80211_OFDM18, 36 }, 1431 { IFM_IEEE80211_OFDM24, 48 }, 1432 { IFM_IEEE80211_OFDM36, 72 }, 1433 { IFM_IEEE80211_OFDM48, 96 }, 1434 { IFM_IEEE80211_OFDM54, 108 }, 1435 { IFM_IEEE80211_OFDM72, 144 }, 1436 }; 1437 for (i = 0; i < nitems(ieeerates); i++) { 1438 if (ieeerates[i].subtype == IFM_SUBTYPE(mword)) 1439 return ieeerates[i].rate; 1440 } 1441 return 0; 1442 } 1443 1444 /* 1445 * Convert bit rate (in 0.5Mbps units) to PLCP signal (R4-R1) and vice versa. 1446 */ 1447 u_int8_t 1448 ieee80211_rate2plcp(u_int8_t rate, enum ieee80211_phymode mode) 1449 { 1450 rate &= IEEE80211_RATE_VAL; 1451 1452 if (mode == IEEE80211_MODE_11B) { 1453 /* IEEE Std 802.11b-1999 page 15, subclause 18.2.3.3 */ 1454 switch (rate) { 1455 case 2: return 10; 1456 case 4: return 20; 1457 case 11: return 55; 1458 case 22: return 110; 1459 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 1460 case 44: return 220; 1461 } 1462 } else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) { 1463 /* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */ 1464 switch (rate) { 1465 case 12: return 0x0b; 1466 case 18: return 0x0f; 1467 case 24: return 0x0a; 1468 case 36: return 0x0e; 1469 case 48: return 0x09; 1470 case 72: return 0x0d; 1471 case 96: return 0x08; 1472 case 108: return 0x0c; 1473 } 1474 } else 1475 panic("%s: unexpected mode %u", __func__, mode); 1476 1477 DPRINTF(("unsupported rate %u\n", rate)); 1478 1479 return 0; 1480 } 1481 1482 u_int8_t 1483 ieee80211_plcp2rate(u_int8_t plcp, enum ieee80211_phymode mode) 1484 { 1485 if (mode == IEEE80211_MODE_11B) { 1486 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 1487 switch (plcp) { 1488 case 10: return 2; 1489 case 20: return 4; 1490 case 55: return 11; 1491 case 110: return 22; 1492 /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 1493 case 220: return 44; 1494 } 1495 } else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) { 1496 /* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */ 1497 switch (plcp) { 1498 case 0x0b: return 12; 1499 case 0x0f: return 18; 1500 case 0x0a: return 24; 1501 case 0x0e: return 36; 1502 case 0x09: return 48; 1503 case 0x0d: return 72; 1504 case 0x08: return 96; 1505 case 0x0c: return 108; 1506 } 1507 } else 1508 panic("%s: unexpected mode %u", __func__, mode); 1509 1510 DPRINTF(("unsupported plcp %u\n", plcp)); 1511 1512 return 0; 1513 } 1514