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