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