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