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