xref: /freebsd/sys/compat/linuxkpi/common/src/linux_80211.c (revision ade8a27ea4c28d12fabc2d5f8e44386a3add23d1)
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 *
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
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
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(&ltxq->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(&ltxq->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
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
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
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
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
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
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
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
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
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
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 *
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(&ltxq->skbq);
896 		LKPI_80211_LTXQ_LOCK_INIT(ltxq);
897 		sta->txq[tid] = &ltxq->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
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
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
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 *
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
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 *
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
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
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
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 *
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
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(&ltxq->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
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
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
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 *
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 *
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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
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
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
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
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 *
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
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
4271 linuxkpi_ieee80211_restart_hw(struct ieee80211_hw *hw)
4272 {
4273 
4274 	TODO();
4275 }
4276 
4277 static void
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
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
4345 lkpi_ic_update_promisc(struct ieee80211com *ic)
4346 {
4347 
4348 	UNIMPLEMENTED;
4349 }
4350 
4351 static void
4352 lkpi_ic_update_chw(struct ieee80211com *ic)
4353 {
4354 
4355 	UNIMPLEMENTED;
4356 }
4357 
4358 /* Start / stop device. */
4359 static void
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
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
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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
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
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
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
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(&ltxq->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(&ltxq->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(&ltxq->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, &ltxq->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, &params);
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, &params);
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, &params);
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, &params);
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, &params);
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(&ltxq->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(&ltxq->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(&ltxq->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 = &ltxq->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(&ltxq->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