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