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