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