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