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