1 /*- 2 * Copyright (c) 2020-2022 The FreeBSD Foundation 3 * Copyright (c) 2020-2022 Bjoern A. Zeeb 4 * 5 * This software was developed by Björn Zeeb under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 /* 31 * Public functions are called linuxkpi_*(). 32 * Internal (static) functions are called lkpi_*(). 33 * 34 * The internal structures holding metadata over public structures are also 35 * called lkpi_xxx (usually with a member at the end called xxx). 36 * Note: we do not replicate the structure names but the general variable names 37 * for these (e.g., struct hw -> struct lkpi_hw, struct sta -> struct lkpi_sta). 38 * There are macros to access one from the other. 39 * We call the internal versions lxxx (e.g., hw -> lhw, sta -> lsta). 40 */ 41 42 #include <sys/cdefs.h> 43 __FBSDID("$FreeBSD$"); 44 45 #include <sys/param.h> 46 #include <sys/types.h> 47 #include <sys/kernel.h> 48 #include <sys/errno.h> 49 #include <sys/malloc.h> 50 #include <sys/module.h> 51 #include <sys/mutex.h> 52 #include <sys/socket.h> 53 #include <sys/sysctl.h> 54 #include <sys/queue.h> 55 #include <sys/taskqueue.h> 56 #include <sys/libkern.h> 57 58 #include <net/if.h> 59 #include <net/if_var.h> 60 #include <net/if_media.h> 61 #include <net/ethernet.h> 62 63 #include <net80211/ieee80211_var.h> 64 #include <net80211/ieee80211_proto.h> 65 #include <net80211/ieee80211_ratectl.h> 66 #include <net80211/ieee80211_radiotap.h> 67 68 #define LINUXKPI_NET80211 69 #include <net/mac80211.h> 70 71 #include <linux/workqueue.h> 72 #include "linux_80211.h" 73 74 /* #define LKPI_80211_HW_CRYPTO */ 75 76 static MALLOC_DEFINE(M_LKPI80211, "lkpi80211", "LinuxKPI 80211 compat"); 77 78 /* -------------------------------------------------------------------------- */ 79 80 /* Keep public for as long as header files are using it too. */ 81 int linuxkpi_debug_80211; 82 83 #ifdef LINUXKPI_DEBUG_80211 84 SYSCTL_DECL(_compat_linuxkpi); 85 SYSCTL_NODE(_compat_linuxkpi, OID_AUTO, 80211, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 86 "LinuxKPI 802.11 compatibility layer"); 87 88 SYSCTL_INT(_compat_linuxkpi_80211, OID_AUTO, debug, CTLFLAG_RWTUN, 89 &linuxkpi_debug_80211, 0, "LinuxKPI 802.11 debug level"); 90 91 #ifndef D80211_TODO 92 #define D80211_TODO 0x1 93 #endif 94 #ifndef D80211_IMPROVE 95 #define D80211_IMPROVE 0x2 96 #endif 97 #define D80211_TRACE 0x10 98 #define D80211_TRACEOK 0x20 99 #define D80211_TRACE_TX 0x100 100 #define D80211_TRACE_TX_DUMP 0x200 101 #define D80211_TRACE_RX 0x1000 102 #define D80211_TRACE_RX_DUMP 0x2000 103 #define D80211_TRACE_RX_BEACONS 0x4000 104 #define D80211_TRACEX (D80211_TRACE_TX|D80211_TRACE_RX) 105 #define D80211_TRACEX_DUMP (D80211_TRACE_TX_DUMP|D80211_TRACE_RX_DUMP) 106 #define D80211_TRACE_STA 0x10000 107 #define UNIMPLEMENTED if (linuxkpi_debug_80211 & D80211_TODO) \ 108 printf("XXX-TODO %s:%d: UNIMPLEMENTED\n", __func__, __LINE__) 109 #define TRACEOK() if (linuxkpi_debug_80211 & D80211_TRACEOK) \ 110 printf("XXX-TODO %s:%d: TRACEPOINT\n", __func__, __LINE__) 111 #else 112 #define UNIMPLEMENTED do { } while (0) 113 #define TRACEOK() do { } while (0) 114 #endif 115 116 /* #define PREP_TX_INFO_DURATION (IEEE80211_TRANS_WAIT * 1000) */ 117 #ifndef PREP_TX_INFO_DURATION 118 #define PREP_TX_INFO_DURATION 0 /* Let the driver do its thing. */ 119 #endif 120 121 /* c.f. ieee80211_ioctl.c */ 122 static const uint8_t zerobssid[IEEE80211_ADDR_LEN]; 123 124 /* This is DSAP | SSAP | CTRL | ProtoID/OrgCode{3}. */ 125 const uint8_t rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; 126 127 /* IEEE 802.11-05/0257r1 */ 128 const uint8_t bridge_tunnel_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; 129 130 const uint8_t tid_to_mac80211_ac[] = { 131 IEEE80211_AC_BE, 132 IEEE80211_AC_BK, 133 IEEE80211_AC_BK, 134 IEEE80211_AC_BE, 135 IEEE80211_AC_VI, 136 IEEE80211_AC_VI, 137 IEEE80211_AC_VO, 138 IEEE80211_AC_VO, 139 #if 0 140 IEEE80211_AC_VO, /* We treat MGMT as TID 8, which is set as AC_VO */ 141 #endif 142 }; 143 144 const struct cfg80211_ops linuxkpi_mac80211cfgops = { 145 /* 146 * XXX TODO need a "glue layer" to link cfg80211 ops to 147 * mac80211 and to the driver or net80211. 148 * Can we pass some on 1:1? Need to compare the (*f)(). 149 */ 150 }; 151 152 static struct lkpi_sta *lkpi_find_lsta_by_ni(struct lkpi_vif *, 153 struct ieee80211_node *); 154 static void lkpi_80211_txq_task(void *, int); 155 static void lkpi_ieee80211_free_skb_mbuf(void *); 156 157 static void 158 lkpi_lsta_dump(struct lkpi_sta *lsta, struct ieee80211_node *ni, 159 const char *_f, int _l) 160 { 161 162 #ifdef LINUXKPI_DEBUG_80211 163 if ((linuxkpi_debug_80211 & D80211_TRACE_STA) == 0) 164 return; 165 if (lsta == NULL) 166 return; 167 168 printf("%s:%d lsta %p ni %p sta %p\n", 169 _f, _l, lsta, ni, &lsta->sta); 170 if (ni != NULL) 171 ieee80211_dump_node(NULL, ni); 172 printf("\ttxq_task txq len %d mtx\n", mbufq_len(&lsta->txq)); 173 printf("\tkc %p state %d added_to_drv %d in_mgd %d\n", 174 lsta->kc, lsta->state, lsta->added_to_drv, lsta->in_mgd); 175 #endif 176 } 177 178 static void 179 lkpi_lsta_remove(struct lkpi_sta *lsta, struct lkpi_vif *lvif) 180 { 181 struct ieee80211_node *ni; 182 183 ni = lsta->ni; 184 185 LKPI_80211_LVIF_LOCK(lvif); 186 TAILQ_REMOVE(&lvif->lsta_head, lsta, lsta_entry); 187 LKPI_80211_LVIF_UNLOCK(lvif); 188 189 lsta->ni = NULL; 190 ni->ni_drv_data = NULL; 191 if (ni != NULL) 192 ieee80211_free_node(ni); 193 194 IMPROVE("more from lkpi_ic_node_free() should happen here."); 195 196 free(lsta, M_LKPI80211); 197 } 198 199 static struct lkpi_sta * 200 lkpi_lsta_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], 201 struct ieee80211_hw *hw, struct ieee80211_node *ni) 202 { 203 struct lkpi_sta *lsta; 204 struct lkpi_vif *lvif; 205 struct ieee80211_vif *vif; 206 struct ieee80211_sta *sta; 207 int tid; 208 209 lsta = malloc(sizeof(*lsta) + hw->sta_data_size, M_LKPI80211, 210 M_NOWAIT | M_ZERO); 211 if (lsta == NULL) 212 return (NULL); 213 214 lsta->added_to_drv = false; 215 lsta->state = IEEE80211_STA_NOTEXIST; 216 #if 0 217 /* 218 * This needs to be done in node_init() as ieee80211_alloc_node() 219 * will initialise the refcount after us. 220 */ 221 lsta->ni = ieee80211_ref_node(ni); 222 #endif 223 /* The back-pointer "drv_data" to net80211_node let's us get lsta. */ 224 ni->ni_drv_data = lsta; 225 226 lvif = VAP_TO_LVIF(vap); 227 vif = LVIF_TO_VIF(lvif); 228 sta = LSTA_TO_STA(lsta); 229 230 IEEE80211_ADDR_COPY(sta->addr, mac); 231 for (tid = 0; tid < nitems(sta->txq); tid++) { 232 struct lkpi_txq *ltxq; 233 234 /* We are not limiting ourselves to hw.queues here. */ 235 ltxq = malloc(sizeof(*ltxq) + hw->txq_data_size, 236 M_LKPI80211, M_NOWAIT | M_ZERO); 237 if (ltxq == NULL) 238 goto cleanup; 239 /* iwlwifi//mvm/sta.c::tid_to_mac80211_ac[] */ 240 if (tid == IEEE80211_NUM_TIDS) { 241 if (!ieee80211_hw_check(hw, STA_MMPDU_TXQ)) { 242 free(ltxq, M_LKPI80211); 243 continue; 244 } 245 IMPROVE("AP/if we support non-STA here too"); 246 ltxq->txq.ac = IEEE80211_AC_VO; 247 } else { 248 ltxq->txq.ac = tid_to_mac80211_ac[tid & 7]; 249 } 250 ltxq->seen_dequeue = false; 251 ltxq->txq.vif = vif; 252 ltxq->txq.tid = tid; 253 ltxq->txq.sta = sta; 254 skb_queue_head_init(<xq->skbq); 255 sta->txq[tid] = <xq->txq; 256 } 257 258 /* Deferred TX path. */ 259 mtx_init(&lsta->txq_mtx, "lsta_txq", NULL, MTX_DEF); 260 TASK_INIT(&lsta->txq_task, 0, lkpi_80211_txq_task, lsta); 261 mbufq_init(&lsta->txq, IFQ_MAXLEN); 262 263 return (lsta); 264 265 cleanup: 266 for (; tid >= 0; tid--) 267 free(sta->txq[tid], M_LKPI80211); 268 free(lsta, M_LKPI80211); 269 return (NULL); 270 } 271 272 static enum nl80211_band 273 lkpi_net80211_chan_to_nl80211_band(struct ieee80211_channel *c) 274 { 275 276 if (IEEE80211_IS_CHAN_2GHZ(c)) 277 return (NL80211_BAND_2GHZ); 278 else if (IEEE80211_IS_CHAN_5GHZ(c)) 279 return (NL80211_BAND_5GHZ); 280 #ifdef __notyet__ 281 else if () 282 return (NL80211_BAND_6GHZ); 283 else if () 284 return (NL80211_BAND_60GHZ); 285 else if (IEEE80211_IS_CHAN_GSM(c)) 286 return (NL80211_BAND_XXX); 287 #endif 288 else 289 panic("%s: unsupported band. c %p flags %#x\n", 290 __func__, c, c->ic_flags); 291 } 292 293 static uint32_t 294 lkpi_nl80211_band_to_net80211_band(enum nl80211_band band) 295 { 296 297 /* XXX-BZ this is just silly; net80211 is too convoluted. */ 298 /* IEEE80211_CHAN_A / _G / .. doesn't really work either. */ 299 switch (band) { 300 case NL80211_BAND_2GHZ: 301 return (IEEE80211_CHAN_2GHZ); 302 break; 303 case NL80211_BAND_5GHZ: 304 return (IEEE80211_CHAN_5GHZ); 305 break; 306 case NL80211_BAND_60GHZ: 307 break; 308 case NL80211_BAND_6GHZ: 309 break; 310 default: 311 panic("%s: unsupported band %u\n", __func__, band); 312 break; 313 } 314 315 IMPROVE(); 316 return (0x00); 317 } 318 319 static enum ieee80211_ac_numbers 320 lkpi_ac_net_to_l80211(int ac) 321 { 322 323 switch (ac) { 324 case WME_AC_VO: 325 return (IEEE80211_AC_VO); 326 case WME_AC_VI: 327 return (IEEE80211_AC_VI); 328 case WME_AC_BE: 329 return (IEEE80211_AC_BE); 330 case WME_AC_BK: 331 return (IEEE80211_AC_BK); 332 default: 333 printf("%s: invalid WME_AC_* input: ac = %d\n", __func__, ac); 334 return (IEEE80211_AC_BE); 335 } 336 } 337 338 static enum nl80211_iftype 339 lkpi_opmode_to_vif_type(enum ieee80211_opmode opmode) 340 { 341 342 switch (opmode) { 343 case IEEE80211_M_IBSS: 344 return (NL80211_IFTYPE_ADHOC); 345 break; 346 case IEEE80211_M_STA: 347 return (NL80211_IFTYPE_STATION); 348 break; 349 case IEEE80211_M_WDS: 350 return (NL80211_IFTYPE_WDS); 351 break; 352 case IEEE80211_M_HOSTAP: 353 return (NL80211_IFTYPE_AP); 354 break; 355 case IEEE80211_M_MONITOR: 356 return (NL80211_IFTYPE_MONITOR); 357 break; 358 case IEEE80211_M_MBSS: 359 return (NL80211_IFTYPE_MESH_POINT); 360 break; 361 case IEEE80211_M_AHDEMO: 362 /* FALLTHROUGH */ 363 default: 364 printf("ERROR: %s: unsupported opmode %d\n", __func__, opmode); 365 /* FALLTHROUGH */ 366 } 367 return (NL80211_IFTYPE_UNSPECIFIED); 368 } 369 370 #ifdef LKPI_80211_HW_CRYPTO 371 static uint32_t 372 lkpi_l80211_to_net80211_cyphers(uint32_t wlan_cipher_suite) 373 { 374 375 switch (wlan_cipher_suite) { 376 case WLAN_CIPHER_SUITE_WEP40: 377 return (IEEE80211_CRYPTO_WEP); 378 case WLAN_CIPHER_SUITE_TKIP: 379 return (IEEE80211_CRYPTO_TKIP); 380 case WLAN_CIPHER_SUITE_CCMP: 381 return (IEEE80211_CIPHER_AES_CCM); 382 case WLAN_CIPHER_SUITE_WEP104: 383 return (IEEE80211_CRYPTO_WEP); 384 case WLAN_CIPHER_SUITE_AES_CMAC: 385 case WLAN_CIPHER_SUITE_GCMP: 386 case WLAN_CIPHER_SUITE_GCMP_256: 387 case WLAN_CIPHER_SUITE_CCMP_256: 388 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 389 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 390 case WLAN_CIPHER_SUITE_BIP_CMAC_256: 391 printf("%s: unsupported WLAN Cipher Suite %#08x | %u\n", __func__, 392 wlan_cipher_suite >> 8, wlan_cipher_suite & 0xff); 393 break; 394 default: 395 printf("%s: unknown WLAN Cipher Suite %#08x | %u\n", __func__, 396 wlan_cipher_suite >> 8, wlan_cipher_suite & 0xff); 397 } 398 399 return (0); 400 } 401 402 static uint32_t 403 lkpi_net80211_to_l80211_cipher_suite(uint32_t cipher, uint8_t keylen) 404 { 405 406 switch (cipher) { 407 case IEEE80211_CIPHER_TKIP: 408 return (WLAN_CIPHER_SUITE_TKIP); 409 case IEEE80211_CIPHER_AES_CCM: 410 return (WLAN_CIPHER_SUITE_CCMP); 411 case IEEE80211_CIPHER_WEP: 412 if (keylen < 8) 413 return (WLAN_CIPHER_SUITE_WEP40); 414 else 415 return (WLAN_CIPHER_SUITE_WEP104); 416 break; 417 case IEEE80211_CIPHER_AES_OCB: 418 case IEEE80211_CIPHER_TKIPMIC: 419 case IEEE80211_CIPHER_CKIP: 420 case IEEE80211_CIPHER_NONE: 421 printf("%s: unsupported cipher %#010x\n", __func__, cipher); 422 break; 423 default: 424 printf("%s: unknown cipher %#010x\n", __func__, cipher); 425 }; 426 return (0); 427 } 428 #endif 429 430 #ifdef __notyet__ 431 static enum ieee80211_sta_state 432 lkpi_net80211_state_to_sta_state(enum ieee80211_state state) 433 { 434 435 /* 436 * XXX-BZ The net80211 states are "try to ..", the lkpi8011 states are 437 * "done". Also ASSOC/AUTHORIZED are both "RUN" then? 438 */ 439 switch (state) { 440 case IEEE80211_S_INIT: 441 return (IEEE80211_STA_NOTEXIST); 442 case IEEE80211_S_SCAN: 443 return (IEEE80211_STA_NONE); 444 case IEEE80211_S_AUTH: 445 return (IEEE80211_STA_AUTH); 446 case IEEE80211_S_ASSOC: 447 return (IEEE80211_STA_ASSOC); 448 case IEEE80211_S_RUN: 449 return (IEEE80211_STA_AUTHORIZED); 450 case IEEE80211_S_CAC: 451 case IEEE80211_S_CSA: 452 case IEEE80211_S_SLEEP: 453 default: 454 UNIMPLEMENTED; 455 }; 456 457 return (IEEE80211_STA_NOTEXIST); 458 } 459 #endif 460 461 static struct linuxkpi_ieee80211_channel * 462 lkpi_find_lkpi80211_chan(struct lkpi_hw *lhw, 463 struct ieee80211_channel *c) 464 { 465 struct ieee80211_hw *hw; 466 struct linuxkpi_ieee80211_channel *channels; 467 enum nl80211_band band; 468 int i, nchans; 469 470 hw = LHW_TO_HW(lhw); 471 band = lkpi_net80211_chan_to_nl80211_band(c); 472 if (hw->wiphy->bands[band] == NULL) 473 return (NULL); 474 475 nchans = hw->wiphy->bands[band]->n_channels; 476 if (nchans <= 0) 477 return (NULL); 478 479 channels = hw->wiphy->bands[band]->channels; 480 for (i = 0; i < nchans; i++) { 481 if (channels[i].hw_value == c->ic_ieee) 482 return (&channels[i]); 483 } 484 485 return (NULL); 486 } 487 488 static struct linuxkpi_ieee80211_channel * 489 lkpi_get_lkpi80211_chan(struct ieee80211com *ic, struct ieee80211_node *ni) 490 { 491 struct linuxkpi_ieee80211_channel *chan; 492 struct ieee80211_channel *c; 493 struct lkpi_hw *lhw; 494 495 chan = NULL; 496 if (ni != NULL && ni->ni_chan != IEEE80211_CHAN_ANYC) 497 c = ni->ni_chan; 498 else if (ic->ic_bsschan != IEEE80211_CHAN_ANYC) 499 c = ic->ic_bsschan; 500 else if (ic->ic_curchan != IEEE80211_CHAN_ANYC) 501 c = ic->ic_curchan; 502 else 503 c = NULL; 504 505 if (c != NULL && c != IEEE80211_CHAN_ANYC) { 506 lhw = ic->ic_softc; 507 chan = lkpi_find_lkpi80211_chan(lhw, c); 508 } 509 510 return (chan); 511 } 512 513 struct linuxkpi_ieee80211_channel * 514 linuxkpi_ieee80211_get_channel(struct wiphy *wiphy, uint32_t freq) 515 { 516 enum nl80211_band band; 517 518 for (band = 0; band < NUM_NL80211_BANDS; band++) { 519 struct ieee80211_supported_band *supband; 520 struct linuxkpi_ieee80211_channel *channels; 521 int i; 522 523 supband = wiphy->bands[band]; 524 if (supband == NULL || supband->n_channels == 0) 525 continue; 526 527 channels = supband->channels; 528 for (i = 0; i < supband->n_channels; i++) { 529 if (channels[i].center_freq == freq) 530 return (&channels[i]); 531 } 532 } 533 534 return (NULL); 535 } 536 537 void 538 linuxkpi_cfg80211_bss_flush(struct wiphy *wiphy) 539 { 540 struct lkpi_hw *lhw; 541 struct ieee80211com *ic; 542 struct ieee80211vap *vap; 543 544 lhw = wiphy_priv(wiphy); 545 ic = lhw->ic; 546 547 /* 548 * If we haven't called ieee80211_ifattach() yet 549 * or there is no VAP, there are no scans to flush. 550 */ 551 if (ic == NULL || 552 (lhw->sc_flags & LKPI_MAC80211_DRV_STARTED) == 0) 553 return; 554 555 /* Should only happen on the current one? Not seen it late enough. */ 556 IEEE80211_LOCK(ic); 557 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) 558 ieee80211_scan_flush(vap); 559 IEEE80211_UNLOCK(ic); 560 } 561 562 #ifdef LKPI_80211_HW_CRYPTO 563 static int 564 _lkpi_iv_key_set_delete(struct ieee80211vap *vap, const struct ieee80211_key *k, 565 enum set_key_cmd cmd) 566 { 567 struct ieee80211com *ic; 568 struct lkpi_hw *lhw; 569 struct ieee80211_hw *hw; 570 struct lkpi_vif *lvif; 571 struct ieee80211_vif *vif; 572 struct ieee80211_sta *sta; 573 struct ieee80211_node *ni; 574 struct ieee80211_key_conf *kc; 575 int error; 576 577 /* XXX TODO Check (k->wk_flags & IEEE80211_KEY_SWENCRYPT) and don't upload to driver/hw? */ 578 579 ic = vap->iv_ic; 580 lhw = ic->ic_softc; 581 hw = LHW_TO_HW(lhw); 582 lvif = VAP_TO_LVIF(vap); 583 vif = LVIF_TO_VIF(lvif); 584 585 memset(&kc, 0, sizeof(kc)); 586 kc = malloc(sizeof(*kc) + k->wk_keylen, M_LKPI80211, M_WAITOK | M_ZERO); 587 kc->cipher = lkpi_net80211_to_l80211_cipher_suite( 588 k->wk_cipher->ic_cipher, k->wk_keylen); 589 kc->keyidx = k->wk_keyix; 590 #if 0 591 kc->hw_key_idx = /* set by hw and needs to be passed for TX */; 592 #endif 593 atomic64_set(&kc->tx_pn, k->wk_keytsc); 594 kc->keylen = k->wk_keylen; 595 memcpy(kc->key, k->wk_key, k->wk_keylen); 596 597 switch (kc->cipher) { 598 case WLAN_CIPHER_SUITE_CCMP: 599 kc->iv_len = k->wk_cipher->ic_header; 600 kc->icv_len = k->wk_cipher->ic_trailer; 601 break; 602 case WLAN_CIPHER_SUITE_TKIP: 603 default: 604 IMPROVE(); 605 return (0); 606 }; 607 608 ni = vap->iv_bss; 609 sta = ieee80211_find_sta(vif, ni->ni_bssid); 610 if (sta != NULL) { 611 struct lkpi_sta *lsta; 612 613 lsta = STA_TO_LSTA(sta); 614 lsta->kc = kc; 615 } 616 617 error = lkpi_80211_mo_set_key(hw, cmd, vif, sta, kc); 618 if (error != 0) { 619 /* XXX-BZ leaking kc currently */ 620 ic_printf(ic, "%s: set_key failed: %d\n", __func__, error); 621 return (0); 622 } else { 623 ic_printf(ic, "%s: set_key succeeded: keyidx %u hw_key_idx %u " 624 "flags %#10x\n", __func__, 625 kc->keyidx, kc->hw_key_idx, kc->flags); 626 return (1); 627 } 628 } 629 630 static int 631 lkpi_iv_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) 632 { 633 634 /* XXX-BZ one day we should replace this iterating over VIFs, or node list? */ 635 return (_lkpi_iv_key_set_delete(vap, k, DISABLE_KEY)); 636 } 637 static int 638 lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k) 639 { 640 641 return (_lkpi_iv_key_set_delete(vap, k, SET_KEY)); 642 } 643 #endif 644 645 static u_int 646 lkpi_ic_update_mcast_copy(void *arg, struct sockaddr_dl *sdl, u_int cnt) 647 { 648 struct netdev_hw_addr_list *mc_list; 649 struct netdev_hw_addr *addr; 650 651 KASSERT(arg != NULL && sdl != NULL, ("%s: arg %p sdl %p cnt %u\n", 652 __func__, arg, sdl, cnt)); 653 654 mc_list = arg; 655 /* If it is on the list already skip it. */ 656 netdev_hw_addr_list_for_each(addr, mc_list) { 657 if (!memcmp(addr->addr, LLADDR(sdl), sdl->sdl_alen)) 658 return (0); 659 } 660 661 addr = malloc(sizeof(*addr), M_LKPI80211, M_NOWAIT | M_ZERO); 662 if (addr == NULL) 663 return (0); 664 665 INIT_LIST_HEAD(&addr->addr_list); 666 memcpy(addr->addr, LLADDR(sdl), sdl->sdl_alen); 667 /* XXX this should be a netdev function? */ 668 list_add(&addr->addr_list, &mc_list->addr_list); 669 mc_list->count++; 670 671 #ifdef LINUXKPI_DEBUG_80211 672 if (linuxkpi_debug_80211 & D80211_TRACE) 673 printf("%s:%d: mc_list count %d: added %6D\n", 674 __func__, __LINE__, mc_list->count, addr->addr, ":"); 675 #endif 676 677 return (1); 678 } 679 680 static void 681 lkpi_update_mcast_filter(struct ieee80211com *ic, bool force) 682 { 683 struct lkpi_hw *lhw; 684 struct ieee80211_hw *hw; 685 struct netdev_hw_addr_list mc_list; 686 struct list_head *le, *next; 687 struct netdev_hw_addr *addr; 688 struct ieee80211vap *vap; 689 u64 mc; 690 unsigned int changed_flags, total_flags; 691 692 lhw = ic->ic_softc; 693 694 if (lhw->ops->prepare_multicast == NULL || 695 lhw->ops->configure_filter == NULL) 696 return; 697 698 if (!lhw->update_mc && !force) 699 return; 700 701 changed_flags = total_flags = 0; 702 mc_list.count = 0; 703 INIT_LIST_HEAD(&mc_list.addr_list); 704 if (ic->ic_allmulti == 0) { 705 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) 706 if_foreach_llmaddr(vap->iv_ifp, 707 lkpi_ic_update_mcast_copy, &mc_list); 708 } else { 709 changed_flags |= FIF_ALLMULTI; 710 } 711 712 hw = LHW_TO_HW(lhw); 713 mc = lkpi_80211_mo_prepare_multicast(hw, &mc_list); 714 /* 715 * XXX-BZ make sure to get this sorted what is a change, 716 * what gets all set; what was already set? 717 */ 718 total_flags = changed_flags; 719 lkpi_80211_mo_configure_filter(hw, changed_flags, &total_flags, mc); 720 721 #ifdef LINUXKPI_DEBUG_80211 722 if (linuxkpi_debug_80211 & D80211_TRACE) 723 printf("%s: changed_flags %#06x count %d total_flags %#010x\n", 724 __func__, changed_flags, mc_list.count, total_flags); 725 #endif 726 727 if (mc_list.count != 0) { 728 list_for_each_safe(le, next, &mc_list.addr_list) { 729 addr = list_entry(le, struct netdev_hw_addr, addr_list); 730 free(addr, M_LKPI80211); 731 mc_list.count--; 732 } 733 } 734 KASSERT(mc_list.count == 0, ("%s: mc_list %p count %d != 0\n", 735 __func__, &mc_list, mc_list.count)); 736 } 737 738 static enum ieee80211_bss_changed 739 lkpi_update_dtim_tsf(struct ieee80211_vif *vif, struct ieee80211_node *ni, 740 struct ieee80211vap *vap, const char *_f, int _l) 741 { 742 enum ieee80211_bss_changed bss_changed; 743 744 bss_changed = 0; 745 746 #ifdef LINUXKPI_DEBUG_80211 747 if (linuxkpi_debug_80211 & D80211_TRACE) 748 printf("%s:%d [%s:%d] assoc %d aid %d beacon_int %u " 749 "dtim_period %u sync_dtim_count %u sync_tsf %ju " 750 "sync_device_ts %u bss_changed %#08x\n", 751 __func__, __LINE__, _f, _l, 752 vif->bss_conf.assoc, vif->bss_conf.aid, 753 vif->bss_conf.beacon_int, vif->bss_conf.dtim_period, 754 vif->bss_conf.sync_dtim_count, 755 (uintmax_t)vif->bss_conf.sync_tsf, 756 vif->bss_conf.sync_device_ts, 757 bss_changed); 758 #endif 759 760 if (vif->bss_conf.beacon_int != ni->ni_intval) { 761 vif->bss_conf.beacon_int = ni->ni_intval; 762 /* iwlwifi FW bug workaround; iwl_mvm_mac_sta_state. */ 763 if (vif->bss_conf.beacon_int < 16) 764 vif->bss_conf.beacon_int = 16; 765 bss_changed |= BSS_CHANGED_BEACON_INT; 766 } 767 if (vif->bss_conf.dtim_period != vap->iv_dtim_period && 768 vap->iv_dtim_period > 0) { 769 vif->bss_conf.dtim_period = vap->iv_dtim_period; 770 bss_changed |= BSS_CHANGED_BEACON_INFO; 771 } 772 773 vif->bss_conf.sync_dtim_count = vap->iv_dtim_count; 774 vif->bss_conf.sync_tsf = le64toh(ni->ni_tstamp.tsf); 775 /* vif->bss_conf.sync_device_ts = set in linuxkpi_ieee80211_rx. */ 776 777 #ifdef LINUXKPI_DEBUG_80211 778 if (linuxkpi_debug_80211 & D80211_TRACE) 779 printf("%s:%d [%s:%d] assoc %d aid %d beacon_int %u " 780 "dtim_period %u sync_dtim_count %u sync_tsf %ju " 781 "sync_device_ts %u bss_changed %#08x\n", 782 __func__, __LINE__, _f, _l, 783 vif->bss_conf.assoc, vif->bss_conf.aid, 784 vif->bss_conf.beacon_int, vif->bss_conf.dtim_period, 785 vif->bss_conf.sync_dtim_count, 786 (uintmax_t)vif->bss_conf.sync_tsf, 787 vif->bss_conf.sync_device_ts, 788 bss_changed); 789 #endif 790 791 return (bss_changed); 792 } 793 794 static void 795 lkpi_stop_hw_scan(struct lkpi_hw *lhw, struct ieee80211_vif *vif) 796 { 797 struct ieee80211_hw *hw; 798 int error; 799 800 if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) == 0) 801 return; 802 803 hw = LHW_TO_HW(lhw); 804 805 IEEE80211_UNLOCK(lhw->ic); 806 LKPI_80211_LHW_LOCK(lhw); 807 /* Need to cancel the scan. */ 808 lkpi_80211_mo_cancel_hw_scan(hw, vif); 809 810 /* Need to make sure we see ieee80211_scan_completed. */ 811 error = msleep(lhw, &lhw->mtx, 0, "lhwscanstop", hz/2); 812 LKPI_80211_LHW_UNLOCK(lhw); 813 IEEE80211_LOCK(lhw->ic); 814 815 if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0) 816 ic_printf(lhw->ic, "%s: failed to cancel scan: %d (%p, %p)\n", 817 __func__, error, lhw, vif); 818 } 819 820 static void 821 lkpi_hw_conf_idle(struct ieee80211_hw *hw, bool new) 822 { 823 struct lkpi_hw *lhw; 824 int error; 825 bool old; 826 827 old = hw->conf.flags & IEEE80211_CONF_IDLE; 828 if (old == new) 829 return; 830 831 hw->conf.flags ^= IEEE80211_CONF_IDLE; 832 error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_IDLE); 833 if (error != 0 && error != EOPNOTSUPP) { 834 lhw = HW_TO_LHW(hw); 835 ic_printf(lhw->ic, "ERROR: %s: config %#0x returned %d\n", 836 __func__, IEEE80211_CONF_CHANGE_IDLE, error); 837 } 838 } 839 840 static void 841 lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif, 842 struct lkpi_hw *lhw) 843 { 844 sta->aid = 0; 845 if (vif->bss_conf.assoc) { 846 struct ieee80211_hw *hw; 847 enum ieee80211_bss_changed changed; 848 849 lhw->update_mc = true; 850 lkpi_update_mcast_filter(lhw->ic, true); 851 852 changed = 0; 853 vif->bss_conf.assoc = false; 854 vif->bss_conf.aid = 0; 855 changed |= BSS_CHANGED_ASSOC; 856 /* 857 * This will remove the sta from firmware for iwlwifi. 858 * So confusing that they use state and flags and ... ^%$%#%$^. 859 */ 860 IMPROVE(); 861 hw = LHW_TO_HW(lhw); 862 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, 863 changed); 864 865 lkpi_hw_conf_idle(hw, true); 866 } 867 } 868 869 static void 870 lkpi_wake_tx_queues(struct ieee80211_hw *hw, struct ieee80211_sta *sta, 871 bool dequeue_seen, bool no_emptyq) 872 { 873 struct lkpi_txq *ltxq; 874 int tid; 875 876 /* Wake up all queues to know they are allocated in the driver. */ 877 for (tid = 0; tid < nitems(sta->txq); tid++) { 878 879 if (tid == IEEE80211_NUM_TIDS) { 880 IMPROVE("station specific?"); 881 if (!ieee80211_hw_check(hw, STA_MMPDU_TXQ)) 882 continue; 883 } else if (tid >= hw->queues) 884 continue; 885 886 if (sta->txq[tid] == NULL) 887 continue; 888 889 ltxq = TXQ_TO_LTXQ(sta->txq[tid]); 890 if (dequeue_seen && !ltxq->seen_dequeue) 891 continue; 892 893 if (no_emptyq && skb_queue_empty(<xq->skbq)) 894 continue; 895 896 lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid]); 897 } 898 } 899 900 /* -------------------------------------------------------------------------- */ 901 902 static int 903 lkpi_sta_state_do_nada(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 904 { 905 906 return (0); 907 } 908 909 /* lkpi_iv_newstate() handles the stop scan case generally. */ 910 #define lkpi_sta_scan_to_init(_v, _n, _a) lkpi_sta_state_do_nada(_v, _n, _a) 911 912 static int 913 lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 914 { 915 struct linuxkpi_ieee80211_channel *chan; 916 struct ieee80211_chanctx_conf *conf; 917 struct lkpi_hw *lhw; 918 struct ieee80211_hw *hw; 919 struct lkpi_vif *lvif; 920 struct ieee80211_vif *vif; 921 struct ieee80211_node *ni; 922 struct lkpi_sta *lsta; 923 struct ieee80211_sta *sta; 924 enum ieee80211_bss_changed bss_changed; 925 struct ieee80211_prep_tx_info prep_tx_info; 926 uint32_t changed; 927 int error; 928 929 chan = lkpi_get_lkpi80211_chan(vap->iv_ic, vap->iv_bss); 930 if (chan == NULL) { 931 ic_printf(vap->iv_ic, "%s: failed to get channel\n", __func__); 932 return (ESRCH); 933 } 934 935 lhw = vap->iv_ic->ic_softc; 936 hw = LHW_TO_HW(lhw); 937 lvif = VAP_TO_LVIF(vap); 938 vif = LVIF_TO_VIF(lvif); 939 940 ni = ieee80211_ref_node(vap->iv_bss); 941 942 IEEE80211_UNLOCK(vap->iv_ic); 943 944 /* Add chanctx (or if exists, change it). */ 945 if (vif->chanctx_conf != NULL) { 946 conf = vif->chanctx_conf; 947 IMPROVE("diff changes for changed, working on live copy, rcu"); 948 } else { 949 /* Keep separate alloc as in Linux this is rcu managed? */ 950 conf = malloc(sizeof(*conf) + hw->chanctx_data_size, 951 M_LKPI80211, M_WAITOK | M_ZERO); 952 } 953 954 conf->rx_chains_dynamic = 1; 955 conf->rx_chains_static = 1; 956 conf->radar_enabled = 957 (chan->flags & IEEE80211_CHAN_RADAR) ? true : false; 958 conf->def.chan = chan; 959 conf->def.width = NL80211_CHAN_WIDTH_20_NOHT; 960 conf->def.center_freq1 = chan->center_freq; 961 conf->def.center_freq2 = 0; 962 /* Responder ... */ 963 conf->min_def.chan = chan; 964 conf->min_def.width = NL80211_CHAN_WIDTH_20_NOHT; 965 conf->min_def.center_freq1 = chan->center_freq; 966 conf->min_def.center_freq2 = 0; 967 IMPROVE("currently 20_NOHT only"); 968 969 error = 0; 970 if (vif->chanctx_conf != NULL) { 971 changed = IEEE80211_CHANCTX_CHANGE_MIN_WIDTH; 972 changed |= IEEE80211_CHANCTX_CHANGE_RADAR; 973 changed |= IEEE80211_CHANCTX_CHANGE_RX_CHAINS; 974 changed |= IEEE80211_CHANCTX_CHANGE_WIDTH; 975 lkpi_80211_mo_change_chanctx(hw, conf, changed); 976 } else { 977 error = lkpi_80211_mo_add_chanctx(hw, conf); 978 if (error == 0 || error == EOPNOTSUPP) { 979 vif->bss_conf.chandef.chan = conf->def.chan; 980 vif->bss_conf.chandef.width = conf->def.width; 981 vif->bss_conf.chandef.center_freq1 = 982 conf->def.center_freq1; 983 vif->bss_conf.chandef.center_freq2 = 984 conf->def.center_freq2; 985 } else { 986 goto out; 987 } 988 /* Assign vif chanctx. */ 989 if (error == 0) 990 error = lkpi_80211_mo_assign_vif_chanctx(hw, vif, conf); 991 if (error == EOPNOTSUPP) 992 error = 0; 993 if (error != 0) { 994 lkpi_80211_mo_remove_chanctx(hw, conf); 995 free(conf, M_LKPI80211); 996 goto out; 997 } 998 } 999 IMPROVE("update radiotap chan fields too"); 1000 1001 /* Set bss info (bss_info_changed). */ 1002 bss_changed = 0; 1003 vif->bss_conf.bssid = ni->ni_bssid; 1004 bss_changed |= BSS_CHANGED_BSSID; 1005 vif->bss_conf.txpower = ni->ni_txpower; 1006 bss_changed |= BSS_CHANGED_TXPOWER; 1007 vif->bss_conf.idle = false; 1008 bss_changed |= BSS_CHANGED_IDLE; 1009 1010 /* Should almost assert it is this. */ 1011 vif->bss_conf.assoc = false; 1012 vif->bss_conf.aid = 0; 1013 1014 bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__); 1015 1016 /* RATES */ 1017 IMPROVE("bss info: not all needs to come now and rates are missing"); 1018 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); 1019 1020 /* 1021 * This is a bandaid for now. If we went through (*iv_update_bss)() 1022 * and then removed the lsta we end up here without a lsta and have 1023 * to manually allocate and link it in as lkpi_ic_node_alloc()/init() 1024 * would normally do. 1025 * XXX-BZ I do not like this but currently we have no good way of 1026 * intercepting the bss swap and state changes and packets going out 1027 * workflow so live with this. It is a compat layer after all. 1028 */ 1029 if (ni->ni_drv_data == NULL) { 1030 lsta = lkpi_lsta_alloc(vap, ni->ni_macaddr, hw, ni); 1031 if (lsta == NULL) { 1032 error = ENOMEM; 1033 goto out; 1034 } 1035 lsta->ni = ieee80211_ref_node(ni); 1036 } else { 1037 lsta = ni->ni_drv_data; 1038 } 1039 1040 /* Insert the [l]sta into the list of known stations. */ 1041 LKPI_80211_LVIF_LOCK(lvif); 1042 TAILQ_INSERT_TAIL(&lvif->lsta_head, lsta, lsta_entry); 1043 LKPI_80211_LVIF_UNLOCK(lvif); 1044 1045 /* Add (or adjust) sta and change state (from NOTEXIST) to NONE. */ 1046 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1047 KASSERT(lsta->state == IEEE80211_STA_NOTEXIST, ("%s: lsta %p state not " 1048 "NOTEXIST: %#x\n", __func__, lsta, lsta->state)); 1049 sta = LSTA_TO_STA(lsta); 1050 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_NONE); 1051 if (error != 0) { 1052 IMPROVE("do we need to undo the chan ctx?"); 1053 goto out; 1054 } 1055 #if 0 1056 lsta->added_to_drv = true; /* mo manages. */ 1057 #endif 1058 1059 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1060 1061 /* 1062 * Wakeup all queues now that sta is there so we have as much time to 1063 * possibly prepare the queue in the driver to be ready for the 1st 1064 * packet; lkpi_80211_txq_tx_one() still has a workaround as there 1065 * is no guarantee or way to check. 1066 * XXX-BZ and by now we know that this does not work on all drivers 1067 * for all queues. 1068 */ 1069 lkpi_wake_tx_queues(hw, sta, false, false); 1070 1071 /* Start mgd_prepare_tx. */ 1072 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1073 prep_tx_info.duration = PREP_TX_INFO_DURATION; 1074 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); 1075 lsta->in_mgd = true; 1076 1077 /* 1078 * What is going to happen next: 1079 * - <twiddle> .. we should end up in "auth_to_assoc" 1080 * - event_callback 1081 * - update sta_state (NONE to AUTH) 1082 * - mgd_complete_tx 1083 * (ideally we'd do that on a callback for something else ...) 1084 */ 1085 1086 out: 1087 IEEE80211_LOCK(vap->iv_ic); 1088 if (ni != NULL) 1089 ieee80211_free_node(ni); 1090 return (error); 1091 } 1092 1093 static int 1094 lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1095 { 1096 struct lkpi_hw *lhw; 1097 struct ieee80211_hw *hw; 1098 struct lkpi_vif *lvif; 1099 struct ieee80211_vif *vif; 1100 struct ieee80211_node *ni; 1101 struct lkpi_sta *lsta; 1102 struct ieee80211_sta *sta; 1103 struct ieee80211_prep_tx_info prep_tx_info; 1104 int error; 1105 1106 lhw = vap->iv_ic->ic_softc; 1107 hw = LHW_TO_HW(lhw); 1108 lvif = VAP_TO_LVIF(vap); 1109 vif = LVIF_TO_VIF(lvif); 1110 1111 /* Keep ni around. */ 1112 ni = ieee80211_ref_node(vap->iv_bss); 1113 lsta = ni->ni_drv_data; 1114 sta = LSTA_TO_STA(lsta); 1115 1116 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1117 1118 IEEE80211_UNLOCK(vap->iv_ic); 1119 1120 /* flush, drop. */ 1121 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), true); 1122 1123 /* Wake tx queues to get packet(s) out. */ 1124 lkpi_wake_tx_queues(hw, sta, true, true); 1125 1126 /* flush, no drop */ 1127 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), false); 1128 1129 /* End mgd_complete_tx. */ 1130 if (lsta->in_mgd) { 1131 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1132 prep_tx_info.success = false; 1133 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); 1134 lsta->in_mgd = false; 1135 } 1136 1137 /* sync_rx_queues */ 1138 lkpi_80211_mo_sync_rx_queues(hw); 1139 1140 /* sta_pre_rcu_remove */ 1141 lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta); 1142 1143 /* Take the station down. */ 1144 1145 /* Adjust sta and change state (from NONE) to NOTEXIST. */ 1146 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1147 KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not " 1148 "NONE: %#x, nstate %d arg %d\n", __func__, lsta, lsta->state, nstate, arg)); 1149 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_NOTEXIST); 1150 if (error != 0) { 1151 IMPROVE("do we need to undo the chan ctx?"); 1152 goto out; 1153 } 1154 #if 0 1155 lsta->added_to_drv = false; /* mo manages. */ 1156 #endif 1157 1158 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1159 1160 lkpi_lsta_remove(lsta, lvif); 1161 1162 /* conf_tx */ 1163 1164 /* Take the chan ctx down. */ 1165 if (vif->chanctx_conf != NULL) { 1166 struct ieee80211_chanctx_conf *conf; 1167 1168 conf = vif->chanctx_conf; 1169 /* Remove vif context. */ 1170 lkpi_80211_mo_unassign_vif_chanctx(hw, vif, &vif->chanctx_conf); 1171 /* NB: vif->chanctx_conf is NULL now. */ 1172 1173 /* Remove chan ctx. */ 1174 lkpi_80211_mo_remove_chanctx(hw, conf); 1175 free(conf, M_LKPI80211); 1176 } 1177 1178 out: 1179 IEEE80211_LOCK(vap->iv_ic); 1180 if (ni != NULL) 1181 ieee80211_free_node(ni); 1182 return (error); 1183 } 1184 1185 static int 1186 lkpi_sta_auth_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1187 { 1188 int error; 1189 1190 error = lkpi_sta_auth_to_scan(vap, nstate, arg); 1191 if (error == 0) 1192 error = lkpi_sta_scan_to_init(vap, nstate, arg); 1193 return (error); 1194 } 1195 1196 static int 1197 lkpi_sta_auth_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1198 { 1199 struct lkpi_hw *lhw; 1200 struct ieee80211_hw *hw; 1201 struct lkpi_vif *lvif; 1202 struct ieee80211_vif *vif; 1203 struct ieee80211_node *ni; 1204 struct lkpi_sta *lsta; 1205 struct ieee80211_sta *sta; 1206 struct ieee80211_prep_tx_info prep_tx_info; 1207 int error; 1208 1209 lhw = vap->iv_ic->ic_softc; 1210 hw = LHW_TO_HW(lhw); 1211 lvif = VAP_TO_LVIF(vap); 1212 vif = LVIF_TO_VIF(lvif); 1213 1214 IEEE80211_UNLOCK(vap->iv_ic); 1215 ni = NULL; 1216 1217 /* Finish auth. */ 1218 IMPROVE("event callback"); 1219 1220 /* Update sta_state (NONE to AUTH). */ 1221 ni = ieee80211_ref_node(vap->iv_bss); 1222 lsta = ni->ni_drv_data; 1223 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1224 KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not " 1225 "NONE: %#x\n", __func__, lsta, lsta->state)); 1226 sta = LSTA_TO_STA(lsta); 1227 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_AUTH); 1228 if (error != 0) 1229 goto out; 1230 1231 /* End mgd_complete_tx. */ 1232 if (lsta->in_mgd) { 1233 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1234 prep_tx_info.success = true; 1235 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); 1236 lsta->in_mgd = false; 1237 } 1238 1239 /* Now start assoc. */ 1240 1241 /* Start mgd_prepare_tx. */ 1242 if (!lsta->in_mgd) { 1243 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1244 prep_tx_info.duration = PREP_TX_INFO_DURATION; 1245 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); 1246 lsta->in_mgd = true; 1247 } 1248 1249 /* Wake tx queue to get packet out. */ 1250 lkpi_wake_tx_queues(hw, sta, true, true); 1251 1252 /* 1253 * <twiddle> .. we end up in "assoc_to_run" 1254 * - update sta_state (AUTH to ASSOC) 1255 * - conf_tx [all] 1256 * - bss_info_changed (assoc, aid, ssid, ..) 1257 * - change_chanctx (if needed) 1258 * - event_callback 1259 * - mgd_complete_tx 1260 */ 1261 1262 out: 1263 IEEE80211_LOCK(vap->iv_ic); 1264 if (ni != NULL) 1265 ieee80211_free_node(ni); 1266 return (error); 1267 } 1268 1269 /* auth_to_auth, assoc_to_assoc. */ 1270 static int 1271 lkpi_sta_a_to_a(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1272 { 1273 struct lkpi_hw *lhw; 1274 struct ieee80211_hw *hw; 1275 struct lkpi_vif *lvif; 1276 struct ieee80211_vif *vif; 1277 struct ieee80211_node *ni; 1278 struct lkpi_sta *lsta; 1279 struct ieee80211_prep_tx_info prep_tx_info; 1280 1281 lhw = vap->iv_ic->ic_softc; 1282 hw = LHW_TO_HW(lhw); 1283 lvif = VAP_TO_LVIF(vap); 1284 vif = LVIF_TO_VIF(lvif); 1285 1286 ni = ieee80211_ref_node(vap->iv_bss); 1287 1288 IEEE80211_UNLOCK(vap->iv_ic); 1289 lsta = ni->ni_drv_data; 1290 1291 IMPROVE("event callback?"); 1292 1293 /* End mgd_complete_tx. */ 1294 if (lsta->in_mgd) { 1295 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1296 prep_tx_info.success = false; 1297 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); 1298 lsta->in_mgd = false; 1299 } 1300 1301 /* Now start assoc. */ 1302 1303 /* Start mgd_prepare_tx. */ 1304 if (!lsta->in_mgd) { 1305 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1306 prep_tx_info.duration = PREP_TX_INFO_DURATION; 1307 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); 1308 lsta->in_mgd = true; 1309 } 1310 1311 IEEE80211_LOCK(vap->iv_ic); 1312 if (ni != NULL) 1313 ieee80211_free_node(ni); 1314 1315 return (0); 1316 } 1317 1318 static int 1319 _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1320 { 1321 struct lkpi_hw *lhw; 1322 struct ieee80211_hw *hw; 1323 struct lkpi_vif *lvif; 1324 struct ieee80211_vif *vif; 1325 struct ieee80211_node *ni; 1326 struct lkpi_sta *lsta; 1327 struct ieee80211_sta *sta; 1328 struct ieee80211_prep_tx_info prep_tx_info; 1329 enum ieee80211_bss_changed bss_changed; 1330 int error; 1331 1332 lhw = vap->iv_ic->ic_softc; 1333 hw = LHW_TO_HW(lhw); 1334 lvif = VAP_TO_LVIF(vap); 1335 vif = LVIF_TO_VIF(lvif); 1336 1337 /* Keep ni around. */ 1338 ni = ieee80211_ref_node(vap->iv_bss); 1339 lsta = ni->ni_drv_data; 1340 sta = LSTA_TO_STA(lsta); 1341 1342 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1343 1344 IEEE80211_UNLOCK(vap->iv_ic); 1345 1346 /* flush, drop. */ 1347 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), true); 1348 1349 IMPROVE("What are the proper conditions for DEAUTH_NEED_MGD_TX_PREP?"); 1350 if (ieee80211_hw_check(hw, DEAUTH_NEED_MGD_TX_PREP) && 1351 !lsta->in_mgd) { 1352 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1353 prep_tx_info.duration = PREP_TX_INFO_DURATION; 1354 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); 1355 lsta->in_mgd = true; 1356 } 1357 1358 IEEE80211_LOCK(vap->iv_ic); 1359 1360 /* Call iv_newstate first so we get potential DISASSOC packet out. */ 1361 error = lvif->iv_newstate(vap, nstate, arg); 1362 if (error != 0) 1363 goto outni; 1364 1365 IEEE80211_UNLOCK(vap->iv_ic); 1366 1367 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1368 1369 /* Wake tx queues to get packet(s) out. */ 1370 lkpi_wake_tx_queues(hw, sta, true, true); 1371 1372 /* flush, no drop */ 1373 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), false); 1374 1375 /* End mgd_complete_tx. */ 1376 if (lsta->in_mgd) { 1377 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1378 prep_tx_info.success = false; 1379 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); 1380 lsta->in_mgd = false; 1381 } 1382 1383 /* sync_rx_queues */ 1384 lkpi_80211_mo_sync_rx_queues(hw); 1385 1386 /* sta_pre_rcu_remove */ 1387 lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta); 1388 1389 /* Take the station down. */ 1390 1391 /* Update sta and change state (from AUTH) to NONE. */ 1392 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1393 KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not " 1394 "AUTH: %#x\n", __func__, lsta, lsta->state)); 1395 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_NONE); 1396 if (error != 0) 1397 goto out; 1398 1399 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1400 1401 /* Adjust sta and change state (from NONE) to NOTEXIST. */ 1402 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1403 KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not " 1404 "NONE: %#x, nstate %d arg %d\n", __func__, lsta, lsta->state, nstate, arg)); 1405 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_NOTEXIST); 1406 if (error != 0) { 1407 IMPROVE("do we need to undo the chan ctx?"); 1408 goto out; 1409 } 1410 #if 0 1411 lsta->added_to_drv = false; /* mo manages. */ 1412 #endif 1413 1414 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1415 1416 /* Update bss info (bss_info_changed) (assoc, aid, ..). */ 1417 /* We need to do this now, can only do after sta is IEEE80211_STA_NOTEXIST. */ 1418 lkpi_disassoc(sta, vif, lhw); 1419 1420 IMPROVE("Any bss_info changes to announce?"); 1421 bss_changed = 0; 1422 vif->bss_conf.qos = 0; 1423 bss_changed |= BSS_CHANGED_QOS; 1424 vif->bss_conf.ssid_len = 0; 1425 memset(vif->bss_conf.ssid, '\0', sizeof(vif->bss_conf.ssid)); 1426 bss_changed |= BSS_CHANGED_BSSID; 1427 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); 1428 1429 lkpi_lsta_remove(lsta, lvif); 1430 1431 /* conf_tx */ 1432 1433 /* Take the chan ctx down. */ 1434 if (vif->chanctx_conf != NULL) { 1435 struct ieee80211_chanctx_conf *conf; 1436 1437 conf = vif->chanctx_conf; 1438 /* Remove vif context. */ 1439 lkpi_80211_mo_unassign_vif_chanctx(hw, vif, &vif->chanctx_conf); 1440 /* NB: vif->chanctx_conf is NULL now. */ 1441 1442 /* Remove chan ctx. */ 1443 lkpi_80211_mo_remove_chanctx(hw, conf); 1444 free(conf, M_LKPI80211); 1445 } 1446 1447 error = EALREADY; 1448 out: 1449 IEEE80211_LOCK(vap->iv_ic); 1450 outni: 1451 if (ni != NULL) 1452 ieee80211_free_node(ni); 1453 return (error); 1454 } 1455 1456 static int 1457 lkpi_sta_assoc_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1458 { 1459 int error; 1460 1461 error = _lkpi_sta_assoc_to_down(vap, nstate, arg); 1462 if (error != 0 && error != EALREADY) 1463 return (error); 1464 1465 /* At this point iv_bss is long a new node! */ 1466 1467 error |= lkpi_sta_scan_to_auth(vap, nstate, 0); 1468 return (error); 1469 } 1470 1471 static int 1472 lkpi_sta_assoc_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1473 { 1474 int error; 1475 1476 error = _lkpi_sta_assoc_to_down(vap, nstate, arg); 1477 return (error); 1478 } 1479 1480 static int 1481 lkpi_sta_assoc_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1482 { 1483 int error; 1484 1485 error = _lkpi_sta_assoc_to_down(vap, nstate, arg); 1486 return (error); 1487 } 1488 1489 static int 1490 lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1491 { 1492 struct lkpi_hw *lhw; 1493 struct ieee80211_hw *hw; 1494 struct lkpi_vif *lvif; 1495 struct ieee80211_vif *vif; 1496 struct ieee80211_node *ni; 1497 struct lkpi_sta *lsta; 1498 struct ieee80211_sta *sta; 1499 struct ieee80211_prep_tx_info prep_tx_info; 1500 enum ieee80211_bss_changed bss_changed; 1501 int error; 1502 1503 lhw = vap->iv_ic->ic_softc; 1504 hw = LHW_TO_HW(lhw); 1505 lvif = VAP_TO_LVIF(vap); 1506 vif = LVIF_TO_VIF(lvif); 1507 1508 IEEE80211_UNLOCK(vap->iv_ic); 1509 ni = NULL; 1510 1511 IMPROVE("ponder some of this moved to ic_newassoc, scan_assoc_success, " 1512 "and to lesser extend ieee80211_notify_node_join"); 1513 1514 /* Finish assoc. */ 1515 /* Update sta_state (AUTH to ASSOC) and set aid. */ 1516 ni = ieee80211_ref_node(vap->iv_bss); 1517 lsta = ni->ni_drv_data; 1518 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1519 KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not " 1520 "AUTH: %#x\n", __func__, lsta, lsta->state)); 1521 sta = LSTA_TO_STA(lsta); 1522 sta->aid = IEEE80211_NODE_AID(ni); 1523 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_ASSOC); 1524 if (error != 0) 1525 goto out; 1526 1527 IMPROVE("wme / conf_tx [all]"); 1528 1529 /* Update bss info (bss_info_changed) (assoc, aid, ..). */ 1530 bss_changed = 0; 1531 if (!vif->bss_conf.assoc || vif->bss_conf.aid != IEEE80211_NODE_AID(ni)) { 1532 vif->bss_conf.assoc = true; 1533 vif->bss_conf.aid = IEEE80211_NODE_AID(ni); 1534 bss_changed |= BSS_CHANGED_ASSOC; 1535 } 1536 /* We set SSID but this is not BSSID! */ 1537 vif->bss_conf.ssid_len = ni->ni_esslen; 1538 memcpy(vif->bss_conf.ssid, ni->ni_essid, ni->ni_esslen); 1539 if ((vap->iv_flags & IEEE80211_F_SHPREAMBLE) != 1540 vif->bss_conf.use_short_preamble) { 1541 vif->bss_conf.use_short_preamble ^= 1; 1542 /* bss_changed |= BSS_CHANGED_??? */ 1543 } 1544 if ((vap->iv_flags & IEEE80211_F_SHSLOT) != 1545 vif->bss_conf.use_short_slot) { 1546 vif->bss_conf.use_short_slot ^= 1; 1547 /* bss_changed |= BSS_CHANGED_??? */ 1548 } 1549 if ((ni->ni_flags & IEEE80211_NODE_QOS) != 1550 vif->bss_conf.qos) { 1551 vif->bss_conf.qos ^= 1; 1552 bss_changed |= BSS_CHANGED_QOS; 1553 } 1554 1555 bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__); 1556 1557 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); 1558 1559 /* - change_chanctx (if needed) 1560 * - event_callback 1561 */ 1562 1563 /* End mgd_complete_tx. */ 1564 if (lsta->in_mgd) { 1565 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1566 prep_tx_info.success = true; 1567 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); 1568 lsta->in_mgd = false; 1569 } 1570 1571 lkpi_hw_conf_idle(hw, false); 1572 1573 /* 1574 * And then: 1575 * - (more packets)? 1576 * - set_key 1577 * - set_default_unicast_key 1578 * - set_key (?) 1579 * - ipv6_addr_change (?) 1580 */ 1581 /* Prepare_multicast && configure_filter. */ 1582 lhw->update_mc = true; 1583 lkpi_update_mcast_filter(vap->iv_ic, true); 1584 1585 if (!ieee80211_node_is_authorized(ni)) { 1586 IMPROVE("net80211 does not consider node authorized"); 1587 } 1588 1589 /* Update sta_state (ASSOC to AUTHORIZED). */ 1590 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1591 KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not " 1592 "ASSOC: %#x\n", __func__, lsta, lsta->state)); 1593 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_AUTHORIZED); 1594 if (error != 0) { 1595 IMPROVE("undo some changes?"); 1596 goto out; 1597 } 1598 1599 /* - drv_config (?) 1600 * - bss_info_changed 1601 * - set_rekey_data (?) 1602 * 1603 * And now we should be passing packets. 1604 */ 1605 IMPROVE("Need that bssid setting, and the keys"); 1606 1607 bss_changed = 0; 1608 bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__); 1609 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); 1610 1611 out: 1612 IEEE80211_LOCK(vap->iv_ic); 1613 if (ni != NULL) 1614 ieee80211_free_node(ni); 1615 return (error); 1616 } 1617 1618 static int 1619 lkpi_sta_auth_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1620 { 1621 int error; 1622 1623 error = lkpi_sta_auth_to_assoc(vap, nstate, arg); 1624 if (error == 0) 1625 error = lkpi_sta_assoc_to_run(vap, nstate, arg); 1626 return (error); 1627 } 1628 1629 static int 1630 lkpi_sta_run_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1631 { 1632 struct lkpi_hw *lhw; 1633 struct ieee80211_hw *hw; 1634 struct lkpi_vif *lvif; 1635 struct ieee80211_vif *vif; 1636 struct ieee80211_node *ni; 1637 struct lkpi_sta *lsta; 1638 struct ieee80211_sta *sta; 1639 struct ieee80211_prep_tx_info prep_tx_info; 1640 #if 0 1641 enum ieee80211_bss_changed bss_changed; 1642 #endif 1643 int error; 1644 1645 lhw = vap->iv_ic->ic_softc; 1646 hw = LHW_TO_HW(lhw); 1647 lvif = VAP_TO_LVIF(vap); 1648 vif = LVIF_TO_VIF(lvif); 1649 1650 /* Keep ni around. */ 1651 ni = ieee80211_ref_node(vap->iv_bss); 1652 lsta = ni->ni_drv_data; 1653 sta = LSTA_TO_STA(lsta); 1654 1655 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1656 1657 IEEE80211_UNLOCK(vap->iv_ic); 1658 1659 /* flush, drop. */ 1660 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), true); 1661 1662 IMPROVE("What are the proper conditions for DEAUTH_NEED_MGD_TX_PREP?"); 1663 if (ieee80211_hw_check(hw, DEAUTH_NEED_MGD_TX_PREP) && 1664 !lsta->in_mgd) { 1665 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1666 prep_tx_info.duration = PREP_TX_INFO_DURATION; 1667 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); 1668 lsta->in_mgd = true; 1669 } 1670 1671 IEEE80211_LOCK(vap->iv_ic); 1672 1673 /* Call iv_newstate first so we get potential DISASSOC packet out. */ 1674 error = lvif->iv_newstate(vap, nstate, arg); 1675 if (error != 0) 1676 goto outni; 1677 1678 IEEE80211_UNLOCK(vap->iv_ic); 1679 1680 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1681 1682 /* Wake tx queues to get packet(s) out. */ 1683 lkpi_wake_tx_queues(hw, sta, true, true); 1684 1685 /* flush, no drop */ 1686 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), false); 1687 1688 /* End mgd_complete_tx. */ 1689 if (lsta->in_mgd) { 1690 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1691 prep_tx_info.success = false; 1692 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); 1693 lsta->in_mgd = false; 1694 } 1695 1696 #if 0 1697 /* sync_rx_queues */ 1698 lkpi_80211_mo_sync_rx_queues(hw); 1699 1700 /* sta_pre_rcu_remove */ 1701 lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta); 1702 #endif 1703 1704 /* Take the station down. */ 1705 1706 /* Adjust sta and change state (from AUTHORIZED) to ASSOC. */ 1707 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1708 KASSERT(lsta->state == IEEE80211_STA_AUTHORIZED, ("%s: lsta %p state not " 1709 "AUTHORIZED: %#x\n", __func__, lsta, lsta->state)); 1710 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_ASSOC); 1711 if (error != 0) 1712 goto out; 1713 1714 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1715 1716 /* Update sta_state (ASSOC to AUTH). */ 1717 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1718 KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not " 1719 "ASSOC: %#x\n", __func__, lsta, lsta->state)); 1720 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_AUTH); 1721 if (error != 0) 1722 goto out; 1723 1724 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1725 1726 #if 0 1727 /* Update bss info (bss_info_changed) (assoc, aid, ..). */ 1728 lkpi_disassoc(sta, vif, lhw); 1729 #endif 1730 1731 error = EALREADY; 1732 out: 1733 IEEE80211_LOCK(vap->iv_ic); 1734 outni: 1735 if (ni != NULL) 1736 ieee80211_free_node(ni); 1737 return (error); 1738 } 1739 1740 static int 1741 lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1742 { 1743 struct lkpi_hw *lhw; 1744 struct ieee80211_hw *hw; 1745 struct lkpi_vif *lvif; 1746 struct ieee80211_vif *vif; 1747 struct ieee80211_node *ni; 1748 struct lkpi_sta *lsta; 1749 struct ieee80211_sta *sta; 1750 struct ieee80211_prep_tx_info prep_tx_info; 1751 enum ieee80211_bss_changed bss_changed; 1752 int error; 1753 1754 lhw = vap->iv_ic->ic_softc; 1755 hw = LHW_TO_HW(lhw); 1756 lvif = VAP_TO_LVIF(vap); 1757 vif = LVIF_TO_VIF(lvif); 1758 1759 /* Keep ni around. */ 1760 ni = ieee80211_ref_node(vap->iv_bss); 1761 lsta = ni->ni_drv_data; 1762 sta = LSTA_TO_STA(lsta); 1763 1764 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1765 1766 IEEE80211_UNLOCK(vap->iv_ic); 1767 1768 /* flush, drop. */ 1769 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), true); 1770 1771 IMPROVE("What are the proper conditions for DEAUTH_NEED_MGD_TX_PREP?"); 1772 if (ieee80211_hw_check(hw, DEAUTH_NEED_MGD_TX_PREP) && 1773 !lsta->in_mgd) { 1774 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1775 prep_tx_info.duration = PREP_TX_INFO_DURATION; 1776 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); 1777 lsta->in_mgd = true; 1778 } 1779 1780 IEEE80211_LOCK(vap->iv_ic); 1781 1782 /* Call iv_newstate first so we get potential DISASSOC packet out. */ 1783 error = lvif->iv_newstate(vap, nstate, arg); 1784 if (error != 0) 1785 goto outni; 1786 1787 IEEE80211_UNLOCK(vap->iv_ic); 1788 1789 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1790 1791 /* Wake tx queues to get packet(s) out. */ 1792 lkpi_wake_tx_queues(hw, sta, true, true); 1793 1794 /* flush, no drop */ 1795 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), false); 1796 1797 /* End mgd_complete_tx. */ 1798 if (lsta->in_mgd) { 1799 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1800 prep_tx_info.success = false; 1801 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); 1802 lsta->in_mgd = false; 1803 } 1804 1805 /* sync_rx_queues */ 1806 lkpi_80211_mo_sync_rx_queues(hw); 1807 1808 /* sta_pre_rcu_remove */ 1809 lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta); 1810 1811 /* Take the station down. */ 1812 1813 /* Adjust sta and change state (from AUTHORIZED) to ASSOC. */ 1814 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1815 KASSERT(lsta->state == IEEE80211_STA_AUTHORIZED, ("%s: lsta %p state not " 1816 "AUTHORIZED: %#x\n", __func__, lsta, lsta->state)); 1817 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_ASSOC); 1818 if (error != 0) 1819 goto out; 1820 1821 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1822 1823 /* Update sta_state (ASSOC to AUTH). */ 1824 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1825 KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not " 1826 "ASSOC: %#x\n", __func__, lsta, lsta->state)); 1827 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_AUTH); 1828 if (error != 0) 1829 goto out; 1830 1831 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1832 1833 /* Update sta and change state (from AUTH) to NONE. */ 1834 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1835 KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not " 1836 "AUTH: %#x\n", __func__, lsta, lsta->state)); 1837 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_NONE); 1838 if (error != 0) 1839 goto out; 1840 1841 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1842 1843 /* Adjust sta and change state (from NONE) to NOTEXIST. */ 1844 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1845 KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not " 1846 "NONE: %#x, nstate %d arg %d\n", __func__, lsta, lsta->state, nstate, arg)); 1847 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_NOTEXIST); 1848 if (error != 0) { 1849 IMPROVE("do we need to undo the chan ctx?"); 1850 goto out; 1851 } 1852 #if 0 1853 lsta->added_to_drv = false; /* mo manages. */ 1854 #endif 1855 1856 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); 1857 1858 /* Update bss info (bss_info_changed) (assoc, aid, ..). */ 1859 /* 1860 * One would expect this to happen when going off AUTHORIZED. 1861 * See comment there; removes the sta from fw. 1862 */ 1863 lkpi_disassoc(sta, vif, lhw); 1864 1865 IMPROVE("Any bss_info changes to announce?"); 1866 bss_changed = 0; 1867 vif->bss_conf.qos = 0; 1868 bss_changed |= BSS_CHANGED_QOS; 1869 vif->bss_conf.ssid_len = 0; 1870 memset(vif->bss_conf.ssid, '\0', sizeof(vif->bss_conf.ssid)); 1871 bss_changed |= BSS_CHANGED_BSSID; 1872 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); 1873 1874 lkpi_lsta_remove(lsta, lvif); 1875 1876 /* conf_tx */ 1877 1878 /* Take the chan ctx down. */ 1879 if (vif->chanctx_conf != NULL) { 1880 struct ieee80211_chanctx_conf *conf; 1881 1882 conf = vif->chanctx_conf; 1883 /* Remove vif context. */ 1884 lkpi_80211_mo_unassign_vif_chanctx(hw, vif, &vif->chanctx_conf); 1885 /* NB: vif->chanctx_conf is NULL now. */ 1886 1887 /* Remove chan ctx. */ 1888 lkpi_80211_mo_remove_chanctx(hw, conf); 1889 free(conf, M_LKPI80211); 1890 } 1891 1892 error = EALREADY; 1893 out: 1894 IEEE80211_LOCK(vap->iv_ic); 1895 outni: 1896 if (ni != NULL) 1897 ieee80211_free_node(ni); 1898 return (error); 1899 } 1900 1901 static int 1902 lkpi_sta_run_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1903 { 1904 1905 return (lkpi_sta_run_to_init(vap, nstate, arg)); 1906 } 1907 1908 static int 1909 lkpi_sta_run_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1910 { 1911 int error; 1912 1913 error = lkpi_sta_run_to_init(vap, nstate, arg); 1914 if (error != 0 && error != EALREADY) 1915 return (error); 1916 1917 /* At this point iv_bss is long a new node! */ 1918 1919 error |= lkpi_sta_scan_to_auth(vap, nstate, 0); 1920 return (error); 1921 } 1922 1923 /* -------------------------------------------------------------------------- */ 1924 1925 /* 1926 * The matches the documented state changes in net80211::sta_newstate(). 1927 * XXX (1) without CSA and SLEEP yet, * XXX (2) not all unhandled cases 1928 * there are "invalid" (so there is a room for failure here). 1929 */ 1930 struct fsm_state { 1931 /* INIT, SCAN, AUTH, ASSOC, CAC, RUN, CSA, SLEEP */ 1932 enum ieee80211_state ostate; 1933 enum ieee80211_state nstate; 1934 int (*handler)(struct ieee80211vap *, enum ieee80211_state, int); 1935 } sta_state_fsm[] = { 1936 { IEEE80211_S_INIT, IEEE80211_S_INIT, lkpi_sta_state_do_nada }, 1937 { IEEE80211_S_SCAN, IEEE80211_S_INIT, lkpi_sta_state_do_nada }, /* scan_to_init */ 1938 { IEEE80211_S_AUTH, IEEE80211_S_INIT, lkpi_sta_auth_to_init }, /* not explicitly in sta_newstate() */ 1939 { IEEE80211_S_ASSOC, IEEE80211_S_INIT, lkpi_sta_assoc_to_init }, /* Send DEAUTH. */ 1940 { IEEE80211_S_RUN, IEEE80211_S_INIT, lkpi_sta_run_to_init }, /* Send DISASSOC. */ 1941 1942 { IEEE80211_S_INIT, IEEE80211_S_SCAN, lkpi_sta_state_do_nada }, 1943 { IEEE80211_S_SCAN, IEEE80211_S_SCAN, lkpi_sta_state_do_nada }, 1944 { IEEE80211_S_AUTH, IEEE80211_S_SCAN, lkpi_sta_auth_to_scan }, 1945 { IEEE80211_S_ASSOC, IEEE80211_S_SCAN, lkpi_sta_assoc_to_scan }, 1946 { IEEE80211_S_RUN, IEEE80211_S_SCAN, lkpi_sta_run_to_scan }, /* Beacon miss. */ 1947 1948 { IEEE80211_S_INIT, IEEE80211_S_AUTH, lkpi_sta_scan_to_auth }, /* Send AUTH. */ 1949 { IEEE80211_S_SCAN, IEEE80211_S_AUTH, lkpi_sta_scan_to_auth }, /* Send AUTH. */ 1950 { IEEE80211_S_AUTH, IEEE80211_S_AUTH, lkpi_sta_a_to_a }, /* Send ?AUTH. */ 1951 { IEEE80211_S_ASSOC, IEEE80211_S_AUTH, lkpi_sta_assoc_to_auth }, /* Send ?AUTH. */ 1952 { IEEE80211_S_RUN, IEEE80211_S_AUTH, lkpi_sta_run_to_auth }, /* Send ?AUTH. */ 1953 1954 { IEEE80211_S_AUTH, IEEE80211_S_ASSOC, lkpi_sta_auth_to_assoc }, /* Send ASSOCREQ. */ 1955 { IEEE80211_S_ASSOC, IEEE80211_S_ASSOC, lkpi_sta_a_to_a }, /* Send ASSOCREQ. */ 1956 { IEEE80211_S_RUN, IEEE80211_S_ASSOC, lkpi_sta_run_to_assoc }, /* Send ASSOCREQ/REASSOCREQ. */ 1957 1958 { IEEE80211_S_AUTH, IEEE80211_S_RUN, lkpi_sta_auth_to_run }, 1959 { IEEE80211_S_ASSOC, IEEE80211_S_RUN, lkpi_sta_assoc_to_run }, 1960 { IEEE80211_S_RUN, IEEE80211_S_RUN, lkpi_sta_state_do_nada }, 1961 1962 /* Dummy at the end without handler. */ 1963 { IEEE80211_S_INIT, IEEE80211_S_INIT, NULL }, 1964 }; 1965 1966 static int 1967 lkpi_iv_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1968 { 1969 struct ieee80211com *ic; 1970 struct lkpi_hw *lhw; 1971 struct lkpi_vif *lvif; 1972 struct ieee80211_vif *vif; 1973 struct fsm_state *s; 1974 enum ieee80211_state ostate; 1975 int error; 1976 1977 ic = vap->iv_ic; 1978 IEEE80211_LOCK_ASSERT(ic); 1979 ostate = vap->iv_state; 1980 1981 #ifdef LINUXKPI_DEBUG_80211 1982 if (linuxkpi_debug_80211 & D80211_TRACE) 1983 ic_printf(vap->iv_ic, "%s:%d: vap %p nstate %#x arg %#x\n", 1984 __func__, __LINE__, vap, nstate, arg); 1985 #endif 1986 1987 if (vap->iv_opmode == IEEE80211_M_STA) { 1988 1989 lhw = ic->ic_softc; 1990 lvif = VAP_TO_LVIF(vap); 1991 vif = LVIF_TO_VIF(lvif); 1992 1993 /* No need to replicate this in most state handlers. */ 1994 if (ostate == IEEE80211_S_SCAN && nstate != IEEE80211_S_SCAN) 1995 lkpi_stop_hw_scan(lhw, vif); 1996 1997 s = sta_state_fsm; 1998 1999 } else { 2000 ic_printf(vap->iv_ic, "%s: only station mode currently supported: " 2001 "cap %p iv_opmode %d\n", __func__, vap, vap->iv_opmode); 2002 return (ENOSYS); 2003 } 2004 2005 error = 0; 2006 for (; s->handler != NULL; s++) { 2007 if (ostate == s->ostate && nstate == s->nstate) { 2008 #ifdef LINUXKPI_DEBUG_80211 2009 if (linuxkpi_debug_80211 & D80211_TRACE) 2010 ic_printf(vap->iv_ic, "%s: new state %d (%s) ->" 2011 " %d (%s): arg %d.\n", __func__, 2012 ostate, ieee80211_state_name[ostate], 2013 nstate, ieee80211_state_name[nstate], arg); 2014 #endif 2015 error = s->handler(vap, nstate, arg); 2016 break; 2017 } 2018 } 2019 IEEE80211_LOCK_ASSERT(vap->iv_ic); 2020 2021 if (s->handler == NULL) { 2022 IMPROVE("turn this into a KASSERT\n"); 2023 ic_printf(vap->iv_ic, "%s: unsupported state transition " 2024 "%d (%s) -> %d (%s)\n", __func__, 2025 ostate, ieee80211_state_name[ostate], 2026 nstate, ieee80211_state_name[nstate]); 2027 return (ENOSYS); 2028 } 2029 2030 if (error == EALREADY) { 2031 #ifdef LINUXKPI_DEBUG_80211 2032 if (linuxkpi_debug_80211 & D80211_TRACE) 2033 ic_printf(vap->iv_ic, "%s: state transition %d (%s) -> " 2034 "%d (%s): iv_newstate already handled: %d.\n", 2035 __func__, ostate, ieee80211_state_name[ostate], 2036 nstate, ieee80211_state_name[nstate], error); 2037 #endif 2038 return (0); 2039 } 2040 2041 if (error != 0) { 2042 /* XXX-BZ currently expected so ignore. */ 2043 ic_printf(vap->iv_ic, "%s: error %d during state transition " 2044 "%d (%s) -> %d (%s)\n", __func__, error, 2045 ostate, ieee80211_state_name[ostate], 2046 nstate, ieee80211_state_name[nstate]); 2047 /* return (error); */ 2048 } 2049 2050 #ifdef LINUXKPI_DEBUG_80211 2051 if (linuxkpi_debug_80211 & D80211_TRACE) 2052 ic_printf(vap->iv_ic, "%s:%d: vap %p nstate %#x arg %#x " 2053 "calling net80211 parent\n", 2054 __func__, __LINE__, vap, nstate, arg); 2055 #endif 2056 2057 return (lvif->iv_newstate(vap, nstate, arg)); 2058 } 2059 2060 /* -------------------------------------------------------------------------- */ 2061 2062 /* 2063 * We overload (*iv_update_bss) as otherwise we have cases in, e.g., 2064 * net80211::ieee80211_sta_join1() where vap->iv_bss gets replaced by a 2065 * new node without us knowing and thus our ni/lsta are out of sync. 2066 */ 2067 static struct ieee80211_node * 2068 lkpi_iv_update_bss(struct ieee80211vap *vap, struct ieee80211_node *ni) 2069 { 2070 struct lkpi_vif *lvif; 2071 struct ieee80211_node *obss; 2072 struct lkpi_sta *lsta; 2073 struct ieee80211_sta *sta; 2074 2075 obss = vap->iv_bss; 2076 2077 #ifdef LINUXKPI_DEBUG_80211 2078 if (linuxkpi_debug_80211 & D80211_TRACE) 2079 ic_printf(vap->iv_ic, "%s: obss %p ni_drv_data %p " 2080 "ni %p ni_drv_data %p\n", __func__, 2081 obss, (obss != NULL) ? obss->ni_drv_data : NULL, 2082 ni, (ni != NULL) ? ni->ni_drv_data : NULL); 2083 #endif 2084 2085 /* Nothing to copy from. Just return. */ 2086 if (obss == NULL || obss->ni_drv_data == NULL) 2087 goto out; 2088 2089 /* Nothing to copy to. Just return. */ 2090 IMPROVE("clearing the obss might still be needed?"); 2091 if (ni == NULL) 2092 goto out; 2093 2094 /* Nothing changed? panic? */ 2095 if (obss == ni) 2096 goto out; 2097 2098 lsta = obss->ni_drv_data; 2099 obss->ni_drv_data = ni->ni_drv_data; 2100 ni->ni_drv_data = lsta; 2101 if (lsta != NULL) { 2102 lsta->ni = ni; 2103 sta = LSTA_TO_STA(lsta); 2104 IEEE80211_ADDR_COPY(sta->addr, lsta->ni->ni_macaddr); 2105 } 2106 lsta = obss->ni_drv_data; 2107 if (lsta != NULL) { 2108 lsta->ni = obss; 2109 sta = LSTA_TO_STA(lsta); 2110 IEEE80211_ADDR_COPY(sta->addr, lsta->ni->ni_macaddr); 2111 } 2112 2113 out: 2114 lvif = VAP_TO_LVIF(vap); 2115 return (lvif->iv_update_bss(vap, ni)); 2116 } 2117 2118 static int 2119 lkpi_ic_wme_update(struct ieee80211com *ic) 2120 { 2121 /* This needs queuing and go at the right moment. */ 2122 #ifdef WITH_WME_UPDATE 2123 struct ieee80211vap *vap; 2124 struct lkpi_hw *lhw; 2125 struct ieee80211_hw *hw; 2126 struct lkpi_vif *lvif; 2127 struct ieee80211_vif *vif; 2128 struct chanAccParams chp; 2129 struct wmeParams wmeparr[WME_NUM_AC]; 2130 struct ieee80211_tx_queue_params txqp; 2131 enum ieee80211_bss_changed changed; 2132 int error; 2133 uint16_t ac; 2134 #endif 2135 2136 IMPROVE(); 2137 KASSERT(WME_NUM_AC == IEEE80211_NUM_ACS, ("%s: WME_NUM_AC %d != " 2138 "IEEE80211_NUM_ACS %d\n", __func__, WME_NUM_AC, IEEE80211_NUM_ACS)); 2139 2140 #ifdef WITH_WME_UPDATE 2141 vap = TAILQ_FIRST(&ic->ic_vaps); 2142 if (vap == NULL) 2143 return (0); 2144 2145 /* We should factor this out into per-vap (*wme_update). */ 2146 lhw = ic->ic_softc; 2147 if (lhw->ops->conf_tx == NULL) 2148 return (0); 2149 2150 /* XXX-BZ check amount of hw queues */ 2151 hw = LHW_TO_HW(lhw); 2152 lvif = VAP_TO_LVIF(vap); 2153 vif = LVIF_TO_VIF(lvif); 2154 2155 ieee80211_wme_ic_getparams(ic, &chp); 2156 IEEE80211_LOCK(ic); 2157 for (ac = 0; ac < WME_NUM_AC; ac++) 2158 wmeparr[ac] = chp.cap_wmeParams[ac]; 2159 IEEE80211_UNLOCK(ic); 2160 2161 /* Configure tx queues (conf_tx) & send BSS_CHANGED_QOS. */ 2162 LKPI_80211_LHW_LOCK(lhw); 2163 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 2164 struct wmeParams *wmep; 2165 2166 /* XXX-BZ should keep this in lvif? */ 2167 wmep = &wmeparr[ac]; 2168 bzero(&txqp, sizeof(txqp)); 2169 txqp.cw_min = wmep->wmep_logcwmin; 2170 txqp.cw_max = wmep->wmep_logcwmax; 2171 txqp.txop = wmep->wmep_txopLimit; 2172 txqp.aifs = wmep->wmep_aifsn; 2173 error = lkpi_80211_mo_conf_tx(hw, vif, ac, &txqp); 2174 if (error != 0) 2175 printf("%s: conf_tx ac %u failed %d\n", 2176 __func__, ac, error); 2177 } 2178 LKPI_80211_LHW_UNLOCK(lhw); 2179 changed = BSS_CHANGED_QOS; 2180 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed); 2181 #endif 2182 2183 return (0); 2184 } 2185 2186 static struct ieee80211vap * 2187 lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], 2188 int unit, enum ieee80211_opmode opmode, int flags, 2189 const uint8_t bssid[IEEE80211_ADDR_LEN], 2190 const uint8_t mac[IEEE80211_ADDR_LEN]) 2191 { 2192 struct lkpi_hw *lhw; 2193 struct ieee80211_hw *hw; 2194 struct lkpi_vif *lvif; 2195 struct ieee80211vap *vap; 2196 struct ieee80211_vif *vif; 2197 enum ieee80211_bss_changed changed; 2198 size_t len; 2199 int error; 2200 2201 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* 1 so far. Add <n> once this works. */ 2202 return (NULL); 2203 2204 lhw = ic->ic_softc; 2205 hw = LHW_TO_HW(lhw); 2206 2207 len = sizeof(*lvif); 2208 len += hw->vif_data_size; /* vif->drv_priv */ 2209 2210 lvif = malloc(len, M_80211_VAP, M_WAITOK | M_ZERO); 2211 mtx_init(&lvif->mtx, "lvif", NULL, MTX_DEF); 2212 TAILQ_INIT(&lvif->lsta_head); 2213 vap = LVIF_TO_VAP(lvif); 2214 2215 vif = LVIF_TO_VIF(lvif); 2216 memcpy(vif->addr, mac, IEEE80211_ADDR_LEN); 2217 vif->p2p = false; 2218 vif->probe_req_reg = false; 2219 vif->type = lkpi_opmode_to_vif_type(opmode); 2220 lvif->wdev.iftype = vif->type; 2221 /* Need to fill in other fields as well. */ 2222 IMPROVE(); 2223 2224 /* XXX-BZ hardcoded for now! */ 2225 #if 1 2226 vif->chanctx_conf = NULL; 2227 vif->bss_conf.idle = true; 2228 vif->bss_conf.ps = false; 2229 vif->bss_conf.chandef.width = NL80211_CHAN_WIDTH_20_NOHT; 2230 vif->bss_conf.use_short_preamble = false; /* vap->iv_flags IEEE80211_F_SHPREAMBLE */ 2231 vif->bss_conf.use_short_slot = false; /* vap->iv_flags IEEE80211_F_SHSLOT */ 2232 vif->bss_conf.qos = false; 2233 vif->bss_conf.use_cts_prot = false; /* vap->iv_protmode */ 2234 vif->bss_conf.ht_operation_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONE; 2235 vif->bss_conf.assoc = false; 2236 vif->bss_conf.aid = 0; 2237 /* 2238 * We need to initialize it to something as the bss_info_changed call 2239 * will try to copy from it in iwlwifi and NULL is a panic. 2240 * We will set the proper one in scan_to_auth() before being assoc. 2241 * NB: the logic there with using an array as bssid_override and checking 2242 * for non-NULL later is flawed but in their workflow does not seem to 2243 * matter. 2244 */ 2245 vif->bss_conf.bssid = zerobssid; 2246 #endif 2247 #if 0 2248 vif->bss_conf.dtim_period = 0; /* IEEE80211_DTIM_DEFAULT ; must stay 0. */ 2249 IEEE80211_ADDR_COPY(vif->bss_conf.bssid, bssid); 2250 vif->bss_conf.beacon_int = ic->ic_bintval; 2251 /* iwlwifi bug. */ 2252 if (vif->bss_conf.beacon_int < 16) 2253 vif->bss_conf.beacon_int = 16; 2254 #endif 2255 IMPROVE(); 2256 2257 error = lkpi_80211_mo_start(hw); 2258 if (error != 0) { 2259 printf("%s: failed to start hw: %d\n", __func__, error); 2260 mtx_destroy(&lvif->mtx); 2261 free(lvif, M_80211_VAP); 2262 return (NULL); 2263 } 2264 2265 error = lkpi_80211_mo_add_interface(hw, vif); 2266 if (error != 0) { 2267 IMPROVE(); /* XXX-BZ mo_stop()? */ 2268 printf("%s: failed to add interface: %d\n", __func__, error); 2269 mtx_destroy(&lvif->mtx); 2270 free(lvif, M_80211_VAP); 2271 return (NULL); 2272 } 2273 2274 LKPI_80211_LHW_LVIF_LOCK(lhw); 2275 TAILQ_INSERT_TAIL(&lhw->lvif_head, lvif, lvif_entry); 2276 LKPI_80211_LHW_LVIF_UNLOCK(lhw); 2277 2278 /* Set bss_info. */ 2279 changed = 0; 2280 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed); 2281 2282 /* conf_tx setup; default WME? */ 2283 2284 /* Force MC init. */ 2285 lkpi_update_mcast_filter(ic, true); 2286 2287 IMPROVE(); 2288 2289 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); 2290 2291 /* Override with LinuxKPI method so we can drive mac80211/cfg80211. */ 2292 lvif->iv_newstate = vap->iv_newstate; 2293 vap->iv_newstate = lkpi_iv_newstate; 2294 lvif->iv_update_bss = vap->iv_update_bss; 2295 vap->iv_update_bss = lkpi_iv_update_bss; 2296 2297 /* Key management. */ 2298 if (lhw->ops->set_key != NULL) { 2299 #ifdef LKPI_80211_HW_CRYPTO 2300 vap->iv_key_set = lkpi_iv_key_set; 2301 vap->iv_key_delete = lkpi_iv_key_delete; 2302 #endif 2303 } 2304 2305 ieee80211_ratectl_init(vap); 2306 2307 /* Complete setup. */ 2308 ieee80211_vap_attach(vap, ieee80211_media_change, 2309 ieee80211_media_status, mac); 2310 2311 if (hw->max_listen_interval == 0) 2312 hw->max_listen_interval = 7 * (ic->ic_lintval / ic->ic_bintval); 2313 hw->conf.listen_interval = hw->max_listen_interval; 2314 ic->ic_set_channel(ic); 2315 2316 /* XXX-BZ do we need to be able to update these? */ 2317 hw->wiphy->frag_threshold = vap->iv_fragthreshold; 2318 lkpi_80211_mo_set_frag_threshold(hw, vap->iv_fragthreshold); 2319 hw->wiphy->rts_threshold = vap->iv_rtsthreshold; 2320 lkpi_80211_mo_set_rts_threshold(hw, vap->iv_rtsthreshold); 2321 /* any others? */ 2322 IMPROVE(); 2323 2324 return (vap); 2325 } 2326 2327 static void 2328 lkpi_ic_vap_delete(struct ieee80211vap *vap) 2329 { 2330 struct ieee80211com *ic; 2331 struct lkpi_hw *lhw; 2332 struct ieee80211_hw *hw; 2333 struct lkpi_vif *lvif; 2334 struct ieee80211_vif *vif; 2335 2336 lvif = VAP_TO_LVIF(vap); 2337 vif = LVIF_TO_VIF(lvif); 2338 ic = vap->iv_ic; 2339 lhw = ic->ic_softc; 2340 hw = LHW_TO_HW(lhw); 2341 2342 LKPI_80211_LHW_LVIF_LOCK(lhw); 2343 TAILQ_REMOVE(&lhw->lvif_head, lvif, lvif_entry); 2344 LKPI_80211_LHW_LVIF_UNLOCK(lhw); 2345 lkpi_80211_mo_remove_interface(hw, vif); 2346 2347 ieee80211_ratectl_deinit(vap); 2348 ieee80211_vap_detach(vap); 2349 mtx_destroy(&lvif->mtx); 2350 free(lvif, M_80211_VAP); 2351 } 2352 2353 static void 2354 lkpi_ic_update_mcast(struct ieee80211com *ic) 2355 { 2356 2357 lkpi_update_mcast_filter(ic, false); 2358 TRACEOK(); 2359 } 2360 2361 static void 2362 lkpi_ic_update_promisc(struct ieee80211com *ic) 2363 { 2364 2365 UNIMPLEMENTED; 2366 } 2367 2368 static void 2369 lkpi_ic_update_chw(struct ieee80211com *ic) 2370 { 2371 2372 UNIMPLEMENTED; 2373 } 2374 2375 /* Start / stop device. */ 2376 static void 2377 lkpi_ic_parent(struct ieee80211com *ic) 2378 { 2379 struct lkpi_hw *lhw; 2380 struct ieee80211_hw *hw; 2381 int error; 2382 bool start_all; 2383 2384 IMPROVE(); 2385 2386 lhw = ic->ic_softc; 2387 hw = LHW_TO_HW(lhw); 2388 start_all = false; 2389 2390 if (ic->ic_nrunning > 0) { 2391 error = lkpi_80211_mo_start(hw); 2392 if (error == 0) 2393 start_all = true; 2394 } else { 2395 lkpi_80211_mo_stop(hw); 2396 } 2397 2398 if (start_all) 2399 ieee80211_start_all(ic); 2400 } 2401 2402 bool 2403 linuxkpi_ieee80211_is_ie_id_in_ie_buf(const u8 ie, const u8 *ie_ids, 2404 size_t ie_ids_len) 2405 { 2406 int i; 2407 2408 for (i = 0; i < ie_ids_len; i++) { 2409 if (ie == *ie_ids) 2410 return (true); 2411 } 2412 2413 return (false); 2414 } 2415 2416 /* Return true if skipped; false if error. */ 2417 bool 2418 linuxkpi_ieee80211_ie_advance(size_t *xp, const u8 *ies, size_t ies_len) 2419 { 2420 size_t x; 2421 uint8_t l; 2422 2423 x = *xp; 2424 2425 KASSERT(x < ies_len, ("%s: x %zu ies_len %zu ies %p\n", 2426 __func__, x, ies_len, ies)); 2427 l = ies[x + 1]; 2428 x += 2 + l; 2429 2430 if (x > ies_len) 2431 return (false); 2432 2433 *xp = x; 2434 return (true); 2435 } 2436 2437 static uint8_t * 2438 lkpi_scan_ies_add(uint8_t *p, struct ieee80211_scan_ies *scan_ies, 2439 uint32_t band_mask, struct ieee80211vap *vap, struct ieee80211_hw *hw) 2440 { 2441 struct ieee80211_supported_band *supband; 2442 struct linuxkpi_ieee80211_channel *channels; 2443 const struct ieee80211_channel *chan; 2444 const struct ieee80211_rateset *rs; 2445 uint8_t *pb; 2446 int band, i; 2447 2448 for (band = 0; band < NUM_NL80211_BANDS; band++) { 2449 if ((band_mask & (1 << band)) == 0) 2450 continue; 2451 2452 supband = hw->wiphy->bands[band]; 2453 /* 2454 * This should not happen; 2455 * band_mask is a bitmask of valid bands to scan on. 2456 */ 2457 if (supband == NULL || supband->n_channels == 0) 2458 continue; 2459 2460 /* Find a first channel to get the mode and rates from. */ 2461 channels = supband->channels; 2462 chan = NULL; 2463 for (i = 0; i < supband->n_channels; i++) { 2464 2465 if (channels[i].flags & IEEE80211_CHAN_DISABLED) 2466 continue; 2467 2468 chan = ieee80211_find_channel(vap->iv_ic, 2469 channels[i].center_freq, 0); 2470 if (chan != NULL) 2471 break; 2472 } 2473 2474 /* This really should not happen. */ 2475 if (chan == NULL) 2476 continue; 2477 2478 pb = p; 2479 rs = ieee80211_get_suprates(vap->iv_ic, chan); /* calls chan2mode */ 2480 p = ieee80211_add_rates(p, rs); 2481 p = ieee80211_add_xrates(p, rs); 2482 2483 scan_ies->ies[band] = pb; 2484 scan_ies->len[band] = p - pb; 2485 } 2486 2487 /* Add common_ies */ 2488 pb = p; 2489 if ((vap->iv_flags & IEEE80211_F_WPA1) != 0 && 2490 vap->iv_wpa_ie != NULL) { 2491 memcpy(p, vap->iv_wpa_ie, 2 + vap->iv_wpa_ie[1]); 2492 p += 2 + vap->iv_wpa_ie[1]; 2493 } 2494 if (vap->iv_appie_probereq != NULL) { 2495 memcpy(p, vap->iv_appie_probereq->ie_data, 2496 vap->iv_appie_probereq->ie_len); 2497 p += vap->iv_appie_probereq->ie_len; 2498 } 2499 scan_ies->common_ies = pb; 2500 scan_ies->common_ie_len = p - pb; 2501 2502 return (p); 2503 } 2504 2505 static void 2506 lkpi_ic_scan_start(struct ieee80211com *ic) 2507 { 2508 struct lkpi_hw *lhw; 2509 struct ieee80211_hw *hw; 2510 struct lkpi_vif *lvif; 2511 struct ieee80211_vif *vif; 2512 struct ieee80211_scan_state *ss; 2513 struct ieee80211vap *vap; 2514 int error; 2515 2516 lhw = ic->ic_softc; 2517 if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0) { 2518 /* A scan is still running. */ 2519 return; 2520 } 2521 2522 ss = ic->ic_scan; 2523 vap = ss->ss_vap; 2524 if (vap->iv_state != IEEE80211_S_SCAN) { 2525 IMPROVE("We need to be able to scan if not in S_SCAN"); 2526 return; 2527 } 2528 2529 hw = LHW_TO_HW(lhw); 2530 if ((lhw->scan_flags & LKPI_LHW_SCAN_HW) == 0) { 2531 /* If hw_scan is cleared clear FEXT_SCAN_OFFLOAD too. */ 2532 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCAN_OFFLOAD; 2533 sw_scan: 2534 lvif = VAP_TO_LVIF(vap); 2535 vif = LVIF_TO_VIF(lvif); 2536 2537 if (vap->iv_state == IEEE80211_S_SCAN) 2538 lkpi_hw_conf_idle(hw, false); 2539 2540 lkpi_80211_mo_sw_scan_start(hw, vif, vif->addr); 2541 /* net80211::scan_start() handled PS for us. */ 2542 IMPROVE(); 2543 /* XXX Also means it is too late to flush queues? 2544 * need to check iv_sta_ps or overload? */ 2545 /* XXX want to adjust ss end time/ maxdwell? */ 2546 2547 } else { 2548 struct ieee80211_channel *c; 2549 struct ieee80211_scan_request *hw_req; 2550 struct linuxkpi_ieee80211_channel *lc, **cpp; 2551 struct cfg80211_ssid *ssids; 2552 struct cfg80211_scan_6ghz_params *s6gp; 2553 size_t chan_len, nchan, ssids_len, s6ghzlen; 2554 int band, i, ssid_count, common_ie_len; 2555 uint32_t band_mask; 2556 uint8_t *ie, *ieend; 2557 2558 if (!ieee80211_hw_check(hw, SINGLE_SCAN_ON_ALL_BANDS)) { 2559 IMPROVE("individual band scans not yet supported"); 2560 /* In theory net80211 would have to drive this. */ 2561 return; 2562 } 2563 2564 ssid_count = min(ss->ss_nssid, hw->wiphy->max_scan_ssids); 2565 ssids_len = ssid_count * sizeof(*ssids); 2566 s6ghzlen = 0 * (sizeof(*s6gp)); /* XXX-BZ */ 2567 2568 band_mask = 0; 2569 nchan = 0; 2570 for (i = ss->ss_next; i < ss->ss_last; i++) { 2571 nchan++; 2572 band = lkpi_net80211_chan_to_nl80211_band( 2573 ss->ss_chans[ss->ss_next + i]); 2574 band_mask |= (1 << band); 2575 } 2576 chan_len = nchan * (sizeof(lc) + sizeof(*lc)); 2577 2578 common_ie_len = 0; 2579 if ((vap->iv_flags & IEEE80211_F_WPA1) != 0 && 2580 vap->iv_wpa_ie != NULL) 2581 common_ie_len += vap->iv_wpa_ie[1]; 2582 if (vap->iv_appie_probereq != NULL) 2583 common_ie_len += vap->iv_appie_probereq->ie_len; 2584 2585 /* We would love to check this at an earlier stage... */ 2586 if (common_ie_len > hw->wiphy->max_scan_ie_len) { 2587 ic_printf(ic, "WARNING: %s: common_ie_len %d > " 2588 "wiphy->max_scan_ie_len %d\n", __func__, 2589 common_ie_len, hw->wiphy->max_scan_ie_len); 2590 } 2591 2592 KASSERT(lhw->hw_req == NULL, ("%s: ic %p lhw %p hw_req %p " 2593 "!= NULL\n", __func__, ic, lhw, lhw->hw_req)); 2594 2595 lhw->hw_req = hw_req = malloc(sizeof(*hw_req) + ssids_len + 2596 s6ghzlen + chan_len + lhw->supbands * lhw->scan_ie_len + 2597 common_ie_len, M_LKPI80211, M_WAITOK | M_ZERO); 2598 2599 hw_req->req.flags = 0; /* XXX ??? */ 2600 /* hw_req->req.wdev */ 2601 hw_req->req.wiphy = hw->wiphy; 2602 hw_req->req.no_cck = false; /* XXX */ 2603 #if 0 2604 /* This seems to pessimise default scanning behaviour. */ 2605 hw_req->req.duration_mandatory = TICKS_2_USEC(ss->ss_mindwell); 2606 hw_req->req.duration = TICKS_2_USEC(ss->ss_maxdwell); 2607 #endif 2608 #ifdef __notyet__ 2609 hw_req->req.flags |= NL80211_SCAN_FLAG_RANDOM_ADDR; 2610 memcpy(hw_req->req.mac_addr, xxx, IEEE80211_ADDR_LEN); 2611 memset(hw_req->req.mac_addr_mask, 0xxx, IEEE80211_ADDR_LEN); 2612 #endif 2613 2614 hw_req->req.n_channels = nchan; 2615 cpp = (struct linuxkpi_ieee80211_channel **)(hw_req + 1); 2616 lc = (struct linuxkpi_ieee80211_channel *)(cpp + nchan); 2617 for (i = 0; i < nchan; i++) { 2618 *(cpp + i) = 2619 (struct linuxkpi_ieee80211_channel *)(lc + i); 2620 } 2621 for (i = 0; i < nchan; i++) { 2622 c = ss->ss_chans[ss->ss_next + i]; 2623 2624 lc->hw_value = c->ic_ieee; 2625 lc->center_freq = c->ic_freq; 2626 /* lc->flags */ 2627 lc->band = lkpi_net80211_chan_to_nl80211_band(c); 2628 lc->max_power = c->ic_maxpower; 2629 /* lc-> ... */ 2630 lc++; 2631 } 2632 2633 hw_req->req.n_ssids = ssid_count; 2634 if (hw_req->req.n_ssids > 0) { 2635 ssids = (struct cfg80211_ssid *)lc; 2636 hw_req->req.ssids = ssids; 2637 for (i = 0; i < ssid_count; i++) { 2638 ssids->ssid_len = ss->ss_ssid[i].len; 2639 memcpy(ssids->ssid, ss->ss_ssid[i].ssid, 2640 ss->ss_ssid[i].len); 2641 ssids++; 2642 } 2643 s6gp = (struct cfg80211_scan_6ghz_params *)ssids; 2644 } else { 2645 s6gp = (struct cfg80211_scan_6ghz_params *)lc; 2646 } 2647 2648 /* 6GHz one day. */ 2649 hw_req->req.n_6ghz_params = 0; 2650 hw_req->req.scan_6ghz_params = NULL; 2651 hw_req->req.scan_6ghz = false; /* Weird boolean; not what you think. */ 2652 /* s6gp->... */ 2653 2654 ie = ieend = (uint8_t *)s6gp; 2655 /* Copy per-band IEs, copy common IEs */ 2656 ieend = lkpi_scan_ies_add(ie, &hw_req->ies, band_mask, vap, hw); 2657 hw_req->req.ie = ie; 2658 hw_req->req.ie_len = ieend - ie; 2659 2660 lvif = VAP_TO_LVIF(vap); 2661 vif = LVIF_TO_VIF(lvif); 2662 error = lkpi_80211_mo_hw_scan(hw, vif, hw_req); 2663 if (error != 0) { 2664 ieee80211_cancel_scan(vap); 2665 2666 free(hw_req, M_LKPI80211); 2667 lhw->hw_req = NULL; 2668 2669 /* 2670 * XXX-SIGH magic number. 2671 * rtw88 has a magic "return 1" if offloading scan is 2672 * not possible. Fall back to sw scan in that case. 2673 */ 2674 if (error == 1) { 2675 lhw->scan_flags &= ~LKPI_LHW_SCAN_HW; 2676 ieee80211_start_scan(vap, 2677 IEEE80211_SCAN_ACTIVE | 2678 IEEE80211_SCAN_NOPICK | 2679 IEEE80211_SCAN_ONCE, 2680 IEEE80211_SCAN_FOREVER, 2681 ss->ss_mindwell ? ss->ss_mindwell : msecs_to_ticks(20), 2682 ss->ss_maxdwell ? ss->ss_maxdwell : msecs_to_ticks(200), 2683 vap->iv_des_nssid, vap->iv_des_ssid); 2684 goto sw_scan; 2685 } 2686 2687 ic_printf(ic, "ERROR: %s: hw_scan returned %d\n", 2688 __func__, error); 2689 } 2690 } 2691 } 2692 2693 static void 2694 lkpi_ic_scan_end(struct ieee80211com *ic) 2695 { 2696 struct lkpi_hw *lhw; 2697 2698 lhw = ic->ic_softc; 2699 if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) == 0) { 2700 return; 2701 } 2702 2703 if ((lhw->scan_flags & LKPI_LHW_SCAN_HW) == 0) { 2704 struct ieee80211_scan_state *ss; 2705 struct ieee80211vap *vap; 2706 struct ieee80211_hw *hw; 2707 struct lkpi_vif *lvif; 2708 struct ieee80211_vif *vif; 2709 2710 ss = ic->ic_scan; 2711 vap = ss->ss_vap; 2712 hw = LHW_TO_HW(lhw); 2713 lvif = VAP_TO_LVIF(vap); 2714 vif = LVIF_TO_VIF(lvif); 2715 2716 lkpi_80211_mo_sw_scan_complete(hw, vif); 2717 2718 /* Send PS to stop buffering if n80211 does not for us? */ 2719 2720 if (vap->iv_state == IEEE80211_S_SCAN) 2721 lkpi_hw_conf_idle(hw, true); 2722 } 2723 } 2724 2725 static void 2726 lkpi_ic_scan_curchan(struct ieee80211_scan_state *ss, 2727 unsigned long maxdwell) 2728 { 2729 struct lkpi_hw *lhw; 2730 2731 lhw = ss->ss_ic->ic_softc; 2732 if ((lhw->scan_flags & LKPI_LHW_SCAN_HW) == 0) 2733 lhw->ic_scan_curchan(ss, maxdwell); 2734 } 2735 2736 static void 2737 lkpi_ic_scan_mindwell(struct ieee80211_scan_state *ss) 2738 { 2739 struct lkpi_hw *lhw; 2740 2741 lhw = ss->ss_ic->ic_softc; 2742 if ((lhw->scan_flags & LKPI_LHW_SCAN_HW) == 0) 2743 lhw->ic_scan_mindwell(ss); 2744 } 2745 2746 static void 2747 lkpi_ic_set_channel(struct ieee80211com *ic) 2748 { 2749 struct lkpi_hw *lhw; 2750 struct ieee80211_hw *hw; 2751 struct ieee80211_channel *c; 2752 struct linuxkpi_ieee80211_channel *chan; 2753 int error; 2754 2755 lhw = ic->ic_softc; 2756 2757 /* If we do not support (*config)() save us the work. */ 2758 if (lhw->ops->config == NULL) 2759 return; 2760 2761 /* If we have a hw_scan running do not switch channels. */ 2762 if ((lhw->scan_flags & (LKPI_LHW_SCAN_RUNNING|LKPI_LHW_SCAN_HW)) == 2763 (LKPI_LHW_SCAN_RUNNING|LKPI_LHW_SCAN_HW)) 2764 return; 2765 2766 c = ic->ic_curchan; 2767 if (c == NULL || c == IEEE80211_CHAN_ANYC) { 2768 ic_printf(ic, "%s: c %p ops->config %p\n", __func__, 2769 c, lhw->ops->config); 2770 return; 2771 } 2772 2773 chan = lkpi_find_lkpi80211_chan(lhw, c); 2774 if (chan == NULL) { 2775 ic_printf(ic, "%s: c %p chan %p\n", __func__, 2776 c, chan); 2777 return; 2778 } 2779 2780 /* XXX max power for scanning? */ 2781 IMPROVE(); 2782 2783 hw = LHW_TO_HW(lhw); 2784 cfg80211_chandef_create(&hw->conf.chandef, chan, 2785 NL80211_CHAN_NO_HT); 2786 2787 error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_CHANNEL); 2788 if (error != 0 && error != EOPNOTSUPP) { 2789 ic_printf(ic, "ERROR: %s: config %#0x returned %d\n", 2790 __func__, IEEE80211_CONF_CHANGE_CHANNEL, error); 2791 /* XXX should we unroll to the previous chandef? */ 2792 IMPROVE(); 2793 } else { 2794 /* Update radiotap channels as well. */ 2795 lhw->rtap_tx.wt_chan_freq = htole16(c->ic_freq); 2796 lhw->rtap_tx.wt_chan_flags = htole16(c->ic_flags); 2797 lhw->rtap_rx.wr_chan_freq = htole16(c->ic_freq); 2798 lhw->rtap_rx.wr_chan_flags = htole16(c->ic_flags); 2799 } 2800 2801 /* Currently PS is hard coded off! Not sure it belongs here. */ 2802 IMPROVE(); 2803 if (ieee80211_hw_check(hw, SUPPORTS_PS) && 2804 (hw->conf.flags & IEEE80211_CONF_PS) != 0) { 2805 hw->conf.flags &= ~IEEE80211_CONF_PS; 2806 error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_PS); 2807 if (error != 0 && error != EOPNOTSUPP) 2808 ic_printf(ic, "ERROR: %s: config %#0x returned " 2809 "%d\n", __func__, IEEE80211_CONF_CHANGE_PS, 2810 error); 2811 } 2812 } 2813 2814 static struct ieee80211_node * 2815 lkpi_ic_node_alloc(struct ieee80211vap *vap, 2816 const uint8_t mac[IEEE80211_ADDR_LEN]) 2817 { 2818 struct ieee80211com *ic; 2819 struct lkpi_hw *lhw; 2820 struct ieee80211_node *ni; 2821 struct ieee80211_hw *hw; 2822 struct lkpi_sta *lsta; 2823 2824 ic = vap->iv_ic; 2825 lhw = ic->ic_softc; 2826 2827 /* We keep allocations de-coupled so we can deal with the two worlds. */ 2828 if (lhw->ic_node_alloc == NULL) 2829 return (NULL); 2830 2831 ni = lhw->ic_node_alloc(vap, mac); 2832 if (ni == NULL) 2833 return (NULL); 2834 2835 hw = LHW_TO_HW(lhw); 2836 lsta = lkpi_lsta_alloc(vap, mac, hw, ni); 2837 if (lsta == NULL) { 2838 if (lhw->ic_node_free != NULL) 2839 lhw->ic_node_free(ni); 2840 return (NULL); 2841 } 2842 2843 return (ni); 2844 } 2845 2846 static int 2847 lkpi_ic_node_init(struct ieee80211_node *ni) 2848 { 2849 struct ieee80211com *ic; 2850 struct lkpi_hw *lhw; 2851 struct lkpi_sta *lsta; 2852 int error; 2853 2854 ic = ni->ni_ic; 2855 lhw = ic->ic_softc; 2856 2857 if (lhw->ic_node_init != NULL) { 2858 error = lhw->ic_node_init(ni); 2859 if (error != 0) 2860 return (error); 2861 } 2862 2863 lsta = ni->ni_drv_data; 2864 2865 /* Now take the reference before linking it to the table. */ 2866 lsta->ni = ieee80211_ref_node(ni); 2867 2868 /* XXX-BZ Sync other state over. */ 2869 IMPROVE(); 2870 2871 return (0); 2872 } 2873 2874 static void 2875 lkpi_ic_node_cleanup(struct ieee80211_node *ni) 2876 { 2877 struct ieee80211com *ic; 2878 struct lkpi_hw *lhw; 2879 2880 ic = ni->ni_ic; 2881 lhw = ic->ic_softc; 2882 2883 /* XXX-BZ remove from driver, ... */ 2884 IMPROVE(); 2885 2886 if (lhw->ic_node_cleanup != NULL) 2887 lhw->ic_node_cleanup(ni); 2888 } 2889 2890 static void 2891 lkpi_ic_node_free(struct ieee80211_node *ni) 2892 { 2893 struct ieee80211com *ic; 2894 struct lkpi_hw *lhw; 2895 struct lkpi_sta *lsta; 2896 2897 ic = ni->ni_ic; 2898 lhw = ic->ic_softc; 2899 lsta = ni->ni_drv_data; 2900 if (lsta == NULL) 2901 goto out; 2902 2903 /* XXX-BZ free resources, ... */ 2904 IMPROVE(); 2905 2906 /* Flush mbufq (make sure to release ni refs!). */ 2907 #ifdef __notyet__ 2908 KASSERT(mbufq_len(&lsta->txq) == 0, ("%s: lsta %p has txq len %d != 0\n", 2909 __func__, lsta, mbufq_len(&lsta->txq))); 2910 #endif 2911 /* Drain taskq. */ 2912 2913 /* Drain sta->txq[] */ 2914 mtx_destroy(&lsta->txq_mtx); 2915 2916 /* Remove lsta if added_to_drv. */ 2917 2918 /* Remove lsta from vif */ 2919 /* Remove ref from lsta node... */ 2920 /* Free lsta. */ 2921 lkpi_lsta_remove(lsta, VAP_TO_LVIF(ni->ni_vap)); 2922 2923 out: 2924 if (lhw->ic_node_free != NULL) 2925 lhw->ic_node_free(ni); 2926 } 2927 2928 static int 2929 lkpi_ic_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2930 const struct ieee80211_bpf_params *params __unused) 2931 { 2932 struct lkpi_sta *lsta; 2933 2934 lsta = ni->ni_drv_data; 2935 2936 /* Queue the packet and enqueue the task to handle it. */ 2937 LKPI_80211_LSTA_LOCK(lsta); 2938 mbufq_enqueue(&lsta->txq, m); 2939 LKPI_80211_LSTA_UNLOCK(lsta); 2940 2941 #ifdef LINUXKPI_DEBUG_80211 2942 if (linuxkpi_debug_80211 & D80211_TRACE_TX) 2943 printf("%s:%d lsta %p ni %p %6D mbuf_qlen %d\n", 2944 __func__, __LINE__, lsta, ni, ni->ni_macaddr, ":", 2945 mbufq_len(&lsta->txq)); 2946 #endif 2947 2948 taskqueue_enqueue(taskqueue_thread, &lsta->txq_task); 2949 return (0); 2950 } 2951 2952 static void 2953 lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m) 2954 { 2955 struct ieee80211_node *ni; 2956 #ifndef LKPI_80211_HW_CRYPTO 2957 struct ieee80211_frame *wh; 2958 #endif 2959 struct ieee80211_key *k; 2960 struct sk_buff *skb; 2961 struct ieee80211com *ic; 2962 struct lkpi_hw *lhw; 2963 struct ieee80211_hw *hw; 2964 struct lkpi_vif *lvif; 2965 struct ieee80211_vif *vif; 2966 struct ieee80211_channel *c; 2967 struct ieee80211_tx_control control; 2968 struct ieee80211_tx_info *info; 2969 struct ieee80211_sta *sta; 2970 void *buf; 2971 int ac; 2972 2973 M_ASSERTPKTHDR(m); 2974 #ifdef LINUXKPI_DEBUG_80211 2975 if (linuxkpi_debug_80211 & D80211_TRACE_TX_DUMP) 2976 hexdump(mtod(m, const void *), m->m_len, "RAW TX (plain) ", 0); 2977 #endif 2978 2979 ni = lsta->ni; 2980 k = NULL; 2981 #ifndef LKPI_80211_HW_CRYPTO 2982 /* Encrypt the frame if need be; XXX-BZ info->control.hw_key. */ 2983 wh = mtod(m, struct ieee80211_frame *); 2984 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 2985 /* Retrieve key for TX && do software encryption. */ 2986 k = ieee80211_crypto_encap(ni, m); 2987 if (k == NULL) { 2988 ieee80211_free_node(ni); 2989 m_freem(m); 2990 return; 2991 } 2992 } 2993 #endif 2994 2995 ic = ni->ni_ic; 2996 lhw = ic->ic_softc; 2997 hw = LHW_TO_HW(lhw); 2998 c = ni->ni_chan; 2999 3000 if (ieee80211_radiotap_active_vap(ni->ni_vap)) { 3001 struct lkpi_radiotap_tx_hdr *rtap; 3002 3003 rtap = &lhw->rtap_tx; 3004 rtap->wt_flags = 0; 3005 if (k != NULL) 3006 rtap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; 3007 if (m->m_flags & M_FRAG) 3008 rtap->wt_flags |= IEEE80211_RADIOTAP_F_FRAG; 3009 IMPROVE(); 3010 rtap->wt_rate = 0; 3011 if (c != NULL && c != IEEE80211_CHAN_ANYC) { 3012 rtap->wt_chan_freq = htole16(c->ic_freq); 3013 rtap->wt_chan_flags = htole16(c->ic_flags); 3014 } 3015 3016 ieee80211_radiotap_tx(ni->ni_vap, m); 3017 } 3018 3019 /* 3020 * net80211 should handle hw->extra_tx_headroom. 3021 * Though for as long as we are copying we don't mind. 3022 * XXX-BZ rtw88 asks for too much headroom for ipv6+tcp: 3023 * https://lists.freebsd.org/archives/freebsd-transport/2022-February/000012.html 3024 */ 3025 skb = dev_alloc_skb(hw->extra_tx_headroom + m->m_pkthdr.len); 3026 if (skb == NULL) { 3027 printf("XXX ERROR %s: skb alloc failed\n", __func__); 3028 ieee80211_free_node(ni); 3029 m_freem(m); 3030 return; 3031 } 3032 skb_reserve(skb, hw->extra_tx_headroom); 3033 3034 /* XXX-BZ we need a SKB version understanding mbuf. */ 3035 /* Save the mbuf for ieee80211_tx_complete(). */ 3036 skb->m_free_func = lkpi_ieee80211_free_skb_mbuf; 3037 skb->m = m; 3038 #if 0 3039 skb_put_data(skb, m->m_data, m->m_pkthdr.len); 3040 #else 3041 buf = skb_put(skb, m->m_pkthdr.len); 3042 m_copydata(m, 0, m->m_pkthdr.len, buf); 3043 #endif 3044 /* Save the ni. */ 3045 m->m_pkthdr.PH_loc.ptr = ni; 3046 3047 lvif = VAP_TO_LVIF(ni->ni_vap); 3048 vif = LVIF_TO_VIF(lvif); 3049 3050 /* XXX-BZ review this at some point [4] vs. [8] vs. [16](TID). */ 3051 ac = M_WME_GETAC(m); 3052 skb->priority = WME_AC_TO_TID(ac); 3053 ac = lkpi_ac_net_to_l80211(ac); 3054 skb_set_queue_mapping(skb, ac); 3055 3056 info = IEEE80211_SKB_CB(skb); 3057 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; 3058 /* Slight delay; probably only happens on scanning so fine? */ 3059 if (c == NULL || c == IEEE80211_CHAN_ANYC) 3060 c = ic->ic_curchan; 3061 info->band = lkpi_net80211_chan_to_nl80211_band(c); 3062 info->hw_queue = ac; /* XXX-BZ is this correct? */ 3063 if (m->m_flags & M_EAPOL) 3064 info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO; 3065 info->control.vif = vif; 3066 /* XXX-BZ info->control.rates */ 3067 3068 lsta = lkpi_find_lsta_by_ni(lvif, ni); 3069 if (lsta != NULL) { 3070 sta = LSTA_TO_STA(lsta); 3071 #ifdef LKPI_80211_HW_CRYPTO 3072 info->control.hw_key = lsta->kc; 3073 #endif 3074 } else { 3075 sta = NULL; 3076 } 3077 3078 IMPROVE(); 3079 3080 if (sta != NULL) { 3081 struct lkpi_txq *ltxq; 3082 struct ieee80211_hdr *hdr; 3083 3084 hdr = (void *)skb->data; 3085 if (lsta->added_to_drv && 3086 !ieee80211_is_data_present(hdr->frame_control)) { 3087 if (sta->txq[IEEE80211_NUM_TIDS] != NULL) 3088 ltxq = TXQ_TO_LTXQ(sta->txq[IEEE80211_NUM_TIDS]); 3089 else 3090 goto ops_tx; 3091 } else if (lsta->added_to_drv) { 3092 ltxq = TXQ_TO_LTXQ(sta->txq[ac]); /* XXX-BZ re-check */ 3093 } else 3094 goto ops_tx; 3095 KASSERT(ltxq != NULL, ("%s: lsta %p sta %p m %p skb %p " 3096 "ltxq %p != NULL\n", __func__, lsta, sta, m, skb, ltxq)); 3097 3098 /* 3099 * We currently do not use queues but do direct TX. 3100 * The exception to the rule is initial packets, as we cannot 3101 * TX until queues are allocated (at least for iwlwifi). 3102 * So we wake_tx_queue in newstate and register any dequeue 3103 * calls. In the time until then we queue packets and 3104 * let the driver deal with them. 3105 */ 3106 #if 0 3107 if (!ltxq->seen_dequeue) { 3108 3109 /* Prevent an ordering problem, likely other issues. */ 3110 while (!skb_queue_empty(<xq->skbq)) { 3111 struct sk_buff *skb2; 3112 3113 skb2 = skb_dequeue(<xq->skbq); 3114 if (skb2 != NULL) { 3115 memset(&control, 0, sizeof(control)); 3116 control.sta = sta; 3117 lkpi_80211_mo_tx(hw, &control, skb2); 3118 } 3119 } 3120 goto ops_tx; 3121 } 3122 if (0 && ltxq->seen_dequeue && skb_queue_empty(<xq->skbq)) 3123 goto ops_tx; 3124 #endif 3125 3126 skb_queue_tail(<xq->skbq, skb); 3127 #ifdef LINUXKPI_DEBUG_80211 3128 if (linuxkpi_debug_80211 & D80211_TRACE_TX) 3129 printf("%s:%d mo_wake_tx_queue :: %d %u lsta %p sta %p " 3130 "ni %p %6D skb %p lxtq %p { qlen %u, ac %d tid %u } " 3131 "WAKE_TX_Q ac %d prio %u qmap %u\n", 3132 __func__, __LINE__, 3133 curthread->td_tid, (unsigned int)ticks, 3134 lsta, sta, ni, ni->ni_macaddr, ":", skb, ltxq, 3135 skb_queue_len(<xq->skbq), ltxq->txq.ac, 3136 ltxq->txq.tid, ac, skb->priority, skb->qmap); 3137 #endif 3138 lkpi_80211_mo_wake_tx_queue(hw, <xq->txq); 3139 return; 3140 } 3141 3142 ops_tx: 3143 #ifdef LINUXKPI_DEBUG_80211 3144 if (linuxkpi_debug_80211 & D80211_TRACE_TX) 3145 printf("%s:%d mo_tx :: lsta %p sta %p ni %p %6D skb %p " 3146 "TX ac %d prio %u qmap %u\n", 3147 __func__, __LINE__, lsta, sta, ni, ni->ni_macaddr, ":", 3148 skb, ac, skb->priority, skb->qmap); 3149 #endif 3150 memset(&control, 0, sizeof(control)); 3151 control.sta = sta; 3152 3153 lkpi_80211_mo_tx(hw, &control, skb); 3154 return; 3155 } 3156 3157 static void 3158 lkpi_80211_txq_task(void *ctx, int pending) 3159 { 3160 struct lkpi_sta *lsta; 3161 struct mbufq mq; 3162 struct mbuf *m; 3163 3164 lsta = ctx; 3165 3166 #ifdef LINUXKPI_DEBUG_80211 3167 if (linuxkpi_debug_80211 & D80211_TRACE_TX) 3168 printf("%s:%d lsta %p ni %p %6D pending %d mbuf_qlen %d\n", 3169 __func__, __LINE__, lsta, lsta->ni, lsta->ni->ni_macaddr, ":", 3170 pending, mbufq_len(&lsta->txq)); 3171 #endif 3172 3173 mbufq_init(&mq, IFQ_MAXLEN); 3174 3175 LKPI_80211_LSTA_LOCK(lsta); 3176 mbufq_concat(&mq, &lsta->txq); 3177 LKPI_80211_LSTA_UNLOCK(lsta); 3178 3179 m = mbufq_dequeue(&mq); 3180 while (m != NULL) { 3181 lkpi_80211_txq_tx_one(lsta, m); 3182 m = mbufq_dequeue(&mq); 3183 } 3184 } 3185 3186 static int 3187 lkpi_ic_transmit(struct ieee80211com *ic, struct mbuf *m) 3188 { 3189 3190 /* XXX TODO */ 3191 IMPROVE(); 3192 3193 /* Quick and dirty cheating hack. */ 3194 struct ieee80211_node *ni; 3195 3196 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 3197 return (lkpi_ic_raw_xmit(ni, m, NULL)); 3198 } 3199 3200 static void 3201 lkpi_ic_getradiocaps(struct ieee80211com *ic, int maxchan, 3202 int *n, struct ieee80211_channel *c) 3203 { 3204 struct lkpi_hw *lhw; 3205 struct ieee80211_hw *hw; 3206 struct linuxkpi_ieee80211_channel *channels; 3207 uint8_t bands[IEEE80211_MODE_BYTES]; 3208 int chan_flags, error, i, nchans; 3209 3210 /* Channels */ 3211 lhw = ic->ic_softc; 3212 hw = LHW_TO_HW(lhw); 3213 3214 /* NL80211_BAND_2GHZ */ 3215 nchans = 0; 3216 if (hw->wiphy->bands[NL80211_BAND_2GHZ] != NULL) 3217 nchans = hw->wiphy->bands[NL80211_BAND_2GHZ]->n_channels; 3218 if (nchans > 0) { 3219 memset(bands, 0, sizeof(bands)); 3220 chan_flags = 0; 3221 setbit(bands, IEEE80211_MODE_11B); 3222 /* XXX-BZ unclear how to check for 11g. */ 3223 setbit(bands, IEEE80211_MODE_11G); 3224 #ifdef __notyet__ 3225 if (hw->wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.ht_supported) { 3226 setbit(bands, IEEE80211_MODE_11NG); 3227 chan_flags |= NET80211_CBW_FLAG_HT40; 3228 } 3229 #endif 3230 3231 channels = hw->wiphy->bands[NL80211_BAND_2GHZ]->channels; 3232 for (i = 0; i < nchans && *n < maxchan; i++) { 3233 uint32_t nflags = 0; 3234 int cflags = chan_flags; 3235 3236 if (channels[i].flags & IEEE80211_CHAN_DISABLED) { 3237 printf("%s: %s: Skipping disabled chan " 3238 "[%u/%u/%#x]\n", ic->ic_name, __func__, 3239 channels[i].hw_value, 3240 channels[i].center_freq, channels[i].flags); 3241 continue; 3242 } 3243 if (channels[i].flags & IEEE80211_CHAN_NO_IR) 3244 nflags |= (IEEE80211_CHAN_NOADHOC|IEEE80211_CHAN_PASSIVE); 3245 if (channels[i].flags & IEEE80211_CHAN_RADAR) 3246 nflags |= IEEE80211_CHAN_DFS; 3247 if (channels[i].flags & IEEE80211_CHAN_NO_160MHZ) 3248 cflags &= ~(NET80211_CBW_FLAG_VHT160|NET80211_CBW_FLAG_VHT80P80); 3249 if (channels[i].flags & IEEE80211_CHAN_NO_80MHZ) 3250 cflags &= ~NET80211_CBW_FLAG_VHT80; 3251 /* XXX how to map the remaining enum ieee80211_channel_flags? */ 3252 if (channels[i].flags & IEEE80211_CHAN_NO_HT40) 3253 cflags &= ~NET80211_CBW_FLAG_HT40; 3254 3255 error = ieee80211_add_channel_cbw(c, maxchan, n, 3256 channels[i].hw_value, channels[i].center_freq, 3257 channels[i].max_power, 3258 nflags, bands, chan_flags); 3259 /* net80211::ENOBUFS: *n >= maxchans */ 3260 if (error != 0 && error != ENOBUFS) 3261 printf("%s: %s: Adding chan %u/%u/%#x/%#x/%#x/%#x " 3262 "returned error %d\n", ic->ic_name, 3263 __func__, channels[i].hw_value, 3264 channels[i].center_freq, channels[i].flags, 3265 nflags, chan_flags, cflags, error); 3266 if (error != 0) 3267 break; 3268 } 3269 } 3270 3271 /* NL80211_BAND_5GHZ */ 3272 nchans = 0; 3273 if (hw->wiphy->bands[NL80211_BAND_5GHZ] != NULL) 3274 nchans = hw->wiphy->bands[NL80211_BAND_5GHZ]->n_channels; 3275 if (nchans > 0) { 3276 memset(bands, 0, sizeof(bands)); 3277 chan_flags = 0; 3278 setbit(bands, IEEE80211_MODE_11A); 3279 #ifdef __not_yet__ 3280 if (hw->wiphy->bands[NL80211_BAND_5GHZ]->ht_cap.ht_supported) { 3281 setbit(bands, IEEE80211_MODE_11NA); 3282 chan_flags |= NET80211_CBW_FLAG_HT40; 3283 } 3284 if (hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.vht_supported){ 3285 3286 ic->ic_flags_ext |= IEEE80211_FEXT_VHT; 3287 ic->ic_vhtcaps = 3288 hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.cap; 3289 3290 setbit(bands, IEEE80211_MODE_VHT_5GHZ); 3291 chan_flags |= NET80211_CBW_FLAG_VHT80; 3292 if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ( 3293 ic->ic_vhtcaps)) 3294 chan_flags |= NET80211_CBW_FLAG_VHT160; 3295 if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160_80P80MHZ( 3296 ic->ic_vhtcaps)) 3297 chan_flags |= NET80211_CBW_FLAG_VHT80P80; 3298 } 3299 #endif 3300 3301 channels = hw->wiphy->bands[NL80211_BAND_5GHZ]->channels; 3302 for (i = 0; i < nchans && *n < maxchan; i++) { 3303 uint32_t nflags = 0; 3304 int cflags = chan_flags; 3305 3306 if (channels[i].flags & IEEE80211_CHAN_DISABLED) { 3307 printf("%s: %s: Skipping disabled chan " 3308 "[%u/%u/%#x]\n", ic->ic_name, __func__, 3309 channels[i].hw_value, 3310 channels[i].center_freq, channels[i].flags); 3311 continue; 3312 } 3313 if (channels[i].flags & IEEE80211_CHAN_NO_IR) 3314 nflags |= (IEEE80211_CHAN_NOADHOC|IEEE80211_CHAN_PASSIVE); 3315 if (channels[i].flags & IEEE80211_CHAN_RADAR) 3316 nflags |= IEEE80211_CHAN_DFS; 3317 if (channels[i].flags & IEEE80211_CHAN_NO_160MHZ) 3318 cflags &= ~(NET80211_CBW_FLAG_VHT160|NET80211_CBW_FLAG_VHT80P80); 3319 if (channels[i].flags & IEEE80211_CHAN_NO_80MHZ) 3320 cflags &= ~NET80211_CBW_FLAG_VHT80; 3321 /* XXX hwo to map the remaining enum ieee80211_channel_flags? */ 3322 if (channels[i].flags & IEEE80211_CHAN_NO_HT40) 3323 cflags &= ~NET80211_CBW_FLAG_HT40; 3324 3325 error = ieee80211_add_channel_cbw(c, maxchan, n, 3326 channels[i].hw_value, channels[i].center_freq, 3327 channels[i].max_power, 3328 nflags, bands, chan_flags); 3329 /* net80211::ENOBUFS: *n >= maxchans */ 3330 if (error != 0 && error != ENOBUFS) 3331 printf("%s: %s: Adding chan %u/%u/%#x/%#x/%#x/%#x " 3332 "returned error %d\n", ic->ic_name, 3333 __func__, channels[i].hw_value, 3334 channels[i].center_freq, channels[i].flags, 3335 nflags, chan_flags, cflags, error); 3336 if (error != 0) 3337 break; 3338 } 3339 } 3340 } 3341 3342 static void * 3343 lkpi_ieee80211_ifalloc(void) 3344 { 3345 struct ieee80211com *ic; 3346 3347 ic = malloc(sizeof(*ic), M_LKPI80211, M_WAITOK | M_ZERO); 3348 if (ic == NULL) 3349 return (NULL); 3350 3351 /* Setting these happens later when we have device information. */ 3352 ic->ic_softc = NULL; 3353 ic->ic_name = "linuxkpi"; 3354 3355 return (ic); 3356 } 3357 3358 struct ieee80211_hw * 3359 linuxkpi_ieee80211_alloc_hw(size_t priv_len, const struct ieee80211_ops *ops) 3360 { 3361 struct ieee80211_hw *hw; 3362 struct lkpi_hw *lhw; 3363 struct wiphy *wiphy; 3364 3365 /* Get us and the driver data also allocated. */ 3366 wiphy = wiphy_new(&linuxkpi_mac80211cfgops, sizeof(*lhw) + priv_len); 3367 if (wiphy == NULL) 3368 return (NULL); 3369 3370 lhw = wiphy_priv(wiphy); 3371 lhw->ops = ops; 3372 3373 mtx_init(&lhw->mtx, "lhw", NULL, MTX_DEF | MTX_RECURSE); 3374 sx_init_flags(&lhw->lvif_sx, "lhw-lvif", SX_RECURSE | SX_DUPOK); 3375 TAILQ_INIT(&lhw->lvif_head); 3376 3377 /* 3378 * XXX-BZ TODO make sure there is a "_null" function to all ops 3379 * not initialized. 3380 */ 3381 hw = LHW_TO_HW(lhw); 3382 hw->wiphy = wiphy; 3383 hw->conf.flags |= IEEE80211_CONF_IDLE; 3384 hw->priv = (void *)(lhw + 1); 3385 3386 /* BSD Specific. */ 3387 lhw->ic = lkpi_ieee80211_ifalloc(); 3388 if (lhw->ic == NULL) { 3389 ieee80211_free_hw(hw); 3390 return (NULL); 3391 } 3392 3393 IMPROVE(); 3394 3395 return (hw); 3396 } 3397 3398 void 3399 linuxkpi_ieee80211_iffree(struct ieee80211_hw *hw) 3400 { 3401 struct lkpi_hw *lhw; 3402 3403 lhw = HW_TO_LHW(hw); 3404 free(lhw->ic, M_LKPI80211); 3405 lhw->ic = NULL; 3406 3407 /* Cleanup more of lhw here or in wiphy_free()? */ 3408 sx_destroy(&lhw->lvif_sx); 3409 mtx_destroy(&lhw->mtx); 3410 IMPROVE(); 3411 } 3412 3413 void 3414 linuxkpi_set_ieee80211_dev(struct ieee80211_hw *hw, char *name) 3415 { 3416 struct lkpi_hw *lhw; 3417 struct ieee80211com *ic; 3418 3419 lhw = HW_TO_LHW(hw); 3420 ic = lhw->ic; 3421 3422 /* Now set a proper name before ieee80211_ifattach(). */ 3423 ic->ic_softc = lhw; 3424 ic->ic_name = name; 3425 3426 /* XXX-BZ do we also need to set wiphy name? */ 3427 } 3428 3429 struct ieee80211_hw * 3430 linuxkpi_wiphy_to_ieee80211_hw(struct wiphy *wiphy) 3431 { 3432 struct lkpi_hw *lhw; 3433 3434 lhw = wiphy_priv(wiphy); 3435 return (LHW_TO_HW(lhw)); 3436 } 3437 3438 static void 3439 lkpi_radiotap_attach(struct lkpi_hw *lhw) 3440 { 3441 struct ieee80211com *ic; 3442 3443 ic = lhw->ic; 3444 ieee80211_radiotap_attach(ic, 3445 &lhw->rtap_tx.wt_ihdr, sizeof(lhw->rtap_tx), 3446 LKPI_RTAP_TX_FLAGS_PRESENT, 3447 &lhw->rtap_rx.wr_ihdr, sizeof(lhw->rtap_rx), 3448 LKPI_RTAP_RX_FLAGS_PRESENT); 3449 } 3450 3451 int 3452 linuxkpi_ieee80211_ifattach(struct ieee80211_hw *hw) 3453 { 3454 struct ieee80211com *ic; 3455 struct lkpi_hw *lhw; 3456 int band, i; 3457 3458 lhw = HW_TO_LHW(hw); 3459 ic = lhw->ic; 3460 3461 /* We do it this late as wiphy->dev should be set for the name. */ 3462 lhw->workq = alloc_ordered_workqueue(wiphy_name(hw->wiphy), 0); 3463 if (lhw->workq == NULL) 3464 return (-EAGAIN); 3465 3466 /* XXX-BZ figure this out how they count his... */ 3467 if (!is_zero_ether_addr(hw->wiphy->perm_addr)) { 3468 IEEE80211_ADDR_COPY(ic->ic_macaddr, 3469 hw->wiphy->perm_addr); 3470 } else if (hw->wiphy->n_addresses > 0) { 3471 /* We take the first one. */ 3472 IEEE80211_ADDR_COPY(ic->ic_macaddr, 3473 hw->wiphy->addresses[0].addr); 3474 } else { 3475 ic_printf(ic, "%s: warning, no hardware address!\n", __func__); 3476 } 3477 3478 #ifdef __not_yet__ 3479 /* See comment in lkpi_80211_txq_tx_one(). */ 3480 ic->ic_headroom = hw->extra_tx_headroom; 3481 #endif 3482 3483 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 3484 ic->ic_opmode = IEEE80211_M_STA; 3485 3486 /* Set device capabilities. */ 3487 /* XXX-BZ we need to get these from linux80211/drivers and convert. */ 3488 ic->ic_caps = 3489 IEEE80211_C_STA | 3490 IEEE80211_C_MONITOR | 3491 IEEE80211_C_WPA | /* WPA/RSN */ 3492 IEEE80211_C_WME | 3493 #if 0 3494 IEEE80211_C_PMGT | 3495 #endif 3496 IEEE80211_C_SHSLOT | /* short slot time supported */ 3497 IEEE80211_C_SHPREAMBLE /* short preamble supported */ 3498 ; 3499 #if 0 3500 /* Scanning is a different kind of beast to re-work. */ 3501 ic->ic_caps |= IEEE80211_C_BGSCAN; 3502 #endif 3503 if (lhw->ops->hw_scan) { 3504 /* 3505 * Advertise full-offload scanning. 3506 * 3507 * Not limiting to SINGLE_SCAN_ON_ALL_BANDS here as otherwise 3508 * we essentially disable hw_scan for all drivers not setting 3509 * the flag. 3510 */ 3511 ic->ic_flags_ext |= IEEE80211_FEXT_SCAN_OFFLOAD; 3512 lhw->scan_flags |= LKPI_LHW_SCAN_HW; 3513 } 3514 3515 #ifdef __notyet__ 3516 ic->ic_htcaps = IEEE80211_HTC_HT /* HT operation */ 3517 | IEEE80211_HTC_AMPDU /* A-MPDU tx/rx */ 3518 | IEEE80211_HTC_AMSDU /* A-MSDU tx/rx */ 3519 | IEEE80211_HTCAP_MAXAMSDU_3839 3520 /* max A-MSDU length */ 3521 | IEEE80211_HTCAP_SMPS_OFF; /* SM power save off */ 3522 ic->ic_htcaps |= IEEE80211_HTCAP_SHORTGI20; 3523 ic->ic_htcaps |= IEEE80211_HTCAP_CHWIDTH40 | IEEE80211_HTCAP_SHORTGI40; 3524 ic->ic_htcaps |= IEEE80211_HTCAP_TXSTBC; 3525 #endif 3526 3527 /* 3528 * The wiphy variables report bitmasks of avail antennas. 3529 * (*get_antenna) get the current bitmask sets which can be 3530 * altered by (*set_antenna) for some drivers. 3531 * XXX-BZ will the count alone do us much good long-term in net80211? 3532 */ 3533 if (hw->wiphy->available_antennas_rx || 3534 hw->wiphy->available_antennas_tx) { 3535 uint32_t rxs, txs; 3536 3537 if (lkpi_80211_mo_get_antenna(hw, &txs, &rxs) == 0) { 3538 ic->ic_rxstream = bitcount32(rxs); 3539 ic->ic_txstream = bitcount32(txs); 3540 } 3541 } 3542 3543 ic->ic_cryptocaps = 0; 3544 #ifdef LKPI_80211_HW_CRYPTO 3545 if (hw->wiphy->n_cipher_suites > 0) { 3546 for (i = 0; i < hw->wiphy->n_cipher_suites; i++) 3547 ic->ic_cryptocaps |= lkpi_l80211_to_net80211_cyphers( 3548 hw->wiphy->cipher_suites[i]); 3549 } 3550 #endif 3551 3552 lkpi_ic_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, 3553 ic->ic_channels); 3554 3555 ieee80211_ifattach(ic); 3556 3557 ic->ic_update_mcast = lkpi_ic_update_mcast; 3558 ic->ic_update_promisc = lkpi_ic_update_promisc; 3559 ic->ic_update_chw = lkpi_ic_update_chw; 3560 ic->ic_parent = lkpi_ic_parent; 3561 ic->ic_scan_start = lkpi_ic_scan_start; 3562 ic->ic_scan_end = lkpi_ic_scan_end; 3563 ic->ic_set_channel = lkpi_ic_set_channel; 3564 ic->ic_transmit = lkpi_ic_transmit; 3565 ic->ic_raw_xmit = lkpi_ic_raw_xmit; 3566 ic->ic_vap_create = lkpi_ic_vap_create; 3567 ic->ic_vap_delete = lkpi_ic_vap_delete; 3568 ic->ic_getradiocaps = lkpi_ic_getradiocaps; 3569 ic->ic_wme.wme_update = lkpi_ic_wme_update; 3570 3571 lhw->ic_scan_curchan = ic->ic_scan_curchan; 3572 ic->ic_scan_curchan = lkpi_ic_scan_curchan; 3573 lhw->ic_scan_mindwell = ic->ic_scan_mindwell; 3574 ic->ic_scan_mindwell = lkpi_ic_scan_mindwell; 3575 3576 lhw->ic_node_alloc = ic->ic_node_alloc; 3577 ic->ic_node_alloc = lkpi_ic_node_alloc; 3578 lhw->ic_node_init = ic->ic_node_init; 3579 ic->ic_node_init = lkpi_ic_node_init; 3580 lhw->ic_node_cleanup = ic->ic_node_cleanup; 3581 ic->ic_node_cleanup = lkpi_ic_node_cleanup; 3582 lhw->ic_node_free = ic->ic_node_free; 3583 ic->ic_node_free = lkpi_ic_node_free; 3584 3585 lkpi_radiotap_attach(lhw); 3586 3587 /* 3588 * Assign the first possible channel for now; seems Realtek drivers 3589 * expect one. 3590 * Also remember the amount of bands we support and the most rates 3591 * in any band so we can scale [(ext) sup rates] IE(s) accordingly. 3592 */ 3593 lhw->supbands = lhw->max_rates = 0; 3594 for (band = 0; band < NUM_NL80211_BANDS && 3595 hw->conf.chandef.chan == NULL; band++) { 3596 struct ieee80211_supported_band *supband; 3597 struct linuxkpi_ieee80211_channel *channels; 3598 3599 supband = hw->wiphy->bands[band]; 3600 if (supband == NULL || supband->n_channels == 0) 3601 continue; 3602 3603 lhw->supbands++; 3604 lhw->max_rates = max(lhw->max_rates, supband->n_bitrates); 3605 3606 channels = supband->channels; 3607 for (i = 0; i < supband->n_channels; i++) { 3608 3609 if (channels[i].flags & IEEE80211_CHAN_DISABLED) 3610 continue; 3611 3612 cfg80211_chandef_create(&hw->conf.chandef, &channels[i], 3613 NL80211_CHAN_NO_HT); 3614 break; 3615 } 3616 } 3617 3618 IMPROVE("see net80211::ieee80211_chan_init vs. wiphy->bands[].bitrates possibly in lkpi_ic_getradiocaps?"); 3619 3620 /* Make sure we do not support more than net80211 is willing to take. */ 3621 if (lhw->max_rates > IEEE80211_RATE_MAXSIZE) { 3622 ic_printf(ic, "%s: limiting max_rates %d to %d!\n", __func__, 3623 lhw->max_rates, IEEE80211_RATE_MAXSIZE); 3624 lhw->max_rates = IEEE80211_RATE_MAXSIZE; 3625 } 3626 3627 /* 3628 * The maximum supported bitrates on any band + size for 3629 * DSSS Parameter Set give our per-band IE size. 3630 * XXX-BZ FIXME add HT VHT ... later 3631 * SSID is the responsibility of the driver and goes on the side. 3632 * The user specified bits coming from the vap go into the 3633 * "common ies" fields. 3634 */ 3635 lhw->scan_ie_len = 2 + IEEE80211_RATE_SIZE; 3636 if (lhw->max_rates > IEEE80211_RATE_SIZE) 3637 lhw->scan_ie_len += 2 + (lhw->max_rates - IEEE80211_RATE_SIZE); 3638 /* 3639 * net80211 does not seem to support the DSSS Parameter Set but some of 3640 * the drivers insert it so calculate the extra fixed space in. 3641 */ 3642 lhw->scan_ie_len += 2 + 1; 3643 3644 /* Reduce the max_scan_ie_len "left" by the amount we consume already. */ 3645 if (hw->wiphy->max_scan_ie_len > 0) 3646 hw->wiphy->max_scan_ie_len -= lhw->scan_ie_len; 3647 3648 if (bootverbose) 3649 ieee80211_announce(ic); 3650 3651 return (0); 3652 } 3653 3654 void 3655 linuxkpi_ieee80211_ifdetach(struct ieee80211_hw *hw) 3656 { 3657 struct lkpi_hw *lhw; 3658 struct ieee80211com *ic; 3659 3660 lhw = HW_TO_LHW(hw); 3661 ic = lhw->ic; 3662 ieee80211_ifdetach(ic); 3663 } 3664 3665 void 3666 linuxkpi_ieee80211_iterate_interfaces(struct ieee80211_hw *hw, 3667 enum ieee80211_iface_iter flags, 3668 void(*iterfunc)(void *, uint8_t *, struct ieee80211_vif *), 3669 void *arg) 3670 { 3671 struct lkpi_hw *lhw; 3672 struct lkpi_vif *lvif; 3673 struct ieee80211_vif *vif; 3674 bool active, atomic, nin_drv; 3675 3676 lhw = HW_TO_LHW(hw); 3677 3678 if (flags & ~(IEEE80211_IFACE_ITER_NORMAL| 3679 IEEE80211_IFACE_ITER_RESUME_ALL| 3680 IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER| 3681 IEEE80211_IFACE_ITER__ACTIVE|IEEE80211_IFACE_ITER__ATOMIC)) { 3682 ic_printf(lhw->ic, "XXX TODO %s flags(%#x) not yet supported.\n", 3683 __func__, flags); 3684 } 3685 3686 active = (flags & IEEE80211_IFACE_ITER__ACTIVE) != 0; 3687 atomic = (flags & IEEE80211_IFACE_ITER__ATOMIC) != 0; 3688 nin_drv = (flags & IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER) != 0; 3689 3690 if (atomic) 3691 LKPI_80211_LHW_LVIF_LOCK(lhw); 3692 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) { 3693 struct ieee80211vap *vap; 3694 3695 vif = LVIF_TO_VIF(lvif); 3696 3697 /* 3698 * If we want "active" interfaces, we need to distinguish on 3699 * whether the driver knows about them or not to be able to 3700 * handle the "resume" case correctly. Skip the ones the 3701 * driver does not know about. 3702 */ 3703 if (active && !lvif->added_to_drv && 3704 (flags & IEEE80211_IFACE_ITER_RESUME_ALL) != 0) 3705 continue; 3706 3707 /* 3708 * If we shall skip interfaces not added to the driver do so 3709 * if we haven't yet. 3710 */ 3711 if (nin_drv && !lvif->added_to_drv) 3712 continue; 3713 3714 /* 3715 * Run the iterator function if we are either not asking 3716 * asking for active only or if the VAP is "running". 3717 */ 3718 /* XXX-BZ probably should have state in the lvif as well. */ 3719 vap = LVIF_TO_VAP(lvif); 3720 if (!active || (vap->iv_state != IEEE80211_S_INIT)) 3721 iterfunc(arg, vif->addr, vif); 3722 } 3723 if (atomic) 3724 LKPI_80211_LHW_LVIF_UNLOCK(lhw); 3725 } 3726 3727 void 3728 linuxkpi_ieee80211_iterate_keys(struct ieee80211_hw *hw, 3729 struct ieee80211_vif *vif, 3730 void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *, 3731 struct ieee80211_sta *, struct ieee80211_key_conf *, void *), 3732 void *arg) 3733 { 3734 3735 UNIMPLEMENTED; 3736 } 3737 3738 void 3739 linuxkpi_ieee80211_iterate_chan_contexts(struct ieee80211_hw *hw, 3740 void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *, 3741 void *), 3742 void *arg) 3743 { 3744 3745 UNIMPLEMENTED; 3746 } 3747 3748 void 3749 linuxkpi_ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw, 3750 void (*iterfunc)(void *, struct ieee80211_sta *), void *arg) 3751 { 3752 struct lkpi_hw *lhw; 3753 struct lkpi_vif *lvif; 3754 struct lkpi_sta *lsta; 3755 struct ieee80211_sta *sta; 3756 3757 KASSERT(hw != NULL && iterfunc != NULL, 3758 ("%s: hw %p iterfunc %p arg %p\n", __func__, hw, iterfunc, arg)); 3759 3760 lhw = HW_TO_LHW(hw); 3761 3762 LKPI_80211_LHW_LVIF_LOCK(lhw); 3763 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) { 3764 3765 LKPI_80211_LVIF_LOCK(lvif); 3766 TAILQ_FOREACH(lsta, &lvif->lsta_head, lsta_entry) { 3767 if (!lsta->added_to_drv) 3768 continue; 3769 sta = LSTA_TO_STA(lsta); 3770 iterfunc(arg, sta); 3771 } 3772 LKPI_80211_LVIF_UNLOCK(lvif); 3773 } 3774 LKPI_80211_LHW_LVIF_UNLOCK(lhw); 3775 } 3776 3777 int 3778 linuxkpi_regulatory_set_wiphy_regd_sync(struct wiphy *wiphy, 3779 struct linuxkpi_ieee80211_regdomain *regd) 3780 { 3781 struct lkpi_hw *lhw; 3782 struct ieee80211com *ic; 3783 struct ieee80211_regdomain *rd; 3784 3785 lhw = wiphy_priv(wiphy); 3786 ic = lhw->ic; 3787 3788 rd = &ic->ic_regdomain; 3789 if (rd->isocc[0] == '\0') { 3790 rd->isocc[0] = regd->alpha2[0]; 3791 rd->isocc[1] = regd->alpha2[1]; 3792 } 3793 3794 TODO(); 3795 /* XXX-BZ finish the rest. */ 3796 3797 return (0); 3798 } 3799 3800 void 3801 linuxkpi_ieee80211_scan_completed(struct ieee80211_hw *hw, 3802 struct cfg80211_scan_info *info) 3803 { 3804 struct lkpi_hw *lhw; 3805 struct ieee80211com *ic; 3806 struct ieee80211_scan_state *ss; 3807 3808 lhw = wiphy_priv(hw->wiphy); 3809 ic = lhw->ic; 3810 ss = ic->ic_scan; 3811 3812 ieee80211_scan_done(ss->ss_vap); 3813 3814 LKPI_80211_LHW_LOCK(lhw); 3815 free(lhw->hw_req, M_LKPI80211); 3816 lhw->hw_req = NULL; 3817 lhw->scan_flags &= ~LKPI_LHW_SCAN_RUNNING; 3818 wakeup(lhw); 3819 LKPI_80211_LHW_UNLOCK(lhw); 3820 3821 return; 3822 } 3823 3824 void 3825 linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, 3826 struct ieee80211_sta *sta, struct napi_struct *napi __unused) 3827 { 3828 struct epoch_tracker et; 3829 struct lkpi_hw *lhw; 3830 struct ieee80211com *ic; 3831 struct mbuf *m; 3832 struct skb_shared_info *shinfo; 3833 struct ieee80211_rx_status *rx_status; 3834 struct ieee80211_rx_stats rx_stats; 3835 struct ieee80211_node *ni; 3836 struct ieee80211vap *vap; 3837 struct ieee80211_hdr *hdr; 3838 struct lkpi_sta *lsta; 3839 int i, offset, ok; 3840 int8_t rssi; 3841 bool is_beacon; 3842 3843 if (skb->len < 2) { 3844 /* Need 80211 stats here. */ 3845 IMPROVE(); 3846 goto err; 3847 } 3848 3849 /* 3850 * For now do the data copy; we can later improve things. Might even 3851 * have an mbuf backing the skb data then? 3852 */ 3853 m = m_get2(skb->len, M_NOWAIT, MT_DATA, M_PKTHDR); 3854 if (m == NULL) 3855 goto err; 3856 m_copyback(m, 0, skb->tail - skb->data, skb->data); 3857 3858 shinfo = skb_shinfo(skb); 3859 offset = m->m_len; 3860 for (i = 0; i < shinfo->nr_frags; i++) { 3861 m_copyback(m, offset, shinfo->frags[i].size, 3862 (uint8_t *)linux_page_address(shinfo->frags[i].page) + 3863 shinfo->frags[i].offset); 3864 offset += shinfo->frags[i].size; 3865 } 3866 3867 rx_status = IEEE80211_SKB_RXCB(skb); 3868 3869 hdr = (void *)skb->data; 3870 is_beacon = ieee80211_is_beacon(hdr->frame_control); 3871 3872 #ifdef LINUXKPI_DEBUG_80211 3873 if (is_beacon && (linuxkpi_debug_80211 & D80211_TRACE_RX_BEACONS) == 0) 3874 goto no_trace_beacons; 3875 3876 if (linuxkpi_debug_80211 & D80211_TRACE_RX) 3877 printf("TRACE-RX: %s: skb %p a/l/d/t-len (%u/%u/%u/%u) " 3878 "h %p d %p t %p e %p sh %p (%u) m %p plen %u len %u%s\n", 3879 __func__, skb, skb->_alloc_len, skb->len, skb->data_len, 3880 skb->truesize, skb->head, skb->data, skb->tail, skb->end, 3881 shinfo, shinfo->nr_frags, 3882 m, m->m_pkthdr.len, m->m_len, is_beacon ? " beacon" : ""); 3883 3884 if (linuxkpi_debug_80211 & D80211_TRACE_RX_DUMP) 3885 hexdump(mtod(m, const void *), m->m_len, "RX (raw) ", 0); 3886 3887 /* Implement a dump_rxcb() !!! */ 3888 if (linuxkpi_debug_80211 & D80211_TRACE_RX) 3889 printf("TRACE %s: RXCB: %ju %ju %u, %#0x, %u, %#0x, %#0x, " 3890 "%u band %u, %u { %d %d %d %d }, %d, %#x %#x %#x %#x %u %u %u\n", 3891 __func__, 3892 (uintmax_t)rx_status->boottime_ns, 3893 (uintmax_t)rx_status->mactime, 3894 rx_status->device_timestamp, 3895 rx_status->flag, 3896 rx_status->freq, 3897 rx_status->bw, 3898 rx_status->encoding, 3899 rx_status->ampdu_reference, 3900 rx_status->band, 3901 rx_status->chains, 3902 rx_status->chain_signal[0], 3903 rx_status->chain_signal[1], 3904 rx_status->chain_signal[2], 3905 rx_status->chain_signal[3], 3906 rx_status->signal, 3907 rx_status->enc_flags, 3908 rx_status->he_dcm, 3909 rx_status->he_gi, 3910 rx_status->he_ru, 3911 rx_status->zero_length_psdu_type, 3912 rx_status->nss, 3913 rx_status->rate_idx); 3914 no_trace_beacons: 3915 #endif 3916 3917 memset(&rx_stats, 0, sizeof(rx_stats)); 3918 rx_stats.r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI; 3919 /* XXX-BZ correct hardcoded rssi and noise floor, how? survey? */ 3920 rx_stats.c_nf = -96; 3921 if (ieee80211_hw_check(hw, SIGNAL_DBM) && 3922 !(rx_status->flag & RX_FLAG_NO_SIGNAL_VAL)) 3923 rssi = rx_status->signal; 3924 else 3925 rssi = rx_stats.c_nf; 3926 /* 3927 * net80211 signal strength data are in .5 dBm units relative to 3928 * the current noise floor (see comment in ieee80211_node.h). 3929 */ 3930 rssi -= rx_stats.c_nf; 3931 rx_stats.c_rssi = rssi * 2; 3932 rx_stats.r_flags |= IEEE80211_R_BAND; 3933 rx_stats.c_band = 3934 lkpi_nl80211_band_to_net80211_band(rx_status->band); 3935 rx_stats.r_flags |= IEEE80211_R_FREQ | IEEE80211_R_IEEE; 3936 rx_stats.c_freq = rx_status->freq; 3937 rx_stats.c_ieee = ieee80211_mhz2ieee(rx_stats.c_freq, rx_stats.c_band); 3938 3939 /* XXX (*sta_statistics)() to get to some of that? */ 3940 /* XXX-BZ dump the FreeBSD version of rx_stats as well! */ 3941 3942 lhw = HW_TO_LHW(hw); 3943 ic = lhw->ic; 3944 3945 ok = ieee80211_add_rx_params(m, &rx_stats); 3946 if (ok == 0) { 3947 m_freem(m); 3948 counter_u64_add(ic->ic_ierrors, 1); 3949 goto err; 3950 } 3951 3952 if (sta != NULL) { 3953 lsta = STA_TO_LSTA(sta); 3954 ni = ieee80211_ref_node(lsta->ni); 3955 } else { 3956 struct ieee80211_frame_min *wh; 3957 3958 wh = mtod(m, struct ieee80211_frame_min *); 3959 ni = ieee80211_find_rxnode(ic, wh); 3960 if (ni != NULL) 3961 lsta = ni->ni_drv_data; 3962 } 3963 3964 if (ni != NULL) 3965 vap = ni->ni_vap; 3966 else 3967 /* 3968 * XXX-BZ can we improve this by looking at the frame hdr 3969 * or other meta-data passed up? 3970 */ 3971 vap = TAILQ_FIRST(&ic->ic_vaps); 3972 3973 #ifdef LINUXKPI_DEBUG_80211 3974 if (linuxkpi_debug_80211 & D80211_TRACE_RX) 3975 printf("TRACE %s: sta %p lsta %p state %d ni %p vap %p%s\n", 3976 __func__, sta, lsta, (lsta != NULL) ? lsta->state : -1, 3977 ni, vap, is_beacon ? " beacon" : ""); 3978 #endif 3979 3980 if (ni != NULL && vap != NULL && is_beacon && 3981 rx_status->device_timestamp > 0 && 3982 m->m_pkthdr.len >= sizeof(struct ieee80211_frame)) { 3983 struct lkpi_vif *lvif; 3984 struct ieee80211_vif *vif; 3985 struct ieee80211_frame *wh; 3986 3987 wh = mtod(m, struct ieee80211_frame *); 3988 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) 3989 goto skip_device_ts; 3990 3991 lvif = VAP_TO_LVIF(vap); 3992 vif = LVIF_TO_VIF(lvif); 3993 3994 IMPROVE("TIMING_BEACON_ONLY?"); 3995 /* mac80211 specific (not net80211) so keep it here. */ 3996 vif->bss_conf.sync_device_ts = rx_status->device_timestamp; 3997 /* 3998 * net80211 should take care of the other information (sync_tsf, 3999 * sync_dtim_count) as otherwise we need to parse the beacon. 4000 */ 4001 } 4002 skip_device_ts: 4003 4004 if (vap != NULL && vap->iv_state > IEEE80211_S_INIT && 4005 ieee80211_radiotap_active_vap(vap)) { 4006 struct lkpi_radiotap_rx_hdr *rtap; 4007 4008 rtap = &lhw->rtap_rx; 4009 rtap->wr_tsft = rx_status->device_timestamp; 4010 rtap->wr_flags = 0; 4011 if (rx_status->enc_flags & RX_ENC_FLAG_SHORTPRE) 4012 rtap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 4013 if (rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI) 4014 rtap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI; 4015 #if 0 /* .. or it does not given we strip it below. */ 4016 if (ieee80211_hw_check(hw, RX_INCLUDES_FCS)) 4017 rtap->wr_flags |= IEEE80211_RADIOTAP_F_FCS; 4018 #endif 4019 if (rx_status->flag & RX_FLAG_FAILED_FCS_CRC) 4020 rtap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; 4021 rtap->wr_rate = 0; 4022 IMPROVE(); 4023 /* XXX TODO status->encoding / rate_index / bw */ 4024 rtap->wr_chan_freq = htole16(rx_stats.c_freq); 4025 if (ic->ic_curchan->ic_ieee == rx_stats.c_ieee) 4026 rtap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); 4027 rtap->wr_dbm_antsignal = rssi; 4028 rtap->wr_dbm_antnoise = rx_stats.c_nf; 4029 } 4030 4031 if (ieee80211_hw_check(hw, RX_INCLUDES_FCS)) 4032 m_adj(m, -IEEE80211_CRC_LEN); 4033 4034 NET_EPOCH_ENTER(et); 4035 if (ni != NULL) { 4036 ok = ieee80211_input_mimo(ni, m); 4037 ieee80211_free_node(ni); 4038 if (ok < 0) 4039 m_freem(m); 4040 } else { 4041 ok = ieee80211_input_mimo_all(ic, m); 4042 /* mbuf got consumed. */ 4043 } 4044 NET_EPOCH_EXIT(et); 4045 4046 #ifdef LINUXKPI_DEBUG_80211 4047 if (linuxkpi_debug_80211 & D80211_TRACE_RX) 4048 printf("TRACE %s: handled frame type %#0x\n", __func__, ok); 4049 #endif 4050 4051 IMPROVE(); 4052 4053 err: 4054 /* The skb is ours so we can free it :-) */ 4055 kfree_skb(skb); 4056 } 4057 4058 uint8_t 4059 linuxkpi_ieee80211_get_tid(struct ieee80211_hdr *hdr) 4060 { 4061 const struct ieee80211_frame *wh; 4062 4063 wh = (const struct ieee80211_frame *)hdr; 4064 return (ieee80211_gettid(wh)); 4065 } 4066 4067 struct wiphy * 4068 linuxkpi_wiphy_new(const struct cfg80211_ops *ops, size_t priv_len) 4069 { 4070 struct lkpi_wiphy *lwiphy; 4071 4072 lwiphy = kzalloc(sizeof(*lwiphy) + priv_len, GFP_KERNEL); 4073 if (lwiphy == NULL) 4074 return (NULL); 4075 lwiphy->ops = ops; 4076 4077 /* XXX TODO */ 4078 return (LWIPHY_TO_WIPHY(lwiphy)); 4079 } 4080 4081 void 4082 linuxkpi_wiphy_free(struct wiphy *wiphy) 4083 { 4084 struct lkpi_wiphy *lwiphy; 4085 4086 if (wiphy == NULL) 4087 return; 4088 4089 lwiphy = WIPHY_TO_LWIPHY(wiphy); 4090 kfree(lwiphy); 4091 } 4092 4093 uint32_t 4094 linuxkpi_ieee80211_channel_to_frequency(uint32_t channel, 4095 enum nl80211_band band) 4096 { 4097 4098 switch (band) { 4099 case NL80211_BAND_2GHZ: 4100 return (ieee80211_ieee2mhz(channel, IEEE80211_CHAN_2GHZ)); 4101 break; 4102 case NL80211_BAND_5GHZ: 4103 return (ieee80211_ieee2mhz(channel, IEEE80211_CHAN_5GHZ)); 4104 break; 4105 default: 4106 /* XXX abort, retry, error, panic? */ 4107 break; 4108 } 4109 4110 return (0); 4111 } 4112 4113 uint32_t 4114 linuxkpi_ieee80211_frequency_to_channel(uint32_t freq, uint32_t flags __unused) 4115 { 4116 4117 return (ieee80211_mhz2ieee(freq, 0)); 4118 } 4119 4120 static struct lkpi_sta * 4121 lkpi_find_lsta_by_ni(struct lkpi_vif *lvif, struct ieee80211_node *ni) 4122 { 4123 struct lkpi_sta *lsta, *temp; 4124 4125 LKPI_80211_LVIF_LOCK(lvif); 4126 TAILQ_FOREACH_SAFE(lsta, &lvif->lsta_head, lsta_entry, temp) { 4127 if (lsta->ni == ni) { 4128 LKPI_80211_LVIF_UNLOCK(lvif); 4129 return (lsta); 4130 } 4131 } 4132 LKPI_80211_LVIF_UNLOCK(lvif); 4133 4134 return (NULL); 4135 } 4136 4137 struct ieee80211_sta * 4138 linuxkpi_ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *peer) 4139 { 4140 struct lkpi_vif *lvif; 4141 struct lkpi_sta *lsta, *temp; 4142 struct ieee80211_sta *sta; 4143 4144 lvif = VIF_TO_LVIF(vif); 4145 4146 LKPI_80211_LVIF_LOCK(lvif); 4147 TAILQ_FOREACH_SAFE(lsta, &lvif->lsta_head, lsta_entry, temp) { 4148 sta = LSTA_TO_STA(lsta); 4149 if (IEEE80211_ADDR_EQ(sta->addr, peer)) { 4150 LKPI_80211_LVIF_UNLOCK(lvif); 4151 return (sta); 4152 } 4153 } 4154 LKPI_80211_LVIF_UNLOCK(lvif); 4155 return (NULL); 4156 } 4157 4158 struct ieee80211_sta * 4159 linuxkpi_ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, 4160 const uint8_t *addr, const uint8_t *ourvifaddr) 4161 { 4162 struct lkpi_hw *lhw; 4163 struct lkpi_vif *lvif; 4164 struct lkpi_sta *lsta; 4165 struct ieee80211_vif *vif; 4166 struct ieee80211_sta *sta; 4167 4168 lhw = wiphy_priv(hw->wiphy); 4169 sta = NULL; 4170 4171 LKPI_80211_LHW_LVIF_LOCK(lhw); 4172 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) { 4173 4174 /* XXX-BZ check our address from the vif. */ 4175 4176 vif = LVIF_TO_VIF(lvif); 4177 if (ourvifaddr != NULL && 4178 !IEEE80211_ADDR_EQ(vif->addr, ourvifaddr)) 4179 continue; 4180 sta = linuxkpi_ieee80211_find_sta(vif, addr); 4181 if (sta != NULL) 4182 break; 4183 } 4184 LKPI_80211_LHW_LVIF_UNLOCK(lhw); 4185 4186 if (sta != NULL) { 4187 lsta = STA_TO_LSTA(sta); 4188 if (!lsta->added_to_drv) 4189 return (NULL); 4190 } 4191 4192 return (sta); 4193 } 4194 4195 struct sk_buff * 4196 linuxkpi_ieee80211_tx_dequeue(struct ieee80211_hw *hw, 4197 struct ieee80211_txq *txq) 4198 { 4199 struct lkpi_txq *ltxq; 4200 struct sk_buff *skb; 4201 4202 ltxq = TXQ_TO_LTXQ(txq); 4203 ltxq->seen_dequeue = true; 4204 4205 skb = skb_dequeue(<xq->skbq); 4206 4207 return (skb); 4208 } 4209 4210 void 4211 linuxkpi_ieee80211_txq_get_depth(struct ieee80211_txq *txq, 4212 unsigned long *frame_cnt, unsigned long *byte_cnt) 4213 { 4214 struct lkpi_txq *ltxq; 4215 struct sk_buff *skb; 4216 unsigned long fc, bc; 4217 4218 ltxq = TXQ_TO_LTXQ(txq); 4219 4220 fc = bc = 0; 4221 skb_queue_walk(<xq->skbq, skb) { 4222 fc++; 4223 bc += skb->len; 4224 } 4225 if (frame_cnt) 4226 *frame_cnt = fc; 4227 if (byte_cnt) 4228 *byte_cnt = bc; 4229 4230 /* Validate that this is doing the correct thing. */ 4231 /* Should we keep track on en/dequeue? */ 4232 IMPROVE(); 4233 } 4234 4235 /* 4236 * We are called from ieee80211_free_txskb() or ieee80211_tx_status(). 4237 * The latter tries to derive the success status from the info flags 4238 * passed back from the driver. rawx_mit() saves the ni on the m and the 4239 * m on the skb for us to be able to give feedback to net80211. 4240 */ 4241 void 4242 linuxkpi_ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb, 4243 int status) 4244 { 4245 struct ieee80211_node *ni; 4246 struct mbuf *m; 4247 4248 m = skb->m; 4249 skb->m = NULL; 4250 4251 if (m != NULL) { 4252 ni = m->m_pkthdr.PH_loc.ptr; 4253 /* Status: 0 is ok, != 0 is error. */ 4254 ieee80211_tx_complete(ni, m, status); 4255 /* ni & mbuf were consumed. */ 4256 } 4257 4258 kfree_skb(skb); 4259 } 4260 4261 void 4262 linuxkpi_ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) 4263 { 4264 struct ieee80211_tx_info *info; 4265 struct ieee80211_ratectl_tx_status txs; 4266 struct ieee80211_node *ni; 4267 int status; 4268 4269 info = IEEE80211_SKB_CB(skb); 4270 4271 if (skb->m != NULL) { 4272 struct mbuf *m; 4273 4274 m = skb->m; 4275 ni = m->m_pkthdr.PH_loc.ptr; 4276 memset(&txs, 0, sizeof(txs)); 4277 } else { 4278 ni = NULL; 4279 } 4280 4281 if (info->flags & IEEE80211_TX_STAT_ACK) { 4282 status = 0; /* No error. */ 4283 txs.status = IEEE80211_RATECTL_TX_SUCCESS; 4284 } else { 4285 status = 1; 4286 txs.status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED; 4287 } 4288 4289 if (ni != NULL) { 4290 int ridx __unused; 4291 #ifdef LINUXKPI_DEBUG_80211 4292 int old_rate; 4293 4294 old_rate = ni->ni_vap->iv_bss->ni_txrate; 4295 #endif 4296 txs.pktlen = skb->len; 4297 txs.flags |= IEEE80211_RATECTL_STATUS_PKTLEN; 4298 if (info->status.rates[0].count > 1) { 4299 txs.long_retries = info->status.rates[0].count - 1; /* 1 + retries in drivers. */ 4300 txs.flags |= IEEE80211_RATECTL_STATUS_LONG_RETRY; 4301 } 4302 #if 0 /* Unused in net80211 currently. */ 4303 /* XXX-BZ conver;t check .flags for MCS/VHT/.. */ 4304 txs.final_rate = info->status.rates[0].idx; 4305 txs.flags |= IEEE80211_RATECTL_STATUS_FINAL_RATE; 4306 #endif 4307 if (info->status.is_valid_ack_signal) { 4308 txs.rssi = info->status.ack_signal; /* XXX-BZ CONVERT? */ 4309 txs.flags |= IEEE80211_RATECTL_STATUS_RSSI; 4310 } 4311 4312 IMPROVE("only update of rate matches but that requires us to get a proper rate"); 4313 ieee80211_ratectl_tx_complete(ni, &txs); 4314 ridx = ieee80211_ratectl_rate(ni->ni_vap->iv_bss, NULL, 0); 4315 4316 #ifdef LINUXKPI_DEBUG_80211 4317 if (linuxkpi_debug_80211 & D80211_TRACE_TX) { 4318 printf("TX-RATE: %s: old %d new %d ridx %d, " 4319 "long_retries %d\n", __func__, 4320 old_rate, ni->ni_vap->iv_bss->ni_txrate, 4321 ridx, txs.long_retries); 4322 } 4323 #endif 4324 } 4325 4326 #ifdef LINUXKPI_DEBUG_80211 4327 if (linuxkpi_debug_80211 & D80211_TRACE_TX) 4328 printf("TX-STATUS: %s: hw %p skb %p status %d : flags %#x " 4329 "band %u hw_queue %u tx_time_est %d : " 4330 "rates [ %u %u %#x, %u %u %#x, %u %u %#x, %u %u %#x ] " 4331 "ack_signal %u ampdu_ack_len %u ampdu_len %u antenna %u " 4332 "tx_time %u is_valid_ack_signal %u " 4333 "status_driver_data [ %p %p ]\n", 4334 __func__, hw, skb, status, info->flags, 4335 info->band, info->hw_queue, info->tx_time_est, 4336 info->status.rates[0].idx, info->status.rates[0].count, 4337 info->status.rates[0].flags, 4338 info->status.rates[1].idx, info->status.rates[1].count, 4339 info->status.rates[1].flags, 4340 info->status.rates[2].idx, info->status.rates[2].count, 4341 info->status.rates[2].flags, 4342 info->status.rates[3].idx, info->status.rates[3].count, 4343 info->status.rates[3].flags, 4344 info->status.ack_signal, info->status.ampdu_ack_len, 4345 info->status.ampdu_len, info->status.antenna, 4346 info->status.tx_time, info->status.is_valid_ack_signal, 4347 info->status.status_driver_data[0], 4348 info->status.status_driver_data[1]); 4349 #endif 4350 4351 linuxkpi_ieee80211_free_txskb(hw, skb, status); 4352 } 4353 4354 /* 4355 * This is an internal bandaid for the moment for the way we glue 4356 * skbs and mbufs together for TX. Once we have skbs backed by 4357 * mbufs this should go away. 4358 * This is a public function but kept on the private KPI (lkpi_) 4359 * and is not exposed by a header file. 4360 */ 4361 static void 4362 lkpi_ieee80211_free_skb_mbuf(void *p) 4363 { 4364 struct ieee80211_node *ni; 4365 struct mbuf *m; 4366 4367 if (p == NULL) 4368 return; 4369 4370 m = (struct mbuf *)p; 4371 M_ASSERTPKTHDR(m); 4372 4373 ni = m->m_pkthdr.PH_loc.ptr; 4374 m->m_pkthdr.PH_loc.ptr = NULL; 4375 if (ni != NULL) 4376 ieee80211_free_node(ni); 4377 m_freem(m); 4378 } 4379 4380 void 4381 linuxkpi_ieee80211_queue_delayed_work(struct ieee80211_hw *hw, 4382 struct delayed_work *w, int delay) 4383 { 4384 struct lkpi_hw *lhw; 4385 4386 /* Need to make sure hw is in a stable (non-suspended) state. */ 4387 IMPROVE(); 4388 4389 lhw = HW_TO_LHW(hw); 4390 queue_delayed_work(lhw->workq, w, delay); 4391 } 4392 4393 void 4394 linuxkpi_ieee80211_queue_work(struct ieee80211_hw *hw, 4395 struct work_struct *w) 4396 { 4397 struct lkpi_hw *lhw; 4398 4399 /* Need to make sure hw is in a stable (non-suspended) state. */ 4400 IMPROVE(); 4401 4402 lhw = HW_TO_LHW(hw); 4403 queue_work(lhw->workq, w); 4404 } 4405 4406 struct sk_buff * 4407 linuxkpi_ieee80211_probereq_get(struct ieee80211_hw *hw, uint8_t *addr, 4408 uint8_t *ssid, size_t ssid_len, size_t tailroom) 4409 { 4410 struct sk_buff *skb; 4411 struct ieee80211_frame *wh; 4412 uint8_t *p; 4413 size_t len; 4414 4415 len = sizeof(*wh); 4416 len += 2 + ssid_len; 4417 4418 skb = dev_alloc_skb(hw->extra_tx_headroom + len + tailroom); 4419 if (skb == NULL) 4420 return (NULL); 4421 4422 skb_reserve(skb, hw->extra_tx_headroom); 4423 4424 wh = skb_put_zero(skb, sizeof(*wh)); 4425 wh->i_fc[0] = IEEE80211_FC0_VERSION_0; 4426 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_PROBE_REQ | IEEE80211_FC0_TYPE_MGT; 4427 IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr); 4428 IEEE80211_ADDR_COPY(wh->i_addr2, addr); 4429 IEEE80211_ADDR_COPY(wh->i_addr3, ieee80211broadcastaddr); 4430 4431 p = skb_put(skb, 2 + ssid_len); 4432 *p++ = IEEE80211_ELEMID_SSID; 4433 *p++ = ssid_len; 4434 if (ssid_len > 0) 4435 memcpy(p, ssid, ssid_len); 4436 4437 return (skb); 4438 } 4439 4440 struct sk_buff * 4441 linuxkpi_ieee80211_pspoll_get(struct ieee80211_hw *hw, 4442 struct ieee80211_vif *vif) 4443 { 4444 struct lkpi_vif *lvif; 4445 struct ieee80211vap *vap; 4446 struct sk_buff *skb; 4447 struct ieee80211_frame_pspoll *psp; 4448 uint16_t v; 4449 4450 skb = dev_alloc_skb(hw->extra_tx_headroom + sizeof(*psp)); 4451 if (skb == NULL) 4452 return (NULL); 4453 4454 skb_reserve(skb, hw->extra_tx_headroom); 4455 4456 lvif = VIF_TO_LVIF(vif); 4457 vap = LVIF_TO_VAP(lvif); 4458 4459 psp = skb_put_zero(skb, sizeof(*psp)); 4460 psp->i_fc[0] = IEEE80211_FC0_VERSION_0; 4461 psp->i_fc[0] |= IEEE80211_FC0_SUBTYPE_PS_POLL | IEEE80211_FC0_TYPE_CTL; 4462 v = htole16(vif->bss_conf.aid | 1<<15 | 1<<16); 4463 memcpy(&psp->i_aid, &v, sizeof(v)); 4464 IEEE80211_ADDR_COPY(psp->i_bssid, vap->iv_bss->ni_macaddr); 4465 IEEE80211_ADDR_COPY(psp->i_ta, vif->addr); 4466 4467 return (skb); 4468 } 4469 4470 struct sk_buff * 4471 linuxkpi_ieee80211_nullfunc_get(struct ieee80211_hw *hw, 4472 struct ieee80211_vif *vif, bool qos) 4473 { 4474 struct lkpi_vif *lvif; 4475 struct ieee80211vap *vap; 4476 struct sk_buff *skb; 4477 struct ieee80211_frame *nullf; 4478 4479 skb = dev_alloc_skb(hw->extra_tx_headroom + sizeof(*nullf)); 4480 if (skb == NULL) 4481 return (NULL); 4482 4483 skb_reserve(skb, hw->extra_tx_headroom); 4484 4485 lvif = VIF_TO_LVIF(vif); 4486 vap = LVIF_TO_VAP(lvif); 4487 4488 nullf = skb_put_zero(skb, sizeof(*nullf)); 4489 nullf->i_fc[0] = IEEE80211_FC0_VERSION_0; 4490 nullf->i_fc[0] |= IEEE80211_FC0_SUBTYPE_NODATA | IEEE80211_FC0_TYPE_DATA; 4491 nullf->i_fc[1] = IEEE80211_FC1_DIR_TODS; 4492 4493 IEEE80211_ADDR_COPY(nullf->i_addr1, vap->iv_bss->ni_bssid); 4494 IEEE80211_ADDR_COPY(nullf->i_addr2, vif->addr); 4495 IEEE80211_ADDR_COPY(nullf->i_addr3, vap->iv_bss->ni_macaddr); 4496 4497 return (skb); 4498 } 4499 4500 struct wireless_dev * 4501 linuxkpi_ieee80211_vif_to_wdev(struct ieee80211_vif *vif) 4502 { 4503 struct lkpi_vif *lvif; 4504 4505 lvif = VIF_TO_LVIF(vif); 4506 return (&lvif->wdev); 4507 } 4508 4509 void 4510 linuxkpi_ieee80211_connection_loss(struct ieee80211_vif *vif) 4511 { 4512 struct lkpi_vif *lvif; 4513 struct ieee80211vap *vap; 4514 enum ieee80211_state nstate; 4515 int arg; 4516 4517 lvif = VIF_TO_LVIF(vif); 4518 vap = LVIF_TO_VAP(lvif); 4519 4520 /* 4521 * Go to init; otherwise we need to elaborately check state and 4522 * handle accordingly, e.g., if in RUN we could call iv_bmiss. 4523 * Let the statemachine handle all neccessary changes. 4524 */ 4525 nstate = IEEE80211_S_INIT; 4526 arg = 0; /* Not a valid reason. */ 4527 4528 #ifdef LINUXKPI_DEBUG_80211 4529 if (linuxkpi_debug_80211 & D80211_TRACE) 4530 ic_printf(vap->iv_ic, "%s: vif %p\n", __func__, vif); 4531 #endif 4532 ieee80211_new_state(vap, nstate, arg); 4533 } 4534 4535 void 4536 linuxkpi_ieee80211_beacon_loss(struct ieee80211_vif *vif) 4537 { 4538 struct lkpi_vif *lvif; 4539 struct ieee80211vap *vap; 4540 4541 lvif = VIF_TO_LVIF(vif); 4542 vap = LVIF_TO_VAP(lvif); 4543 4544 #ifdef LINUXKPI_DEBUG_80211 4545 if (linuxkpi_debug_80211 & D80211_TRACE || vap->iv_state != IEEE80211_S_RUN) 4546 ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s\n", __func__, 4547 vif, vap, ieee80211_state_name[vap->iv_state]); 4548 #endif 4549 ieee80211_beacon_miss(vap->iv_ic); 4550 } 4551 4552 MODULE_VERSION(linuxkpi_wlan, 1); 4553 MODULE_DEPEND(linuxkpi_wlan, linuxkpi, 1, 1, 1); 4554 MODULE_DEPEND(linuxkpi_wlan, wlan, 1, 1, 1); 4555