1 /*-
2 * Copyright (c) 2020-2026 The FreeBSD Foundation
3 * Copyright (c) 2020-2025 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 /*
43 * TODO:
44 * - lots :)
45 * - HW_CRYPTO: we need a "keystore" and an ordered list for suspend/resume.
46 */
47
48 #include <sys/param.h>
49 #include <sys/types.h>
50 #include <sys/kernel.h>
51 #include <sys/errno.h>
52 #include <sys/malloc.h>
53 #include <sys/module.h>
54 #include <sys/mutex.h>
55 #include <sys/sbuf.h>
56 #include <sys/socket.h>
57 #include <sys/sysctl.h>
58 #include <sys/queue.h>
59 #include <sys/taskqueue.h>
60 #include <sys/libkern.h>
61
62 #include <net/if.h>
63 #include <net/if_var.h>
64 #include <net/if_media.h>
65 #include <net/ethernet.h>
66
67 #include <net80211/ieee80211_var.h>
68 #include <net80211/ieee80211_proto.h>
69 #include <net80211/ieee80211_ratectl.h>
70 #include <net80211/ieee80211_radiotap.h>
71 #include <net80211/ieee80211_vht.h>
72
73 #define LINUXKPI_NET80211
74 #include <net/mac80211.h>
75
76 #include <linux/workqueue.h>
77 #include <linux/rculist.h>
78 #include "linux_80211.h"
79
80 /* #define LKPI_80211_USE_SCANLIST */
81 /* #define LKPI_80211_BGSCAN */
82 #define LKPI_80211_WME
83 #define LKPI_80211_HW_CRYPTO
84 #define LKPI_80211_HT
85 #define LKPI_80211_VHT
86
87 #if defined(LKPI_80211_VHT) && !defined(LKPI_80211_HT)
88 #define LKPI_80211_HT
89 #endif
90 #if defined(LKPI_80211_HT) && !defined(LKPI_80211_HW_CRYPTO)
91 #define LKPI_80211_HW_CRYPTO
92 #endif
93
94 static MALLOC_DEFINE(M_LKPI80211, "lkpi80211", "LinuxKPI 80211 compat");
95
96 /* XXX-BZ really want this and others in queue.h */
97 #define TAILQ_ELEM_INIT(elm, field) do { \
98 (elm)->field.tqe_next = NULL; \
99 (elm)->field.tqe_prev = NULL; \
100 } while (0)
101
102 /* -------------------------------------------------------------------------- */
103
104 SYSCTL_DECL(_compat_linuxkpi);
105 SYSCTL_NODE(_compat_linuxkpi, OID_AUTO, 80211, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
106 "LinuxKPI 802.11 compatibility layer");
107
108 static bool lkpi_order_scanlist = false;
109 SYSCTL_BOOL(_compat_linuxkpi_80211, OID_AUTO, order_scanlist, CTLFLAG_RW,
110 &lkpi_order_scanlist, 0, "Enable LinuxKPI 802.11 scan list shuffeling");
111
112 #if defined(LKPI_80211_HW_CRYPTO)
113 static bool lkpi_hwcrypto = false;
114 SYSCTL_BOOL(_compat_linuxkpi_80211, OID_AUTO, hw_crypto, CTLFLAG_RDTUN,
115 &lkpi_hwcrypto, 0, "Enable LinuxKPI 802.11 hardware crypto offload");
116
117 static bool lkpi_hwcrypto_tkip = false;
118 SYSCTL_BOOL(_compat_linuxkpi_80211, OID_AUTO, tkip, CTLFLAG_RDTUN,
119 &lkpi_hwcrypto_tkip, 0, "Enable LinuxKPI 802.11 TKIP crypto offload");
120 #endif
121
122 /* Keep public for as long as header files are using it too. */
123 int linuxkpi_debug_80211;
124
125 #ifdef LINUXKPI_DEBUG_80211
126 SYSCTL_INT(_compat_linuxkpi_80211, OID_AUTO, debug, CTLFLAG_RWTUN,
127 &linuxkpi_debug_80211, 0, "LinuxKPI 802.11 debug level");
128
129 #define UNIMPLEMENTED if (linuxkpi_debug_80211 & D80211_TODO) \
130 printf("XXX-TODO %s:%d: UNIMPLEMENTED\n", __func__, __LINE__)
131 #define TRACEOK(_fmt, ...) if (linuxkpi_debug_80211 & D80211_TRACEOK) \
132 printf("%s:%d: TRACEPOINT " _fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
133 #else
134 #define UNIMPLEMENTED do { } while (0)
135 #define TRACEOK(...) do { } while (0)
136 #endif
137
138 /* #define PREP_TX_INFO_DURATION (IEEE80211_TRANS_WAIT * 1000) */
139 #ifndef PREP_TX_INFO_DURATION
140 #define PREP_TX_INFO_DURATION 0 /* Let the driver do its thing. */
141 #endif
142
143 /* This is DSAP | SSAP | CTRL | ProtoID/OrgCode{3}. */
144 const uint8_t rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
145
146 /* IEEE 802.11-05/0257r1 */
147 const uint8_t bridge_tunnel_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
148
149 /* IEEE 802.11e Table 20i-UP-to-AC mappings. */
150 static const uint8_t ieee80211e_up_to_ac[] = {
151 IEEE80211_AC_BE,
152 IEEE80211_AC_BK,
153 IEEE80211_AC_BK,
154 IEEE80211_AC_BE,
155 IEEE80211_AC_VI,
156 IEEE80211_AC_VI,
157 IEEE80211_AC_VO,
158 IEEE80211_AC_VO,
159 #if 0
160 IEEE80211_AC_VO, /* We treat MGMT as TID 8, which is set as AC_VO */
161 #endif
162 };
163
164 const struct cfg80211_ops linuxkpi_mac80211cfgops = {
165 /*
166 * XXX TODO need a "glue layer" to link cfg80211 ops to
167 * mac80211 and to the driver or net80211.
168 * Can we pass some on 1:1? Need to compare the (*f)().
169 */
170 };
171
172 #if 0
173 static struct lkpi_sta *lkpi_find_lsta_by_ni(struct lkpi_vif *,
174 struct ieee80211_node *);
175 #endif
176 static void lkpi_sw_scan_task(void *, int);
177 static void lkpi_80211_txq_tx_one(struct lkpi_sta *, struct mbuf *);
178 static void lkpi_80211_txq_task(void *, int);
179 static void lkpi_80211_lhw_rxq_task(void *, int);
180 static void lkpi_ieee80211_free_skb_mbuf(void *);
181 #ifdef LKPI_80211_WME
182 static int lkpi_wme_update(struct lkpi_hw *, struct ieee80211vap *, bool);
183 #endif
184 static int lkpi_80211_update_chandef(struct ieee80211_hw *,
185 struct ieee80211_chanctx_conf *);
186 static void lkpi_ieee80211_wake_queues_locked(struct ieee80211_hw *);
187
188 static const char *
lkpi_rate_info_bw_to_str(enum rate_info_bw bw)189 lkpi_rate_info_bw_to_str(enum rate_info_bw bw)
190 {
191
192 switch (bw) {
193
194 case RATE_INFO_BW_20:
195 return ("20");
196 break;
197 case RATE_INFO_BW_5:
198 return ("5");
199 break;
200 case RATE_INFO_BW_10:
201 return ("10");
202 break;
203 case RATE_INFO_BW_40:
204 return ("40");
205 break;
206 case RATE_INFO_BW_80:
207 return ("80");
208 break;
209 case RATE_INFO_BW_160:
210 return ("160");
211 break;
212 case RATE_INFO_BW_HE_RU:
213 IMPROVE("nl80211_he_ru_alloc");
214 return ("HE_RU");
215 break;
216 case RATE_INFO_BW_320:
217 return ("320");
218 break;
219 case RATE_INFO_BW_EHT_RU:
220 IMPROVE("nl80211_eht_ru_alloc");
221 return ("EHT_RU");
222 break;
223 default:
224 return ("?");
225 break;
226 }
227 }
228
229 static void
lkpi_nl80211_sta_info_to_str(struct sbuf * s,const char * prefix,const uint64_t flags)230 lkpi_nl80211_sta_info_to_str(struct sbuf *s, const char *prefix,
231 const uint64_t flags)
232 {
233 int bit, i;
234
235 sbuf_printf(s, "%s %#010jx", prefix, flags);
236
237 i = 0;
238 for (bit = 0; bit < BITS_PER_TYPE(flags); bit++) {
239
240 if ((flags & BIT_ULL(bit)) == 0)
241 continue;
242
243 #define EXPAND_CASE(_flag) \
244 case NL80211_STA_INFO_ ## _flag: \
245 sbuf_printf(s, "%c%s", (i == 0) ? '<' : ',', #_flag); \
246 i++; \
247 break;
248
249 switch (bit) {
250 EXPAND_CASE(BEACON_RX)
251 EXPAND_CASE(BEACON_SIGNAL_AVG)
252 EXPAND_CASE(BSS_PARAM)
253 EXPAND_CASE(CHAIN_SIGNAL)
254 EXPAND_CASE(CHAIN_SIGNAL_AVG)
255 EXPAND_CASE(CONNECTED_TIME)
256 EXPAND_CASE(INACTIVE_TIME)
257 EXPAND_CASE(SIGNAL)
258 EXPAND_CASE(SIGNAL_AVG)
259 EXPAND_CASE(STA_FLAGS)
260 EXPAND_CASE(RX_BITRATE)
261 EXPAND_CASE(RX_PACKETS)
262 EXPAND_CASE(RX_BYTES)
263 EXPAND_CASE(RX_DROP_MISC)
264 EXPAND_CASE(TX_BITRATE)
265 EXPAND_CASE(TX_PACKETS)
266 EXPAND_CASE(TX_BYTES)
267 EXPAND_CASE(TX_BYTES64)
268 EXPAND_CASE(RX_BYTES64)
269 EXPAND_CASE(TX_FAILED)
270 EXPAND_CASE(TX_RETRIES)
271 EXPAND_CASE(RX_DURATION)
272 EXPAND_CASE(TX_DURATION)
273 EXPAND_CASE(ACK_SIGNAL)
274 EXPAND_CASE(ACK_SIGNAL_AVG)
275 default:
276 sbuf_printf(s, "%c?%d", (i == 0) ? '<' : ',', bit);
277 break;
278 }
279 }
280 #undef EXPAND_CASE
281 if (i > 0)
282 sbuf_printf(s, ">");
283 sbuf_printf(s, "\n");
284 }
285
286 static void
lkpi_80211_dump_lvif_stas(struct lkpi_vif * lvif,struct sbuf * s,bool dump_queues)287 lkpi_80211_dump_lvif_stas(struct lkpi_vif *lvif, struct sbuf *s, bool dump_queues)
288 {
289 struct lkpi_hw *lhw;
290 struct ieee80211_hw *hw;
291 struct ieee80211vap *vap;
292 struct ieee80211_vif *vif;
293 struct lkpi_sta *lsta;
294 struct ieee80211_sta *sta;
295 struct station_info sinfo;
296 int error;
297 uint8_t tid;
298
299 vif = LVIF_TO_VIF(lvif);
300 vap = LVIF_TO_VAP(lvif);
301 lhw = vap->iv_ic->ic_softc;
302 hw = LHW_TO_HW(lhw);
303
304 wiphy_lock(hw->wiphy);
305 list_for_each_entry(lsta, &lvif->lsta_list, lsta_list) {
306 sta = LSTA_TO_STA(lsta);
307
308 sbuf_putc(s, '\n');
309 sbuf_printf(s, "lsta %p sta %p added_to_drv %d\n", lsta, sta, lsta->added_to_drv);
310
311 memset(&sinfo, 0, sizeof(sinfo));
312 error = lkpi_80211_mo_sta_statistics(hw, vif, sta, &sinfo);
313 if (error == EEXIST) /* Not added to driver. */
314 continue;
315 if (error == ENOTSUPP) {
316 sbuf_printf(s, " sta_statistics not supported\n");
317 continue;
318 }
319 if (error != 0) {
320 sbuf_printf(s, " sta_statistics failed: %d\n", error);
321 continue;
322 }
323
324 /* If no RX_BITRATE is reported, try to fill it in from the lsta sinfo. */
325 if ((sinfo.filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) == 0 &&
326 (lsta->sinfo.filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) != 0) {
327 memcpy(&sinfo.rxrate, &lsta->sinfo.rxrate, sizeof(sinfo.rxrate));
328 sinfo.filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
329 }
330 /* If no CHAIN_SIGNAL is reported, try to fill it in from the lsta sinfo. */
331 if ((sinfo.filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) == 0 &&
332 (lsta->sinfo.filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) != 0) {
333 sinfo.chains = lsta->sinfo.chains;
334 memcpy(sinfo.chain_signal, lsta->sinfo.chain_signal,
335 sizeof(sinfo.chain_signal));
336 sinfo.filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
337 }
338
339 lkpi_nl80211_sta_info_to_str(s, " nl80211_sta_info (valid fields)", sinfo.filled);
340 sbuf_printf(s, " connected_time %u inactive_time %u\n",
341 sinfo.connected_time, sinfo.inactive_time);
342 sbuf_printf(s, " rx_bytes %ju rx_packets %u rx_dropped_misc %u\n",
343 (uintmax_t)sinfo.rx_bytes, sinfo.rx_packets, sinfo.rx_dropped_misc);
344 sbuf_printf(s, " rx_duration %ju rx_beacon %u rx_beacon_signal_avg %d\n",
345 (uintmax_t)sinfo.rx_duration, sinfo.rx_beacon, (int8_t)sinfo.rx_beacon_signal_avg);
346
347 sbuf_printf(s, " tx_bytes %ju tx_packets %u tx_failed %u\n",
348 (uintmax_t)sinfo.tx_bytes, sinfo.tx_packets, sinfo.tx_failed);
349 sbuf_printf(s, " tx_duration %ju tx_retries %u\n",
350 (uintmax_t)sinfo.tx_duration, sinfo.tx_retries);
351
352 sbuf_printf(s, " signal %d signal_avg %d ack_signal %d avg_ack_signal %d\n",
353 sinfo.signal, sinfo.signal_avg, sinfo.ack_signal, sinfo.avg_ack_signal);
354 sbuf_printf(s, " generation %d assoc_req_ies_len %zu chains %#04x\n",
355 sinfo.generation, sinfo.assoc_req_ies_len, sinfo.chains);
356
357 for (int i = 0; i < nitems(sinfo.chain_signal) && i < IEEE80211_MAX_CHAINS; i++) {
358 if (!(sinfo.chains & BIT(i)))
359 continue;
360 sbuf_printf(s, " chain[%d] signal %d signal_avg %d\n",
361 i, (int8_t)sinfo.chain_signal[i], (int8_t)sinfo.chain_signal_avg[i]);
362 }
363
364 /* assoc_req_ies, bss_param, sta_flags */
365
366 sbuf_printf(s, " rxrate: flags %b bw %u(%s) legacy %u kbit/s mcs %u nss %u\n",
367 sinfo.rxrate.flags, CFG80211_RATE_INFO_FLAGS_BITS,
368 sinfo.rxrate.bw, lkpi_rate_info_bw_to_str(sinfo.rxrate.bw),
369 sinfo.rxrate.legacy * 100,
370 sinfo.rxrate.mcs, sinfo.rxrate.nss);
371 sbuf_printf(s, " he_dcm %u he_gi %u he_ru_alloc %u eht_gi %u\n",
372 sinfo.rxrate.he_dcm, sinfo.rxrate.he_gi, sinfo.rxrate.he_ru_alloc,
373 sinfo.rxrate.eht_gi);
374 sbuf_printf(s, " txrate: flags %b bw %u(%s) legacy %u kbit/s mcs %u nss %u\n",
375 sinfo.txrate.flags, CFG80211_RATE_INFO_FLAGS_BITS,
376 sinfo.txrate.bw, lkpi_rate_info_bw_to_str(sinfo.txrate.bw),
377 sinfo.txrate.legacy * 100,
378 sinfo.txrate.mcs, sinfo.txrate.nss);
379 sbuf_printf(s, " he_dcm %u he_gi %u he_ru_alloc %u eht_gi %u\n",
380 sinfo.txrate.he_dcm, sinfo.txrate.he_gi, sinfo.txrate.he_ru_alloc,
381 sinfo.txrate.eht_gi);
382
383 if (!dump_queues)
384 continue;
385
386 /* Dump queue information. */
387 sbuf_printf(s, " Queue information:\n");
388 sbuf_printf(s, " frms direct tx %ju\n", lsta->frms_tx);
389 for (tid = 0; tid <= IEEE80211_NUM_TIDS; tid++) {
390 struct lkpi_txq *ltxq;
391
392 if (sta->txq[tid] == NULL) {
393 sbuf_printf(s, " tid %-2u NOQ\n", tid);
394 continue;
395 }
396
397 ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
398 #ifdef __notyet__
399 sbuf_printf(s, " tid %-2u flags: %b "
400 "txq_generation %u skbq len %d\n",
401 tid, ltxq->flags, LKPI_TXQ_FLAGS_BITS,
402 ltxq->txq_generation,
403 skb_queue_len_lockless(<xq->skbq));
404 #else
405 sbuf_printf(s, " tid %-2u "
406 "txq_generation %u skbq len %d\n",
407 tid,
408 ltxq->txq_generation,
409 skb_queue_len_lockless(<xq->skbq));
410 #endif
411 sbuf_printf(s, " frms_enqueued %ju frms_dequeued %ju "
412 "frms_tx %ju\n",
413 ltxq->frms_enqueued, ltxq->frms_dequeued, ltxq->frms_tx);
414 }
415 }
416 wiphy_unlock(hw->wiphy);
417 }
418
419 static int
lkpi_80211_dump_stas(SYSCTL_HANDLER_ARGS)420 lkpi_80211_dump_stas(SYSCTL_HANDLER_ARGS)
421 {
422 struct lkpi_vif *lvif;
423 struct sbuf s;
424
425 if (req->newptr)
426 return (EPERM);
427
428 lvif = (struct lkpi_vif *)arg1;
429
430 sbuf_new_for_sysctl(&s, NULL, 1024, req);
431
432 lkpi_80211_dump_lvif_stas(lvif, &s, false);
433
434 sbuf_finish(&s);
435 sbuf_delete(&s);
436
437 return (0);
438 }
439
440 static int
lkpi_80211_dump_sta_queues(SYSCTL_HANDLER_ARGS)441 lkpi_80211_dump_sta_queues(SYSCTL_HANDLER_ARGS)
442 {
443 struct lkpi_vif *lvif;
444 struct sbuf s;
445
446 if (req->newptr)
447 return (EPERM);
448
449 lvif = (struct lkpi_vif *)arg1;
450
451 sbuf_new_for_sysctl(&s, NULL, 1024, req);
452
453 lkpi_80211_dump_lvif_stas(lvif, &s, true);
454
455 sbuf_finish(&s);
456 sbuf_delete(&s);
457
458 return (0);
459 }
460
461 static enum ieee80211_sta_rx_bandwidth
lkpi_cw_to_rx_bw(enum nl80211_chan_width cw)462 lkpi_cw_to_rx_bw(enum nl80211_chan_width cw)
463 {
464 switch (cw) {
465 case NL80211_CHAN_WIDTH_320:
466 return (IEEE80211_STA_RX_BW_320);
467 case NL80211_CHAN_WIDTH_160:
468 case NL80211_CHAN_WIDTH_80P80:
469 return (IEEE80211_STA_RX_BW_160);
470 case NL80211_CHAN_WIDTH_80:
471 return (IEEE80211_STA_RX_BW_80);
472 case NL80211_CHAN_WIDTH_40:
473 return (IEEE80211_STA_RX_BW_40);
474 case NL80211_CHAN_WIDTH_20:
475 case NL80211_CHAN_WIDTH_20_NOHT:
476 return (IEEE80211_STA_RX_BW_20);
477 case NL80211_CHAN_WIDTH_5:
478 case NL80211_CHAN_WIDTH_10:
479 /* Unsupported input. */
480 return (IEEE80211_STA_RX_BW_20);
481 }
482 }
483
484 static enum nl80211_chan_width
lkpi_rx_bw_to_cw(enum ieee80211_sta_rx_bandwidth rx_bw)485 lkpi_rx_bw_to_cw(enum ieee80211_sta_rx_bandwidth rx_bw)
486 {
487 switch (rx_bw) {
488 case IEEE80211_STA_RX_BW_20:
489 return (NL80211_CHAN_WIDTH_20); /* _NOHT */
490 case IEEE80211_STA_RX_BW_40:
491 return (NL80211_CHAN_WIDTH_40);
492 case IEEE80211_STA_RX_BW_80:
493 return (NL80211_CHAN_WIDTH_80);
494 case IEEE80211_STA_RX_BW_160:
495 return (NL80211_CHAN_WIDTH_160); /* 80P80 */
496 case IEEE80211_STA_RX_BW_320:
497 return (NL80211_CHAN_WIDTH_320);
498 }
499 }
500
501 static void
lkpi_sync_chanctx_cw_from_rx_bw(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta)502 lkpi_sync_chanctx_cw_from_rx_bw(struct ieee80211_hw *hw,
503 struct ieee80211_vif *vif, struct ieee80211_sta *sta)
504 {
505 struct ieee80211_chanctx_conf *chanctx_conf;
506 enum ieee80211_sta_rx_bandwidth old_bw;
507 uint32_t changed;
508
509 chanctx_conf = rcu_dereference_protected(vif->bss_conf.chanctx_conf,
510 lockdep_is_held(&hw->wiphy->mtx));
511 if (chanctx_conf == NULL)
512 return;
513
514 old_bw = lkpi_cw_to_rx_bw(chanctx_conf->def.width);
515 if (old_bw == sta->deflink.bandwidth)
516 return;
517
518 chanctx_conf->def.width = lkpi_rx_bw_to_cw(sta->deflink.bandwidth);
519 if (chanctx_conf->def.width == NL80211_CHAN_WIDTH_20 &&
520 !sta->deflink.ht_cap.ht_supported)
521 chanctx_conf->def.width = NL80211_CHAN_WIDTH_20_NOHT;
522
523 chanctx_conf->min_def = chanctx_conf->def;
524
525 vif->bss_conf.chanreq.oper.width = chanctx_conf->def.width;
526
527 changed = IEEE80211_CHANCTX_CHANGE_MIN_WIDTH;
528 changed |= IEEE80211_CHANCTX_CHANGE_WIDTH;
529 lkpi_80211_mo_change_chanctx(hw, chanctx_conf, changed);
530 }
531
532 #if defined(LKPI_80211_HT)
533 static void
lkpi_sta_sync_ht_from_ni(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_node * ni)534 lkpi_sta_sync_ht_from_ni(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
535 struct ieee80211_sta *sta, struct ieee80211_node *ni)
536 {
537 struct ieee80211vap *vap;
538 uint8_t *ie;
539 struct ieee80211_ht_cap *htcap;
540 struct ieee80211_sta_ht_cap *ht_cap, *sta_ht_cap;
541 enum nl80211_band band;
542 int i, rx_nss;
543
544 if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) {
545 sta->deflink.ht_cap.ht_supported = false;
546 return;
547 }
548
549 sta->deflink.ht_cap.ht_supported = true;
550
551 /* htcap->ampdu_params_info */
552 vap = ni->ni_vap;
553 sta->deflink.ht_cap.ampdu_density = _IEEE80211_MASKSHIFT(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
554 if (sta->deflink.ht_cap.ampdu_density > vap->iv_ampdu_density)
555 sta->deflink.ht_cap.ampdu_density = vap->iv_ampdu_density;
556 sta->deflink.ht_cap.ampdu_factor = _IEEE80211_MASKSHIFT(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU);
557 if (sta->deflink.ht_cap.ampdu_factor > vap->iv_ampdu_rxmax)
558 sta->deflink.ht_cap.ampdu_factor = vap->iv_ampdu_rxmax;
559
560 ie = ni->ni_ies.htcap_ie;
561 KASSERT(ie != NULL, ("%s: HT but no htcap_ie on ni %p\n", __func__, ni));
562 if (ie[0] == IEEE80211_ELEMID_VENDOR)
563 ie += 4;
564 ie += 2;
565 htcap = (struct ieee80211_ht_cap *)ie;
566 sta->deflink.ht_cap.cap = htcap->cap_info;
567 sta->deflink.ht_cap.mcs = htcap->mcs;
568
569 /*
570 * 802.11n-2009 20.6 Parameters for HT MCSs gives the mandatory/
571 * optional MCS for Nss=1..4. We need to check the first four
572 * MCS sets from the Rx MCS Bitmask; then there is MCS 32 and
573 * MCS33.. is UEQM.
574 */
575 band = vif->bss_conf.chanctx_conf->def.chan->band;
576 ht_cap = &hw->wiphy->bands[band]->ht_cap;
577 sta_ht_cap = &sta->deflink.ht_cap;
578 rx_nss = 0;
579 for (i = 0; i < 4; i++) {
580 TRACEOK("HT rx_mask[%d] sta %#04x & hw %#04x", i,
581 sta_ht_cap->mcs.rx_mask[i], ht_cap->mcs.rx_mask[i]);
582 sta_ht_cap->mcs.rx_mask[i] =
583 sta_ht_cap->mcs.rx_mask[i] & ht_cap->mcs.rx_mask[i];
584 /* XXX-BZ masking unequal modulation? */
585
586 if (sta_ht_cap->mcs.rx_mask[i] != 0)
587 rx_nss++;
588 }
589 if (rx_nss > 0) {
590 TRACEOK("HT rx_nss = max(%d, %d)", rx_nss, sta->deflink.rx_nss);
591 sta->deflink.rx_nss = MAX(rx_nss, sta->deflink.rx_nss);
592 } else {
593 sta->deflink.ht_cap.ht_supported = false;
594 return;
595 }
596
597 if ((sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) != 0 &&
598 IEEE80211_IS_CHAN_HT40(ni->ni_chan))
599 sta->deflink.bandwidth = IEEE80211_STA_RX_BW_40;
600 else
601 sta->deflink.bandwidth = IEEE80211_STA_RX_BW_20;
602
603 IMPROVE("sta->wme");
604
605 if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_MAX_AMSDU)
606 sta->deflink.agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_7935;
607 else
608 sta->deflink.agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_3839;
609 sta->deflink.agg.max_rc_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_BA;
610 #ifdef __handled_by_driver__ /* iwlwifi only? actually unused? */
611 for (i = 0; i < nitems(sta.deflink.agg.max_tid_amsdu_len); i++) {
612 sta->deflink.agg.max_tid_amsdu_len[j] = ;
613 }
614 #endif
615 }
616 #endif
617
618 #if defined(LKPI_80211_VHT)
619 static void
lkpi_sta_sync_vht_from_ni(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_node * ni)620 lkpi_sta_sync_vht_from_ni(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
621 struct ieee80211_sta *sta, struct ieee80211_node *ni)
622 {
623 struct ieee80211_sta_vht_cap *vht_cap, *sta_vht_cap;;
624 enum ieee80211_sta_rx_bandwidth bw;
625 enum nl80211_band band;
626 uint32_t width;
627 int rx_nss;
628 uint16_t rx_map, tx_map;
629
630 if ((ni->ni_flags & IEEE80211_NODE_VHT) == 0 ||
631 !IEEE80211_IS_CHAN_VHT_5GHZ(ni->ni_chan)) {
632 sta->deflink.vht_cap.vht_supported = false;
633 return;
634 }
635
636 sta->deflink.vht_cap.vht_supported = true;
637
638 sta->deflink.vht_cap.cap = ni->ni_vhtcap;
639 sta->deflink.vht_cap.vht_mcs = ni->ni_vht_mcsinfo;
640
641 /*
642 * If VHT20/40 are selected do not update the bandwidth
643 * from HT but stya on VHT.
644 */
645 if (ni->ni_vht_chanwidth == IEEE80211_VHT_CHANWIDTH_USE_HT)
646 goto skip_bw;
647
648 bw = sta->deflink.bandwidth;
649 width = (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK);
650 switch (width) {
651 /* Deprecated. */
652 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
653 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
654 bw = IEEE80211_STA_RX_BW_160;
655 break;
656 default:
657 /* Check if we do support 160Mhz somehow after all. */
658 if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) != 0)
659 bw = IEEE80211_STA_RX_BW_160;
660 else
661 bw = IEEE80211_STA_RX_BW_80;
662 }
663 /*
664 * While we can set what is possibly supported we also need to be
665 * on a channel which supports that bandwidth; e.g., we can support
666 * VHT160 but the AP only does VHT80.
667 * Further ni_chan will also have filtered out what we disabled
668 * by configuration.
669 * Once net80211 channel selection is fixed for 802.11-2020 and
670 * VHT160 we can possibly spare ourselves the above.
671 */
672 if (bw == IEEE80211_STA_RX_BW_160 &&
673 !IEEE80211_IS_CHAN_VHT160(ni->ni_chan) &&
674 !IEEE80211_IS_CHAN_VHT80P80(ni->ni_chan))
675 bw = IEEE80211_STA_RX_BW_80;
676 if (bw == IEEE80211_STA_RX_BW_80 &&
677 !IEEE80211_IS_CHAN_VHT80(ni->ni_chan))
678 bw = sta->deflink.bandwidth;
679 sta->deflink.bandwidth = bw;
680 skip_bw:
681
682 band = vif->bss_conf.chanctx_conf->def.chan->band;
683 vht_cap = &hw->wiphy->bands[band]->vht_cap;
684 sta_vht_cap = &sta->deflink.vht_cap;
685
686 rx_nss = 0;
687 rx_map = tx_map = 0;
688 for (int i = 7; i >= 0; i--) {
689 uint8_t card, sta;
690
691 card = (vht_cap->vht_mcs.rx_mcs_map >> (2 * i)) & 0x3;
692 sta = (sta_vht_cap->vht_mcs.rx_mcs_map >> (2 * i)) & 0x3;
693 if (sta != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
694 if (card == IEEE80211_VHT_MCS_NOT_SUPPORTED)
695 sta = IEEE80211_VHT_MCS_NOT_SUPPORTED;
696 else {
697 sta = MIN(sta, card);
698 if (rx_nss == 0)
699 rx_nss = i + 1;
700 }
701 }
702 rx_map |= (sta << (2 * i));
703
704 card = (vht_cap->vht_mcs.tx_mcs_map >> (2 * i)) & 0x3;
705 sta = (sta_vht_cap->vht_mcs.tx_mcs_map >> (2 * i)) & 0x3;
706 if (sta != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
707 if (card == IEEE80211_VHT_MCS_NOT_SUPPORTED)
708 sta = IEEE80211_VHT_MCS_NOT_SUPPORTED;
709 else
710 sta = MIN(sta, card);
711 }
712 tx_map |= (sta << (2 * i));
713 }
714 TRACEOK("VHT rx_mcs_map %#010x->%#010x, tx_mcs_map %#010x->%#010x, rx_nss = %d",
715 sta_vht_cap->vht_mcs.rx_mcs_map, rx_map,
716 sta_vht_cap->vht_mcs.tx_mcs_map, tx_map, rx_nss);
717 sta_vht_cap->vht_mcs.rx_mcs_map = rx_map;
718 sta_vht_cap->vht_mcs.tx_mcs_map = tx_map;
719 if (rx_nss > 0) {
720 TRACEOK("VHT rx_nss = max(%d, %d)", rx_nss, sta->deflink.rx_nss);
721 sta->deflink.rx_nss = MAX(rx_nss, sta->deflink.rx_nss);
722 } else {
723 sta->deflink.vht_cap.vht_supported = false;
724 return;
725 }
726
727 switch (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) {
728 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
729 sta->deflink.agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454;
730 break;
731 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991:
732 sta->deflink.agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_7991;
733 break;
734 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895:
735 default:
736 sta->deflink.agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_3895;
737 break;
738 }
739 }
740 #endif
741
742 static void
lkpi_sta_sync_from_ni(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_node * ni,bool updchnctx)743 lkpi_sta_sync_from_ni(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
744 struct ieee80211_sta *sta, struct ieee80211_node *ni, bool updchnctx)
745 {
746
747 /*
748 * Ensure rx_nss is at least 1 as otherwise drivers run into
749 * unexpected problems.
750 */
751 sta->deflink.rx_nss = 1;
752
753 #if defined(LKPI_80211_HT)
754 lkpi_sta_sync_ht_from_ni(hw, vif, sta, ni);
755 #endif
756 #if defined(LKPI_80211_VHT)
757 lkpi_sta_sync_vht_from_ni(hw, vif, sta, ni);
758 #endif
759
760 /*
761 * We are also called from node allocation which net80211
762 * can do even on `ifconfig down`; in that case the chanctx
763 * may still be valid and we get a discrepancy between
764 * sta and chanctx. Thus do not try to update the chanctx
765 * when called from lkpi_lsta_alloc().
766 */
767 if (updchnctx)
768 lkpi_sync_chanctx_cw_from_rx_bw(hw, vif, sta);
769 }
770
771 #if 0
772 static uint8_t
773 lkpi_get_max_rx_chains(struct ieee80211_node *ni)
774 {
775 uint8_t chains;
776 #if defined(LKPI_80211_HT) || defined(LKPI_80211_VHT)
777 struct lkpi_sta *lsta;
778 struct ieee80211_sta *sta;
779
780 lsta = ni->ni_drv_data;
781 sta = LSTA_TO_STA(lsta);
782 #endif
783
784 chains = 1;
785 #if defined(LKPI_80211_HT)
786 IMPROVE("We should factor counting MCS/NSS out for sync and here");
787 if (sta->deflink.ht_cap.ht_supported)
788 chains = MAX(chains, sta->deflink.rx_nss);
789 #endif
790
791 #if defined(LKPI_80211_VHT)
792 if (sta->deflink.vht_cap.vht_supported)
793 chains = MAX(chains, sta->deflink.rx_nss);
794 #endif
795
796 return (chains);
797 }
798 #endif
799
800 static void
lkpi_lsta_dump(struct lkpi_sta * lsta,struct ieee80211_node * ni,const char * _f,int _l)801 lkpi_lsta_dump(struct lkpi_sta *lsta, struct ieee80211_node *ni,
802 const char *_f, int _l)
803 {
804
805 #ifdef LINUXKPI_DEBUG_80211
806 if ((linuxkpi_debug_80211 & D80211_TRACE_STA) == 0)
807 return;
808 if (lsta == NULL)
809 return;
810
811 printf("%s:%d lsta %p ni %p sta %p\n",
812 _f, _l, lsta, ni, &lsta->sta);
813 if (ni != NULL)
814 ieee80211_dump_node(NULL, ni);
815 printf("\ttxq_task txq len %d mtx\n", mbufq_len(&lsta->txq));
816 printf("\tkc %p state %d added_to_drv %d in_mgd %d\n",
817 &lsta->kc[0], lsta->state, lsta->added_to_drv, lsta->in_mgd);
818 #endif
819 }
820
821 static void
lkpi_lsta_remove(struct lkpi_sta * lsta,struct lkpi_vif * lvif)822 lkpi_lsta_remove(struct lkpi_sta *lsta, struct lkpi_vif *lvif)
823 {
824
825 lockdep_assert_wiphy(lsta->hw->wiphy);
826
827 KASSERT(!list_empty(&lsta->lsta_list),
828 ("%s: lsta %p ni %p\n", __func__, lsta, lsta->ni));
829 list_del_init(&lsta->lsta_list);
830 }
831
832 static struct lkpi_sta *
lkpi_lsta_alloc(struct ieee80211vap * vap,const uint8_t mac[IEEE80211_ADDR_LEN],struct ieee80211_hw * hw,struct ieee80211_node * ni)833 lkpi_lsta_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN],
834 struct ieee80211_hw *hw, struct ieee80211_node *ni)
835 {
836 struct lkpi_sta *lsta;
837 struct lkpi_vif *lvif;
838 struct ieee80211_vif *vif;
839 struct ieee80211_sta *sta;
840 int band, i, tid;
841
842 lsta = malloc(sizeof(*lsta) + hw->sta_data_size, M_LKPI80211,
843 M_NOWAIT | M_ZERO);
844 if (lsta == NULL)
845 return (NULL);
846
847 lsta->hw = hw;
848 lsta->added_to_drv = false;
849 lsta->state = IEEE80211_STA_NOTEXIST;
850 /*
851 * Link the ni to the lsta here without taking a reference.
852 * For one we would have to take the reference in node_init()
853 * as ieee80211_alloc_node() will initialise the refcount after us.
854 * For the other a ni and an lsta are 1:1 mapped and always together
855 * from [ic_]node_alloc() to [ic_]node_free() so we are essentally
856 * using the ni references for the lsta as well despite it being
857 * two separate allocations.
858 */
859 lsta->ni = ni;
860 /* The back-pointer "drv_data" to net80211_node let's us get lsta. */
861 ni->ni_drv_data = lsta;
862
863 lvif = VAP_TO_LVIF(vap);
864 vif = LVIF_TO_VIF(lvif);
865 sta = LSTA_TO_STA(lsta);
866
867 IEEE80211_ADDR_COPY(sta->addr, mac);
868
869 /* TXQ */
870 for (tid = 0; tid < nitems(sta->txq); tid++) {
871 struct lkpi_txq *ltxq;
872
873 /* We are not limiting ourselves to hw.queues here. */
874 ltxq = malloc(sizeof(*ltxq) + hw->txq_data_size,
875 M_LKPI80211, M_NOWAIT | M_ZERO);
876 if (ltxq == NULL)
877 goto cleanup;
878 /* iwlwifi//mvm/sta.c::tid_to_mac80211_ac[] */
879 if (tid == IEEE80211_NUM_TIDS) {
880 if (!ieee80211_hw_check(hw, STA_MMPDU_TXQ)) {
881 free(ltxq, M_LKPI80211);
882 continue;
883 }
884 IMPROVE("AP/if we support non-STA here too");
885 ltxq->txq.ac = IEEE80211_AC_VO;
886 } else {
887 ltxq->txq.ac = ieee80211e_up_to_ac[tid & 7];
888 }
889 ltxq->seen_dequeue = false;
890 ltxq->stopped = false;
891 ltxq->txq.vif = vif;
892 ltxq->txq.tid = tid;
893 ltxq->txq.sta = sta;
894 TAILQ_ELEM_INIT(ltxq, txq_entry);
895 skb_queue_head_init(<xq->skbq);
896 LKPI_80211_LTXQ_LOCK_INIT(ltxq);
897 sta->txq[tid] = <xq->txq;
898 }
899
900 /* Deflink information. */
901 for (band = 0; band < NUM_NL80211_BANDS; band++) {
902 struct ieee80211_supported_band *supband;
903 uint32_t rate_mandatory;;
904
905 supband = hw->wiphy->bands[band];
906 if (supband == NULL)
907 continue;
908
909 switch (band) {
910 case NL80211_BAND_2GHZ:
911 /* We have to assume 11g support here. */
912 rate_mandatory = IEEE80211_RATE_MANDATORY_G |
913 IEEE80211_RATE_MANDATORY_B;
914 break;
915 case NL80211_BAND_5GHZ:
916 rate_mandatory = IEEE80211_RATE_MANDATORY_A;
917 break;
918 default:
919 continue;
920 }
921
922 for (i = 0; i < supband->n_bitrates; i++) {
923 if ((supband->bitrates[i].flags & rate_mandatory) != 0)
924 sta->deflink.supp_rates[band] |= BIT(i);
925 }
926 }
927
928 sta->deflink.smps_mode = IEEE80211_SMPS_OFF;
929 sta->deflink.bandwidth = IEEE80211_STA_RX_BW_20;
930 sta->deflink.agg.max_rc_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_BA;
931 sta->deflink.rx_nss = 1;
932 sta->deflink.sta = sta;
933
934 lkpi_sta_sync_from_ni(hw, vif, sta, ni, false);
935
936 IMPROVE("he, eht, bw_320, ... smps_mode, ..");
937
938 /* Link configuration. */
939 IEEE80211_ADDR_COPY(sta->deflink.addr, sta->addr);
940 sta->link[0] = &sta->deflink;
941 for (i = 1; i < nitems(sta->link); i++) {
942 IMPROVE("more links; only link[0] = deflink currently.");
943 }
944 IMPROVE("11be");
945 sta->mlo = false;
946
947 /* Deferred TX path. */
948 LKPI_80211_LSTA_TXQ_LOCK_INIT(lsta);
949 TASK_INIT(&lsta->txq_task, 0, lkpi_80211_txq_task, lsta);
950 mbufq_init(&lsta->txq, 32 * NAPI_POLL_WEIGHT);
951 lsta->txq_ready = true;
952
953 return (lsta);
954
955 cleanup:
956 for (; tid >= 0; tid--) {
957 struct lkpi_txq *ltxq;
958
959 ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
960 LKPI_80211_LTXQ_LOCK_DESTROY(ltxq);
961 free(sta->txq[tid], M_LKPI80211);
962 }
963 free(lsta, M_LKPI80211);
964 return (NULL);
965 }
966
967 static void
lkpi_lsta_free(struct lkpi_sta * lsta,struct ieee80211_node * ni)968 lkpi_lsta_free(struct lkpi_sta *lsta, struct ieee80211_node *ni)
969 {
970 struct mbuf *m;
971
972 if (lsta->added_to_drv)
973 panic("%s: Trying to free an lsta still known to firmware: "
974 "lsta %p ni %p added_to_drv %d\n",
975 __func__, lsta, ni, lsta->added_to_drv);
976
977 /* XXX-BZ free resources, ... */
978 IMPROVE();
979
980 /* Drain sta->txq[] */
981
982 LKPI_80211_LSTA_TXQ_LOCK(lsta);
983 lsta->txq_ready = false;
984 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
985
986 /* Drain taskq, won't be restarted until added_to_drv is set again. */
987 while (taskqueue_cancel(taskqueue_thread, &lsta->txq_task, NULL) != 0)
988 taskqueue_drain(taskqueue_thread, &lsta->txq_task);
989
990 /* Flush mbufq (make sure to release ni refs!). */
991 m = mbufq_dequeue(&lsta->txq);
992 while (m != NULL) {
993 struct ieee80211_node *nim;
994
995 nim = (struct ieee80211_node *)m->m_pkthdr.rcvif;
996 if (nim != NULL)
997 ieee80211_free_node(nim);
998 m_freem(m);
999 m = mbufq_dequeue(&lsta->txq);
1000 }
1001 KASSERT(mbufq_empty(&lsta->txq), ("%s: lsta %p has txq len %d != 0\n",
1002 __func__, lsta, mbufq_len(&lsta->txq)));
1003 LKPI_80211_LSTA_TXQ_LOCK_DESTROY(lsta);
1004
1005 /* Remove lsta from vif; that is done by the state machine. Should assert it? */
1006
1007 IMPROVE("Make sure everything is cleaned up.");
1008
1009 /* Free lsta. */
1010 lsta->ni = NULL;
1011 ni->ni_drv_data = NULL;
1012 free(lsta, M_LKPI80211);
1013 }
1014
1015
1016 static enum nl80211_band
lkpi_net80211_chan_to_nl80211_band(struct ieee80211_channel * c)1017 lkpi_net80211_chan_to_nl80211_band(struct ieee80211_channel *c)
1018 {
1019
1020 if (IEEE80211_IS_CHAN_2GHZ(c))
1021 return (NL80211_BAND_2GHZ);
1022 else if (IEEE80211_IS_CHAN_5GHZ(c))
1023 return (NL80211_BAND_5GHZ);
1024 #ifdef __notyet__
1025 else if ()
1026 return (NL80211_BAND_6GHZ);
1027 else if ()
1028 return (NL80211_BAND_60GHZ);
1029 else if (IEEE80211_IS_CHAN_GSM(c))
1030 return (NL80211_BAND_XXX);
1031 #endif
1032 else
1033 panic("%s: unsupported band. c %p flags %#x\n",
1034 __func__, c, c->ic_flags);
1035 }
1036
1037 static uint32_t
lkpi_nl80211_band_to_net80211_band(enum nl80211_band band)1038 lkpi_nl80211_band_to_net80211_band(enum nl80211_band band)
1039 {
1040
1041 /* XXX-BZ this is just silly; net80211 is too convoluted. */
1042 /* IEEE80211_CHAN_A / _G / .. doesn't really work either. */
1043 switch (band) {
1044 case NL80211_BAND_2GHZ:
1045 return (IEEE80211_CHAN_2GHZ);
1046 break;
1047 case NL80211_BAND_5GHZ:
1048 return (IEEE80211_CHAN_5GHZ);
1049 break;
1050 case NL80211_BAND_60GHZ:
1051 break;
1052 case NL80211_BAND_6GHZ:
1053 break;
1054 default:
1055 panic("%s: unsupported band %u\n", __func__, band);
1056 break;
1057 }
1058
1059 IMPROVE();
1060 return (0x00);
1061 }
1062
1063 #ifdef LINUXKPI_DEBUG_80211
1064 static const char *
lkpi_nl80211_band_name(enum nl80211_band band)1065 lkpi_nl80211_band_name(enum nl80211_band band)
1066 {
1067 switch (band) {
1068 case NL80211_BAND_2GHZ:
1069 return "2Ghz";
1070 break;
1071 case NL80211_BAND_5GHZ:
1072 return "5Ghz";
1073 break;
1074 case NL80211_BAND_60GHZ:
1075 return "60Ghz";
1076 break;
1077 case NL80211_BAND_6GHZ:
1078 return "6Ghz";
1079 break;
1080 default:
1081 panic("%s: unsupported band %u\n", __func__, band);
1082 break;
1083 }
1084 }
1085 #endif
1086
1087 #if 0
1088 static enum ieee80211_ac_numbers
1089 lkpi_ac_net_to_l80211(int ac)
1090 {
1091
1092 switch (ac) {
1093 case WME_AC_VO:
1094 return (IEEE80211_AC_VO);
1095 case WME_AC_VI:
1096 return (IEEE80211_AC_VI);
1097 case WME_AC_BE:
1098 return (IEEE80211_AC_BE);
1099 case WME_AC_BK:
1100 return (IEEE80211_AC_BK);
1101 default:
1102 printf("%s: invalid WME_AC_* input: ac = %d\n", __func__, ac);
1103 return (IEEE80211_AC_BE);
1104 }
1105 }
1106 #endif
1107
1108 static enum nl80211_iftype
lkpi_opmode_to_vif_type(enum ieee80211_opmode opmode)1109 lkpi_opmode_to_vif_type(enum ieee80211_opmode opmode)
1110 {
1111
1112 switch (opmode) {
1113 case IEEE80211_M_IBSS:
1114 return (NL80211_IFTYPE_ADHOC);
1115 break;
1116 case IEEE80211_M_STA:
1117 return (NL80211_IFTYPE_STATION);
1118 break;
1119 case IEEE80211_M_WDS:
1120 return (NL80211_IFTYPE_WDS);
1121 break;
1122 case IEEE80211_M_HOSTAP:
1123 return (NL80211_IFTYPE_AP);
1124 break;
1125 case IEEE80211_M_MONITOR:
1126 return (NL80211_IFTYPE_MONITOR);
1127 break;
1128 case IEEE80211_M_MBSS:
1129 return (NL80211_IFTYPE_MESH_POINT);
1130 break;
1131 case IEEE80211_M_AHDEMO:
1132 /* FALLTHROUGH */
1133 default:
1134 printf("ERROR: %s: unsupported opmode %d\n", __func__, opmode);
1135 /* FALLTHROUGH */
1136 }
1137 return (NL80211_IFTYPE_UNSPECIFIED);
1138 }
1139
1140 #ifdef LKPI_80211_HW_CRYPTO
1141 static const char *
lkpi_cipher_suite_to_name(uint32_t wlan_cipher_suite)1142 lkpi_cipher_suite_to_name(uint32_t wlan_cipher_suite)
1143 {
1144 switch (wlan_cipher_suite) {
1145 case WLAN_CIPHER_SUITE_WEP40:
1146 return ("WEP40");
1147 case WLAN_CIPHER_SUITE_WEP104:
1148 return ("WEP104");
1149 case WLAN_CIPHER_SUITE_TKIP:
1150 return ("TKIP");
1151 case WLAN_CIPHER_SUITE_CCMP:
1152 return ("CCMP");
1153 case WLAN_CIPHER_SUITE_CCMP_256:
1154 return ("CCMP_256");
1155 case WLAN_CIPHER_SUITE_GCMP:
1156 return ("GCMP");
1157 case WLAN_CIPHER_SUITE_GCMP_256:
1158 return ("GCMP_256");
1159 case WLAN_CIPHER_SUITE_AES_CMAC:
1160 return ("AES_CMAC");
1161 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
1162 return ("BIP_CMAC_256");
1163 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
1164 return ("BIP_GMAC_128");
1165 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
1166 return ("BIP_GMAC_256");
1167 default:
1168 return ("??");
1169 }
1170 }
1171
1172 static uint32_t
lkpi_l80211_to_net80211_cyphers(struct ieee80211com * ic,uint32_t wlan_cipher_suite)1173 lkpi_l80211_to_net80211_cyphers(struct ieee80211com *ic,
1174 uint32_t wlan_cipher_suite)
1175 {
1176 switch (wlan_cipher_suite) {
1177 case WLAN_CIPHER_SUITE_WEP40:
1178 return (IEEE80211_CRYPTO_WEP);
1179 case WLAN_CIPHER_SUITE_WEP104:
1180 return (IEEE80211_CRYPTO_WEP);
1181 case WLAN_CIPHER_SUITE_TKIP:
1182 return (IEEE80211_CRYPTO_TKIP);
1183 case WLAN_CIPHER_SUITE_CCMP:
1184 return (IEEE80211_CRYPTO_AES_CCM);
1185 case WLAN_CIPHER_SUITE_CCMP_256:
1186 return (IEEE80211_CRYPTO_AES_CCM_256);
1187 case WLAN_CIPHER_SUITE_GCMP:
1188 return (IEEE80211_CRYPTO_AES_GCM_128);
1189 case WLAN_CIPHER_SUITE_GCMP_256:
1190 return (IEEE80211_CRYPTO_AES_GCM_256);
1191 case WLAN_CIPHER_SUITE_AES_CMAC:
1192 return (IEEE80211_CRYPTO_BIP_CMAC_128);
1193 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
1194 return (IEEE80211_CRYPTO_BIP_CMAC_256);
1195 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
1196 return (IEEE80211_CRYPTO_BIP_GMAC_128);
1197 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
1198 return (IEEE80211_CRYPTO_BIP_GMAC_256);
1199 default:
1200 ic_printf(ic, "%s: unknown WLAN Cipher Suite %#08x | %u (%s)\n",
1201 __func__,
1202 wlan_cipher_suite >> 8, wlan_cipher_suite & 0xff,
1203 lkpi_cipher_suite_to_name(wlan_cipher_suite));
1204 return (0);
1205 }
1206 }
1207
1208 static uint32_t
lkpi_net80211_to_l80211_cipher_suite(uint32_t cipher,uint8_t keylen)1209 lkpi_net80211_to_l80211_cipher_suite(uint32_t cipher, uint8_t keylen)
1210 {
1211
1212 switch (cipher) {
1213 case IEEE80211_CIPHER_WEP:
1214 if (keylen == (40/NBBY))
1215 return (WLAN_CIPHER_SUITE_WEP40);
1216 else if (keylen == (104/NBBY))
1217 return (WLAN_CIPHER_SUITE_WEP104);
1218 else {
1219 printf("%s: WEP with unsupported keylen %d\n",
1220 __func__, keylen * NBBY);
1221 return (0);
1222 }
1223 break;
1224 case IEEE80211_CIPHER_TKIP:
1225 return (WLAN_CIPHER_SUITE_TKIP);
1226 case IEEE80211_CIPHER_AES_CCM:
1227 return (WLAN_CIPHER_SUITE_CCMP);
1228 case IEEE80211_CIPHER_AES_CCM_256:
1229 return (WLAN_CIPHER_SUITE_CCMP_256);
1230 case IEEE80211_CIPHER_AES_GCM_128:
1231 return (WLAN_CIPHER_SUITE_GCMP);
1232 case IEEE80211_CIPHER_AES_GCM_256:
1233 return (WLAN_CIPHER_SUITE_GCMP_256);
1234 case IEEE80211_CIPHER_BIP_CMAC_128:
1235 return (WLAN_CIPHER_SUITE_AES_CMAC);
1236 case IEEE80211_CIPHER_BIP_CMAC_256:
1237 return (WLAN_CIPHER_SUITE_BIP_CMAC_256);
1238 case IEEE80211_CIPHER_BIP_GMAC_128:
1239 return (WLAN_CIPHER_SUITE_BIP_GMAC_128);
1240 case IEEE80211_CIPHER_BIP_GMAC_256:
1241 return (WLAN_CIPHER_SUITE_BIP_GMAC_256);
1242
1243 case IEEE80211_CIPHER_AES_OCB:
1244 case IEEE80211_CIPHER_TKIPMIC:
1245 /*
1246 * TKIP w/ hw MIC support
1247 * (gone wrong; should really be a crypto flag in net80211).
1248 */
1249 case IEEE80211_CIPHER_CKIP:
1250 case IEEE80211_CIPHER_NONE:
1251 printf("%s: unsupported cipher %#010x\n", __func__, cipher);
1252 break;
1253 default:
1254 printf("%s: unknown cipher %#010x\n", __func__, cipher);
1255 };
1256 return (0);
1257 }
1258 #endif
1259
1260 #ifdef __notyet__
1261 static enum ieee80211_sta_state
lkpi_net80211_state_to_sta_state(enum ieee80211_state state)1262 lkpi_net80211_state_to_sta_state(enum ieee80211_state state)
1263 {
1264
1265 /*
1266 * XXX-BZ The net80211 states are "try to ..", the lkpi8011 states are
1267 * "done". Also ASSOC/AUTHORIZED are both "RUN" then?
1268 */
1269 switch (state) {
1270 case IEEE80211_S_INIT:
1271 return (IEEE80211_STA_NOTEXIST);
1272 case IEEE80211_S_SCAN:
1273 return (IEEE80211_STA_NONE);
1274 case IEEE80211_S_AUTH:
1275 return (IEEE80211_STA_AUTH);
1276 case IEEE80211_S_ASSOC:
1277 return (IEEE80211_STA_ASSOC);
1278 case IEEE80211_S_RUN:
1279 return (IEEE80211_STA_AUTHORIZED);
1280 case IEEE80211_S_CAC:
1281 case IEEE80211_S_CSA:
1282 case IEEE80211_S_SLEEP:
1283 default:
1284 UNIMPLEMENTED;
1285 };
1286
1287 return (IEEE80211_STA_NOTEXIST);
1288 }
1289 #endif
1290
1291 static struct linuxkpi_ieee80211_channel *
lkpi_find_lkpi80211_chan(struct lkpi_hw * lhw,struct ieee80211_channel * c)1292 lkpi_find_lkpi80211_chan(struct lkpi_hw *lhw,
1293 struct ieee80211_channel *c)
1294 {
1295 struct ieee80211_hw *hw;
1296 struct linuxkpi_ieee80211_channel *channels;
1297 enum nl80211_band band;
1298 int i, nchans;
1299
1300 hw = LHW_TO_HW(lhw);
1301 band = lkpi_net80211_chan_to_nl80211_band(c);
1302 if (hw->wiphy->bands[band] == NULL)
1303 return (NULL);
1304
1305 nchans = hw->wiphy->bands[band]->n_channels;
1306 if (nchans <= 0)
1307 return (NULL);
1308
1309 channels = hw->wiphy->bands[band]->channels;
1310 for (i = 0; i < nchans; i++) {
1311 if (channels[i].center_freq == c->ic_freq)
1312 return (&channels[i]);
1313 }
1314
1315 return (NULL);
1316 }
1317
1318 #if 0
1319 static struct linuxkpi_ieee80211_channel *
1320 lkpi_get_lkpi80211_chan(struct ieee80211com *ic, struct ieee80211_node *ni)
1321 {
1322 struct linuxkpi_ieee80211_channel *chan;
1323 struct ieee80211_channel *c;
1324 struct lkpi_hw *lhw;
1325
1326 chan = NULL;
1327 if (ni != NULL && ni->ni_chan != IEEE80211_CHAN_ANYC)
1328 c = ni->ni_chan;
1329 else if (ic->ic_bsschan != IEEE80211_CHAN_ANYC)
1330 c = ic->ic_bsschan;
1331 else if (ic->ic_curchan != IEEE80211_CHAN_ANYC)
1332 c = ic->ic_curchan;
1333 else
1334 c = NULL;
1335
1336 if (c != NULL && c != IEEE80211_CHAN_ANYC) {
1337 lhw = ic->ic_softc;
1338 chan = lkpi_find_lkpi80211_chan(lhw, c);
1339 }
1340
1341 return (chan);
1342 }
1343 #endif
1344
1345 struct linuxkpi_ieee80211_channel *
linuxkpi_ieee80211_get_channel(struct wiphy * wiphy,uint32_t freq)1346 linuxkpi_ieee80211_get_channel(struct wiphy *wiphy, uint32_t freq)
1347 {
1348 enum nl80211_band band;
1349
1350 for (band = 0; band < NUM_NL80211_BANDS; band++) {
1351 struct ieee80211_supported_band *supband;
1352 struct linuxkpi_ieee80211_channel *channels;
1353 int i;
1354
1355 supband = wiphy->bands[band];
1356 if (supband == NULL || supband->n_channels == 0)
1357 continue;
1358
1359 channels = supband->channels;
1360 for (i = 0; i < supband->n_channels; i++) {
1361 if (channels[i].center_freq == freq)
1362 return (&channels[i]);
1363 }
1364 }
1365
1366 return (NULL);
1367 }
1368
1369 #ifdef LKPI_80211_HW_CRYPTO
1370 static int
lkpi_sta_del_keys(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct lkpi_sta * lsta)1371 lkpi_sta_del_keys(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1372 struct lkpi_sta *lsta)
1373 {
1374 int error;
1375
1376 if (!lkpi_hwcrypto)
1377 return (0);
1378
1379 lockdep_assert_wiphy(hw->wiphy);
1380
1381 if (vif->cfg.assoc && lsta->state == IEEE80211_STA_AUTHORIZED) {
1382 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1383 ic_printf(lsta->ni->ni_ic,
1384 "%d %lu %s: vif still assoc; not deleting keys\n",
1385 curthread->td_tid, jiffies, __func__);
1386 return (0);
1387 }
1388
1389 ieee80211_ref_node(lsta->ni);
1390
1391 error = 0;
1392 for (ieee80211_keyix keyix = 0; keyix < nitems(lsta->kc); keyix++) {
1393 struct ieee80211_key_conf *kc;
1394 int err;
1395
1396 if (lsta->kc[keyix] == NULL)
1397 continue;
1398 kc = lsta->kc[keyix];
1399
1400 #ifdef LINUXKPI_DEBUG_80211
1401 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1402 ic_printf(lsta->ni->ni_ic, "%d %lu %s: running set_key cmd %d(%s) for "
1403 "sta %6D: keyidx %u hw_key_idx %u flags %b\n",
1404 curthread->td_tid, jiffies, __func__,
1405 DISABLE_KEY, "DISABLE", lsta->sta.addr, ":",
1406 kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS);
1407 #endif
1408
1409 err = lkpi_80211_mo_set_key(hw, DISABLE_KEY, vif,
1410 LSTA_TO_STA(lsta), kc);
1411 if (err != 0) {
1412 ic_printf(lsta->ni->ni_ic, "%d %lu %s: set_key cmd %d(%s) for "
1413 "sta %6D failed: %d\n", curthread->td_tid, jiffies, __func__,
1414 DISABLE_KEY, "DISABLE", lsta->sta.addr, ":", err);
1415 error++;
1416
1417 /*
1418 * If we free the key here we will never be able to get it
1419 * removed from the driver/fw which will likely make us
1420 * crash (firmware).
1421 */
1422 continue;
1423 }
1424 #ifdef LINUXKPI_DEBUG_80211
1425 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1426 ic_printf(lsta->ni->ni_ic, "%d %lu %s: set_key cmd %d(%s) for "
1427 "sta %6D succeeded: keyidx %u hw_key_idx %u flags %b\n",
1428 curthread->td_tid, jiffies, __func__,
1429 DISABLE_KEY, "DISABLE", lsta->sta.addr, ":",
1430 kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS);
1431 #endif
1432
1433 lsta->kc[keyix] = NULL;
1434 free(kc, M_LKPI80211);
1435 }
1436 ieee80211_free_node(lsta->ni);
1437 return (error);
1438 }
1439
1440 /* XXX-BZ one day we should replace this iterating over VIFs, or node list? */
1441 /* See also lkpi_sta_del_keys() these days. */
1442 static int
lkpi_iv_key_delete(struct ieee80211vap * vap,const struct ieee80211_key * k)1443 lkpi_iv_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
1444 {
1445 struct ieee80211com *ic;
1446 struct lkpi_hw *lhw;
1447 struct ieee80211_hw *hw;
1448 struct lkpi_vif *lvif;
1449 struct lkpi_sta *lsta;
1450 struct ieee80211_vif *vif;
1451 struct ieee80211_sta *sta;
1452 struct ieee80211_node *ni;
1453 struct ieee80211_key_conf *kc;
1454 int error;
1455
1456 ic = vap->iv_ic;
1457 lhw = ic->ic_softc;
1458 hw = LHW_TO_HW(lhw);
1459 lvif = VAP_TO_LVIF(vap);
1460 vif = LVIF_TO_VIF(lvif);
1461
1462 /*
1463 * Make sure we do not make it here without going through
1464 * lkpi_iv_key_update_begin() first.
1465 */
1466 lockdep_assert_wiphy(hw->wiphy);
1467
1468 ni = ieee80211_ref_node(vap->iv_bss);
1469 lsta = ni->ni_drv_data;
1470 if (lsta == NULL) {
1471 ic_printf(ic, "%s: ni %p (%6D) with lsta NULL\n",
1472 __func__, ni, ni->ni_bssid, ":");
1473 ieee80211_free_node(ni);
1474 return (0);
1475 }
1476
1477 /*
1478 * While we are assoc we may still send packets. We cannot delete the
1479 * keys as otherwise packets could go out unencrypted. Some firmware
1480 * does not like this and will fire an assert.
1481 * net80211 needs to drive this better but given we want the disassoc
1482 * frame out and have to unlock we are open to a race currently.
1483 * This check should prevent problems.
1484 * How to test: run 800Mbit/s UDP traffic and during that restart your
1485 * supplicant. You want to survive that.
1486 */
1487 if (vif->cfg.assoc && lsta->state == IEEE80211_STA_AUTHORIZED) {
1488 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1489 ic_printf(ic, "%d %lu %s: vif still assoc; not deleting keys\n",
1490 curthread->td_tid, jiffies, __func__);
1491 ieee80211_free_node(ni);
1492 return (0);
1493 }
1494
1495 if (IEEE80211_KEY_UNDEFINED(k)) {
1496 ic_printf(ic, "%s: vap %p key %p is undefined: %p %u\n",
1497 __func__, vap, k, k->wk_cipher, k->wk_keyix);
1498 ieee80211_free_node(ni);
1499 return (0);
1500 }
1501
1502 if (vap->iv_bss == NULL) {
1503 ic_printf(ic, "%s: iv_bss %p for vap %p is NULL\n",
1504 __func__, vap->iv_bss, vap);
1505 ieee80211_free_node(ni);
1506 return (0);
1507 }
1508 sta = LSTA_TO_STA(lsta);
1509
1510 if (lsta->kc[k->wk_keyix] == NULL) {
1511 #ifdef LINUXKPI_DEBUG_80211
1512 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1513 ic_printf(ic, "%d %lu %s: sta %6D and no key information, "
1514 "keyidx %u wk_macaddr %6D; returning success\n",
1515 curthread->td_tid, jiffies, __func__, sta->addr, ":",
1516 k->wk_keyix, k->wk_macaddr, ":");
1517 #endif
1518 ieee80211_free_node(ni);
1519 return (1);
1520 }
1521 kc = lsta->kc[k->wk_keyix];
1522
1523 #ifdef LINUXKPI_DEBUG_80211
1524 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1525 ic_printf(ic, "%d %lu %s: running set_key cmd %d(%s) for sta %6D: "
1526 "keyidx %u hw_key_idx %u flags %b\n",
1527 curthread->td_tid, jiffies, __func__,
1528 DISABLE_KEY, "DISABLE", sta->addr, ":",
1529 kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS);
1530 #endif
1531
1532 error = lkpi_80211_mo_set_key(hw, DISABLE_KEY, vif, sta, kc);
1533 if (error != 0) {
1534 ic_printf(ic, "%d %lu %s: set_key cmd %d(%s) for sta %6D failed: %d\n",
1535 curthread->td_tid, jiffies, __func__,
1536 DISABLE_KEY, "DISABLE", sta->addr, ":", error);
1537 error = 0;
1538 goto out;
1539 }
1540
1541 #ifdef LINUXKPI_DEBUG_80211
1542 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1543 ic_printf(ic, "%d %lu %s: set_key cmd %d(%s) for sta %6D succeeded: "
1544 "keyidx %u hw_key_idx %u flags %b\n",
1545 curthread->td_tid, jiffies, __func__,
1546 DISABLE_KEY, "DISABLE", sta->addr, ":",
1547 kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS);
1548 #endif
1549 lsta->kc[k->wk_keyix] = NULL;
1550 free(kc, M_LKPI80211);
1551 error = 1;
1552 out:
1553 ieee80211_free_node(ni);
1554 return (error);
1555 }
1556
1557 static int
lkpi_iv_key_set(struct ieee80211vap * vap,const struct ieee80211_key * k)1558 lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
1559 {
1560 struct ieee80211com *ic;
1561 struct lkpi_hw *lhw;
1562 struct ieee80211_hw *hw;
1563 struct lkpi_vif *lvif;
1564 struct lkpi_sta *lsta;
1565 struct ieee80211_vif *vif;
1566 struct ieee80211_sta *sta;
1567 struct ieee80211_node *ni;
1568 struct ieee80211_key_conf *kc;
1569 uint32_t lcipher;
1570 uint16_t exp_flags;
1571 uint8_t keylen;
1572 int error;
1573
1574 ic = vap->iv_ic;
1575 lhw = ic->ic_softc;
1576 hw = LHW_TO_HW(lhw);
1577
1578 /*
1579 * Make sure we do not make it here without going through
1580 * lkpi_iv_key_update_begin() first.
1581 */
1582 lockdep_assert_wiphy(hw->wiphy);
1583
1584 if (IEEE80211_KEY_UNDEFINED(k)) {
1585 ic_printf(ic, "%s: vap %p key %p is undefined: %p %u\n",
1586 __func__, vap, k, k->wk_cipher, k->wk_keyix);
1587 return (0);
1588 }
1589
1590 if (vap->iv_bss == NULL) {
1591 ic_printf(ic, "%s: iv_bss %p for vap %p is NULL\n",
1592 __func__, vap->iv_bss, vap);
1593 return (0);
1594 }
1595 ni = ieee80211_ref_node(vap->iv_bss);
1596 lsta = ni->ni_drv_data;
1597 if (lsta == NULL) {
1598 ic_printf(ic, "%s: ni %p (%6D) with lsta NULL\n",
1599 __func__, ni, ni->ni_bssid, ":");
1600 ieee80211_free_node(ni);
1601 return (0);
1602 }
1603 sta = LSTA_TO_STA(lsta);
1604
1605 keylen = k->wk_keylen;
1606 lcipher = lkpi_net80211_to_l80211_cipher_suite(
1607 k->wk_cipher->ic_cipher, k->wk_keylen);
1608 switch (lcipher) {
1609 case WLAN_CIPHER_SUITE_TKIP:
1610 keylen += 2 * k->wk_cipher->ic_miclen;
1611 break;
1612 case WLAN_CIPHER_SUITE_CCMP:
1613 case WLAN_CIPHER_SUITE_GCMP:
1614 break;
1615 default:
1616 ic_printf(ic, "%s: CIPHER SUITE %#x (%s) not supported\n",
1617 __func__, lcipher, lkpi_cipher_suite_to_name(lcipher));
1618 IMPROVE();
1619 ieee80211_free_node(ni);
1620 return (0);
1621 }
1622
1623 if (lsta->kc[k->wk_keyix] != NULL) {
1624 IMPROVE("Still in firmware? Del first. Can we assert this cannot happen?");
1625 ic_printf(ic, "%s: sta %6D found with key information\n",
1626 __func__, sta->addr, ":");
1627 kc = lsta->kc[k->wk_keyix];
1628 lsta->kc[k->wk_keyix] = NULL;
1629 free(kc, M_LKPI80211);
1630 kc = NULL; /* safeguard */
1631 }
1632
1633 kc = malloc(sizeof(*kc) + keylen, M_LKPI80211, M_WAITOK | M_ZERO);
1634 kc->_k = k; /* Save the pointer to net80211. */
1635 kc->cipher = lcipher;
1636 kc->keyidx = k->wk_keyix;
1637 #if 0
1638 kc->hw_key_idx = /* set by hw and needs to be passed for TX */;
1639 #endif
1640 atomic64_set(&kc->tx_pn, k->wk_keytsc);
1641 kc->keylen = k->wk_keylen;
1642 memcpy(kc->key, k->wk_key, k->wk_keylen);
1643
1644 if (k->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV))
1645 kc->flags |= IEEE80211_KEY_FLAG_PAIRWISE;
1646 if (k->wk_flags & IEEE80211_KEY_GROUP)
1647 kc->flags &= ~IEEE80211_KEY_FLAG_PAIRWISE;
1648
1649 kc->iv_len = k->wk_cipher->ic_header;
1650 kc->icv_len = k->wk_cipher->ic_trailer;
1651
1652 switch (kc->cipher) {
1653 case WLAN_CIPHER_SUITE_TKIP:
1654 memcpy(kc->key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY, k->wk_txmic, k->wk_cipher->ic_miclen);
1655 memcpy(kc->key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, k->wk_rxmic, k->wk_cipher->ic_miclen);
1656 break;
1657 case WLAN_CIPHER_SUITE_CCMP:
1658 case WLAN_CIPHER_SUITE_GCMP:
1659 break;
1660 default:
1661 /* currently UNREACH */
1662 IMPROVE();
1663 break;
1664 };
1665 lsta->kc[k->wk_keyix] = kc;
1666
1667 #ifdef LINUXKPI_DEBUG_80211
1668 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1669 ic_printf(ic, "%d %lu %s: running set_key cmd %d(%s) for sta %6D: "
1670 "kc %p keyidx %u hw_key_idx %u keylen %u flags %b\n",
1671 curthread->td_tid, jiffies, __func__,
1672 SET_KEY, "SET", sta->addr, ":", kc, kc->keyidx, kc->hw_key_idx,
1673 kc->keylen, kc->flags, IEEE80211_KEY_FLAG_BITS);
1674 #endif
1675
1676 lvif = VAP_TO_LVIF(vap);
1677 vif = LVIF_TO_VIF(lvif);
1678 error = lkpi_80211_mo_set_key(hw, SET_KEY, vif, sta, kc);
1679 if (error != 0) {
1680 ic_printf(ic, "%d %lu %s: set_key cmd %d(%s) for sta %6D failed: %d\n",
1681 curthread->td_tid, jiffies, __func__,
1682 SET_KEY, "SET", sta->addr, ":", error);
1683 lsta->kc[k->wk_keyix] = NULL;
1684 free(kc, M_LKPI80211);
1685 ieee80211_free_node(ni);
1686 return (0);
1687 }
1688
1689 #ifdef LINUXKPI_DEBUG_80211
1690 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1691 ic_printf(ic, "%d %lu %s: set_key cmd %d(%s) for sta %6D succeeded: "
1692 "kc %p keyidx %u hw_key_idx %u flags %b\n",
1693 curthread->td_tid, jiffies, __func__,
1694 SET_KEY, "SET", sta->addr, ":",
1695 kc, kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS);
1696 #endif
1697
1698 exp_flags = 0;
1699 switch (kc->cipher) {
1700 case WLAN_CIPHER_SUITE_TKIP:
1701 exp_flags = (IEEE80211_KEY_FLAG_PAIRWISE |
1702 IEEE80211_KEY_FLAG_PUT_IV_SPACE |
1703 IEEE80211_KEY_FLAG_GENERATE_MMIC |
1704 IEEE80211_KEY_FLAG_PUT_MIC_SPACE);
1705 #define TKIP_INVAL_COMBINATION \
1706 (IEEE80211_KEY_FLAG_PUT_MIC_SPACE|IEEE80211_KEY_FLAG_GENERATE_MMIC)
1707 if ((kc->flags & TKIP_INVAL_COMBINATION) == TKIP_INVAL_COMBINATION) {
1708 ic_printf(ic, "%s: SET_KEY for %s returned invalid "
1709 "combination %b\n", __func__,
1710 lkpi_cipher_suite_to_name(kc->cipher),
1711 kc->flags, IEEE80211_KEY_FLAG_BITS);
1712 }
1713 #undef TKIP_INVAL_COMBINATION
1714 #ifdef __notyet__
1715 /* Do flags surgery; special see linuxkpi_ieee80211_ifattach(). */
1716 if ((kc->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) != 0) {
1717 k->wk_flags &= ~(IEEE80211_KEY_NOMICMGT|IEEE80211_KEY_NOMIC);
1718 k->wk_flags |= IEEE80211_KEY_SWMIC;
1719 ic->ic_cryptocaps &= ~IEEE80211_CRYPTO_TKIPMIC
1720 }
1721 #endif
1722 break;
1723 case WLAN_CIPHER_SUITE_CCMP:
1724 case WLAN_CIPHER_SUITE_GCMP:
1725 exp_flags = (IEEE80211_KEY_FLAG_PAIRWISE |
1726 IEEE80211_KEY_FLAG_PUT_IV_SPACE |
1727 IEEE80211_KEY_FLAG_GENERATE_IV |
1728 IEEE80211_KEY_FLAG_GENERATE_IV_MGMT | /* Only needs IV geeration for MGMT frames. */
1729 IEEE80211_KEY_FLAG_SW_MGMT_TX); /* MFP in software */
1730 break;
1731 }
1732 if ((kc->flags & ~exp_flags) != 0)
1733 ic_printf(ic, "%s: SET_KEY for %s returned unexpected key flags: "
1734 " %#06x & ~%#06x = %b\n", __func__,
1735 lkpi_cipher_suite_to_name(kc->cipher), kc->flags, exp_flags,
1736 (kc->flags & ~exp_flags), IEEE80211_KEY_FLAG_BITS);
1737
1738 #ifdef __notyet__
1739 /* Do flags surgery. */
1740 if ((kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) == 0)
1741 k->wk_flags |= IEEE80211_KEY_NOIVMGT;
1742 if ((kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV) == 0)
1743 k->wk_flags |= IEEE80211_KEY_NOIV;
1744 #endif
1745
1746 ieee80211_free_node(ni);
1747 return (1);
1748 }
1749
1750 static void
lkpi_iv_key_update_begin(struct ieee80211vap * vap)1751 lkpi_iv_key_update_begin(struct ieee80211vap *vap)
1752 {
1753 struct ieee80211_node_table *nt;
1754 struct ieee80211com *ic;
1755 struct lkpi_hw *lhw;
1756 struct ieee80211_hw *hw;
1757 struct lkpi_vif *lvif;
1758 struct ieee80211_node *ni;
1759 bool icislocked, ntislocked;
1760
1761 ic = vap->iv_ic;
1762 lhw = ic->ic_softc;
1763 hw = LHW_TO_HW(lhw);
1764 lvif = VAP_TO_LVIF(vap);
1765 nt = &ic->ic_sta;
1766
1767 icislocked = IEEE80211_IS_LOCKED(ic);
1768 ntislocked = IEEE80211_NODE_IS_LOCKED(nt);
1769
1770 #ifdef LINUXKPI_DEBUG_80211
1771 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1772 ic_printf(ic, "%d %lu %s: vap %p ic %p %slocked nt %p %slocked "
1773 "lvif ic_unlocked %d nt_unlocked %d\n",
1774 curthread->td_tid, jiffies, __func__, vap,
1775 ic, icislocked ? "" : "un", nt, ntislocked ? "" : "un",
1776 lvif->ic_unlocked, lvif->nt_unlocked);
1777 #endif
1778
1779 /*
1780 * This is inconsistent net80211 locking to be fixed one day.
1781 */
1782 /* Try to make sure the node does not go away while possibly unlocked. */
1783 ni = NULL;
1784 if (icislocked || ntislocked) {
1785 if (vap->iv_bss != NULL)
1786 ni = ieee80211_ref_node(vap->iv_bss);
1787 }
1788
1789 if (icislocked)
1790 IEEE80211_UNLOCK(ic);
1791 if (ntislocked)
1792 IEEE80211_NODE_UNLOCK(nt);
1793
1794 wiphy_lock(hw->wiphy);
1795
1796 KASSERT(lvif->key_update_iv_bss == NULL, ("%s: key_update_iv_bss not NULL %p",
1797 __func__, lvif->key_update_iv_bss));
1798 lvif->key_update_iv_bss = ni;
1799
1800 /*
1801 * ic/nt_unlocked could be a bool given we are under the lock and there
1802 * must only be a single thread.
1803 * In case anything in the future disturbs the order the refcnt will
1804 * help us catching problems a lot easier.
1805 */
1806 if (icislocked)
1807 refcount_acquire(&lvif->ic_unlocked);
1808 if (ntislocked)
1809 refcount_acquire(&lvif->nt_unlocked);
1810
1811 /*
1812 * Stop the queues while doing key updates.
1813 */
1814 ieee80211_stop_queues(hw);
1815 }
1816
1817 static void
lkpi_iv_key_update_end(struct ieee80211vap * vap)1818 lkpi_iv_key_update_end(struct ieee80211vap *vap)
1819 {
1820 struct ieee80211_node_table *nt;
1821 struct ieee80211com *ic;
1822 struct lkpi_hw *lhw;
1823 struct ieee80211_hw *hw;
1824 struct lkpi_vif *lvif;
1825 bool icislocked, ntislocked;
1826
1827 ic = vap->iv_ic;
1828 lhw = ic->ic_softc;
1829 hw = LHW_TO_HW(lhw);
1830 lvif = VAP_TO_LVIF(vap);
1831 nt = &ic->ic_sta;
1832
1833 /*
1834 * Re-enabled the queues after the key update.
1835 */
1836 lkpi_ieee80211_wake_queues_locked(hw);
1837
1838 icislocked = IEEE80211_IS_LOCKED(ic);
1839 MPASS(!icislocked);
1840 ntislocked = IEEE80211_NODE_IS_LOCKED(nt);
1841 MPASS(!ntislocked);
1842
1843 #ifdef LINUXKPI_DEBUG_80211
1844 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1845 ic_printf(ic, "%d %lu %s: vap %p ic %p %slocked nt %p %slocked "
1846 "lvif ic_unlocked %d nt_unlocked %d\n",
1847 curthread->td_tid, jiffies, __func__, vap,
1848 ic, icislocked ? "" : "un", nt, ntislocked ? "" : "un",
1849 lvif->ic_unlocked, lvif->nt_unlocked);
1850 #endif
1851
1852 /*
1853 * Check under lock; see comment in lkpi_iv_key_update_begin().
1854 * In case the refcnt gets out of sync locking in net80211 will
1855 * quickly barf as well (trying to unlock a lock not held).
1856 */
1857 icislocked = refcount_release_if_last(&lvif->ic_unlocked);
1858 ntislocked = refcount_release_if_last(&lvif->nt_unlocked);
1859
1860 if (lvif->key_update_iv_bss != NULL) {
1861 ieee80211_free_node(lvif->key_update_iv_bss);
1862 lvif->key_update_iv_bss = NULL;
1863 }
1864
1865 wiphy_unlock(hw->wiphy);
1866
1867 /*
1868 * This is inconsistent net80211 locking to be fixed one day.
1869 * ic before nt to avoid a LOR.
1870 */
1871 if (icislocked)
1872 IEEE80211_LOCK(ic);
1873 if (ntislocked)
1874 IEEE80211_NODE_LOCK(nt);
1875 }
1876 #endif
1877
1878 static void
lkpi_cleanup_mcast_list_locked(struct lkpi_hw * lhw)1879 lkpi_cleanup_mcast_list_locked(struct lkpi_hw *lhw)
1880 {
1881 struct list_head *le, *next;
1882 struct netdev_hw_addr *addr;
1883
1884 if (lhw->mc_list.count != 0) {
1885 list_for_each_safe(le, next, &lhw->mc_list.addr_list) {
1886 addr = list_entry(le, struct netdev_hw_addr, addr_list);
1887 list_del(le);
1888 lhw->mc_list.count--;
1889 free(addr, M_LKPI80211);
1890 }
1891 }
1892 KASSERT(lhw->mc_list.count == 0, ("%s: mc_list %p count %d != 0\n",
1893 __func__, &lhw->mc_list, lhw->mc_list.count));
1894 }
1895
1896 static u_int
lkpi_ic_update_mcast_copy(void * arg,struct sockaddr_dl * sdl,u_int cnt)1897 lkpi_ic_update_mcast_copy(void *arg, struct sockaddr_dl *sdl, u_int cnt)
1898 {
1899 struct netdev_hw_addr_list *mc_list;
1900 struct netdev_hw_addr *addr;
1901
1902 KASSERT(arg != NULL && sdl != NULL, ("%s: arg %p sdl %p cnt %u\n",
1903 __func__, arg, sdl, cnt));
1904
1905 mc_list = arg;
1906 /* If it is on the list already skip it. */
1907 netdev_hw_addr_list_for_each(addr, mc_list) {
1908 if (!memcmp(addr->addr, LLADDR(sdl), sdl->sdl_alen))
1909 return (0);
1910 }
1911
1912 addr = malloc(sizeof(*addr), M_LKPI80211, M_NOWAIT | M_ZERO);
1913 if (addr == NULL)
1914 return (0);
1915
1916 INIT_LIST_HEAD(&addr->addr_list);
1917 memcpy(addr->addr, LLADDR(sdl), sdl->sdl_alen);
1918 /* XXX this should be a netdev function? */
1919 list_add(&addr->addr_list, &mc_list->addr_list);
1920 mc_list->count++;
1921
1922 #ifdef LINUXKPI_DEBUG_80211
1923 if (linuxkpi_debug_80211 & D80211_TRACE)
1924 printf("%s:%d: mc_list count %d: added %6D\n",
1925 __func__, __LINE__, mc_list->count, addr->addr, ":");
1926 #endif
1927
1928 return (1);
1929 }
1930
1931 static void
lkpi_update_mcast_filter(struct ieee80211com * ic)1932 lkpi_update_mcast_filter(struct ieee80211com *ic)
1933 {
1934 struct lkpi_hw *lhw;
1935 struct ieee80211_hw *hw;
1936 u64 mc;
1937 unsigned int changed_flags, flags;
1938 bool scanning;
1939
1940 lhw = ic->ic_softc;
1941
1942 LKPI_80211_LHW_SCAN_LOCK(lhw);
1943 scanning = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
1944 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
1945
1946 LKPI_80211_LHW_MC_LOCK(lhw);
1947
1948 flags = 0;
1949 if (scanning)
1950 flags |= FIF_BCN_PRBRESP_PROMISC;
1951 /* The latter condition may not be as expected but seems wise. */
1952 if (lhw->mc_all_multi || lhw->ops->prepare_multicast == NULL)
1953 flags |= FIF_ALLMULTI;
1954
1955 hw = LHW_TO_HW(lhw);
1956 mc = lkpi_80211_mo_prepare_multicast(hw, &lhw->mc_list);
1957
1958 changed_flags = (lhw->mc_flags ^ flags) & FIF_FLAGS_MASK;
1959 lkpi_80211_mo_configure_filter(hw, changed_flags, &flags, mc);
1960 lhw->mc_flags = flags;
1961
1962 #ifdef LINUXKPI_DEBUG_80211
1963 if (linuxkpi_debug_80211 & D80211_TRACE)
1964 printf("%s: changed_flags %#06x count %d mc_flags %#010x\n",
1965 __func__, changed_flags, lhw->mc_list.count, lhw->mc_flags);
1966 #endif
1967
1968 LKPI_80211_LHW_MC_UNLOCK(lhw);
1969 }
1970
1971 static enum ieee80211_bss_changed
lkpi_update_dtim_tsf(struct ieee80211_vif * vif,struct ieee80211_node * ni,struct ieee80211vap * vap,const char * _f,int _l)1972 lkpi_update_dtim_tsf(struct ieee80211_vif *vif, struct ieee80211_node *ni,
1973 struct ieee80211vap *vap, const char *_f, int _l)
1974 {
1975 enum ieee80211_bss_changed bss_changed;
1976
1977 bss_changed = 0;
1978
1979 #ifdef LINUXKPI_DEBUG_80211
1980 if (linuxkpi_debug_80211 & D80211_TRACE)
1981 printf("%s:%d [%s:%d] assoc %d aid %d beacon_int %u "
1982 "dtim_period %u sync_dtim_count %u sync_tsf %ju "
1983 "sync_device_ts %u bss_changed %#010jx\n",
1984 __func__, __LINE__, _f, _l,
1985 vif->cfg.assoc, vif->cfg.aid,
1986 vif->bss_conf.beacon_int, vif->bss_conf.dtim_period,
1987 vif->bss_conf.sync_dtim_count,
1988 (uintmax_t)vif->bss_conf.sync_tsf,
1989 vif->bss_conf.sync_device_ts,
1990 (uintmax_t)bss_changed);
1991 #endif
1992
1993 if (vif->bss_conf.beacon_int != ni->ni_intval) {
1994 vif->bss_conf.beacon_int = ni->ni_intval;
1995 /* iwlwifi FW bug workaround; iwl_mvm_mac_sta_state. */
1996 if (vif->bss_conf.beacon_int < 16)
1997 vif->bss_conf.beacon_int = 16;
1998 bss_changed |= BSS_CHANGED_BEACON_INT;
1999 }
2000
2001 /*
2002 * lkpi_iv_sta_recv_mgmt() will directly call into this function.
2003 * iwlwifi(4) in iwl_mvm_bss_info_changed_station_common() will
2004 * stop seesion protection the moment it sees
2005 * BSS_CHANGED_BEACON_INFO (with the expectations that it was
2006 * "a beacon from the associated AP"). It will also update
2007 * the beacon filter in that case. This is the only place
2008 * we set the BSS_CHANGED_BEACON_INFO on the non-teardown
2009 * path so make sure we only do run this check once we are
2010 * assoc. (*iv_recv_mgmt)() will be called before we enter
2011 * here so the ni will be updated with information from the
2012 * beacon via net80211::sta_recv_mgmt(). We also need to
2013 * make sure we do not do it on every beacon we still may
2014 * get so only do if something changed. vif->bss_conf.dtim_period
2015 * should be 0 as we start up (we also reset it on teardown).
2016 *
2017 * If we are assoc we need to make sure dtim_period is non-0.
2018 * 0 is a reserved value and drivers assume they can DIV by it.
2019 * In theory this means we need to wait for the first beacon
2020 * before we finalize the vif being assoc. In practise that
2021 * is harder until net80211 learns how to. Work around like
2022 * this for the moment.
2023 */
2024 if (vif->cfg.assoc) {
2025 if (vif->bss_conf.dtim_period != ni->ni_dtim_period &&
2026 ni->ni_dtim_period > 0) {
2027 vif->bss_conf.dtim_period = ni->ni_dtim_period;
2028 bss_changed |= BSS_CHANGED_BEACON_INFO;
2029 } else if (vif->bss_conf.dtim_period == 0) {
2030 vif->bss_conf.dtim_period = 1;
2031 bss_changed |= BSS_CHANGED_BEACON_INFO;
2032 }
2033 }
2034
2035 vif->bss_conf.sync_dtim_count = ni->ni_dtim_count;
2036 vif->bss_conf.sync_tsf = le64toh(ni->ni_tstamp.tsf);
2037 /* vif->bss_conf.sync_device_ts = set in linuxkpi_ieee80211_rx. */
2038
2039 #ifdef LINUXKPI_DEBUG_80211
2040 if (linuxkpi_debug_80211 & D80211_TRACE)
2041 printf("%s:%d [%s:%d] assoc %d aid %d beacon_int %u "
2042 "dtim_period %u sync_dtim_count %u sync_tsf %ju "
2043 "sync_device_ts %u bss_changed %#010jx\n",
2044 __func__, __LINE__, _f, _l,
2045 vif->cfg.assoc, vif->cfg.aid,
2046 vif->bss_conf.beacon_int, vif->bss_conf.dtim_period,
2047 vif->bss_conf.sync_dtim_count,
2048 (uintmax_t)vif->bss_conf.sync_tsf,
2049 vif->bss_conf.sync_device_ts,
2050 (uintmax_t)bss_changed);
2051 #endif
2052
2053 return (bss_changed);
2054 }
2055
2056 static void
lkpi_stop_hw_scan(struct lkpi_hw * lhw,struct ieee80211_vif * vif)2057 lkpi_stop_hw_scan(struct lkpi_hw *lhw, struct ieee80211_vif *vif)
2058 {
2059 struct ieee80211_hw *hw;
2060 int error;
2061 bool cancel;
2062
2063 TRACE_SCAN(lhw->ic, "scan_flags %b", lhw->scan_flags, LKPI_LHW_SCAN_BITS);
2064
2065 LKPI_80211_LHW_SCAN_LOCK(lhw);
2066 cancel = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
2067 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
2068 if (!cancel)
2069 return;
2070
2071 hw = LHW_TO_HW(lhw);
2072
2073 IEEE80211_UNLOCK(lhw->ic);
2074 wiphy_lock(hw->wiphy);
2075 /* Need to cancel the scan. */
2076 lkpi_80211_mo_cancel_hw_scan(hw, vif);
2077 wiphy_unlock(hw->wiphy);
2078
2079 /* Need to make sure we see ieee80211_scan_completed. */
2080 LKPI_80211_LHW_SCAN_LOCK(lhw);
2081 if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0)
2082 error = msleep(lhw, &lhw->scan_mtx, 0, "lhwscanstop", hz/2);
2083 cancel = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
2084 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
2085
2086 IEEE80211_LOCK(lhw->ic);
2087
2088 if (cancel)
2089 ic_printf(lhw->ic, "%s: failed to cancel scan: %d (%p, %p)\n",
2090 __func__, error, lhw, vif);
2091 }
2092
2093 static void
lkpi_hw_conf_idle(struct ieee80211_hw * hw,bool new)2094 lkpi_hw_conf_idle(struct ieee80211_hw *hw, bool new)
2095 {
2096 struct lkpi_hw *lhw;
2097 int error;
2098 bool old;
2099
2100 old = hw->conf.flags & IEEE80211_CONF_IDLE;
2101 if (old == new)
2102 return;
2103
2104 hw->conf.flags ^= IEEE80211_CONF_IDLE;
2105 error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_IDLE);
2106 if (error != 0 && error != EOPNOTSUPP) {
2107 lhw = HW_TO_LHW(hw);
2108 ic_printf(lhw->ic, "ERROR: %s: config %#0x returned %d\n",
2109 __func__, IEEE80211_CONF_CHANGE_IDLE, error);
2110 }
2111 }
2112
2113 static enum ieee80211_bss_changed
lkpi_disassoc(struct ieee80211_sta * sta,struct ieee80211_vif * vif,struct lkpi_hw * lhw)2114 lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
2115 struct lkpi_hw *lhw)
2116 {
2117 enum ieee80211_bss_changed changed;
2118 struct lkpi_vif *lvif;
2119
2120 changed = 0;
2121 sta->aid = 0;
2122 if (vif->cfg.assoc) {
2123
2124 vif->cfg.assoc = false;
2125 vif->cfg.aid = 0;
2126 changed |= BSS_CHANGED_ASSOC;
2127 IMPROVE();
2128
2129 lkpi_update_mcast_filter(lhw->ic);
2130
2131 /*
2132 * Executing the bss_info_changed(BSS_CHANGED_ASSOC) with
2133 * assoc = false right away here will remove the sta from
2134 * firmware for iwlwifi.
2135 * We no longer do this but only return the BSS_CHNAGED value.
2136 * The caller is responsible for removing the sta gong to
2137 * IEEE80211_STA_NOTEXIST and then executing the
2138 * bss_info_changed() update.
2139 * See DOWN4 for more detailed comment.
2140 */
2141
2142 lvif = VIF_TO_LVIF(vif);
2143 lvif->beacons = 0;
2144 }
2145
2146 return (changed);
2147 }
2148
2149 static void
lkpi_wake_tx_queues(struct ieee80211_hw * hw,struct ieee80211_sta * sta,bool dequeue_seen,bool no_emptyq)2150 lkpi_wake_tx_queues(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
2151 bool dequeue_seen, bool no_emptyq)
2152 {
2153 struct lkpi_txq *ltxq;
2154 int tid;
2155 bool ltxq_empty;
2156
2157 /* Wake up all queues to know they are allocated in the driver. */
2158 for (tid = 0; tid < nitems(sta->txq); tid++) {
2159
2160 if (tid == IEEE80211_NUM_TIDS) {
2161 IMPROVE("station specific?");
2162 if (!ieee80211_hw_check(hw, STA_MMPDU_TXQ))
2163 continue;
2164 } else if (tid >= hw->queues)
2165 continue;
2166
2167 if (sta->txq[tid] == NULL)
2168 continue;
2169
2170 ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
2171 if (dequeue_seen && !ltxq->seen_dequeue)
2172 continue;
2173
2174 LKPI_80211_LTXQ_LOCK(ltxq);
2175 ltxq_empty = skb_queue_empty(<xq->skbq);
2176 LKPI_80211_LTXQ_UNLOCK(ltxq);
2177 if (no_emptyq && ltxq_empty)
2178 continue;
2179
2180 lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid], false);
2181 }
2182 }
2183
2184 /*
2185 * On the way down from RUN -> ASSOC -> AUTH we may send a DISASSOC or DEAUTH
2186 * packet. The problem is that the state machine functions tend to hold the
2187 * LHW lock which will prevent lkpi_80211_txq_tx_one() from sending the packet.
2188 * We call this after dropping the ic lock and before acquiring the LHW lock.
2189 * we make sure no further packets are queued and if they are queued the task
2190 * will finish or be cancelled. At the end if a packet is left we manually
2191 * send it. scan_to_auth() would re-enable sending if the lsta would be
2192 * re-used.
2193 */
2194 static void
lkpi_80211_flush_tx(struct lkpi_hw * lhw,struct lkpi_sta * lsta)2195 lkpi_80211_flush_tx(struct lkpi_hw *lhw, struct lkpi_sta *lsta)
2196 {
2197 struct ieee80211_hw *hw;
2198 struct mbufq mq;
2199 struct mbuf *m;
2200 int len;
2201
2202 /* There is no lockdep_assert_not_held_wiphy(). */
2203 hw = LHW_TO_HW(lhw);
2204 lockdep_assert_not_held(&hw->wiphy->mtx);
2205
2206 /* Do not accept any new packets until scan_to_auth or lsta_free(). */
2207 LKPI_80211_LSTA_TXQ_LOCK(lsta);
2208 lsta->txq_ready = false;
2209 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
2210
2211 while (taskqueue_cancel(taskqueue_thread, &lsta->txq_task, NULL) != 0)
2212 taskqueue_drain(taskqueue_thread, &lsta->txq_task);
2213
2214 LKPI_80211_LSTA_TXQ_LOCK(lsta);
2215 len = mbufq_len(&lsta->txq);
2216 if (len <= 0) {
2217 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
2218 return;
2219 }
2220
2221 mbufq_init(&mq, IFQ_MAXLEN);
2222 mbufq_concat(&mq, &lsta->txq);
2223 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
2224
2225 m = mbufq_dequeue(&mq);
2226 while (m != NULL) {
2227 lkpi_80211_txq_tx_one(lsta, m);
2228 m = mbufq_dequeue(&mq);
2229 }
2230 }
2231
2232 static void
lkpi_init_chandef(struct ieee80211com * ic __unused,struct cfg80211_chan_def * chandef,struct linuxkpi_ieee80211_channel * chan,struct ieee80211_channel * c,bool can_ht)2233 lkpi_init_chandef(struct ieee80211com *ic __unused,
2234 struct cfg80211_chan_def *chandef,
2235 struct linuxkpi_ieee80211_channel *chan, struct ieee80211_channel *c,
2236 bool can_ht)
2237 {
2238
2239 cfg80211_chandef_create(chandef, chan,
2240 (can_ht) ? NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
2241 chandef->center_freq1 = ieee80211_get_channel_center_freq1(c);
2242 chandef->center_freq2 = ieee80211_get_channel_center_freq2(c);
2243
2244 IMPROVE("Check ht/vht_cap from band not just chan? See lkpi_sta_sync_from_ni...");
2245 #ifdef LKPI_80211_HT
2246 if (IEEE80211_IS_CHAN_HT(c)) {
2247 if (IEEE80211_IS_CHAN_HT40(c))
2248 chandef->width = NL80211_CHAN_WIDTH_40;
2249 else
2250 chandef->width = NL80211_CHAN_WIDTH_20;
2251 }
2252 #endif
2253 #ifdef LKPI_80211_VHT
2254 if (IEEE80211_IS_CHAN_VHT_5GHZ(c)) {
2255 if (IEEE80211_IS_CHAN_VHT80P80(c))
2256 chandef->width = NL80211_CHAN_WIDTH_80P80;
2257 else if (IEEE80211_IS_CHAN_VHT160(c))
2258 chandef->width = NL80211_CHAN_WIDTH_160;
2259 else if (IEEE80211_IS_CHAN_VHT80(c))
2260 chandef->width = NL80211_CHAN_WIDTH_80;
2261 }
2262 #endif
2263
2264 #ifdef LINUXKPI_DEBUG_80211
2265 if ((linuxkpi_debug_80211 & D80211_CHANDEF) != 0)
2266 ic_printf(ic, "%s:%d: chandef %p { chan %p { %u }, "
2267 "width %d cfreq1 %u cfreq2 %u punctured %u }\n",
2268 __func__, __LINE__, chandef,
2269 chandef->chan, chandef->chan->center_freq,
2270 chandef->width,
2271 chandef->center_freq1, chandef->center_freq2,
2272 chandef->punctured);
2273 #endif
2274 }
2275
2276 static uint32_t
lkpi_init_chanctx_conf(struct ieee80211_hw * hw,struct cfg80211_chan_def * chandef,struct ieee80211_chanctx_conf * chanctx_conf)2277 lkpi_init_chanctx_conf(struct ieee80211_hw *hw,
2278 struct cfg80211_chan_def *chandef,
2279 struct ieee80211_chanctx_conf *chanctx_conf)
2280 {
2281 uint32_t changed;
2282
2283 lockdep_assert_wiphy(hw->wiphy);
2284
2285 changed = 0;
2286
2287 chanctx_conf->rx_chains_static = 1;
2288 chanctx_conf->rx_chains_dynamic = 1;
2289 changed |= IEEE80211_CHANCTX_CHANGE_RX_CHAINS;
2290
2291 if (chanctx_conf->radar_enabled != hw->conf.radar_enabled) {
2292 chanctx_conf->radar_enabled = hw->conf.radar_enabled;
2293 changed |= IEEE80211_CHANCTX_CHANGE_RADAR;
2294 }
2295
2296 chanctx_conf->def = *chandef;
2297 changed |= IEEE80211_CHANCTX_CHANGE_WIDTH;
2298
2299 /* One day we should figure this out; is for iwlwifi-only. */
2300 chanctx_conf->min_def = chanctx_conf->def;
2301 changed |= IEEE80211_CHANCTX_CHANGE_MIN_WIDTH;
2302
2303 /* chanctx_conf->ap = */
2304
2305 return (changed);
2306 }
2307
2308 static struct lkpi_chanctx *
lkpi_alloc_lchanctx(struct ieee80211_hw * hw,struct lkpi_vif * lvif)2309 lkpi_alloc_lchanctx(struct ieee80211_hw *hw, struct lkpi_vif *lvif)
2310 {
2311 struct lkpi_chanctx *lchanctx;
2312
2313 lchanctx = malloc(sizeof(*lchanctx) + hw->chanctx_data_size,
2314 M_LKPI80211, M_WAITOK | M_ZERO);
2315 lchanctx->lvif = lvif;
2316
2317 return (lchanctx);
2318 }
2319
2320 static struct lkpi_chanctx *
lkpi_find_lchanctx_reserved(struct ieee80211_hw * hw,struct lkpi_vif * lvif)2321 lkpi_find_lchanctx_reserved(struct ieee80211_hw *hw, struct lkpi_vif *lvif)
2322 {
2323 struct lkpi_hw *lhw;
2324 struct lkpi_chanctx *lchanctx;
2325 bool found;
2326
2327 lhw = HW_TO_LHW(hw);
2328
2329 found = false;
2330 rcu_read_lock();
2331 list_for_each_entry_rcu(lchanctx, &lhw->lchanctx_list_reserved, entry) {
2332 if (lchanctx->lvif == lvif) {
2333 found = true;
2334 break;
2335 }
2336 }
2337 rcu_read_unlock();
2338
2339 if (!found) {
2340 lchanctx = lkpi_alloc_lchanctx(hw, lvif);
2341 list_add_rcu(&lchanctx->entry, &lhw->lchanctx_list_reserved);
2342 }
2343
2344 return (lchanctx);
2345 }
2346
2347 static struct ieee80211_chanctx_conf *
lkpi_get_chanctx_conf(struct ieee80211_hw * hw,struct ieee80211_vif * vif)2348 lkpi_get_chanctx_conf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2349 {
2350 struct ieee80211_chanctx_conf *chanctx_conf;
2351
2352 chanctx_conf = rcu_dereference_protected(vif->bss_conf.chanctx_conf,
2353 lockdep_is_held(&hw->wiphy->mtx));
2354 if (chanctx_conf == NULL) {
2355 struct lkpi_chanctx *lchanctx;
2356 struct lkpi_vif *lvif;
2357
2358 lvif = VIF_TO_LVIF(vif);
2359 lchanctx = lkpi_find_lchanctx_reserved(hw, lvif);
2360 KASSERT(lchanctx != NULL, ("%s: hw %p, vif %p no lchanctx\n",
2361 __func__, hw, vif));
2362 list_del(&lchanctx->entry);
2363 chanctx_conf = &lchanctx->chanctx_conf;
2364 }
2365 /* else { IMPROVE("diff changes for changed, working on live copy, rcu"); } */
2366
2367 return (chanctx_conf);
2368 }
2369
2370 static int
lkpi_set_chanctx_conf(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_chanctx_conf * chanctx_conf,uint32_t changed,bool changed_set)2371 lkpi_set_chanctx_conf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2372 struct ieee80211_chanctx_conf *chanctx_conf,
2373 uint32_t changed, bool changed_set)
2374 {
2375 struct lkpi_hw *lhw;
2376 struct lkpi_chanctx *lchanctx;
2377 int error;
2378
2379 if (vif->bss_conf.chanctx_conf == chanctx_conf) {
2380 if (!changed_set) {
2381 IMPROVE("OBSOLETE?");
2382 changed = IEEE80211_CHANCTX_CHANGE_MIN_WIDTH;
2383 changed |= IEEE80211_CHANCTX_CHANGE_RADAR;
2384 changed |= IEEE80211_CHANCTX_CHANGE_RX_CHAINS;
2385 changed |= IEEE80211_CHANCTX_CHANGE_WIDTH;
2386 }
2387 lkpi_80211_mo_change_chanctx(hw, chanctx_conf, changed);
2388
2389 return (0);
2390 }
2391
2392 lhw = HW_TO_LHW(hw);
2393
2394 /* The device is no longer idle. */
2395 IMPROVE("Once we do multi-vif, only do for 1st chanctx");
2396 lkpi_hw_conf_idle(hw, false);
2397
2398 error = lkpi_80211_mo_add_chanctx(hw, chanctx_conf);
2399 if (error != 0 && error != EOPNOTSUPP) {
2400 ic_printf(lhw->ic, "%s:%d: mo_add_chanctx "
2401 "failed: %d\n", __func__, __LINE__, error);
2402 return (error);
2403 }
2404
2405 vif->bss_conf.chanreq.oper.chan = chanctx_conf->def.chan;
2406 vif->bss_conf.chanreq.oper.width = chanctx_conf->def.width;
2407 vif->bss_conf.chanreq.oper.center_freq1 =
2408 chanctx_conf->def.center_freq1;
2409 vif->bss_conf.chanreq.oper.center_freq2 =
2410 chanctx_conf->def.center_freq2;
2411
2412 lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
2413 list_add_rcu(&lchanctx->entry, &lhw->lchanctx_list);
2414 rcu_assign_pointer(vif->bss_conf.chanctx_conf, chanctx_conf);
2415
2416 /* Assign vif chanctx. */
2417 if (error == 0)
2418 error = lkpi_80211_mo_assign_vif_chanctx(hw, vif,
2419 &vif->bss_conf, chanctx_conf);
2420 if (error == EOPNOTSUPP)
2421 error = 0;
2422 if (error != 0) {
2423 ic_printf(lhw->ic, "%s:%d: mo_assign_vif_chanctx "
2424 "failed: %d\n", __func__, __LINE__, error);
2425 lkpi_80211_mo_remove_chanctx(hw, chanctx_conf);
2426 rcu_assign_pointer(vif->bss_conf.chanctx_conf, NULL);
2427 lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
2428 list_del(&lchanctx->entry);
2429 list_add_rcu(&lchanctx->entry, &lhw->lchanctx_list_reserved);
2430 }
2431
2432 return (error);
2433 }
2434
2435 static void
lkpi_remove_chanctx(struct ieee80211_hw * hw,struct ieee80211_vif * vif)2436 lkpi_remove_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2437 {
2438 struct lkpi_hw *lhw;
2439 struct ieee80211_chanctx_conf *chanctx_conf;
2440 struct lkpi_chanctx *lchanctx;
2441
2442 lockdep_assert_wiphy(hw->wiphy);
2443
2444 chanctx_conf = rcu_dereference_protected(vif->bss_conf.chanctx_conf,
2445 lockdep_is_held(&hw->wiphy->mtx));
2446
2447 if (chanctx_conf == NULL)
2448 return;
2449
2450 /* Remove vif context. */
2451 lkpi_80211_mo_unassign_vif_chanctx(hw, vif, &vif->bss_conf, chanctx_conf);
2452
2453 lkpi_hw_conf_idle(hw, true);
2454
2455 /* Remove chan ctx. */
2456 lkpi_80211_mo_remove_chanctx(hw, chanctx_conf);
2457
2458 /* Cleanup. */
2459 rcu_assign_pointer(vif->bss_conf.chanctx_conf, NULL);
2460 lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
2461 list_del(&lchanctx->entry);
2462 lhw = HW_TO_LHW(hw);
2463 list_add_rcu(&lchanctx->entry, &lhw->lchanctx_list_reserved);
2464 }
2465
2466 /* -------------------------------------------------------------------------- */
2467
2468 /* Any other options belong here? Check more drivers. */
2469 #define BSS_CHANGED_VIF_CFG_BITS \
2470 (BSS_CHANGED_SSID | BSS_CHANGED_IDLE | BSS_CHANGED_PS | BSS_CHANGED_ASSOC | \
2471 BSS_CHANGED_ARP_FILTER | BSS_CHANGED_MLD_VALID_LINKS | BSS_CHANGED_MLD_TTLM)
2472
2473 static void
lkpi_bss_info_change(struct ieee80211_hw * hw,struct ieee80211_vif * vif,enum ieee80211_bss_changed bss_changed)2474 lkpi_bss_info_change(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2475 enum ieee80211_bss_changed bss_changed)
2476 {
2477 struct lkpi_vif *lvif;
2478 enum ieee80211_bss_changed vif_cfg_bits, link_info_bits;
2479
2480 if (ieee80211_vif_is_mld(vif)) {
2481 TODO("This likely needs a subset only; split up into 3 parts.");
2482 }
2483
2484 /* Nothing to do? */
2485 if (bss_changed == 0)
2486 return;
2487
2488 /*
2489 * If the vif is not known to the driver there is nothing to notifiy for.
2490 * We MUST NOT check for !lvif_bss_synched here (the reasonable it seems)
2491 * as we need to execute the update(s) or we will have follow-up issues.
2492 */
2493 lvif = VIF_TO_LVIF(vif);
2494 if (!lvif->added_to_drv)
2495 return;
2496
2497 /*
2498 * With the advent of MLO bss_conf got split up into vif and link
2499 * change notfications, while historically it was one.
2500 * We now need to support all possible models.
2501 */
2502 vif_cfg_bits = bss_changed & BSS_CHANGED_VIF_CFG_BITS;
2503 if (vif_cfg_bits != 0)
2504 lkpi_80211_mo_vif_cfg_changed(hw, vif, vif_cfg_bits, false);
2505
2506 link_info_bits = bss_changed & ~(BSS_CHANGED_VIF_CFG_BITS);
2507 if (link_info_bits != 0)
2508 lkpi_80211_mo_link_info_changed(hw, vif, &vif->bss_conf,
2509 link_info_bits, 0, false);
2510
2511 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
2512 }
2513
2514 /* -------------------------------------------------------------------------- */
2515
2516 static int
lkpi_sta_state_do_nada(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2517 lkpi_sta_state_do_nada(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2518 {
2519 return (0);
2520 }
2521
2522 /* UP1 */
2523 static int
lkpi_sta_init_to_scan(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2524 lkpi_sta_init_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2525 {
2526 return (lkpi_sta_state_do_nada(vap, nstate, arg));
2527 }
2528
2529 /* UP2 */
2530 static int
lkpi_sta_scan_to_auth(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2531 lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2532 {
2533 struct linuxkpi_ieee80211_channel *chan;
2534 struct cfg80211_chan_def chandef;
2535 struct ieee80211_chanctx_conf *chanctx_conf;
2536 struct lkpi_hw *lhw;
2537 struct ieee80211_hw *hw;
2538 struct lkpi_vif *lvif;
2539 struct ieee80211_vif *vif;
2540 struct ieee80211_node *ni;
2541 struct lkpi_sta *lsta;
2542 enum ieee80211_bss_changed bss_changed;
2543 struct ieee80211_prep_tx_info prep_tx_info;
2544 uint32_t changed;
2545 int error;
2546 bool synched, can_ht;
2547
2548 /*
2549 * In here we use vap->iv_bss until lvif->lvif_bss is set.
2550 * For all later (STATE >= AUTH) functions we need to use the lvif
2551 * cache which will be tracked even through (*iv_update_bss)().
2552 */
2553
2554 if (vap->iv_bss == NULL) {
2555 ic_printf(vap->iv_ic, "%s: no iv_bss for vap %p\n", __func__, vap);
2556 return (EINVAL);
2557 }
2558 /*
2559 * Keep the ni alive locally. In theory (and practice) iv_bss can change
2560 * once we unlock here. This is due to net80211 allowing state changes
2561 * and new join1() despite having an active node as well as due to
2562 * the fact that the iv_bss can be swapped under the hood in (*iv_update_bss).
2563 */
2564 ni = ieee80211_ref_node(vap->iv_bss);
2565 if (ni->ni_chan == NULL || ni->ni_chan == IEEE80211_CHAN_ANYC) {
2566 ic_printf(vap->iv_ic, "%s: no channel set for iv_bss ni %p "
2567 "on vap %p\n", __func__, ni, vap);
2568 ieee80211_free_node(ni); /* Error handling for the local ni. */
2569 return (EINVAL);
2570 }
2571
2572 lhw = vap->iv_ic->ic_softc;
2573 chan = lkpi_find_lkpi80211_chan(lhw, ni->ni_chan);
2574 if (chan == NULL) {
2575 ic_printf(vap->iv_ic, "%s: failed to get LKPI channel from "
2576 "iv_bss ni %p on vap %p\n", __func__, ni, vap);
2577 ieee80211_free_node(ni); /* Error handling for the local ni. */
2578 return (ESRCH);
2579 }
2580
2581 hw = LHW_TO_HW(lhw);
2582 lvif = VAP_TO_LVIF(vap);
2583 vif = LVIF_TO_VIF(lvif);
2584
2585 LKPI_80211_LVIF_LOCK(lvif);
2586 /* XXX-BZ KASSERT later? */
2587 if (lvif->lvif_bss_synched || lvif->lvif_bss != NULL) {
2588 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2589 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2590 lvif, vap, vap->iv_bss, lvif->lvif_bss,
2591 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2592 lvif->lvif_bss_synched);
2593 LKPI_80211_LVIF_UNLOCK(lvif);
2594 ieee80211_free_node(ni); /* Error handling for the local ni. */
2595 return (EBUSY);
2596 }
2597 LKPI_80211_LVIF_UNLOCK(lvif);
2598
2599 IEEE80211_UNLOCK(vap->iv_ic);
2600 wiphy_lock(hw->wiphy);
2601
2602 /* Add chanctx (or if exists, change it). */
2603 chanctx_conf = lkpi_get_chanctx_conf(hw, vif);
2604
2605 KASSERT(ni->ni_chan != NULL && ni->ni_chan != IEEE80211_CHAN_ANYC,
2606 ("%s:%d: ni %p ni_chan %p\n", __func__, __LINE__, ni, ni->ni_chan));
2607
2608 #ifdef LKPI_80211_HT
2609 can_ht = (vap->iv_ic->ic_flags_ht & IEEE80211_FHT_HT) != 0;
2610 #else
2611 can_ht = false;
2612 #endif
2613 lkpi_init_chandef(vap->iv_ic, &chandef, chan, ni->ni_chan, can_ht);
2614 hw->conf.radar_enabled =
2615 ((chan->flags & IEEE80211_CHAN_RADAR) != 0) ? true : false;
2616 hw->conf.chandef = chandef;
2617 vif->bss_conf.chanreq.oper = hw->conf.chandef;
2618 #ifdef LINUXKPI_DEBUG_80211
2619 if ((linuxkpi_debug_80211 & D80211_CHANDEF) != 0)
2620 ic_printf(vap->iv_ic, "%s:%d: hw->conf.chandef %p = chandef %p = "
2621 "vif->bss_conf.chanreq.oper %p\n", __func__, __LINE__,
2622 &hw->conf.chandef, &chandef, &vif->bss_conf.chanreq.oper);
2623 #endif
2624
2625 changed = lkpi_init_chanctx_conf(hw, &chandef, chanctx_conf);
2626
2627 /* Responder ... */
2628
2629 /* Set bss info (bss_info_changed). */
2630 bss_changed = 0;
2631 IEEE80211_ADDR_COPY(vif->cfg.ap_addr, ni->ni_bssid);
2632 vif->bss_conf.bssid = ni->ni_bssid;
2633 bss_changed |= BSS_CHANGED_BSSID;
2634 vif->bss_conf.txpower = ni->ni_txpower;
2635 bss_changed |= BSS_CHANGED_TXPOWER;
2636 vif->cfg.idle = false;
2637 bss_changed |= BSS_CHANGED_IDLE;
2638
2639 /* vif->bss_conf.basic_rates ? Where exactly? */
2640
2641 lvif->beacons = 0;
2642 /* Should almost assert it is this. */
2643 vif->cfg.assoc = false;
2644 vif->cfg.aid = 0;
2645
2646 bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__);
2647
2648 error = lkpi_set_chanctx_conf(hw, vif, chanctx_conf, changed, true);
2649 if (error != 0)
2650 goto out;
2651
2652 IMPROVE("update radiotap chan fields too");
2653
2654 /* RATES */
2655 IMPROVE("bss info: not all needs to come now and rates are missing");
2656 lkpi_bss_info_change(hw, vif, bss_changed);
2657
2658 /*
2659 * Given ni and lsta are 1:1 from alloc to free we can assert that
2660 * ni always has lsta data attach despite net80211 node swapping
2661 * under the hoods.
2662 */
2663 KASSERT(ni->ni_drv_data != NULL, ("%s: ni %p ni_drv_data %p\n",
2664 __func__, ni, ni->ni_drv_data));
2665 lsta = ni->ni_drv_data;
2666
2667 /* Insert the [l]sta into the list of known stations. */
2668 list_add_tail(&lsta->lsta_list, &lvif->lsta_list);
2669
2670 /* Add (or adjust) sta and change state (from NOTEXIST) to NONE. */
2671 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2672 KASSERT(lsta->state == IEEE80211_STA_NOTEXIST, ("%s: lsta %p state not "
2673 "NOTEXIST: %#x\n", __func__, lsta, lsta->state));
2674 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NONE);
2675 if (error != 0) {
2676 IMPROVE("do we need to undo the chan ctx?");
2677 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NONE) "
2678 "failed: %d\n", __func__, __LINE__, error);
2679 goto out;
2680 }
2681 #if 0
2682 lsta->added_to_drv = true; /* mo manages. */
2683 #endif
2684
2685 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2686
2687 #if 0
2688 /*
2689 * Wakeup all queues now that sta is there so we have as much time to
2690 * possibly prepare the queue in the driver to be ready for the 1st
2691 * packet; lkpi_80211_txq_tx_one() still has a workaround as there
2692 * is no guarantee or way to check.
2693 * XXX-BZ and by now we know that this does not work on all drivers
2694 * for all queues.
2695 */
2696 lkpi_wake_tx_queues(hw, LSTA_TO_STA(lsta), false, false);
2697 #endif
2698
2699 /* Start mgd_prepare_tx. */
2700 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2701 prep_tx_info.duration = PREP_TX_INFO_DURATION; /* SAE */
2702 prep_tx_info.subtype = IEEE80211_STYPE_AUTH;
2703 prep_tx_info.link_id = 0;
2704 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
2705 lsta->in_mgd = true;
2706
2707 /*
2708 * What is going to happen next:
2709 * - <twiddle> .. we should end up in "auth_to_assoc"
2710 * - event_callback
2711 * - update sta_state (NONE to AUTH)
2712 * - mgd_complete_tx
2713 * (ideally we'd do that on a callback for something else ...)
2714 */
2715
2716 wiphy_unlock(hw->wiphy);
2717 IEEE80211_LOCK(vap->iv_ic);
2718
2719 LKPI_80211_LVIF_LOCK(lvif);
2720 /* Re-check given (*iv_update_bss) could have happened while we were unlocked. */
2721 if (lvif->lvif_bss_synched || lvif->lvif_bss != NULL ||
2722 lsta->ni != vap->iv_bss)
2723 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2724 "lvif_bss->ni %p synched %d, ni %p lsta %p\n", __func__, __LINE__,
2725 lvif, vap, vap->iv_bss, lvif->lvif_bss,
2726 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2727 lvif->lvif_bss_synched, ni, lsta);
2728
2729 /*
2730 * Reference the "ni" for caching the lsta/ni in lvif->lvif_bss.
2731 * Given we cache lsta we use lsta->ni instead of ni here (even though
2732 * lsta->ni == ni) to be distinct from the rest of the code where we do
2733 * assume that ni == vap->iv_bss which it may or may not be.
2734 * So do NOT use iv_bss here anymore as that may have diverged from our
2735 * function local ni already while ic was unlocked and would lead to
2736 * inconsistencies. Go and see if we lost a race and do not update
2737 * lvif_bss_synched in that case.
2738 */
2739 ieee80211_ref_node(lsta->ni);
2740 lvif->lvif_bss = lsta;
2741 if (lsta->ni == vap->iv_bss) {
2742 lvif->lvif_bss_synched = synched = true;
2743 } else {
2744 /* Set to un-synched no matter what. */
2745 lvif->lvif_bss_synched = synched = false;
2746 /*
2747 * We do not error as someone has to take us down.
2748 * If we are followed by a 2nd, new net80211::join1() going to
2749 * AUTH lkpi_sta_a_to_a() will error, lkpi_sta_auth_to_{scan,init}()
2750 * will take the lvif->lvif_bss node down eventually.
2751 * What happens with the vap->iv_bss node will entirely be up
2752 * to net80211 as we never used the node beyond alloc()/free()
2753 * and we do not hold an extra reference for that anymore given
2754 * ni : lsta == 1:1.
2755 * Problem is if we do not error a MGMT/AUTH frame will be
2756 * sent from net80211::sta_newstate(); disable lsta queue below.
2757 */
2758 }
2759 LKPI_80211_LVIF_UNLOCK(lvif);
2760 /*
2761 * Make sure in case the sta did not change and we re-added it,
2762 * that we can tx again but only if the vif/iv_bss are in sync.
2763 * Otherwise this should prevent the MGMT/AUTH frame from being
2764 * sent triggering a warning in iwlwifi.
2765 */
2766 LKPI_80211_LSTA_TXQ_LOCK(lsta);
2767 lsta->txq_ready = synched;
2768 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
2769 goto out_relocked;
2770
2771 out:
2772 wiphy_unlock(hw->wiphy);
2773 IEEE80211_LOCK(vap->iv_ic);
2774 out_relocked:
2775 /*
2776 * Release the reference that kept the ni stable locally
2777 * during the work of this function.
2778 */
2779 if (ni != NULL)
2780 ieee80211_free_node(ni);
2781 return (error);
2782 }
2783
2784 /* UP3.1 */
2785 static int
lkpi_sta_auth_to_assoc(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2786 lkpi_sta_auth_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2787 {
2788 struct lkpi_hw *lhw;
2789 struct ieee80211_hw *hw;
2790 struct lkpi_vif *lvif;
2791 struct ieee80211_vif *vif;
2792 struct lkpi_sta *lsta;
2793 struct ieee80211_prep_tx_info prep_tx_info;
2794 int error;
2795
2796 lhw = vap->iv_ic->ic_softc;
2797 hw = LHW_TO_HW(lhw);
2798 lvif = VAP_TO_LVIF(vap);
2799 vif = LVIF_TO_VIF(lvif);
2800
2801 IEEE80211_UNLOCK(vap->iv_ic);
2802 wiphy_lock(hw->wiphy);
2803
2804 LKPI_80211_LVIF_LOCK(lvif);
2805 /* XXX-BZ KASSERT later? */
2806 if (!lvif->lvif_bss_synched || lvif->lvif_bss == NULL) {
2807 #ifdef LINUXKPI_DEBUG_80211
2808 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2809 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2810 lvif, vap, vap->iv_bss, lvif->lvif_bss,
2811 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2812 lvif->lvif_bss_synched);
2813 #endif
2814 error = ENOTRECOVERABLE;
2815 LKPI_80211_LVIF_UNLOCK(lvif);
2816 goto out;
2817 }
2818 lsta = lvif->lvif_bss;
2819 LKPI_80211_LVIF_UNLOCK(lvif);
2820
2821 KASSERT(lsta != NULL, ("%s: lsta %p\n", __func__, lsta));
2822
2823 /* Finish auth. */
2824 IMPROVE("event callback");
2825
2826 /* Update sta_state (NONE to AUTH). */
2827 KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not "
2828 "NONE: %#x\n", __func__, lsta, lsta->state));
2829 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_AUTH);
2830 if (error != 0) {
2831 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(AUTH) "
2832 "failed: %d\n", __func__, __LINE__, error);
2833 goto out;
2834 }
2835
2836 /* End mgd_complete_tx. */
2837 if (lsta->in_mgd) {
2838 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2839 prep_tx_info.subtype = IEEE80211_STYPE_AUTH;
2840 prep_tx_info.success = true;
2841 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
2842 lsta->in_mgd = false;
2843 }
2844
2845 /* Now start assoc. unless nstate=RUN (auth_to_run). */
2846
2847 /* Start mgd_prepare_tx. */
2848 if (nstate == IEEE80211_S_ASSOC && !lsta->in_mgd) {
2849 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2850 prep_tx_info.subtype = IEEE80211_STYPE_ASSOC_REQ;
2851 prep_tx_info.link_id = 0;
2852 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
2853 lsta->in_mgd = true;
2854 }
2855
2856 #if 0
2857 /* We do not yet have a packet to go out. */
2858 /* Wake tx queue to get packet out. */
2859 lkpi_wake_tx_queues(hw, LSTA_TO_STA(lsta), false, true);
2860 #endif
2861
2862 /*
2863 * <twiddle> .. we end up in "assoc_to_run"
2864 * - update sta_state (AUTH to ASSOC)
2865 * - conf_tx [all]
2866 * - bss_info_changed (assoc, aid, ssid, ..)
2867 * - change_chanctx (if needed)
2868 * - event_callback
2869 * - mgd_complete_tx
2870 */
2871
2872 out:
2873 wiphy_unlock(hw->wiphy);
2874 IEEE80211_LOCK(vap->iv_ic);
2875 return (error);
2876 }
2877
2878 static int lkpi_sta_assoc_to_run(struct ieee80211vap *, enum ieee80211_state, int);
2879
2880 /* UP3.2 */
2881 static int
lkpi_sta_auth_to_run(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2882 lkpi_sta_auth_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2883 {
2884 int error;
2885
2886 error = lkpi_sta_auth_to_assoc(vap, nstate, arg);
2887 if (error == 0)
2888 error = lkpi_sta_assoc_to_run(vap, nstate, arg);
2889 return (error);
2890 }
2891
2892 /* UP4 */
2893 static int
lkpi_sta_assoc_to_run(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2894 lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2895 {
2896 struct lkpi_hw *lhw;
2897 struct ieee80211_hw *hw;
2898 struct lkpi_vif *lvif;
2899 struct ieee80211_vif *vif;
2900 struct ieee80211_node *ni;
2901 struct lkpi_sta *lsta;
2902 struct ieee80211_sta *sta;
2903 struct ieee80211_prep_tx_info prep_tx_info;
2904 enum ieee80211_bss_changed bss_changed;
2905 int error;
2906
2907 lhw = vap->iv_ic->ic_softc;
2908 hw = LHW_TO_HW(lhw);
2909 lvif = VAP_TO_LVIF(vap);
2910 vif = LVIF_TO_VIF(lvif);
2911
2912 IEEE80211_UNLOCK(vap->iv_ic);
2913 wiphy_lock(hw->wiphy);
2914
2915 LKPI_80211_LVIF_LOCK(lvif);
2916 /* XXX-BZ KASSERT later? */
2917 if (!lvif->lvif_bss_synched || lvif->lvif_bss == NULL) {
2918 #ifdef LINUXKPI_DEBUG_80211
2919 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2920 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2921 lvif, vap, vap->iv_bss, lvif->lvif_bss,
2922 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2923 lvif->lvif_bss_synched);
2924 #endif
2925 LKPI_80211_LVIF_UNLOCK(lvif);
2926 error = ENOTRECOVERABLE;
2927 goto out;
2928 }
2929 lsta = lvif->lvif_bss;
2930 LKPI_80211_LVIF_UNLOCK(lvif);
2931 KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
2932 "lvif %p vap %p\n", __func__,
2933 lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
2934
2935 ni = lsta->ni; /* Reference held for lvif_bss. */
2936
2937 IMPROVE("ponder some of this moved to ic_newassoc, scan_assoc_success, "
2938 "and to lesser extend ieee80211_notify_node_join");
2939
2940 /* Finish assoc. (even if this is auth_to_run!) */
2941 /* Update sta_state (AUTH to ASSOC) and set aid. */
2942 KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not "
2943 "AUTH: %#x\n", __func__, lsta, lsta->state));
2944 sta = LSTA_TO_STA(lsta);
2945 sta->aid = IEEE80211_NODE_AID(ni);
2946 #ifdef LKPI_80211_WME
2947 if (vap->iv_flags & IEEE80211_F_WME)
2948 sta->wme = true;
2949 #endif
2950 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_ASSOC);
2951 if (error != 0) {
2952 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(ASSOC) "
2953 "failed: %d\n", __func__, __LINE__, error);
2954 goto out;
2955 }
2956
2957 IMPROVE("wme / conf_tx [all]");
2958
2959 /* Update bss info (bss_info_changed) (assoc, aid, ..). */
2960 bss_changed = 0;
2961 #ifdef LKPI_80211_WME
2962 bss_changed |= lkpi_wme_update(lhw, vap, true);
2963 #endif
2964 if (!vif->cfg.assoc || vif->cfg.aid != IEEE80211_NODE_AID(ni)) {
2965 lvif->beacons = 0;
2966 vif->cfg.assoc = true;
2967 vif->cfg.aid = IEEE80211_NODE_AID(ni);
2968 bss_changed |= BSS_CHANGED_ASSOC;
2969 }
2970 /* We set SSID but this is not BSSID! */
2971 vif->cfg.ssid_len = ni->ni_esslen;
2972 memcpy(vif->cfg.ssid, ni->ni_essid, ni->ni_esslen);
2973 if ((vap->iv_flags & IEEE80211_F_SHPREAMBLE) !=
2974 vif->bss_conf.use_short_preamble) {
2975 vif->bss_conf.use_short_preamble ^= 1;
2976 /* bss_changed |= BSS_CHANGED_??? */
2977 }
2978 if ((vap->iv_flags & IEEE80211_F_SHSLOT) !=
2979 vif->bss_conf.use_short_slot) {
2980 vif->bss_conf.use_short_slot ^= 1;
2981 /* bss_changed |= BSS_CHANGED_??? */
2982 }
2983 if ((ni->ni_flags & IEEE80211_NODE_QOS) !=
2984 vif->bss_conf.qos) {
2985 vif->bss_conf.qos ^= 1;
2986 bss_changed |= BSS_CHANGED_QOS;
2987 }
2988
2989 bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__);
2990 lkpi_bss_info_change(hw, vif, bss_changed);
2991
2992 /* - change_chanctx (if needed)
2993 * - event_callback
2994 */
2995
2996 /* End mgd_complete_tx. (we do not have to check ostate == IEEE80211_S_ASSOC). */
2997 if (lsta->in_mgd) {
2998 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2999 prep_tx_info.subtype = IEEE80211_STYPE_ASSOC_REQ;
3000 prep_tx_info.success = true; /* Needs vif->cfg.assoc set! */
3001 prep_tx_info.link_id = 0;
3002 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
3003 lsta->in_mgd = false;
3004 }
3005
3006 /*
3007 * And then:
3008 * - (more packets)?
3009 * - set_key
3010 * - set_default_unicast_key
3011 * - set_key (?)
3012 * - ipv6_addr_change (?)
3013 */
3014
3015 if (!ieee80211_node_is_authorized(ni)) {
3016 IMPROVE("net80211 does not consider node authorized");
3017 }
3018
3019 IMPROVE("Is this the right spot, has net80211 done all updates already?");
3020 lkpi_sta_sync_from_ni(hw, vif, sta, ni, true);
3021
3022 /* Update thresholds. */
3023 hw->wiphy->frag_threshold = vap->iv_fragthreshold;
3024 lkpi_80211_mo_set_frag_threshold(hw, vap->iv_fragthreshold);
3025 hw->wiphy->rts_threshold = vap->iv_rtsthreshold;
3026 lkpi_80211_mo_set_rts_threshold(hw, vap->iv_rtsthreshold);
3027
3028 /* Update sta_state (ASSOC to AUTHORIZED). */
3029 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
3030 KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not "
3031 "ASSOC: %#x\n", __func__, lsta, lsta->state));
3032 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_AUTHORIZED);
3033 if (error != 0) {
3034 IMPROVE("undo some changes?");
3035 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(AUTHORIZED) "
3036 "failed: %d\n", __func__, __LINE__, error);
3037 goto out;
3038 }
3039
3040 /* - drv_config (?)
3041 * - bss_info_changed
3042 * - set_rekey_data (?)
3043 *
3044 * And now we should be passing packets.
3045 */
3046 IMPROVE("Need that bssid setting, and the keys");
3047
3048 bss_changed = 0;
3049 bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__);
3050 lkpi_bss_info_change(hw, vif, bss_changed);
3051
3052 /* Prepare_multicast && configure_filter. */
3053 lkpi_update_mcast_filter(vap->iv_ic);
3054
3055 out:
3056 wiphy_unlock(hw->wiphy);
3057 IEEE80211_LOCK(vap->iv_ic);
3058 return (error);
3059 }
3060
3061 /*
3062 * DOWN1
3063 * "to assoc" means we are going back to State 2 from State 4[/3].
3064 * This means ni still is authenticated, so we keep sta, chanctx, ..
3065 * We will send a (Re)Assoc Request in case net80211 handles roadming.
3066 * Note: this can be called as part of a DEAUTH going to State 1 as well,
3067 * so for RoC prep_tx_info we need to check nstate (see run_to_{auth,scan,init}).
3068 */
3069 static int
lkpi_sta_run_to_assoc(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3070 lkpi_sta_run_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3071 {
3072 struct lkpi_hw *lhw;
3073 struct ieee80211_hw *hw;
3074 struct lkpi_vif *lvif;
3075 struct ieee80211_vif *vif;
3076 struct ieee80211_node *ni;
3077 struct lkpi_sta *lsta;
3078 struct ieee80211_sta *sta;
3079 struct ieee80211_prep_tx_info prep_tx_info;
3080 #if 0
3081 enum ieee80211_bss_changed bss_changed;
3082 #endif
3083 struct ieee80211_rx_ampdu *rap;
3084 int error;
3085
3086 lhw = vap->iv_ic->ic_softc;
3087 hw = LHW_TO_HW(lhw);
3088 lvif = VAP_TO_LVIF(vap);
3089 vif = LVIF_TO_VIF(lvif);
3090
3091 IEEE80211_UNLOCK(vap->iv_ic);
3092 wiphy_lock(hw->wiphy);
3093
3094 LKPI_80211_LVIF_LOCK(lvif);
3095 #ifdef LINUXKPI_DEBUG_80211
3096 /* XXX-BZ KASSERT later; state going down so no action. */
3097 if (lvif->lvif_bss == NULL)
3098 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
3099 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
3100 lvif, vap, vap->iv_bss, lvif->lvif_bss,
3101 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
3102 lvif->lvif_bss_synched);
3103 #endif
3104 lsta = lvif->lvif_bss;
3105 LKPI_80211_LVIF_UNLOCK(lvif);
3106 KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
3107 "lvif %p vap %p\n", __func__,
3108 lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
3109
3110 ni = lsta->ni; /* Reference held for lvif_bss. */
3111 sta = LSTA_TO_STA(lsta);
3112
3113 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3114
3115 /* flush, drop. */
3116 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), true);
3117
3118 /* We should make this a KASSERT. */
3119 if (lsta->in_mgd) {
3120 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p lsta %p in_mgd\n",
3121 __func__, __LINE__, lvif, vap, lsta);
3122 }
3123 /*
3124 * Problem is that we should hook into the tx/rx flow and not
3125 * try to re-model the state machine parts. We may miss a SME
3126 * triggered frame this way.
3127 */
3128 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
3129 if (nstate == IEEE80211_S_ASSOC) {
3130 if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) {
3131 if (arg)
3132 prep_tx_info.subtype = IEEE80211_STYPE_REASSOC_REQ;
3133 else
3134 prep_tx_info.subtype = IEEE80211_STYPE_ASSOC_REQ;
3135 } else {
3136 /* wpa_supplicant upon RTM_IEEE80211_LEAVE. */
3137 prep_tx_info.subtype = IEEE80211_STYPE_DISASSOC;
3138 }
3139 } else
3140 prep_tx_info.subtype = IEEE80211_STYPE_DEAUTH;
3141 prep_tx_info.was_assoc = true;
3142 prep_tx_info.link_id = 0;
3143 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
3144 lsta->in_mgd = true;
3145
3146 wiphy_unlock(hw->wiphy);
3147 IEEE80211_LOCK(vap->iv_ic);
3148
3149 /* Call iv_newstate first so we get potential (RE-)ASSOC/DEAUTH? packet out. */
3150 error = lvif->iv_newstate(vap, nstate, arg);
3151 if (error != 0) {
3152 ic_printf(vap->iv_ic, "%s:%d: iv_newstate(%p, %d, %d) "
3153 "failed: %d\n", __func__, __LINE__, vap, nstate, arg, error);
3154 goto outni;
3155 }
3156
3157 /* Stop any BA sessions if still active. */
3158 for (int rapn = 0; rapn < WME_NUM_TID; rapn++) {
3159 rap = &ni->ni_rx_ampdu[rapn];
3160
3161 if ((rap->rxa_flags & IEEE80211_AGGR_RUNNING) == 0)
3162 continue;
3163
3164 vap->iv_ic->ic_ampdu_rx_stop(ni, rap);
3165 }
3166
3167 IEEE80211_UNLOCK(vap->iv_ic);
3168
3169 /* Ensure the packets get out. */
3170 lkpi_80211_flush_tx(lhw, lsta);
3171
3172 wiphy_lock(hw->wiphy);
3173
3174 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3175
3176 /* Wake tx queues to get packet(s) out. */
3177 lkpi_wake_tx_queues(hw, sta, false, true);
3178
3179 /* flush, no drop */
3180 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), false);
3181
3182 /* End mgd_complete_tx. */
3183 /* We should make this a KASSERT. */
3184 if (!lsta->in_mgd) {
3185 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p lsta %p !in_mgd\n",
3186 __func__, __LINE__, lvif, vap, lsta);
3187 }
3188 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
3189 lsta->in_mgd = false;
3190
3191 #if 0
3192 /* sync_rx_queues */
3193 lkpi_80211_mo_sync_rx_queues(hw);
3194
3195 /* sta_pre_rcu_remove */
3196 lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta);
3197 #endif
3198
3199 /* Take the station down. */
3200
3201 /* Adjust sta and change state (from AUTHORIZED) to ASSOC. */
3202 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
3203 KASSERT(lsta->state == IEEE80211_STA_AUTHORIZED, ("%s: lsta %p state not "
3204 "AUTHORIZED: %#x\n", __func__, lsta, lsta->state));
3205 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_ASSOC);
3206 if (error != 0) {
3207 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(ASSOC) "
3208 "failed: %d\n", __func__, __LINE__, error);
3209 goto out;
3210 }
3211
3212 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3213
3214 #ifdef LKPI_80211_HW_CRYPTO
3215 if (lkpi_hwcrypto) {
3216 error = lkpi_sta_del_keys(hw, vif, lsta);
3217 if (error != 0) {
3218 ic_printf(vap->iv_ic, "%s:%d: lkpi_sta_del_keys "
3219 "failed: %d\n", __func__, __LINE__, error);
3220 /*
3221 * Either drv/fw will crash or cleanup itself,
3222 * otherwise net80211 will delete the keys (at a
3223 * less appropriate time).
3224 */
3225 /* goto out; */
3226 }
3227 }
3228 #endif
3229
3230 /* Update sta_state (ASSOC to AUTH). */
3231 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
3232 KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not "
3233 "ASSOC: %#x\n", __func__, lsta, lsta->state));
3234 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_AUTH);
3235 if (error != 0) {
3236 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(AUTH) "
3237 "failed: %d\n", __func__, __LINE__, error);
3238 goto out;
3239 }
3240
3241 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3242
3243 #if 0
3244 /* Update bss info (bss_info_changed) (assoc, aid, ..). */
3245 /* See comment in DOWN4. */
3246 lkpi_disassoc(sta, vif, lhw);
3247 #endif
3248
3249 error = EALREADY;
3250 out:
3251 wiphy_unlock(hw->wiphy);
3252 IEEE80211_LOCK(vap->iv_ic);
3253 outni:
3254 return (error);
3255 }
3256
3257 /*
3258 * DOWN2
3259 * We are in state 2 and go back to state 1 and will try to auth again
3260 * (to IEEE80211_S_AUTH in FreeBSD means "try to auth"). This should be
3261 * like scan_to_auth but that we keep the "ni" and with that chanctx/bssid,
3262 * which essentially makes this "a_to_a" in LinuxKPI.
3263 */
3264 static int
lkpi_sta_assoc_to_auth(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3265 lkpi_sta_assoc_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3266 {
3267 struct lkpi_hw *lhw;
3268 struct ieee80211_hw *hw;
3269 struct lkpi_vif *lvif;
3270 struct ieee80211_vif *vif;
3271 struct ieee80211_node *ni;
3272 struct lkpi_sta *lsta;
3273 struct ieee80211_prep_tx_info prep_tx_info;
3274 int error;
3275
3276 lhw = vap->iv_ic->ic_softc;
3277 hw = LHW_TO_HW(lhw);
3278 lvif = VAP_TO_LVIF(vap);
3279 vif = LVIF_TO_VIF(lvif);
3280
3281 IEEE80211_UNLOCK(vap->iv_ic);
3282 wiphy_lock(hw->wiphy);
3283
3284 LKPI_80211_LVIF_LOCK(lvif);
3285 #ifdef LINUXKPI_DEBUG_80211
3286 /* XXX-BZ KASSERT later; state going down so no action. */
3287 if (lvif->lvif_bss == NULL)
3288 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
3289 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
3290 lvif, vap, vap->iv_bss, lvif->lvif_bss,
3291 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
3292 lvif->lvif_bss_synched);
3293 #endif
3294 lsta = lvif->lvif_bss;
3295 LKPI_80211_LVIF_UNLOCK(lvif);
3296 KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
3297 "lvif %p vap %p\n", __func__,
3298 lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
3299
3300 ni = lsta->ni; /* Reference held for lvif_bss. */
3301
3302 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3303
3304 /* End mgd_complete_tx. */
3305 if (lsta->in_mgd && vap->iv_state == IEEE80211_S_ASSOC) {
3306 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
3307 prep_tx_info.subtype = IEEE80211_STYPE_ASSOC_REQ;
3308 prep_tx_info.link_id = 0;
3309 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
3310 lsta->in_mgd = false;
3311 } else if (lsta->in_mgd) {
3312 ic_printf(vap->iv_ic, "%s:%d: in_mgd %d (%s) -> %d (%s) %d\n",
3313 __func__, __LINE__,
3314 vap->iv_state, ieee80211_state_name[vap->iv_state],
3315 nstate, ieee80211_state_name[nstate], arg);
3316 }
3317
3318 /* Take the station down. */
3319 /* Update sta_state (AUTH to NONE). */
3320 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
3321 KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not "
3322 "AUTH: %#x\n", __func__, lsta, lsta->state));
3323 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NONE);
3324 if (error != 0) {
3325 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NONE) "
3326 "failed: %d\n", __func__, __LINE__, error);
3327 goto out;
3328 }
3329
3330 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3331
3332 out:
3333 wiphy_unlock(hw->wiphy);
3334 IEEE80211_LOCK(vap->iv_ic);
3335 return (error);
3336 }
3337
3338 /*
3339 * DOWN3
3340 * We are in state 1. Either auth timed out (arg != 0) or we have an internal
3341 * state change forcing us to give up trying to authenticate.
3342 * Cleanup and remove chanctx, sta, ...
3343 */
3344 static int
lkpi_sta_auth_to_scan(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3345 lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3346 {
3347 struct lkpi_hw *lhw;
3348 struct ieee80211_hw *hw;
3349 struct lkpi_vif *lvif;
3350 struct ieee80211_vif *vif;
3351 struct ieee80211_node *ni;
3352 struct lkpi_sta *lsta;
3353 struct ieee80211_sta *sta;
3354 struct ieee80211_prep_tx_info prep_tx_info;
3355 enum ieee80211_bss_changed bss_changed;
3356 int error;
3357
3358 lhw = vap->iv_ic->ic_softc;
3359 hw = LHW_TO_HW(lhw);
3360 lvif = VAP_TO_LVIF(vap);
3361 vif = LVIF_TO_VIF(lvif);
3362
3363 IEEE80211_UNLOCK(vap->iv_ic);
3364 wiphy_lock(hw->wiphy);
3365
3366 LKPI_80211_LVIF_LOCK(lvif);
3367 /*
3368 * XXX-BZ KASSERT later; state going down so no action in theory
3369 * but try to avoid a NULL-pointer derref for now and gracefully
3370 * fail for non-debug kernels.
3371 */
3372 if (lvif->lvif_bss == NULL) {
3373 ic_printf(vap->iv_ic, "%s:%d: ERROR: lvif %p vap %p iv_bss %p "
3374 "lvif_bss %p lvif_bss->ni %p synched %d; "
3375 "expect follow-up problems\n", __func__, __LINE__,
3376 lvif, vap, vap->iv_bss, lvif->lvif_bss,
3377 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
3378 lvif->lvif_bss_synched);
3379 LKPI_80211_LVIF_UNLOCK(lvif);
3380 /*
3381 * This will likely lead to a firmware crash (if there
3382 * was not one before already) and need a
3383 * ieee80211_restart_hw() but still better than a panic
3384 * for users as they can at least recover.
3385 */
3386 error = ENOTRECOVERABLE;
3387 goto out;
3388 }
3389 lsta = lvif->lvif_bss;
3390 LKPI_80211_LVIF_UNLOCK(lvif);
3391 KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
3392 "lvif %p vap %p\n", __func__,
3393 lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
3394 ni = lsta->ni; /* Reference held for lvif_bss. */
3395 sta = LSTA_TO_STA(lsta);
3396
3397 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3398
3399 /* flush, drop. */
3400 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), true);
3401
3402 /* Wake tx queues to get packet(s) out. */
3403 lkpi_wake_tx_queues(hw, sta, false, true);
3404
3405 /* flush, no drop */
3406 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), false);
3407
3408 /* End mgd_complete_tx. */
3409 if (lsta->in_mgd) {
3410 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
3411 prep_tx_info.subtype = IEEE80211_STYPE_AUTH;
3412 prep_tx_info.link_id = 0;
3413 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
3414 lsta->in_mgd = false;
3415 }
3416
3417 /* sync_rx_queues */
3418 lkpi_80211_mo_sync_rx_queues(hw);
3419
3420 #ifdef LKPI_80211_HW_CRYPTO
3421 if (lkpi_hwcrypto) {
3422 error = lkpi_sta_del_keys(hw, vif, lsta);
3423 if (error != 0) {
3424 ic_printf(vap->iv_ic, "%s:%d: lkpi_sta_del_keys "
3425 "failed: %d\n", __func__, __LINE__, error);
3426 /*
3427 * Either drv/fw will crash or cleanup itself,
3428 * otherwise net80211 will delete the keys (at a
3429 * less appropriate time).
3430 */
3431 /* goto out; */
3432 }
3433 }
3434 #endif
3435
3436 /* sta_pre_rcu_remove */
3437 lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta);
3438
3439 synchronize_net();
3440
3441 /* Take the station down. */
3442
3443 bss_changed = 0;
3444 /*
3445 * Start updating bss info (*bss_info_changed) (assoc, aid, ..).
3446 *
3447 * One would expect this to happen when going off AUTHORIZED but
3448 * not so.
3449 *
3450 * Immediately issuing the (*bss_info_changed) used to also remove the
3451 * sta from firmware for iwlwifi; or we have problems with the sta
3452 * silently not being removed and then crash upon the next sta add.
3453 * Neither seems to be the case or a problem still.
3454 *
3455 * Contrary for BE200 (iwlwifi/mld) if we do not issue the
3456 * (*vif_cfg_change) to tell FW that we are no longer assoc
3457 * it will crash now upon sta rm. So the order now is as we once
3458 * expected it:
3459 *
3460 * 1) lkpi_disassoc(): set vif->cfg.assoc = false and .aid=0
3461 * 2) add the remaining BSS_CHANGED changes and call (*bss_info_changed)
3462 * (which may be split up into (*vif_cfg_change) and
3463 * (*link_info_changed) for more modern drivers).
3464 * 3) call the last sta_state update -> IEEE80211_STA_NOTEXIST
3465 * (removes the sta given assoc is false) and tidy up our lists.
3466 * 4) call unassign_vif_chanctx
3467 * 5) call lkpi_hw_conf_idle
3468 * 6) call remove_chanctx
3469 *
3470 * Note: vif->driver_flags & IEEE80211_VIF_REMOVE_AP_AFTER_DISASSOC
3471 * might change this.
3472 */
3473 bss_changed |= lkpi_disassoc(sta, vif, lhw);
3474
3475 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3476
3477 IMPROVE("Any bss_info changes to announce?");
3478 vif->bss_conf.qos = false;
3479 bss_changed |= BSS_CHANGED_QOS;
3480 vif->cfg.ssid_len = 0;
3481 memset(vif->cfg.ssid, '\0', sizeof(vif->cfg.ssid));
3482 IEEE80211_ADDR_COPY(vif->cfg.ap_addr, ieee80211broadcastaddr);
3483 bss_changed |= BSS_CHANGED_BSSID;
3484 vif->bss_conf.use_short_preamble = false;
3485 /* XXX BSS_CHANGED_???? */
3486 vif->bss_conf.dtim_period = 0; /* go back to 0. */
3487 bss_changed |= BSS_CHANGED_BEACON_INFO;
3488 lkpi_bss_info_change(hw, vif, bss_changed);
3489
3490 /* Adjust sta and change state (from NONE) to NOTEXIST. */
3491 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
3492 KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not "
3493 "NONE: %#x, nstate %d arg %d\n", __func__, lsta, lsta->state, nstate, arg));
3494 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NOTEXIST);
3495 if (error != 0) {
3496 IMPROVE("do we need to undo the chan ctx?");
3497 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NOTEXIST) "
3498 "failed: %d\n", __func__, __LINE__, error);
3499 goto out;
3500 }
3501
3502 lkpi_lsta_remove(lsta, lvif);
3503
3504 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3505
3506 LKPI_80211_LVIF_LOCK(lvif);
3507 /* Remove ni reference for this cache of lsta. */
3508 lvif->lvif_bss = NULL;
3509 lvif->lvif_bss_synched = false;
3510 LKPI_80211_LVIF_UNLOCK(lvif);
3511
3512 /* conf_tx */
3513
3514 lkpi_remove_chanctx(hw, vif);
3515
3516 out:
3517 wiphy_unlock(hw->wiphy);
3518 IEEE80211_LOCK(vap->iv_ic);
3519 if (error == 0) {
3520 /*
3521 * We do this outside the wiphy lock as net80211::node_free() may call
3522 * into crypto code to delete keys and we have a recursed on
3523 * non-recursive sx panic. Also only do this if we get here w/o error.
3524 *
3525 * The very last release the reference on the ni for the ni/lsta on
3526 * lvif->lvif_bss. Upon return from this both ni and lsta are invalid
3527 * and potentially freed.
3528 */
3529 ieee80211_free_node(ni);
3530 }
3531 return (error);
3532 }
3533
3534 /* DOWN4 */
3535 static int
lkpi_sta_scan_to_init(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3536 lkpi_sta_scan_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3537 {
3538 /* lkpi_iv_newstate() handles the stop scan case in common code. */
3539 return (lkpi_sta_state_do_nada(vap, nstate, arg));
3540 }
3541
3542 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
3543
3544 static int
lkpi_sta_auth_to_init(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3545 lkpi_sta_auth_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3546 {
3547 int error;
3548
3549 error = lkpi_sta_auth_to_scan(vap, nstate, arg);
3550 if (error == 0)
3551 error = lkpi_sta_scan_to_init(vap, nstate, arg);
3552 return (error);
3553 }
3554
3555 /* auth_to_auth, assoc_to_assoc. */
3556 static int
lkpi_sta_a_to_a(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3557 lkpi_sta_a_to_a(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3558 {
3559 struct lkpi_hw *lhw;
3560 struct ieee80211_hw *hw;
3561 struct lkpi_vif *lvif;
3562 struct ieee80211_vif *vif;
3563 struct lkpi_sta *lsta;
3564 struct ieee80211_prep_tx_info prep_tx_info;
3565 int error;
3566
3567 lhw = vap->iv_ic->ic_softc;
3568 hw = LHW_TO_HW(lhw);
3569 lvif = VAP_TO_LVIF(vap);
3570 vif = LVIF_TO_VIF(lvif);
3571
3572 IEEE80211_UNLOCK(vap->iv_ic);
3573 wiphy_lock(hw->wiphy);
3574
3575 LKPI_80211_LVIF_LOCK(lvif);
3576 /* XXX-BZ KASSERT later? */
3577 if (!lvif->lvif_bss_synched || lvif->lvif_bss == NULL) {
3578 #ifdef LINUXKPI_DEBUG_80211
3579 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
3580 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
3581 lvif, vap, vap->iv_bss, lvif->lvif_bss,
3582 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
3583 lvif->lvif_bss_synched);
3584 #endif
3585 LKPI_80211_LVIF_UNLOCK(lvif);
3586 error = ENOTRECOVERABLE;
3587 goto out;
3588 }
3589 lsta = lvif->lvif_bss;
3590 LKPI_80211_LVIF_UNLOCK(lvif);
3591
3592 KASSERT(lsta != NULL, ("%s: lsta %p! lvif %p vap %p\n", __func__,
3593 lsta, lvif, vap));
3594
3595 IMPROVE("event callback?");
3596
3597 /* End mgd_complete_tx. */
3598 if (lsta->in_mgd) {
3599 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
3600 if (vap->iv_state == IEEE80211_S_AUTH)
3601 prep_tx_info.subtype = IEEE80211_STYPE_AUTH;
3602 else
3603 prep_tx_info.subtype = IEEE80211_STYPE_ASSOC_REQ;
3604 prep_tx_info.link_id = 0;
3605 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
3606 lsta->in_mgd = false;
3607 }
3608
3609 /* Now start auth/assoc. */
3610
3611 /* Start mgd_prepare_tx. */
3612 if (!lsta->in_mgd) {
3613 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
3614 if (nstate == IEEE80211_S_AUTH)
3615 prep_tx_info.subtype = IEEE80211_STYPE_AUTH;
3616 else
3617 prep_tx_info.subtype = IEEE80211_STYPE_ASSOC_REQ;
3618 prep_tx_info.link_id = 0;
3619 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
3620 lsta->in_mgd = true;
3621 }
3622
3623 error = 0;
3624 out:
3625 wiphy_unlock(hw->wiphy);
3626 IEEE80211_LOCK(vap->iv_ic);
3627
3628 return (error);
3629 }
3630
3631 static int
lkpi_sta_assoc_to_scan(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3632 lkpi_sta_assoc_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3633 {
3634 int error;
3635
3636 error = lkpi_sta_assoc_to_auth(vap, nstate, arg);
3637 if (error != 0 && error != EALREADY)
3638 return (error);
3639
3640 error = lkpi_sta_auth_to_scan(vap, nstate, arg);
3641 return (error);
3642 }
3643
3644 static int
lkpi_sta_assoc_to_init(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3645 lkpi_sta_assoc_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3646 {
3647 int error;
3648
3649 error = lkpi_sta_assoc_to_scan(vap, nstate, arg);
3650 if (error != 0 && error != EALREADY)
3651 return (error);
3652
3653 error = lkpi_sta_scan_to_init(vap, nstate, arg); /* do_nada */
3654 return (error);
3655 }
3656
3657 static int
lkpi_sta_run_to_init(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3658 lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3659 {
3660 int error;
3661
3662 error = lkpi_sta_run_to_assoc(vap, nstate, arg);
3663 if (error != 0 && error != EALREADY)
3664 return (error);
3665
3666 error = lkpi_sta_assoc_to_init(vap, nstate, arg);
3667 return (error);
3668 }
3669
3670 static int
lkpi_sta_run_to_scan(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3671 lkpi_sta_run_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3672 {
3673 int error;
3674
3675 error = lkpi_sta_run_to_assoc(vap, nstate, arg);
3676 if (error != 0 && error != EALREADY)
3677 return (error);
3678
3679 error = lkpi_sta_assoc_to_scan(vap, nstate, arg);
3680 return (error);
3681 }
3682
3683 static int
lkpi_sta_run_to_auth(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3684 lkpi_sta_run_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3685 {
3686 int error;
3687
3688 error = lkpi_sta_run_to_assoc(vap, nstate, arg);
3689 if (error != 0 && error != EALREADY)
3690 return (error);
3691
3692 error = lkpi_sta_assoc_to_auth(vap, nstate, arg);
3693 return (error);
3694 }
3695
3696 /* -------------------------------------------------------------------------- */
3697
3698 /*
3699 * The matches the documented state changes in net80211::sta_newstate().
3700 * XXX (1) without CSA and SLEEP yet, * XXX (2) not all unhandled cases
3701 * there are "invalid" (so there is a room for failure here).
3702 */
3703 struct fsm_state {
3704 /* INIT, SCAN, AUTH, ASSOC, CAC, RUN, CSA, SLEEP */
3705 enum ieee80211_state ostate;
3706 enum ieee80211_state nstate;
3707 int (*handler)(struct ieee80211vap *, enum ieee80211_state, int);
3708 } sta_state_fsm[] = {
3709 { IEEE80211_S_INIT, IEEE80211_S_INIT, lkpi_sta_state_do_nada },
3710 { IEEE80211_S_SCAN, IEEE80211_S_INIT, lkpi_sta_state_do_nada }, /* DOWN4 scan_to_init */
3711 { IEEE80211_S_AUTH, IEEE80211_S_INIT, lkpi_sta_auth_to_init }, /* not explicitly in sta_newstate() */
3712 { IEEE80211_S_ASSOC, IEEE80211_S_INIT, lkpi_sta_assoc_to_init }, /* Send DEAUTH. */
3713 { IEEE80211_S_RUN, IEEE80211_S_INIT, lkpi_sta_run_to_init }, /* Send DISASSOC. */
3714
3715 { IEEE80211_S_INIT, IEEE80211_S_SCAN, lkpi_sta_init_to_scan }, /* UP1 */
3716 { IEEE80211_S_SCAN, IEEE80211_S_SCAN, lkpi_sta_state_do_nada },
3717 { IEEE80211_S_AUTH, IEEE80211_S_SCAN, lkpi_sta_auth_to_scan }, /* DOWN3 */
3718 { IEEE80211_S_ASSOC, IEEE80211_S_SCAN, lkpi_sta_assoc_to_scan },
3719 { IEEE80211_S_RUN, IEEE80211_S_SCAN, lkpi_sta_run_to_scan }, /* Beacon miss. */
3720
3721 { IEEE80211_S_INIT, IEEE80211_S_AUTH, lkpi_sta_scan_to_auth }, /* Send AUTH. */
3722 { IEEE80211_S_SCAN, IEEE80211_S_AUTH, lkpi_sta_scan_to_auth }, /* UP2 Send AUTH. */
3723 { IEEE80211_S_AUTH, IEEE80211_S_AUTH, lkpi_sta_a_to_a }, /* Send ?AUTH. */
3724 { IEEE80211_S_ASSOC, IEEE80211_S_AUTH, lkpi_sta_assoc_to_auth }, /* DOWN2 Send ?AUTH. */
3725 { IEEE80211_S_RUN, IEEE80211_S_AUTH, lkpi_sta_run_to_auth }, /* Send ?AUTH. */
3726
3727 { IEEE80211_S_AUTH, IEEE80211_S_ASSOC, lkpi_sta_auth_to_assoc }, /* UP3.1 Send ASSOCREQ. */
3728 { IEEE80211_S_ASSOC, IEEE80211_S_ASSOC, lkpi_sta_a_to_a }, /* Send ASSOCREQ. */
3729 { IEEE80211_S_RUN, IEEE80211_S_ASSOC, lkpi_sta_run_to_assoc }, /* DOWN1 Send ASSOCREQ/REASSOCREQ. */
3730
3731 { IEEE80211_S_AUTH, IEEE80211_S_RUN, lkpi_sta_auth_to_run }, /* UP3.2 */
3732 { IEEE80211_S_ASSOC, IEEE80211_S_RUN, lkpi_sta_assoc_to_run }, /* UP4 */
3733 { IEEE80211_S_RUN, IEEE80211_S_RUN, lkpi_sta_state_do_nada },
3734
3735 /* Dummy at the end without handler. */
3736 { IEEE80211_S_INIT, IEEE80211_S_INIT, NULL },
3737 };
3738
3739 static int
lkpi_iv_newstate(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3740 lkpi_iv_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3741 {
3742 struct ieee80211com *ic;
3743 struct lkpi_hw *lhw;
3744 struct lkpi_vif *lvif;
3745 struct ieee80211_vif *vif;
3746 struct fsm_state *s;
3747 enum ieee80211_state ostate;
3748 int error;
3749
3750 ic = vap->iv_ic;
3751 IEEE80211_LOCK_ASSERT(ic);
3752 ostate = vap->iv_state;
3753
3754 #ifdef LINUXKPI_DEBUG_80211
3755 if (linuxkpi_debug_80211 & D80211_TRACE)
3756 ic_printf(vap->iv_ic, "%s:%d: vap %p nstate %#x arg %#x\n",
3757 __func__, __LINE__, vap, nstate, arg);
3758 #endif
3759
3760 if (vap->iv_opmode == IEEE80211_M_STA) {
3761
3762 lhw = ic->ic_softc;
3763 lvif = VAP_TO_LVIF(vap);
3764 vif = LVIF_TO_VIF(lvif);
3765
3766 /* No need to replicate this in most state handlers. */
3767 if (nstate > IEEE80211_S_SCAN)
3768 lkpi_stop_hw_scan(lhw, vif);
3769
3770 s = sta_state_fsm;
3771
3772 } else {
3773 ic_printf(vap->iv_ic, "%s: only station mode currently supported: "
3774 "vap %p iv_opmode %d\n", __func__, vap, vap->iv_opmode);
3775 return (ENOSYS);
3776 }
3777
3778 error = 0;
3779 for (; s->handler != NULL; s++) {
3780 if (ostate == s->ostate && nstate == s->nstate) {
3781 #ifdef LINUXKPI_DEBUG_80211
3782 if (linuxkpi_debug_80211 & D80211_TRACE)
3783 ic_printf(vap->iv_ic, "%s: new state %d (%s) ->"
3784 " %d (%s): arg %d.\n", __func__,
3785 ostate, ieee80211_state_name[ostate],
3786 nstate, ieee80211_state_name[nstate], arg);
3787 #endif
3788 error = s->handler(vap, nstate, arg);
3789 break;
3790 }
3791 }
3792 IEEE80211_LOCK_ASSERT(vap->iv_ic);
3793
3794 if (s->handler == NULL) {
3795 IMPROVE("turn this into a KASSERT\n");
3796 ic_printf(vap->iv_ic, "%s: unsupported state transition "
3797 "%d (%s) -> %d (%s)\n", __func__,
3798 ostate, ieee80211_state_name[ostate],
3799 nstate, ieee80211_state_name[nstate]);
3800 return (ENOSYS);
3801 }
3802
3803 if (error == EALREADY) {
3804 #ifdef LINUXKPI_DEBUG_80211
3805 if (linuxkpi_debug_80211 & D80211_TRACE)
3806 ic_printf(vap->iv_ic, "%s: state transition %d (%s) -> "
3807 "%d (%s): iv_newstate already handled: %d.\n",
3808 __func__, ostate, ieee80211_state_name[ostate],
3809 nstate, ieee80211_state_name[nstate], error);
3810 #endif
3811 return (0);
3812 }
3813
3814 if (error != 0) {
3815 ic_printf(vap->iv_ic, "%s: error %d during state transition "
3816 "%d (%s) -> %d (%s)\n", __func__, error,
3817 ostate, ieee80211_state_name[ostate],
3818 nstate, ieee80211_state_name[nstate]);
3819 return (error);
3820 }
3821
3822 #ifdef LINUXKPI_DEBUG_80211
3823 if (linuxkpi_debug_80211 & D80211_TRACE)
3824 ic_printf(vap->iv_ic, "%s:%d: vap %p nstate %#x arg %#x "
3825 "calling net80211 parent\n",
3826 __func__, __LINE__, vap, nstate, arg);
3827 #endif
3828
3829 return (lvif->iv_newstate(vap, nstate, arg));
3830 }
3831
3832 /* -------------------------------------------------------------------------- */
3833
3834 /*
3835 * We overload (*iv_update_bss) as otherwise we have cases in, e.g.,
3836 * net80211::ieee80211_sta_join1() where vap->iv_bss gets replaced by a
3837 * new node without us knowing and thus our ni/lsta are out of sync.
3838 */
3839 static struct ieee80211_node *
lkpi_iv_update_bss(struct ieee80211vap * vap,struct ieee80211_node * ni)3840 lkpi_iv_update_bss(struct ieee80211vap *vap, struct ieee80211_node *ni)
3841 {
3842 struct lkpi_vif *lvif;
3843 struct ieee80211_node *rni;
3844
3845 IEEE80211_LOCK_ASSERT(vap->iv_ic);
3846
3847 lvif = VAP_TO_LVIF(vap);
3848
3849 LKPI_80211_LVIF_LOCK(lvif);
3850 lvif->lvif_bss_synched = false;
3851 LKPI_80211_LVIF_UNLOCK(lvif);
3852
3853 rni = lvif->iv_update_bss(vap, ni);
3854 return (rni);
3855 }
3856
3857 #ifdef LKPI_80211_WME
3858 static int
lkpi_wme_update(struct lkpi_hw * lhw,struct ieee80211vap * vap,bool planned)3859 lkpi_wme_update(struct lkpi_hw *lhw, struct ieee80211vap *vap, bool planned)
3860 {
3861 struct ieee80211com *ic;
3862 struct ieee80211_hw *hw;
3863 struct lkpi_vif *lvif;
3864 struct ieee80211_vif *vif;
3865 struct chanAccParams chp;
3866 struct wmeParams wmeparr[WME_NUM_AC];
3867 struct ieee80211_tx_queue_params txqp;
3868 enum ieee80211_bss_changed bss_changed;
3869 int error;
3870 uint16_t ac;
3871
3872 hw = LHW_TO_HW(lhw);
3873 lockdep_assert_wiphy(hw->wiphy);
3874
3875 IMPROVE();
3876 KASSERT(WME_NUM_AC == IEEE80211_NUM_ACS, ("%s: WME_NUM_AC %d != "
3877 "IEEE80211_NUM_ACS %d\n", __func__, WME_NUM_AC, IEEE80211_NUM_ACS));
3878
3879 if (vap == NULL)
3880 return (0);
3881
3882 if ((vap->iv_flags & IEEE80211_F_WME) == 0)
3883 return (0);
3884
3885 if (lhw->ops->conf_tx == NULL)
3886 return (0);
3887
3888 if (!planned && (vap->iv_state != IEEE80211_S_RUN)) {
3889 lhw->update_wme = true;
3890 return (0);
3891 }
3892 lhw->update_wme = false;
3893
3894 ic = lhw->ic;
3895 ieee80211_wme_ic_getparams(ic, &chp);
3896 IEEE80211_LOCK(ic);
3897 for (ac = 0; ac < WME_NUM_AC; ac++)
3898 wmeparr[ac] = chp.cap_wmeParams[ac];
3899 IEEE80211_UNLOCK(ic);
3900
3901 lvif = VAP_TO_LVIF(vap);
3902 vif = LVIF_TO_VIF(lvif);
3903
3904 /* Configure tx queues (conf_tx) & send BSS_CHANGED_QOS. */
3905 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
3906 struct wmeParams *wmep;
3907
3908 wmep = &wmeparr[ac];
3909 bzero(&txqp, sizeof(txqp));
3910 txqp.cw_min = wmep->wmep_logcwmin;
3911 txqp.cw_max = wmep->wmep_logcwmax;
3912 txqp.txop = wmep->wmep_txopLimit;
3913 txqp.aifs = wmep->wmep_aifsn;
3914 error = lkpi_80211_mo_conf_tx(hw, vif, /* link_id */0, ac, &txqp);
3915 if (error != 0)
3916 ic_printf(ic, "%s: conf_tx ac %u failed %d\n",
3917 __func__, ac, error);
3918 }
3919 bss_changed = BSS_CHANGED_QOS;
3920 if (!planned)
3921 lkpi_bss_info_change(hw, vif, bss_changed);
3922
3923 return (bss_changed);
3924 }
3925 #endif
3926
3927 static int
lkpi_ic_wme_update(struct ieee80211com * ic)3928 lkpi_ic_wme_update(struct ieee80211com *ic)
3929 {
3930 #ifdef LKPI_80211_WME
3931 struct ieee80211vap *vap;
3932 struct lkpi_hw *lhw;
3933 struct ieee80211_hw *hw;
3934
3935 IMPROVE("Use the per-VAP callback in net80211.");
3936 vap = TAILQ_FIRST(&ic->ic_vaps);
3937 if (vap == NULL)
3938 return (0);
3939
3940 lhw = ic->ic_softc;
3941 hw = LHW_TO_HW(lhw);
3942
3943 wiphy_lock(hw->wiphy);
3944 lkpi_wme_update(lhw, vap, false);
3945 wiphy_unlock(hw->wiphy);
3946 #endif
3947 return (0); /* unused */
3948 }
3949
3950 static void
lkpi_iv_sta_recv_mgmt(struct ieee80211_node * ni,struct mbuf * m0,int subtype,const struct ieee80211_rx_stats * rxs,int rssi,int nf)3951 lkpi_iv_sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
3952 int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
3953 {
3954 struct lkpi_hw *lhw;
3955 struct ieee80211_hw *hw;
3956 struct lkpi_vif *lvif;
3957 struct ieee80211_vif *vif;
3958 enum ieee80211_bss_changed bss_changed;
3959
3960 lvif = VAP_TO_LVIF(ni->ni_vap);
3961 vif = LVIF_TO_VIF(lvif);
3962
3963 lvif->iv_recv_mgmt(ni, m0, subtype, rxs, rssi, nf);
3964
3965 switch (subtype) {
3966 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
3967 break;
3968 case IEEE80211_FC0_SUBTYPE_BEACON:
3969 /*
3970 * Only count beacons when assoc. SCAN has its own logging.
3971 * This is for connection/beacon loss/session protection almost
3972 * over debugging when trying to get into a stable RUN state.
3973 */
3974 if (vif->cfg.assoc)
3975 lvif->beacons++;
3976 break;
3977 default:
3978 return;
3979 }
3980
3981 lhw = ni->ni_ic->ic_softc;
3982 hw = LHW_TO_HW(lhw);
3983
3984 /*
3985 * If this direct call to mo_bss_info_changed will not work due to
3986 * locking, see if queue_work() is fast enough.
3987 */
3988 bss_changed = lkpi_update_dtim_tsf(vif, ni, ni->ni_vap, __func__, __LINE__);
3989 lkpi_bss_info_change(hw, vif, bss_changed);
3990 }
3991
3992 /*
3993 * Change link-layer address on the vif (if the vap is not started/"UP").
3994 * This can happen if a user changes 'ether' using ifconfig.
3995 * The code is based on net80211/ieee80211_freebsd.c::wlan_iflladdr() but
3996 * we do use a per-[l]vif event handler to be sure we exist as we
3997 * cannot assume that from every vap derives a vif and we have a hard
3998 * time checking based on net80211 information.
3999 * Should this ever become a real problem we could add a callback function
4000 * to wlan_iflladdr() to be set optionally but that would be for a
4001 * single-consumer (or needs a list) -- was just too complicated for an
4002 * otherwise perfect mechanism FreeBSD already provides.
4003 */
4004 static void
lkpi_vif_iflladdr(void * arg,struct ifnet * ifp)4005 lkpi_vif_iflladdr(void *arg, struct ifnet *ifp)
4006 {
4007 struct epoch_tracker et;
4008 struct ieee80211_vif *vif;
4009
4010 NET_EPOCH_ENTER(et);
4011 /* NB: identify vap's by if_transmit; left as an extra check. */
4012 if (if_gettransmitfn(ifp) != ieee80211_vap_transmit ||
4013 (if_getflags(ifp) & IFF_UP) != 0) {
4014 NET_EPOCH_EXIT(et);
4015 return;
4016 }
4017
4018 vif = arg;
4019 IEEE80211_ADDR_COPY(vif->bss_conf.addr, if_getlladdr(ifp));
4020 NET_EPOCH_EXIT(et);
4021 }
4022
4023 static struct ieee80211vap *
lkpi_ic_vap_create(struct ieee80211com * ic,const char name[IFNAMSIZ],int unit,enum ieee80211_opmode opmode,int flags,const uint8_t bssid[IEEE80211_ADDR_LEN],const uint8_t mac[IEEE80211_ADDR_LEN])4024 lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
4025 int unit, enum ieee80211_opmode opmode, int flags,
4026 const uint8_t bssid[IEEE80211_ADDR_LEN],
4027 const uint8_t mac[IEEE80211_ADDR_LEN])
4028 {
4029 struct lkpi_hw *lhw;
4030 struct ieee80211_hw *hw;
4031 struct lkpi_vif *lvif;
4032 struct ieee80211vap *vap;
4033 struct ieee80211_vif *vif;
4034 struct ieee80211_tx_queue_params txqp;
4035 enum ieee80211_bss_changed bss_changed;
4036 struct sysctl_oid *node;
4037 size_t len;
4038 int error, i;
4039 uint16_t ac;
4040
4041 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* 1 so far. Add <n> once this works. */
4042 return (NULL);
4043
4044 lhw = ic->ic_softc;
4045 hw = LHW_TO_HW(lhw);
4046
4047 len = sizeof(*lvif);
4048 len += hw->vif_data_size; /* vif->drv_priv */
4049
4050 lvif = malloc(len, M_80211_VAP, M_WAITOK | M_ZERO);
4051 mtx_init(&lvif->mtx, "lvif", NULL, MTX_DEF);
4052 TASK_INIT(&lvif->sw_scan_task, 0, lkpi_sw_scan_task, lvif);
4053 INIT_LIST_HEAD(&lvif->lsta_list);
4054 lvif->lvif_bss = NULL;
4055 refcount_init(&lvif->nt_unlocked, 0);
4056 lvif->lvif_bss_synched = false;
4057 vap = LVIF_TO_VAP(lvif);
4058
4059 vif = LVIF_TO_VIF(lvif);
4060 memcpy(vif->addr, mac, IEEE80211_ADDR_LEN);
4061 vif->p2p = false;
4062 vif->probe_req_reg = false;
4063 vif->type = lkpi_opmode_to_vif_type(opmode);
4064 lvif->wdev.iftype = vif->type;
4065 /* Need to fill in other fields as well. */
4066 IMPROVE();
4067
4068 /* Create a chanctx to be used later. */
4069 IMPROVE("lkpi_alloc_lchanctx reserved as many as can be");
4070 (void) lkpi_find_lchanctx_reserved(hw, lvif);
4071
4072 /* XXX-BZ hardcoded for now! */
4073 #if 1
4074 RCU_INIT_POINTER(vif->bss_conf.chanctx_conf, NULL);
4075 vif->bss_conf.vif = vif;
4076 /* vap->iv_myaddr is not set until net80211::vap_setup or vap_attach. */
4077 IEEE80211_ADDR_COPY(vif->bss_conf.addr, mac);
4078 lvif->lvif_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
4079 lkpi_vif_iflladdr, vif, EVENTHANDLER_PRI_ANY);
4080 vif->bss_conf.link_id = 0; /* Non-MLO operation. */
4081 vif->bss_conf.chanreq.oper.chan = lhw->dflt_chandef.chan;
4082 vif->bss_conf.chanreq.oper.width = NL80211_CHAN_WIDTH_20_NOHT;
4083 vif->bss_conf.use_short_preamble = false; /* vap->iv_flags IEEE80211_F_SHPREAMBLE */
4084 vif->bss_conf.use_short_slot = false; /* vap->iv_flags IEEE80211_F_SHSLOT */
4085 vif->bss_conf.qos = false;
4086 vif->bss_conf.use_cts_prot = false; /* vap->iv_protmode */
4087 vif->bss_conf.ht_operation_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
4088 IEEE80211_ADDR_COPY(vif->cfg.ap_addr, ieee80211broadcastaddr);
4089 vif->cfg.aid = 0;
4090 vif->cfg.assoc = false;
4091 vif->cfg.idle = true;
4092 vif->cfg.ps = false;
4093 IMPROVE("Check other fields and then figure out whats is left elsewhere of them");
4094 /*
4095 * We need to initialize it to something as the bss_info_changed call
4096 * will try to copy from it in iwlwifi and NULL is a panic.
4097 * We will set the proper one in scan_to_auth() before being assoc.
4098 */
4099 vif->bss_conf.bssid = ieee80211broadcastaddr;
4100 #endif
4101 #if 0
4102 vif->bss_conf.dtim_period = 0; /* IEEE80211_DTIM_DEFAULT ; must stay 0. */
4103 IEEE80211_ADDR_COPY(vif->bss_conf.bssid, bssid);
4104 vif->bss_conf.beacon_int = ic->ic_bintval;
4105 /* iwlwifi bug. */
4106 if (vif->bss_conf.beacon_int < 16)
4107 vif->bss_conf.beacon_int = 16;
4108 #endif
4109
4110 /* Link Config */
4111 vif->link_conf[0] = &vif->bss_conf;
4112 for (i = 0; i < nitems(vif->link_conf); i++) {
4113 IMPROVE("more than 1 link one day");
4114 }
4115
4116 /* Setup queue defaults; driver may override in (*add_interface). */
4117 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
4118 if (ieee80211_hw_check(hw, QUEUE_CONTROL))
4119 vif->hw_queue[i] = IEEE80211_INVAL_HW_QUEUE;
4120 else if (hw->queues >= IEEE80211_NUM_ACS)
4121 vif->hw_queue[i] = i;
4122 else
4123 vif->hw_queue[i] = 0;
4124
4125 /* Initialize the queue to running. Stopped? */
4126 lvif->hw_queue_stopped[i] = false;
4127 }
4128 vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
4129
4130 IMPROVE();
4131
4132 wiphy_lock(hw->wiphy);
4133 error = lkpi_80211_mo_start(hw);
4134 if (error != 0) {
4135 wiphy_unlock(hw->wiphy);
4136 ic_printf(ic, "%s: failed to start hw: %d\n", __func__, error);
4137 mtx_destroy(&lvif->mtx);
4138 free(lvif, M_80211_VAP);
4139 return (NULL);
4140 }
4141
4142 error = lkpi_80211_mo_add_interface(hw, vif);
4143 if (error != 0) {
4144 IMPROVE(); /* XXX-BZ mo_stop()? */
4145 wiphy_unlock(hw->wiphy);
4146 ic_printf(ic, "%s: failed to add interface: %d\n", __func__, error);
4147 mtx_destroy(&lvif->mtx);
4148 free(lvif, M_80211_VAP);
4149 return (NULL);
4150 }
4151 wiphy_unlock(hw->wiphy);
4152
4153 LKPI_80211_LHW_LVIF_LOCK(lhw);
4154 TAILQ_INSERT_TAIL(&lhw->lvif_head, lvif, lvif_entry);
4155 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
4156
4157 /* Set bss_info. */
4158 bss_changed = 0;
4159 lkpi_bss_info_change(hw, vif, bss_changed);
4160
4161 /* Configure tx queues (conf_tx), default WME & send BSS_CHANGED_QOS. */
4162 IMPROVE("Hardcoded values; to fix see 802.11-2016, 9.4.2.29 EDCA Parameter Set element");
4163 wiphy_lock(hw->wiphy);
4164 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
4165
4166 bzero(&txqp, sizeof(txqp));
4167 txqp.cw_min = 15;
4168 txqp.cw_max = 1023;
4169 txqp.txop = 0;
4170 txqp.aifs = 2;
4171 error = lkpi_80211_mo_conf_tx(hw, vif, /* link_id */0, ac, &txqp);
4172 if (error != 0)
4173 ic_printf(ic, "%s: conf_tx ac %u failed %d\n",
4174 __func__, ac, error);
4175 }
4176 wiphy_unlock(hw->wiphy);
4177 bss_changed = BSS_CHANGED_QOS;
4178 lkpi_bss_info_change(hw, vif, bss_changed);
4179
4180 /* Force MC init. */
4181 lkpi_update_mcast_filter(ic);
4182
4183 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
4184
4185 /* Now we have a valid vap->iv_ifp. Any checksum offloading goes below. */
4186
4187 IMPROVE();
4188
4189 /* Override with LinuxKPI method so we can drive mac80211/cfg80211. */
4190 lvif->iv_newstate = vap->iv_newstate;
4191 vap->iv_newstate = lkpi_iv_newstate;
4192 lvif->iv_update_bss = vap->iv_update_bss;
4193 vap->iv_update_bss = lkpi_iv_update_bss;
4194 lvif->iv_recv_mgmt = vap->iv_recv_mgmt;
4195 vap->iv_recv_mgmt = lkpi_iv_sta_recv_mgmt;
4196
4197 #ifdef LKPI_80211_HW_CRYPTO
4198 /* Key management. */
4199 if (lkpi_hwcrypto && lhw->ops->set_key != NULL) {
4200 vap->iv_key_set = lkpi_iv_key_set;
4201 vap->iv_key_delete = lkpi_iv_key_delete;
4202 vap->iv_key_update_begin = lkpi_iv_key_update_begin;
4203 vap->iv_key_update_end = lkpi_iv_key_update_end;
4204 }
4205 #endif
4206
4207 #ifdef LKPI_80211_HT
4208 /* Stay with the iv_ampdu_rxmax,limit / iv_ampdu_density defaults until later. */
4209 #endif
4210
4211 ieee80211_ratectl_init(vap);
4212
4213 /* Complete setup. */
4214 ieee80211_vap_attach(vap, ieee80211_media_change,
4215 ieee80211_media_status, mac);
4216
4217 #ifdef LKPI_80211_HT
4218 /*
4219 * Modern chipset/fw/drv will do A-MPDU in drv/fw and fail
4220 * to do so if they cannot do the crypto too.
4221 */
4222 if (!lkpi_hwcrypto && IEEE80211_CONF_AMPDU_OFFLOAD(ic))
4223 vap->iv_flags_ht &= ~IEEE80211_FHT_AMPDU_RX;
4224 #endif
4225
4226 if (hw->max_listen_interval == 0)
4227 hw->max_listen_interval = 7 * (ic->ic_lintval / ic->ic_bintval);
4228 hw->conf.listen_interval = hw->max_listen_interval;
4229
4230 /* XXX-BZ do we need to be able to update these? */
4231 hw->wiphy->frag_threshold = vap->iv_fragthreshold;
4232 lkpi_80211_mo_set_frag_threshold(hw, vap->iv_fragthreshold);
4233 hw->wiphy->rts_threshold = vap->iv_rtsthreshold;
4234 lkpi_80211_mo_set_rts_threshold(hw, vap->iv_rtsthreshold);
4235 /* any others? */
4236
4237 /* Add per-VIF/VAP sysctls. */
4238 sysctl_ctx_init(&lvif->sysctl_ctx);
4239
4240 node = SYSCTL_ADD_NODE(&lvif->sysctl_ctx,
4241 SYSCTL_CHILDREN(&sysctl___compat_linuxkpi_80211),
4242 OID_AUTO, if_name(vap->iv_ifp),
4243 CTLFLAG_RD | CTLFLAG_SKIP | CTLFLAG_MPSAFE, NULL, "VIF Information");
4244
4245 SYSCTL_ADD_PROC(&lvif->sysctl_ctx,
4246 SYSCTL_CHILDREN(node), OID_AUTO, "dump_stas",
4247 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, lvif, 0,
4248 lkpi_80211_dump_stas, "A", "Dump sta statistics of this vif");
4249 SYSCTL_ADD_PROC(&lvif->sysctl_ctx,
4250 SYSCTL_CHILDREN(node), OID_AUTO, "dump_stas_queues",
4251 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_SKIP, lvif, 0,
4252 lkpi_80211_dump_sta_queues, "A",
4253 "Dump queue statistics for any sta of this vif");
4254
4255 IMPROVE();
4256
4257 return (vap);
4258 }
4259
4260 void
linuxkpi_ieee80211_unregister_hw(struct ieee80211_hw * hw)4261 linuxkpi_ieee80211_unregister_hw(struct ieee80211_hw *hw)
4262 {
4263
4264 wiphy_unregister(hw->wiphy);
4265 linuxkpi_ieee80211_ifdetach(hw);
4266
4267 IMPROVE();
4268 }
4269
4270 void
linuxkpi_ieee80211_restart_hw(struct ieee80211_hw * hw)4271 linuxkpi_ieee80211_restart_hw(struct ieee80211_hw *hw)
4272 {
4273
4274 TODO();
4275 }
4276
4277 static void
lkpi_ic_vap_delete(struct ieee80211vap * vap)4278 lkpi_ic_vap_delete(struct ieee80211vap *vap)
4279 {
4280 struct ieee80211com *ic;
4281 struct lkpi_hw *lhw;
4282 struct ieee80211_hw *hw;
4283 struct lkpi_vif *lvif;
4284 struct ieee80211_vif *vif;
4285
4286 lvif = VAP_TO_LVIF(vap);
4287 vif = LVIF_TO_VIF(lvif);
4288 ic = vap->iv_ic;
4289 lhw = ic->ic_softc;
4290 hw = LHW_TO_HW(lhw);
4291
4292 EVENTHANDLER_DEREGISTER(iflladdr_event, lvif->lvif_ifllevent);
4293
4294 /* Clear up per-VIF/VAP sysctls. */
4295 sysctl_ctx_free(&lvif->sysctl_ctx);
4296
4297 ieee80211_draintask(ic, &lvif->sw_scan_task);
4298
4299 LKPI_80211_LHW_LVIF_LOCK(lhw);
4300 TAILQ_REMOVE(&lhw->lvif_head, lvif, lvif_entry);
4301 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
4302
4303 ieee80211_ratectl_deinit(vap);
4304 ieee80211_vap_detach(vap);
4305
4306 IMPROVE("clear up other bits in this state");
4307
4308 lkpi_80211_mo_remove_interface(hw, vif);
4309
4310 /* Single VAP, so we can do this here. */
4311 lkpi_80211_mo_stop(hw, false); /* XXX SUSPEND */
4312
4313 mtx_destroy(&lvif->mtx);
4314 free(lvif, M_80211_VAP);
4315 }
4316
4317 static void
lkpi_ic_update_mcast(struct ieee80211com * ic)4318 lkpi_ic_update_mcast(struct ieee80211com *ic)
4319 {
4320 struct ieee80211vap *vap;
4321 struct lkpi_hw *lhw;
4322
4323 lhw = ic->ic_softc;
4324
4325 LKPI_80211_LHW_MC_LOCK(lhw);
4326 /* Cleanup anything on the current list. */
4327 lkpi_cleanup_mcast_list_locked(lhw);
4328
4329 /* Build up the new list (or allmulti). */
4330 if (ic->ic_allmulti == 0) {
4331 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
4332 if_foreach_llmaddr(vap->iv_ifp,
4333 lkpi_ic_update_mcast_copy, &lhw->mc_list);
4334 lhw->mc_all_multi = false;
4335 } else {
4336 lhw->mc_all_multi = true;
4337 }
4338 LKPI_80211_LHW_MC_UNLOCK(lhw);
4339
4340 lkpi_update_mcast_filter(ic);
4341 TRACEOK();
4342 }
4343
4344 static void
lkpi_ic_update_promisc(struct ieee80211com * ic)4345 lkpi_ic_update_promisc(struct ieee80211com *ic)
4346 {
4347
4348 UNIMPLEMENTED;
4349 }
4350
4351 static void
lkpi_ic_update_chw(struct ieee80211com * ic)4352 lkpi_ic_update_chw(struct ieee80211com *ic)
4353 {
4354
4355 UNIMPLEMENTED;
4356 }
4357
4358 /* Start / stop device. */
4359 static void
lkpi_ic_parent(struct ieee80211com * ic)4360 lkpi_ic_parent(struct ieee80211com *ic)
4361 {
4362 struct lkpi_hw *lhw;
4363 struct ieee80211_hw *hw;
4364 #ifdef HW_START_STOP
4365 int error;
4366 #endif
4367 bool start_all;
4368
4369 IMPROVE();
4370
4371 lhw = ic->ic_softc;
4372 hw = LHW_TO_HW(lhw);
4373 start_all = false;
4374
4375 /* IEEE80211_UNLOCK(ic); */
4376 wiphy_lock(hw->wiphy);
4377 if (ic->ic_nrunning > 0) {
4378 #ifdef HW_START_STOP
4379 error = lkpi_80211_mo_start(hw);
4380 if (error == 0)
4381 #endif
4382 start_all = true;
4383 } else {
4384 #ifdef HW_START_STOP
4385 lkpi_80211_mo_stop(hw, false); /* XXX SUSPEND */
4386 #endif
4387 }
4388 wiphy_unlock(hw->wiphy);
4389 /* IEEE80211_LOCK(ic); */
4390
4391 if (start_all)
4392 ieee80211_start_all(ic);
4393 }
4394
4395 bool
linuxkpi_ieee80211_is_ie_id_in_ie_buf(const u8 ie,const u8 * ie_ids,size_t ie_ids_len)4396 linuxkpi_ieee80211_is_ie_id_in_ie_buf(const u8 ie, const u8 *ie_ids,
4397 size_t ie_ids_len)
4398 {
4399 int i;
4400
4401 for (i = 0; i < ie_ids_len; i++) {
4402 if (ie == *ie_ids)
4403 return (true);
4404 }
4405
4406 return (false);
4407 }
4408
4409 /* Return true if skipped; false if error. */
4410 bool
linuxkpi_ieee80211_ie_advance(size_t * xp,const u8 * ies,size_t ies_len)4411 linuxkpi_ieee80211_ie_advance(size_t *xp, const u8 *ies, size_t ies_len)
4412 {
4413 size_t x;
4414 uint8_t l;
4415
4416 x = *xp;
4417
4418 KASSERT(x < ies_len, ("%s: x %zu ies_len %zu ies %p\n",
4419 __func__, x, ies_len, ies));
4420 l = ies[x + 1];
4421 x += 2 + l;
4422
4423 if (x > ies_len)
4424 return (false);
4425
4426 *xp = x;
4427 return (true);
4428 }
4429
4430 static uint8_t *
lkpi_scan_ies_add(uint8_t * p,struct ieee80211_scan_ies * scan_ies,uint32_t band_mask,struct ieee80211vap * vap,struct ieee80211_hw * hw)4431 lkpi_scan_ies_add(uint8_t *p, struct ieee80211_scan_ies *scan_ies,
4432 uint32_t band_mask, struct ieee80211vap *vap, struct ieee80211_hw *hw)
4433 {
4434 struct ieee80211_supported_band *supband;
4435 struct linuxkpi_ieee80211_channel *channels;
4436 struct ieee80211com *ic;
4437 const struct ieee80211_channel *chan;
4438 const struct ieee80211_rateset *rs;
4439 uint8_t *pb;
4440 int band, i;
4441
4442 ic = vap->iv_ic;
4443 for (band = 0; band < NUM_NL80211_BANDS; band++) {
4444 if ((band_mask & (1 << band)) == 0)
4445 continue;
4446
4447 supband = hw->wiphy->bands[band];
4448 /*
4449 * This should not happen;
4450 * band_mask is a bitmask of valid bands to scan on.
4451 */
4452 if (supband == NULL || supband->n_channels == 0)
4453 continue;
4454
4455 /* Find a first channel to get the mode and rates from. */
4456 channels = supband->channels;
4457 chan = NULL;
4458 for (i = 0; i < supband->n_channels; i++) {
4459 uint32_t flags;
4460
4461 if (channels[i].flags & IEEE80211_CHAN_DISABLED)
4462 continue;
4463
4464 flags = 0;
4465 switch (band) {
4466 case NL80211_BAND_2GHZ:
4467 flags |= IEEE80211_CHAN_G;
4468 break;
4469 case NL80211_BAND_5GHZ:
4470 flags |= IEEE80211_CHAN_A;
4471 break;
4472 default:
4473 panic("%s:%d: unupported band %d\n",
4474 __func__, __LINE__, band);
4475 }
4476
4477 chan = ieee80211_find_channel(ic,
4478 channels[i].center_freq, flags);
4479 if (chan != NULL)
4480 break;
4481 }
4482
4483 /* This really should not happen. */
4484 if (chan == NULL)
4485 continue;
4486
4487 pb = p;
4488 rs = ieee80211_get_suprates(ic, chan); /* calls chan2mode */
4489 p = ieee80211_add_rates(p, rs);
4490 p = ieee80211_add_xrates(p, rs);
4491
4492 #if defined(LKPI_80211_HT)
4493 if ((vap->iv_flags_ht & IEEE80211_FHT_HT) != 0) {
4494 struct ieee80211_channel *c;
4495
4496 c = ieee80211_ht_adjust_channel(ic, ic->ic_curchan,
4497 vap->iv_flags_ht);
4498 p = ieee80211_add_htcap_ch(p, vap, c);
4499 }
4500 #endif
4501 #if defined(LKPI_80211_VHT)
4502 if (band == NL80211_BAND_5GHZ &&
4503 (vap->iv_vht_flags & IEEE80211_FVHT_VHT) != 0) {
4504 struct ieee80211_channel *c;
4505
4506 c = ieee80211_ht_adjust_channel(ic, ic->ic_curchan,
4507 vap->iv_flags_ht);
4508 c = ieee80211_vht_adjust_channel(ic, c,
4509 vap->iv_vht_flags);
4510 p = ieee80211_add_vhtcap_ch(p, vap, c);
4511 }
4512 #endif
4513
4514 scan_ies->ies[band] = pb;
4515 scan_ies->len[band] = p - pb;
4516 }
4517
4518 /* Add common_ies */
4519 pb = p;
4520 if ((vap->iv_flags & IEEE80211_F_WPA1) != 0 &&
4521 vap->iv_wpa_ie != NULL) {
4522 memcpy(p, vap->iv_wpa_ie, 2 + vap->iv_wpa_ie[1]);
4523 p += 2 + vap->iv_wpa_ie[1];
4524 }
4525 if (vap->iv_appie_probereq != NULL) {
4526 memcpy(p, vap->iv_appie_probereq->ie_data,
4527 vap->iv_appie_probereq->ie_len);
4528 p += vap->iv_appie_probereq->ie_len;
4529 }
4530 scan_ies->common_ies = pb;
4531 scan_ies->common_ie_len = p - pb;
4532
4533 return (p);
4534 }
4535
4536 static void
lkpi_enable_hw_scan(struct lkpi_hw * lhw)4537 lkpi_enable_hw_scan(struct lkpi_hw *lhw)
4538 {
4539
4540 if (lhw->ops->hw_scan) {
4541 /*
4542 * Advertise full-offload scanning.
4543 *
4544 * Not limiting to SINGLE_SCAN_ON_ALL_BANDS here as otherwise
4545 * we essentially disable hw_scan for all drivers not setting
4546 * the flag.
4547 */
4548 lhw->ic->ic_flags_ext |= IEEE80211_FEXT_SCAN_OFFLOAD;
4549 lhw->scan_flags |= LKPI_LHW_SCAN_HW;
4550 }
4551 }
4552
4553 #ifndef LKPI_80211_USE_SCANLIST
4554 static const uint32_t chan_pri[] = {
4555 5180, 5500, 5745,
4556 5260, 5580, 5660, 5825,
4557 5220, 5300, 5540, 5620, 5700, 5785, 5865,
4558 2437, 2412, 2422, 2462, 2472, 2432, 2452
4559 };
4560
4561 static int
lkpi_scan_chan_list_idx(const struct linuxkpi_ieee80211_channel * lc)4562 lkpi_scan_chan_list_idx(const struct linuxkpi_ieee80211_channel *lc)
4563 {
4564 int i;
4565
4566 for (i = 0; i < nitems(chan_pri); i++) {
4567 if (lc->center_freq == chan_pri[i])
4568 return (i);
4569 }
4570
4571 return (-1);
4572 }
4573
4574 static int
lkpi_scan_chan_list_comp(const struct linuxkpi_ieee80211_channel * lc1,const struct linuxkpi_ieee80211_channel * lc2)4575 lkpi_scan_chan_list_comp(const struct linuxkpi_ieee80211_channel *lc1,
4576 const struct linuxkpi_ieee80211_channel *lc2)
4577 {
4578 int idx1, idx2;
4579
4580 /* Find index in list. */
4581 idx1 = lkpi_scan_chan_list_idx(lc1);
4582 idx2 = lkpi_scan_chan_list_idx(lc2);
4583
4584 if (idx1 == -1 && idx2 != -1)
4585 return (1);
4586 if (idx1 != -1 && idx2 == -1)
4587 return (-1);
4588
4589 /* Neither on the list, use center_freq. */
4590 if (idx1 == -1 && idx2 == -1)
4591 return (lc1->center_freq - lc2->center_freq);
4592
4593 /* Whichever is first in the list. */
4594 return (idx1 - idx2);
4595 }
4596
4597 static void
lkpi_scan_chan_list_resort(struct linuxkpi_ieee80211_channel ** cpp,size_t nchan)4598 lkpi_scan_chan_list_resort(struct linuxkpi_ieee80211_channel **cpp, size_t nchan)
4599 {
4600 struct linuxkpi_ieee80211_channel *lc, *nc;
4601 size_t i, j;
4602 int rc;
4603
4604 for (i = (nchan - 1); i > 0; i--) {
4605 for (j = i; j > 0 ; j--) {
4606 lc = *(cpp + j);
4607 nc = *(cpp + j - 1);
4608 rc = lkpi_scan_chan_list_comp(lc, nc);
4609 if (rc < 0) {
4610 *(cpp + j) = nc;
4611 *(cpp + j - 1) = lc;
4612 }
4613 }
4614 }
4615 }
4616
4617 static bool
lkpi_scan_chan(struct linuxkpi_ieee80211_channel * c,struct ieee80211com * ic,bool log)4618 lkpi_scan_chan(struct linuxkpi_ieee80211_channel *c,
4619 struct ieee80211com *ic, bool log)
4620 {
4621
4622 if ((c->flags & IEEE80211_CHAN_DISABLED) != 0) {
4623 if (log)
4624 TRACE_SCAN(ic, "Skipping disabled chan "
4625 "on band %s [%#x/%u/%#x]",
4626 lkpi_nl80211_band_name(c->band), c->hw_value,
4627 c->center_freq, c->flags);
4628 return (false);
4629 }
4630 if (isclr(ic->ic_chan_active, ieee80211_mhz2ieee(c->center_freq,
4631 lkpi_nl80211_band_to_net80211_band(c->band)))) {
4632 if (log)
4633 TRACE_SCAN(ic, "Skipping !active chan "
4634 "on band %s [%#x/%u/%#x]",
4635 lkpi_nl80211_band_name(c->band), c->hw_value,
4636 c->center_freq, c->flags);
4637 return (false);
4638 }
4639 return (true);
4640 }
4641 #endif
4642
4643 static void
lkpi_ic_scan_start(struct ieee80211com * ic)4644 lkpi_ic_scan_start(struct ieee80211com *ic)
4645 {
4646 struct lkpi_hw *lhw;
4647 struct ieee80211_hw *hw;
4648 struct lkpi_vif *lvif;
4649 struct ieee80211_vif *vif;
4650 struct ieee80211_scan_state *ss;
4651 struct ieee80211vap *vap;
4652 int error;
4653 bool is_hw_scan;
4654
4655 lhw = ic->ic_softc;
4656 ss = ic->ic_scan;
4657 vap = ss->ss_vap;
4658 TRACE_SCAN(ic, "scan_flags %b", lhw->scan_flags, LKPI_LHW_SCAN_BITS);
4659
4660 LKPI_80211_LHW_SCAN_LOCK(lhw);
4661 if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0) {
4662 /* A scan is still running. */
4663 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4664 TRACE_SCAN(ic, "Trying to start new scan while still running; "
4665 "cancelling new net80211 scan; scan_flags %b",
4666 lhw->scan_flags, LKPI_LHW_SCAN_BITS);
4667 ieee80211_cancel_scan(vap);
4668 return;
4669 }
4670 is_hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
4671 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4672
4673 #if 0
4674 if (vap->iv_state != IEEE80211_S_SCAN) {
4675 TODO("We need to be able to scan if not in S_SCAN");
4676 TRACE_SCAN(ic, "scan_flags %b iv_state %d",
4677 lhw->scan_flags, LKPI_LHW_SCAN_BITS, vap->iv_state);
4678 ieee80211_cancel_scan(vap);
4679 return;
4680 }
4681 #endif
4682
4683 hw = LHW_TO_HW(lhw);
4684 if (!is_hw_scan) {
4685 /* If hw_scan is cleared clear FEXT_SCAN_OFFLOAD too. */
4686 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCAN_OFFLOAD;
4687
4688 lvif = VAP_TO_LVIF(vap);
4689 vif = LVIF_TO_VIF(lvif);
4690
4691 if (vap->iv_state == IEEE80211_S_SCAN)
4692 lkpi_hw_conf_idle(hw, false);
4693
4694 LKPI_80211_LHW_SCAN_LOCK(lhw);
4695 lhw->scan_flags |= LKPI_LHW_SCAN_RUNNING;
4696 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4697
4698 lkpi_update_mcast_filter(ic);
4699
4700 TRACE_SCAN(vap->iv_ic, "Starting SW_SCAN: scan_flags %b",
4701 lhw->scan_flags, LKPI_LHW_SCAN_BITS);
4702 lkpi_80211_mo_sw_scan_start(hw, vif, vif->addr);
4703 /* net80211::scan_start() handled PS for us. */
4704 IMPROVE();
4705 /* XXX Also means it is too late to flush queues?
4706 * need to check iv_sta_ps or overload? */
4707 /* XXX want to adjust ss end time/ maxdwell? */
4708
4709 } else {
4710 struct ieee80211_scan_request *hw_req;
4711 struct linuxkpi_ieee80211_channel *lc, **cpp;
4712 struct cfg80211_ssid *ssids;
4713 struct cfg80211_scan_6ghz_params *s6gp;
4714 size_t chan_len, nchan, ssids_len, s6ghzlen;
4715 int band, i, ssid_count, common_ie_len;
4716 #ifndef LKPI_80211_USE_SCANLIST
4717 int n;
4718 #endif
4719 uint32_t band_mask;
4720 uint8_t *ie, *ieend;
4721 bool running;
4722
4723 ssid_count = min(ss->ss_nssid, hw->wiphy->max_scan_ssids);
4724 ssids_len = ssid_count * sizeof(*ssids);
4725 s6ghzlen = 0 * (sizeof(*s6gp)); /* XXX-BZ */
4726
4727 band_mask = 0;
4728 nchan = 0;
4729 if (ieee80211_hw_check(hw, SINGLE_SCAN_ON_ALL_BANDS)) {
4730 #ifdef LKPI_80211_USE_SCANLIST
4731 /* Avoid net80211 scan lists until it has proper scan offload support. */
4732 for (i = ss->ss_next; i < ss->ss_last; i++) {
4733 nchan++;
4734 band = lkpi_net80211_chan_to_nl80211_band(
4735 ss->ss_chans[ss->ss_next + i]);
4736 band_mask |= (1 << band);
4737 }
4738 #else
4739 /* Instead we scan for all channels all the time. */
4740 for (band = 0; band < NUM_NL80211_BANDS; band++) {
4741 switch (band) {
4742 case NL80211_BAND_2GHZ:
4743 case NL80211_BAND_5GHZ:
4744 break;
4745 default:
4746 continue;
4747 }
4748 if (hw->wiphy->bands[band] != NULL) {
4749 struct linuxkpi_ieee80211_channel *channels;
4750 int n;
4751
4752 band_mask |= (1 << band);
4753
4754 channels = hw->wiphy->bands[band]->channels;
4755 n = hw->wiphy->bands[band]->n_channels;
4756 for (i = 0; i < n; i++) {
4757 if (lkpi_scan_chan(&channels[i], ic, true))
4758 nchan++;
4759 }
4760 }
4761 }
4762 #endif
4763 } else {
4764 IMPROVE("individual band scans not yet supported, only scanning first band");
4765 /* In theory net80211 should drive this. */
4766 /* Probably we need to add local logic for now;
4767 * need to deal with scan_complete
4768 * and cancel_scan and keep local state.
4769 * Also cut the nchan down above.
4770 */
4771 /* XXX-BZ ath10k does not set this but still does it? &$%^ */
4772 }
4773
4774 chan_len = nchan * (sizeof(lc) + sizeof(*lc));
4775
4776 common_ie_len = 0;
4777 if ((vap->iv_flags & IEEE80211_F_WPA1) != 0 &&
4778 vap->iv_wpa_ie != NULL)
4779 common_ie_len += vap->iv_wpa_ie[1];
4780 if (vap->iv_appie_probereq != NULL)
4781 common_ie_len += vap->iv_appie_probereq->ie_len;
4782
4783 /* We would love to check this at an earlier stage... */
4784 if (common_ie_len > hw->wiphy->max_scan_ie_len) {
4785 ic_printf(ic, "WARNING: %s: common_ie_len %d > "
4786 "wiphy->max_scan_ie_len %d\n", __func__,
4787 common_ie_len, hw->wiphy->max_scan_ie_len);
4788 }
4789
4790 hw_req = malloc(sizeof(*hw_req) + ssids_len +
4791 s6ghzlen + chan_len + lhw->supbands * lhw->scan_ie_len +
4792 common_ie_len, M_LKPI80211, M_WAITOK | M_ZERO);
4793
4794 hw_req->req.flags = 0; /* XXX ??? */
4795 /* hw_req->req.wdev */
4796 hw_req->req.wiphy = hw->wiphy;
4797 hw_req->req.no_cck = false; /* XXX */
4798
4799 /*
4800 * In general setting duration[_mandatory] seems to pessimise
4801 * default scanning behaviour. We only use it for BGSCANnig
4802 * to keep the dwell times small.
4803 * Setting duration_mandatory makes this the maximum dwell
4804 * time (otherwise may be shorter). Duration is in TU.
4805 */
4806 if ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) != 0) {
4807 unsigned long dwell;
4808
4809 if ((ic->ic_caps & IEEE80211_C_BGSCAN) == 0 ||
4810 (vap->iv_flags & IEEE80211_F_BGSCAN) == 0)
4811 ic_printf(ic, "BGSCAN despite off: %b, %b, %b\n",
4812 ic->ic_flags_ext, IEEE80211_FEXT_BITS,
4813 vap->iv_flags, IEEE80211_F_BITS,
4814 ic->ic_caps, IEEE80211_C_BITS);
4815
4816 dwell = ss->ss_mindwell;
4817 if (dwell == 0)
4818 dwell = msecs_to_ticks(20);
4819
4820 hw_req->req.duration_mandatory = true;
4821 hw_req->req.duration = TICKS_2_USEC(dwell) / 1024;
4822 }
4823
4824 #ifdef __notyet__
4825 hw_req->req.flags |= NL80211_SCAN_FLAG_RANDOM_ADDR;
4826 memcpy(hw_req->req.mac_addr, xxx, IEEE80211_ADDR_LEN);
4827 memset(hw_req->req.mac_addr_mask, 0xxx, IEEE80211_ADDR_LEN);
4828 #endif
4829 eth_broadcast_addr(hw_req->req.bssid);
4830
4831 hw_req->req.n_channels = nchan;
4832 cpp = (struct linuxkpi_ieee80211_channel **)(hw_req + 1);
4833 lc = (struct linuxkpi_ieee80211_channel *)(cpp + nchan);
4834 #ifdef LKPI_80211_USE_SCANLIST
4835 for (i = 0; i < nchan; i++) {
4836 *(cpp + i) =
4837 (struct linuxkpi_ieee80211_channel *)(lc + i);
4838 }
4839 /* Avoid net80211 scan lists until it has proper scan offload support. */
4840 for (i = 0; i < nchan; i++) {
4841 struct ieee80211_channel *c;
4842
4843 c = ss->ss_chans[ss->ss_next + i];
4844 lc->center_freq = c->ic_freq; /* XXX */
4845 /* lc->flags */
4846 lc->band = lkpi_net80211_chan_to_nl80211_band(c);
4847 lc->max_power = c->ic_maxpower;
4848 /* lc-> ... */
4849 lc++;
4850 }
4851 #else
4852 /* Add bands in reverse order for scanning. */
4853 n = 0;
4854 for (band = NUM_NL80211_BANDS - 1; band >= 0; band--) {
4855 struct ieee80211_supported_band *supband;
4856 struct linuxkpi_ieee80211_channel *channels;
4857
4858 /* Band disabled for scanning? */
4859 if ((band_mask & (1 << band)) == 0)
4860 continue;
4861
4862 /* Nothing to scan in band? */
4863 supband = hw->wiphy->bands[band];
4864 if (supband == NULL || supband->n_channels == 0)
4865 continue;
4866
4867 channels = supband->channels;
4868 for (i = 0; i < supband->n_channels; i++) {
4869 if (lkpi_scan_chan(&channels[i], ic, false))
4870 *(cpp + n++) = &channels[i];
4871 }
4872 }
4873 if (lkpi_order_scanlist)
4874 lkpi_scan_chan_list_resort(cpp, nchan);
4875
4876 if ((linuxkpi_debug_80211 & D80211_SCAN) != 0) {
4877 printf("%s:%d: %s SCAN Channel List (nchan=%zu): ",
4878 __func__, __LINE__, ic->ic_name, nchan);
4879 for (i = 0; i < nchan; i++) {
4880 struct linuxkpi_ieee80211_channel *xc;
4881
4882 xc = *(cpp + i);
4883 printf(" %d(%d)",
4884 ieee80211_mhz2ieee(xc->center_freq,
4885 lkpi_nl80211_band_to_net80211_band(
4886 xc->band)),
4887 xc->center_freq);
4888 }
4889 printf("\n");
4890 }
4891 #endif
4892
4893 hw_req->req.n_ssids = ssid_count;
4894 if (hw_req->req.n_ssids > 0) {
4895 ssids = (struct cfg80211_ssid *)lc;
4896 hw_req->req.ssids = ssids;
4897 for (i = 0; i < ssid_count; i++) {
4898 ssids->ssid_len = ss->ss_ssid[i].len;
4899 memcpy(ssids->ssid, ss->ss_ssid[i].ssid,
4900 ss->ss_ssid[i].len);
4901 ssids++;
4902 }
4903 s6gp = (struct cfg80211_scan_6ghz_params *)ssids;
4904 } else {
4905 s6gp = (struct cfg80211_scan_6ghz_params *)lc;
4906 }
4907
4908 /* 6GHz one day. */
4909 hw_req->req.n_6ghz_params = 0;
4910 hw_req->req.scan_6ghz_params = NULL;
4911 hw_req->req.scan_6ghz = false; /* Weird boolean; not what you think. */
4912 /* s6gp->... */
4913
4914 ie = ieend = (uint8_t *)s6gp;
4915 /* Copy per-band IEs, copy common IEs */
4916 ieend = lkpi_scan_ies_add(ie, &hw_req->ies, band_mask, vap, hw);
4917 hw_req->req.ie = ie;
4918 hw_req->req.ie_len = ieend - ie;
4919 hw_req->req.scan_start = jiffies;
4920
4921 lvif = VAP_TO_LVIF(vap);
4922 vif = LVIF_TO_VIF(lvif);
4923
4924 LKPI_80211_LHW_SCAN_LOCK(lhw);
4925 /* Re-check under lock. */
4926 running = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
4927 if (!running) {
4928 KASSERT(lhw->hw_req == NULL, ("%s: ic %p lhw %p hw_req %p "
4929 "!= NULL\n", __func__, ic, lhw, lhw->hw_req));
4930
4931 lhw->scan_flags |= LKPI_LHW_SCAN_RUNNING;
4932 lhw->hw_req = hw_req;
4933 }
4934 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4935 if (running) {
4936 free(hw_req, M_LKPI80211);
4937 TRACE_SCAN(ic, "Trying to start new scan while still "
4938 "running (2); cancelling new net80211 scan; "
4939 "scan_flags %b",
4940 lhw->scan_flags, LKPI_LHW_SCAN_BITS);
4941 ieee80211_cancel_scan(vap);
4942 return;
4943 }
4944
4945 lkpi_update_mcast_filter(ic);
4946 TRACE_SCAN(ic, "Starting HW_SCAN: scan_flags %b, "
4947 "ie_len %d, n_ssids %d, n_chan %d, common_ie_len %d [%d, %d]",
4948 lhw->scan_flags, LKPI_LHW_SCAN_BITS, hw_req->req.ie_len,
4949 hw_req->req.n_ssids, hw_req->req.n_channels,
4950 hw_req->ies.common_ie_len,
4951 hw_req->ies.len[NL80211_BAND_2GHZ],
4952 hw_req->ies.len[NL80211_BAND_5GHZ]);
4953
4954 error = lkpi_80211_mo_hw_scan(hw, vif, hw_req);
4955 if (error != 0) {
4956 bool scan_done;
4957 int e;
4958
4959 TRACE_SCAN(ic, "hw_scan failed; scan_flags %b, error %d",
4960 lhw->scan_flags, LKPI_LHW_SCAN_BITS, error);
4961 ieee80211_cancel_scan(vap);
4962
4963 /*
4964 * ieee80211_scan_completed must be called in either
4965 * case of error or none. So let the free happen there
4966 * and only there.
4967 * That would be fine in theory but in practice drivers
4968 * behave differently:
4969 * ath10k does not return hw_scan until after scan_complete
4970 * and can then still return an error.
4971 * rtw88 can return 1 or -EBUSY without scan_complete
4972 * iwlwifi can return various errors before scan starts
4973 * ...
4974 * So we cannot rely on that behaviour and have to check
4975 * and balance between both code paths.
4976 */
4977 e = 0;
4978 scan_done = true;
4979 LKPI_80211_LHW_SCAN_LOCK(lhw);
4980 if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0) {
4981
4982 free(lhw->hw_req, M_LKPI80211);
4983 lhw->hw_req = NULL;
4984 /*
4985 * The ieee80211_cancel_scan() above runs in a
4986 * taskq and it may take ages for the previous
4987 * scan to clear; starting a new one right away
4988 * we run into the problem that the old one is
4989 * still active.
4990 */
4991 e = msleep(lhw, &lhw->scan_mtx, 0, "lhwscanstop", hz);
4992 scan_done = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
4993
4994 /*
4995 * Now we can clear running if no one else did.
4996 */
4997 lhw->scan_flags &= ~LKPI_LHW_SCAN_RUNNING;
4998 }
4999 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
5000 lkpi_update_mcast_filter(ic);
5001 if (!scan_done) {
5002 ic_printf(ic, "ERROR: %s: timeout/error to wait "
5003 "for ieee80211_cancel_scan: %d\n", __func__, e);
5004 return;
5005 }
5006
5007 /*
5008 * XXX-SIGH magic number.
5009 * rtw88 has a magic "return 1" if offloading scan is
5010 * not possible. Fall back to sw scan in that case.
5011 */
5012 if (error == 1) {
5013 /*
5014 * We need to put this into some defered context
5015 * the net80211 scan may not be done yet
5016 * (ic_flags & IEEE80211_F_SCAN) and we cannot
5017 * wait here; if we do scan_curchan_task always
5018 * runs after our timeout to finalize the scan.
5019 */
5020 ieee80211_runtask(ic, &lvif->sw_scan_task);
5021 return;
5022 }
5023
5024 ic_printf(ic, "ERROR: %s: hw_scan returned %d\n",
5025 __func__, error);
5026 }
5027 }
5028 }
5029
5030 static void
lkpi_sw_scan_task(void * arg,int pending __unused)5031 lkpi_sw_scan_task(void *arg, int pending __unused)
5032 {
5033 struct lkpi_hw *lhw;
5034 struct lkpi_vif *lvif;
5035 struct ieee80211vap *vap;
5036 struct ieee80211_scan_state *ss;
5037
5038 lvif = arg;
5039 vap = LVIF_TO_VAP(lvif);
5040 lhw = vap->iv_ic->ic_softc;
5041 ss = vap->iv_ic->ic_scan;
5042
5043 LKPI_80211_LHW_SCAN_LOCK(lhw);
5044 /*
5045 * We will re-enable this at scan_end calling lkpi_enable_hw_scan().
5046 * IEEE80211_FEXT_SCAN_OFFLOAD will be cleared by lkpi_ic_scan_start.
5047 */
5048 lhw->scan_flags &= ~LKPI_LHW_SCAN_HW;
5049 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
5050
5051 TRACE_SCAN(vap->iv_ic, "Triggering SW_SCAN: pending %d, scan_flags %b",
5052 pending, lhw->scan_flags, LKPI_LHW_SCAN_BITS);
5053
5054 /*
5055 * This will call ic_scan_start() and we will get into the right path
5056 * unless other scans started in between.
5057 */
5058 ieee80211_start_scan(vap,
5059 IEEE80211_SCAN_ONCE,
5060 msecs_to_ticks(10000), /* 10000 ms (=~ 50 chan * 200 ms) */
5061 ss->ss_mindwell ? ss->ss_mindwell : msecs_to_ticks(20),
5062 ss->ss_maxdwell ? ss->ss_maxdwell : msecs_to_ticks(200),
5063 vap->iv_des_nssid, vap->iv_des_ssid);
5064 }
5065
5066 static void
lkpi_ic_scan_end(struct ieee80211com * ic)5067 lkpi_ic_scan_end(struct ieee80211com *ic)
5068 {
5069 struct lkpi_hw *lhw;
5070 bool is_hw_scan;
5071
5072 lhw = ic->ic_softc;
5073 TRACE_SCAN(ic, "scan_flags %b", lhw->scan_flags, LKPI_LHW_SCAN_BITS);
5074
5075 LKPI_80211_LHW_SCAN_LOCK(lhw);
5076 if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) == 0) {
5077 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
5078 return;
5079 }
5080 is_hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
5081 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
5082
5083 if (!is_hw_scan) {
5084 struct ieee80211_scan_state *ss;
5085 struct ieee80211vap *vap;
5086 struct ieee80211_hw *hw;
5087 struct lkpi_vif *lvif;
5088 struct ieee80211_vif *vif;
5089
5090 ss = ic->ic_scan;
5091 vap = ss->ss_vap;
5092 hw = LHW_TO_HW(lhw);
5093 lvif = VAP_TO_LVIF(vap);
5094 vif = LVIF_TO_VIF(lvif);
5095
5096 lkpi_80211_mo_sw_scan_complete(hw, vif);
5097
5098 /* Send PS to stop buffering if n80211 does not for us? */
5099
5100 if (vap->iv_state == IEEE80211_S_SCAN)
5101 lkpi_hw_conf_idle(hw, true);
5102 }
5103
5104 /*
5105 * In case we disabled the hw_scan in lkpi_ic_scan_start() and
5106 * switched to swscan, re-enable hw_scan if available.
5107 */
5108 lkpi_enable_hw_scan(lhw);
5109
5110 /* Clear the scanning chandef. */
5111 memset(&lhw->scan_chandef, 0, sizeof(lhw->scan_chandef));
5112
5113 LKPI_80211_LHW_SCAN_LOCK(lhw);
5114 wakeup(lhw);
5115 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
5116 }
5117
5118 static void
lkpi_ic_scan_curchan(struct ieee80211_scan_state * ss,unsigned long maxdwell)5119 lkpi_ic_scan_curchan(struct ieee80211_scan_state *ss,
5120 unsigned long maxdwell)
5121 {
5122 struct lkpi_hw *lhw;
5123 bool is_hw_scan;
5124
5125 lhw = ss->ss_ic->ic_softc;
5126 TRACE_SCAN(ss->ss_ic, "scan_flags %b chan %d maxdwell %lu",
5127 lhw->scan_flags, LKPI_LHW_SCAN_BITS,
5128 ss->ss_ic->ic_curchan->ic_ieee, maxdwell);
5129
5130 LKPI_80211_LHW_SCAN_LOCK(lhw);
5131 is_hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
5132 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
5133 if (!is_hw_scan)
5134 lhw->ic_scan_curchan(ss, maxdwell);
5135 }
5136
5137 static void
lkpi_ic_scan_mindwell(struct ieee80211_scan_state * ss)5138 lkpi_ic_scan_mindwell(struct ieee80211_scan_state *ss)
5139 {
5140 struct lkpi_hw *lhw;
5141 bool is_hw_scan;
5142
5143 lhw = ss->ss_ic->ic_softc;
5144 TRACE_SCAN(ss->ss_ic, "scan_flags %b chan %d mindwell %lu",
5145 lhw->scan_flags, LKPI_LHW_SCAN_BITS,
5146 ss->ss_ic->ic_curchan->ic_ieee, ss->ss_mindwell);
5147
5148 LKPI_80211_LHW_SCAN_LOCK(lhw);
5149 is_hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
5150 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
5151 if (!is_hw_scan)
5152 lhw->ic_scan_mindwell(ss);
5153 }
5154
5155 struct lkpi_ic_set_channel_iter_arg {
5156 struct linuxkpi_ieee80211_channel *chan;
5157 struct ieee80211_chanctx_conf *chanctx_conf;
5158 };
5159
5160 static void
lkpi_ic_set_channel_chanctx_iterf(struct ieee80211_hw * hw,struct ieee80211_chanctx_conf * chanctx_conf,void * arg)5161 lkpi_ic_set_channel_chanctx_iterf(struct ieee80211_hw *hw,
5162 struct ieee80211_chanctx_conf *chanctx_conf, void *arg)
5163 {
5164 struct lkpi_ic_set_channel_iter_arg *chanctx_iter_arg;
5165
5166 chanctx_iter_arg = arg;
5167 if (chanctx_iter_arg->chanctx_conf != NULL)
5168 return;
5169
5170 if (chanctx_iter_arg->chan == chanctx_conf->def.chan)
5171 chanctx_iter_arg->chanctx_conf = chanctx_conf;
5172 }
5173
5174 static void
lkpi_ic_set_channel(struct ieee80211com * ic)5175 lkpi_ic_set_channel(struct ieee80211com *ic)
5176 {
5177 struct lkpi_hw *lhw;
5178 struct ieee80211_hw *hw;
5179 struct ieee80211_channel *c;
5180 struct linuxkpi_ieee80211_channel *chan;
5181 struct ieee80211_chanctx_conf *chanctx_conf;
5182 uint32_t changed;
5183 int error;
5184 bool hw_scan, scan_running;
5185
5186 IEEE80211_UNLOCK_ASSERT(ic);
5187
5188 lhw = ic->ic_softc;
5189
5190 c = ic->ic_curchan;
5191 if (c == NULL || c == IEEE80211_CHAN_ANYC) {
5192 ic_printf(ic, "%s: Unset channel: c %p, ignoring update\n",
5193 __func__, c);
5194 return;
5195 }
5196
5197 chan = lkpi_find_lkpi80211_chan(lhw, c);
5198 if (chan == NULL) {
5199 ic_printf(ic, "%s: No channel found for c %p(%d) chan %p\n",
5200 __func__, c, c->ic_ieee, chan);
5201 return;
5202 }
5203
5204 /*
5205 * All net80211 callers call ieee80211_radiotap_chan_change().
5206 * That means we have nothing to do ourselves.
5207 */
5208
5209 /* If we have a hw_scan running do not switch channels. */
5210 LKPI_80211_LHW_SCAN_LOCK(lhw);
5211 scan_running = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
5212 hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
5213 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
5214 if (scan_running && hw_scan) {
5215 TRACE_SCAN(ic, "scan_flags %b chan %d nothing to do.",
5216 lhw->scan_flags, LKPI_LHW_SCAN_BITS,
5217 c->ic_ieee);
5218 /* Let us hope we set tx power levels elsewhere. */
5219 return;
5220 }
5221
5222 hw = LHW_TO_HW(lhw);
5223 wiphy_lock(hw->wiphy);
5224 if (scan_running) {
5225 struct ieee80211vap *vap;
5226 struct lkpi_vif *lvif;
5227 struct ieee80211_vif *vif;
5228
5229 /*
5230 * For now and for scanning just pick the first VIF.
5231 * net80211 will need to grow DBDC/link_id support
5232 * for us to find the vif/chanctx otherwise.
5233 */
5234 vap = TAILQ_FIRST(&ic->ic_vaps);
5235 lvif = VAP_TO_LVIF(vap);
5236 vif = LVIF_TO_VIF(lvif);
5237
5238 /* We always set the chandef to no-HT for scanning. */
5239 cfg80211_chandef_create(&lhw->scan_chandef, chan,
5240 NL80211_CHAN_NO_HT);
5241 #ifdef LINUXKPI_DEBUG_80211
5242 if ((linuxkpi_debug_80211 & D80211_CHANDEF) != 0)
5243 ic_printf(ic, "%s:%d: initialized lhw->scan_chandef\n",
5244 __func__, __LINE__);
5245 #endif
5246
5247 /*
5248 * This works for as long as we do not do BGSCANs; otherwise
5249 * it'll have to be offchan work.
5250 */
5251 chanctx_conf = lkpi_get_chanctx_conf(hw, vif);
5252 changed = lkpi_init_chanctx_conf(hw, &lhw->scan_chandef, chanctx_conf);
5253 error = lkpi_set_chanctx_conf(hw, vif, chanctx_conf, changed, true);
5254
5255 TRACE_SCAN(ic, "scan_flags %b chan %d ???, error %d",
5256 lhw->scan_flags, LKPI_LHW_SCAN_BITS,
5257 c->ic_ieee, error);
5258
5259 IMPROVE("max power for scanning; TODO in lkpi_80211_update_chandef");
5260
5261 } else if (lhw->emulate_chanctx) {
5262 /*
5263 * We do not set the channel here for normal chanctx operation.
5264 * That's just a setup to fail. scan_to_auth will setup all the
5265 * other neccessary options for this to work.
5266 */
5267 struct lkpi_ic_set_channel_iter_arg chanctx_iter_arg = {
5268 .chan = chan,
5269 .chanctx_conf = NULL,
5270 };
5271 struct cfg80211_chan_def chandef;
5272
5273 lkpi_init_chandef(ic, &chandef, chan, c, false);
5274
5275 ieee80211_iter_chan_contexts_mtx(hw,
5276 lkpi_ic_set_channel_chanctx_iterf, &chanctx_iter_arg);
5277
5278 if (chanctx_iter_arg.chanctx_conf == NULL) {
5279 /* No chanctx found for this channel. */
5280 struct ieee80211vap *vap;
5281 struct lkpi_vif *lvif;
5282 struct ieee80211_vif *vif;
5283
5284 /*
5285 * For now just pick the first VIF.
5286 * net80211 will need to grow DBDC/link_id support
5287 * for us to find the vif/chanctx otherwise.
5288 */
5289 vap = TAILQ_FIRST(&ic->ic_vaps);
5290 lvif = VAP_TO_LVIF(vap);
5291 vif = LVIF_TO_VIF(lvif);
5292
5293 #ifdef LINUXKPI_DEBUG_80211
5294 if ((linuxkpi_debug_80211 & D80211_CHANDEF) != 0)
5295 ic_printf(ic, "%s:%d: using on stack chandef\n",
5296 __func__, __LINE__);
5297 #endif
5298 chanctx_conf = lkpi_get_chanctx_conf(hw, vif);
5299 changed = lkpi_init_chanctx_conf(hw, &chandef, chanctx_conf);
5300 IMPROVE("update HT, VHT, bw, ...");
5301 error = lkpi_set_chanctx_conf(hw, vif, chanctx_conf, changed, true);
5302
5303 } else {
5304 /*
5305 * We know we are on the same channel.
5306 * Do we really have to reset everything?
5307 */
5308 IMPROVE("update HT, VHT, bw, ...");
5309
5310 #ifdef LINUXKPI_DEBUG_80211
5311 if ((linuxkpi_debug_80211 & D80211_CHANDEF) != 0)
5312 ic_printf(ic, "%s:%d: using on stack chandef\n",
5313 __func__, __LINE__);
5314 #endif
5315
5316 chanctx_conf = chanctx_iter_arg.chanctx_conf;
5317 changed = lkpi_init_chanctx_conf(hw, &chandef, chanctx_conf);
5318 lkpi_80211_mo_change_chanctx(hw, chanctx_conf, changed);
5319 }
5320 }
5321
5322 /* Currently PS is hard coded off! Not sure it belongs here. */
5323 IMPROVE("PS");
5324 if (ieee80211_hw_check(hw, SUPPORTS_PS) &&
5325 (hw->conf.flags & IEEE80211_CONF_PS) != 0) {
5326 hw->conf.flags &= ~IEEE80211_CONF_PS;
5327 error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_PS);
5328 if (error != 0 && error != EOPNOTSUPP)
5329 ic_printf(ic, "ERROR: %s: config %#0x returned "
5330 "%d\n", __func__, IEEE80211_CONF_CHANGE_PS,
5331 error);
5332 }
5333
5334 wiphy_unlock(hw->wiphy);
5335 }
5336
5337 static struct ieee80211_node *
lkpi_ic_node_alloc(struct ieee80211vap * vap,const uint8_t mac[IEEE80211_ADDR_LEN])5338 lkpi_ic_node_alloc(struct ieee80211vap *vap,
5339 const uint8_t mac[IEEE80211_ADDR_LEN])
5340 {
5341 struct ieee80211com *ic;
5342 struct lkpi_hw *lhw;
5343 struct ieee80211_node *ni;
5344 struct ieee80211_hw *hw;
5345 struct lkpi_sta *lsta;
5346
5347 ic = vap->iv_ic;
5348 lhw = ic->ic_softc;
5349
5350 /* We keep allocations de-coupled so we can deal with the two worlds. */
5351 if (lhw->ic_node_alloc == NULL)
5352 return (NULL);
5353
5354 ni = lhw->ic_node_alloc(vap, mac);
5355 if (ni == NULL)
5356 return (NULL);
5357
5358 hw = LHW_TO_HW(lhw);
5359 lsta = lkpi_lsta_alloc(vap, mac, hw, ni);
5360 if (lsta == NULL) {
5361 if (lhw->ic_node_free != NULL)
5362 lhw->ic_node_free(ni);
5363 return (NULL);
5364 }
5365
5366 return (ni);
5367 }
5368
5369 static int
lkpi_ic_node_init(struct ieee80211_node * ni)5370 lkpi_ic_node_init(struct ieee80211_node *ni)
5371 {
5372 struct ieee80211com *ic;
5373 struct lkpi_hw *lhw;
5374 int error;
5375
5376 ic = ni->ni_ic;
5377 lhw = ic->ic_softc;
5378
5379 if (lhw->ic_node_init != NULL) {
5380 error = lhw->ic_node_init(ni);
5381 if (error != 0)
5382 return (error);
5383 }
5384
5385 /* XXX-BZ Sync other state over. */
5386 IMPROVE();
5387
5388 return (0);
5389 }
5390
5391 static void
lkpi_ic_node_cleanup(struct ieee80211_node * ni)5392 lkpi_ic_node_cleanup(struct ieee80211_node *ni)
5393 {
5394 struct ieee80211com *ic;
5395 struct lkpi_hw *lhw;
5396
5397 ic = ni->ni_ic;
5398 lhw = ic->ic_softc;
5399
5400 /* XXX-BZ remove from driver, ... */
5401 IMPROVE();
5402
5403 if (lhw->ic_node_cleanup != NULL)
5404 lhw->ic_node_cleanup(ni);
5405 }
5406
5407 static void
lkpi_ic_node_free(struct ieee80211_node * ni)5408 lkpi_ic_node_free(struct ieee80211_node *ni)
5409 {
5410 struct ieee80211com *ic;
5411 struct lkpi_hw *lhw;
5412 struct lkpi_sta *lsta;
5413
5414 ic = ni->ni_ic;
5415 lhw = ic->ic_softc;
5416 lsta = ni->ni_drv_data;
5417
5418 /* KASSERT lsta is not NULL here. Print ni/ni__refcnt. */
5419
5420 /*
5421 * Pass in the original ni just in case of error we could check that
5422 * it is the same as lsta->ni.
5423 */
5424 lkpi_lsta_free(lsta, ni);
5425
5426 if (lhw->ic_node_free != NULL)
5427 lhw->ic_node_free(ni);
5428 }
5429
5430 /*
5431 * lkpi_xmit() called from both the (*ic_raw_xmit) as well as the (*ic_transmit)
5432 * call path.
5433 * Unfortunately they have slightly different invariants. See
5434 * ieee80211_raw_output() and ieee80211_parent_xmitpkt().
5435 * Both take care of the ni reference in case of error, and otherwise during
5436 * the callback after transmit.
5437 * The difference is that in case of error (*ic_raw_xmit) needs us to release
5438 * the mbuf, while (*ic_transmit) will free the mbuf itself.
5439 */
5440 static int
lkpi_xmit(struct ieee80211_node * ni,struct mbuf * m,const struct ieee80211_bpf_params * params __unused,bool freem)5441 lkpi_xmit(struct ieee80211_node *ni, struct mbuf *m,
5442 const struct ieee80211_bpf_params *params __unused,
5443 bool freem)
5444 {
5445 struct lkpi_sta *lsta;
5446 int error;
5447
5448 lsta = ni->ni_drv_data;
5449 LKPI_80211_LSTA_TXQ_LOCK(lsta);
5450 #if 0
5451 if (!lsta->added_to_drv || !lsta->txq_ready) {
5452 #else
5453 /*
5454 * Backout this part of 886653492945f which breaks rtw88 or
5455 * in general drivers without (*sta_state)() but only the
5456 * legacy fallback to (*sta_add)().
5457 */
5458 if (!lsta->txq_ready) {
5459 #endif
5460 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
5461 if (freem)
5462 m_free(m);
5463 return (ENETDOWN);
5464 }
5465
5466 /* Queue the packet and enqueue the task to handle it. */
5467 error = mbufq_enqueue(&lsta->txq, m);
5468 if (error != 0) {
5469 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
5470 if (freem)
5471 m_free(m);
5472 #ifdef LINUXKPI_DEBUG_80211
5473 if (linuxkpi_debug_80211 & D80211_TRACE_TX)
5474 ic_printf(ni->ni_ic, "%s: mbufq_enqueue failed: %d\n",
5475 __func__, error);
5476 #endif
5477 return (ENETDOWN);
5478 }
5479 taskqueue_enqueue(taskqueue_thread, &lsta->txq_task);
5480 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
5481
5482 #ifdef LINUXKPI_DEBUG_80211
5483 if (linuxkpi_debug_80211 & D80211_TRACE_TX)
5484 printf("%s:%d lsta %p ni %p %6D mbuf_qlen %d\n",
5485 __func__, __LINE__, lsta, ni, ni->ni_macaddr, ":",
5486 mbufq_len(&lsta->txq));
5487 #endif
5488
5489 return (0);
5490 }
5491
5492 static int
5493 lkpi_ic_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
5494 const struct ieee80211_bpf_params *params __unused)
5495 {
5496 return (lkpi_xmit(ni, m, NULL, true));
5497 }
5498
5499 #ifdef LKPI_80211_HW_CRYPTO
5500 /*
5501 * This is a bit of a hack given we know we are operating on a
5502 * single frame and we know that hardware will deal with it.
5503 * But otherwise the enmic bit and the encrypt bit need to be
5504 * decoupled.
5505 */
5506 static int
5507 lkpi_hw_crypto_prepare_tkip(struct ieee80211_key *k,
5508 struct ieee80211_key_conf *kc, struct sk_buff *skb)
5509 {
5510 struct ieee80211_hdr *hdr;
5511 uint32_t hlen, hdrlen;
5512 uint8_t *p;
5513
5514 /*
5515 * TKIP only happens on data.
5516 */
5517 hdr = (void *)skb->data;
5518 if (!ieee80211_is_data_present(hdr->frame_control))
5519 return (0);
5520
5521 /*
5522 * "enmic" (though we do not do that).
5523 */
5524 /* any conditions to not apply this? */
5525 if (skb_tailroom(skb) < k->wk_cipher->ic_miclen)
5526 return (ENOBUFS);
5527
5528 p = skb_put(skb, k->wk_cipher->ic_miclen);
5529 if ((kc->flags & IEEE80211_KEY_FLAG_PUT_MIC_SPACE) != 0)
5530 goto encrypt;
5531
5532 /*
5533 * (*enmic) which we hopefully do not have to do with hw accel.
5534 * That means if we make it here we have a problem.
5535 */
5536 TODO("(*enmic)");
5537 return (ENXIO);
5538
5539 encrypt:
5540 /*
5541 * "encrypt" (though we do not do that).
5542 */
5543 /*
5544 * Check if we have anything to do as requested by driver
5545 * or if we are done?
5546 */
5547 if ((kc->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) == 0 &&
5548 (kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV) == 0)
5549 return (0);
5550
5551 hlen = k->wk_cipher->ic_header;
5552 if (skb_headroom(skb) < hlen)
5553 return (ENOBUFS);
5554
5555 hdr = (void *)skb->data;
5556 hdrlen = ieee80211_hdrlen(hdr->frame_control);
5557 p = skb_push(skb, hlen);
5558 memmove(p, p + hlen, hdrlen);
5559
5560 /* If driver request space only we are done. */
5561 if ((kc->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) != 0)
5562 return (0);
5563
5564 p += hdrlen;
5565 k->wk_cipher->ic_setiv(k, p);
5566
5567 /* If we make it hear we do sw encryption. */
5568 TODO("sw encrypt");
5569 return (ENXIO);
5570 }
5571
5572 static int
5573 lkpi_hw_crypto_prepare_ccmp(struct ieee80211_key *k,
5574 struct ieee80211_key_conf *kc, struct sk_buff *skb)
5575 {
5576 struct ieee80211_hdr *hdr;
5577 uint32_t hlen, hdrlen;
5578 uint8_t *p;
5579
5580 hdr = (void *)skb->data;
5581
5582 /*
5583 * Check if we have anythig to do as requested by driver
5584 * or if we are done?
5585 */
5586 if ((kc->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) == 0 &&
5587 (kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV) == 0 &&
5588 /* MFP */
5589 !((kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) != 0 &&
5590 ieee80211_is_mgmt(hdr->frame_control)))
5591 return (0);
5592
5593 hlen = k->wk_cipher->ic_header;
5594 if (skb_headroom(skb) < hlen)
5595 return (ENOBUFS);
5596
5597 hdrlen = ieee80211_hdrlen(hdr->frame_control);
5598 p = skb_push(skb, hlen);
5599 memmove(p, p + hlen, hdrlen);
5600
5601 /* If driver request space only we are done. */
5602 if ((kc->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) != 0)
5603 return (0);
5604
5605 p += hdrlen;
5606 k->wk_cipher->ic_setiv(k, p);
5607
5608 return (0);
5609 }
5610
5611 static int
5612 lkpi_hw_crypto_prepare(struct lkpi_sta *lsta, struct ieee80211_key *k,
5613 struct sk_buff *skb)
5614 {
5615 struct ieee80211_tx_info *info;
5616 struct ieee80211_key_conf *kc;
5617
5618 KASSERT(lsta != NULL, ("%s: lsta is NULL", __func__));
5619 KASSERT(k != NULL, ("%s: key is NULL", __func__));
5620 KASSERT(skb != NULL, ("%s: skb is NULL", __func__));
5621
5622 kc = lsta->kc[k->wk_keyix];
5623
5624 info = IEEE80211_SKB_CB(skb);
5625 info->control.hw_key = kc;
5626
5627 /* MUST NOT happen. KASSERT? */
5628 if (kc == NULL) {
5629 ic_printf(lsta->ni->ni_ic, "%s: lsta %p k %p skb %p, "
5630 "kc is NULL on hw crypto offload\n", __func__, lsta, k, skb);
5631 return (ENXIO);
5632 }
5633
5634 switch (kc->cipher) {
5635 case WLAN_CIPHER_SUITE_TKIP:
5636 return (lkpi_hw_crypto_prepare_tkip(k, kc, skb));
5637 case WLAN_CIPHER_SUITE_CCMP:
5638 return (lkpi_hw_crypto_prepare_ccmp(k, kc, skb));
5639 case WLAN_CIPHER_SUITE_GCMP:
5640 return (lkpi_hw_crypto_prepare_ccmp(k, kc, skb));
5641 case WLAN_CIPHER_SUITE_WEP40:
5642 case WLAN_CIPHER_SUITE_WEP104:
5643 case WLAN_CIPHER_SUITE_CCMP_256:
5644 case WLAN_CIPHER_SUITE_GCMP_256:
5645 case WLAN_CIPHER_SUITE_AES_CMAC:
5646 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
5647 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
5648 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
5649 default:
5650 ic_printf(lsta->ni->ni_ic, "%s: lsta %p k %p kc %p skb %p, "
5651 "unsupported cipher suite %u (%s)\n", __func__, lsta, k, kc,
5652 skb, kc->cipher, lkpi_cipher_suite_to_name(kc->cipher));
5653 return (EOPNOTSUPP);
5654 }
5655 }
5656
5657 static uint8_t
5658 lkpi_hw_crypto_tailroom(struct lkpi_sta *lsta, struct ieee80211_key *k)
5659 {
5660 struct ieee80211_key_conf *kc;
5661
5662 kc = lsta->kc[k->wk_keyix];
5663 if (kc == NULL)
5664 return (0);
5665
5666 IMPROVE("which other flags need tailroom?");
5667 if (kc->flags & (IEEE80211_KEY_FLAG_PUT_MIC_SPACE))
5668 return (32); /* Large enough to hold everything and pow2. */
5669
5670 return (0);
5671 }
5672 #endif
5673
5674 static void
5675 lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
5676 {
5677 struct ieee80211_node *ni;
5678 struct ieee80211_frame *wh;
5679 struct ieee80211_key *k;
5680 struct sk_buff *skb;
5681 struct ieee80211com *ic;
5682 struct lkpi_hw *lhw;
5683 struct ieee80211_hw *hw;
5684 struct lkpi_vif *lvif;
5685 struct ieee80211_vif *vif;
5686 struct ieee80211_channel *c;
5687 struct ieee80211_tx_control control;
5688 struct ieee80211_tx_info *info;
5689 struct ieee80211_sta *sta;
5690 struct ieee80211_hdr *hdr;
5691 struct lkpi_txq *ltxq;
5692 void *buf;
5693 ieee80211_keyix keyix;
5694 uint8_t ac, tid, tailroom;
5695
5696 M_ASSERTPKTHDR(m);
5697 #ifdef LINUXKPI_DEBUG_80211
5698 if (linuxkpi_debug_80211 & D80211_TRACE_TX_DUMP)
5699 hexdump(mtod(m, const void *), m->m_len, "RAW TX (plain) ", 0);
5700 #endif
5701
5702 ni = lsta->ni;
5703 ieee80211_output_seqno_assign(ni, -1, m);
5704
5705 k = NULL;
5706 keyix = IEEE80211_KEYIX_NONE;
5707 wh = mtod(m, struct ieee80211_frame *);
5708 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
5709
5710 #ifdef LKPI_80211_HW_CRYPTO
5711 if (lkpi_hwcrypto) {
5712 k = ieee80211_crypto_get_txkey(ni, m);
5713 if (k != NULL && lsta->kc[k->wk_keyix] != NULL)
5714 keyix = k->wk_keyix;
5715 }
5716 #endif
5717
5718 /* Encrypt the frame if need be. */
5719 if (keyix == IEEE80211_KEYIX_NONE) {
5720 /* Retrieve key for TX && do software encryption. */
5721 k = ieee80211_crypto_encap(ni, m);
5722 if (k == NULL) {
5723 ieee80211_free_node(ni);
5724 m_freem(m);
5725 return;
5726 }
5727 }
5728 }
5729
5730 ic = ni->ni_ic;
5731 lhw = ic->ic_softc;
5732 hw = LHW_TO_HW(lhw);
5733 c = ni->ni_chan;
5734
5735 if (ieee80211_radiotap_active_vap(ni->ni_vap)) {
5736 struct lkpi_radiotap_tx_hdr *rtap;
5737
5738 rtap = &lhw->rtap_tx;
5739 rtap->wt_flags = 0;
5740 if (k != NULL)
5741 rtap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
5742 if (m->m_flags & M_FRAG)
5743 rtap->wt_flags |= IEEE80211_RADIOTAP_F_FRAG;
5744 IMPROVE();
5745 rtap->wt_rate = 0;
5746 if (c != NULL && c != IEEE80211_CHAN_ANYC) {
5747 rtap->wt_chan_freq = htole16(c->ic_freq);
5748 rtap->wt_chan_flags = htole16(c->ic_flags);
5749 }
5750
5751 ieee80211_radiotap_tx(ni->ni_vap, m);
5752 }
5753
5754 #ifdef LKPI_80211_HW_CRYPTO
5755 if (lkpi_hwcrypto && keyix != IEEE80211_KEYIX_NONE)
5756 tailroom = lkpi_hw_crypto_tailroom(lsta, k);
5757 else
5758 #endif
5759 tailroom = 0;
5760
5761 /*
5762 * net80211 should handle hw->extra_tx_headroom.
5763 * Though for as long as we are copying we don't mind.
5764 * XXX-BZ rtw88 asks for too much headroom for ipv6+tcp:
5765 * https://lists.freebsd.org/archives/freebsd-transport/2022-February/000012.html
5766 */
5767 skb = dev_alloc_skb(hw->extra_tx_headroom + tailroom + m->m_pkthdr.len);
5768 if (skb == NULL) {
5769 static uint8_t skb_alloc_failures = 0;
5770
5771 if (skb_alloc_failures++ == 0) {
5772 int tid;
5773
5774 sta = LSTA_TO_STA(lsta);
5775 ic_printf(ic, "ERROR %s: skb alloc failed %d + %d, lsta %p sta %p ni %p\n",
5776 __func__, hw->extra_tx_headroom, m->m_pkthdr.len, lsta, sta, ni);
5777 for (tid = 0; tid < nitems(sta->txq); tid++) {
5778 if (sta->txq[tid] == NULL)
5779 continue;
5780 ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
5781 ic_printf(ic, " tid %d ltxq %p seen_dequeue %d stopped %d skb_queue_len %u\n",
5782 tid, ltxq, ltxq->seen_dequeue, ltxq->stopped, skb_queue_len(<xq->skbq));
5783 }
5784 }
5785 ieee80211_free_node(ni);
5786 m_freem(m);
5787 return;
5788 }
5789 skb_reserve(skb, hw->extra_tx_headroom);
5790
5791 /* XXX-BZ we need a SKB version understanding mbuf. */
5792 /* Save the mbuf for ieee80211_tx_complete(). */
5793 skb->m_free_func = lkpi_ieee80211_free_skb_mbuf;
5794 skb->m = m;
5795 #if 0
5796 skb_put_data(skb, m->m_data, m->m_pkthdr.len);
5797 #else
5798 buf = skb_put(skb, m->m_pkthdr.len);
5799 m_copydata(m, 0, m->m_pkthdr.len, buf);
5800 #endif
5801 /* Save the ni. */
5802 m->m_pkthdr.PH_loc.ptr = ni;
5803
5804 lvif = VAP_TO_LVIF(ni->ni_vap);
5805 vif = LVIF_TO_VIF(lvif);
5806
5807 hdr = (void *)skb->data;
5808 tid = linuxkpi_ieee80211_get_tid(hdr, true);
5809 if (tid == IEEE80211_NONQOS_TID) { /* == IEEE80211_NUM_TIDS */
5810 if (!ieee80211_is_data(hdr->frame_control)) {
5811 /* MGMT and CTRL frames go on TID 7/VO. */
5812 skb->priority = 7;
5813 ac = IEEE80211_AC_VO;
5814 } else {
5815 /* Other non-QOS traffic goes to BE. */
5816 /* Contrary to net80211 we MUST NOT promote M_EAPOL. */
5817 skb->priority = 0;
5818 ac = IEEE80211_AC_BE;
5819 }
5820 } else {
5821 skb->priority = tid & IEEE80211_QOS_CTL_TID_MASK;
5822 ac = ieee80211e_up_to_ac[tid & 7];
5823 }
5824 skb_set_queue_mapping(skb, ac);
5825
5826 info = IEEE80211_SKB_CB(skb);
5827 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
5828 /* Slight delay; probably only happens on scanning so fine? */
5829 if (c == NULL || c == IEEE80211_CHAN_ANYC)
5830 c = ic->ic_curchan;
5831 info->band = lkpi_net80211_chan_to_nl80211_band(c);
5832 info->hw_queue = vif->hw_queue[ac];
5833 if ((m->m_flags & M_EAPOL) != 0) {
5834 info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
5835 info->flags |= IEEE80211_TX_CTL_USE_MINRATE; /* mt76 */
5836 }
5837 info->control.vif = vif;
5838 /* XXX-BZ info->control.rates */
5839 #ifdef __notyet__
5840 #ifdef LKPI_80211_HT
5841 info->control.rts_cts_rate_idx=
5842 info->control.use_rts= /* RTS */
5843 info->control.use_cts_prot= /* RTS/CTS*/
5844 #endif
5845 #endif
5846
5847 sta = LSTA_TO_STA(lsta);
5848 #ifdef LKPI_80211_HW_CRYPTO
5849 if (lkpi_hwcrypto && keyix != IEEE80211_KEYIX_NONE) {
5850 int error;
5851
5852 error = lkpi_hw_crypto_prepare(lsta, k, skb);
5853 if (error != 0) {
5854 /*
5855 * We only have to free the skb which will free the
5856 * mbuf and release the reference on the ni.
5857 */
5858 dev_kfree_skb(skb);
5859 return;
5860 }
5861 /* Reset header as data might have moved. */
5862 hdr = (void *)skb->data;
5863 }
5864 #endif
5865
5866 IMPROVE();
5867
5868 ltxq = NULL;
5869 if (!ieee80211_is_data_present(hdr->frame_control)) {
5870 if (vif->type == NL80211_IFTYPE_STATION &&
5871 lsta->added_to_drv &&
5872 sta->txq[IEEE80211_NUM_TIDS] != NULL)
5873 ltxq = TXQ_TO_LTXQ(sta->txq[IEEE80211_NUM_TIDS]);
5874 } else if (lsta->added_to_drv &&
5875 sta->txq[skb->priority] != NULL) {
5876 ltxq = TXQ_TO_LTXQ(sta->txq[skb->priority]);
5877 }
5878 if (ltxq == NULL)
5879 goto ops_tx;
5880
5881 KASSERT(ltxq != NULL, ("%s: lsta %p sta %p m %p skb %p "
5882 "ltxq %p != NULL\n", __func__, lsta, sta, m, skb, ltxq));
5883
5884 LKPI_80211_LTXQ_LOCK(ltxq);
5885 skb_queue_tail(<xq->skbq, skb);
5886 ltxq->frms_enqueued++;
5887 #ifdef LINUXKPI_DEBUG_80211
5888 if (linuxkpi_debug_80211 & D80211_TRACE_TX)
5889 printf("%s:%d mo_wake_tx_queue :: %d %lu lsta %p sta %p "
5890 "ni %p %6D skb %p lxtq %p { qlen %u, ac %d tid %u } "
5891 "WAKE_TX_Q ac %d prio %u qmap %u\n",
5892 __func__, __LINE__,
5893 curthread->td_tid, jiffies,
5894 lsta, sta, ni, ni->ni_macaddr, ":", skb, ltxq,
5895 skb_queue_len(<xq->skbq), ltxq->txq.ac,
5896 ltxq->txq.tid, ac, skb->priority, skb->qmap);
5897 #endif
5898 LKPI_80211_LTXQ_UNLOCK(ltxq);
5899 wiphy_lock(hw->wiphy);
5900 lkpi_80211_mo_wake_tx_queue(hw, <xq->txq, true);
5901 wiphy_unlock(hw->wiphy);
5902 return;
5903
5904 ops_tx:
5905 #ifdef LINUXKPI_DEBUG_80211
5906 if (linuxkpi_debug_80211 & D80211_TRACE_TX)
5907 printf("%s:%d mo_tx :: lsta %p sta %p ni %p %6D skb %p "
5908 "TX ac %d prio %u qmap %u\n",
5909 __func__, __LINE__, lsta, sta, ni, ni->ni_macaddr, ":",
5910 skb, ac, skb->priority, skb->qmap);
5911 #endif
5912 memset(&control, 0, sizeof(control));
5913 control.sta = sta;
5914 wiphy_lock(hw->wiphy);
5915 lkpi_80211_mo_tx(hw, &control, skb);
5916 lsta->frms_tx++;
5917 wiphy_unlock(hw->wiphy);
5918 }
5919
5920 static void
5921 lkpi_80211_txq_task(void *ctx, int pending)
5922 {
5923 struct lkpi_sta *lsta;
5924 struct mbufq mq;
5925 struct mbuf *m;
5926 bool shall_tx;
5927
5928 lsta = ctx;
5929
5930 #ifdef LINUXKPI_DEBUG_80211
5931 if (linuxkpi_debug_80211 & D80211_TRACE_TX)
5932 printf("%s:%d lsta %p ni %p %6D pending %d mbuf_qlen %d\n",
5933 __func__, __LINE__, lsta, lsta->ni, lsta->ni->ni_macaddr, ":",
5934 pending, mbufq_len(&lsta->txq));
5935 #endif
5936
5937 mbufq_init(&mq, IFQ_MAXLEN);
5938
5939 LKPI_80211_LSTA_TXQ_LOCK(lsta);
5940 /*
5941 * Do not re-check lsta->txq_ready here; we may have a pending
5942 * disassoc/deauth frame still. On the contrary if txq_ready is
5943 * false we do not have a valid sta anymore in the firmware so no
5944 * point to try to TX.
5945 * We also use txq_ready as a semaphore and will drain the txq manually
5946 * if needed on our way towards SCAN/INIT in the state machine.
5947 */
5948 #if 0
5949 shall_tx = lsta->added_to_drv && lsta->txq_ready;
5950 #else
5951 /*
5952 * Backout this part of 886653492945f which breaks rtw88 or
5953 * in general drivers without (*sta_state)() but only the
5954 * legacy fallback to (*sta_add)().
5955 */
5956 shall_tx = lsta->txq_ready;
5957 #endif
5958 if (__predict_true(shall_tx))
5959 mbufq_concat(&mq, &lsta->txq);
5960 /*
5961 * else a state change will push the packets out manually or
5962 * lkpi_lsta_free() will drain the lsta->txq and free the mbufs.
5963 */
5964 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
5965
5966 m = mbufq_dequeue(&mq);
5967 while (m != NULL) {
5968 lkpi_80211_txq_tx_one(lsta, m);
5969 m = mbufq_dequeue(&mq);
5970 }
5971 }
5972
5973 static int
5974 lkpi_ic_transmit(struct ieee80211com *ic, struct mbuf *m)
5975 {
5976
5977 /* XXX TODO */
5978 IMPROVE();
5979
5980 /* Quick and dirty cheating hack. */
5981 struct ieee80211_node *ni;
5982
5983 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
5984 return (lkpi_xmit(ni, m, NULL, false));
5985 }
5986
5987 #ifdef LKPI_80211_HT
5988 static int
5989 lkpi_ic_recv_action(struct ieee80211_node *ni, const struct ieee80211_frame *wh,
5990 const uint8_t *frm, const uint8_t *efrm)
5991 {
5992 struct ieee80211com *ic;
5993 struct lkpi_hw *lhw;
5994
5995 ic = ni->ni_ic;
5996 lhw = ic->ic_softc;
5997
5998 IMPROVE_HT("recv_action called; nothing to do in lkpi; make debugging");
5999
6000 return (lhw->ic_recv_action(ni, wh, frm, efrm));
6001 }
6002
6003 static int
6004 lkpi_ic_send_action(struct ieee80211_node *ni, int category, int action, void *sa)
6005 {
6006 struct ieee80211com *ic;
6007 struct lkpi_hw *lhw;
6008
6009 ic = ni->ni_ic;
6010 lhw = ic->ic_softc;
6011
6012 IMPROVE_HT("send_action called; nothing to do in lkpi; make debugging");
6013
6014 return (lhw->ic_send_action(ni, category, action, sa));
6015 }
6016
6017
6018 static int
6019 lkpi_ic_ampdu_enable(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
6020 {
6021 struct ieee80211com *ic;
6022 struct lkpi_hw *lhw;
6023
6024 ic = ni->ni_ic;
6025 lhw = ic->ic_softc;
6026
6027 IMPROVE_HT("ieee80211_ampdu_enable called; nothing to do in lkpi for now; make debugging");
6028
6029 return (lhw->ic_ampdu_enable(ni, tap));
6030 }
6031
6032 /*
6033 * (*ic_addba_request)() is called by ieee80211_ampdu_request() before
6034 * calling send_action(CAT_BA, BA_ADDBA_REQUEST).
6035 *
6036 * NB: returns 0 on ERROR!
6037 */
6038 static int
6039 lkpi_ic_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
6040 int dialogtoken, int baparamset, int batimeout)
6041 {
6042 struct ieee80211com *ic;
6043 struct lkpi_hw *lhw;
6044 struct ieee80211_hw *hw;
6045 struct ieee80211vap *vap;
6046 struct lkpi_vif *lvif;
6047 struct ieee80211_vif *vif;
6048 struct lkpi_sta *lsta;
6049 struct ieee80211_sta *sta;
6050 struct ieee80211_ampdu_params params = { };
6051 int error;
6052
6053 ic = ni->ni_ic;
6054 lhw = ic->ic_softc;
6055 hw = LHW_TO_HW(lhw);
6056 vap = ni->ni_vap;
6057 lvif = VAP_TO_LVIF(vap);
6058 vif = LVIF_TO_VIF(lvif);
6059 lsta = ni->ni_drv_data;
6060 sta = LSTA_TO_STA(lsta);
6061
6062 if (!lsta->added_to_drv) {
6063 ic_printf(ic, "%s: lsta %p ni %p, sta %p not added to firmware\n",
6064 __func__, lsta, ni, sta);
6065 return (0);
6066 }
6067
6068 params.sta = sta;
6069 params.action = IEEE80211_AMPDU_TX_START;
6070 /* Keep 0 here! */
6071 params.buf_size = 0;
6072 params.timeout = 0;
6073 params.ssn = tap->txa_start & (IEEE80211_SEQ_RANGE-1);
6074 params.tid = tap->txa_tid;
6075 params.amsdu = false;
6076
6077 IEEE80211_UNLOCK(ic);
6078 wiphy_lock(hw->wiphy);
6079 error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
6080 wiphy_unlock(hw->wiphy);
6081 IEEE80211_LOCK(ic);
6082 if (error != 0) {
6083 ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p tap %p\n",
6084 __func__, error, ni, tap);
6085 return (0);
6086 }
6087
6088 return (lhw->ic_addba_request(ni, tap, dialogtoken, baparamset, batimeout));
6089 }
6090
6091 /*
6092 * (*ic_addba_response)() is called from ht_recv_action_ba_addba_response()
6093 * and calls the default ieee80211_addba_response() which always returns 1.
6094 *
6095 * NB: No error checking in net80211!
6096 * Staying with 0 is an error.
6097 */
6098 static int
6099 lkpi_ic_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
6100 int status, int baparamset, int batimeout)
6101 {
6102 struct ieee80211com *ic;
6103 struct lkpi_hw *lhw;
6104 struct ieee80211_hw *hw;
6105 struct ieee80211vap *vap;
6106 struct lkpi_vif *lvif;
6107 struct ieee80211_vif *vif;
6108 struct lkpi_sta *lsta;
6109 struct ieee80211_sta *sta;
6110 struct ieee80211_ampdu_params params = { };
6111 int error;
6112
6113 ic = ni->ni_ic;
6114 lhw = ic->ic_softc;
6115 hw = LHW_TO_HW(lhw);
6116 vap = ni->ni_vap;
6117 lvif = VAP_TO_LVIF(vap);
6118 vif = LVIF_TO_VIF(lvif);
6119 lsta = ni->ni_drv_data;
6120 sta = LSTA_TO_STA(lsta);
6121
6122 if (!lsta->added_to_drv) {
6123 ic_printf(ic, "%s: lsta %p ni %p, sta %p not added to firmware\n",
6124 __func__, lsta, ni, sta);
6125 return (0);
6126 }
6127
6128 if (status == IEEE80211_STATUS_SUCCESS) {
6129 params.sta = sta;
6130 params.action = IEEE80211_AMPDU_TX_OPERATIONAL;
6131 params.buf_size = tap->txa_wnd;
6132 params.timeout = 0;
6133 params.ssn = 0;
6134 params.tid = tap->txa_tid;
6135 if ((tap->txa_flags & IEEE80211_AGGR_AMSDU) != 0)
6136 params.amsdu = true;
6137 else
6138 params.amsdu = false;
6139 } else {
6140 /* We need to free the allocated resources. */
6141 params.sta = sta;
6142 switch (status) {
6143 /* params.action = FLUSH, FLUSH_CONT */
6144 default:
6145 params.action = IEEE80211_AMPDU_TX_STOP_CONT;
6146 break;
6147 }
6148 params.buf_size = 0;
6149 params.timeout = 0;
6150 params.ssn = 0;
6151 params.tid = tap->txa_tid;
6152 params.amsdu = false;
6153 }
6154
6155 IEEE80211_UNLOCK(ic);
6156 wiphy_lock(hw->wiphy);
6157 error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
6158 wiphy_unlock(hw->wiphy);
6159 IEEE80211_LOCK(ic);
6160 if (error != 0) {
6161 ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p tap %p\n",
6162 __func__, error, ni, tap);
6163 return (0);
6164 }
6165
6166 IMPROVE_HT("who unleashes the TXQ? and when?, do we need to ni->ni_txseqs[tid] = tap->txa_start & 0xfff;");
6167
6168 return (lhw->ic_addba_response(ni, tap, status, baparamset, batimeout));
6169 }
6170
6171 /*
6172 * (*ic_addba_stop)() is called from ampdu_tx_stop(), ht_recv_action_ba_delba(),
6173 * and ieee80211_ampdu_stop() and calls the default ieee80211_addba_stop().
6174 */
6175 static void
6176 lkpi_ic_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
6177 {
6178 struct ieee80211com *ic;
6179 struct lkpi_hw *lhw;
6180 struct ieee80211_hw *hw;
6181 struct ieee80211vap *vap;
6182 struct lkpi_vif *lvif;
6183 struct ieee80211_vif *vif;
6184 struct lkpi_sta *lsta;
6185 struct ieee80211_sta *sta;
6186 struct ieee80211_ampdu_params params = { };
6187 int error;
6188
6189 ic = ni->ni_ic;
6190 lhw = ic->ic_softc;
6191 hw = LHW_TO_HW(lhw);
6192 vap = ni->ni_vap;
6193 lvif = VAP_TO_LVIF(vap);
6194 vif = LVIF_TO_VIF(lvif);
6195 lsta = ni->ni_drv_data;
6196 sta = LSTA_TO_STA(lsta);
6197
6198 if (!lsta->added_to_drv) {
6199 ic_printf(ic, "%s: lsta %p ni %p, sta %p not added to firmware\n",
6200 __func__, lsta, ni, sta);
6201 goto n80211;
6202 }
6203
6204 /* We need to free the allocated resources. */
6205 params.sta = sta;
6206 IMPROVE("net80211 does not provide a reason to us");
6207 params.action = IEEE80211_AMPDU_TX_STOP_CONT; /* params.action = FLUSH, FLUSH_CONT */
6208 params.buf_size = 0;
6209 params.timeout = 0;
6210 params.ssn = 0;
6211 params.tid = tap->txa_tid;
6212 params.amsdu = false;
6213
6214 IEEE80211_UNLOCK(ic);
6215 wiphy_lock(hw->wiphy);
6216 error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
6217 wiphy_unlock(hw->wiphy);
6218 IEEE80211_LOCK(ic);
6219 if (error != 0) {
6220 ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p tap %p\n",
6221 __func__, error, ni, tap);
6222 goto n80211;
6223 }
6224
6225 IMPROVE_HT("anyting else?");
6226
6227 n80211:
6228 lhw->ic_addba_stop(ni, tap);
6229 }
6230
6231 static void
6232 lkpi_ic_addba_response_timeout(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
6233 {
6234 struct ieee80211com *ic;
6235 struct lkpi_hw *lhw;
6236
6237 ic = ni->ni_ic;
6238 lhw = ic->ic_softc;
6239
6240 IMPROVE_HT();
6241
6242 lhw->ic_addba_response_timeout(ni, tap);
6243 }
6244
6245 static void
6246 lkpi_ic_bar_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
6247 int status)
6248 {
6249 struct ieee80211com *ic;
6250 struct lkpi_hw *lhw;
6251
6252 ic = ni->ni_ic;
6253 lhw = ic->ic_softc;
6254
6255 IMPROVE_HT();
6256
6257 lhw->ic_bar_response(ni, tap, status);
6258 }
6259
6260 static int
6261 lkpi_ic_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
6262 int baparamset, int batimeout, int baseqctl)
6263 {
6264 struct ieee80211com *ic;
6265 struct lkpi_hw *lhw;
6266 struct ieee80211_hw *hw;
6267 struct ieee80211vap *vap;
6268 struct lkpi_vif *lvif;
6269 struct ieee80211_vif *vif;
6270 struct lkpi_sta *lsta;
6271 struct ieee80211_sta *sta;
6272 struct ieee80211_ampdu_params params = { };
6273 int error;
6274
6275 ic = ni->ni_ic;
6276 lhw = ic->ic_softc;
6277 hw = LHW_TO_HW(lhw);
6278 vap = ni->ni_vap;
6279 lvif = VAP_TO_LVIF(vap);
6280 vif = LVIF_TO_VIF(lvif);
6281 lsta = ni->ni_drv_data;
6282 sta = LSTA_TO_STA(lsta);
6283
6284 IEEE80211_UNLOCK_ASSERT(ic);
6285
6286 if (!lsta->added_to_drv) {
6287 ic_printf(ic, "%s: lsta %p ni %p vap %p, sta %p not added to firmware\n",
6288 __func__, lsta, ni, vap, sta);
6289 return (-ENXIO);
6290 }
6291
6292 if (lsta->state != IEEE80211_STA_AUTHORIZED) {
6293 ic_printf(ic, "%s: lsta %p ni %p vap %p, sta %p state %d not AUTHORIZED\n",
6294 __func__, lsta, ni, vap, sta, lsta->state);
6295 return (-ENXIO);
6296 }
6297
6298 params.sta = sta;
6299 params.action = IEEE80211_AMPDU_RX_START;
6300 params.buf_size = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_BUFSIZ);
6301 if (params.buf_size == 0)
6302 params.buf_size = IEEE80211_MAX_AMPDU_BUF_HT;
6303 else
6304 params.buf_size = min(params.buf_size, IEEE80211_MAX_AMPDU_BUF_HT);
6305 if (hw->max_rx_aggregation_subframes > 0 &&
6306 params.buf_size > hw->max_rx_aggregation_subframes)
6307 params.buf_size = hw->max_rx_aggregation_subframes;
6308 params.timeout = le16toh(batimeout);
6309 params.ssn = _IEEE80211_MASKSHIFT(le16toh(baseqctl), IEEE80211_BASEQ_START);
6310 params.tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID);
6311
6312 /* Based on net80211::ampdu_rx_start(). */
6313 if ((vap->iv_htcaps & IEEE80211_HTC_RX_AMSDU_AMPDU) &&
6314 (_IEEE80211_MASKSHIFT(baparamset, IEEE80211_BAPS_AMSDU)))
6315 params.amsdu = true;
6316 else
6317 params.amsdu = false;
6318
6319 wiphy_lock(hw->wiphy);
6320 error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
6321 wiphy_unlock(hw->wiphy);
6322 if (error != 0) {
6323 ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p rap %p\n",
6324 __func__, error, ni, rap);
6325 return (error);
6326 }
6327
6328 if (!ieee80211_hw_check(hw, SUPPORTS_REORDERING_BUFFER)) {
6329 IMPROVE("%s: TODO: SUPPORTS_REORDERING_BUFFER not set; check net80211\n", __func__);
6330 }
6331
6332 IMPROVE_HT("net80211 is missing the error check on return and assumes success");
6333
6334 error = lhw->ic_ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl);
6335 return (error);
6336 }
6337
6338 static void
6339 lkpi_ic_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
6340 {
6341 struct ieee80211com *ic;
6342 struct lkpi_hw *lhw;
6343 struct ieee80211_hw *hw;
6344 struct ieee80211vap *vap;
6345 struct lkpi_vif *lvif;
6346 struct ieee80211_vif *vif;
6347 struct lkpi_sta *lsta;
6348 struct ieee80211_sta *sta;
6349 struct ieee80211_ampdu_params params = { };
6350 int error;
6351 uint8_t tid;
6352 bool ic_locked;
6353
6354 ic = ni->ni_ic;
6355 lhw = ic->ic_softc;
6356
6357 /*
6358 * We should not (cannot) call into mac80211 ops with AMPDU_RX_STOP if
6359 * we did not START. Some drivers pass it down to firmware which will
6360 * simply barf and net80211 calls ieee80211_ht_node_cleanup() from
6361 * ieee80211_ht_node_init() amongst others which will iterate over all
6362 * tid and call ic_ampdu_rx_stop() unconditionally.
6363 * XXX net80211 should probably be more "gentle" in these cases and
6364 * track some state itself.
6365 */
6366 if ((rap->rxa_flags & IEEE80211_AGGR_RUNNING) == 0)
6367 goto net80211_only;
6368
6369 hw = LHW_TO_HW(lhw);
6370 vap = ni->ni_vap;
6371 lvif = VAP_TO_LVIF(vap);
6372 vif = LVIF_TO_VIF(lvif);
6373 lsta = ni->ni_drv_data;
6374 if (lsta == NULL) {
6375 ic_printf(ic, "%s: lsta %p ni %p vap %p, lsta is NULL\n",
6376 __func__, lsta, ni, vap);
6377 goto net80211_only;
6378 }
6379 sta = LSTA_TO_STA(lsta);
6380
6381 if (!lsta->added_to_drv) {
6382 ic_printf(ic, "%s: lsta %p ni %p vap %p, sta %p not added to firmware\n",
6383 __func__, lsta, ni, vap, sta);
6384 goto net80211_only;
6385 }
6386
6387 if (lsta->state != IEEE80211_STA_AUTHORIZED) {
6388 ic_printf(ic, "%s: lsta %p ni %p vap %p, sta %p state %d not AUTHORIZED\n",
6389 __func__, lsta, ni, vap, sta, lsta->state);
6390 goto net80211_only;
6391 }
6392
6393 IMPROVE_HT("This really should be passed from ht_recv_action_ba_delba.");
6394 for (tid = 0; tid < WME_NUM_TID; tid++) {
6395 if (&ni->ni_rx_ampdu[tid] == rap)
6396 break;
6397 }
6398 if (tid == WME_NUM_TID) {
6399 ic_printf(ic, "%s: lsta %p ni %p vap %p, sta %p TID not found\n",
6400 __func__, lsta, ni, vap, sta);
6401 goto net80211_only;
6402 }
6403
6404 params.sta = sta;
6405 params.action = IEEE80211_AMPDU_RX_STOP;
6406 params.buf_size = 0;
6407 params.timeout = 0;
6408 params.ssn = 0;
6409 params.tid = tid;
6410 params.amsdu = false;
6411
6412 ic_locked = IEEE80211_IS_LOCKED(ic);
6413 if (ic_locked)
6414 IEEE80211_UNLOCK(ic);
6415 wiphy_lock(hw->wiphy);
6416 error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
6417 wiphy_unlock(hw->wiphy);
6418 if (ic_locked)
6419 IEEE80211_LOCK(ic);
6420 if (error != 0)
6421 ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p rap %p\n",
6422 __func__, error, ni, rap);
6423
6424 net80211_only:
6425 lhw->ic_ampdu_rx_stop(ni, rap);
6426 }
6427 #endif
6428
6429 static void
6430 lkpi_ic_getradiocaps_ht(struct ieee80211com *ic, struct ieee80211_hw *hw,
6431 uint8_t *bands, int *chan_flags, enum nl80211_band band)
6432 {
6433 #ifdef LKPI_80211_HT
6434 struct ieee80211_sta_ht_cap *ht_cap;
6435
6436 ht_cap = &hw->wiphy->bands[band]->ht_cap;
6437 if (!ht_cap->ht_supported)
6438 return;
6439
6440 switch (band) {
6441 case NL80211_BAND_2GHZ:
6442 setbit(bands, IEEE80211_MODE_11NG);
6443 break;
6444 case NL80211_BAND_5GHZ:
6445 setbit(bands, IEEE80211_MODE_11NA);
6446 break;
6447 default:
6448 IMPROVE("Unsupported band %d", band);
6449 return;
6450 }
6451
6452 ic->ic_htcaps = IEEE80211_HTC_HT; /* HT operation */
6453
6454 /*
6455 * Rather than manually checking each flag and
6456 * translating IEEE80211_HT_CAP_ to IEEE80211_HTCAP_,
6457 * simply copy the 16bits.
6458 */
6459 ic->ic_htcaps |= ht_cap->cap;
6460
6461 /* Then deal with the other flags. */
6462 if (ieee80211_hw_check(hw, AMPDU_AGGREGATION))
6463 ic->ic_htcaps |= IEEE80211_HTC_AMPDU;
6464 #ifdef __notyet__
6465 if (ieee80211_hw_check(hw, TX_AMSDU))
6466 ic->ic_htcaps |= IEEE80211_HTC_AMSDU;
6467 if (ieee80211_hw_check(hw, SUPPORTS_AMSDU_IN_AMPDU))
6468 ic->ic_htcaps |= (IEEE80211_HTC_RX_AMSDU_AMPDU |
6469 IEEE80211_HTC_TX_AMSDU_AMPDU);
6470 #endif
6471
6472 IMPROVE("PS, ampdu_*, ht_cap.mcs.tx_params, ...");
6473
6474 /* Only add HT40 channels if supported. */
6475 if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) != 0 &&
6476 chan_flags != NULL)
6477 *chan_flags |= NET80211_CBW_FLAG_HT40;
6478 #endif
6479 }
6480
6481 static void
6482 lkpi_ic_getradiocaps(struct ieee80211com *ic, int maxchan,
6483 int *n, struct ieee80211_channel *c)
6484 {
6485 struct lkpi_hw *lhw;
6486 struct ieee80211_hw *hw;
6487 struct linuxkpi_ieee80211_channel *channels;
6488 uint8_t bands[IEEE80211_MODE_BYTES];
6489 int chan_flags, error, i, nchans;
6490
6491 /* Channels */
6492 lhw = ic->ic_softc;
6493 hw = LHW_TO_HW(lhw);
6494
6495 /* NL80211_BAND_2GHZ */
6496 nchans = 0;
6497 if (hw->wiphy->bands[NL80211_BAND_2GHZ] != NULL)
6498 nchans = hw->wiphy->bands[NL80211_BAND_2GHZ]->n_channels;
6499 if (nchans > 0) {
6500 memset(bands, 0, sizeof(bands));
6501 chan_flags = 0;
6502 setbit(bands, IEEE80211_MODE_11B);
6503 /* XXX-BZ unclear how to check for 11g. */
6504
6505 IMPROVE("the bitrates may have flags?");
6506 setbit(bands, IEEE80211_MODE_11G);
6507
6508 lkpi_ic_getradiocaps_ht(ic, hw, bands, &chan_flags,
6509 NL80211_BAND_2GHZ);
6510
6511 channels = hw->wiphy->bands[NL80211_BAND_2GHZ]->channels;
6512 for (i = 0; i < nchans && *n < maxchan; i++) {
6513 uint32_t nflags = 0;
6514 int cflags = chan_flags;
6515
6516 if (channels[i].flags & IEEE80211_CHAN_DISABLED) {
6517 ic_printf(ic, "%s: Skipping disabled chan "
6518 "[%u/%u/%#x]\n", __func__,
6519 channels[i].hw_value,
6520 channels[i].center_freq, channels[i].flags);
6521 continue;
6522 }
6523 if (channels[i].flags & IEEE80211_CHAN_NO_IR)
6524 nflags |= (IEEE80211_CHAN_NOADHOC|IEEE80211_CHAN_PASSIVE);
6525 if (channels[i].flags & IEEE80211_CHAN_RADAR)
6526 nflags |= IEEE80211_CHAN_DFS;
6527 if (channels[i].flags & IEEE80211_CHAN_NO_160MHZ)
6528 cflags &= ~(NET80211_CBW_FLAG_VHT160|NET80211_CBW_FLAG_VHT80P80);
6529 if (channels[i].flags & IEEE80211_CHAN_NO_80MHZ)
6530 cflags &= ~NET80211_CBW_FLAG_VHT80;
6531 /* XXX how to map the remaining enum ieee80211_channel_flags? */
6532 if (channels[i].flags & IEEE80211_CHAN_NO_HT40)
6533 cflags &= ~NET80211_CBW_FLAG_HT40;
6534
6535 error = ieee80211_add_channel_cbw(c, maxchan, n,
6536 ieee80211_mhz2ieee(channels[i].center_freq,
6537 lkpi_nl80211_band_to_net80211_band(channels[i].band)),
6538 channels[i].center_freq, channels[i].max_power,
6539 nflags, bands, cflags);
6540 /* net80211::ENOBUFS: *n >= maxchans */
6541 if (error != 0 && error != ENOBUFS)
6542 ic_printf(ic, "%s: Adding chan %u/%u/%#x/%#x/%#x/%#x "
6543 "returned error %d\n",
6544 __func__, channels[i].hw_value,
6545 channels[i].center_freq, channels[i].flags,
6546 nflags, chan_flags, cflags, error);
6547 if (error != 0)
6548 break;
6549 }
6550 }
6551
6552 /* NL80211_BAND_5GHZ */
6553 nchans = 0;
6554 if (hw->wiphy->bands[NL80211_BAND_5GHZ] != NULL)
6555 nchans = hw->wiphy->bands[NL80211_BAND_5GHZ]->n_channels;
6556 if (nchans > 0) {
6557 memset(bands, 0, sizeof(bands));
6558 chan_flags = 0;
6559 setbit(bands, IEEE80211_MODE_11A);
6560
6561 lkpi_ic_getradiocaps_ht(ic, hw, bands, &chan_flags,
6562 NL80211_BAND_5GHZ);
6563
6564 #ifdef LKPI_80211_VHT
6565 if (hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.vht_supported) {
6566
6567 ic->ic_flags_ext |= IEEE80211_FEXT_VHT;
6568 ic->ic_vht_cap.vht_cap_info =
6569 hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.cap;
6570 ic->ic_vht_cap.supp_mcs =
6571 hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.vht_mcs;
6572
6573 setbit(bands, IEEE80211_MODE_VHT_5GHZ);
6574 chan_flags |= NET80211_CBW_FLAG_VHT80;
6575 if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ(
6576 ic->ic_vht_cap.vht_cap_info))
6577 chan_flags |= NET80211_CBW_FLAG_VHT160;
6578 if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160_80P80MHZ(
6579 ic->ic_vht_cap.vht_cap_info))
6580 chan_flags |= NET80211_CBW_FLAG_VHT80P80;
6581 }
6582 #endif
6583
6584 channels = hw->wiphy->bands[NL80211_BAND_5GHZ]->channels;
6585 for (i = 0; i < nchans && *n < maxchan; i++) {
6586 uint32_t nflags = 0;
6587 int cflags = chan_flags;
6588
6589 if (channels[i].flags & IEEE80211_CHAN_DISABLED) {
6590 ic_printf(ic, "%s: Skipping disabled chan "
6591 "[%u/%u/%#x]\n", __func__,
6592 channels[i].hw_value,
6593 channels[i].center_freq, channels[i].flags);
6594 continue;
6595 }
6596 if (channels[i].flags & IEEE80211_CHAN_NO_IR)
6597 nflags |= (IEEE80211_CHAN_NOADHOC|IEEE80211_CHAN_PASSIVE);
6598 if (channels[i].flags & IEEE80211_CHAN_RADAR)
6599 nflags |= IEEE80211_CHAN_DFS;
6600 if (channels[i].flags & IEEE80211_CHAN_NO_160MHZ)
6601 cflags &= ~(NET80211_CBW_FLAG_VHT160|NET80211_CBW_FLAG_VHT80P80);
6602 if (channels[i].flags & IEEE80211_CHAN_NO_80MHZ)
6603 cflags &= ~NET80211_CBW_FLAG_VHT80;
6604 /* XXX hwo to map the remaining enum ieee80211_channel_flags? */
6605 if (channels[i].flags & IEEE80211_CHAN_NO_HT40)
6606 cflags &= ~NET80211_CBW_FLAG_HT40;
6607
6608 error = ieee80211_add_channel_cbw(c, maxchan, n,
6609 ieee80211_mhz2ieee(channels[i].center_freq,
6610 lkpi_nl80211_band_to_net80211_band(channels[i].band)),
6611 channels[i].center_freq, channels[i].max_power,
6612 nflags, bands, cflags);
6613 /* net80211::ENOBUFS: *n >= maxchans */
6614 if (error != 0 && error != ENOBUFS)
6615 ic_printf(ic, "%s: Adding chan %u/%u/%#x/%#x/%#x/%#x "
6616 "returned error %d\n",
6617 __func__, channels[i].hw_value,
6618 channels[i].center_freq, channels[i].flags,
6619 nflags, chan_flags, cflags, error);
6620 if (error != 0)
6621 break;
6622 }
6623 }
6624 }
6625
6626 static void *
6627 lkpi_ieee80211_ifalloc(void)
6628 {
6629 struct ieee80211com *ic;
6630
6631 ic = malloc(sizeof(*ic), M_LKPI80211, M_WAITOK | M_ZERO);
6632
6633 /* Setting these happens later when we have device information. */
6634 ic->ic_softc = NULL;
6635 ic->ic_name = "linuxkpi";
6636
6637 return (ic);
6638 }
6639
6640 struct ieee80211_hw *
6641 linuxkpi_ieee80211_alloc_hw(size_t priv_len, const struct ieee80211_ops *ops)
6642 {
6643 struct ieee80211_hw *hw;
6644 struct lkpi_hw *lhw;
6645 struct wiphy *wiphy;
6646 int ac;
6647 bool emuchanctx;
6648
6649 /*
6650 * Do certain checks before starting to allocate resources.
6651 * Store results in temporary variables.
6652 */
6653
6654 /* ac1d519c01ca introduced emulating chanctx changes. */
6655 emuchanctx = false;
6656 if (ops->add_chanctx == ieee80211_emulate_add_chanctx &&
6657 ops->change_chanctx == ieee80211_emulate_change_chanctx &&
6658 ops->remove_chanctx == ieee80211_emulate_remove_chanctx) {
6659 /*
6660 * If we emulate the chanctx ops, we must not have
6661 * assign_vif_chanctx and unassign_vif_chanctx.
6662 */
6663 if (ops->assign_vif_chanctx != NULL ||
6664 ops->unassign_vif_chanctx != NULL) {
6665 /* Fail gracefully. */
6666 printf("%s: emulate_chanctx but "
6667 "assign_vif_chanctx %p != NULL || "
6668 "unassign_vif_chanctx %p != NULL\n", __func__,
6669 ops->assign_vif_chanctx, ops->unassign_vif_chanctx);
6670 return (NULL);
6671 }
6672 emuchanctx = true;
6673 }
6674 if (!emuchanctx && (ops->add_chanctx == ieee80211_emulate_add_chanctx ||
6675 ops->change_chanctx == ieee80211_emulate_change_chanctx ||
6676 ops->remove_chanctx == ieee80211_emulate_remove_chanctx)) {
6677 printf("%s: not emulating chanctx changes but emulating "
6678 "function set: %d/%d/%d\n", __func__,
6679 ops->add_chanctx == ieee80211_emulate_add_chanctx,
6680 ops->change_chanctx == ieee80211_emulate_change_chanctx,
6681 ops->remove_chanctx == ieee80211_emulate_remove_chanctx);
6682 return (NULL);
6683 }
6684 if (!emuchanctx && (ops->add_chanctx == NULL || ops->change_chanctx == NULL ||
6685 ops->remove_chanctx == NULL || ops->assign_vif_chanctx == NULL ||
6686 ops->unassign_vif_chanctx == NULL)) {
6687 printf("%s: not all functions set for chanctx operations "
6688 "(emulating chanctx %d): %p/%p/%p %p/%p\n",
6689 __func__, emuchanctx,
6690 ops->add_chanctx, ops->change_chanctx, ops->remove_chanctx,
6691 ops->assign_vif_chanctx, ops->unassign_vif_chanctx);
6692 return (NULL);
6693 }
6694
6695 /* Get us and the driver data also allocated. */
6696 wiphy = wiphy_new(&linuxkpi_mac80211cfgops, sizeof(*lhw) + priv_len);
6697 if (wiphy == NULL)
6698 return (NULL);
6699
6700 lhw = wiphy_priv(wiphy);
6701 lhw->ops = ops;
6702
6703 LKPI_80211_LHW_SCAN_LOCK_INIT(lhw);
6704 LKPI_80211_LHW_TXQ_LOCK_INIT(lhw);
6705 spin_lock_init(&lhw->txq_lock);
6706 sx_init_flags(&lhw->lvif_sx, "lhw-lvif", SX_RECURSE | SX_DUPOK);
6707 LKPI_80211_LHW_MC_LOCK_INIT(lhw);
6708 TAILQ_INIT(&lhw->lvif_head);
6709 __hw_addr_init(&lhw->mc_list);
6710 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
6711 spin_lock_init(&lhw->txq_scheduled_lock[ac]);
6712 lhw->txq_generation[ac] = 1;
6713 TAILQ_INIT(&lhw->txq_scheduled[ac]);
6714 }
6715
6716 /* Chanctx_conf */
6717 INIT_LIST_HEAD(&lhw->lchanctx_list);
6718 INIT_LIST_HEAD(&lhw->lchanctx_list_reserved);
6719 lhw->emulate_chanctx = emuchanctx;
6720
6721 /* Deferred RX path. */
6722 LKPI_80211_LHW_RXQ_LOCK_INIT(lhw);
6723 TASK_INIT(&lhw->rxq_task, 0, lkpi_80211_lhw_rxq_task, lhw);
6724 mbufq_init(&lhw->rxq, 32 * NAPI_POLL_WEIGHT);
6725 lhw->rxq_stopped = false;
6726
6727 /*
6728 * XXX-BZ TODO make sure there is a "_null" function to all ops
6729 * not initialized.
6730 */
6731 hw = LHW_TO_HW(lhw);
6732 hw->wiphy = wiphy;
6733 hw->conf.flags |= IEEE80211_CONF_IDLE;
6734 hw->priv = (void *)(lhw + 1);
6735
6736 /* BSD Specific. */
6737 lhw->ic = lkpi_ieee80211_ifalloc();
6738
6739 if (lhw->emulate_chanctx)
6740 ic_printf(lhw->ic, "Using chanctx emulation.\n");
6741 IMPROVE();
6742
6743 return (hw);
6744 }
6745
6746 void
6747 linuxkpi_ieee80211_iffree(struct ieee80211_hw *hw)
6748 {
6749 struct lkpi_hw *lhw;
6750 struct mbuf *m;
6751 int ac;
6752
6753 lhw = HW_TO_LHW(hw);
6754 free(lhw->ic, M_LKPI80211);
6755 lhw->ic = NULL;
6756
6757 /*
6758 * Drain the deferred RX path.
6759 */
6760 LKPI_80211_LHW_RXQ_LOCK(lhw);
6761 lhw->rxq_stopped = true;
6762 LKPI_80211_LHW_RXQ_UNLOCK(lhw);
6763
6764 /* Drain taskq, won't be restarted due to rxq_stopped being set. */
6765 while (taskqueue_cancel(taskqueue_thread, &lhw->rxq_task, NULL) != 0)
6766 taskqueue_drain(taskqueue_thread, &lhw->rxq_task);
6767
6768 /* Flush mbufq (make sure to release ni refs!). */
6769 m = mbufq_dequeue(&lhw->rxq);
6770 while (m != NULL) {
6771 #ifdef LKPI_80211_USE_MTAG
6772 struct m_tag *mtag;
6773
6774 mtag = m_tag_locate(m, MTAG_ABI_LKPI80211, LKPI80211_TAG_RXNI, NULL);
6775 if (mtag != NULL) {
6776 struct lkpi_80211_tag_rxni *rxni;
6777
6778 rxni = (struct lkpi_80211_tag_rxni *)(mtag + 1);
6779 ieee80211_free_node(rxni->ni);
6780 }
6781 #else
6782 if (m->m_pkthdr.PH_loc.ptr != NULL) {
6783 struct ieee80211_node *ni;
6784
6785 ni = m->m_pkthdr.PH_loc.ptr;
6786 ieee80211_free_node(ni);
6787 }
6788 #endif
6789 m_freem(m);
6790 m = mbufq_dequeue(&lhw->rxq);
6791 }
6792 KASSERT(mbufq_empty(&lhw->rxq), ("%s: lhw %p has rxq len %d != 0\n",
6793 __func__, lhw, mbufq_len(&lhw->rxq)));
6794 LKPI_80211_LHW_RXQ_LOCK_DESTROY(lhw);
6795
6796 wiphy_lock(hw->wiphy);
6797 /* Chanctx_conf. */
6798 if (!list_empty_careful(&lhw->lchanctx_list)) {
6799 struct lkpi_chanctx *lchanctx, *next;
6800 struct ieee80211_chanctx_conf *chanctx_conf;
6801
6802 list_for_each_entry_safe(lchanctx, next, &lhw->lchanctx_list, entry) {
6803 if (lchanctx->added_to_drv) {
6804 /* In reality we should panic? */
6805 chanctx_conf = &lchanctx->chanctx_conf;
6806 lkpi_80211_mo_remove_chanctx(hw, chanctx_conf);
6807 }
6808 list_del(&lchanctx->entry);
6809 list_add_rcu(&lchanctx->entry, &lhw->lchanctx_list_reserved);
6810 }
6811 }
6812 if (!list_empty_careful(&lhw->lchanctx_list_reserved)) {
6813 struct lkpi_chanctx *lchanctx, *next;
6814
6815 list_for_each_entry_safe(lchanctx, next, &lhw->lchanctx_list_reserved, entry) {
6816 list_del(&lchanctx->entry);
6817 if (lchanctx->added_to_drv)
6818 panic("%s: lchanctx %p on reserved list still added_to_drv\n",
6819 __func__, lchanctx);
6820 free(lchanctx, M_LKPI80211);
6821 }
6822 }
6823 wiphy_unlock(hw->wiphy);
6824
6825 LKPI_80211_LHW_MC_LOCK(lhw);
6826 lkpi_cleanup_mcast_list_locked(lhw);
6827 LKPI_80211_LHW_MC_UNLOCK(lhw);
6828
6829 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
6830 spin_lock_destroy(&lhw->txq_scheduled_lock[ac]);
6831
6832 /* Cleanup more of lhw here or in wiphy_free()? */
6833 spin_lock_destroy(&lhw->txq_lock);
6834 LKPI_80211_LHW_TXQ_LOCK_DESTROY(lhw);
6835 LKPI_80211_LHW_SCAN_LOCK_DESTROY(lhw);
6836 sx_destroy(&lhw->lvif_sx);
6837 LKPI_80211_LHW_MC_LOCK_DESTROY(lhw)
6838 IMPROVE();
6839 }
6840
6841 void
6842 linuxkpi_set_ieee80211_dev(struct ieee80211_hw *hw)
6843 {
6844 struct lkpi_hw *lhw;
6845 struct ieee80211com *ic;
6846 struct device *dev;
6847
6848 lhw = HW_TO_LHW(hw);
6849 ic = lhw->ic;
6850
6851 /* Save the backpointer from net80211 to LinuxKPI. */
6852 ic->ic_softc = lhw;
6853
6854 /*
6855 * Set a proper name before ieee80211_ifattach() if dev is set.
6856 * ath1xk also unset the dev so we need to check.
6857 */
6858 dev = wiphy_dev(hw->wiphy);
6859 if (dev != NULL) {
6860 ic->ic_name = dev_name(dev);
6861 } else {
6862 TODO("adjust arguments to still have the old dev or go through "
6863 "the hoops of getting the bsddev from hw and detach; "
6864 "or do in XXX; check ath1kx drivers");
6865 }
6866
6867 /* XXX-BZ do we also need to set wiphy name? */
6868 }
6869
6870 struct ieee80211_hw *
6871 linuxkpi_wiphy_to_ieee80211_hw(struct wiphy *wiphy)
6872 {
6873 struct lkpi_hw *lhw;
6874
6875 lhw = wiphy_priv(wiphy);
6876 return (LHW_TO_HW(lhw));
6877 }
6878
6879 static void
6880 lkpi_radiotap_attach(struct lkpi_hw *lhw)
6881 {
6882 struct ieee80211com *ic;
6883
6884 ic = lhw->ic;
6885 ieee80211_radiotap_attach(ic,
6886 &lhw->rtap_tx.wt_ihdr, sizeof(lhw->rtap_tx),
6887 LKPI_RTAP_TX_FLAGS_PRESENT,
6888 &lhw->rtap_rx.wr_ihdr, sizeof(lhw->rtap_rx),
6889 LKPI_RTAP_RX_FLAGS_PRESENT);
6890 }
6891
6892 int
6893 linuxkpi_ieee80211_ifattach(struct ieee80211_hw *hw)
6894 {
6895 struct ieee80211com *ic;
6896 struct lkpi_hw *lhw;
6897 int band, i;
6898
6899 lhw = HW_TO_LHW(hw);
6900 ic = lhw->ic;
6901
6902 /* We do it this late as wiphy->dev should be set for the name. */
6903 lhw->workq = alloc_ordered_workqueue(wiphy_name(hw->wiphy), 0);
6904 if (lhw->workq == NULL)
6905 return (-EAGAIN);
6906
6907 /* XXX-BZ figure this out how they count his... */
6908 if (!is_zero_ether_addr(hw->wiphy->perm_addr)) {
6909 IEEE80211_ADDR_COPY(ic->ic_macaddr,
6910 hw->wiphy->perm_addr);
6911 } else if (hw->wiphy->n_addresses > 0) {
6912 /* We take the first one. */
6913 IEEE80211_ADDR_COPY(ic->ic_macaddr,
6914 hw->wiphy->addresses[0].addr);
6915 } else {
6916 ic_printf(ic, "%s: warning, no hardware address!\n", __func__);
6917 }
6918
6919 #ifdef __not_yet__
6920 /* See comment in lkpi_80211_txq_tx_one(). */
6921 ic->ic_headroom = hw->extra_tx_headroom;
6922 #endif
6923
6924 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
6925 ic->ic_opmode = IEEE80211_M_STA;
6926
6927 /* Set device capabilities. */
6928 /* XXX-BZ we need to get these from linux80211/drivers and convert. */
6929 ic->ic_caps =
6930 IEEE80211_C_STA |
6931 IEEE80211_C_MONITOR |
6932 IEEE80211_C_WPA | /* WPA/RSN */
6933 #ifdef LKPI_80211_WME
6934 IEEE80211_C_WME |
6935 #endif
6936 #if 0
6937 IEEE80211_C_PMGT |
6938 #endif
6939 IEEE80211_C_SHSLOT | /* short slot time supported */
6940 IEEE80211_C_SHPREAMBLE /* short preamble supported */
6941 ;
6942
6943 #ifdef LKPI_80211_BGSCAN
6944 if (lhw->ops->hw_scan)
6945 ic->ic_caps |= IEEE80211_C_BGSCAN;
6946 #endif
6947
6948 lkpi_enable_hw_scan(lhw);
6949
6950 /* Does HW support Fragmentation offload? */
6951 if (ieee80211_hw_check(hw, SUPPORTS_TX_FRAG))
6952 ic->ic_flags_ext |= IEEE80211_FEXT_FRAG_OFFLOAD;
6953
6954 /* Does HW support full AMPDU[-TX] offload? */
6955 if (ieee80211_hw_check(hw, AMPDU_AGGREGATION))
6956 ic->ic_flags_ext |= IEEE80211_FEXT_AMPDU_OFFLOAD;
6957 #ifdef __notyet__
6958 if (ieee80211_hw_check(hw, TX_AMSDU))
6959 if (ieee80211_hw_check(hw, SUPPORTS_AMSDU_IN_AMPDU))
6960 #endif
6961
6962 /*
6963 * The wiphy variables report bitmasks of avail antennas.
6964 * (*get_antenna) get the current bitmask sets which can be
6965 * altered by (*set_antenna) for some drivers.
6966 * XXX-BZ will the count alone do us much good long-term in net80211?
6967 */
6968 if (hw->wiphy->available_antennas_rx ||
6969 hw->wiphy->available_antennas_tx) {
6970 uint32_t rxs, txs;
6971
6972 if (lkpi_80211_mo_get_antenna(hw, &txs, &rxs) == 0) {
6973 ic->ic_rxstream = bitcount32(rxs);
6974 ic->ic_txstream = bitcount32(txs);
6975 }
6976 }
6977
6978 ic->ic_cryptocaps = 0;
6979 #ifdef LKPI_80211_HW_CRYPTO
6980 if (lkpi_hwcrypto && hw->wiphy->n_cipher_suites > 0) {
6981 uint32_t hwciphers;
6982
6983 hwciphers = 0;
6984 for (i = 0; i < hw->wiphy->n_cipher_suites; i++) {
6985 uint32_t cs;
6986
6987 cs = lkpi_l80211_to_net80211_cyphers(
6988 ic, hw->wiphy->cipher_suites[i]);
6989 if (cs == IEEE80211_CRYPTO_TKIP) {
6990 /*
6991 * We do set this here. We will only find out
6992 * when doing a SET_KEY operation depending on
6993 * what the driver returns.
6994 * net80211::ieee80211_crypto_newkey()
6995 * checks this so we will have to do flags
6996 * surgery later.
6997 */
6998 cs |= IEEE80211_CRYPTO_TKIPMIC;
6999 }
7000 hwciphers |= cs;
7001 }
7002 /*
7003 * (20250415) nothing anywhere in the path checks we actually
7004 * support all these in net80211.
7005 * net80211 supports _256 variants but the ioctl does not.
7006 */
7007 IMPROVE("as net80211 grows more support, enable them");
7008 hwciphers &= (IEEE80211_CRYPTO_WEP |
7009 IEEE80211_CRYPTO_TKIP | IEEE80211_CRYPTO_TKIPMIC |
7010 IEEE80211_CRYPTO_AES_CCM | IEEE80211_CRYPTO_AES_GCM_128);
7011 /*
7012 * We only support CCMP here, so further filter.
7013 * Also permit TKIP if turned on.
7014 */
7015 hwciphers &= (IEEE80211_CRYPTO_AES_CCM |
7016 IEEE80211_CRYPTO_AES_GCM_128 |
7017 (lkpi_hwcrypto_tkip ? (IEEE80211_CRYPTO_TKIP |
7018 IEEE80211_CRYPTO_TKIPMIC) : 0));
7019 ieee80211_set_hardware_ciphers(ic, hwciphers);
7020 }
7021 #endif
7022
7023 lkpi_ic_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
7024 ic->ic_channels);
7025
7026 ieee80211_ifattach(ic);
7027
7028 ic->ic_update_mcast = lkpi_ic_update_mcast;
7029 ic->ic_update_promisc = lkpi_ic_update_promisc;
7030 ic->ic_update_chw = lkpi_ic_update_chw;
7031 ic->ic_parent = lkpi_ic_parent;
7032 ic->ic_scan_start = lkpi_ic_scan_start;
7033 ic->ic_scan_end = lkpi_ic_scan_end;
7034 ic->ic_set_channel = lkpi_ic_set_channel;
7035 ic->ic_transmit = lkpi_ic_transmit;
7036 ic->ic_raw_xmit = lkpi_ic_raw_xmit;
7037 ic->ic_vap_create = lkpi_ic_vap_create;
7038 ic->ic_vap_delete = lkpi_ic_vap_delete;
7039 ic->ic_getradiocaps = lkpi_ic_getradiocaps;
7040 ic->ic_wme.wme_update = lkpi_ic_wme_update;
7041
7042 lhw->ic_scan_curchan = ic->ic_scan_curchan;
7043 ic->ic_scan_curchan = lkpi_ic_scan_curchan;
7044 lhw->ic_scan_mindwell = ic->ic_scan_mindwell;
7045 ic->ic_scan_mindwell = lkpi_ic_scan_mindwell;
7046
7047 lhw->ic_node_alloc = ic->ic_node_alloc;
7048 ic->ic_node_alloc = lkpi_ic_node_alloc;
7049 lhw->ic_node_init = ic->ic_node_init;
7050 ic->ic_node_init = lkpi_ic_node_init;
7051 lhw->ic_node_cleanup = ic->ic_node_cleanup;
7052 ic->ic_node_cleanup = lkpi_ic_node_cleanup;
7053 lhw->ic_node_free = ic->ic_node_free;
7054 ic->ic_node_free = lkpi_ic_node_free;
7055
7056 #ifdef LKPI_80211_HT
7057 /*
7058 * Only attach if the driver/firmware supports (*ampdu_action)().
7059 * Otherwise it is in the hands of net80211.
7060 */
7061 if (lhw->ops->ampdu_action != NULL) {
7062 lhw->ic_recv_action = ic->ic_recv_action;
7063 ic->ic_recv_action = lkpi_ic_recv_action;
7064 lhw->ic_send_action = ic->ic_send_action;
7065 ic->ic_send_action = lkpi_ic_send_action;
7066
7067 lhw->ic_ampdu_enable = ic->ic_ampdu_enable;
7068 ic->ic_ampdu_enable = lkpi_ic_ampdu_enable;
7069
7070 lhw->ic_addba_request = ic->ic_addba_request;
7071 ic->ic_addba_request = lkpi_ic_addba_request;
7072 lhw->ic_addba_response = ic->ic_addba_response;
7073 ic->ic_addba_response = lkpi_ic_addba_response;
7074 lhw->ic_addba_stop = ic->ic_addba_stop;
7075 ic->ic_addba_stop = lkpi_ic_addba_stop;
7076 lhw->ic_addba_response_timeout = ic->ic_addba_response_timeout;
7077 ic->ic_addba_response_timeout = lkpi_ic_addba_response_timeout;
7078
7079 lhw->ic_bar_response = ic->ic_bar_response;
7080 ic->ic_bar_response = lkpi_ic_bar_response;
7081
7082 lhw->ic_ampdu_rx_start = ic->ic_ampdu_rx_start;
7083 ic->ic_ampdu_rx_start = lkpi_ic_ampdu_rx_start;
7084 lhw->ic_ampdu_rx_stop = ic->ic_ampdu_rx_stop;
7085 ic->ic_ampdu_rx_stop = lkpi_ic_ampdu_rx_stop;
7086 }
7087 #endif
7088
7089 lkpi_radiotap_attach(lhw);
7090
7091 /*
7092 * Assign the first possible channel for now; seems Realtek drivers
7093 * expect one.
7094 * Also remember the amount of bands we support and the most rates
7095 * in any band so we can scale [(ext) sup rates] IE(s) accordingly.
7096 */
7097 lhw->supbands = lhw->max_rates = 0;
7098 for (band = 0; band < NUM_NL80211_BANDS; band++) {
7099 struct ieee80211_supported_band *supband;
7100 struct linuxkpi_ieee80211_channel *channels;
7101
7102 supband = hw->wiphy->bands[band];
7103 if (supband == NULL || supband->n_channels == 0)
7104 continue;
7105
7106 lhw->supbands++;
7107 lhw->max_rates = max(lhw->max_rates, supband->n_bitrates);
7108
7109 /* If we have a channel, we need to keep counting supbands. */
7110 if (hw->conf.chandef.chan != NULL)
7111 continue;
7112
7113 channels = supband->channels;
7114 for (i = 0; i < supband->n_channels; i++) {
7115
7116 if (channels[i].flags & IEEE80211_CHAN_DISABLED)
7117 continue;
7118
7119 cfg80211_chandef_create(&hw->conf.chandef, &channels[i],
7120 #ifdef LKPI_80211_HT
7121 (ic->ic_flags_ht & IEEE80211_FHT_HT) ? NL80211_CHAN_HT20 :
7122 #endif
7123 NL80211_CHAN_NO_HT);
7124 lhw->dflt_chandef = hw->conf.chandef;
7125 #ifdef LINUXKPI_DEBUG_80211
7126 if ((linuxkpi_debug_80211 & D80211_CHANDEF) != 0)
7127 ic_printf(ic, "%s:%d: initialized "
7128 "hw->conf.chandef and dflt_chandef to %p\n",
7129 __func__, __LINE__, &lhw->dflt_chandef);
7130 #endif
7131 break;
7132 }
7133 }
7134
7135 IMPROVE("see net80211::ieee80211_chan_init vs. wiphy->bands[].bitrates possibly in lkpi_ic_getradiocaps?");
7136
7137 /* Make sure we do not support more than net80211 is willing to take. */
7138 if (lhw->max_rates > IEEE80211_RATE_MAXSIZE) {
7139 ic_printf(ic, "%s: limiting max_rates %d to %d!\n", __func__,
7140 lhw->max_rates, IEEE80211_RATE_MAXSIZE);
7141 lhw->max_rates = IEEE80211_RATE_MAXSIZE;
7142 }
7143
7144 /*
7145 * The maximum supported bitrates on any band + size for
7146 * DSSS Parameter Set give our per-band IE size.
7147 * SSID is the responsibility of the driver and goes on the side.
7148 * The user specified bits coming from the vap go into the
7149 * "common ies" fields.
7150 */
7151 lhw->scan_ie_len = 2 + IEEE80211_RATE_SIZE;
7152 if (lhw->max_rates > IEEE80211_RATE_SIZE)
7153 lhw->scan_ie_len += 2 + (lhw->max_rates - IEEE80211_RATE_SIZE);
7154
7155 if (hw->wiphy->features & NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) {
7156 /*
7157 * net80211 does not seem to support the DSSS Parameter Set but
7158 * some of the drivers insert it so calculate the extra fixed
7159 * space in.
7160 */
7161 lhw->scan_ie_len += 2 + 1;
7162 }
7163
7164 #if defined(LKPI_80211_HT)
7165 if ((ic->ic_htcaps & IEEE80211_HTC_HT) != 0)
7166 lhw->scan_ie_len += sizeof(struct ieee80211_ie_htcap);
7167 #endif
7168 #if defined(LKPI_80211_VHT)
7169 if (IEEE80211_CONF_VHT(ic))
7170 lhw->scan_ie_len += 2 + sizeof(struct ieee80211_vht_cap);
7171 #endif
7172
7173 /* Reduce the max_scan_ie_len "left" by the amount we consume already. */
7174 if (hw->wiphy->max_scan_ie_len > 0) {
7175 if (lhw->scan_ie_len > hw->wiphy->max_scan_ie_len)
7176 goto err;
7177 hw->wiphy->max_scan_ie_len -= lhw->scan_ie_len;
7178 }
7179
7180 if (bootverbose) {
7181 if (hw->netdev_features != 0)
7182 ic_printf(ic, "netdev_features %b\n",
7183 hw->netdev_features, NETIF_F_BITS);
7184 ieee80211_announce(ic);
7185 }
7186
7187 return (0);
7188 err:
7189 IMPROVE("TODO FIXME CLEANUP");
7190 return (-EAGAIN);
7191 }
7192
7193 void
7194 linuxkpi_ieee80211_ifdetach(struct ieee80211_hw *hw)
7195 {
7196 struct lkpi_hw *lhw;
7197 struct ieee80211com *ic;
7198
7199 lhw = HW_TO_LHW(hw);
7200 ic = lhw->ic;
7201 ieee80211_ifdetach(ic);
7202 }
7203
7204 void
7205 linuxkpi_ieee80211_iterate_interfaces(struct ieee80211_hw *hw,
7206 enum ieee80211_iface_iter flags,
7207 void(*iterfunc)(void *, uint8_t *, struct ieee80211_vif *),
7208 void *arg)
7209 {
7210 struct lkpi_hw *lhw;
7211 struct lkpi_vif *lvif;
7212 struct ieee80211_vif *vif;
7213 bool active, atomic, nin_drv;
7214
7215 lhw = HW_TO_LHW(hw);
7216
7217 if (flags & ~(IEEE80211_IFACE_ITER_NORMAL|
7218 IEEE80211_IFACE_ITER_RESUME_ALL|
7219 IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER|
7220 IEEE80211_IFACE_ITER_ACTIVE|IEEE80211_IFACE_ITER__ATOMIC|
7221 IEEE80211_IFACE_ITER__MTX)) {
7222 ic_printf(lhw->ic, "XXX TODO %s flags(%#x) not yet supported.\n",
7223 __func__, flags);
7224 }
7225
7226 if ((flags & IEEE80211_IFACE_ITER__MTX) != 0)
7227 lockdep_assert_wiphy(hw->wiphy);
7228
7229 active = (flags & IEEE80211_IFACE_ITER_ACTIVE) != 0;
7230 atomic = (flags & IEEE80211_IFACE_ITER__ATOMIC) != 0;
7231 nin_drv = (flags & IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER) != 0;
7232
7233 if (atomic) {
7234 IMPROVE("LKPI_80211_LHW_LVIF_LOCK atomic assume to be rcu?");
7235 LKPI_80211_LHW_LVIF_LOCK(lhw);
7236 }
7237 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
7238 struct ieee80211vap *vap;
7239
7240 vif = LVIF_TO_VIF(lvif);
7241
7242 /*
7243 * If we want "active" interfaces, we need to distinguish on
7244 * whether the driver knows about them or not to be able to
7245 * handle the "resume" case correctly. Skip the ones the
7246 * driver does not know about.
7247 */
7248 if (active && !lvif->added_to_drv &&
7249 (flags & IEEE80211_IFACE_ITER_RESUME_ALL) != 0)
7250 continue;
7251
7252 /*
7253 * If we shall skip interfaces not added to the driver do so
7254 * if we haven't yet.
7255 */
7256 if (nin_drv && !lvif->added_to_drv)
7257 continue;
7258
7259 /*
7260 * Run the iterator function if we are either not asking
7261 * asking for active only or if the VAP is "running".
7262 */
7263 /* XXX-BZ probably should have state in the lvif as well. */
7264 vap = LVIF_TO_VAP(lvif);
7265 if (!active || (vap->iv_state != IEEE80211_S_INIT))
7266 iterfunc(arg, vif->addr, vif);
7267 }
7268 if (atomic)
7269 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
7270 }
7271
7272 static void
7273 lkpi_ieee80211_iterate_keys(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
7274 ieee80211_keyix keyix, struct lkpi_sta *lsta,
7275 void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *,
7276 struct ieee80211_sta *, struct ieee80211_key_conf *, void *),
7277 void *arg)
7278 {
7279 #ifdef LINUXKPI_DEBUG_80211
7280 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
7281 net80211_vap_printf(LVIF_TO_VAP(VIF_TO_LVIF(vif)),
7282 "%s:%d: lsta %6D added_to_drv %d kc[keyix %u] %p\n",
7283 __func__, __LINE__, LSTA_TO_STA(lsta)->addr, ":",
7284 lsta->added_to_drv, keyix, lsta->kc[keyix]);
7285 #endif
7286
7287 if (!lsta->added_to_drv)
7288 return;
7289
7290 if (lsta->kc[keyix] == NULL)
7291 return;
7292
7293 iterfunc(hw, vif, LSTA_TO_STA(lsta), lsta->kc[keyix], arg);
7294 }
7295
7296 void
7297 linuxkpi_ieee80211_iterate_keys(struct ieee80211_hw *hw,
7298 struct ieee80211_vif *vif,
7299 void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *,
7300 struct ieee80211_sta *, struct ieee80211_key_conf *, void *),
7301 void *arg, bool rcu)
7302 {
7303 struct lkpi_sta *lsta;
7304 struct lkpi_vif *lvif;
7305
7306 lvif = VIF_TO_LVIF(vif);
7307
7308 if (rcu) {
7309 rcu_read_lock_held(); /* XXX-BZ is this correct? */
7310
7311 if (vif == NULL) {
7312 TODO();
7313 } else {
7314 list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
7315 for (ieee80211_keyix keyix = 0; keyix < nitems(lsta->kc);
7316 keyix++)
7317 lkpi_ieee80211_iterate_keys(hw, vif,
7318 keyix, lsta, iterfunc, arg);
7319 }
7320 }
7321 } else {
7322 TODO("Used by suspend/resume; order of keys as installed to "
7323 "firmware is important; we'll need to rewrite some code for that");
7324 lockdep_assert_wiphy(hw->wiphy);
7325
7326 if (vif == NULL) {
7327 TODO();
7328 } else {
7329 list_for_each_entry(lsta, &lvif->lsta_list, lsta_list) {
7330 for (ieee80211_keyix keyix = 0; keyix < nitems(lsta->kc);
7331 keyix++)
7332 lkpi_ieee80211_iterate_keys(hw, vif,
7333 keyix, lsta, iterfunc, arg);
7334 }
7335 }
7336 }
7337 }
7338
7339 void
7340 linuxkpi_ieee80211_iterate_chan_contexts(struct ieee80211_hw *hw,
7341 void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *,
7342 void *),
7343 void *arg)
7344 {
7345 struct lkpi_hw *lhw;
7346 struct lkpi_chanctx *lchanctx;
7347
7348 KASSERT(hw != NULL && iterfunc != NULL,
7349 ("%s: hw %p iterfunc %p arg %p\n", __func__, hw, iterfunc, arg));
7350
7351 lhw = HW_TO_LHW(hw);
7352
7353 rcu_read_lock();
7354 list_for_each_entry_rcu(lchanctx, &lhw->lchanctx_list, entry) {
7355 if (!lchanctx->added_to_drv)
7356 continue;
7357 iterfunc(hw, &lchanctx->chanctx_conf, arg);
7358 }
7359 rcu_read_unlock();
7360 }
7361
7362 void
7363 linuxkpi_ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
7364 void (*iterfunc)(void *, struct ieee80211_sta *), void *arg)
7365 {
7366 struct lkpi_hw *lhw;
7367 struct lkpi_vif *lvif;
7368 struct lkpi_sta *lsta;
7369 struct ieee80211_sta *sta;
7370
7371 KASSERT(hw != NULL && iterfunc != NULL,
7372 ("%s: hw %p iterfunc %p arg %p\n", __func__, hw, iterfunc, arg));
7373
7374 lhw = HW_TO_LHW(hw);
7375
7376 LKPI_80211_LHW_LVIF_LOCK(lhw);
7377 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
7378
7379 rcu_read_lock();
7380 list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
7381 if (!lsta->added_to_drv)
7382 continue;
7383 sta = LSTA_TO_STA(lsta);
7384 iterfunc(arg, sta);
7385 }
7386 rcu_read_unlock();
7387 }
7388 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
7389 }
7390
7391 struct linuxkpi_ieee80211_regdomain *
7392 lkpi_get_linuxkpi_ieee80211_regdomain(size_t n)
7393 {
7394 struct linuxkpi_ieee80211_regdomain *regd;
7395
7396 regd = kzalloc(sizeof(*regd) + n * sizeof(struct ieee80211_reg_rule),
7397 GFP_KERNEL);
7398 return (regd);
7399 }
7400
7401 int
7402 linuxkpi_regulatory_set_wiphy_regd_sync(struct wiphy *wiphy,
7403 struct linuxkpi_ieee80211_regdomain *regd)
7404 {
7405 struct lkpi_hw *lhw;
7406 struct ieee80211com *ic;
7407 struct ieee80211_regdomain *rd;
7408
7409 lhw = wiphy_priv(wiphy);
7410 ic = lhw->ic;
7411
7412 rd = &ic->ic_regdomain;
7413 if (rd->isocc[0] == '\0') {
7414 rd->isocc[0] = regd->alpha2[0];
7415 rd->isocc[1] = regd->alpha2[1];
7416 }
7417
7418 TODO();
7419 /* XXX-BZ finish the rest. */
7420
7421 return (0);
7422 }
7423
7424 void
7425 linuxkpi_ieee80211_scan_completed(struct ieee80211_hw *hw,
7426 struct cfg80211_scan_info *info)
7427 {
7428 struct lkpi_hw *lhw;
7429 struct ieee80211com *ic;
7430 struct ieee80211_scan_state *ss;
7431
7432 lhw = wiphy_priv(hw->wiphy);
7433 ic = lhw->ic;
7434 ss = ic->ic_scan;
7435
7436 TRACE_SCAN(ic, "scan_flags %b info { %ju, %6D, aborted %d }",
7437 lhw->scan_flags, LKPI_LHW_SCAN_BITS,
7438 (uintmax_t)info->scan_start_tsf, info->tsf_bssid, ":",
7439 info->aborted);
7440
7441 ieee80211_scan_done(ss->ss_vap);
7442
7443 LKPI_80211_LHW_SCAN_LOCK(lhw);
7444 free(lhw->hw_req, M_LKPI80211);
7445 lhw->hw_req = NULL;
7446 lhw->scan_flags &= ~LKPI_LHW_SCAN_RUNNING;
7447 /* The wakeup(lhw) will be called from lkpi_ic_scan_end(). */
7448 /* wakeup(lhw); */
7449 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
7450
7451 return;
7452 }
7453
7454 static void
7455 lkpi_80211_lhw_rxq_rx_one(struct lkpi_hw *lhw, struct mbuf *m)
7456 {
7457 struct ieee80211_node *ni;
7458 #ifdef LKPI_80211_USE_MTAG
7459 struct m_tag *mtag;
7460 #endif
7461 int ok;
7462
7463 ni = NULL;
7464 #ifdef LKPI_80211_USE_MTAG
7465 mtag = m_tag_locate(m, MTAG_ABI_LKPI80211, LKPI80211_TAG_RXNI, NULL);
7466 if (mtag != NULL) {
7467 struct lkpi_80211_tag_rxni *rxni;
7468
7469 rxni = (struct lkpi_80211_tag_rxni *)(mtag + 1);
7470 ni = rxni->ni;
7471 }
7472 #else
7473 if (m->m_pkthdr.PH_loc.ptr != NULL) {
7474 ni = m->m_pkthdr.PH_loc.ptr;
7475 m->m_pkthdr.PH_loc.ptr = NULL;
7476 }
7477 #endif
7478
7479 if (ni != NULL) {
7480 ok = ieee80211_input_mimo(ni, m);
7481 ieee80211_free_node(ni); /* Release the reference. */
7482 if (ok < 0)
7483 m_freem(m);
7484 } else {
7485 ok = ieee80211_input_mimo_all(lhw->ic, m);
7486 /* mbuf got consumed. */
7487 }
7488
7489 #ifdef LINUXKPI_DEBUG_80211
7490 if (linuxkpi_debug_80211 & D80211_TRACE_RX)
7491 printf("TRACE-RX: %s: handled frame type %#0x\n", __func__, ok);
7492 #endif
7493 }
7494
7495 static void
7496 lkpi_80211_lhw_rxq_task(void *ctx, int pending)
7497 {
7498 struct lkpi_hw *lhw;
7499 struct mbufq mq;
7500 struct mbuf *m;
7501
7502 lhw = ctx;
7503
7504 #ifdef LINUXKPI_DEBUG_80211
7505 if (linuxkpi_debug_80211 & D80211_TRACE_RX)
7506 printf("TRACE-RX: %s: lhw %p pending %d mbuf_qlen %d\n",
7507 __func__, lhw, pending, mbufq_len(&lhw->rxq));
7508 #endif
7509
7510 mbufq_init(&mq, IFQ_MAXLEN);
7511
7512 LKPI_80211_LHW_RXQ_LOCK(lhw);
7513 mbufq_concat(&mq, &lhw->rxq);
7514 LKPI_80211_LHW_RXQ_UNLOCK(lhw);
7515
7516 m = mbufq_dequeue(&mq);
7517 while (m != NULL) {
7518 lkpi_80211_lhw_rxq_rx_one(lhw, m);
7519 m = mbufq_dequeue(&mq);
7520 }
7521 }
7522
7523 static void
7524 lkpi_convert_rx_status(struct ieee80211_hw *hw, struct lkpi_sta *lsta,
7525 struct ieee80211_rx_status *rx_status,
7526 struct ieee80211_rx_stats *rx_stats,
7527 uint8_t *rssip)
7528 {
7529 struct ieee80211_supported_band *supband;
7530 struct rate_info rxrate;
7531 int i;
7532 uint8_t rssi;
7533
7534 memset(&rxrate, 0, sizeof(rxrate));
7535 memset(rx_stats, 0, sizeof(*rx_stats));
7536 rx_stats->r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI;
7537 /* XXX-BZ correct hardcoded noise floor, survey data? */
7538 rx_stats->c_nf = -96;
7539 if (ieee80211_hw_check(hw, SIGNAL_DBM) &&
7540 !(rx_status->flag & RX_FLAG_NO_SIGNAL_VAL))
7541 rssi = rx_status->signal;
7542 else
7543 rssi = rx_stats->c_nf;
7544 /*
7545 * net80211 signal strength data are in .5 dBm units relative to
7546 * the current noise floor (see comment in ieee80211_node.h).
7547 */
7548 rssi -= rx_stats->c_nf;
7549 if (rssip != NULL)
7550 *rssip = rssi;
7551 rx_stats->c_rssi = rssi * 2;
7552 rx_stats->r_flags |= IEEE80211_R_BAND;
7553 rx_stats->c_band =
7554 lkpi_nl80211_band_to_net80211_band(rx_status->band);
7555 rx_stats->r_flags |= IEEE80211_R_FREQ | IEEE80211_R_IEEE;
7556 rx_stats->c_freq = rx_status->freq;
7557 rx_stats->c_ieee = ieee80211_mhz2ieee(rx_stats->c_freq, rx_stats->c_band);
7558
7559 rx_stats->c_rx_tsf = rx_status->mactime;
7560
7561 /* XXX RX_FLAG_MACTIME_IS_RTAP_TS64 ? */
7562 if ((rx_status->flag & RX_FLAG_MACTIME) ==
7563 (RX_FLAG_MACTIME_START|RX_FLAG_MACTIME_END)) {
7564 rx_stats->r_flags |= IEEE80211_R_TSF64;
7565 /* XXX RX_FLAG_MACTIME_PLCP_START ? */
7566 if ((rx_status->flag & RX_FLAG_MACTIME) == RX_FLAG_MACTIME_START)
7567 rx_stats->r_flags |= IEEE80211_R_TSF_START;
7568 if ((rx_status->flag & RX_FLAG_MACTIME) == RX_FLAG_MACTIME_END)
7569 rx_stats->r_flags |= IEEE80211_R_TSF_END;
7570 /* XXX-BZ if TSF_END will net80211 do the unwind of time? */
7571 }
7572
7573 if (rx_status->chains != 0) {
7574 int cc;
7575 int8_t crssi;
7576
7577 rx_stats->c_chain = rx_status->chains;
7578 rx_stats->r_flags |= IEEE80211_R_C_CHAIN;
7579
7580 cc = 0;
7581 for (i = 0; i < nitems(rx_status->chain_signal); i++) {
7582 if (!(rx_status->chains & BIT(i)))
7583 continue;
7584 crssi = rx_status->chain_signal[i];
7585 crssi -= rx_stats->c_nf;
7586 rx_stats->c_rssi_ctl[i] = crssi * 2;
7587 rx_stats->c_rssi_ext[i] = crssi * 2; /* XXX _ext ??? ATH thing? */
7588 /* We currently only have the global noise floor value. */
7589 rx_stats->c_nf_ctl[i] = rx_stats->c_nf;
7590 rx_stats->c_nf_ext[i] = rx_stats->c_nf;
7591 cc++;
7592 }
7593 if (cc > 0)
7594 rx_stats->r_flags |= (IEEE80211_R_C_NF | IEEE80211_R_C_RSSI);
7595 }
7596
7597 /* XXX-NET80211 We are not going to populate c_phytype! */
7598
7599 switch (rx_status->encoding) {
7600 case RX_ENC_LEGACY:
7601 {
7602 uint32_t legacy = 0;
7603
7604 supband = hw->wiphy->bands[rx_status->band];
7605 if (supband != NULL)
7606 legacy = supband->bitrates[rx_status->rate_idx].bitrate;
7607 rx_stats->c_rate = legacy;
7608 rxrate.legacy = legacy;
7609 /* Is there a LinuxKPI way of reporting IEEE80211_RX_F_CCK / _OFDM? */
7610 break;
7611 }
7612 case RX_ENC_HT:
7613 rx_stats->c_pktflags |= IEEE80211_RX_F_HT;
7614 rx_stats->c_rate = rx_status->rate_idx; /* mcs */
7615 rxrate.flags |= RATE_INFO_FLAGS_MCS;
7616 rxrate.mcs = rx_status->rate_idx;
7617 if ((rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI) != 0) {
7618 rx_stats->c_pktflags |= IEEE80211_RX_F_SHORTGI;
7619 rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7620 }
7621 break;
7622 case RX_ENC_VHT:
7623 rx_stats->c_pktflags |= IEEE80211_RX_F_VHT;
7624 rx_stats->c_rate = rx_status->rate_idx; /* mcs */
7625 rx_stats->c_vhtnss = rx_status->nss;
7626 rxrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7627 rxrate.mcs = rx_status->rate_idx;
7628 rxrate.nss = rx_status->nss;
7629 if ((rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI) != 0) {
7630 rx_stats->c_pktflags |= IEEE80211_RX_F_SHORTGI;
7631 rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7632 }
7633 break;
7634 case RX_ENC_HE:
7635 rxrate.flags |= RATE_INFO_FLAGS_HE_MCS;
7636 rxrate.mcs = rx_status->rate_idx;
7637 rxrate.nss = rx_status->nss;
7638 /* XXX TODO */
7639 TODO("net80211 has not matching encoding for %u", rx_status->encoding);
7640 break;
7641 case RX_ENC_EHT:
7642 rxrate.flags |= RATE_INFO_FLAGS_EHT_MCS;
7643 rxrate.mcs = rx_status->rate_idx;
7644 rxrate.nss = rx_status->nss;
7645 /* XXX TODO */
7646 TODO("net80211 has not matching encoding for %u", rx_status->encoding);
7647 break;
7648 }
7649
7650 rxrate.bw = rx_status->bw;
7651 switch (rx_status->bw) {
7652 case RATE_INFO_BW_20:
7653 rx_stats->c_width = IEEE80211_RX_FW_20MHZ;
7654 break;
7655 case RATE_INFO_BW_40:
7656 rx_stats->c_width = IEEE80211_RX_FW_40MHZ;
7657 break;
7658 case RATE_INFO_BW_80:
7659 rx_stats->c_width = IEEE80211_RX_FW_80MHZ;
7660 break;
7661 case RATE_INFO_BW_160:
7662 rx_stats->c_width = IEEE80211_RX_FW_160MHZ;
7663 break;
7664 case RATE_INFO_BW_320:
7665 case RATE_INFO_BW_HE_RU:
7666 case RATE_INFO_BW_EHT_RU:
7667 case RATE_INFO_BW_5:
7668 case RATE_INFO_BW_10:
7669 TODO("net80211 has not matching bandwidth for %u", rx_status->bw);
7670 break;
7671 }
7672
7673 if ((rx_status->enc_flags & RX_ENC_FLAG_LDPC) != 0)
7674 rx_stats->c_pktflags |= IEEE80211_RX_F_LDPC;
7675 if ((rx_status->enc_flags & RX_ENC_FLAG_STBC_MASK) != 0)
7676 rx_stats->c_pktflags |= IEEE80211_RX_F_STBC;
7677
7678 /*
7679 * We only need these for LKPI_80211_HW_CRYPTO in theory but in
7680 * case the hardware does something we do not expect always leave
7681 * these enabled. Leaving this commant as documentation for the || 1.
7682 */
7683 #if defined(LKPI_80211_HW_CRYPTO) || 1
7684 if (rx_status->flag & RX_FLAG_DECRYPTED) {
7685 rx_stats->c_pktflags |= IEEE80211_RX_F_DECRYPTED;
7686 /* Only valid if decrypted is set. */
7687 if (rx_status->flag & RX_FLAG_PN_VALIDATED)
7688 rx_stats->c_pktflags |= IEEE80211_RX_F_PN_VALIDATED;
7689 }
7690 if (rx_status->flag & RX_FLAG_IV_STRIPPED)
7691 rx_stats->c_pktflags |= IEEE80211_RX_F_IV_STRIP;
7692 if (rx_status->flag & RX_FLAG_ICV_STRIPPED)
7693 rx_stats->c_pktflags |= IEEE80211_RX_F_ICV_STRIP;
7694 if (rx_status->flag & RX_FLAG_MIC_STRIPPED)
7695 rx_stats->c_pktflags |= IEEE80211_RX_F_MIC_STRIP;
7696 if (rx_status->flag & RX_FLAG_MMIC_STRIPPED)
7697 rx_stats->c_pktflags |= IEEE80211_RX_F_MMIC_STRIP;
7698 if (rx_status->flag & RX_FLAG_MMIC_ERROR)
7699 rx_stats->c_pktflags |= IEEE80211_RX_F_FAIL_MMIC;
7700 if (rx_status->flag & RX_FLAG_FAILED_FCS_CRC)
7701 rx_stats->c_pktflags |= IEEE80211_RX_F_FAIL_FCSCRC;
7702 #endif
7703
7704 /* Fill in some sinfo bits to fill gaps not reported byt the driver. */
7705 if (lsta != NULL) {
7706 memcpy(&lsta->sinfo.rxrate, &rxrate, sizeof(rxrate));
7707 lsta->sinfo.filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
7708
7709 if (rx_status->chains != 0) {
7710 lsta->sinfo.chains = rx_status->chains;
7711 memcpy(lsta->sinfo.chain_signal, rx_status->chain_signal,
7712 sizeof(lsta->sinfo.chain_signal));
7713 lsta->sinfo.filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
7714 }
7715 }
7716 }
7717
7718 #ifdef LINUXKPI_DEBUG_80211
7719 static void
7720 lkpi_rx_log_beacon(struct mbuf *m, struct lkpi_hw *lhw,
7721 struct ieee80211_rx_status *rx_status)
7722 {
7723 struct ieee80211_mgmt *f;
7724 uint8_t *e;
7725 char ssid[IEEE80211_NWID_LEN * 4 + 1];
7726
7727 memset(ssid, '\0', sizeof(ssid));
7728
7729 f = mtod(m, struct ieee80211_mgmt *);
7730 e = f->u.beacon.variable;
7731 /*
7732 * Usually SSID is right after the fixed part and for debugging we will
7733 * be fine should we miss it if it is not.
7734 */
7735 while ((e - (uint8_t *)f) < m->m_len) {
7736 if (*e == IEEE80211_ELEMID_SSID)
7737 break;
7738 e += (2 + *(e + 1));
7739 }
7740 if (*e == IEEE80211_ELEMID_SSID) {
7741 int i, len;
7742 char *p;
7743
7744 p = ssid;
7745 len = m->m_len - ((e + 2) - (uint8_t *)f);
7746 if (len > *(e + 1))
7747 len = *(e + 1);
7748 e += 2;
7749 for (i = 0; i < len; i++) {
7750 /* Printable character? */
7751 if (*e >= 0x20 && *e < 0x7f) {
7752 *p++ = *e++;
7753 } else {
7754 snprintf(p, 5, "%#04x", *e++);
7755 p += 4;
7756 }
7757 }
7758 *p = '\0';
7759 }
7760
7761 /* We print skb, skb->data, m as we are seeing 'ghost beacons'. */
7762 TRACE_SCAN_BEACON(lhw->ic, "Beacon: scan_flags %b, band %s freq %u chan %-4d "
7763 "len %d { %#06x %#06x %6D %6D %6D %#06x %ju %u %#06x SSID '%s' }",
7764 lhw->scan_flags, LKPI_LHW_SCAN_BITS,
7765 lkpi_nl80211_band_name(rx_status->band), rx_status->freq,
7766 linuxkpi_ieee80211_frequency_to_channel(rx_status->freq, 0),
7767 m->m_pkthdr.len, f->frame_control, f->duration_id,
7768 f->da, ":", f->sa, ":", f->bssid, ":", f->seq_ctrl,
7769 (uintmax_t)le64_to_cpu(f->u.beacon.timestamp),
7770 le16_to_cpu(f->u.beacon.beacon_int),
7771 le16_to_cpu(f->u.beacon.capab_info), ssid);
7772 }
7773 #endif
7774
7775 /* For %list see comment towards the end of the function. */
7776 void
7777 linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
7778 struct ieee80211_sta *sta, struct napi_struct *napi __unused,
7779 struct list_head *list __unused)
7780 {
7781 struct lkpi_hw *lhw;
7782 struct ieee80211com *ic;
7783 struct mbuf *m;
7784 struct skb_shared_info *shinfo;
7785 struct ieee80211_rx_status *rx_status;
7786 struct ieee80211_rx_stats rx_stats;
7787 struct ieee80211_node *ni;
7788 struct ieee80211vap *vap;
7789 struct ieee80211_hdr *hdr;
7790 struct lkpi_sta *lsta;
7791 int i, offset, ok, error;
7792 uint8_t rssi;
7793 bool is_beacon;
7794
7795 lhw = HW_TO_LHW(hw);
7796 ic = lhw->ic;
7797
7798 if (skb->len < 2) {
7799 /* Need 80211 stats here. */
7800 counter_u64_add(ic->ic_ierrors, 1);
7801 IMPROVE();
7802 goto err;
7803 }
7804
7805 /*
7806 * For now do the data copy; we can later improve things. Might even
7807 * have an mbuf backing the skb data then?
7808 */
7809 m = m_get3(skb->len, M_NOWAIT, MT_DATA, M_PKTHDR);
7810 if (m == NULL) {
7811 counter_u64_add(ic->ic_ierrors, 1);
7812 goto err;
7813 }
7814 m_copyback(m, 0, skb->tail - skb->data, skb->data);
7815
7816 shinfo = skb_shinfo(skb);
7817 offset = m->m_len;
7818 for (i = 0; i < shinfo->nr_frags; i++) {
7819 m_copyback(m, offset, shinfo->frags[i].size,
7820 (uint8_t *)linux_page_address(shinfo->frags[i].page) +
7821 shinfo->frags[i].offset);
7822 offset += shinfo->frags[i].size;
7823 }
7824
7825 rx_status = IEEE80211_SKB_RXCB(skb);
7826
7827 hdr = (void *)skb->data;
7828 is_beacon = ieee80211_is_beacon(hdr->frame_control);
7829
7830 #ifdef LINUXKPI_DEBUG_80211
7831 /*
7832 * We use the mbuf here as otherwise the variable part might
7833 * be in skb frags.
7834 */
7835 if (is_beacon && ((linuxkpi_debug_80211 & D80211_SCAN_BEACON) != 0))
7836 lkpi_rx_log_beacon(m, lhw, rx_status);
7837
7838 if (is_beacon && (linuxkpi_debug_80211 & D80211_TRACE_RX_BEACONS) == 0 &&
7839 (linuxkpi_debug_80211 & D80211_SCAN_BEACON) == 0)
7840 goto no_trace_beacons;
7841
7842 if (linuxkpi_debug_80211 & D80211_TRACE_RX)
7843 printf("TRACE-RX: %s: skb %p l/d/t-len (%u/%u/%u) "
7844 "h %p d %p t %p e %p sh %p (%u) m %p plen %u len %u%s\n",
7845 __func__, skb, skb->len, skb->data_len,
7846 skb->truesize, skb->head, skb->data, skb->tail, skb->end,
7847 shinfo, shinfo->nr_frags,
7848 m, m->m_pkthdr.len, m->m_len, is_beacon ? " beacon" : "");
7849
7850 if (linuxkpi_debug_80211 & D80211_TRACE_RX_DUMP)
7851 hexdump(mtod(m, const void *), m->m_len, "RX (raw) ", 0);
7852
7853 /* Implement a dump_rxcb() !!! */
7854 if ((linuxkpi_debug_80211 & D80211_TRACE_RX) != 0 ||
7855 (linuxkpi_debug_80211 & D80211_SCAN_BEACON) != 0)
7856 printf("TRACE-RX: %s: RXCB: %ju %ju %u, %b, %u, %#0x, %#0x, "
7857 "%u band %u, %u { %d %d %d %d }, %d, %#x %#x %#x %#x %u %u %u\n",
7858 __func__,
7859 (uintmax_t)rx_status->boottime_ns,
7860 (uintmax_t)rx_status->mactime,
7861 rx_status->device_timestamp,
7862 rx_status->flag, IEEE80211_RX_STATUS_FLAGS_BITS,
7863 rx_status->freq,
7864 rx_status->bw,
7865 rx_status->encoding,
7866 rx_status->ampdu_reference,
7867 rx_status->band,
7868 rx_status->chains,
7869 rx_status->chain_signal[0],
7870 rx_status->chain_signal[1],
7871 rx_status->chain_signal[2],
7872 rx_status->chain_signal[3],
7873 rx_status->signal,
7874 rx_status->enc_flags,
7875 rx_status->he_dcm,
7876 rx_status->he_gi,
7877 rx_status->he_ru,
7878 rx_status->zero_length_psdu_type,
7879 rx_status->nss,
7880 rx_status->rate_idx);
7881 no_trace_beacons:
7882 #endif
7883
7884 lsta = NULL;
7885 if (sta != NULL) {
7886 lsta = STA_TO_LSTA(sta);
7887 ni = ieee80211_ref_node(lsta->ni);
7888 } else {
7889 struct ieee80211_frame_min *wh;
7890
7891 wh = mtod(m, struct ieee80211_frame_min *);
7892 ni = ieee80211_find_rxnode(ic, wh);
7893 if (ni != NULL)
7894 lsta = ni->ni_drv_data;
7895 }
7896
7897 rssi = 0;
7898 lkpi_convert_rx_status(hw, lsta, rx_status, &rx_stats, &rssi);
7899
7900 ok = ieee80211_add_rx_params(m, &rx_stats);
7901 if (ok == 0) {
7902 m_freem(m);
7903 counter_u64_add(ic->ic_ierrors, 1);
7904 goto err;
7905 }
7906
7907 if (ni != NULL)
7908 vap = ni->ni_vap;
7909 else
7910 /*
7911 * XXX-BZ can we improve this by looking at the frame hdr
7912 * or other meta-data passed up?
7913 */
7914 vap = TAILQ_FIRST(&ic->ic_vaps);
7915
7916 #ifdef LINUXKPI_DEBUG_80211
7917 if (linuxkpi_debug_80211 & D80211_TRACE_RX)
7918 printf("TRACE-RX: %s: sta %p lsta %p state %d ni %p vap %p%s\n",
7919 __func__, sta, lsta, (lsta != NULL) ? lsta->state : -1,
7920 ni, vap, is_beacon ? " beacon" : "");
7921 #endif
7922
7923 if (ni != NULL && vap != NULL && is_beacon &&
7924 rx_status->device_timestamp > 0 &&
7925 m->m_pkthdr.len >= sizeof(struct ieee80211_frame)) {
7926 struct lkpi_vif *lvif;
7927 struct ieee80211_vif *vif;
7928 struct ieee80211_frame *wh;
7929
7930 lvif = VAP_TO_LVIF(vap);
7931 vif = LVIF_TO_VIF(lvif);
7932
7933 wh = mtod(m, struct ieee80211_frame *);
7934 if (!IEEE80211_ADDR_EQ(wh->i_addr2, vif->cfg.ap_addr))
7935 goto skip_device_ts;
7936
7937 IMPROVE("TIMING_BEACON_ONLY?");
7938 /* mac80211 specific (not net80211) so keep it here. */
7939 vif->bss_conf.sync_device_ts = rx_status->device_timestamp;
7940 /*
7941 * net80211 should take care of the other information (sync_tsf,
7942 * sync_dtim_count) as otherwise we need to parse the beacon.
7943 */
7944 skip_device_ts:
7945 ;
7946 }
7947
7948 if (vap != NULL && vap->iv_state > IEEE80211_S_INIT &&
7949 ieee80211_radiotap_active_vap(vap)) {
7950 struct lkpi_radiotap_rx_hdr *rtap;
7951
7952 rtap = &lhw->rtap_rx;
7953 rtap->wr_tsft = rx_status->device_timestamp;
7954 rtap->wr_flags = 0;
7955 if (rx_status->enc_flags & RX_ENC_FLAG_SHORTPRE)
7956 rtap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7957 if (rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI)
7958 rtap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI;
7959 #if 0 /* .. or it does not given we strip it below. */
7960 if (ieee80211_hw_check(hw, RX_INCLUDES_FCS))
7961 rtap->wr_flags |= IEEE80211_RADIOTAP_F_FCS;
7962 #endif
7963 if (rx_status->flag & RX_FLAG_FAILED_FCS_CRC)
7964 rtap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
7965 rtap->wr_rate = 0;
7966 IMPROVE();
7967 /* XXX TODO status->encoding / rate_index / bw */
7968 rtap->wr_chan_freq = htole16(rx_stats.c_freq);
7969 if (ic->ic_curchan->ic_ieee == rx_stats.c_ieee)
7970 rtap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
7971 rtap->wr_dbm_antsignal = rssi;
7972 rtap->wr_dbm_antnoise = rx_stats.c_nf;
7973 }
7974
7975 if (ieee80211_hw_check(hw, RX_INCLUDES_FCS))
7976 m_adj(m, -IEEE80211_CRC_LEN);
7977
7978 #if 0
7979 if (list != NULL) {
7980 /*
7981 * Normally this would be queued up and delivered by
7982 * netif_receive_skb_list(), napi_gro_receive(), or the like.
7983 * See mt76::mac80211.c as only current possible consumer.
7984 */
7985 IMPROVE("we simply pass the packet to net80211 to deal with.");
7986 }
7987 #endif
7988
7989 /* Attach meta-information to the mbuf for the deferred RX path. */
7990 if (ni != NULL) {
7991 #ifdef LKPI_80211_USE_MTAG
7992 struct m_tag *mtag;
7993 struct lkpi_80211_tag_rxni *rxni;
7994
7995 mtag = m_tag_alloc(MTAG_ABI_LKPI80211, LKPI80211_TAG_RXNI,
7996 sizeof(*rxni), IEEE80211_M_NOWAIT);
7997 if (mtag == NULL) {
7998 m_freem(m);
7999 counter_u64_add(ic->ic_ierrors, 1);
8000 goto err;
8001 }
8002 rxni = (struct lkpi_80211_tag_rxni *)(mtag + 1);
8003 rxni->ni = ni; /* We hold a reference. */
8004 m_tag_prepend(m, mtag);
8005 #else
8006 m->m_pkthdr.PH_loc.ptr = ni; /* We hold a reference. */
8007 #endif
8008 }
8009
8010 LKPI_80211_LHW_RXQ_LOCK(lhw);
8011 if (lhw->rxq_stopped) {
8012 LKPI_80211_LHW_RXQ_UNLOCK(lhw);
8013 m_freem(m);
8014 counter_u64_add(ic->ic_ierrors, 1);
8015 goto err;
8016 }
8017
8018 error = mbufq_enqueue(&lhw->rxq, m);
8019 if (error != 0) {
8020 LKPI_80211_LHW_RXQ_UNLOCK(lhw);
8021 m_freem(m);
8022 counter_u64_add(ic->ic_ierrors, 1);
8023 #ifdef LINUXKPI_DEBUG_80211
8024 if (linuxkpi_debug_80211 & D80211_TRACE_RX)
8025 ic_printf(ni->ni_ic, "%s: mbufq_enqueue failed: %d\n",
8026 __func__, error);
8027 #endif
8028 goto err;
8029 }
8030 taskqueue_enqueue(taskqueue_thread, &lhw->rxq_task);
8031 LKPI_80211_LHW_RXQ_UNLOCK(lhw);
8032
8033 IMPROVE();
8034
8035 err:
8036 /* The skb is ours so we can free it :-) */
8037 kfree_skb(skb);
8038 }
8039
8040 uint8_t
8041 linuxkpi_ieee80211_get_tid(struct ieee80211_hdr *hdr, bool nonqos_ok)
8042 {
8043 const struct ieee80211_frame *wh;
8044 uint8_t tid;
8045
8046 /* Linux seems to assume this is a QOS-Data-Frame */
8047 KASSERT(nonqos_ok || ieee80211_is_data_qos(hdr->frame_control),
8048 ("%s: hdr %p fc %#06x not qos_data\n", __func__, hdr,
8049 hdr->frame_control));
8050
8051 wh = (const struct ieee80211_frame *)hdr;
8052 tid = ieee80211_gettid(wh);
8053 KASSERT(nonqos_ok || tid == (tid & IEEE80211_QOS_TID), ("%s: tid %u "
8054 "not expected (%u?)\n", __func__, tid, IEEE80211_NONQOS_TID));
8055
8056 return (tid);
8057 }
8058
8059 /* -------------------------------------------------------------------------- */
8060
8061 static void
8062 lkpi_wiphy_work(struct work_struct *work)
8063 {
8064 struct lkpi_wiphy *lwiphy;
8065 struct wiphy *wiphy;
8066 struct wiphy_work *wk;
8067
8068 lwiphy = container_of(work, struct lkpi_wiphy, wwk);
8069 wiphy = LWIPHY_TO_WIPHY(lwiphy);
8070
8071 wiphy_lock(wiphy);
8072
8073 LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
8074 wk = list_first_entry_or_null(&lwiphy->wwk_list, struct wiphy_work, entry);
8075 /* If there is nothing we do nothing. */
8076 if (wk == NULL) {
8077 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
8078 wiphy_unlock(wiphy);
8079 return;
8080 }
8081 list_del_init(&wk->entry);
8082
8083 /* More work to do? */
8084 if (!list_empty(&lwiphy->wwk_list))
8085 schedule_work(work);
8086 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
8087
8088 /* Finally call the (*wiphy_work_fn)() function. */
8089 wk->fn(wiphy, wk);
8090
8091 wiphy_unlock(wiphy);
8092 }
8093
8094 void
8095 linuxkpi_wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *wwk)
8096 {
8097 struct lkpi_wiphy *lwiphy;
8098
8099 lwiphy = WIPHY_TO_LWIPHY(wiphy);
8100
8101 LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
8102 /* Do not double-queue. */
8103 if (list_empty(&wwk->entry))
8104 list_add_tail(&wwk->entry, &lwiphy->wwk_list);
8105 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
8106
8107 /*
8108 * See how ieee80211_queue_work() work continues in Linux or if things
8109 * migrate here over time?
8110 * Use a system queue from linux/workqueue.h for now.
8111 */
8112 queue_work(system_wq, &lwiphy->wwk);
8113 }
8114
8115 void
8116 linuxkpi_wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *wwk)
8117 {
8118 struct lkpi_wiphy *lwiphy;
8119
8120 lwiphy = WIPHY_TO_LWIPHY(wiphy);
8121
8122 LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
8123 /* Only cancel if queued. */
8124 if (!list_empty(&wwk->entry))
8125 list_del_init(&wwk->entry);
8126 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
8127 }
8128
8129 void
8130 linuxkpi_wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *wwk)
8131 {
8132 struct lkpi_wiphy *lwiphy;
8133 struct wiphy_work *wk;
8134
8135 lwiphy = WIPHY_TO_LWIPHY(wiphy);
8136 LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
8137 /* If wwk is unset, flush everything; called when wiphy is shut down. */
8138 if (wwk != NULL && list_empty(&wwk->entry)) {
8139 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
8140 return;
8141 }
8142
8143 while (!list_empty(&lwiphy->wwk_list)) {
8144
8145 wk = list_first_entry(&lwiphy->wwk_list, struct wiphy_work,
8146 entry);
8147 list_del_init(&wk->entry);
8148 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
8149 wk->fn(wiphy, wk);
8150 LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
8151 if (wk == wwk)
8152 break;
8153 }
8154 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
8155 }
8156
8157 void
8158 lkpi_wiphy_delayed_work_timer(struct timer_list *tl)
8159 {
8160 struct wiphy_delayed_work *wdwk;
8161
8162 wdwk = timer_container_of(wdwk, tl, timer);
8163 wiphy_work_queue(wdwk->wiphy, &wdwk->work);
8164 }
8165
8166 void
8167 linuxkpi_wiphy_delayed_work_queue(struct wiphy *wiphy,
8168 struct wiphy_delayed_work *wdwk, unsigned long delay)
8169 {
8170 if (delay == 0) {
8171 /* Run right away. */
8172 del_timer(&wdwk->timer);
8173 wiphy_work_queue(wiphy, &wdwk->work);
8174 } else {
8175 wdwk->wiphy = wiphy;
8176 mod_timer(&wdwk->timer, jiffies + delay);
8177 }
8178 }
8179
8180 void
8181 linuxkpi_wiphy_delayed_work_cancel(struct wiphy *wiphy,
8182 struct wiphy_delayed_work *wdwk)
8183 {
8184 del_timer_sync(&wdwk->timer);
8185 wiphy_work_cancel(wiphy, &wdwk->work);
8186 }
8187
8188 void
8189 linuxkpi_wiphy_delayed_work_flush(struct wiphy *wiphy,
8190 struct wiphy_delayed_work *wdwk)
8191 {
8192 lockdep_assert_held(&wiphy->mtx);
8193
8194 del_timer_sync(&wdwk->timer);
8195 wiphy_work_flush(wiphy, &wdwk->work);
8196 }
8197
8198 /* -------------------------------------------------------------------------- */
8199
8200 struct wiphy *
8201 linuxkpi_wiphy_new(const struct cfg80211_ops *ops, size_t priv_len)
8202 {
8203 struct lkpi_wiphy *lwiphy;
8204 struct wiphy *wiphy;
8205
8206 lwiphy = kzalloc(sizeof(*lwiphy) + priv_len, GFP_KERNEL);
8207 if (lwiphy == NULL)
8208 return (NULL);
8209 lwiphy->ops = ops;
8210
8211 LKPI_80211_LWIPHY_WORK_LOCK_INIT(lwiphy);
8212 INIT_LIST_HEAD(&lwiphy->wwk_list);
8213 INIT_WORK(&lwiphy->wwk, lkpi_wiphy_work);
8214
8215 wiphy = LWIPHY_TO_WIPHY(lwiphy);
8216
8217 mutex_init(&wiphy->mtx);
8218 TODO();
8219
8220 return (wiphy);
8221 }
8222
8223 void
8224 linuxkpi_wiphy_free(struct wiphy *wiphy)
8225 {
8226 struct lkpi_wiphy *lwiphy;
8227
8228 if (wiphy == NULL)
8229 return;
8230
8231 linuxkpi_wiphy_work_flush(wiphy, NULL);
8232 mutex_destroy(&wiphy->mtx);
8233
8234 lwiphy = WIPHY_TO_LWIPHY(wiphy);
8235 LKPI_80211_LWIPHY_WORK_LOCK_DESTROY(lwiphy);
8236
8237 kfree(lwiphy);
8238 }
8239
8240 static void
8241 lkpi_wiphy_band_annotate(struct wiphy *wiphy)
8242 {
8243 int band;
8244
8245 for (band = 0; band < NUM_NL80211_BANDS; band++) {
8246 struct ieee80211_supported_band *supband;
8247 int i;
8248
8249 supband = wiphy->bands[band];
8250 if (supband == NULL)
8251 continue;
8252
8253 switch (band) {
8254 case NL80211_BAND_2GHZ:
8255 case NL80211_BAND_5GHZ:
8256 break;
8257 default:
8258 #ifdef LINUXKPI_DEBUG_80211
8259 IMPROVE("band %d(%s) not yet supported",
8260 band, lkpi_nl80211_band_name(band));
8261 /* For bands added here, also check lkpi_lsta_alloc(). */
8262 #endif
8263 continue;
8264 }
8265
8266 for (i = 0; i < supband->n_bitrates; i++) {
8267 switch (band) {
8268 case NL80211_BAND_2GHZ:
8269 switch (supband->bitrates[i].bitrate) {
8270 case 110:
8271 case 55:
8272 case 20:
8273 case 10:
8274 supband->bitrates[i].flags |=
8275 IEEE80211_RATE_MANDATORY_B;
8276 /* FALLTHROUGH */
8277 /* 11g only */
8278 case 240:
8279 case 120:
8280 case 60:
8281 supband->bitrates[i].flags |=
8282 IEEE80211_RATE_MANDATORY_G;
8283 break;
8284 }
8285 break;
8286 case NL80211_BAND_5GHZ:
8287 switch (supband->bitrates[i].bitrate) {
8288 case 240:
8289 case 120:
8290 case 60:
8291 supband->bitrates[i].flags |=
8292 IEEE80211_RATE_MANDATORY_A;
8293 break;
8294 }
8295 break;
8296 }
8297 }
8298 }
8299 }
8300
8301 int
8302 linuxkpi_80211_wiphy_register(struct wiphy *wiphy)
8303 {
8304 TODO("Lots of checks and initialization");
8305
8306 lkpi_wiphy_band_annotate(wiphy);
8307
8308 return (0);
8309 }
8310
8311 static uint32_t
8312 lkpi_cfg80211_calculate_bitrate_ht(struct rate_info *rate)
8313 {
8314 TODO("cfg80211_calculate_bitrate_ht");
8315 return (rate->legacy);
8316 }
8317
8318 static uint32_t
8319 lkpi_cfg80211_calculate_bitrate_vht(struct rate_info *rate)
8320 {
8321 TODO("cfg80211_calculate_bitrate_vht");
8322 return (rate->legacy);
8323 }
8324
8325 uint32_t
8326 linuxkpi_cfg80211_calculate_bitrate(struct rate_info *rate)
8327 {
8328
8329 /* Beware: order! */
8330 if (rate->flags & RATE_INFO_FLAGS_MCS)
8331 return (lkpi_cfg80211_calculate_bitrate_ht(rate));
8332
8333 if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
8334 return (lkpi_cfg80211_calculate_bitrate_vht(rate));
8335
8336 IMPROVE("HE/EHT/...");
8337
8338 return (rate->legacy);
8339 }
8340
8341 uint32_t
8342 linuxkpi_ieee80211_channel_to_frequency(uint32_t channel,
8343 enum nl80211_band band)
8344 {
8345
8346 switch (band) {
8347 case NL80211_BAND_2GHZ:
8348 return (ieee80211_ieee2mhz(channel, IEEE80211_CHAN_2GHZ));
8349 break;
8350 case NL80211_BAND_5GHZ:
8351 return (ieee80211_ieee2mhz(channel, IEEE80211_CHAN_5GHZ));
8352 break;
8353 default:
8354 /* XXX abort, retry, error, panic? */
8355 break;
8356 }
8357
8358 return (0);
8359 }
8360
8361 uint32_t
8362 linuxkpi_ieee80211_frequency_to_channel(uint32_t freq, uint32_t flags __unused)
8363 {
8364
8365 return (ieee80211_mhz2ieee(freq, 0));
8366 }
8367
8368 #if 0
8369 static struct lkpi_sta *
8370 lkpi_find_lsta_by_ni(struct lkpi_vif *lvif, struct ieee80211_node *ni)
8371 {
8372 struct lkpi_sta *lsta, *temp;
8373
8374 rcu_read_lock();
8375 list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
8376 if (lsta->ni == ni) {
8377 rcu_read_unlock();
8378 return (lsta);
8379 }
8380 }
8381 rcu_read_unlock();
8382
8383 return (NULL);
8384 }
8385 #endif
8386
8387 struct ieee80211_sta *
8388 linuxkpi_ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *peer)
8389 {
8390 struct lkpi_vif *lvif;
8391 struct lkpi_sta *lsta;
8392 struct ieee80211_sta *sta;
8393
8394 lvif = VIF_TO_LVIF(vif);
8395
8396 rcu_read_lock();
8397 list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
8398 sta = LSTA_TO_STA(lsta);
8399 if (IEEE80211_ADDR_EQ(sta->addr, peer)) {
8400 rcu_read_unlock();
8401 return (sta);
8402 }
8403 }
8404 rcu_read_unlock();
8405 return (NULL);
8406 }
8407
8408 struct ieee80211_sta *
8409 linuxkpi_ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw,
8410 const uint8_t *addr, const uint8_t *ourvifaddr)
8411 {
8412 struct lkpi_hw *lhw;
8413 struct lkpi_vif *lvif;
8414 struct lkpi_sta *lsta;
8415 struct ieee80211_vif *vif;
8416 struct ieee80211_sta *sta;
8417
8418 lhw = wiphy_priv(hw->wiphy);
8419 sta = NULL;
8420
8421 LKPI_80211_LHW_LVIF_LOCK(lhw);
8422 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
8423
8424 /* XXX-BZ check our address from the vif. */
8425
8426 vif = LVIF_TO_VIF(lvif);
8427 if (ourvifaddr != NULL &&
8428 !IEEE80211_ADDR_EQ(vif->addr, ourvifaddr))
8429 continue;
8430 sta = linuxkpi_ieee80211_find_sta(vif, addr);
8431 if (sta != NULL)
8432 break;
8433 }
8434 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
8435
8436 if (sta != NULL) {
8437 lsta = STA_TO_LSTA(sta);
8438 if (!lsta->added_to_drv)
8439 return (NULL);
8440 }
8441
8442 return (sta);
8443 }
8444
8445 struct sk_buff *
8446 linuxkpi_ieee80211_tx_dequeue(struct ieee80211_hw *hw,
8447 struct ieee80211_txq *txq)
8448 {
8449 struct lkpi_txq *ltxq;
8450 struct lkpi_vif *lvif;
8451 struct sk_buff *skb;
8452
8453 IMPROVE("wiphy_lock? or assert?");
8454 skb = NULL;
8455 ltxq = TXQ_TO_LTXQ(txq);
8456 ltxq->seen_dequeue = true;
8457
8458 if (ltxq->stopped)
8459 goto stopped;
8460
8461 lvif = VIF_TO_LVIF(ltxq->txq.vif);
8462 if (lvif->hw_queue_stopped[ltxq->txq.ac]) {
8463 ltxq->stopped = true;
8464 goto stopped;
8465 }
8466
8467 IMPROVE("hw(TX_FRAG_LIST)");
8468
8469 LKPI_80211_LTXQ_LOCK(ltxq);
8470 skb = skb_dequeue(<xq->skbq);
8471 if (skb != NULL)
8472 ltxq->frms_dequeued++;
8473 LKPI_80211_LTXQ_UNLOCK(ltxq);
8474
8475 stopped:
8476 return (skb);
8477 }
8478
8479 void
8480 linuxkpi_ieee80211_txq_get_depth(struct ieee80211_txq *txq,
8481 unsigned long *frame_cnt, unsigned long *byte_cnt)
8482 {
8483 struct lkpi_txq *ltxq;
8484 struct sk_buff *skb;
8485 unsigned long fc, bc;
8486
8487 ltxq = TXQ_TO_LTXQ(txq);
8488
8489 fc = bc = 0;
8490 LKPI_80211_LTXQ_LOCK(ltxq);
8491 skb_queue_walk(<xq->skbq, skb) {
8492 fc++;
8493 bc += skb->len;
8494 }
8495 LKPI_80211_LTXQ_UNLOCK(ltxq);
8496 if (frame_cnt)
8497 *frame_cnt = fc;
8498 if (byte_cnt)
8499 *byte_cnt = bc;
8500
8501 /* Validate that this is doing the correct thing. */
8502 /* Should we keep track on en/dequeue? */
8503 IMPROVE();
8504 }
8505
8506 /*
8507 * We are called from ieee80211_free_txskb() or ieee80211_tx_status().
8508 * The latter tries to derive the success status from the info flags
8509 * passed back from the driver. rawx_mit() saves the ni on the m and the
8510 * m on the skb for us to be able to give feedback to net80211.
8511 */
8512 static void
8513 _lkpi_ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb,
8514 int status)
8515 {
8516 struct ieee80211_node *ni;
8517 struct mbuf *m;
8518
8519 if (skb == NULL)
8520 return;
8521
8522 m = skb->m;
8523 skb->m = NULL;
8524
8525 if (m != NULL) {
8526 ni = m->m_pkthdr.PH_loc.ptr;
8527 /* Status: 0 is ok, != 0 is error. */
8528 ieee80211_tx_complete(ni, m, status);
8529 /* ni & mbuf were consumed. */
8530 }
8531 }
8532
8533 void
8534 linuxkpi_ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb,
8535 int status)
8536 {
8537
8538 _lkpi_ieee80211_free_txskb(hw, skb, status);
8539 kfree_skb(skb);
8540 }
8541
8542 void
8543 linuxkpi_ieee80211_tx_status_ext(struct ieee80211_hw *hw,
8544 struct ieee80211_tx_status *txstat)
8545 {
8546 struct sk_buff *skb;
8547 struct ieee80211_tx_info *info, _info = { };
8548 struct ieee80211_ratectl_tx_status txs;
8549 struct ieee80211_node *ni;
8550 int status;
8551
8552 skb = txstat->skb;
8553 if (skb != NULL && skb->m != NULL) {
8554 struct mbuf *m;
8555
8556 m = skb->m;
8557 ni = m->m_pkthdr.PH_loc.ptr;
8558 memset(&txs, 0, sizeof(txs));
8559 } else {
8560 ni = NULL;
8561 }
8562
8563 /*
8564 * If we have no info information on tx, set info to an all-zero struct
8565 * to make the code (and debug output) simpler.
8566 */
8567 info = txstat->info;
8568 if (info == NULL)
8569 info = &_info;
8570 if (info->flags & IEEE80211_TX_STAT_ACK) {
8571 status = 0; /* No error. */
8572 txs.status = IEEE80211_RATECTL_TX_SUCCESS;
8573 } else {
8574 status = 1;
8575 txs.status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED;
8576 }
8577
8578 if (ni != NULL) {
8579 txs.pktlen = skb->len;
8580 txs.flags |= IEEE80211_RATECTL_STATUS_PKTLEN;
8581 if (info->status.rates[0].count > 1) {
8582 txs.long_retries = info->status.rates[0].count - 1; /* 1 + retries in drivers. */
8583 txs.flags |= IEEE80211_RATECTL_STATUS_LONG_RETRY;
8584 }
8585 #if 0 /* Unused in net80211 currently. */
8586 /* XXX-BZ convert check .flags for MCS/VHT/.. */
8587 txs.final_rate = info->status.rates[0].idx;
8588 txs.flags |= IEEE80211_RATECTL_STATUS_FINAL_RATE;
8589 #endif
8590 if (info->status.flags & IEEE80211_TX_STATUS_ACK_SIGNAL_VALID) {
8591 txs.rssi = info->status.ack_signal; /* XXX-BZ CONVERT? */
8592 txs.flags |= IEEE80211_RATECTL_STATUS_RSSI;
8593 }
8594
8595 IMPROVE("only update rate if needed but that requires us to get a proper rate from mo_sta_statistics");
8596 ieee80211_ratectl_tx_complete(ni, &txs);
8597 ieee80211_ratectl_rate(ni->ni_vap->iv_bss, NULL, 0);
8598
8599 #ifdef LINUXKPI_DEBUG_80211
8600 if (linuxkpi_debug_80211 & D80211_TRACE_TX) {
8601 printf("TX-RATE: %s: long_retries %d\n", __func__,
8602 txs.long_retries);
8603 }
8604 #endif
8605 }
8606
8607 #ifdef LINUXKPI_DEBUG_80211
8608 if (linuxkpi_debug_80211 & D80211_TRACE_TX)
8609 printf("TX-STATUS: %s: hw %p skb %p status %d : flags %#x "
8610 "band %u hw_queue %u tx_time_est %d : "
8611 "rates [ %u %u %#x, %u %u %#x, %u %u %#x, %u %u %#x ] "
8612 "ack_signal %u ampdu_ack_len %u ampdu_len %u antenna %u "
8613 "tx_time %u flags %#x "
8614 "status_driver_data [ %p %p ]\n",
8615 __func__, hw, skb, status, info->flags,
8616 info->band, info->hw_queue, info->tx_time_est,
8617 info->status.rates[0].idx, info->status.rates[0].count,
8618 info->status.rates[0].flags,
8619 info->status.rates[1].idx, info->status.rates[1].count,
8620 info->status.rates[1].flags,
8621 info->status.rates[2].idx, info->status.rates[2].count,
8622 info->status.rates[2].flags,
8623 info->status.rates[3].idx, info->status.rates[3].count,
8624 info->status.rates[3].flags,
8625 info->status.ack_signal, info->status.ampdu_ack_len,
8626 info->status.ampdu_len, info->status.antenna,
8627 info->status.tx_time, info->status.flags,
8628 info->status.status_driver_data[0],
8629 info->status.status_driver_data[1]);
8630 #endif
8631
8632 if (txstat->free_list) {
8633 _lkpi_ieee80211_free_txskb(hw, skb, status);
8634 if (skb != NULL)
8635 list_add_tail(&skb->list, txstat->free_list);
8636 } else {
8637 linuxkpi_ieee80211_free_txskb(hw, skb, status);
8638 }
8639 }
8640
8641 void
8642 linuxkpi_ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
8643 {
8644 struct ieee80211_tx_status status;
8645
8646 memset(&status, 0, sizeof(status));
8647 status.info = IEEE80211_SKB_CB(skb);
8648 status.skb = skb;
8649 /* sta, n_rates, rates, free_list? */
8650
8651 ieee80211_tx_status_ext(hw, &status);
8652 }
8653
8654 /*
8655 * This is an internal bandaid for the moment for the way we glue
8656 * skbs and mbufs together for TX. Once we have skbs backed by
8657 * mbufs this should go away.
8658 * This is a public function but kept on the private KPI (lkpi_)
8659 * and is not exposed by a header file.
8660 */
8661 static void
8662 lkpi_ieee80211_free_skb_mbuf(void *p)
8663 {
8664 struct ieee80211_node *ni;
8665 struct mbuf *m;
8666
8667 if (p == NULL)
8668 return;
8669
8670 m = (struct mbuf *)p;
8671 M_ASSERTPKTHDR(m);
8672
8673 ni = m->m_pkthdr.PH_loc.ptr;
8674 m->m_pkthdr.PH_loc.ptr = NULL;
8675 if (ni != NULL)
8676 ieee80211_free_node(ni);
8677 m_freem(m);
8678 }
8679
8680 void
8681 linuxkpi_ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
8682 struct delayed_work *w, int delay)
8683 {
8684 struct lkpi_hw *lhw;
8685
8686 /* Need to make sure hw is in a stable (non-suspended) state. */
8687 IMPROVE();
8688
8689 lhw = HW_TO_LHW(hw);
8690 queue_delayed_work(lhw->workq, w, delay);
8691 }
8692
8693 void
8694 linuxkpi_ieee80211_queue_work(struct ieee80211_hw *hw,
8695 struct work_struct *w)
8696 {
8697 struct lkpi_hw *lhw;
8698
8699 /* Need to make sure hw is in a stable (non-suspended) state. */
8700 IMPROVE();
8701
8702 lhw = HW_TO_LHW(hw);
8703 queue_work(lhw->workq, w);
8704 }
8705
8706 struct sk_buff *
8707 linuxkpi_ieee80211_probereq_get(struct ieee80211_hw *hw, const uint8_t *addr,
8708 const uint8_t *ssid, size_t ssid_len, size_t tailroom)
8709 {
8710 struct sk_buff *skb;
8711 struct ieee80211_frame *wh;
8712 uint8_t *p;
8713 size_t len;
8714
8715 len = sizeof(*wh);
8716 len += 2 + ssid_len;
8717
8718 skb = dev_alloc_skb(hw->extra_tx_headroom + len + tailroom);
8719 if (skb == NULL)
8720 return (NULL);
8721
8722 skb_reserve(skb, hw->extra_tx_headroom);
8723
8724 wh = skb_put_zero(skb, sizeof(*wh));
8725 wh->i_fc[0] = IEEE80211_FC0_VERSION_0;
8726 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_PROBE_REQ | IEEE80211_FC0_TYPE_MGT;
8727 IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr);
8728 IEEE80211_ADDR_COPY(wh->i_addr2, addr);
8729 IEEE80211_ADDR_COPY(wh->i_addr3, ieee80211broadcastaddr);
8730
8731 p = skb_put(skb, 2 + ssid_len);
8732 *p++ = IEEE80211_ELEMID_SSID;
8733 *p++ = ssid_len;
8734 if (ssid_len > 0)
8735 memcpy(p, ssid, ssid_len);
8736
8737 return (skb);
8738 }
8739
8740 struct sk_buff *
8741 linuxkpi_ieee80211_pspoll_get(struct ieee80211_hw *hw,
8742 struct ieee80211_vif *vif)
8743 {
8744 struct lkpi_vif *lvif;
8745 struct ieee80211vap *vap;
8746 struct sk_buff *skb;
8747 struct ieee80211_frame_pspoll *psp;
8748 uint16_t v;
8749
8750 skb = dev_alloc_skb(hw->extra_tx_headroom + sizeof(*psp));
8751 if (skb == NULL)
8752 return (NULL);
8753
8754 skb_reserve(skb, hw->extra_tx_headroom);
8755
8756 lvif = VIF_TO_LVIF(vif);
8757 vap = LVIF_TO_VAP(lvif);
8758
8759 psp = skb_put_zero(skb, sizeof(*psp));
8760 psp->i_fc[0] = IEEE80211_FC0_VERSION_0;
8761 psp->i_fc[0] |= IEEE80211_FC0_SUBTYPE_PS_POLL | IEEE80211_FC0_TYPE_CTL;
8762 v = htole16(vif->cfg.aid | 1<<15 | 1<<16);
8763 memcpy(&psp->i_aid, &v, sizeof(v));
8764 IEEE80211_ADDR_COPY(psp->i_bssid, vap->iv_bss->ni_macaddr);
8765 IEEE80211_ADDR_COPY(psp->i_ta, vif->addr);
8766
8767 return (skb);
8768 }
8769
8770 struct sk_buff *
8771 linuxkpi_ieee80211_nullfunc_get(struct ieee80211_hw *hw,
8772 struct ieee80211_vif *vif, int linkid, bool qos)
8773 {
8774 struct sk_buff *skb;
8775 struct ieee80211_frame *nullf;
8776
8777 IMPROVE("linkid");
8778
8779 skb = dev_alloc_skb(hw->extra_tx_headroom + sizeof(*nullf));
8780 if (skb == NULL)
8781 return (NULL);
8782
8783 skb_reserve(skb, hw->extra_tx_headroom);
8784
8785 nullf = skb_put_zero(skb, sizeof(*nullf));
8786 nullf->i_fc[0] = IEEE80211_FC0_VERSION_0;
8787 nullf->i_fc[0] |= IEEE80211_FC0_SUBTYPE_NODATA | IEEE80211_FC0_TYPE_DATA;
8788 nullf->i_fc[1] = IEEE80211_FC1_DIR_TODS;
8789
8790 /* XXX-BZ if link is given, this is different. */
8791 IEEE80211_ADDR_COPY(nullf->i_addr1, vif->cfg.ap_addr);
8792 IEEE80211_ADDR_COPY(nullf->i_addr2, vif->addr);
8793 IEEE80211_ADDR_COPY(nullf->i_addr3, vif->cfg.ap_addr);
8794
8795 return (skb);
8796 }
8797
8798 struct wireless_dev *
8799 linuxkpi_ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
8800 {
8801 struct lkpi_vif *lvif;
8802
8803 lvif = VIF_TO_LVIF(vif);
8804 return (&lvif->wdev);
8805 }
8806
8807 void
8808 linuxkpi_ieee80211_connection_loss(struct ieee80211_vif *vif)
8809 {
8810 struct lkpi_vif *lvif;
8811 struct ieee80211vap *vap;
8812 enum ieee80211_state nstate;
8813 int arg;
8814
8815 lvif = VIF_TO_LVIF(vif);
8816 vap = LVIF_TO_VAP(lvif);
8817
8818 /*
8819 * Go to init; otherwise we need to elaborately check state and
8820 * handle accordingly, e.g., if in RUN we could call iv_bmiss.
8821 * Let the statemachine handle all neccessary changes.
8822 */
8823 nstate = IEEE80211_S_INIT;
8824 arg = 0; /* Not a valid reason. */
8825
8826 ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s (synched %d, assoc %d "
8827 "beacons %d dtim_period %d)\n", __func__, vif, vap,
8828 ieee80211_state_name[vap->iv_state],
8829 lvif->lvif_bss_synched, vif->cfg.assoc, lvif->beacons,
8830 vif->bss_conf.dtim_period);
8831 ieee80211_new_state(vap, nstate, arg);
8832 }
8833
8834 void
8835 linuxkpi_ieee80211_beacon_loss(struct ieee80211_vif *vif)
8836 {
8837 struct lkpi_vif *lvif;
8838 struct ieee80211vap *vap;
8839
8840 lvif = VIF_TO_LVIF(vif);
8841 vap = LVIF_TO_VAP(lvif);
8842
8843 ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s (synched %d, assoc %d "
8844 "beacons %d dtim_period %d)\n", __func__, vif, vap,
8845 ieee80211_state_name[vap->iv_state],
8846 lvif->lvif_bss_synched, vif->cfg.assoc, lvif->beacons,
8847 vif->bss_conf.dtim_period);
8848 ieee80211_beacon_miss(vap->iv_ic);
8849 }
8850
8851 /* -------------------------------------------------------------------------- */
8852
8853 void
8854 linuxkpi_ieee80211_stop_queue(struct ieee80211_hw *hw, int qnum)
8855 {
8856 struct lkpi_hw *lhw;
8857 struct lkpi_vif *lvif;
8858 struct ieee80211_vif *vif;
8859 int ac_count, ac;
8860
8861 KASSERT(qnum < hw->queues, ("%s: qnum %d >= hw->queues %d, hw %p\n",
8862 __func__, qnum, hw->queues, hw));
8863
8864 lhw = wiphy_priv(hw->wiphy);
8865
8866 /* See lkpi_ic_vap_create(). */
8867 if (hw->queues >= IEEE80211_NUM_ACS)
8868 ac_count = IEEE80211_NUM_ACS;
8869 else
8870 ac_count = 1;
8871
8872 LKPI_80211_LHW_LVIF_LOCK(lhw);
8873 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
8874
8875 vif = LVIF_TO_VIF(lvif);
8876 for (ac = 0; ac < ac_count; ac++) {
8877 IMPROVE_TXQ("LOCKING");
8878 if (qnum == vif->hw_queue[ac]) {
8879 #ifdef LINUXKPI_DEBUG_80211
8880 /*
8881 * For now log this to better understand
8882 * how this is supposed to work.
8883 */
8884 if (lvif->hw_queue_stopped[ac] &&
8885 (linuxkpi_debug_80211 & D80211_IMPROVE_TXQ) != 0)
8886 ic_printf(lhw->ic, "%s:%d: lhw %p hw %p "
8887 "lvif %p vif %p ac %d qnum %d already "
8888 "stopped\n", __func__, __LINE__,
8889 lhw, hw, lvif, vif, ac, qnum);
8890 #endif
8891 lvif->hw_queue_stopped[ac] = true;
8892 }
8893 }
8894 }
8895 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
8896 }
8897
8898 void
8899 linuxkpi_ieee80211_stop_queues(struct ieee80211_hw *hw)
8900 {
8901 int i;
8902
8903 IMPROVE_TXQ("Locking; do we need further info?");
8904 for (i = 0; i < hw->queues; i++)
8905 linuxkpi_ieee80211_stop_queue(hw, i);
8906 }
8907
8908
8909 static void
8910 lkpi_ieee80211_wake_queues(struct ieee80211_hw *hw, int hwq)
8911 {
8912 struct lkpi_hw *lhw;
8913 struct lkpi_vif *lvif;
8914 struct lkpi_sta *lsta;
8915 int ac_count, ac, tid;
8916
8917 /* See lkpi_ic_vap_create(). */
8918 if (hw->queues >= IEEE80211_NUM_ACS)
8919 ac_count = IEEE80211_NUM_ACS;
8920 else
8921 ac_count = 1;
8922
8923 lhw = wiphy_priv(hw->wiphy);
8924
8925 IMPROVE_TXQ("Locking");
8926 LKPI_80211_LHW_LVIF_LOCK(lhw);
8927 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
8928 struct ieee80211_vif *vif;
8929
8930 vif = LVIF_TO_VIF(lvif);
8931 for (ac = 0; ac < ac_count; ac++) {
8932
8933 if (hwq == vif->hw_queue[ac]) {
8934
8935 /* XXX-BZ what about software scan? */
8936
8937 #ifdef LINUXKPI_DEBUG_80211
8938 /*
8939 * For now log this to better understand
8940 * how this is supposed to work.
8941 */
8942 if (!lvif->hw_queue_stopped[ac] &&
8943 (linuxkpi_debug_80211 & D80211_IMPROVE_TXQ) != 0)
8944 ic_printf(lhw->ic, "%s:%d: lhw %p hw %p "
8945 "lvif %p vif %p ac %d hw_q not stopped\n",
8946 __func__, __LINE__,
8947 lhw, hw, lvif, vif, ac);
8948 #endif
8949 lvif->hw_queue_stopped[ac] = false;
8950
8951 rcu_read_lock();
8952 list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
8953 struct ieee80211_sta *sta;
8954
8955 sta = LSTA_TO_STA(lsta);
8956 for (tid = 0; tid < nitems(sta->txq); tid++) {
8957 struct lkpi_txq *ltxq;
8958
8959 if (sta->txq[tid] == NULL)
8960 continue;
8961
8962 if (sta->txq[tid]->ac != ac)
8963 continue;
8964
8965 ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
8966 if (!ltxq->stopped)
8967 continue;
8968
8969 ltxq->stopped = false;
8970
8971 if (!skb_queue_empty(<xq->skbq))
8972 lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid], false);
8973 }
8974 }
8975 rcu_read_unlock();
8976 }
8977 }
8978 }
8979 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
8980 }
8981
8982 static void
8983 lkpi_ieee80211_wake_queues_locked(struct ieee80211_hw *hw)
8984 {
8985 int i;
8986
8987 IMPROVE_TXQ("Is this all/enough here?");
8988 for (i = 0; i < hw->queues; i++)
8989 lkpi_ieee80211_wake_queues(hw, i);
8990 }
8991
8992 void
8993 linuxkpi_ieee80211_wake_queues(struct ieee80211_hw *hw)
8994 {
8995 struct lkpi_hw *lhw;
8996 unsigned long flags;
8997
8998 lhw = HW_TO_LHW(hw);
8999
9000 spin_lock_irqsave(&lhw->txq_lock, flags);
9001 lkpi_ieee80211_wake_queues_locked(hw);
9002 spin_unlock_irqrestore(&lhw->txq_lock, flags);
9003 }
9004
9005 void
9006 linuxkpi_ieee80211_wake_queue(struct ieee80211_hw *hw, int qnum)
9007 {
9008 struct lkpi_hw *lhw;
9009 unsigned long flags;
9010
9011 KASSERT(qnum < hw->queues, ("%s: qnum %d >= hw->queues %d, hw %p\n",
9012 __func__, qnum, hw->queues, hw));
9013
9014 lhw = HW_TO_LHW(hw);
9015
9016 spin_lock_irqsave(&lhw->txq_lock, flags);
9017 lkpi_ieee80211_wake_queues(hw, qnum);
9018 spin_unlock_irqrestore(&lhw->txq_lock, flags);
9019 }
9020
9021 void
9022 linuxkpi_ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
9023 struct ieee80211_txq *txq)
9024 {
9025 struct lkpi_hw *lhw;
9026
9027 lhw = HW_TO_LHW(hw);
9028
9029 LKPI_80211_LHW_TXQ_LOCK(lhw);
9030 ieee80211_txq_schedule_start(hw, txq->ac);
9031 do {
9032 struct lkpi_txq *ltxq;
9033 struct ieee80211_txq *ntxq;
9034 struct ieee80211_tx_control control;
9035 struct sk_buff *skb;
9036
9037 ntxq = ieee80211_next_txq(hw, txq->ac);
9038 if (ntxq == NULL)
9039 break;
9040 ltxq = TXQ_TO_LTXQ(ntxq);
9041
9042 memset(&control, 0, sizeof(control));
9043 control.sta = ntxq->sta;
9044 do {
9045 skb = linuxkpi_ieee80211_tx_dequeue(hw, ntxq);
9046 if (skb == NULL)
9047 break;
9048 ltxq->frms_tx++;
9049 lkpi_80211_mo_tx(hw, &control, skb);
9050 } while(1);
9051
9052 ieee80211_return_txq(hw, ntxq, false);
9053 } while (1);
9054 ieee80211_txq_schedule_end(hw, txq->ac);
9055 LKPI_80211_LHW_TXQ_UNLOCK(lhw);
9056 }
9057
9058 /* -------------------------------------------------------------------------- */
9059
9060 /* This is just hardware queues. */
9061 /*
9062 * Being called from the driver thus use _bh() locking.
9063 */
9064 void
9065 linuxkpi_ieee80211_txq_schedule_start(struct ieee80211_hw *hw, uint8_t ac)
9066 {
9067 struct lkpi_hw *lhw;
9068
9069 lhw = HW_TO_LHW(hw);
9070
9071 if (ac >= IEEE80211_NUM_ACS) {
9072 ic_printf(lhw->ic, "%s: ac %u out of bounds.\n", __func__, ac);
9073 return;
9074 }
9075
9076 spin_lock_bh(&lhw->txq_scheduled_lock[ac]);
9077 IMPROVE("check AIRTIME_FAIRNESS");
9078 if (++lhw->txq_generation[ac] == 0)
9079 lhw->txq_generation[ac]++;
9080 spin_unlock_bh(&lhw->txq_scheduled_lock[ac]);
9081 }
9082
9083 struct ieee80211_txq *
9084 linuxkpi_ieee80211_next_txq(struct ieee80211_hw *hw, uint8_t ac)
9085 {
9086 struct lkpi_hw *lhw;
9087 struct ieee80211_txq *txq;
9088 struct lkpi_txq *ltxq;
9089
9090 lhw = HW_TO_LHW(hw);
9091 txq = NULL;
9092
9093 if (ac >= IEEE80211_NUM_ACS) {
9094 ic_printf(lhw->ic, "%s: ac %u out of bounds.\n", __func__, ac);
9095 return (NULL);
9096 }
9097
9098 spin_lock_bh(&lhw->txq_scheduled_lock[ac]);
9099
9100 /* Check that we are scheduled. */
9101 if (lhw->txq_generation[ac] == 0)
9102 goto out;
9103
9104 ltxq = TAILQ_FIRST(&lhw->txq_scheduled[ac]);
9105 if (ltxq == NULL)
9106 goto out;
9107 if (ltxq->txq_generation == lhw->txq_generation[ac])
9108 goto out;
9109
9110 IMPROVE("check AIRTIME_FAIRNESS");
9111
9112 TAILQ_REMOVE(&lhw->txq_scheduled[ac], ltxq, txq_entry);
9113 ltxq->txq_generation = lhw->txq_generation[ac];
9114 txq = <xq->txq;
9115 TAILQ_ELEM_INIT(ltxq, txq_entry);
9116
9117 out:
9118 spin_unlock_bh(&lhw->txq_scheduled_lock[ac]);
9119
9120 return (txq);
9121 }
9122
9123 void linuxkpi_ieee80211_schedule_txq(struct ieee80211_hw *hw,
9124 struct ieee80211_txq *txq, bool withoutpkts)
9125 {
9126 struct lkpi_hw *lhw;
9127 struct lkpi_txq *ltxq;
9128 bool ltxq_empty;
9129
9130 ltxq = TXQ_TO_LTXQ(txq);
9131
9132 /* Only schedule if work to do or asked to anyway. */
9133 LKPI_80211_LTXQ_LOCK(ltxq);
9134 ltxq_empty = skb_queue_empty(<xq->skbq);
9135 LKPI_80211_LTXQ_UNLOCK(ltxq);
9136 if (!withoutpkts && ltxq_empty)
9137 goto out;
9138
9139 lhw = HW_TO_LHW(hw);
9140 spin_lock_bh(&lhw->txq_scheduled_lock[txq->ac]);
9141 /*
9142 * Make sure we do not double-schedule. We do this by checking tqe_prev,
9143 * the previous entry in our tailq. tqe_prev is always valid if this entry
9144 * is queued, tqe_next may be NULL if this is the only element in the list.
9145 */
9146 if (ltxq->txq_entry.tqe_prev != NULL)
9147 goto unlock;
9148
9149 TAILQ_INSERT_TAIL(&lhw->txq_scheduled[txq->ac], ltxq, txq_entry);
9150 unlock:
9151 spin_unlock_bh(&lhw->txq_scheduled_lock[txq->ac]);
9152
9153 out:
9154 return;
9155 }
9156
9157 /* -------------------------------------------------------------------------- */
9158
9159 struct lkpi_cfg80211_bss {
9160 u_int refcnt;
9161 struct cfg80211_bss bss;
9162 };
9163
9164 struct lkpi_cfg80211_get_bss_iter_lookup {
9165 struct wiphy *wiphy;
9166 struct linuxkpi_ieee80211_channel *chan;
9167 const uint8_t *bssid;
9168 const uint8_t *ssid;
9169 size_t ssid_len;
9170 enum ieee80211_bss_type bss_type;
9171 enum ieee80211_privacy privacy;
9172
9173 /*
9174 * Something to store a copy of the result as the net80211 scan cache
9175 * is not refoucnted so a scan entry might go away any time.
9176 */
9177 bool match;
9178 struct cfg80211_bss *bss;
9179 };
9180
9181 static void
9182 lkpi_cfg80211_get_bss_iterf(void *arg, const struct ieee80211_scan_entry *se)
9183 {
9184 struct lkpi_cfg80211_get_bss_iter_lookup *lookup;
9185 size_t ielen;
9186
9187 lookup = arg;
9188
9189 /* Do not try to find another match. */
9190 if (lookup->match)
9191 return;
9192
9193 /* Nothing to store result. */
9194 if (lookup->bss == NULL)
9195 return;
9196
9197 if (lookup->privacy != IEEE80211_PRIVACY_ANY) {
9198 /* if (se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) */
9199 /* We have no idea what to compare to as the drivers only request ANY */
9200 return;
9201 }
9202
9203 if (lookup->bss_type != IEEE80211_BSS_TYPE_ANY) {
9204 /* if (se->se_capinfo & (IEEE80211_CAPINFO_IBSS|IEEE80211_CAPINFO_ESS)) */
9205 /* We have no idea what to compare to as the drivers only request ANY */
9206 return;
9207 }
9208
9209 if (lookup->chan != NULL) {
9210 struct linuxkpi_ieee80211_channel *chan;
9211
9212 chan = linuxkpi_ieee80211_get_channel(lookup->wiphy,
9213 se->se_chan->ic_freq);
9214 if (chan == NULL || chan != lookup->chan)
9215 return;
9216 }
9217
9218 if (lookup->bssid && !IEEE80211_ADDR_EQ(lookup->bssid, se->se_bssid))
9219 return;
9220
9221 if (lookup->ssid) {
9222 if (lookup->ssid_len != se->se_ssid[1] ||
9223 se->se_ssid[1] == 0)
9224 return;
9225 if (memcmp(lookup->ssid, se->se_ssid+2, lookup->ssid_len) != 0)
9226 return;
9227 }
9228
9229 ielen = se->se_ies.len;
9230
9231 lookup->bss->ies = malloc(sizeof(*lookup->bss->ies) + ielen,
9232 M_LKPI80211, M_NOWAIT | M_ZERO);
9233 if (lookup->bss->ies == NULL)
9234 return;
9235
9236 lookup->bss->ies->data = (uint8_t *)lookup->bss->ies + sizeof(*lookup->bss->ies);
9237 lookup->bss->ies->len = ielen;
9238 if (ielen)
9239 memcpy(lookup->bss->ies->data, se->se_ies.data, ielen);
9240
9241 lookup->match = true;
9242 }
9243
9244 struct cfg80211_bss *
9245 linuxkpi_cfg80211_get_bss(struct wiphy *wiphy, struct linuxkpi_ieee80211_channel *chan,
9246 const uint8_t *bssid, const uint8_t *ssid, size_t ssid_len,
9247 enum ieee80211_bss_type bss_type, enum ieee80211_privacy privacy)
9248 {
9249 struct lkpi_cfg80211_bss *lbss;
9250 struct lkpi_cfg80211_get_bss_iter_lookup lookup;
9251 struct lkpi_hw *lhw;
9252 struct ieee80211vap *vap;
9253
9254 lhw = wiphy_priv(wiphy);
9255
9256 /* Let's hope we can alloc. */
9257 lbss = malloc(sizeof(*lbss), M_LKPI80211, M_NOWAIT | M_ZERO);
9258 if (lbss == NULL) {
9259 ic_printf(lhw->ic, "%s: alloc failed.\n", __func__);
9260 return (NULL);
9261 }
9262
9263 lookup.wiphy = wiphy;
9264 lookup.chan = chan;
9265 lookup.bssid = bssid;
9266 lookup.ssid = ssid;
9267 lookup.ssid_len = ssid_len;
9268 lookup.bss_type = bss_type;
9269 lookup.privacy = privacy;
9270 lookup.match = false;
9271 lookup.bss = &lbss->bss;
9272
9273 IMPROVE("Iterate over all VAPs comparing perm_addr and addresses?");
9274 vap = TAILQ_FIRST(&lhw->ic->ic_vaps);
9275 ieee80211_scan_iterate(vap, lkpi_cfg80211_get_bss_iterf, &lookup);
9276 if (!lookup.match) {
9277 free(lbss, M_LKPI80211);
9278 return (NULL);
9279 }
9280
9281 refcount_init(&lbss->refcnt, 1);
9282 return (&lbss->bss);
9283 }
9284
9285 void
9286 linuxkpi_cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss)
9287 {
9288 struct lkpi_cfg80211_bss *lbss;
9289
9290 lbss = container_of(bss, struct lkpi_cfg80211_bss, bss);
9291
9292 /* Free everything again on refcount ... */
9293 if (refcount_release(&lbss->refcnt)) {
9294 free(lbss->bss.ies, M_LKPI80211);
9295 free(lbss, M_LKPI80211);
9296 }
9297 }
9298
9299 void
9300 linuxkpi_cfg80211_bss_flush(struct wiphy *wiphy)
9301 {
9302 struct lkpi_hw *lhw;
9303 struct ieee80211com *ic;
9304 struct ieee80211vap *vap;
9305
9306 lhw = wiphy_priv(wiphy);
9307 ic = lhw->ic;
9308
9309 /*
9310 * If we haven't called ieee80211_ifattach() yet
9311 * or there is no VAP, there are no scans to flush.
9312 */
9313 if (ic == NULL ||
9314 (lhw->sc_flags & LKPI_MAC80211_DRV_STARTED) == 0)
9315 return;
9316
9317 /* Should only happen on the current one? Not seen it late enough. */
9318 IEEE80211_LOCK(ic);
9319 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
9320 ieee80211_scan_flush(vap);
9321 IEEE80211_UNLOCK(ic);
9322 }
9323
9324 /* -------------------------------------------------------------------------- */
9325
9326 static bool
9327 cfg80211_chan_def_are_same(struct cfg80211_chan_def *cd1,
9328 struct cfg80211_chan_def *cd2)
9329 {
9330
9331 if (cd1 == cd2)
9332 return (true);
9333
9334 if (cd1 == NULL || cd2 == NULL)
9335 return (false);
9336
9337 if (cd1->chan != cd2->chan)
9338 return (false);
9339
9340 if (cd1->width != cd2->width)
9341 return (false);
9342
9343 if (cd1->center_freq1 != cd2->center_freq1)
9344 return (false);
9345
9346 if (cd1->center_freq2 != cd2->center_freq2)
9347 return (false);
9348
9349 if (cd1->punctured != cd2->punctured)
9350 return (false);
9351
9352 return (true);
9353 }
9354
9355 /*
9356 * hw->conf get initialized/set in various places for us:
9357 * - linuxkpi_ieee80211_alloc_hw(): flags
9358 * - linuxkpi_ieee80211_ifattach(): chandef
9359 * - lkpi_ic_vap_create(): listen_interval
9360 * - lkpi_ic_set_channel(): chandef, flags
9361 */
9362
9363 static int
9364 lkpi_80211_update_chandef(struct ieee80211_hw *hw,
9365 struct ieee80211_chanctx_conf *new)
9366 {
9367 struct lkpi_hw *lhw;
9368 struct cfg80211_chan_def *cd;
9369 uint32_t changed;
9370 int error;
9371 bool same;
9372
9373 lockdep_assert_wiphy(hw->wiphy);
9374
9375 lhw = HW_TO_LHW(hw);
9376 if (!lhw->emulate_chanctx)
9377 return (0);
9378
9379 if (new == NULL || new->def.chan == NULL) {
9380 /*
9381 * In case of remove "new" is NULL, we need to get us to some
9382 * basic channel width but we'd also need to set the channel
9383 * accordingly somewhere.
9384 * The same is true if we are scanning in which case the
9385 * scan_chandef should have a channel set.
9386 */
9387 if (lhw->scan_chandef.chan != NULL) {
9388 #ifdef LINUXKPI_DEBUG_80211
9389 if ((linuxkpi_debug_80211 & D80211_CHANDEF) != 0)
9390 ic_printf(lhw->ic, "%s:%d: using scan_chandef %p\n",
9391 __func__, __LINE__, &lhw->scan_chandef);
9392 #endif
9393 cd = &lhw->scan_chandef;
9394 } else {
9395 #ifdef LINUXKPI_DEBUG_80211
9396 if ((linuxkpi_debug_80211 & D80211_CHANDEF) != 0)
9397 ic_printf(lhw->ic, "%s:%d: using dflt_chandef %p\n",
9398 __func__, __LINE__, &lhw->dflt_chandef);
9399 #endif
9400 cd = &lhw->dflt_chandef;
9401 }
9402 } else {
9403 #ifdef LINUXKPI_DEBUG_80211
9404 if ((linuxkpi_debug_80211 & D80211_CHANDEF) != 0)
9405 ic_printf(lhw->ic, "%s:%d: using chanctx %p chandef %p\n",
9406 __func__, __LINE__, new, &new->def);
9407 #endif
9408 cd = &new->def;
9409 }
9410
9411 changed = 0;
9412 same = cfg80211_chan_def_are_same(cd, &hw->conf.chandef);
9413 if (!same) {
9414 /* Copy; the chan pointer is fine and will stay valid. */
9415 hw->conf.chandef = *cd;
9416 changed |= IEEE80211_CONF_CHANGE_CHANNEL;
9417 }
9418 IMPROVE("IEEE80211_CONF_CHANGE_PS, IEEE80211_CONF_CHANGE_POWER");
9419
9420 #ifdef LINUXKPI_DEBUG_80211
9421 if ((linuxkpi_debug_80211 & D80211_CHANDEF) != 0)
9422 ic_printf(lhw->ic, "%s:%d: chanctx %p { %u } cd %p { %u } "
9423 "hw->conf.chandef %p { %u %d %u %u %u }, "
9424 "changed %#04x same %d\n",
9425 __func__, __LINE__,
9426 new, (new != NULL && new->def.chan != NULL) ?
9427 new->def.chan->center_freq : 0,
9428 cd, cd->chan->center_freq,
9429 &hw->conf.chandef, hw->conf.chandef.chan->center_freq,
9430 hw->conf.chandef.width,
9431 hw->conf.chandef.center_freq1,
9432 hw->conf.chandef.center_freq2,
9433 hw->conf.chandef.punctured,
9434 changed, same);
9435 #endif
9436
9437 if (changed == 0)
9438 return (0);
9439
9440 error = lkpi_80211_mo_config(hw, changed);
9441 return (error);
9442 }
9443
9444 int
9445 ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw,
9446 struct ieee80211_chanctx_conf *chanctx_conf)
9447 {
9448 int error;
9449
9450 lockdep_assert_wiphy(hw->wiphy);
9451
9452 #ifdef LINUXKPI_DEBUG_80211
9453 if ((linuxkpi_debug_80211 & D80211_TRACE) != 0) {
9454 struct lkpi_hw *lhw;
9455
9456 lhw = HW_TO_LHW(hw);
9457 ic_printf(lhw->ic, "%s:%d: chanctx_conf %p\n",
9458 __func__, __LINE__, chanctx_conf);
9459 }
9460 #endif
9461
9462 hw->conf.radar_enabled = chanctx_conf->radar_enabled;
9463 error = lkpi_80211_update_chandef(hw, chanctx_conf);
9464 return (error);
9465 }
9466
9467 void
9468 ieee80211_emulate_remove_chanctx(struct ieee80211_hw *hw,
9469 struct ieee80211_chanctx_conf *chanctx_conf __unused)
9470 {
9471
9472 lockdep_assert_wiphy(hw->wiphy);
9473
9474 #ifdef LINUXKPI_DEBUG_80211
9475 if ((linuxkpi_debug_80211 & D80211_TRACE) != 0) {
9476 struct lkpi_hw *lhw;
9477
9478 lhw = HW_TO_LHW(hw);
9479 ic_printf(lhw->ic, "%s:%d: chanctx_conf %p\n",
9480 __func__, __LINE__, chanctx_conf);
9481 }
9482 #endif
9483
9484 hw->conf.radar_enabled = false;
9485 lkpi_80211_update_chandef(hw, NULL);
9486 }
9487
9488 void
9489 ieee80211_emulate_change_chanctx(struct ieee80211_hw *hw,
9490 struct ieee80211_chanctx_conf *chanctx_conf, uint32_t changed __unused)
9491 {
9492
9493 lockdep_assert_wiphy(hw->wiphy);
9494
9495 #ifdef LINUXKPI_DEBUG_80211
9496 if ((linuxkpi_debug_80211 & D80211_TRACE) != 0) {
9497 struct lkpi_hw *lhw;
9498
9499 lhw = HW_TO_LHW(hw);
9500 ic_printf(lhw->ic, "%s:%d: chanctx_conf %p\n",
9501 __func__, __LINE__, chanctx_conf);
9502 }
9503 #endif
9504
9505 hw->conf.radar_enabled = chanctx_conf->radar_enabled;
9506 lkpi_80211_update_chandef(hw, chanctx_conf);
9507 }
9508
9509 int
9510 ieee80211_emulate_switch_vif_chanctx(struct ieee80211_hw *hw,
9511 struct ieee80211_vif_chanctx_switch *vifs, int n_vifs,
9512 enum ieee80211_chanctx_switch_mode mode __unused)
9513 {
9514 struct ieee80211_chanctx_conf *chanctx_conf;
9515 int error;
9516
9517 lockdep_assert_wiphy(hw->wiphy);
9518
9519 /* Sanity check. */
9520 if (n_vifs <= 0)
9521 return (-EINVAL);
9522 if (vifs == NULL || vifs[0].new_ctx == NULL)
9523 return (-EINVAL);
9524
9525 /*
9526 * What to do if n_vifs > 1?
9527 * Does that make sense for drivers not supporting chanctx?
9528 */
9529 hw->conf.radar_enabled = vifs[0].new_ctx->radar_enabled;
9530 chanctx_conf = vifs[0].new_ctx;
9531 error = lkpi_80211_update_chandef(hw, chanctx_conf);
9532 return (error);
9533 }
9534
9535 /* -------------------------------------------------------------------------- */
9536
9537 MODULE_VERSION(linuxkpi_wlan, 1);
9538 MODULE_DEPEND(linuxkpi_wlan, linuxkpi, 1, 1, 1);
9539 MODULE_DEPEND(linuxkpi_wlan, wlan, 1, 1, 1);
9540