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