1 /*- 2 * Copyright (c) 2020-2021 The FreeBSD Foundation 3 * Copyright (c) 2020-2021 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 57 #include <net/if.h> 58 #include <net/if_var.h> 59 #include <net/if_media.h> 60 #include <net/ethernet.h> 61 62 #include <net80211/ieee80211_var.h> 63 #include <net80211/ieee80211_proto.h> 64 #include <net80211/ieee80211_ratectl.h> 65 #include <net80211/ieee80211_radiotap.h> 66 67 #define LINUXKPI_NET80211 68 #include <net/mac80211.h> 69 70 #include <linux/workqueue.h> 71 #include "linux_80211.h" 72 73 static MALLOC_DEFINE(M_LKPI80211, "lkpi80211", "Linux KPI 80211 compat"); 74 75 /* -------------------------------------------------------------------------- */ 76 /* These are unrelated to 802.11 sysctl bug debugging during 802.11 work so * 77 * keep them here rather than in a more general file. */ 78 79 int debug_skb; 80 SYSCTL_INT(_compat_linuxkpi, OID_AUTO, debug_skb, CTLFLAG_RWTUN, 81 &debug_skb, 0, "SKB debug level"); 82 83 /* -------------------------------------------------------------------------- */ 84 85 int debug_80211; 86 SYSCTL_INT(_compat_linuxkpi, OID_AUTO, debug_80211, CTLFLAG_RWTUN, 87 &debug_80211, 0, "80211 debug Level"); 88 89 #define LINUXKPI_DEBUG_80211 90 #ifdef LINUXKPI_DEBUG_80211 91 #ifndef D80211_TODO 92 #define D80211_TODO 0x1 93 #endif 94 #ifndef D80211_IMPROVE 95 #define D80211_IMPROVE 0x2 96 #endif 97 #define D80211_TRACE 0x10 98 #define D80211_TRACEOK 0x20 99 #define D80211_TRACE_TX 0x100 100 #define D80211_TRACE_TX_DUMP 0x200 101 #define D80211_TRACE_RX 0x1000 102 #define D80211_TRACE_RX_DUMP 0x2000 103 #define D80211_TRACE_RX_BEACONS 0x4000 104 #define D80211_TRACEX (D80211_TRACE_TX|D80211_TRACE_RX) 105 #define D80211_TRACEX_DUMP (D80211_TRACE_TX_DUMP|D80211_TRACE_RX_DUMP) 106 #define UNIMPLEMENTED if (debug_80211 & D80211_TODO) \ 107 printf("XXX-TODO %s:%d: UNIMPLEMENTED\n", __func__, __LINE__) 108 #define TRACEOK() if (debug_80211 & D80211_TRACEOK) \ 109 printf("XXX-TODO %s:%d: TRACEPOINT\n", __func__, __LINE__) 110 #else 111 #define UNIMPLEMENTED do { } while (0) 112 #define TRACEOK() do { } while (0) 113 #endif 114 115 /* #define PREP_TX_INFO_DURATION (IEEE80211_TRANS_WAIT * 1000) */ 116 #ifndef PREP_TX_INFO_DURATION 117 #define PREP_TX_INFO_DURATION 0 /* Let the driver do its thing. */ 118 #endif 119 120 /* This is DSAP | SSAP | CTRL | ProtoID/OrgCode{3}. */ 121 const uint8_t rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; 122 123 const struct cfg80211_ops linuxkpi_mac80211cfgops = { 124 /* 125 * XXX TODO need a "glue layer" to link cfg80211 ops to 126 * mac80211 and to the driver or net80211. 127 * Can we pass some on 1:1? Need to compare the (*f)(). 128 */ 129 }; 130 131 static struct lkpi_sta *lkpi_find_lsta_by_ni(struct lkpi_vif *, 132 struct ieee80211_node *); 133 static void lkpi_80211_txq_task(void *, int); 134 static void lkpi_ieee80211_free_skb_mbuf(void *); 135 136 static enum nl80211_band 137 lkpi_net80211_chan_to_nl80211_band(struct ieee80211_channel *c) 138 { 139 140 if (IEEE80211_IS_CHAN_2GHZ(c)) 141 return (NL80211_BAND_2GHZ); 142 else if (IEEE80211_IS_CHAN_5GHZ(c)) 143 return (NL80211_BAND_5GHZ); 144 #ifdef __notyet__ 145 else if () 146 return (NL80211_BAND_6GHZ); 147 else if () 148 return (NL80211_BAND_60GHZ); 149 else if (IEEE80211_IS_CHAN_GSM(c)) 150 return (NL80211_BAND_XXX); 151 #endif 152 else 153 panic("%s: unsupported band. c %p flags %#x\n", 154 __func__, c, c->ic_flags); 155 } 156 157 static uint32_t 158 lkpi_nl80211_band_to_net80211_band(enum nl80211_band band) 159 { 160 161 /* XXX-BZ this is just silly; net80211 is too convoluted. */ 162 /* IEEE80211_CHAN_A / _G / .. doesn't really work either. */ 163 switch (band) { 164 case NL80211_BAND_2GHZ: 165 return (IEEE80211_CHAN_2GHZ); 166 break; 167 case NL80211_BAND_5GHZ: 168 return (IEEE80211_CHAN_5GHZ); 169 break; 170 case NL80211_BAND_60GHZ: 171 break; 172 case NL80211_BAND_6GHZ: 173 break; 174 default: 175 panic("%s: unsupported band %u\n", __func__, band); 176 break; 177 } 178 179 IMPROVE(); 180 return (0x00); 181 } 182 183 static enum ieee80211_ac_numbers 184 lkpi_ac_net_to_l80211(int ac) 185 { 186 187 switch (ac) { 188 case WME_AC_VO: 189 return (IEEE80211_AC_VO); 190 case WME_AC_VI: 191 return (IEEE80211_AC_VI); 192 case WME_AC_BE: 193 return (IEEE80211_AC_BE); 194 case WME_AC_BK: 195 return (IEEE80211_AC_BK); 196 default: 197 printf("%s: invalid WME_AC_* input: ac = %d\n", __func__, ac); 198 return (IEEE80211_AC_BE); 199 } 200 } 201 202 static enum nl80211_iftype 203 lkpi_opmode_to_vif_type(enum ieee80211_opmode opmode) 204 { 205 206 switch (opmode) { 207 case IEEE80211_M_IBSS: 208 return (NL80211_IFTYPE_ADHOC); 209 break; 210 case IEEE80211_M_STA: 211 return (NL80211_IFTYPE_STATION); 212 break; 213 case IEEE80211_M_WDS: 214 return (NL80211_IFTYPE_WDS); 215 break; 216 case IEEE80211_M_HOSTAP: 217 return (NL80211_IFTYPE_AP); 218 break; 219 case IEEE80211_M_MONITOR: 220 return (NL80211_IFTYPE_MONITOR); 221 break; 222 case IEEE80211_M_MBSS: 223 return (NL80211_IFTYPE_MESH_POINT); 224 break; 225 case IEEE80211_M_AHDEMO: 226 /* FALLTHROUGH */ 227 default: 228 printf("ERROR: %s: unsupported opmode %d\n", __func__, opmode); 229 /* FALLTHROUGH */ 230 } 231 return (NL80211_IFTYPE_UNSPECIFIED); 232 } 233 234 #ifdef __notyet__ 235 static uint32_t 236 lkpi_l80211_to_net80211_cyphers(uint32_t wlan_cipher_suite) 237 { 238 239 switch (wlan_cipher_suite) { 240 case WLAN_CIPHER_SUITE_WEP40: 241 return (IEEE80211_CRYPTO_WEP); 242 case WLAN_CIPHER_SUITE_TKIP: 243 return (IEEE80211_CRYPTO_TKIP); 244 case WLAN_CIPHER_SUITE_CCMP: 245 return (IEEE80211_CIPHER_AES_CCM); 246 case WLAN_CIPHER_SUITE_WEP104: 247 return (IEEE80211_CRYPTO_WEP); 248 case WLAN_CIPHER_SUITE_AES_CMAC: 249 case WLAN_CIPHER_SUITE_GCMP: 250 case WLAN_CIPHER_SUITE_GCMP_256: 251 case WLAN_CIPHER_SUITE_CCMP_256: 252 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 253 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 254 case WLAN_CIPHER_SUITE_BIP_CMAC_256: 255 printf("%s: unsupported WLAN Cipher Suite %#08x | %u\n", __func__, 256 wlan_cipher_suite >> 8, wlan_cipher_suite & 0xff); 257 break; 258 default: 259 printf("%s: unknown WLAN Cipher Suite %#08x | %u\n", __func__, 260 wlan_cipher_suite >> 8, wlan_cipher_suite & 0xff); 261 } 262 263 return (0); 264 } 265 #endif 266 267 #ifdef TRY_HW_CRYPTO 268 static uint32_t 269 lkpi_net80211_to_l80211_cipher_suite(uint32_t cipher, uint8_t keylen) 270 { 271 272 switch (cipher) { 273 case IEEE80211_CIPHER_TKIP: 274 return (WLAN_CIPHER_SUITE_TKIP); 275 case IEEE80211_CIPHER_AES_CCM: 276 return (WLAN_CIPHER_SUITE_CCMP); 277 case IEEE80211_CIPHER_WEP: 278 if (keylen < 8) 279 return (WLAN_CIPHER_SUITE_WEP40); 280 else 281 return (WLAN_CIPHER_SUITE_WEP104); 282 break; 283 case IEEE80211_CIPHER_AES_OCB: 284 case IEEE80211_CIPHER_TKIPMIC: 285 case IEEE80211_CIPHER_CKIP: 286 case IEEE80211_CIPHER_NONE: 287 printf("%s: unsupported cipher %#010x\n", __func__, cipher); 288 break; 289 default: 290 printf("%s: unknown cipher %#010x\n", __func__, cipher); 291 }; 292 return (0); 293 } 294 #endif 295 296 #ifdef __notyet__ 297 static enum ieee80211_sta_state 298 lkpi_net80211_state_to_sta_state(enum ieee80211_state state) 299 { 300 301 /* 302 * XXX-BZ The net80211 states are "try to ..", the lkpi8011 states are 303 * "done". Also ASSOC/AUTHORIZED are both "RUN" then? 304 */ 305 switch (state) { 306 case IEEE80211_S_INIT: 307 return (IEEE80211_STA_NOTEXIST); 308 case IEEE80211_S_SCAN: 309 return (IEEE80211_STA_NONE); 310 case IEEE80211_S_AUTH: 311 return (IEEE80211_STA_AUTH); 312 case IEEE80211_S_ASSOC: 313 return (IEEE80211_STA_ASSOC); 314 case IEEE80211_S_RUN: 315 return (IEEE80211_STA_AUTHORIZED); 316 case IEEE80211_S_CAC: 317 case IEEE80211_S_CSA: 318 case IEEE80211_S_SLEEP: 319 default: 320 UNIMPLEMENTED; 321 }; 322 323 return (IEEE80211_STA_NOTEXIST); 324 } 325 #endif 326 327 static struct linuxkpi_ieee80211_channel * 328 lkpi_find_lkpi80211_chan(struct lkpi_hw *lhw, 329 struct ieee80211_channel *c) 330 { 331 struct ieee80211_hw *hw; 332 struct linuxkpi_ieee80211_channel *channels; 333 enum nl80211_band band; 334 int i, nchans; 335 336 hw = LHW_TO_HW(lhw); 337 band = lkpi_net80211_chan_to_nl80211_band(c); 338 if (hw->wiphy->bands[band] == NULL) 339 return (NULL); 340 341 nchans = hw->wiphy->bands[band]->n_channels; 342 if (nchans <= 0) 343 return (NULL); 344 345 channels = hw->wiphy->bands[band]->channels; 346 for (i = 0; i < nchans; i++) { 347 if (channels[i].hw_value == c->ic_ieee) 348 return (&channels[i]); 349 } 350 351 return (NULL); 352 } 353 354 static struct linuxkpi_ieee80211_channel * 355 lkpi_get_lkpi80211_chan(struct ieee80211com *ic, struct ieee80211_node *ni) 356 { 357 struct linuxkpi_ieee80211_channel *chan; 358 struct ieee80211_channel *c; 359 struct lkpi_hw *lhw; 360 361 chan = NULL; 362 if (ni != NULL && ni->ni_chan != IEEE80211_CHAN_ANYC) 363 c = ni->ni_chan; 364 else if (ic->ic_bsschan != IEEE80211_CHAN_ANYC) 365 c = ic->ic_bsschan; 366 else if (ic->ic_curchan != IEEE80211_CHAN_ANYC) 367 c = ic->ic_curchan; 368 else 369 c = NULL; 370 371 if (c != NULL && c != IEEE80211_CHAN_ANYC) { 372 lhw = ic->ic_softc; 373 chan = lkpi_find_lkpi80211_chan(lhw, c); 374 } 375 376 return (chan); 377 } 378 379 #ifdef TRY_HW_CRYPTO 380 static int 381 _lkpi_iv_key_set_delete(struct ieee80211vap *vap, const struct ieee80211_key *k, 382 enum set_key_cmd cmd) 383 { 384 struct ieee80211com *ic; 385 struct lkpi_hw *lhw; 386 struct ieee80211_hw *hw; 387 struct lkpi_vif *lvif; 388 struct ieee80211_vif *vif; 389 struct ieee80211_sta *sta; 390 struct ieee80211_node *ni; 391 struct ieee80211_key_conf *kc; 392 int error; 393 394 /* XXX TODO Check (k->wk_flags & IEEE80211_KEY_SWENCRYPT) and don't upload to driver/hw? */ 395 396 ic = vap->iv_ic; 397 lhw = ic->ic_softc; 398 hw = LHW_TO_HW(lhw); 399 lvif = VAP_TO_LVIF(vap); 400 vif = LVIF_TO_VIF(lvif); 401 402 memset(&kc, 0, sizeof(kc)); 403 kc = malloc(sizeof(*kc) + k->wk_keylen, M_LKPI80211, M_WAITOK | M_ZERO); 404 kc->cipher = lkpi_net80211_to_l80211_cipher_suite( 405 k->wk_cipher->ic_cipher, k->wk_keylen); 406 kc->keyidx = k->wk_keyix; 407 #if 0 408 kc->hw_key_idx = /* set by hw and needs to be passed for TX */; 409 #endif 410 atomic64_set(&kc->tx_pn, k->wk_keytsc); 411 kc->keylen = k->wk_keylen; 412 memcpy(kc->key, k->wk_key, k->wk_keylen); 413 414 switch (kc->cipher) { 415 case WLAN_CIPHER_SUITE_CCMP: 416 kc->iv_len = k->wk_cipher->ic_header; 417 kc->icv_len = k->wk_cipher->ic_trailer; 418 break; 419 case WLAN_CIPHER_SUITE_TKIP: 420 default: 421 IMPROVE(); 422 return (0); 423 }; 424 425 ni = vap->iv_bss; 426 sta = ieee80211_find_sta(vif, ni->ni_bssid); 427 if (sta != NULL) { 428 struct lkpi_sta *lsta; 429 430 lsta = STA_TO_LSTA(sta); 431 lsta->kc = kc; 432 } 433 434 error = lkpi_80211_mo_set_key(hw, cmd, vif, sta, kc); 435 if (error != 0) { 436 /* XXX-BZ leaking kc currently */ 437 ic_printf(ic, "%s: set_key failed: %d\n", __func__, error); 438 return (0); 439 } else { 440 ic_printf(ic, "%s: set_key succeeded: keyidx %u hw_key_idx %u " 441 "flags %#10x\n", __func__, 442 kc->keyidx, kc->hw_key_idx, kc->flags); 443 return (1); 444 } 445 } 446 447 static int 448 lkpi_iv_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) 449 { 450 451 /* XXX-BZ one day we should replace this iterating over VIFs, or node list? */ 452 return (_lkpi_iv_key_set_delete(vap, k, DISABLE_KEY)); 453 } 454 static int 455 lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k) 456 { 457 458 return (_lkpi_iv_key_set_delete(vap, k, SET_KEY)); 459 } 460 #endif 461 462 static u_int 463 lkpi_ic_update_mcast_copy(void *arg, struct sockaddr_dl *sdl, u_int cnt) 464 { 465 struct netdev_hw_addr_list *mc_list; 466 struct netdev_hw_addr *addr; 467 468 KASSERT(arg != NULL && sdl != NULL, ("%s: arg %p sdl %p cnt %u\n", 469 __func__, arg, sdl, cnt)); 470 471 mc_list = arg; 472 /* If it is on the list already skip it. */ 473 netdev_hw_addr_list_for_each(addr, mc_list) { 474 if (!memcmp(addr->addr, LLADDR(sdl), sdl->sdl_alen)) 475 return (0); 476 } 477 478 addr = malloc(sizeof(*addr), M_LKPI80211, M_NOWAIT | M_ZERO); 479 if (addr == NULL) 480 return (0); 481 482 INIT_LIST_HEAD(&addr->addr_list); 483 memcpy(addr->addr, LLADDR(sdl), sdl->sdl_alen); 484 /* XXX this should be a netdev function? */ 485 list_add(&addr->addr_list, &mc_list->addr_list); 486 mc_list->count++; 487 488 if (debug_80211 & D80211_TRACE) 489 printf("%s:%d: mc_list count %d: added %6D\n", 490 __func__, __LINE__, mc_list->count, addr->addr, ":"); 491 492 return (1); 493 } 494 495 static void 496 lkpi_update_mcast_filter(struct ieee80211com *ic, bool force) 497 { 498 struct lkpi_hw *lhw; 499 struct ieee80211_hw *hw; 500 struct netdev_hw_addr_list mc_list; 501 struct list_head *le, *next; 502 struct netdev_hw_addr *addr; 503 struct ieee80211vap *vap; 504 u64 mc; 505 unsigned int changed_flags, total_flags; 506 507 lhw = ic->ic_softc; 508 509 if (lhw->ops->prepare_multicast == NULL || 510 lhw->ops->configure_filter == NULL) 511 return; 512 513 if (!lhw->update_mc && !force) 514 return; 515 516 changed_flags = total_flags = 0; 517 mc_list.count = 0; 518 INIT_LIST_HEAD(&mc_list.addr_list); 519 if (ic->ic_allmulti == 0) { 520 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) 521 if_foreach_llmaddr(vap->iv_ifp, 522 lkpi_ic_update_mcast_copy, &mc_list); 523 } else { 524 changed_flags |= FIF_ALLMULTI; 525 } 526 527 hw = LHW_TO_HW(lhw); 528 mc = lkpi_80211_mo_prepare_multicast(hw, &mc_list); 529 /* 530 * XXX-BZ make sure to get this sorted what is a change, 531 * what gets all set; what was already set? 532 */ 533 total_flags = changed_flags; 534 lkpi_80211_mo_configure_filter(hw, changed_flags, &total_flags, mc); 535 536 if (debug_80211 & D80211_TRACE) 537 printf("%s: changed_flags %#06x count %d total_flags %#010x\n", 538 __func__, changed_flags, mc_list.count, total_flags); 539 540 if (mc_list.count != 0) { 541 list_for_each_safe(le, next, &mc_list.addr_list) { 542 addr = list_entry(le, struct netdev_hw_addr, addr_list); 543 free(addr, M_LKPI80211); 544 mc_list.count--; 545 } 546 } 547 KASSERT(mc_list.count == 0, ("%s: mc_list %p count %d != 0\n", 548 __func__, &mc_list, mc_list.count)); 549 } 550 551 const uint8_t tid_to_mac80211_ac[] = { 552 IEEE80211_AC_BE, 553 IEEE80211_AC_BK, 554 IEEE80211_AC_BK, 555 IEEE80211_AC_BE, 556 IEEE80211_AC_VI, 557 IEEE80211_AC_VI, 558 IEEE80211_AC_VO, 559 IEEE80211_AC_VO, 560 #if 0 561 IEEE80211_AC_VO, /* We treat MGMT as TID 8, which is set as AC_VO */ 562 #endif 563 }; 564 565 static void 566 lkpi_stop_hw_scan(struct lkpi_hw *lhw, struct ieee80211_vif *vif) 567 { 568 struct ieee80211_hw *hw; 569 int error; 570 571 if ((lhw->scan_flags & LKPI_SCAN_RUNNING) == 0) 572 return; 573 574 hw = LHW_TO_HW(lhw); 575 576 /* Need to cancel the scan. */ 577 lkpi_80211_mo_cancel_hw_scan(hw, vif); 578 579 /* Need to make sure we see ieee80211_scan_completed. */ 580 error = msleep(lhw, &lhw->mtx, 0, "lhwscanstop", hz/2); 581 582 if ((lhw->scan_flags & LKPI_SCAN_RUNNING) != 0) 583 ic_printf(lhw->ic, "%s: failed to cancel scan: %d (%p, %p)\n", 584 __func__, error, lhw, vif); 585 } 586 587 static void 588 lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif, 589 struct lkpi_hw *lhw) 590 { 591 sta->aid = 0; 592 if (vif->bss_conf.assoc) { 593 struct ieee80211_hw *hw; 594 enum ieee80211_bss_changed changed; 595 596 lhw->update_mc = true; 597 lkpi_update_mcast_filter(lhw->ic, true); 598 599 changed = 0; 600 vif->bss_conf.assoc = false; 601 vif->bss_conf.aid = 0; 602 changed |= BSS_CHANGED_ASSOC; 603 IMPROVE(); 604 hw = LHW_TO_HW(lhw); 605 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, 606 changed); 607 } 608 } 609 610 static void 611 lkpi_wake_tx_queues(struct ieee80211_hw *hw, struct ieee80211_sta *sta, 612 bool dequeue_seen, bool no_emptyq) 613 { 614 struct lkpi_txq *ltxq; 615 int tid; 616 617 /* Wake up all queues to know they are allocated in the driver. */ 618 for (tid = 0; tid < nitems(sta->txq); tid++) { 619 620 if (tid == IEEE80211_NUM_TIDS) { 621 IMPROVE("station specific?"); 622 if (!ieee80211_hw_check(hw, STA_MMPDU_TXQ)) 623 continue; 624 } else if (tid >= hw->queues) 625 continue; 626 627 if (sta->txq[tid] == NULL) 628 continue; 629 630 ltxq = TXQ_TO_LTXQ(sta->txq[tid]); 631 if (dequeue_seen && !ltxq->seen_dequeue) 632 continue; 633 634 if (no_emptyq && skb_queue_empty(<xq->skbq)) 635 continue; 636 637 lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid]); 638 } 639 } 640 641 /* -------------------------------------------------------------------------- */ 642 643 static int 644 lkpi_sta_state_do_nada(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 645 { 646 647 return (0); 648 } 649 650 /* lkpi_iv_newstate() handles the stop scan case generally. */ 651 #define lkpi_sta_scan_to_init(_v, _n, _a) lkpi_sta_state_do_nada(_v, _n, _a) 652 653 static int 654 lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 655 { 656 struct linuxkpi_ieee80211_channel *chan; 657 struct ieee80211_chanctx_conf *conf; 658 struct lkpi_hw *lhw; 659 struct ieee80211_hw *hw; 660 struct lkpi_vif *lvif; 661 struct ieee80211_vif *vif; 662 struct ieee80211_node *ni; 663 struct lkpi_sta *lsta; 664 struct ieee80211_sta *sta; 665 enum ieee80211_bss_changed bss_changed; 666 struct ieee80211_prep_tx_info prep_tx_info; 667 uint32_t changed; 668 int error; 669 670 chan = lkpi_get_lkpi80211_chan(vap->iv_ic, vap->iv_bss); 671 if (chan == NULL) { 672 ic_printf(vap->iv_ic, "%s: failed to get channel\n", __func__); 673 return (ESRCH); 674 } 675 676 lhw = vap->iv_ic->ic_softc; 677 hw = LHW_TO_HW(lhw); 678 lvif = VAP_TO_LVIF(vap); 679 vif = LVIF_TO_VIF(lvif); 680 681 IEEE80211_UNLOCK(vap->iv_ic); 682 683 /* Add chanctx (or if exists, change it). */ 684 if (vif->chanctx_conf != NULL) { 685 conf = vif->chanctx_conf; 686 IMPROVE("diff changes for changed, working on live copy, rcu"); 687 } else { 688 /* Keep separate alloc as in Linux this is rcu managed? */ 689 conf = malloc(sizeof(*conf) + hw->chanctx_data_size, 690 M_LKPI80211, M_WAITOK | M_ZERO); 691 } 692 693 conf->rx_chains_dynamic = 1; 694 conf->rx_chains_static = 1; 695 conf->radar_enabled = 696 (chan->flags & IEEE80211_CHAN_RADAR) ? true : false; 697 conf->def.chan = chan; 698 conf->def.width = NL80211_CHAN_WIDTH_20_NOHT; 699 conf->def.center_freq1 = chan->center_freq; 700 conf->def.center_freq2 = 0; 701 /* Responder ... */ 702 conf->min_def.chan = chan; 703 conf->min_def.width = NL80211_CHAN_WIDTH_20_NOHT; 704 conf->min_def.center_freq1 = chan->center_freq; 705 conf->min_def.center_freq2 = 0; 706 IMPROVE("currently 20_NOHT only"); 707 708 ni = NULL; 709 error = 0; 710 if (vif->chanctx_conf != NULL) { 711 changed = IEEE80211_CHANCTX_CHANGE_MIN_WIDTH; 712 changed |= IEEE80211_CHANCTX_CHANGE_RADAR; 713 changed |= IEEE80211_CHANCTX_CHANGE_RX_CHAINS; 714 changed |= IEEE80211_CHANCTX_CHANGE_WIDTH; 715 lkpi_80211_mo_change_chanctx(hw, conf, changed); 716 } else { 717 error = lkpi_80211_mo_add_chanctx(hw, conf); 718 if (error == 0 || error == EOPNOTSUPP) { 719 vif->bss_conf.chandef.chan = conf->def.chan; 720 vif->bss_conf.chandef.width = conf->def.width; 721 vif->bss_conf.chandef.center_freq1 = 722 conf->def.center_freq1; 723 vif->bss_conf.chandef.center_freq2 = 724 conf->def.center_freq2; 725 } else { 726 goto out; 727 } 728 /* Assign vif chanctx. */ 729 if (error == 0) 730 error = lkpi_80211_mo_assign_vif_chanctx(hw, vif, conf); 731 if (error == EOPNOTSUPP) 732 error = 0; 733 if (error != 0) { 734 lkpi_80211_mo_remove_chanctx(hw, conf); 735 free(conf, M_LKPI80211); 736 goto out; 737 } 738 } 739 IMPROVE("update radiotap chan fields too"); 740 741 ni = ieee80211_ref_node(vap->iv_bss); 742 743 /* Set bss info (bss_info_changed). */ 744 bss_changed = 0; 745 IEEE80211_ADDR_COPY(vif->bss_conf.bssid, ni->ni_bssid); 746 bss_changed |= BSS_CHANGED_BSSID; 747 vif->bss_conf.txpower = ni->ni_txpower; 748 bss_changed |= BSS_CHANGED_TXPOWER; 749 vif->bss_conf.idle = false; 750 bss_changed |= BSS_CHANGED_IDLE; 751 vif->bss_conf.beacon_int = ni->ni_intval; 752 /* iwlwifi FW bug workaround; iwl_mvm_mac_sta_state. */ 753 if (vif->bss_conf.beacon_int < 16) 754 vif->bss_conf.beacon_int = 16; 755 bss_changed |= BSS_CHANGED_BEACON_INT; 756 /* Should almost assert it is this. */ 757 vif->bss_conf.assoc = false; 758 vif->bss_conf.aid = 0; 759 /* RATES */ 760 IMPROVE("bss info: not all needs to come now and rates are missing"); 761 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); 762 763 /* Add (or adjust) sta and change state (from NOTEXIST) to NONE. */ 764 lsta = ni->ni_drv_data; 765 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 766 KASSERT(lsta->state == IEEE80211_STA_NOTEXIST, ("%s: lsta %p state not " 767 "NOTEXIST: %#x\n", __func__, lsta, lsta->state)); 768 sta = LSTA_TO_STA(lsta); 769 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_NONE); 770 if (error != 0) { 771 IMPROVE("do we need to undo the chan ctx?"); 772 goto out; 773 } 774 #if 0 775 lsta->added_to_drv = true; /* mo manages. */ 776 #endif 777 778 /* 779 * Wakeup all queues now that sta is there so we have as much time to 780 * possibly prepare the queue in the driver to be ready for the 1st 781 * packet; lkpi_80211_txq_tx_one() still has a workaround as there 782 * is no guarantee or way to check. 783 */ 784 lkpi_wake_tx_queues(hw, sta, false, false); 785 786 { 787 int i, count; 788 789 for (i = 3 * (hw->queues + 1); i > 0; i--) { 790 struct lkpi_txq *ltxq; 791 int tid; 792 793 count = 0; 794 /* Wake up all queues to know they are allocated in the driver. */ 795 for (tid = 0; tid < nitems(sta->txq); tid++) { 796 797 if (tid == IEEE80211_NUM_TIDS) { 798 IMPROVE("station specific?"); 799 if (!ieee80211_hw_check(hw, STA_MMPDU_TXQ)) 800 continue; 801 } else if (tid >= hw->queues) 802 continue; 803 804 if (sta->txq[tid] == NULL) 805 continue; 806 807 ltxq = TXQ_TO_LTXQ(sta->txq[tid]); 808 if (!ltxq->seen_dequeue) 809 count++; 810 } 811 if (count == 0) 812 break; 813 #ifdef LINUXKPI_DEBUG_80211 814 if (count > 0) 815 ic_printf(vap->iv_ic, "%s: waiting for %d quuees " 816 "to be allocated by driver\n", __func__, count); 817 #endif 818 pause("lkpi80211txq", hz/10); 819 } 820 #ifdef LINUXKPI_DEBUG_80211 821 if (count > 0) 822 ic_printf(vap->iv_ic, "%s: %d quuees still not " 823 "allocated by driver\n", __func__, count); 824 #endif 825 } 826 827 /* Start mgd_prepare_tx. */ 828 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 829 prep_tx_info.duration = PREP_TX_INFO_DURATION; 830 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); 831 lsta->in_mgd = true; 832 833 /* 834 * What is going to happen next: 835 * - <twiddle> .. we should end up in "auth_to_assoc" 836 * - event_callback 837 * - update sta_state (NONE to AUTH) 838 * - mgd_complete_tx 839 * (ideally we'd do that on a callback for something else ...) 840 */ 841 842 out: 843 IEEE80211_LOCK(vap->iv_ic); 844 if (ni != NULL) 845 ieee80211_free_node(ni); 846 return (error); 847 } 848 849 static int 850 lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 851 { 852 struct lkpi_hw *lhw; 853 struct ieee80211_hw *hw; 854 struct lkpi_vif *lvif; 855 struct ieee80211_vif *vif; 856 struct ieee80211_node *ni; 857 struct lkpi_sta *lsta; 858 struct ieee80211_sta *sta; 859 struct ieee80211_prep_tx_info prep_tx_info; 860 int error; 861 862 lhw = vap->iv_ic->ic_softc; 863 hw = LHW_TO_HW(lhw); 864 lvif = VAP_TO_LVIF(vap); 865 vif = LVIF_TO_VIF(lvif); 866 867 /* Keep ni around. */ 868 ni = ieee80211_ref_node(vap->iv_bss); 869 870 IEEE80211_UNLOCK(vap->iv_ic); 871 lsta = ni->ni_drv_data; 872 sta = LSTA_TO_STA(lsta); 873 874 /* flush, drop. */ 875 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), true); 876 877 IEEE80211_LOCK(vap->iv_ic); 878 879 /* Call iv_newstate first so we get potential deauth packet out. */ 880 error = lvif->iv_newstate(vap, nstate, arg); 881 if (error != 0) 882 goto outni; 883 884 IEEE80211_UNLOCK(vap->iv_ic); 885 886 /* Wake tx queues to get packet(s) out. */ 887 lkpi_wake_tx_queues(hw, sta, true, true); 888 889 /* flush, no drop */ 890 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), false); 891 892 /* Take the station and chan ctx down again. */ 893 894 IMPROVE("event callback with failure?"); 895 896 /* End mgd_complete_tx. */ 897 if (lsta->in_mgd) { 898 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 899 prep_tx_info.success = false; 900 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); 901 lsta->in_mgd = false; 902 } 903 904 #ifdef __not_yet__ 905 /* sync_rx_queues */ 906 lkpi_80211_mo_sync_rx_queues(hw); 907 908 /* sta_pre_rcu_remove */ 909 lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta); 910 #endif 911 912 /* Adjust sta and change state (from NONE) to NOTEXIST. */ 913 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 914 KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not " 915 "NONE: %#x\n", __func__, lsta, lsta->state)); 916 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_NOTEXIST); 917 if (error != 0) { 918 IMPROVE("do we need to undo the chan ctx?"); 919 goto out; 920 } 921 #if 0 922 lsta->added_to_drv = false; /* mo manages. */ 923 #endif 924 925 IMPROVE("Any bss_info changes to announce?"); 926 927 if (vif->chanctx_conf != NULL) { 928 struct ieee80211_chanctx_conf *conf; 929 930 conf = vif->chanctx_conf; 931 /* Remove vif context. */ 932 lkpi_80211_mo_unassign_vif_chanctx(hw, vif, &vif->chanctx_conf); 933 /* NB: vif->chanctx_conf is NULL now. */ 934 935 /* Remove chan ctx. */ 936 lkpi_80211_mo_remove_chanctx(hw, conf); 937 free(conf, M_LKPI80211); 938 } 939 940 /* No need to start a scan; ic_scan_start should do. */ 941 942 error = EALREADY; 943 out: 944 IEEE80211_LOCK(vap->iv_ic); 945 outni: 946 if (ni != NULL) 947 ieee80211_free_node(ni); 948 return (error); 949 } 950 951 static int 952 lkpi_sta_auth_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 953 { 954 int error; 955 956 error = lkpi_sta_auth_to_scan(vap, nstate, arg); 957 if (error == 0) 958 error = lkpi_sta_scan_to_init(vap, nstate, arg); 959 return (error); 960 } 961 962 static int 963 lkpi_sta_auth_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 964 { 965 struct lkpi_hw *lhw; 966 struct ieee80211_hw *hw; 967 struct lkpi_vif *lvif; 968 struct ieee80211_vif *vif; 969 struct ieee80211_node *ni; 970 struct lkpi_sta *lsta; 971 struct ieee80211_sta *sta; 972 struct ieee80211_prep_tx_info prep_tx_info; 973 int error; 974 975 lhw = vap->iv_ic->ic_softc; 976 hw = LHW_TO_HW(lhw); 977 lvif = VAP_TO_LVIF(vap); 978 vif = LVIF_TO_VIF(lvif); 979 980 IEEE80211_UNLOCK(vap->iv_ic); 981 ni = NULL; 982 983 /* Finish auth. */ 984 IMPROVE("event callback"); 985 986 /* Update sta_state (NONE to AUTH). */ 987 ni = ieee80211_ref_node(vap->iv_bss); 988 lsta = ni->ni_drv_data; 989 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 990 KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not " 991 "NONE: %#x\n", __func__, lsta, lsta->state)); 992 sta = LSTA_TO_STA(lsta); 993 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_AUTH); 994 if (error != 0) 995 goto out; 996 997 /* End mgd_complete_tx. */ 998 if (lsta->in_mgd) { 999 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1000 prep_tx_info.success = true; 1001 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); 1002 lsta->in_mgd = false; 1003 } 1004 1005 /* Now start assoc. */ 1006 1007 /* Start mgd_prepare_tx. */ 1008 if (!lsta->in_mgd) { 1009 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1010 prep_tx_info.duration = PREP_TX_INFO_DURATION; 1011 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); 1012 lsta->in_mgd = true; 1013 } 1014 1015 /* Wake tx queue to get packet out. */ 1016 lkpi_wake_tx_queues(hw, sta, true, true); 1017 1018 /* 1019 * <twiddle> .. we end up in "assoc_to_run" 1020 * - update sta_state (AUTH to ASSOC) 1021 * - conf_tx [all] 1022 * - bss_info_changed (assoc, aid, ssid, ..) 1023 * - change_chanctx (if needed) 1024 * - event_callback 1025 * - mgd_complete_tx 1026 */ 1027 1028 out: 1029 IEEE80211_LOCK(vap->iv_ic); 1030 if (ni != NULL) 1031 ieee80211_free_node(ni); 1032 return (error); 1033 } 1034 1035 /* auth_to_auth, assoc_to_assoc. */ 1036 static int 1037 lkpi_sta_a_to_a(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1038 { 1039 struct lkpi_hw *lhw; 1040 struct ieee80211_hw *hw; 1041 struct lkpi_vif *lvif; 1042 struct ieee80211_vif *vif; 1043 struct ieee80211_node *ni; 1044 struct lkpi_sta *lsta; 1045 struct ieee80211_prep_tx_info prep_tx_info; 1046 1047 lhw = vap->iv_ic->ic_softc; 1048 hw = LHW_TO_HW(lhw); 1049 lvif = VAP_TO_LVIF(vap); 1050 vif = LVIF_TO_VIF(lvif); 1051 1052 ni = ieee80211_ref_node(vap->iv_bss); 1053 1054 IEEE80211_UNLOCK(vap->iv_ic); 1055 lsta = ni->ni_drv_data; 1056 1057 IMPROVE("event callback?"); 1058 1059 /* End mgd_complete_tx. */ 1060 if (lsta->in_mgd) { 1061 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1062 prep_tx_info.success = false; 1063 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); 1064 lsta->in_mgd = false; 1065 } 1066 1067 /* Now start assoc. */ 1068 1069 /* Start mgd_prepare_tx. */ 1070 if (!lsta->in_mgd) { 1071 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1072 prep_tx_info.duration = PREP_TX_INFO_DURATION; 1073 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); 1074 lsta->in_mgd = true; 1075 } 1076 1077 IEEE80211_LOCK(vap->iv_ic); 1078 if (ni != NULL) 1079 ieee80211_free_node(ni); 1080 1081 return (0); 1082 } 1083 1084 static int 1085 lkpi_sta_assoc_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1086 { 1087 struct lkpi_hw *lhw; 1088 struct ieee80211_hw *hw; 1089 struct lkpi_vif *lvif; 1090 struct ieee80211_vif *vif; 1091 struct ieee80211_node *ni; 1092 struct lkpi_sta *lsta; 1093 struct ieee80211_sta *sta; 1094 struct ieee80211_prep_tx_info prep_tx_info; 1095 int error; 1096 1097 lhw = vap->iv_ic->ic_softc; 1098 hw = LHW_TO_HW(lhw); 1099 lvif = VAP_TO_LVIF(vap); 1100 vif = LVIF_TO_VIF(lvif); 1101 1102 /* Keep ni around. */ 1103 ni = ieee80211_ref_node(vap->iv_bss); 1104 1105 IEEE80211_UNLOCK(vap->iv_ic); 1106 lsta = ni->ni_drv_data; 1107 sta = LSTA_TO_STA(lsta); 1108 1109 /* End mgd_complete_tx. */ 1110 if (lsta->in_mgd) { 1111 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1112 prep_tx_info.success = false; 1113 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); 1114 lsta->in_mgd = false; 1115 } 1116 1117 /* Update sta and change state (from AUTH) to NONE. */ 1118 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1119 KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not " 1120 "AUTH: %#x\n", __func__, lsta, lsta->state)); 1121 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_NONE); 1122 if (error != 0) 1123 goto out; 1124 1125 IMPROVE("anything else?"); 1126 1127 out: 1128 IEEE80211_LOCK(vap->iv_ic); 1129 if (ni != NULL) 1130 ieee80211_free_node(ni); 1131 return (error); 1132 } 1133 1134 static int 1135 lkpi_sta_assoc_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1136 { 1137 int error; 1138 1139 error = lkpi_sta_assoc_to_auth(vap, nstate, arg); 1140 if (error == 0) 1141 error = lkpi_sta_auth_to_scan(vap, nstate, arg); 1142 return (error); 1143 } 1144 1145 static int 1146 lkpi_sta_assoc_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1147 { 1148 int error; 1149 1150 error = lkpi_sta_assoc_to_scan(vap, nstate, arg); 1151 if (error == 0) 1152 error = lkpi_sta_scan_to_init(vap, nstate, arg); 1153 return (error); 1154 } 1155 1156 static int 1157 lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1158 { 1159 struct lkpi_hw *lhw; 1160 struct ieee80211_hw *hw; 1161 struct lkpi_vif *lvif; 1162 struct ieee80211_vif *vif; 1163 struct ieee80211_node *ni; 1164 struct lkpi_sta *lsta; 1165 struct ieee80211_sta *sta; 1166 struct ieee80211_prep_tx_info prep_tx_info; 1167 enum ieee80211_bss_changed bss_changed; 1168 int error; 1169 1170 lhw = vap->iv_ic->ic_softc; 1171 hw = LHW_TO_HW(lhw); 1172 lvif = VAP_TO_LVIF(vap); 1173 vif = LVIF_TO_VIF(lvif); 1174 1175 IEEE80211_UNLOCK(vap->iv_ic); 1176 ni = NULL; 1177 1178 IMPROVE("ponder some of this moved to ic_newassoc, scan_assoc_success, " 1179 "and to lesser extend ieee80211_notify_node_join"); 1180 1181 /* Finish assoc. */ 1182 /* Update sta_state (AUTH to ASSOC) and set aid. */ 1183 ni = ieee80211_ref_node(vap->iv_bss); 1184 lsta = ni->ni_drv_data; 1185 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1186 KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not " 1187 "AUTH: %#x\n", __func__, lsta, lsta->state)); 1188 sta = LSTA_TO_STA(lsta); 1189 sta->aid = IEEE80211_NODE_AID(ni); 1190 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_ASSOC); 1191 if (error != 0) 1192 goto out; 1193 1194 IMPROVE("wme / conf_tx [all]"); 1195 1196 /* Update bss info (bss_info_changed) (assoc, aid, ..). */ 1197 bss_changed = 0; 1198 if (!vif->bss_conf.assoc || vif->bss_conf.aid != IEEE80211_NODE_AID(ni)) { 1199 vif->bss_conf.assoc = true; 1200 vif->bss_conf.aid = IEEE80211_NODE_AID(ni); 1201 bss_changed |= BSS_CHANGED_ASSOC; 1202 } 1203 /* We set SSID but this is not BSSID! */ 1204 vif->bss_conf.ssid_len = ni->ni_esslen; 1205 memcpy(vif->bss_conf.ssid, ni->ni_essid, ni->ni_esslen); 1206 if ((vap->iv_flags & IEEE80211_F_SHPREAMBLE) != 1207 vif->bss_conf.use_short_preamble) { 1208 vif->bss_conf.use_short_preamble ^= 1; 1209 /* bss_changed |= BSS_CHANGED_??? */ 1210 } 1211 if ((vap->iv_flags & IEEE80211_F_SHSLOT) != 1212 vif->bss_conf.use_short_slot) { 1213 vif->bss_conf.use_short_slot ^= 1; 1214 /* bss_changed |= BSS_CHANGED_??? */ 1215 } 1216 if ((ni->ni_flags & IEEE80211_NODE_QOS) != 1217 vif->bss_conf.qos) { 1218 vif->bss_conf.qos ^= 1; 1219 bss_changed |= BSS_CHANGED_QOS; 1220 } 1221 if (vif->bss_conf.beacon_int != ni->ni_intval) { 1222 vif->bss_conf.beacon_int = ni->ni_intval; 1223 /* iwlwifi FW bug workaround; iwl_mvm_mac_sta_state. */ 1224 if (vif->bss_conf.beacon_int < 16) 1225 vif->bss_conf.beacon_int = 16; 1226 bss_changed |= BSS_CHANGED_BEACON_INT; 1227 } 1228 if (vif->bss_conf.dtim_period != vap->iv_dtim_period && 1229 vap->iv_dtim_period > 0) { 1230 vif->bss_conf.dtim_period = vap->iv_dtim_period; 1231 bss_changed |= BSS_CHANGED_BEACON_INFO; 1232 } 1233 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); 1234 1235 /* - change_chanctx (if needed) 1236 * - event_callback 1237 */ 1238 1239 /* End mgd_complete_tx. */ 1240 if (lsta->in_mgd) { 1241 memset(&prep_tx_info, 0, sizeof(prep_tx_info)); 1242 prep_tx_info.success = true; 1243 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); 1244 lsta->in_mgd = false; 1245 } 1246 1247 /* 1248 * And then: 1249 * - (more packets)? 1250 * - set_key 1251 * - set_default_unicast_key 1252 * - set_key (?) 1253 * - ipv6_addr_change (?) 1254 */ 1255 /* Prepare_multicast && configure_filter. */ 1256 lhw->update_mc = true; 1257 lkpi_update_mcast_filter(vap->iv_ic, true); 1258 1259 if (!ieee80211_node_is_authorized(ni)) { 1260 IMPROVE("net80211 does not consider node authorized"); 1261 } 1262 1263 /* Update sta_state (ASSOC to AUTHORIZED). */ 1264 ni = ieee80211_ref_node(vap->iv_bss); 1265 lsta = ni->ni_drv_data; 1266 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1267 KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not " 1268 "ASSOC: %#x\n", __func__, lsta, lsta->state)); 1269 sta = LSTA_TO_STA(lsta); 1270 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_AUTHORIZED); 1271 if (error != 0) { 1272 IMPROVE("undo some changes?"); 1273 goto out; 1274 } 1275 1276 /* - drv_config (?) 1277 * - bss_info_changed 1278 * - set_rekey_data (?) 1279 * 1280 * And now we should be passing packets. 1281 */ 1282 IMPROVE("Need that bssid setting, and the keys"); 1283 1284 out: 1285 IEEE80211_LOCK(vap->iv_ic); 1286 if (ni != NULL) 1287 ieee80211_free_node(ni); 1288 return (error); 1289 } 1290 1291 static int 1292 lkpi_sta_auth_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1293 { 1294 int error; 1295 1296 error = lkpi_sta_auth_to_assoc(vap, nstate, arg); 1297 if (error == 0) 1298 error = lkpi_sta_assoc_to_run(vap, nstate, arg); 1299 return (error); 1300 } 1301 1302 static int 1303 lkpi_sta_run_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1304 { 1305 struct lkpi_hw *lhw; 1306 struct ieee80211_hw *hw; 1307 struct lkpi_vif *lvif; 1308 struct ieee80211_vif *vif; 1309 struct ieee80211_node *ni; 1310 struct lkpi_sta *lsta; 1311 struct ieee80211_sta *sta; 1312 int error; 1313 1314 lhw = vap->iv_ic->ic_softc; 1315 hw = LHW_TO_HW(lhw); 1316 lvif = VAP_TO_LVIF(vap); 1317 vif = LVIF_TO_VIF(lvif); 1318 1319 /* Keep ni around. */ 1320 ni = ieee80211_ref_node(vap->iv_bss); 1321 1322 IEEE80211_UNLOCK(vap->iv_ic); 1323 lsta = ni->ni_drv_data; 1324 sta = LSTA_TO_STA(lsta); 1325 1326 /* Adjust sta and change state (from AUTHORIZED) to ASSOC. */ 1327 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1328 KASSERT(lsta->state == IEEE80211_STA_AUTHORIZED, ("%s: lsta %p state not " 1329 "AUTHORIZED: %#x\n", __func__, lsta, lsta->state)); 1330 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_ASSOC); 1331 if (error != 0) 1332 goto out; 1333 1334 /* Update bss info (bss_info_changed) (assoc, aid, ..). */ 1335 lkpi_disassoc(sta, vif, lhw); 1336 1337 /* Update sta_state (ASSOC to AUTH). */ 1338 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); 1339 KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not " 1340 "ASSOC: %#x\n", __func__, lsta, lsta->state)); 1341 sta = LSTA_TO_STA(lsta); 1342 sta->aid = 0; 1343 error = lkpi_80211_mo_sta_state(hw, vif, sta, IEEE80211_STA_AUTH); 1344 if (error != 0) 1345 goto out; 1346 1347 IMPROVE("if ASSOC is final state, prep_tx_info?"); 1348 1349 out: 1350 IEEE80211_LOCK(vap->iv_ic); 1351 if (ni != NULL) 1352 ieee80211_free_node(ni); 1353 return (error); 1354 } 1355 1356 static int 1357 lkpi_sta_run_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1358 { 1359 int error; 1360 1361 error = lkpi_sta_run_to_assoc(vap, nstate, arg); 1362 if (error == 0) 1363 error = lkpi_sta_assoc_to_auth(vap, nstate, arg); 1364 return (error); 1365 } 1366 1367 static int 1368 lkpi_sta_run_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1369 { 1370 int error; 1371 1372 error = lkpi_sta_run_to_auth(vap, nstate, arg); 1373 if (error == 0) 1374 error = lkpi_sta_auth_to_scan(vap, nstate, arg); 1375 return (error); 1376 } 1377 1378 static int 1379 lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1380 { 1381 int error; 1382 1383 error = lkpi_sta_run_to_scan(vap, nstate, arg); 1384 if (error == 0) 1385 error = lkpi_sta_scan_to_init(vap, nstate, arg); 1386 return (error); 1387 } 1388 1389 /* 1390 * The matches the documented state changes in net80211::sta_newstate(). 1391 * XXX (1) without CSA and SLEEP yet, * XXX (2) not all unhandled cases 1392 * there are "invalid" (so there is a room for failure here). 1393 */ 1394 struct fsm_state { 1395 /* INIT, SCAN, AUTH, ASSOC, CAC, RUN, CSA, SLEEP */ 1396 enum ieee80211_state ostate; 1397 enum ieee80211_state nstate; 1398 int (*handler)(struct ieee80211vap *, enum ieee80211_state, int); 1399 } sta_state_fsm[] = { 1400 { IEEE80211_S_INIT, IEEE80211_S_INIT, lkpi_sta_state_do_nada }, 1401 { IEEE80211_S_SCAN, IEEE80211_S_INIT, lkpi_sta_state_do_nada }, /* scan_to_init */ 1402 { IEEE80211_S_AUTH, IEEE80211_S_INIT, lkpi_sta_auth_to_init }, /* not explicitly in sta_newstate() */ 1403 { IEEE80211_S_ASSOC, IEEE80211_S_INIT, lkpi_sta_assoc_to_init }, 1404 { IEEE80211_S_RUN, IEEE80211_S_INIT, lkpi_sta_run_to_init }, 1405 1406 { IEEE80211_S_INIT, IEEE80211_S_SCAN, lkpi_sta_state_do_nada }, 1407 { IEEE80211_S_SCAN, IEEE80211_S_SCAN, lkpi_sta_state_do_nada }, 1408 { IEEE80211_S_AUTH, IEEE80211_S_SCAN, lkpi_sta_auth_to_scan }, 1409 { IEEE80211_S_ASSOC, IEEE80211_S_SCAN, lkpi_sta_assoc_to_scan }, 1410 { IEEE80211_S_RUN, IEEE80211_S_SCAN, lkpi_sta_run_to_scan }, 1411 1412 { IEEE80211_S_INIT, IEEE80211_S_AUTH, lkpi_sta_scan_to_auth }, 1413 { IEEE80211_S_SCAN, IEEE80211_S_AUTH, lkpi_sta_scan_to_auth }, 1414 { IEEE80211_S_AUTH, IEEE80211_S_AUTH, lkpi_sta_a_to_a }, 1415 { IEEE80211_S_ASSOC, IEEE80211_S_AUTH, lkpi_sta_assoc_to_auth }, 1416 { IEEE80211_S_RUN, IEEE80211_S_AUTH, lkpi_sta_run_to_auth }, 1417 1418 { IEEE80211_S_AUTH, IEEE80211_S_ASSOC, lkpi_sta_auth_to_assoc }, 1419 { IEEE80211_S_ASSOC, IEEE80211_S_ASSOC, lkpi_sta_a_to_a }, 1420 { IEEE80211_S_RUN, IEEE80211_S_ASSOC, lkpi_sta_run_to_assoc }, 1421 1422 { IEEE80211_S_AUTH, IEEE80211_S_RUN, lkpi_sta_auth_to_run }, 1423 { IEEE80211_S_ASSOC, IEEE80211_S_RUN, lkpi_sta_assoc_to_run }, 1424 { IEEE80211_S_RUN, IEEE80211_S_RUN, lkpi_sta_state_do_nada }, 1425 1426 /* Dummy at the end without handler. */ 1427 { IEEE80211_S_INIT, IEEE80211_S_INIT, NULL }, 1428 }; 1429 1430 static int 1431 lkpi_iv_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1432 { 1433 struct ieee80211com *ic; 1434 struct lkpi_hw *lhw; 1435 struct lkpi_vif *lvif; 1436 struct ieee80211_vif *vif; 1437 struct fsm_state *s; 1438 enum ieee80211_state ostate; 1439 int error; 1440 1441 ic = vap->iv_ic; 1442 IEEE80211_LOCK_ASSERT(ic); 1443 ostate = vap->iv_state; 1444 1445 if (debug_80211 & D80211_TRACE) 1446 ic_printf(vap->iv_ic, "%s:%d: vap %p nstate %#x arg %#x\n", 1447 __func__, __LINE__, vap, nstate, arg); 1448 1449 if (vap->iv_opmode == IEEE80211_M_STA) { 1450 1451 lhw = ic->ic_softc; 1452 lvif = VAP_TO_LVIF(vap); 1453 vif = LVIF_TO_VIF(lvif); 1454 1455 /* No need to replicate this in most state handlers. */ 1456 if (ostate == IEEE80211_S_SCAN && nstate != IEEE80211_S_SCAN) 1457 lkpi_stop_hw_scan(lhw, vif); 1458 1459 s = sta_state_fsm; 1460 1461 } else { 1462 ic_printf(vap->iv_ic, "%s: only station mode currently supported: " 1463 "cap %p iv_opmode %d\n", __func__, vap, vap->iv_opmode); 1464 return (ENOSYS); 1465 } 1466 1467 error = 0; 1468 for (; s->handler != NULL; s++) { 1469 if (ostate == s->ostate && nstate == s->nstate) { 1470 error = s->handler(vap, nstate, arg); 1471 break; 1472 } 1473 } 1474 IEEE80211_LOCK_ASSERT(vap->iv_ic); 1475 1476 if (s->handler == NULL) { 1477 IMPROVE("thurn this into a KASSERT\n"); 1478 ic_printf(vap->iv_ic, "%s: unsupported state transition " 1479 "%d (%s) -> %d (%s)\n", __func__, 1480 ostate, ieee80211_state_name[ostate], 1481 nstate, ieee80211_state_name[nstate]); 1482 return (ENOSYS); 1483 } 1484 1485 if (error == EALREADY) { 1486 IMPROVE("make this a debug log later"); 1487 ic_printf(vap->iv_ic, "%s: error %d during state transition " 1488 "%d (%s) -> %d (%s): iv_newstate already handled.\n", 1489 __func__, error, 1490 ostate, ieee80211_state_name[ostate], 1491 nstate, ieee80211_state_name[nstate]); 1492 return (0); 1493 } 1494 1495 if (error != 0) { 1496 /* XXX-BZ currently expected so ignore. */ 1497 ic_printf(vap->iv_ic, "%s: error %d during state transition " 1498 "%d (%s) -> %d (%s)\n", __func__, error, 1499 ostate, ieee80211_state_name[ostate], 1500 nstate, ieee80211_state_name[nstate]); 1501 /* return (error); */ 1502 } 1503 1504 if (debug_80211 & D80211_TRACE) 1505 ic_printf(vap->iv_ic, "%s:%d: vap %p nstate %#x arg %#x calling net80211 parent\n", 1506 __func__, __LINE__, vap, nstate, arg); 1507 1508 return (lvif->iv_newstate(vap, nstate, arg)); 1509 } 1510 1511 /* -------------------------------------------------------------------------- */ 1512 1513 static int 1514 lkpi_ic_wme_update(struct ieee80211com *ic) 1515 { 1516 /* This needs queuing and go at the right moment. */ 1517 #ifdef WITH_WME_UPDATE 1518 struct ieee80211vap *vap; 1519 struct lkpi_hw *lhw; 1520 struct ieee80211_hw *hw; 1521 struct lkpi_vif *lvif; 1522 struct ieee80211_vif *vif; 1523 struct chanAccParams chp; 1524 struct wmeParams wmeparr[WME_NUM_AC]; 1525 struct ieee80211_tx_queue_params txqp; 1526 enum ieee80211_bss_changed changed; 1527 int error; 1528 uint16_t ac; 1529 #endif 1530 1531 IMPROVE(); 1532 KASSERT(WME_NUM_AC == IEEE80211_NUM_ACS, ("%s: WME_NUM_AC %d != " 1533 "IEEE80211_NUM_ACS %d\n", __func__, WME_NUM_AC, IEEE80211_NUM_ACS)); 1534 1535 #ifdef WITH_WME_UPDATE 1536 vap = TAILQ_FIRST(&ic->ic_vaps); 1537 if (vap == NULL) 1538 return (0); 1539 1540 /* We should factor this out into per-vap (*wme_update). */ 1541 lhw = ic->ic_softc; 1542 if (lhw->ops->conf_tx == NULL) 1543 return (0); 1544 1545 /* XXX-BZ check amount of hw queues */ 1546 hw = LHW_TO_HW(lhw); 1547 lvif = VAP_TO_LVIF(vap); 1548 vif = LVIF_TO_VIF(lvif); 1549 1550 ieee80211_wme_ic_getparams(ic, &chp); 1551 IEEE80211_LOCK(ic); 1552 for (ac = 0; ac < WME_NUM_AC; ac++) 1553 wmeparr[ac] = chp.cap_wmeParams[ac]; 1554 IEEE80211_UNLOCK(ic); 1555 1556 /* Configure tx queues (conf_tx) & send BSS_CHANGED_QOS. */ 1557 LKPI_80211_LHW_LOCK(lhw); 1558 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 1559 struct wmeParams *wmep; 1560 1561 /* XXX-BZ should keep this in lvif? */ 1562 wmep = &wmeparr[ac]; 1563 bzero(&txqp, sizeof(txqp)); 1564 txqp.cw_min = wmep->wmep_logcwmin; 1565 txqp.cw_max = wmep->wmep_logcwmax; 1566 txqp.txop = wmep->wmep_txopLimit; 1567 txqp.aifs = wmep->wmep_aifsn; 1568 error = lkpi_80211_mo_conf_tx(hw, vif, ac, &txqp); 1569 if (error != 0) 1570 printf("%s: conf_tx ac %u failed %d\n", 1571 __func__, ac, error); 1572 } 1573 LKPI_80211_LHW_UNLOCK(lhw); 1574 changed = BSS_CHANGED_QOS; 1575 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed); 1576 #endif 1577 1578 return (0); 1579 } 1580 1581 static struct ieee80211vap * 1582 lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], 1583 int unit, enum ieee80211_opmode opmode, int flags, 1584 const uint8_t bssid[IEEE80211_ADDR_LEN], 1585 const uint8_t mac[IEEE80211_ADDR_LEN]) 1586 { 1587 struct lkpi_hw *lhw; 1588 struct ieee80211_hw *hw; 1589 struct lkpi_vif *lvif; 1590 struct ieee80211vap *vap; 1591 struct ieee80211_vif *vif; 1592 enum ieee80211_bss_changed changed; 1593 size_t len; 1594 int error; 1595 1596 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* 1 so far. Add <n> once this works. */ 1597 return (NULL); 1598 1599 lhw = ic->ic_softc; 1600 hw = LHW_TO_HW(lhw); 1601 1602 len = sizeof(*lvif); 1603 len += hw->vif_data_size; /* vif->drv_priv */ 1604 1605 lvif = malloc(len, M_80211_VAP, M_WAITOK | M_ZERO); 1606 mtx_init(&lvif->mtx, "lvif", NULL, MTX_DEF); 1607 TAILQ_INIT(&lvif->lsta_head); 1608 vap = LVIF_TO_VAP(lvif); 1609 1610 vif = LVIF_TO_VIF(lvif); 1611 memcpy(vif->addr, mac, IEEE80211_ADDR_LEN); 1612 vif->p2p = false; 1613 vif->probe_req_reg = false; 1614 vif->type = lkpi_opmode_to_vif_type(opmode); 1615 lvif->wdev.iftype = vif->type; 1616 /* Need to fill in other fields as well. */ 1617 IMPROVE(); 1618 1619 /* XXX-BZ hardcoded for now! */ 1620 #if 1 1621 vif->chanctx_conf = NULL; 1622 vif->bss_conf.idle = true; 1623 vif->bss_conf.ps = false; 1624 vif->bss_conf.chandef.width = NL80211_CHAN_WIDTH_20_NOHT; 1625 vif->bss_conf.use_short_preamble = false; /* vap->iv_flags IEEE80211_F_SHPREAMBLE */ 1626 vif->bss_conf.use_short_slot = false; /* vap->iv_flags IEEE80211_F_SHSLOT */ 1627 vif->bss_conf.qos = false; 1628 vif->bss_conf.use_cts_prot = false; /* vap->iv_protmode */ 1629 vif->bss_conf.ht_operation_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONE; 1630 vif->bss_conf.assoc = false; 1631 vif->bss_conf.aid = 0; 1632 #endif 1633 #if 0 1634 vif->bss_conf.dtim_period = 0; /* IEEE80211_DTIM_DEFAULT ; must stay 0. */ 1635 IEEE80211_ADDR_COPY(vif->bss_conf.bssid, bssid); 1636 vif->bss_conf.beacon_int = ic->ic_bintval; 1637 /* iwlwifi bug. */ 1638 if (vif->bss_conf.beacon_int < 16) 1639 vif->bss_conf.beacon_int = 16; 1640 #endif 1641 IMPROVE(); 1642 1643 error = lkpi_80211_mo_start(hw); 1644 if (error != 0) { 1645 printf("%s: failed to start hw: %d\n", __func__, error); 1646 mtx_destroy(&lvif->mtx); 1647 free(lvif, M_80211_VAP); 1648 return (NULL); 1649 } 1650 1651 error = lkpi_80211_mo_add_interface(hw, vif); 1652 if (error != 0) { 1653 IMPROVE(); /* XXX-BZ mo_stop()? */ 1654 printf("%s: failed to add interface: %d\n", __func__, error); 1655 mtx_destroy(&lvif->mtx); 1656 free(lvif, M_80211_VAP); 1657 return (NULL); 1658 } 1659 1660 LKPI_80211_LHW_LOCK(lhw); 1661 TAILQ_INSERT_TAIL(&lhw->lvif_head, lvif, lvif_entry); 1662 LKPI_80211_LHW_UNLOCK(lhw); 1663 1664 /* Set bss_info. */ 1665 changed = 0; 1666 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed); 1667 1668 /* conf_tx setup; default WME? */ 1669 1670 /* Force MC init. */ 1671 lkpi_update_mcast_filter(ic, true); 1672 1673 IMPROVE(); 1674 1675 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); 1676 1677 /* Override with LinuxKPI method so we can drive mac80211/cfg80211. */ 1678 lvif->iv_newstate = vap->iv_newstate; 1679 vap->iv_newstate = lkpi_iv_newstate; 1680 1681 /* Key management. */ 1682 if (lhw->ops->set_key != NULL) { 1683 #ifdef TRY_HW_CRYPTO 1684 vap->iv_key_set = lkpi_iv_key_set; 1685 vap->iv_key_delete = lkpi_iv_key_delete; 1686 #endif 1687 } 1688 1689 ieee80211_ratectl_init(vap); 1690 1691 /* Complete setup. */ 1692 ieee80211_vap_attach(vap, ieee80211_media_change, 1693 ieee80211_media_status, mac); 1694 1695 if (hw->max_listen_interval == 0) 1696 hw->max_listen_interval = 7 * (ic->ic_lintval / ic->ic_bintval); 1697 hw->conf.listen_interval = hw->max_listen_interval; 1698 ic->ic_set_channel(ic); 1699 1700 /* XXX-BZ do we need to be able to update these? */ 1701 hw->wiphy->frag_threshold = vap->iv_fragthreshold; 1702 lkpi_80211_mo_set_frag_threshold(hw, vap->iv_fragthreshold); 1703 hw->wiphy->rts_threshold = vap->iv_rtsthreshold; 1704 lkpi_80211_mo_set_rts_threshold(hw, vap->iv_rtsthreshold); 1705 /* any others? */ 1706 IMPROVE(); 1707 1708 return (vap); 1709 } 1710 1711 static void 1712 lkpi_ic_vap_delete(struct ieee80211vap *vap) 1713 { 1714 struct ieee80211com *ic; 1715 struct lkpi_hw *lhw; 1716 struct ieee80211_hw *hw; 1717 struct lkpi_vif *lvif; 1718 struct ieee80211_vif *vif; 1719 1720 lvif = VAP_TO_LVIF(vap); 1721 vif = LVIF_TO_VIF(lvif); 1722 ic = vap->iv_ic; 1723 lhw = ic->ic_softc; 1724 hw = LHW_TO_HW(lhw); 1725 1726 LKPI_80211_LHW_LOCK(lhw); 1727 TAILQ_REMOVE(&lhw->lvif_head, lvif, lvif_entry); 1728 LKPI_80211_LHW_UNLOCK(lhw); 1729 lkpi_80211_mo_remove_interface(hw, vif); 1730 1731 ieee80211_ratectl_deinit(vap); 1732 ieee80211_vap_detach(vap); 1733 mtx_destroy(&lvif->mtx); 1734 free(lvif, M_80211_VAP); 1735 } 1736 1737 static void 1738 lkpi_ic_update_mcast(struct ieee80211com *ic) 1739 { 1740 1741 lkpi_update_mcast_filter(ic, false); 1742 TRACEOK(); 1743 } 1744 1745 static void 1746 lkpi_ic_update_promisc(struct ieee80211com *ic) 1747 { 1748 1749 UNIMPLEMENTED; 1750 } 1751 1752 static void 1753 lkpi_ic_update_chw(struct ieee80211com *ic) 1754 { 1755 1756 UNIMPLEMENTED; 1757 } 1758 1759 /* Start / stop device. */ 1760 static void 1761 lkpi_ic_parent(struct ieee80211com *ic) 1762 { 1763 struct lkpi_hw *lhw; 1764 struct ieee80211_hw *hw; 1765 int error; 1766 bool start_all; 1767 1768 IMPROVE(); 1769 1770 lhw = ic->ic_softc; 1771 hw = LHW_TO_HW(lhw); 1772 start_all = false; 1773 1774 if (ic->ic_nrunning > 0) { 1775 error = lkpi_80211_mo_start(hw); 1776 if (error == 0) 1777 start_all = true; 1778 } else { 1779 lkpi_80211_mo_stop(hw); 1780 } 1781 1782 if (start_all) 1783 ieee80211_start_all(ic); 1784 } 1785 1786 bool 1787 linuxkpi_ieee80211_is_ie_id_in_ie_buf(const u8 ie, const u8 *ie_ids, 1788 size_t ie_ids_len) 1789 { 1790 int i; 1791 1792 for (i = 0; i < ie_ids_len; i++) { 1793 if (ie == *ie_ids) 1794 return (true); 1795 } 1796 1797 return (false); 1798 } 1799 1800 /* Return true if skipped; false if error. */ 1801 bool 1802 linuxkpi_ieee80211_ie_advance(size_t *xp, const u8 *ies, size_t ies_len) 1803 { 1804 size_t x; 1805 uint8_t l; 1806 1807 x = *xp; 1808 1809 KASSERT(x < ies_len, ("%s: x %zu ies_len %zu ies %p\n", 1810 __func__, x, ies_len, ies)); 1811 l = ies[x + 1]; 1812 x += 2 + l; 1813 1814 if (x > ies_len) 1815 return (false); 1816 1817 *xp = x; 1818 return (true); 1819 } 1820 1821 static int 1822 lkpi_ieee80211_probereq_ie_alloc(struct ieee80211vap *vap, 1823 struct ieee80211com *ic, struct ieee80211_scan_ies *scan_ies, 1824 const uint8_t *ssid, size_t ssidlen) 1825 { 1826 1827 return (ieee80211_probereq_ie(vap, ic, 1828 &scan_ies->common_ies, &scan_ies->common_ie_len, 1829 ssid, ssidlen, true)); 1830 } 1831 1832 static void 1833 lkpi_ic_scan_start(struct ieee80211com *ic) 1834 { 1835 struct lkpi_hw *lhw; 1836 struct ieee80211_hw *hw; 1837 struct lkpi_vif *lvif; 1838 struct ieee80211_vif *vif; 1839 struct ieee80211_scan_state *ss; 1840 struct ieee80211vap *vap; 1841 int error; 1842 1843 lhw = ic->ic_softc; 1844 if ((lhw->scan_flags & LKPI_SCAN_RUNNING) != 0) { 1845 /* A scan is still running. */ 1846 return; 1847 } 1848 1849 ss = ic->ic_scan; 1850 vap = ss->ss_vap; 1851 if (vap->iv_state != IEEE80211_S_SCAN) { 1852 /* Do not start a scan for now. */ 1853 return; 1854 } 1855 1856 hw = LHW_TO_HW(lhw); 1857 if ((ic->ic_flags_ext & IEEE80211_FEXT_SCAN_OFFLOAD) == 0) { 1858 1859 lvif = VAP_TO_LVIF(vap); 1860 vif = LVIF_TO_VIF(lvif); 1861 lkpi_80211_mo_sw_scan_start(hw, vif, vif->addr); 1862 /* net80211::scan_start() handled PS for us. */ 1863 IMPROVE(); 1864 /* XXX Also means it is too late to flush queues? 1865 * need to check iv_sta_ps or overload? */ 1866 /* XXX want to adjust ss end time/ maxdwell? */ 1867 1868 } else { 1869 struct ieee80211_channel *c; 1870 struct ieee80211_scan_request *hw_req; 1871 struct linuxkpi_ieee80211_channel *lc, **cpp; 1872 struct cfg80211_ssid *ssids; 1873 struct cfg80211_scan_6ghz_params *s6gp; 1874 size_t chan_len, nchan, ssids_len, s6ghzlen; 1875 int i; 1876 1877 ssids_len = ss->ss_nssid * sizeof(*ssids);; 1878 s6ghzlen = 0 * (sizeof(*s6gp)); /* XXX-BZ */ 1879 1880 nchan = 0; 1881 for (i = ss->ss_next; i < ss->ss_last; i++) 1882 nchan++; 1883 chan_len = nchan * (sizeof(lc) + sizeof(*lc)); 1884 1885 KASSERT(lhw->hw_req == NULL, ("%s: ic %p lhw %p hw_req %p " 1886 "!= NULL\n", __func__, ic, lhw, lhw->hw_req)); 1887 lhw->hw_req = hw_req = malloc(sizeof(*hw_req) + ssids_len + 1888 s6ghzlen + chan_len, M_LKPI80211, M_WAITOK | M_ZERO); 1889 1890 error = lkpi_ieee80211_probereq_ie_alloc(vap, ic, 1891 &hw_req->ies, NULL, -1); 1892 if (error != 0) 1893 ic_printf(ic, "ERROR: %s: probereq_ie returned %d\n", 1894 __func__, error); 1895 1896 hw_req->req.flags = 0; /* XXX ??? */ 1897 /* hw_req->req.wdev */ 1898 hw_req->req.wiphy = hw->wiphy; 1899 hw_req->req.no_cck = false; /* XXX */ 1900 #if 0 1901 /* This seems to pessimise default scanning behaviour. */ 1902 hw_req->req.duration_mandatory = TICKS_2_USEC(ss->ss_mindwell); 1903 hw_req->req.duration = TICKS_2_USEC(ss->ss_maxdwell); 1904 #endif 1905 #ifdef __notyet__ 1906 hw_req->req.flags |= NL80211_SCAN_FLAG_RANDOM_ADDR; 1907 memcpy(hw_req->req.mac_addr, xxx, IEEE80211_ADDR_LEN); 1908 memset(hw_req->req.mac_addr_mask, 0xxx, IEEE80211_ADDR_LEN); 1909 #endif 1910 #if 0 1911 hw_req->req.ie_len = ; 1912 hw_req->req.ie = ; 1913 #endif 1914 1915 hw_req->req.n_channels = nchan; 1916 cpp = (struct linuxkpi_ieee80211_channel **)(hw_req + 1); 1917 lc = (struct linuxkpi_ieee80211_channel *)(cpp + nchan); 1918 for (i = 0; i < nchan; i++) { 1919 *(cpp + i) = 1920 (struct linuxkpi_ieee80211_channel *)(lc + i); 1921 } 1922 for (i = 0; i < nchan; i++) { 1923 c = ss->ss_chans[ss->ss_next + i]; 1924 1925 lc->hw_value = c->ic_ieee; 1926 lc->center_freq = c->ic_freq; 1927 /* lc->flags */ 1928 lc->band = lkpi_net80211_chan_to_nl80211_band(c); 1929 lc->max_power = c->ic_maxpower; 1930 /* lc-> ... */ 1931 lc++; 1932 } 1933 1934 hw_req->req.n_ssids = ss->ss_nssid; 1935 if (hw_req->req.n_ssids > 0) { 1936 ssids = (struct cfg80211_ssid *)lc; 1937 hw_req->req.ssids = ssids; 1938 for (i = 0; i < ss->ss_nssid; i++) { 1939 ssids->ssid_len = ss->ss_ssid[i].len; 1940 memcpy(ssids->ssid, ss->ss_ssid[i].ssid, 1941 ss->ss_ssid[i].len); 1942 ssids++; 1943 } 1944 s6gp = (struct cfg80211_scan_6ghz_params *)ssids; 1945 } else { 1946 s6gp = (struct cfg80211_scan_6ghz_params *)lc; 1947 } 1948 1949 /* 6GHz one day. */ 1950 hw_req->req.n_6ghz_params = 0; 1951 hw_req->req.scan_6ghz_params = NULL; 1952 hw_req->req.scan_6ghz = false; /* Weird boolean; not what you think. */ 1953 /* s6gp->... */ 1954 1955 lvif = VAP_TO_LVIF(vap); 1956 vif = LVIF_TO_VIF(lvif); 1957 error = lkpi_80211_mo_hw_scan(hw, vif, hw_req); 1958 if (error != 0) { 1959 ic_printf(ic, "ERROR: %s: hw_scan returned %d\n", 1960 __func__, error); 1961 ieee80211_cancel_scan(vap); 1962 free(hw_req->ies.common_ies, M_80211_VAP); 1963 free(hw_req, M_LKPI80211); 1964 lhw->hw_req = NULL; 1965 } 1966 } 1967 } 1968 1969 static void 1970 lkpi_ic_scan_end(struct ieee80211com *ic) 1971 { 1972 struct lkpi_hw *lhw; 1973 1974 lhw = ic->ic_softc; 1975 if ((lhw->scan_flags & LKPI_SCAN_RUNNING) == 0) { 1976 return; 1977 } 1978 1979 if (ic->ic_flags_ext & IEEE80211_FEXT_SCAN_OFFLOAD) { 1980 /* Nothing to do. */ 1981 } else { 1982 struct ieee80211_hw *hw; 1983 struct lkpi_vif *lvif; 1984 struct ieee80211_vif *vif; 1985 struct ieee80211_scan_state *ss; 1986 struct ieee80211vap *vap; 1987 1988 hw = LHW_TO_HW(lhw); 1989 ss = ic->ic_scan; 1990 vap = ss->ss_vap; 1991 lvif = VAP_TO_LVIF(vap); 1992 vif = LVIF_TO_VIF(lvif); 1993 lkpi_80211_mo_sw_scan_complete(hw, vif); 1994 1995 /* Send PS to stop buffering if n80211 does not for us? */ 1996 } 1997 } 1998 1999 static void 2000 lkpi_ic_scan_curchan_nada(struct ieee80211_scan_state *ss __unused, 2001 unsigned long maxdwell __unused) 2002 { 2003 } 2004 2005 static void 2006 lkpi_ic_set_channel(struct ieee80211com *ic) 2007 { 2008 struct lkpi_hw *lhw; 2009 struct ieee80211_hw *hw; 2010 int error; 2011 2012 lhw = ic->ic_softc; 2013 #ifdef __no_longer__ 2014 /* For now only be concerned if scanning. */ 2015 if ((lhw->scan_flags & LKPI_SCAN_RUNNING) == 0) { 2016 IMPROVE(); 2017 return; 2018 } 2019 #endif 2020 2021 if (ic->ic_flags_ext & IEEE80211_FEXT_SCAN_OFFLOAD) { 2022 /* 2023 * AP scanning is taken care of by firmware, so only switch 2024 * channels in monitor mode (maybe, maybe not; to be 2025 * investigated at the right time). 2026 */ 2027 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 2028 UNIMPLEMENTED; 2029 } 2030 } else { 2031 struct ieee80211_channel *c = ic->ic_curchan; 2032 struct linuxkpi_ieee80211_channel *chan; 2033 struct cfg80211_chan_def chandef; 2034 2035 if (c == NULL || c == IEEE80211_CHAN_ANYC || 2036 lhw->ops->config == NULL) { 2037 ic_printf(ic, "%s: c %p ops->config %p\n", __func__, 2038 c, lhw->ops->config); 2039 return; 2040 } 2041 2042 chan = lkpi_find_lkpi80211_chan(lhw, c); 2043 if (chan == NULL) { 2044 ic_printf(ic, "%s: c %p chan %p\n", __func__, 2045 c, chan); 2046 return; 2047 } 2048 2049 memset(&chandef, 0, sizeof(chandef)); 2050 chandef.chan = chan; 2051 chandef.width = NL80211_CHAN_WIDTH_20_NOHT; 2052 chandef.center_freq1 = chandef.chan->center_freq; 2053 2054 /* XXX max power for scanning? */ 2055 IMPROVE(); 2056 2057 hw = LHW_TO_HW(lhw); 2058 hw->conf.chandef = chandef; 2059 2060 hw->conf.flags &= ~IEEE80211_CONF_IDLE; 2061 error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_IDLE); 2062 if (error != 0 && error != EOPNOTSUPP) 2063 ic_printf(ic, "ERROR: %s: config %#0x returned %d\n", 2064 __func__, IEEE80211_CONF_CHANGE_IDLE, error); 2065 2066 error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_CHANNEL); 2067 if (error != 0 && error != EOPNOTSUPP) { 2068 ic_printf(ic, "ERROR: %s: config %#0x returned %d\n", 2069 __func__, IEEE80211_CONF_CHANGE_CHANNEL, error); 2070 /* XXX should we unroll to the previous chandef? */ 2071 IMPROVE(); 2072 } else { 2073 /* Update radiotap channels as well. */ 2074 lhw->rtap_tx.wt_chan_freq = htole16(c->ic_freq); 2075 lhw->rtap_tx.wt_chan_flags = htole16(c->ic_flags); 2076 lhw->rtap_rx.wr_chan_freq = htole16(c->ic_freq); 2077 lhw->rtap_rx.wr_chan_flags = htole16(c->ic_flags); 2078 } 2079 2080 /* Currently PS is hard coded off! Not sure it belongs here. */ 2081 IMPROVE(); 2082 if (ieee80211_hw_check(hw, SUPPORTS_PS) && 2083 (hw->conf.flags & IEEE80211_CONF_PS) != 0) { 2084 hw->conf.flags &= ~IEEE80211_CONF_PS; 2085 error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_PS); 2086 if (error != 0 && error != EOPNOTSUPP) 2087 ic_printf(ic, "ERROR: %s: config %#0x returned " 2088 "%d\n", __func__, IEEE80211_CONF_CHANGE_PS, 2089 error); 2090 } 2091 } 2092 } 2093 2094 static struct ieee80211_node * 2095 lkpi_ic_node_alloc(struct ieee80211vap *vap, 2096 const uint8_t mac[IEEE80211_ADDR_LEN]) 2097 { 2098 struct ieee80211com *ic; 2099 struct lkpi_hw *lhw; 2100 struct ieee80211_hw *hw; 2101 struct lkpi_sta *lsta; 2102 struct ieee80211_sta *sta; 2103 struct lkpi_vif *lvif; 2104 struct ieee80211_vif *vif; 2105 struct ieee80211_node *ni; 2106 int tid; 2107 2108 ic = vap->iv_ic; 2109 lhw = ic->ic_softc; 2110 2111 /* We keep allocations de-coupled so we can deal with the two worlds. */ 2112 if (lhw->ic_node_alloc != NULL) { 2113 ni = lhw->ic_node_alloc(vap, mac); 2114 if (ni == NULL) 2115 return (NULL); 2116 } 2117 2118 hw = LHW_TO_HW(lhw); 2119 lsta = malloc(sizeof(*lsta) + hw->sta_data_size, M_LKPI80211, 2120 M_NOWAIT | M_ZERO); 2121 if (lsta == NULL) { 2122 if (lhw->ic_node_free != NULL) 2123 lhw->ic_node_free(ni); 2124 return (NULL); 2125 } 2126 2127 lsta->added_to_drv = false; 2128 lsta->state = IEEE80211_STA_NOTEXIST; 2129 #if 0 2130 /* 2131 * This needs to be done in node_init() as ieee80211_alloc_node() 2132 * will initialise the refcount after us. 2133 */ 2134 lsta->ni = ieee80211_ref_node(ni); 2135 #endif 2136 /* The back-pointer "drv_data" to net80211_node let's us get lsta. */ 2137 ni->ni_drv_data = lsta; 2138 2139 lvif = VAP_TO_LVIF(vap); 2140 vif = LVIF_TO_VIF(lvif); 2141 sta = LSTA_TO_STA(lsta); 2142 2143 IEEE80211_ADDR_COPY(sta->addr, mac); 2144 for (tid = 0; tid < nitems(sta->txq); tid++) { 2145 struct lkpi_txq *ltxq; 2146 2147 /* 2148 * We are neither limiting ourselves to hw.queues here, 2149 * nor do we check if driver wants IEEE80211_NUM_TIDS queue. 2150 */ 2151 2152 ltxq = malloc(sizeof(*ltxq) + hw->txq_data_size, 2153 M_LKPI80211, M_NOWAIT | M_ZERO); 2154 if (ltxq == NULL) 2155 goto cleanup; 2156 ltxq->seen_dequeue = false; 2157 skb_queue_head_init(<xq->skbq); 2158 /* iwlwifi//mvm/sta.c::tid_to_mac80211_ac[] */ 2159 if (tid == IEEE80211_NUM_TIDS) { 2160 IMPROVE(); 2161 ltxq->txq.ac = IEEE80211_AC_VO; 2162 } else { 2163 ltxq->txq.ac = tid_to_mac80211_ac[tid & 7]; 2164 } 2165 ltxq->txq.tid = tid; 2166 ltxq->txq.sta = sta; 2167 ltxq->txq.vif = vif; 2168 sta->txq[tid] = <xq->txq; 2169 } 2170 2171 /* Deferred TX path. */ 2172 mtx_init(&lsta->txq_mtx, "lsta_txq", NULL, MTX_DEF); 2173 TASK_INIT(&lsta->txq_task, 0, lkpi_80211_txq_task, lsta); 2174 mbufq_init(&lsta->txq, IFQ_MAXLEN); 2175 2176 return (ni); 2177 2178 cleanup: 2179 for (; tid >= 0; tid--) 2180 free(sta->txq[tid], M_LKPI80211); 2181 free(lsta, M_LKPI80211); 2182 if (lhw->ic_node_free != NULL) 2183 lhw->ic_node_free(ni); 2184 return (NULL); 2185 } 2186 2187 static int 2188 lkpi_ic_node_init(struct ieee80211_node *ni) 2189 { 2190 struct ieee80211com *ic; 2191 struct lkpi_hw *lhw; 2192 struct lkpi_sta *lsta; 2193 struct lkpi_vif *lvif; 2194 int error; 2195 2196 ic = ni->ni_ic; 2197 lhw = ic->ic_softc; 2198 2199 if (lhw->ic_node_init != NULL) { 2200 error = lhw->ic_node_init(ni); 2201 if (error != 0) 2202 return (error); 2203 } 2204 2205 lvif = VAP_TO_LVIF(ni->ni_vap); 2206 2207 lsta = ni->ni_drv_data; 2208 2209 /* Now take the reference before linking it to the table. */ 2210 lsta->ni = ieee80211_ref_node(ni); 2211 2212 LKPI_80211_LVIF_LOCK(lvif); 2213 TAILQ_INSERT_TAIL(&lvif->lsta_head, lsta, lsta_entry); 2214 LKPI_80211_LVIF_UNLOCK(lvif); 2215 2216 /* XXX-BZ Sync other state over. */ 2217 IMPROVE(); 2218 2219 return (0); 2220 } 2221 2222 static void 2223 lkpi_ic_node_cleanup(struct ieee80211_node *ni) 2224 { 2225 struct ieee80211com *ic; 2226 struct lkpi_hw *lhw; 2227 2228 ic = ni->ni_ic; 2229 lhw = ic->ic_softc; 2230 2231 /* XXX-BZ remove from driver, ... */ 2232 IMPROVE(); 2233 2234 if (lhw->ic_node_cleanup != NULL) 2235 lhw->ic_node_cleanup(ni); 2236 } 2237 2238 static void 2239 lkpi_ic_node_free(struct ieee80211_node *ni) 2240 { 2241 struct ieee80211com *ic; 2242 struct lkpi_hw *lhw; 2243 struct lkpi_sta *lsta; 2244 2245 ic = ni->ni_ic; 2246 lhw = ic->ic_softc; 2247 lsta = ni->ni_drv_data; 2248 2249 /* XXX-BZ free resources, ... */ 2250 IMPROVE(); 2251 2252 /* Flush mbufq (make sure to release ni refs!). */ 2253 #ifdef __notyet__ 2254 KASSERT(mbufq_len(&lsta->txq) == 0, ("%s: lsta %p has txq len %d != 0\n", 2255 __func__, lsta, mbufq_len(&lsta->txq))); 2256 #endif 2257 /* Drain taskq. */ 2258 2259 /* Drain sta->txq[] */ 2260 mtx_destroy(&lsta->txq_mtx); 2261 2262 /* Remove lsta if added_to_drv. */ 2263 /* Remove lsta from vif */ 2264 2265 /* remove ref from lsta node... */ 2266 2267 if (lhw->ic_node_free != NULL) 2268 lhw->ic_node_free(ni); 2269 2270 /* Free lsta. */ 2271 } 2272 2273 static int 2274 lkpi_ic_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2275 const struct ieee80211_bpf_params *params __unused) 2276 { 2277 struct lkpi_sta *lsta; 2278 2279 lsta = ni->ni_drv_data; 2280 2281 /* Queue the packet and enqueue the task to handle it. */ 2282 LKPI_80211_LSTA_LOCK(lsta); 2283 mbufq_enqueue(&lsta->txq, m); 2284 LKPI_80211_LSTA_UNLOCK(lsta); 2285 2286 if (debug_80211 & D80211_TRACE_TX) 2287 printf("%s:%d lsta %p ni %p %6D mbuf_qlen %d\n", 2288 __func__, __LINE__, lsta, ni, ni->ni_macaddr, ":", 2289 mbufq_len(&lsta->txq)); 2290 2291 taskqueue_enqueue(taskqueue_thread, &lsta->txq_task); 2292 return (0); 2293 } 2294 2295 static void 2296 lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m) 2297 { 2298 struct ieee80211_node *ni; 2299 struct ieee80211_frame *wh; 2300 struct ieee80211_key *k; 2301 struct sk_buff *skb; 2302 struct ieee80211com *ic; 2303 struct lkpi_hw *lhw; 2304 struct ieee80211_hw *hw; 2305 struct lkpi_vif *lvif; 2306 struct ieee80211_vif *vif; 2307 struct ieee80211_channel *c; 2308 struct ieee80211_tx_control control; 2309 struct ieee80211_tx_info *info; 2310 struct ieee80211_sta *sta; 2311 void *buf; 2312 int ac; 2313 2314 M_ASSERTPKTHDR(m); 2315 #ifdef LINUXKPI_DEBUG_80211 2316 if (debug_80211 & D80211_TRACE_TX_DUMP) 2317 hexdump(mtod(m, const void *), m->m_len, "RAW TX (plain) ", 0); 2318 #endif 2319 2320 ni = lsta->ni; 2321 #ifndef TRY_HW_CRYPTO 2322 /* Encrypt the frame if need be; XXX-BZ info->control.hw_key. */ 2323 wh = mtod(m, struct ieee80211_frame *); 2324 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 2325 /* Retrieve key for TX && do software encryption. */ 2326 k = ieee80211_crypto_encap(ni, m); 2327 if (k == NULL) { 2328 ieee80211_free_node(ni); 2329 m_freem(m); 2330 return; 2331 } 2332 } 2333 #endif 2334 2335 ic = ni->ni_ic; 2336 lhw = ic->ic_softc; 2337 hw = LHW_TO_HW(lhw); 2338 c = ni->ni_chan; 2339 2340 if (ieee80211_radiotap_active_vap(ni->ni_vap)) { 2341 struct lkpi_radiotap_tx_hdr *rtap; 2342 2343 rtap = &lhw->rtap_tx; 2344 rtap->wt_flags = 0; 2345 if (k != NULL) 2346 rtap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; 2347 if (m->m_flags & M_FRAG) 2348 rtap->wt_flags |= IEEE80211_RADIOTAP_F_FRAG; 2349 IMPROVE(); 2350 rtap->wt_rate = 0; 2351 if (c != NULL && c != IEEE80211_CHAN_ANYC) { 2352 rtap->wt_chan_freq = htole16(c->ic_freq); 2353 rtap->wt_chan_flags = htole16(c->ic_flags); 2354 } 2355 2356 ieee80211_radiotap_tx(ni->ni_vap, m); 2357 } 2358 2359 /* 2360 * net80211 should handle hw->extra_tx_headroom. 2361 * Though for as long as we are copying we don't mind. 2362 */ 2363 skb = dev_alloc_skb(hw->extra_tx_headroom + m->m_pkthdr.len); 2364 if (skb == NULL) { 2365 printf("XXX ERROR %s: skb alloc failed\n", __func__); 2366 ieee80211_free_node(ni); 2367 m_freem(m); 2368 return; 2369 } 2370 skb_reserve(skb, hw->extra_tx_headroom); 2371 2372 /* XXX-BZ we need a SKB version understanding mbuf. */ 2373 /* Save the mbuf for ieee80211_tx_complete(). */ 2374 skb->m_free_func = lkpi_ieee80211_free_skb_mbuf; 2375 skb->m = m; 2376 #if 0 2377 skb_put_data(skb, m->m_data, m->m_pkthdr.len); 2378 #else 2379 buf = skb_put(skb, m->m_pkthdr.len); 2380 m_copydata(m, 0, m->m_pkthdr.len, buf); 2381 #endif 2382 /* Save the ni. */ 2383 m->m_pkthdr.PH_loc.ptr = ni; 2384 2385 lvif = VAP_TO_LVIF(ni->ni_vap); 2386 vif = LVIF_TO_VIF(lvif); 2387 2388 /* XXX-BZ review this at some point [4] vs. [8] vs. [16](TID). */ 2389 ac = M_WME_GETAC(m); 2390 skb->priority = WME_AC_TO_TID(ac); 2391 ac = lkpi_ac_net_to_l80211(ac); 2392 skb_set_queue_mapping(skb, ac); 2393 2394 info = IEEE80211_SKB_CB(skb); 2395 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; 2396 /* Slight delay; probably only happens on scanning so fine? */ 2397 if (c == NULL || c == IEEE80211_CHAN_ANYC) 2398 c = ic->ic_curchan; 2399 info->band = lkpi_net80211_chan_to_nl80211_band(c); 2400 info->hw_queue = ac; /* XXX-BZ is this correct? */ 2401 if (m->m_flags & M_EAPOL) 2402 info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO; 2403 info->control.vif = vif; 2404 /* XXX-BZ info->control.rates */ 2405 2406 lsta = lkpi_find_lsta_by_ni(lvif, ni); 2407 if (lsta != NULL) { 2408 sta = LSTA_TO_STA(lsta); 2409 #ifdef TRY_HW_CRYPTO 2410 info->control.hw_key = lsta->kc; 2411 #endif 2412 } else { 2413 sta = NULL; 2414 } 2415 2416 IMPROVE(); 2417 2418 if (sta != NULL) { 2419 struct lkpi_txq *ltxq; 2420 2421 ltxq = TXQ_TO_LTXQ(sta->txq[ac]); /* XXX-BZ re-check */ 2422 /* 2423 * We currently do not use queues but do direct TX. 2424 * The exception to the rule is initial packets, as we cannot 2425 * TX until queues are allocated (at least for iwlwifi). 2426 * So we wake_tx_queue in newstate and register any dequeue 2427 * calls. In the time until then we queue packets and 2428 * let the driver deal with them. 2429 */ 2430 if (!ltxq->seen_dequeue) { 2431 2432 /* Prevent an ordering problem, likely other issues. */ 2433 while (!skb_queue_empty(<xq->skbq)) { 2434 struct sk_buff *skb2; 2435 2436 skb2 = skb_dequeue(<xq->skbq); 2437 if (skb2 != NULL) { 2438 memset(&control, 0, sizeof(control)); 2439 control.sta = sta; 2440 lkpi_80211_mo_tx(hw, &control, skb2); 2441 } 2442 } 2443 goto ops_tx; 2444 } 2445 if (0 && ltxq->seen_dequeue && skb_queue_empty(<xq->skbq)) 2446 goto ops_tx; 2447 2448 skb_queue_tail(<xq->skbq, skb); 2449 if (debug_80211 & D80211_TRACE_TX) 2450 printf("%s:%d lsta %p sta %p ni %p %6D skb %p lxtq %p " 2451 "qlen %u WAKE_TX_Q ac %d prio %u qmap %u\n", 2452 __func__, __LINE__, lsta, sta, ni, 2453 ni->ni_macaddr, ":", skb, ltxq, 2454 skb_queue_len(<xq->skbq), ac, 2455 skb->priority, skb->qmap); 2456 lkpi_80211_mo_wake_tx_queue(hw, sta->txq[ac]); /* XXX-BZ */ 2457 return; 2458 } 2459 2460 ops_tx: 2461 if (debug_80211 & D80211_TRACE_TX) 2462 printf("%s:%d lsta %p sta %p ni %p %6D skb %p TX ac %d prio %u qmap %u\n", 2463 __func__, __LINE__, lsta, sta, ni, ni->ni_macaddr, ":", 2464 skb, ac, skb->priority, skb->qmap); 2465 memset(&control, 0, sizeof(control)); 2466 control.sta = sta; 2467 2468 lkpi_80211_mo_tx(hw, &control, skb); 2469 return; 2470 } 2471 2472 static void 2473 lkpi_80211_txq_task(void *ctx, int pending) 2474 { 2475 struct lkpi_sta *lsta; 2476 struct ieee80211_node *ni; 2477 struct mbufq mq; 2478 struct mbuf *m; 2479 2480 lsta = ctx; 2481 ni = lsta->ni; 2482 2483 if (debug_80211 & D80211_TRACE_TX) 2484 printf("%s:%d lsta %p ni %p %6D pending %d mbuf_qlen %d\n", 2485 __func__, __LINE__, lsta, ni, ni->ni_macaddr, ":", 2486 pending, mbufq_len(&lsta->txq)); 2487 2488 mbufq_init(&mq, IFQ_MAXLEN); 2489 2490 LKPI_80211_LSTA_LOCK(lsta); 2491 mbufq_concat(&mq, &lsta->txq); 2492 LKPI_80211_LSTA_UNLOCK(lsta); 2493 2494 m = mbufq_dequeue(&mq); 2495 while (m != NULL) { 2496 lkpi_80211_txq_tx_one(lsta, m); 2497 m = mbufq_dequeue(&mq); 2498 } 2499 } 2500 2501 static int 2502 lkpi_ic_transmit(struct ieee80211com *ic, struct mbuf *m) 2503 { 2504 2505 /* XXX TODO */ 2506 IMPROVE(); 2507 2508 /* Quick and dirty cheating hack. */ 2509 struct ieee80211_node *ni; 2510 2511 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 2512 return (lkpi_ic_raw_xmit(ni, m, NULL)); 2513 } 2514 2515 static void 2516 lkpi_ic_getradiocaps(struct ieee80211com *ic, int maxchan, 2517 int *n, struct ieee80211_channel *c) 2518 { 2519 struct lkpi_hw *lhw; 2520 struct ieee80211_hw *hw; 2521 struct linuxkpi_ieee80211_channel *channels; 2522 uint8_t bands[IEEE80211_MODE_BYTES]; 2523 int chan_flags, error, i, nchans; 2524 2525 /* Channels */ 2526 lhw = ic->ic_softc; 2527 hw = LHW_TO_HW(lhw); 2528 2529 /* NL80211_BAND_2GHZ */ 2530 nchans = 0; 2531 if (hw->wiphy->bands[NL80211_BAND_2GHZ] != NULL) 2532 nchans = hw->wiphy->bands[NL80211_BAND_2GHZ]->n_channels; 2533 if (nchans > 0) { 2534 memset(bands, 0, sizeof(bands)); 2535 chan_flags = 0; 2536 setbit(bands, IEEE80211_MODE_11B); 2537 /* XXX-BZ unclear how to check for 11g. */ 2538 setbit(bands, IEEE80211_MODE_11G); 2539 #ifdef __notyet__ 2540 if (hw->wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.ht_supported) { 2541 setbit(bands, IEEE80211_MODE_11NG); 2542 chan_flags |= NET80211_CBW_FLAG_HT40; 2543 } 2544 #endif 2545 2546 channels = hw->wiphy->bands[NL80211_BAND_2GHZ]->channels; 2547 for (i = 0; i < nchans; i++) { 2548 uint32_t nflags = 0; 2549 int cflags = chan_flags; 2550 2551 if (channels[i].flags & IEEE80211_CHAN_DISABLED) { 2552 printf("%s: %s: Skipping disabled chan " 2553 "[%u/%u/%#x]\n", ic->ic_name, __func__, 2554 channels[i].hw_value, 2555 channels[i].center_freq, channels[i].flags); 2556 continue; 2557 } 2558 if (channels[i].flags & IEEE80211_CHAN_NO_IR) 2559 nflags |= (IEEE80211_CHAN_NOADHOC|IEEE80211_CHAN_PASSIVE); 2560 if (channels[i].flags & IEEE80211_CHAN_RADAR) 2561 nflags |= IEEE80211_CHAN_DFS; 2562 if (channels[i].flags & IEEE80211_CHAN_NO_160MHZ) 2563 cflags &= ~(NET80211_CBW_FLAG_VHT160|NET80211_CBW_FLAG_VHT80P80); 2564 if (channels[i].flags & IEEE80211_CHAN_NO_80MHZ) 2565 cflags &= ~NET80211_CBW_FLAG_VHT80; 2566 /* XXX how to map the remaining enum ieee80211_channel_flags? */ 2567 if (channels[i].flags & IEEE80211_CHAN_NO_HT40) 2568 cflags &= ~NET80211_CBW_FLAG_HT40; 2569 2570 error = ieee80211_add_channel_cbw(c, maxchan, n, 2571 channels[i].hw_value, channels[i].center_freq, 2572 channels[i].max_power, 2573 nflags, bands, chan_flags); 2574 if (error != 0) { 2575 printf("%s: %s: Adding chan %u/%u/%#x/%#x/%#x/%#x " 2576 "returned error %d\n", ic->ic_name, 2577 __func__, channels[i].hw_value, 2578 channels[i].center_freq, channels[i].flags, 2579 nflags, chan_flags, cflags, error); 2580 break; 2581 } 2582 } 2583 } 2584 2585 /* NL80211_BAND_5GHZ */ 2586 nchans = 0; 2587 if (hw->wiphy->bands[NL80211_BAND_5GHZ] != NULL) 2588 nchans = hw->wiphy->bands[NL80211_BAND_5GHZ]->n_channels; 2589 if (nchans > 0) { 2590 memset(bands, 0, sizeof(bands)); 2591 chan_flags = 0; 2592 setbit(bands, IEEE80211_MODE_11A); 2593 #ifdef __not_yet__ 2594 if (hw->wiphy->bands[NL80211_BAND_5GHZ]->ht_cap.ht_supported) { 2595 setbit(bands, IEEE80211_MODE_11NA); 2596 chan_flags |= NET80211_CBW_FLAG_HT40; 2597 } 2598 if (hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.vht_supported){ 2599 2600 ic->ic_flags_ext |= IEEE80211_FEXT_VHT; 2601 ic->ic_vhtcaps = 2602 hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.cap; 2603 2604 setbit(bands, IEEE80211_MODE_VHT_5GHZ); 2605 chan_flags |= NET80211_CBW_FLAG_VHT80; 2606 if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ( 2607 ic->ic_vhtcaps)) 2608 chan_flags |= NET80211_CBW_FLAG_VHT160; 2609 if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160_80P80MHZ( 2610 ic->ic_vhtcaps)) 2611 chan_flags |= NET80211_CBW_FLAG_VHT80P80; 2612 } 2613 #endif 2614 2615 channels = hw->wiphy->bands[NL80211_BAND_5GHZ]->channels; 2616 for (i = 0; i < nchans; i++) { 2617 uint32_t nflags = 0; 2618 int cflags = chan_flags; 2619 2620 if (channels[i].flags & IEEE80211_CHAN_DISABLED) { 2621 printf("%s: %s: Skipping disabled chan " 2622 "[%u/%u/%#x]\n", ic->ic_name, __func__, 2623 channels[i].hw_value, 2624 channels[i].center_freq, channels[i].flags); 2625 continue; 2626 } 2627 if (channels[i].flags & IEEE80211_CHAN_NO_IR) 2628 nflags |= (IEEE80211_CHAN_NOADHOC|IEEE80211_CHAN_PASSIVE); 2629 if (channels[i].flags & IEEE80211_CHAN_RADAR) 2630 nflags |= IEEE80211_CHAN_DFS; 2631 if (channels[i].flags & IEEE80211_CHAN_NO_160MHZ) 2632 cflags &= ~(NET80211_CBW_FLAG_VHT160|NET80211_CBW_FLAG_VHT80P80); 2633 if (channels[i].flags & IEEE80211_CHAN_NO_80MHZ) 2634 cflags &= ~NET80211_CBW_FLAG_VHT80; 2635 /* XXX hwo to map the remaining enum ieee80211_channel_flags? */ 2636 if (channels[i].flags & IEEE80211_CHAN_NO_HT40) 2637 cflags &= ~NET80211_CBW_FLAG_HT40; 2638 2639 error = ieee80211_add_channel_cbw(c, maxchan, n, 2640 channels[i].hw_value, channels[i].center_freq, 2641 channels[i].max_power, 2642 nflags, bands, chan_flags); 2643 if (error != 0) { 2644 printf("%s: %s: Adding chan %u/%u/%#x/%#x/%#x/%#x " 2645 "returned error %d\n", ic->ic_name, 2646 __func__, channels[i].hw_value, 2647 channels[i].center_freq, channels[i].flags, 2648 nflags, chan_flags, cflags, error); 2649 break; 2650 } 2651 } 2652 } 2653 } 2654 2655 static void * 2656 lkpi_ieee80211_ifalloc(void) 2657 { 2658 struct ieee80211com *ic; 2659 2660 ic = malloc(sizeof(*ic), M_LKPI80211, M_WAITOK | M_ZERO); 2661 if (ic == NULL) 2662 return (NULL); 2663 2664 /* Setting these happens later when we have device information. */ 2665 ic->ic_softc = NULL; 2666 ic->ic_name = "linuxkpi"; 2667 2668 return (ic); 2669 } 2670 2671 struct ieee80211_hw * 2672 linuxkpi_ieee80211_alloc_hw(size_t priv_len, const struct ieee80211_ops *ops) 2673 { 2674 struct ieee80211_hw *hw; 2675 struct lkpi_hw *lhw; 2676 struct wiphy *wiphy; 2677 2678 /* Get us and the driver data also allocated. */ 2679 wiphy = wiphy_new(&linuxkpi_mac80211cfgops, sizeof(*lhw) + priv_len); 2680 if (wiphy == NULL) 2681 return (NULL); 2682 2683 lhw = wiphy_priv(wiphy); 2684 lhw->ops = ops; 2685 lhw->workq = alloc_ordered_workqueue(wiphy_name(wiphy), 0); 2686 if (lhw->workq == NULL) { 2687 wiphy_free(wiphy); 2688 return (NULL); 2689 } 2690 mtx_init(&lhw->mtx, "lhw", NULL, MTX_DEF | MTX_RECURSE); 2691 TAILQ_INIT(&lhw->lvif_head); 2692 2693 /* 2694 * XXX-BZ TODO make sure there is a "_null" function to all ops 2695 * not initialized. 2696 */ 2697 hw = LHW_TO_HW(lhw); 2698 hw->wiphy = wiphy; 2699 hw->priv = (void *)(lhw + 1); 2700 2701 /* BSD Specific. */ 2702 lhw->ic = lkpi_ieee80211_ifalloc(); 2703 if (lhw->ic == NULL) { 2704 ieee80211_free_hw(hw); 2705 return (NULL); 2706 } 2707 2708 IMPROVE(); 2709 2710 return (hw); 2711 } 2712 2713 void 2714 linuxkpi_ieee80211_iffree(struct ieee80211_hw *hw) 2715 { 2716 struct lkpi_hw *lhw; 2717 2718 lhw = HW_TO_LHW(hw); 2719 free(lhw->ic, M_LKPI80211); 2720 lhw->ic = NULL; 2721 2722 /* Cleanup more of lhw here or in wiphy_free()? */ 2723 mtx_destroy(&lhw->mtx); 2724 IMPROVE(); 2725 } 2726 2727 void 2728 linuxkpi_set_ieee80211_dev(struct ieee80211_hw *hw, char *name) 2729 { 2730 struct lkpi_hw *lhw; 2731 struct ieee80211com *ic; 2732 2733 lhw = HW_TO_LHW(hw); 2734 ic = lhw->ic; 2735 2736 /* Now set a proper name before ieee80211_ifattach(). */ 2737 ic->ic_softc = lhw; 2738 ic->ic_name = name; 2739 2740 /* XXX-BZ do we also need to set wiphy name? */ 2741 } 2742 2743 struct ieee80211_hw * 2744 linuxkpi_wiphy_to_ieee80211_hw(struct wiphy *wiphy) 2745 { 2746 struct lkpi_hw *lhw; 2747 2748 lhw = wiphy_priv(wiphy); 2749 return (LHW_TO_HW(lhw)); 2750 } 2751 2752 static void 2753 lkpi_radiotap_attach(struct lkpi_hw *lhw) 2754 { 2755 struct ieee80211com *ic; 2756 2757 ic = lhw->ic; 2758 ieee80211_radiotap_attach(ic, 2759 &lhw->rtap_tx.wt_ihdr, sizeof(lhw->rtap_tx), 2760 LKPI_RTAP_TX_FLAGS_PRESENT, 2761 &lhw->rtap_rx.wr_ihdr, sizeof(lhw->rtap_rx), 2762 LKPI_RTAP_RX_FLAGS_PRESENT); 2763 } 2764 2765 void 2766 linuxkpi_ieee80211_ifattach(struct ieee80211_hw *hw) 2767 { 2768 struct ieee80211com *ic; 2769 struct lkpi_hw *lhw; 2770 #ifdef TRY_HW_CRYPTO 2771 int i; 2772 #endif 2773 2774 lhw = HW_TO_LHW(hw); 2775 ic = lhw->ic; 2776 2777 /* XXX-BZ figure this out how they count his... */ 2778 if (!is_zero_ether_addr(hw->wiphy->perm_addr)) { 2779 IEEE80211_ADDR_COPY(ic->ic_macaddr, 2780 hw->wiphy->perm_addr); 2781 } else if (hw->wiphy->n_addresses > 0) { 2782 /* We take the first one. */ 2783 IEEE80211_ADDR_COPY(ic->ic_macaddr, 2784 hw->wiphy->addresses[0].addr); 2785 } else { 2786 ic_printf(ic, "%s: warning, no hardware address!\n", __func__); 2787 } 2788 2789 ic->ic_headroom = hw->extra_tx_headroom; 2790 2791 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 2792 ic->ic_opmode = IEEE80211_M_STA; 2793 2794 /* Set device capabilities. */ 2795 /* XXX-BZ we need to get these from linux80211/drivers and convert. */ 2796 ic->ic_caps = 2797 IEEE80211_C_STA | 2798 IEEE80211_C_MONITOR | 2799 IEEE80211_C_WPA | /* WPA/RSN */ 2800 IEEE80211_C_WME | 2801 #if 0 2802 IEEE80211_C_PMGT | 2803 #endif 2804 IEEE80211_C_SHSLOT | /* short slot time supported */ 2805 IEEE80211_C_SHPREAMBLE /* short preamble supported */ 2806 ; 2807 #if 0 2808 /* Scanning is a different kind of beast to re-work. */ 2809 ic->ic_caps |= IEEE80211_C_BGSCAN; 2810 #endif 2811 if (lhw->ops->hw_scan && 2812 ieee80211_hw_check(hw, SINGLE_SCAN_ON_ALL_BANDS)) { 2813 /* Advertise full-offload scanning */ 2814 ic->ic_flags_ext |= IEEE80211_FEXT_SCAN_OFFLOAD; 2815 } 2816 2817 #ifdef __notyet__ 2818 ic->ic_htcaps = IEEE80211_HTC_HT /* HT operation */ 2819 | IEEE80211_HTC_AMPDU /* A-MPDU tx/rx */ 2820 | IEEE80211_HTC_AMSDU /* A-MSDU tx/rx */ 2821 | IEEE80211_HTCAP_MAXAMSDU_3839 2822 /* max A-MSDU length */ 2823 | IEEE80211_HTCAP_SMPS_OFF; /* SM power save off */ 2824 ic->ic_htcaps |= IEEE80211_HTCAP_SHORTGI20; 2825 ic->ic_htcaps |= IEEE80211_HTCAP_CHWIDTH40 | IEEE80211_HTCAP_SHORTGI40; 2826 ic->ic_htcaps |= IEEE80211_HTCAP_TXSTBC; 2827 #endif 2828 2829 ic->ic_cryptocaps = 0; 2830 #ifdef TRY_HW_CRYPTO 2831 if (hw->wiphy->n_cipher_suites > 0) { 2832 for (i = 0; i < hw->wiphy->n_cipher_suites; i++) 2833 ic->ic_cryptocaps |= lkpi_l80211_to_net80211_cyphers( 2834 hw->wiphy->cipher_suites[i]); 2835 } 2836 #endif 2837 2838 lkpi_ic_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, 2839 ic->ic_channels); 2840 2841 ieee80211_ifattach(ic); 2842 2843 ic->ic_update_mcast = lkpi_ic_update_mcast; 2844 ic->ic_update_promisc = lkpi_ic_update_promisc; 2845 ic->ic_update_chw = lkpi_ic_update_chw; 2846 ic->ic_parent = lkpi_ic_parent; 2847 ic->ic_scan_start = lkpi_ic_scan_start; 2848 ic->ic_scan_end = lkpi_ic_scan_end; 2849 if (lhw->ops->hw_scan && 2850 ieee80211_hw_check(hw, SINGLE_SCAN_ON_ALL_BANDS)) 2851 ic->ic_scan_curchan = lkpi_ic_scan_curchan_nada; 2852 ic->ic_set_channel = lkpi_ic_set_channel; 2853 ic->ic_transmit = lkpi_ic_transmit; 2854 ic->ic_raw_xmit = lkpi_ic_raw_xmit; 2855 ic->ic_vap_create = lkpi_ic_vap_create; 2856 ic->ic_vap_delete = lkpi_ic_vap_delete; 2857 ic->ic_getradiocaps = lkpi_ic_getradiocaps; 2858 ic->ic_wme.wme_update = lkpi_ic_wme_update; 2859 2860 lhw->ic_node_alloc = ic->ic_node_alloc; 2861 ic->ic_node_alloc = lkpi_ic_node_alloc; 2862 lhw->ic_node_init = ic->ic_node_init; 2863 ic->ic_node_init = lkpi_ic_node_init; 2864 lhw->ic_node_cleanup = ic->ic_node_cleanup; 2865 ic->ic_node_cleanup = lkpi_ic_node_cleanup; 2866 lhw->ic_node_free = ic->ic_node_free; 2867 ic->ic_node_free = lkpi_ic_node_free; 2868 2869 lkpi_radiotap_attach(lhw); 2870 2871 if (bootverbose) 2872 ieee80211_announce(ic); 2873 } 2874 2875 void 2876 linuxkpi_ieee80211_ifdetach(struct ieee80211_hw *hw) 2877 { 2878 struct lkpi_hw *lhw; 2879 struct ieee80211com *ic; 2880 2881 lhw = HW_TO_LHW(hw); 2882 ic = lhw->ic; 2883 ieee80211_ifdetach(ic); 2884 } 2885 2886 void 2887 linuxkpi_ieee80211_iterate_interfaces(struct ieee80211_hw *hw, 2888 enum ieee80211_iface_iter flags, 2889 void(*iterfunc)(void *, uint8_t *, struct ieee80211_vif *), 2890 void *arg) 2891 { 2892 struct lkpi_hw *lhw; 2893 struct lkpi_vif *lvif; 2894 struct ieee80211_vif *vif; 2895 bool active, atomic; 2896 2897 lhw = HW_TO_LHW(hw); 2898 2899 if (flags & ~(IEEE80211_IFACE_ITER_NORMAL| 2900 IEEE80211_IFACE_ITER_RESUME_ALL| 2901 IEEE80211_IFACE_ITER__ACTIVE|IEEE80211_IFACE_ITER__ATOMIC)) { 2902 ic_printf(lhw->ic, "XXX TODO %s flags(%#x) not yet supported.\n", 2903 __func__, flags); 2904 } 2905 2906 active = (flags & IEEE80211_IFACE_ITER__ACTIVE) != 0; 2907 atomic = (flags & IEEE80211_IFACE_ITER__ATOMIC) != 0; 2908 2909 if (atomic) 2910 LKPI_80211_LHW_LOCK(lhw); 2911 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) { 2912 struct ieee80211vap *vap; 2913 2914 vif = LVIF_TO_VIF(lvif); 2915 2916 /* 2917 * If we want "active" interfaces, we need to distinguish on 2918 * whether the driver knows about them or not to be able to 2919 * handle the "resume" case correctly. Skip the ones the 2920 * driver does not know about. 2921 */ 2922 if (active && !lvif->added_to_drv && 2923 (flags & IEEE80211_IFACE_ITER_RESUME_ALL) != 0) 2924 continue; 2925 2926 /* 2927 * Run the iterator function if we are either not asking 2928 * asking for active only or if the VAP is "running". 2929 */ 2930 /* XXX-BZ probably should have state in the lvif as well. */ 2931 vap = LVIF_TO_VAP(lvif); 2932 if (!active || (vap->iv_state != IEEE80211_S_INIT)) 2933 iterfunc(arg, vif->addr, vif); 2934 } 2935 if (atomic) 2936 LKPI_80211_LHW_UNLOCK(lhw); 2937 } 2938 2939 void 2940 linuxkpi_ieee80211_iterate_keys(struct ieee80211_hw *hw, 2941 struct ieee80211_vif *vif, 2942 void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *, 2943 struct ieee80211_sta *, struct ieee80211_key_conf *, void *), 2944 void *arg) 2945 { 2946 2947 UNIMPLEMENTED; 2948 } 2949 2950 void 2951 linuxkpi_ieee80211_iterate_chan_contexts(struct ieee80211_hw *hw, 2952 void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *, 2953 void *), 2954 void *arg) 2955 { 2956 2957 UNIMPLEMENTED; 2958 } 2959 2960 void 2961 linuxkpi_ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw, 2962 void (*iterfunc)(void *, struct ieee80211_sta *), void *arg) 2963 { 2964 struct lkpi_hw *lhw; 2965 struct lkpi_vif *lvif; 2966 struct lkpi_sta *lsta; 2967 struct ieee80211_sta *sta; 2968 2969 KASSERT(hw != NULL && iterfunc != NULL, 2970 ("%s: hw %p iterfunc %p arg %p\n", __func__, hw, iterfunc, arg)); 2971 2972 lhw = HW_TO_LHW(hw); 2973 2974 LKPI_80211_LHW_LOCK(lhw); 2975 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) { 2976 2977 LKPI_80211_LVIF_LOCK(lvif); 2978 TAILQ_FOREACH(lsta, &lvif->lsta_head, lsta_entry) { 2979 if (!lsta->added_to_drv) 2980 continue; 2981 sta = LSTA_TO_STA(lsta); 2982 iterfunc(arg, sta); 2983 } 2984 LKPI_80211_LVIF_UNLOCK(lvif); 2985 } 2986 LKPI_80211_LHW_UNLOCK(lhw); 2987 } 2988 2989 int 2990 linuxkpi_regulatory_set_wiphy_regd_sync(struct wiphy *wiphy, 2991 struct linuxkpi_ieee80211_regdomain *regd) 2992 { 2993 struct lkpi_hw *lhw; 2994 struct ieee80211com *ic; 2995 struct ieee80211_regdomain *rd; 2996 2997 lhw = wiphy_priv(wiphy); 2998 ic = lhw->ic; 2999 3000 rd = &ic->ic_regdomain; 3001 if (rd->isocc[0] == '\0') { 3002 rd->isocc[0] = regd->alpha2[0]; 3003 rd->isocc[1] = regd->alpha2[1]; 3004 } 3005 3006 TODO(); 3007 /* XXX-BZ finish the rest. */ 3008 3009 return (0); 3010 } 3011 3012 void 3013 linuxkpi_ieee80211_scan_completed(struct ieee80211_hw *hw, 3014 struct cfg80211_scan_info *info) 3015 { 3016 struct lkpi_hw *lhw; 3017 struct ieee80211com *ic; 3018 struct ieee80211_scan_state *ss; 3019 3020 lhw = wiphy_priv(hw->wiphy); 3021 ic = lhw->ic; 3022 ss = ic->ic_scan; 3023 3024 ieee80211_scan_done(ss->ss_vap); 3025 3026 LKPI_80211_LHW_LOCK(lhw); 3027 free(lhw->hw_req->ies.common_ies, M_80211_VAP); 3028 free(lhw->hw_req, M_LKPI80211); 3029 lhw->hw_req = NULL; 3030 lhw->scan_flags &= ~LKPI_SCAN_RUNNING; 3031 wakeup(lhw); 3032 LKPI_80211_LHW_UNLOCK(lhw); 3033 3034 return; 3035 } 3036 3037 void 3038 linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, 3039 struct ieee80211_sta *sta, struct napi_struct *napi __unused) 3040 { 3041 struct epoch_tracker et; 3042 struct lkpi_hw *lhw; 3043 struct ieee80211com *ic; 3044 struct mbuf *m; 3045 struct skb_shared_info *shinfo; 3046 struct ieee80211_rx_status *rx_status; 3047 struct ieee80211_rx_stats rx_stats; 3048 struct ieee80211_node *ni; 3049 struct ieee80211vap *vap; 3050 struct ieee80211_frame_min *wh; 3051 struct ieee80211_hdr *hdr; 3052 struct lkpi_sta *lsta; 3053 int i, offset, ok, type; 3054 3055 if (skb->len < 2) { 3056 /* Need 80211 stats here. */ 3057 IMPROVE(); 3058 goto err; 3059 } 3060 3061 /* 3062 * For now do the data copy; we can later improve things. Might even 3063 * have an mbuf backing the skb data then? 3064 */ 3065 m = m_get2(skb->len, M_NOWAIT, MT_DATA, M_PKTHDR); 3066 if (m == NULL) 3067 goto err; 3068 m_copyback(m, 0, skb->tail - skb->data, skb->data); 3069 3070 shinfo = skb_shinfo(skb); 3071 offset = m->m_len; 3072 for (i = 0; i < shinfo->nr_frags; i++) { 3073 m_copyback(m, offset, shinfo->frags[i].size, 3074 (uint8_t *)linux_page_address(shinfo->frags[i].page) + 3075 shinfo->frags[i].offset); 3076 offset += shinfo->frags[i].size; 3077 } 3078 3079 rx_status = IEEE80211_SKB_RXCB(skb); 3080 3081 #ifdef LINUXKPI_DEBUG_80211 3082 hdr = (void *)skb->data; 3083 if ((debug_80211 & D80211_TRACE_RX_BEACONS) == 0 && 3084 ieee80211_is_beacon(hdr->frame_control)) 3085 goto no_trace_beacons; 3086 3087 if (debug_80211 & D80211_TRACE_RX) 3088 printf("TRACE-RX: %s: skb %p a/l/d/t-len (%u/%u/%u/%u) " 3089 "h %p d %p t %p e %p sh %p (%u) m %p plen %u len %u\n", 3090 __func__, skb, skb->_alloc_len, skb->len, skb->data_len, 3091 skb->truesize, skb->head, skb->data, skb->tail, skb->end, 3092 shinfo, shinfo->nr_frags, 3093 m, m->m_pkthdr.len, m->m_len); 3094 3095 if (debug_80211 & D80211_TRACE_RX_DUMP) 3096 hexdump(mtod(m, const void *), m->m_len, "RX (raw) ", 0); 3097 3098 /* Implement a dump_rxcb() !!! */ 3099 if (debug_80211 & D80211_TRACE_RX) 3100 printf("TRACE %s: RXCB: %u %u %u, %#0x, %u, %#0x, %#0x, " 3101 "%u band %u, %u %u %u %u, %u, %#x %#x %#x %#x %u %u %u\n", 3102 __func__, 3103 rx_status->boottime_ns, 3104 rx_status->mactime, 3105 rx_status->device_timestamp, 3106 rx_status->flag, 3107 rx_status->freq, 3108 rx_status->bw, 3109 rx_status->encoding, 3110 rx_status->ampdu_reference, 3111 rx_status->band, 3112 rx_status->chains, 3113 rx_status->chain_signal[0], 3114 rx_status->chain_signal[1], 3115 rx_status->chain_signal[2], 3116 rx_status->signal, 3117 rx_status->enc_flags, 3118 rx_status->he_dcm, 3119 rx_status->he_gi, 3120 rx_status->he_ru, 3121 rx_status->zero_length_psdu_type, 3122 rx_status->nss, 3123 rx_status->rate_idx); 3124 no_trace_beacons: 3125 #endif 3126 3127 memset(&rx_stats, 0, sizeof(rx_stats)); 3128 rx_stats.r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI; 3129 if (ieee80211_hw_check(hw, SIGNAL_DBM) && 3130 !(rx_status->flag & RX_FLAG_NO_SIGNAL_VAL)) 3131 rx_stats.c_rssi = rx_status->signal; 3132 else 3133 rx_stats.c_rssi = 0; /* XXX */ 3134 rx_stats.c_nf = -96; /* XXX */ 3135 rx_stats.r_flags |= IEEE80211_R_BAND; 3136 rx_stats.c_band = 3137 lkpi_nl80211_band_to_net80211_band(rx_status->band); 3138 rx_stats.r_flags |= IEEE80211_R_FREQ | IEEE80211_R_IEEE; 3139 rx_stats.c_freq = rx_status->freq; 3140 rx_stats.c_ieee = ieee80211_mhz2ieee(rx_stats.c_freq, rx_stats.c_band); 3141 3142 /* XXX-BZ correct hardcoded rssi and noise floor. */ 3143 /* XXX (*sta_statistics)() to get to some of that? */ 3144 /* XXX-BZ dump the FreeBSD version of rx_stats as well! */ 3145 3146 lhw = HW_TO_LHW(hw); 3147 ic = lhw->ic; 3148 3149 ok = ieee80211_add_rx_params(m, &rx_stats); 3150 if (ok == 0) { 3151 counter_u64_add(ic->ic_ierrors, 1); 3152 goto err; 3153 } 3154 3155 if (sta != NULL) { 3156 lsta = STA_TO_LSTA(sta); 3157 ni = ieee80211_ref_node(lsta->ni); 3158 } else { 3159 wh = mtod(m, struct ieee80211_frame_min *); 3160 ni = ieee80211_find_rxnode(ic, wh); 3161 if (ni != NULL) 3162 lsta = ni->ni_drv_data; 3163 } 3164 3165 if (ni != NULL) 3166 vap = ni->ni_vap; 3167 else 3168 /* 3169 * XXX-BZ can we improve this by looking at the frame hdr 3170 * or other meta-data passed up? 3171 */ 3172 vap = TAILQ_FIRST(&ic->ic_vaps); 3173 3174 if (debug_80211 & D80211_TRACE_RX) 3175 printf("TRACE %s: sta %p lsta %p ni %p vap %p\n", __func__, sta, lsta, ni, vap); 3176 3177 if (vap != NULL && vap->iv_state > IEEE80211_S_INIT && 3178 ieee80211_radiotap_active_vap(vap)) { 3179 struct lkpi_radiotap_rx_hdr *rtap; 3180 3181 rtap = &lhw->rtap_rx; 3182 rtap->wr_tsft = rx_status->device_timestamp; 3183 rtap->wr_flags = 0; 3184 if (rx_status->enc_flags & RX_ENC_FLAG_SHORTPRE) 3185 rtap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 3186 if (rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI) 3187 rtap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI; 3188 #if 0 /* .. or it does not given we strip it below. */ 3189 if (ieee80211_hw_check(hw, RX_INCLUDES_FCS)) 3190 rtap->wr_flags |= IEEE80211_RADIOTAP_F_FCS; 3191 #endif 3192 if (rx_status->flag & RX_FLAG_FAILED_FCS_CRC) 3193 rtap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; 3194 rtap->wr_rate = 0; 3195 IMPROVE(); 3196 /* XXX TODO status->encoding / rate_index / bw */ 3197 rtap->wr_chan_freq = htole16(rx_stats.c_freq); 3198 if (ic->ic_curchan->ic_ieee == rx_stats.c_ieee) 3199 rtap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); 3200 rtap->wr_dbm_antsignal = rx_stats.c_rssi; 3201 rtap->wr_dbm_antnoise = rx_stats.c_nf; 3202 } 3203 3204 if (ieee80211_hw_check(hw, RX_INCLUDES_FCS)) 3205 m_adj(m, -IEEE80211_CRC_LEN); 3206 3207 NET_EPOCH_ENTER(et); 3208 if (ni != NULL) { 3209 type = ieee80211_input_mimo(ni, m); 3210 ieee80211_free_node(ni); 3211 } else { 3212 type = ieee80211_input_mimo_all(ic, m); 3213 } 3214 NET_EPOCH_EXIT(et); 3215 3216 if (debug_80211 & D80211_TRACE_RX) 3217 printf("TRACE %s: handled frame type %#0x\n", __func__, type); 3218 3219 IMPROVE(); 3220 3221 err: 3222 /* The skb is ours so we can free it :-) */ 3223 kfree_skb(skb); 3224 } 3225 3226 uint8_t 3227 linuxkpi_ieee80211_get_tid(struct ieee80211_hdr *hdr) 3228 { 3229 const struct ieee80211_frame *wh; 3230 3231 wh = (const struct ieee80211_frame *)hdr; 3232 return (ieee80211_gettid(wh)); 3233 } 3234 3235 struct wiphy * 3236 linuxkpi_wiphy_new(const struct cfg80211_ops *ops, size_t priv_len) 3237 { 3238 struct lkpi_wiphy *lwiphy; 3239 3240 lwiphy = kzalloc(sizeof(*lwiphy) + priv_len, GFP_KERNEL); 3241 if (lwiphy == NULL) 3242 return (NULL); 3243 lwiphy->ops = ops; 3244 3245 /* XXX TODO */ 3246 return (LWIPHY_TO_WIPHY(lwiphy)); 3247 } 3248 3249 void 3250 linuxkpi_wiphy_free(struct wiphy *wiphy) 3251 { 3252 struct lkpi_wiphy *lwiphy; 3253 3254 if (wiphy == NULL) 3255 return; 3256 3257 lwiphy = WIPHY_TO_LWIPHY(wiphy); 3258 kfree(lwiphy); 3259 } 3260 3261 uint32_t 3262 linuxkpi_ieee80211_channel_to_frequency(uint32_t channel, 3263 enum nl80211_band band) 3264 { 3265 3266 switch (band) { 3267 case NL80211_BAND_2GHZ: 3268 return (ieee80211_ieee2mhz(channel, IEEE80211_CHAN_2GHZ)); 3269 break; 3270 case NL80211_BAND_5GHZ: 3271 return (ieee80211_ieee2mhz(channel, IEEE80211_CHAN_5GHZ)); 3272 break; 3273 default: 3274 /* XXX abort, retry, error, panic? */ 3275 break; 3276 } 3277 3278 return (0); 3279 } 3280 3281 uint32_t 3282 linuxkpi_ieee80211_frequency_to_channel(uint32_t freq, uint32_t flags __unused) 3283 { 3284 3285 return (ieee80211_mhz2ieee(freq, 0)); 3286 } 3287 3288 static struct lkpi_sta * 3289 lkpi_find_lsta_by_ni(struct lkpi_vif *lvif, struct ieee80211_node *ni) 3290 { 3291 struct lkpi_sta *lsta, *temp; 3292 3293 LKPI_80211_LVIF_LOCK(lvif); 3294 TAILQ_FOREACH_SAFE(lsta, &lvif->lsta_head, lsta_entry, temp) { 3295 if (lsta->ni == ni) { 3296 LKPI_80211_LVIF_UNLOCK(lvif); 3297 return (lsta); 3298 } 3299 } 3300 LKPI_80211_LVIF_UNLOCK(lvif); 3301 3302 return (NULL); 3303 } 3304 3305 struct ieee80211_sta * 3306 linuxkpi_ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *peer) 3307 { 3308 struct lkpi_vif *lvif; 3309 struct lkpi_sta *lsta, *temp; 3310 struct ieee80211_sta *sta; 3311 3312 lvif = VIF_TO_LVIF(vif); 3313 3314 LKPI_80211_LVIF_LOCK(lvif); 3315 TAILQ_FOREACH_SAFE(lsta, &lvif->lsta_head, lsta_entry, temp) { 3316 sta = LSTA_TO_STA(lsta); 3317 if (IEEE80211_ADDR_EQ(sta->addr, peer)) { 3318 LKPI_80211_LVIF_UNLOCK(lvif); 3319 return (sta); 3320 } 3321 } 3322 LKPI_80211_LVIF_UNLOCK(lvif); 3323 return (NULL); 3324 } 3325 3326 struct ieee80211_sta * 3327 linuxkpi_ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, uint8_t *addr, 3328 uint8_t *ourvifaddr) 3329 { 3330 struct lkpi_hw *lhw; 3331 struct lkpi_vif *lvif; 3332 struct lkpi_sta *lsta; 3333 struct ieee80211_vif *vif; 3334 struct ieee80211_sta *sta; 3335 3336 lhw = wiphy_priv(hw->wiphy); 3337 sta = NULL; 3338 3339 LKPI_80211_LHW_LOCK(lhw); 3340 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) { 3341 3342 /* XXX-BZ check our address from the vif. */ 3343 3344 vif = LVIF_TO_VIF(lvif); 3345 if (ourvifaddr != NULL && 3346 !IEEE80211_ADDR_EQ(vif->addr, ourvifaddr)) 3347 continue; 3348 sta = linuxkpi_ieee80211_find_sta(vif, addr); 3349 if (sta != NULL) 3350 break; 3351 } 3352 LKPI_80211_LHW_UNLOCK(lhw); 3353 3354 if (sta != NULL) { 3355 lsta = STA_TO_LSTA(sta); 3356 if (!lsta->added_to_drv) 3357 return (NULL); 3358 } 3359 3360 return (sta); 3361 } 3362 3363 struct sk_buff * 3364 linuxkpi_ieee80211_tx_dequeue(struct ieee80211_hw *hw, 3365 struct ieee80211_txq *txq) 3366 { 3367 struct lkpi_txq *ltxq; 3368 struct sk_buff *skb; 3369 3370 ltxq = TXQ_TO_LTXQ(txq); 3371 ltxq->seen_dequeue = true; 3372 3373 skb = skb_dequeue(<xq->skbq); 3374 3375 return (skb); 3376 } 3377 3378 void 3379 linuxkpi_ieee80211_txq_get_depth(struct ieee80211_txq *txq, 3380 uint64_t *frame_cnt, uint64_t *byte_cnt) 3381 { 3382 struct lkpi_txq *ltxq; 3383 struct sk_buff *skb; 3384 uint64_t fc, bc; 3385 3386 ltxq = TXQ_TO_LTXQ(txq); 3387 3388 fc = bc = 0; 3389 skb_queue_walk(<xq->skbq, skb) { 3390 fc++; 3391 bc += skb->len; 3392 } 3393 if (frame_cnt) 3394 *frame_cnt = fc; 3395 if (byte_cnt) 3396 *byte_cnt = bc; 3397 3398 /* Validate that this is doing the correct thing. */ 3399 /* Should we keep track on en/dequeue? */ 3400 IMPROVE(); 3401 } 3402 3403 /* 3404 * We are called from ieee80211_free_txskb() or ieee80211_tx_status(). 3405 * The latter tries to derive the success status from the info flags 3406 * passed back from the driver. rawx_mit() saves the ni on the m and the 3407 * m on the skb for us to be able to give feedback to net80211. 3408 */ 3409 void 3410 linuxkpi_ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb, 3411 int status) 3412 { 3413 struct ieee80211_node *ni; 3414 struct mbuf *m; 3415 3416 m = skb->m; 3417 skb->m = NULL; 3418 3419 if (m != NULL) { 3420 ni = m->m_pkthdr.PH_loc.ptr; 3421 /* Status: 0 is ok, != 0 is error. */ 3422 ieee80211_tx_complete(ni, m, status); 3423 /* ni & mbuf were consumed. */ 3424 } 3425 3426 kfree_skb(skb); 3427 } 3428 3429 /* 3430 * This is an internal bandaid for the moment for the way we glue 3431 * skbs and mbufs together for TX. Once we have skbs backed by 3432 * mbufs this should go away. 3433 * This is a public function but kept on the private KPI (lkpi_) 3434 * and is not exposed by a header file. 3435 */ 3436 static void 3437 lkpi_ieee80211_free_skb_mbuf(void *p) 3438 { 3439 struct ieee80211_node *ni; 3440 struct mbuf *m; 3441 3442 if (p == NULL) 3443 return; 3444 3445 m = (struct mbuf *)p; 3446 M_ASSERTPKTHDR(m); 3447 3448 ni = m->m_pkthdr.PH_loc.ptr; 3449 m->m_pkthdr.PH_loc.ptr = NULL; 3450 if (ni != NULL) 3451 ieee80211_free_node(ni); 3452 m_freem(m); 3453 } 3454 3455 void 3456 linuxkpi_ieee80211_queue_delayed_work(struct ieee80211_hw *hw, 3457 struct delayed_work *w, int delay) 3458 { 3459 struct lkpi_hw *lhw; 3460 3461 /* Need to make sure hw is in a stable (non-suspended) state. */ 3462 IMPROVE(); 3463 3464 lhw = HW_TO_LHW(hw); 3465 queue_delayed_work(lhw->workq, w, delay); 3466 } 3467 3468 void 3469 linuxkpi_ieee80211_queue_work(struct ieee80211_hw *hw, 3470 struct work_struct *w) 3471 { 3472 struct lkpi_hw *lhw; 3473 3474 /* Need to make sure hw is in a stable (non-suspended) state. */ 3475 IMPROVE(); 3476 3477 lhw = HW_TO_LHW(hw); 3478 queue_work(lhw->workq, w); 3479 } 3480 3481 struct sk_buff * 3482 linuxkpi_ieee80211_pspoll_get(struct ieee80211_hw *hw, 3483 struct ieee80211_vif *vif) 3484 { 3485 struct lkpi_vif *lvif; 3486 struct ieee80211vap *vap; 3487 struct sk_buff *skb; 3488 struct ieee80211_frame_pspoll *psp; 3489 uint16_t v; 3490 3491 skb = dev_alloc_skb(hw->extra_tx_headroom + sizeof(*psp)); 3492 if (skb == NULL) 3493 return (NULL); 3494 3495 skb_reserve(skb, hw->extra_tx_headroom); 3496 3497 lvif = VIF_TO_LVIF(vif); 3498 vap = LVIF_TO_VAP(lvif); 3499 3500 psp = skb_put_zero(skb, sizeof(*psp)); 3501 psp->i_fc[0] = IEEE80211_FC0_VERSION_0; 3502 psp->i_fc[0] |= IEEE80211_FC0_SUBTYPE_PS_POLL | IEEE80211_FC0_TYPE_CTL; 3503 v = htole16(vif->bss_conf.aid | 1<<15 | 1<<16); 3504 memcpy(&psp->i_aid, &v, sizeof(v)); 3505 IEEE80211_ADDR_COPY(psp->i_bssid, vap->iv_bss->ni_macaddr); 3506 IEEE80211_ADDR_COPY(psp->i_ta, vif->addr); 3507 3508 return (skb); 3509 } 3510 3511 struct sk_buff * 3512 linuxkpi_ieee80211_nullfunc_get(struct ieee80211_hw *hw, 3513 struct ieee80211_vif *vif, bool qos) 3514 { 3515 struct lkpi_vif *lvif; 3516 struct ieee80211vap *vap; 3517 struct sk_buff *skb; 3518 struct ieee80211_frame *nullf; 3519 3520 skb = dev_alloc_skb(hw->extra_tx_headroom + sizeof(*nullf)); 3521 if (skb == NULL) 3522 return (NULL); 3523 3524 skb_reserve(skb, hw->extra_tx_headroom); 3525 3526 lvif = VIF_TO_LVIF(vif); 3527 vap = LVIF_TO_VAP(lvif); 3528 3529 nullf = skb_put_zero(skb, sizeof(*nullf)); 3530 nullf->i_fc[0] = IEEE80211_FC0_VERSION_0; 3531 nullf->i_fc[0] |= IEEE80211_FC0_SUBTYPE_NODATA | IEEE80211_FC0_TYPE_DATA; 3532 nullf->i_fc[1] = IEEE80211_FC1_DIR_TODS; 3533 3534 IEEE80211_ADDR_COPY(nullf->i_addr1, vap->iv_bss->ni_bssid); 3535 IEEE80211_ADDR_COPY(nullf->i_addr2, vif->addr); 3536 IEEE80211_ADDR_COPY(nullf->i_addr3, vap->iv_bss->ni_macaddr); 3537 3538 return (skb); 3539 } 3540 3541 struct wireless_dev * 3542 linuxkpi_ieee80211_vif_to_wdev(struct ieee80211_vif *vif) 3543 { 3544 struct lkpi_vif *lvif; 3545 3546 lvif = VIF_TO_LVIF(vif); 3547 return (&lvif->wdev); 3548 } 3549 3550 void 3551 linuxkpi_ieee80211_connection_loss(struct ieee80211_vif *vif) 3552 { 3553 struct lkpi_vif *lvif; 3554 struct ieee80211vap *vap; 3555 enum ieee80211_state nstate; 3556 int arg; 3557 3558 lvif = VIF_TO_LVIF(vif); 3559 vap = LVIF_TO_VAP(lvif); 3560 3561 /* 3562 * Go to scan; otherwise we need to elaborately check state and 3563 * handle accordingly, e.g., if in RUN we could call iv_bmiss. 3564 * Let the statemachine handle all neccessary changes. 3565 */ 3566 nstate = IEEE80211_S_SCAN; 3567 arg = 0; 3568 3569 if (debug_80211 & D80211_TRACE) 3570 ic_printf(vap->iv_ic, "%s: vif %p\n", __func__, vif); 3571 ieee80211_new_state(vap, nstate, arg); 3572 } 3573 3574 MODULE_VERSION(linuxkpi_wlan, 1); 3575 MODULE_DEPEND(linuxkpi_wlan, linuxkpi, 1, 1, 1); 3576 MODULE_DEPEND(linuxkpi_wlan, wlan, 1, 1, 1); 3577