xref: /freebsd/sys/compat/linuxkpi/common/src/linux_80211.c (revision 97ca2ada80b870edbbb4f66b26e274cf8e55e0bc)
1 /*-
2  * Copyright (c) 2020-2025 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_WME
81 #define	LKPI_80211_HW_CRYPTO
82 /* #define	LKPI_80211_HT */
83 /* #define	LKPI_80211_VHT */
84 
85 #if defined(LKPI_80211_VHT) && !defined(LKPI_80211_HT)
86 #define	LKPI_80211_HT
87 #endif
88 #if defined(LKPI_80211_HT) && !defined(LKPI_80211_HW_CRYPTO)
89 #define	LKPI_80211_HW_CRYPTO
90 #endif
91 
92 static MALLOC_DEFINE(M_LKPI80211, "lkpi80211", "LinuxKPI 80211 compat");
93 
94 /* XXX-BZ really want this and others in queue.h */
95 #define	TAILQ_ELEM_INIT(elm, field) do {				\
96 	(elm)->field.tqe_next = NULL;					\
97 	(elm)->field.tqe_prev = NULL;					\
98 } while (0)
99 
100 /* -------------------------------------------------------------------------- */
101 
102 SYSCTL_DECL(_compat_linuxkpi);
103 SYSCTL_NODE(_compat_linuxkpi, OID_AUTO, 80211, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
104     "LinuxKPI 802.11 compatibility layer");
105 
106 #if defined(LKPI_80211_HW_CRYPTO)
107 static bool lkpi_hwcrypto = false;
108 SYSCTL_BOOL(_compat_linuxkpi_80211, OID_AUTO, hw_crypto, CTLFLAG_RDTUN,
109     &lkpi_hwcrypto, 0, "Enable LinuxKPI 802.11 hardware crypto offload");
110 #endif
111 
112 /* Keep public for as long as header files are using it too. */
113 int linuxkpi_debug_80211;
114 
115 #ifdef LINUXKPI_DEBUG_80211
116 SYSCTL_INT(_compat_linuxkpi_80211, OID_AUTO, debug, CTLFLAG_RWTUN,
117     &linuxkpi_debug_80211, 0, "LinuxKPI 802.11 debug level");
118 
119 #define	UNIMPLEMENTED		if (linuxkpi_debug_80211 & D80211_TODO)		\
120     printf("XXX-TODO %s:%d: UNIMPLEMENTED\n", __func__, __LINE__)
121 #define	TRACEOK()		if (linuxkpi_debug_80211 & D80211_TRACEOK)	\
122     printf("XXX-TODO %s:%d: TRACEPOINT\n", __func__, __LINE__)
123 #else
124 #define	UNIMPLEMENTED		do { } while (0)
125 #define	TRACEOK()		do { } while (0)
126 #endif
127 
128 /* #define	PREP_TX_INFO_DURATION	(IEEE80211_TRANS_WAIT * 1000) */
129 #ifndef PREP_TX_INFO_DURATION
130 #define	PREP_TX_INFO_DURATION	0 /* Let the driver do its thing. */
131 #endif
132 
133 /* This is DSAP | SSAP | CTRL | ProtoID/OrgCode{3}. */
134 const uint8_t rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
135 
136 /* IEEE 802.11-05/0257r1 */
137 const uint8_t bridge_tunnel_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
138 
139 /* IEEE 802.11e Table 20i-UP-to-AC mappings. */
140 static const uint8_t ieee80211e_up_to_ac[] = {
141 	IEEE80211_AC_BE,
142 	IEEE80211_AC_BK,
143 	IEEE80211_AC_BK,
144 	IEEE80211_AC_BE,
145 	IEEE80211_AC_VI,
146 	IEEE80211_AC_VI,
147 	IEEE80211_AC_VO,
148 	IEEE80211_AC_VO,
149 #if 0
150 	IEEE80211_AC_VO, /* We treat MGMT as TID 8, which is set as AC_VO */
151 #endif
152 };
153 
154 const struct cfg80211_ops linuxkpi_mac80211cfgops = {
155 	/*
156 	 * XXX TODO need a "glue layer" to link cfg80211 ops to
157 	 * mac80211 and to the driver or net80211.
158 	 * Can we pass some on 1:1? Need to compare the (*f)().
159 	 */
160 };
161 
162 #if 0
163 static struct lkpi_sta *lkpi_find_lsta_by_ni(struct lkpi_vif *,
164     struct ieee80211_node *);
165 #endif
166 static void lkpi_80211_txq_tx_one(struct lkpi_sta *, struct mbuf *);
167 static void lkpi_80211_txq_task(void *, int);
168 static void lkpi_80211_lhw_rxq_task(void *, int);
169 static void lkpi_ieee80211_free_skb_mbuf(void *);
170 #ifdef LKPI_80211_WME
171 static int lkpi_wme_update(struct lkpi_hw *, struct ieee80211vap *, bool);
172 #endif
173 
174 static const char *
175 lkpi_rate_info_bw_to_str(enum rate_info_bw bw)
176 {
177 
178 	switch (bw) {
179 
180         case RATE_INFO_BW_20:
181 		return ("20");
182 		break;
183         case RATE_INFO_BW_5:
184 		return ("5");
185 		break;
186         case RATE_INFO_BW_10:
187 		return ("10");
188 		break;
189         case RATE_INFO_BW_40:
190 		return ("40");
191 		break;
192         case RATE_INFO_BW_80:
193 		return ("80");
194 		break;
195         case RATE_INFO_BW_160:
196 		return ("160");
197 		break;
198         case RATE_INFO_BW_HE_RU:
199 		IMPROVE("nl80211_he_ru_alloc");
200 		return ("HE_RU");
201 		break;
202         case RATE_INFO_BW_320:
203 		return ("320");
204 		break;
205         case RATE_INFO_BW_EHT_RU:
206 		IMPROVE("nl80211_eht_ru_alloc");
207 		return ("EHT_RU");
208 		break;
209 	default:
210 		return ("?");
211 		break;
212 	}
213 }
214 
215 static void
216 lkpi_nl80211_sta_info_to_str(struct sbuf *s, const char *prefix,
217     const uint64_t flags)
218 {
219 	int bit, i;
220 
221 	sbuf_printf(s, "%s %#010jx", prefix, flags);
222 
223 	i = 0;
224 	for (bit = 0; bit < BITS_PER_TYPE(flags); bit++) {
225 
226 		if ((flags & BIT_ULL(bit)) == 0)
227 			continue;
228 
229 #define	EXPAND_CASE(_flag)						\
230 	case NL80211_STA_INFO_ ## _flag:				\
231 		sbuf_printf(s, "%c%s", (i == 0) ? '<' : ',', #_flag);	\
232 		i++;							\
233 		break;
234 
235 		switch (bit) {
236 		EXPAND_CASE(BEACON_RX)
237 		EXPAND_CASE(BEACON_SIGNAL_AVG)
238 		EXPAND_CASE(BSS_PARAM)
239 		EXPAND_CASE(CHAIN_SIGNAL)
240 		EXPAND_CASE(CHAIN_SIGNAL_AVG)
241 		EXPAND_CASE(CONNECTED_TIME)
242 		EXPAND_CASE(INACTIVE_TIME)
243 		EXPAND_CASE(SIGNAL)
244 		EXPAND_CASE(SIGNAL_AVG)
245 		EXPAND_CASE(STA_FLAGS)
246 		EXPAND_CASE(RX_BITRATE)
247 		EXPAND_CASE(RX_PACKETS)
248 		EXPAND_CASE(RX_BYTES)
249 		EXPAND_CASE(RX_DROP_MISC)
250 		EXPAND_CASE(TX_BITRATE)
251 		EXPAND_CASE(TX_PACKETS)
252 		EXPAND_CASE(TX_BYTES)
253 		EXPAND_CASE(TX_BYTES64)
254 		EXPAND_CASE(RX_BYTES64)
255 		EXPAND_CASE(TX_FAILED)
256 		EXPAND_CASE(TX_RETRIES)
257 		EXPAND_CASE(RX_DURATION)
258 		EXPAND_CASE(TX_DURATION)
259 		EXPAND_CASE(ACK_SIGNAL)
260 		EXPAND_CASE(ACK_SIGNAL_AVG)
261 		default:
262 			sbuf_printf(s, "%c?%d", (i == 0) ? '<' : ',', bit);
263 			break;
264 		}
265 	}
266 #undef	EXPAND_CASE
267 	if (i > 0)
268 		sbuf_printf(s, ">");
269 	sbuf_printf(s, "\n");
270 }
271 
272 static int
273 lkpi_80211_dump_stas(SYSCTL_HANDLER_ARGS)
274 {
275 	struct lkpi_hw *lhw;
276 	struct ieee80211_hw *hw;
277 	struct ieee80211vap *vap;
278 	struct lkpi_vif *lvif;
279 	struct ieee80211_vif *vif;
280 	struct lkpi_sta *lsta;
281 	struct ieee80211_sta *sta;
282 	struct station_info sinfo;
283 	struct sbuf s;
284 	int error;
285 
286 	if (req->newptr)
287 		return (EPERM);
288 
289 	lvif = (struct lkpi_vif *)arg1;
290 	vif = LVIF_TO_VIF(lvif);
291 	vap = LVIF_TO_VAP(lvif);
292 	lhw = vap->iv_ic->ic_softc;
293 	hw = LHW_TO_HW(lhw);
294 
295 	sbuf_new_for_sysctl(&s, NULL, 1024, req);
296 
297 	wiphy_lock(hw->wiphy);
298 	list_for_each_entry(lsta, &lvif->lsta_list, lsta_list) {
299 		sta = LSTA_TO_STA(lsta);
300 
301 		sbuf_putc(&s, '\n');
302 		sbuf_printf(&s, "lsta %p sta %p added_to_drv %d\n", lsta, sta, lsta->added_to_drv);
303 
304 		memset(&sinfo, 0, sizeof(sinfo));
305 		error = lkpi_80211_mo_sta_statistics(hw, vif, sta, &sinfo);
306 		if (error == EEXIST)	/* Not added to driver. */
307 			continue;
308 		if (error == ENOTSUPP) {
309 			sbuf_printf(&s, " sta_statistics not supported\n");
310 			continue;
311 		}
312 		if (error != 0) {
313 			sbuf_printf(&s, " sta_statistics failed: %d\n", error);
314 			continue;
315 		}
316 
317 		lkpi_nl80211_sta_info_to_str(&s, " nl80211_sta_info (valid fields)", sinfo.filled);
318 		sbuf_printf(&s, " connected_time %u inactive_time %u\n",
319 		    sinfo.connected_time, sinfo.inactive_time);
320 		sbuf_printf(&s, " rx_bytes %ju rx_packets %u rx_dropped_misc %u\n",
321 		    (uintmax_t)sinfo.rx_bytes, sinfo.rx_packets, sinfo.rx_dropped_misc);
322 		sbuf_printf(&s, " rx_duration %ju rx_beacon %u rx_beacon_signal_avg %d\n",
323 		    (uintmax_t)sinfo.rx_duration, sinfo.rx_beacon, (int8_t)sinfo.rx_beacon_signal_avg);
324 
325 		sbuf_printf(&s, " tx_bytes %ju tx_packets %u tx_failed %u\n",
326 		    (uintmax_t)sinfo.tx_bytes, sinfo.tx_packets, sinfo.tx_failed);
327 		sbuf_printf(&s, " tx_duration %ju tx_retries %u\n",
328 		    (uintmax_t)sinfo.tx_duration, sinfo.tx_retries);
329 
330 		sbuf_printf(&s, " signal %d signal_avg %d ack_signal %d avg_ack_signal %d\n",
331 		    sinfo.signal, sinfo.signal_avg, sinfo.ack_signal, sinfo.avg_ack_signal);
332 
333 		sbuf_printf(&s, " generation %d assoc_req_ies_len %zu chains %d\n",
334 		    sinfo.generation, sinfo.assoc_req_ies_len, sinfo.chains);
335 
336 		for (int i = 0; i < sinfo.chains && i < IEEE80211_MAX_CHAINS; i++) {
337 			sbuf_printf(&s, "  chain[%d] signal %d signal_avg %d\n",
338 			    i, (int8_t)sinfo.chain_signal[i], (int8_t)sinfo.chain_signal_avg[i]);
339 		}
340 
341 		/* assoc_req_ies, bss_param, sta_flags */
342 
343 		sbuf_printf(&s, " rxrate: flags %b bw %u(%s) legacy %u kbit/s mcs %u nss %u\n",
344 		    sinfo.rxrate.flags, CFG80211_RATE_INFO_FLAGS_BITS,
345 		    sinfo.rxrate.bw, lkpi_rate_info_bw_to_str(sinfo.rxrate.bw),
346 		    sinfo.rxrate.legacy * 100,
347 		    sinfo.rxrate.mcs, sinfo.rxrate.nss);
348 		sbuf_printf(&s, "         he_dcm %u he_gi %u he_ru_alloc %u eht_gi %u\n",
349 		    sinfo.rxrate.he_dcm, sinfo.rxrate.he_gi, sinfo.rxrate.he_ru_alloc,
350 		    sinfo.rxrate.eht_gi);
351 		sbuf_printf(&s, " txrate: flags %b bw %u(%s) legacy %u kbit/s mcs %u nss %u\n",
352 		    sinfo.txrate.flags, CFG80211_RATE_INFO_FLAGS_BITS,
353 		    sinfo.txrate.bw, lkpi_rate_info_bw_to_str(sinfo.txrate.bw),
354 		    sinfo.txrate.legacy * 100,
355 		    sinfo.txrate.mcs, sinfo.txrate.nss);
356 		sbuf_printf(&s, "         he_dcm %u he_gi %u he_ru_alloc %u eht_gi %u\n",
357 		    sinfo.txrate.he_dcm, sinfo.txrate.he_gi, sinfo.txrate.he_ru_alloc,
358 		    sinfo.txrate.eht_gi);
359 	}
360 	wiphy_unlock(hw->wiphy);
361 
362 	sbuf_finish(&s);
363 	sbuf_delete(&s);
364 
365 	return (0);
366 }
367 
368 #if defined(LKPI_80211_HT)
369 static void
370 lkpi_sta_sync_ht_from_ni(struct ieee80211_sta *sta, struct ieee80211_node *ni, int *ht_rx_nss)
371 {
372 	struct ieee80211vap *vap;
373 	uint8_t *ie;
374 	struct ieee80211_ht_cap *htcap;
375 	int i, rx_nss;
376 
377 	if ((ni->ni_flags & IEEE80211_NODE_HT) == 0)
378 		return;
379 
380 	if (IEEE80211_IS_CHAN_HT(ni->ni_chan) &&
381 	    IEEE80211_IS_CHAN_HT40(ni->ni_chan))
382 		sta->deflink.bandwidth = IEEE80211_STA_RX_BW_40;
383 
384 	sta->deflink.ht_cap.ht_supported = true;
385 
386 	/* htcap->ampdu_params_info */
387 	vap = ni->ni_vap;
388 	sta->deflink.ht_cap.ampdu_density = _IEEE80211_MASKSHIFT(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
389 	if (sta->deflink.ht_cap.ampdu_density > vap->iv_ampdu_density)
390 		sta->deflink.ht_cap.ampdu_density = vap->iv_ampdu_density;
391 	sta->deflink.ht_cap.ampdu_factor = _IEEE80211_MASKSHIFT(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU);
392 	if (sta->deflink.ht_cap.ampdu_factor > vap->iv_ampdu_rxmax)
393 		sta->deflink.ht_cap.ampdu_factor = vap->iv_ampdu_rxmax;
394 
395 	ie = ni->ni_ies.htcap_ie;
396 	KASSERT(ie != NULL, ("%s: HT but no htcap_ie on ni %p\n", __func__, ni));
397 	if (ie[0] == IEEE80211_ELEMID_VENDOR)
398 		ie += 4;
399 	ie += 2;
400 	htcap = (struct ieee80211_ht_cap *)ie;
401 	sta->deflink.ht_cap.cap = htcap->cap_info;
402 	sta->deflink.ht_cap.mcs = htcap->mcs;
403 
404 	rx_nss = 0;
405 	for (i = 0; i < nitems(htcap->mcs.rx_mask); i++) {
406 		if (htcap->mcs.rx_mask[i])
407 			rx_nss++;
408 	}
409 	if (ht_rx_nss != NULL)
410 		*ht_rx_nss = rx_nss;
411 
412 	IMPROVE("sta->wme, sta->deflink.agg.max*");
413 }
414 #endif
415 
416 #if defined(LKPI_80211_VHT)
417 static void
418 lkpi_sta_sync_vht_from_ni(struct ieee80211_sta *sta, struct ieee80211_node *ni, int *vht_rx_nss)
419 {
420 
421 	if ((ni->ni_flags & IEEE80211_NODE_VHT) == 0)
422 		return;
423 
424 	if (IEEE80211_IS_CHAN_VHT(ni->ni_chan)) {
425 #ifdef __notyet__
426 		if (IEEE80211_IS_CHAN_VHT80P80(ni->ni_chan)) {
427 			sta->deflink.bandwidth = IEEE80211_STA_RX_BW_160; /* XXX? */
428 		} else
429 #endif
430 		if (IEEE80211_IS_CHAN_VHT160(ni->ni_chan))
431 			sta->deflink.bandwidth = IEEE80211_STA_RX_BW_160;
432 		else if (IEEE80211_IS_CHAN_VHT80(ni->ni_chan))
433 			sta->deflink.bandwidth = IEEE80211_STA_RX_BW_80;
434 	}
435 
436 	IMPROVE("VHT sync ni to sta");
437 	return;
438 }
439 #endif
440 
441 static void
442 lkpi_lsta_dump(struct lkpi_sta *lsta, struct ieee80211_node *ni,
443     const char *_f, int _l)
444 {
445 
446 #ifdef LINUXKPI_DEBUG_80211
447 	if ((linuxkpi_debug_80211 & D80211_TRACE_STA) == 0)
448 		return;
449 	if (lsta == NULL)
450 		return;
451 
452 	printf("%s:%d lsta %p ni %p sta %p\n",
453 	    _f, _l, lsta, ni, &lsta->sta);
454 	if (ni != NULL)
455 		ieee80211_dump_node(NULL, ni);
456 	printf("\ttxq_task txq len %d mtx\n", mbufq_len(&lsta->txq));
457 	printf("\tkc %p state %d added_to_drv %d in_mgd %d\n",
458 		&lsta->kc[0], lsta->state, lsta->added_to_drv, lsta->in_mgd);
459 #endif
460 }
461 
462 static void
463 lkpi_lsta_remove(struct lkpi_sta *lsta, struct lkpi_vif *lvif)
464 {
465 
466 
467 	wiphy_lock(lsta->hw->wiphy);
468 	KASSERT(!list_empty(&lsta->lsta_list),
469 	    ("%s: lsta %p ni %p\n", __func__, lsta, lsta->ni));
470 	list_del_init(&lsta->lsta_list);
471 	wiphy_unlock(lsta->hw->wiphy);
472 }
473 
474 static struct lkpi_sta *
475 lkpi_lsta_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN],
476     struct ieee80211_hw *hw, struct ieee80211_node *ni)
477 {
478 	struct lkpi_sta *lsta;
479 	struct lkpi_vif *lvif;
480 	struct ieee80211_vif *vif;
481 	struct ieee80211_sta *sta;
482 	int band, i, tid;
483 	int ht_rx_nss;
484 	int vht_rx_nss;
485 
486 	lsta = malloc(sizeof(*lsta) + hw->sta_data_size, M_LKPI80211,
487 	    M_NOWAIT | M_ZERO);
488 	if (lsta == NULL)
489 		return (NULL);
490 
491 	lsta->hw = hw;
492 	lsta->added_to_drv = false;
493 	lsta->state = IEEE80211_STA_NOTEXIST;
494 	/*
495 	 * Link the ni to the lsta here without taking a reference.
496 	 * For one we would have to take the reference in node_init()
497 	 * as ieee80211_alloc_node() will initialise the refcount after us.
498 	 * For the other a ni and an lsta are 1:1 mapped and always together
499 	 * from [ic_]node_alloc() to [ic_]node_free() so we are essentally
500 	 * using the ni references for the lsta as well despite it being
501 	 * two separate allocations.
502 	 */
503 	lsta->ni = ni;
504 	/* The back-pointer "drv_data" to net80211_node let's us get lsta. */
505 	ni->ni_drv_data = lsta;
506 
507 	lvif = VAP_TO_LVIF(vap);
508 	vif = LVIF_TO_VIF(lvif);
509 	sta = LSTA_TO_STA(lsta);
510 
511 	IEEE80211_ADDR_COPY(sta->addr, mac);
512 
513 	/* TXQ */
514 	for (tid = 0; tid < nitems(sta->txq); tid++) {
515 		struct lkpi_txq *ltxq;
516 
517 		/* We are not limiting ourselves to hw.queues here. */
518 		ltxq = malloc(sizeof(*ltxq) + hw->txq_data_size,
519 		    M_LKPI80211, M_NOWAIT | M_ZERO);
520 		if (ltxq == NULL)
521 			goto cleanup;
522 		/* iwlwifi//mvm/sta.c::tid_to_mac80211_ac[] */
523 		if (tid == IEEE80211_NUM_TIDS) {
524 			if (!ieee80211_hw_check(hw, STA_MMPDU_TXQ)) {
525 				free(ltxq, M_LKPI80211);
526 				continue;
527 			}
528 			IMPROVE("AP/if we support non-STA here too");
529 			ltxq->txq.ac = IEEE80211_AC_VO;
530 		} else {
531 			ltxq->txq.ac = ieee80211e_up_to_ac[tid & 7];
532 		}
533 		ltxq->seen_dequeue = false;
534 		ltxq->stopped = false;
535 		ltxq->txq.vif = vif;
536 		ltxq->txq.tid = tid;
537 		ltxq->txq.sta = sta;
538 		TAILQ_ELEM_INIT(ltxq, txq_entry);
539 		skb_queue_head_init(&ltxq->skbq);
540 		LKPI_80211_LTXQ_LOCK_INIT(ltxq);
541 		sta->txq[tid] = &ltxq->txq;
542 	}
543 
544 	/* Deflink information. */
545 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
546 		struct ieee80211_supported_band *supband;
547 
548 		supband = hw->wiphy->bands[band];
549 		if (supband == NULL)
550 			continue;
551 
552 		for (i = 0; i < supband->n_bitrates; i++) {
553 
554 			IMPROVE("Further supband->bitrates[i]* checks?");
555 			/* or should we get them from the ni? */
556 			sta->deflink.supp_rates[band] |= BIT(i);
557 		}
558 	}
559 
560 	sta->deflink.smps_mode = IEEE80211_SMPS_OFF;
561 	sta->deflink.bandwidth = IEEE80211_STA_RX_BW_20;
562 	sta->deflink.rx_nss = 1;
563 
564 	ht_rx_nss = 0;
565 #if defined(LKPI_80211_HT)
566 	lkpi_sta_sync_ht_from_ni(sta, ni, &ht_rx_nss);
567 #endif
568 	vht_rx_nss = 0;
569 #if defined(LKPI_80211_VHT)
570 	lkpi_sta_sync_vht_from_ni(sta, ni, &vht_rx_nss);
571 #endif
572 
573 	sta->deflink.rx_nss = MAX(ht_rx_nss, sta->deflink.rx_nss);
574 	sta->deflink.rx_nss = MAX(vht_rx_nss, sta->deflink.rx_nss);
575 	IMPROVE("he, ... smps_mode, ..");
576 
577 	/* Link configuration. */
578 	IEEE80211_ADDR_COPY(sta->deflink.addr, sta->addr);
579 	sta->link[0] = &sta->deflink;
580 	for (i = 1; i < nitems(sta->link); i++) {
581 		IMPROVE("more links; only link[0] = deflink currently.");
582 	}
583 
584 	/* Deferred TX path. */
585 	LKPI_80211_LSTA_TXQ_LOCK_INIT(lsta);
586 	TASK_INIT(&lsta->txq_task, 0, lkpi_80211_txq_task, lsta);
587 	mbufq_init(&lsta->txq, IFQ_MAXLEN);
588 	lsta->txq_ready = true;
589 
590 	return (lsta);
591 
592 cleanup:
593 	for (; tid >= 0; tid--) {
594 		struct lkpi_txq *ltxq;
595 
596 		ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
597 		LKPI_80211_LTXQ_LOCK_DESTROY(ltxq);
598 		free(sta->txq[tid], M_LKPI80211);
599 	}
600 	free(lsta, M_LKPI80211);
601 	return (NULL);
602 }
603 
604 static void
605 lkpi_lsta_free(struct lkpi_sta *lsta, struct ieee80211_node *ni)
606 {
607 	struct mbuf *m;
608 
609 	if (lsta->added_to_drv)
610 		panic("%s: Trying to free an lsta still known to firmware: "
611 		    "lsta %p ni %p added_to_drv %d\n",
612 		    __func__, lsta, ni, lsta->added_to_drv);
613 
614 	/* XXX-BZ free resources, ... */
615 	IMPROVE();
616 
617 	/* Drain sta->txq[] */
618 
619 	LKPI_80211_LSTA_TXQ_LOCK(lsta);
620 	lsta->txq_ready = false;
621 	LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
622 
623 	/* Drain taskq, won't be restarted until added_to_drv is set again. */
624 	while (taskqueue_cancel(taskqueue_thread, &lsta->txq_task, NULL) != 0)
625 		taskqueue_drain(taskqueue_thread, &lsta->txq_task);
626 
627 	/* Flush mbufq (make sure to release ni refs!). */
628 	m = mbufq_dequeue(&lsta->txq);
629 	while (m != NULL) {
630 		struct ieee80211_node *nim;
631 
632 		nim = (struct ieee80211_node *)m->m_pkthdr.rcvif;
633 		if (nim != NULL)
634 			ieee80211_free_node(nim);
635 		m_freem(m);
636 		m = mbufq_dequeue(&lsta->txq);
637 	}
638 	KASSERT(mbufq_empty(&lsta->txq), ("%s: lsta %p has txq len %d != 0\n",
639 	    __func__, lsta, mbufq_len(&lsta->txq)));
640 	LKPI_80211_LSTA_TXQ_LOCK_DESTROY(lsta);
641 
642 	/* Remove lsta from vif; that is done by the state machine.  Should assert it? */
643 
644 	IMPROVE("Make sure everything is cleaned up.");
645 
646 	/* Free lsta. */
647 	lsta->ni = NULL;
648 	ni->ni_drv_data = NULL;
649 	free(lsta, M_LKPI80211);
650 }
651 
652 
653 static enum nl80211_band
654 lkpi_net80211_chan_to_nl80211_band(struct ieee80211_channel *c)
655 {
656 
657 	if (IEEE80211_IS_CHAN_2GHZ(c))
658 		return (NL80211_BAND_2GHZ);
659 	else if (IEEE80211_IS_CHAN_5GHZ(c))
660 		return (NL80211_BAND_5GHZ);
661 #ifdef __notyet__
662 	else if ()
663 		return (NL80211_BAND_6GHZ);
664 	else if ()
665 		return (NL80211_BAND_60GHZ);
666 	else if (IEEE80211_IS_CHAN_GSM(c))
667 		return (NL80211_BAND_XXX);
668 #endif
669 	else
670 		panic("%s: unsupported band. c %p flags %#x\n",
671 		    __func__, c, c->ic_flags);
672 }
673 
674 static uint32_t
675 lkpi_nl80211_band_to_net80211_band(enum nl80211_band band)
676 {
677 
678 	/* XXX-BZ this is just silly; net80211 is too convoluted. */
679 	/* IEEE80211_CHAN_A / _G / .. doesn't really work either. */
680 	switch (band) {
681 	case NL80211_BAND_2GHZ:
682 		return (IEEE80211_CHAN_2GHZ);
683 		break;
684 	case NL80211_BAND_5GHZ:
685 		return (IEEE80211_CHAN_5GHZ);
686 		break;
687 	case NL80211_BAND_60GHZ:
688 		break;
689 	case NL80211_BAND_6GHZ:
690 		break;
691 	default:
692 		panic("%s: unsupported band %u\n", __func__, band);
693 		break;
694 	}
695 
696 	IMPROVE();
697 	return (0x00);
698 }
699 
700 #if 0
701 static enum ieee80211_ac_numbers
702 lkpi_ac_net_to_l80211(int ac)
703 {
704 
705 	switch (ac) {
706 	case WME_AC_VO:
707 		return (IEEE80211_AC_VO);
708 	case WME_AC_VI:
709 		return (IEEE80211_AC_VI);
710 	case WME_AC_BE:
711 		return (IEEE80211_AC_BE);
712 	case WME_AC_BK:
713 		return (IEEE80211_AC_BK);
714 	default:
715 		printf("%s: invalid WME_AC_* input: ac = %d\n", __func__, ac);
716 		return (IEEE80211_AC_BE);
717 	}
718 }
719 #endif
720 
721 static enum nl80211_iftype
722 lkpi_opmode_to_vif_type(enum ieee80211_opmode opmode)
723 {
724 
725 	switch (opmode) {
726 	case IEEE80211_M_IBSS:
727 		return (NL80211_IFTYPE_ADHOC);
728 		break;
729 	case IEEE80211_M_STA:
730 		return (NL80211_IFTYPE_STATION);
731 		break;
732 	case IEEE80211_M_WDS:
733 		return (NL80211_IFTYPE_WDS);
734 		break;
735 	case IEEE80211_M_HOSTAP:
736 		return (NL80211_IFTYPE_AP);
737 		break;
738 	case IEEE80211_M_MONITOR:
739 		return (NL80211_IFTYPE_MONITOR);
740 		break;
741 	case IEEE80211_M_MBSS:
742 		return (NL80211_IFTYPE_MESH_POINT);
743 		break;
744 	case IEEE80211_M_AHDEMO:
745 		/* FALLTHROUGH */
746 	default:
747 		printf("ERROR: %s: unsupported opmode %d\n", __func__, opmode);
748 		/* FALLTHROUGH */
749 	}
750 	return (NL80211_IFTYPE_UNSPECIFIED);
751 }
752 
753 #ifdef LKPI_80211_HW_CRYPTO
754 static const char *
755 lkpi_cipher_suite_to_name(uint32_t wlan_cipher_suite)
756 {
757 
758 	switch (wlan_cipher_suite) {
759 	case WLAN_CIPHER_SUITE_WEP40:
760 		return ("WEP40");
761 	case WLAN_CIPHER_SUITE_TKIP:
762 		return ("TKIP");
763 	case WLAN_CIPHER_SUITE_CCMP:
764 		return ("CCMP");
765 	case WLAN_CIPHER_SUITE_WEP104:
766 		return ("WEP104");
767 	case WLAN_CIPHER_SUITE_AES_CMAC:
768 		return ("AES_CMAC");
769 	case WLAN_CIPHER_SUITE_GCMP:
770 		return ("GCMP");
771 	case WLAN_CIPHER_SUITE_GCMP_256:
772 		return ("GCMP_256");
773 	case WLAN_CIPHER_SUITE_CCMP_256:
774 		return ("CCMP_256");
775 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
776 		return ("BIP_GMAC_128");
777 	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
778 		return ("BIP_GMAC_256");
779 	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
780 		return ("BIP_CMAC_256");
781 	default:
782 		return ("??");
783 	}
784 }
785 
786 static uint32_t
787 lkpi_l80211_to_net80211_cyphers(uint32_t wlan_cipher_suite)
788 {
789 
790 	switch (wlan_cipher_suite) {
791 	case WLAN_CIPHER_SUITE_WEP40:
792 		return (IEEE80211_CRYPTO_WEP);
793 	case WLAN_CIPHER_SUITE_TKIP:
794 		return (IEEE80211_CRYPTO_TKIP);
795 	case WLAN_CIPHER_SUITE_CCMP:
796 		return (IEEE80211_CRYPTO_AES_CCM);
797 	case WLAN_CIPHER_SUITE_WEP104:
798 		return (IEEE80211_CRYPTO_WEP);
799 	case WLAN_CIPHER_SUITE_AES_CMAC:
800 	case WLAN_CIPHER_SUITE_GCMP:
801 	case WLAN_CIPHER_SUITE_GCMP_256:
802 	case WLAN_CIPHER_SUITE_CCMP_256:
803 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
804 	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
805 	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
806 		printf("%s: unsupported WLAN Cipher Suite %#08x | %u (%s)\n",
807 		    __func__,
808 		    wlan_cipher_suite >> 8, wlan_cipher_suite & 0xff,
809 		    lkpi_cipher_suite_to_name(wlan_cipher_suite));
810 		break;
811 	default:
812 		printf("%s: unknown WLAN Cipher Suite %#08x | %u (%s)\n",
813 		    __func__,
814 		    wlan_cipher_suite >> 8, wlan_cipher_suite & 0xff,
815 		    lkpi_cipher_suite_to_name(wlan_cipher_suite));
816 	}
817 
818 	return (0);
819 }
820 
821 static uint32_t
822 lkpi_net80211_to_l80211_cipher_suite(uint32_t cipher, uint8_t keylen)
823 {
824 
825 	switch (cipher) {
826 	case IEEE80211_CIPHER_TKIP:
827 		return (WLAN_CIPHER_SUITE_TKIP);
828 	case IEEE80211_CIPHER_AES_CCM:
829 		return (WLAN_CIPHER_SUITE_CCMP);
830 	case IEEE80211_CIPHER_WEP:
831 		if (keylen < 8)
832 			return (WLAN_CIPHER_SUITE_WEP40);
833 		else
834 			return (WLAN_CIPHER_SUITE_WEP104);
835 		break;
836 	case IEEE80211_CIPHER_AES_OCB:
837 	case IEEE80211_CIPHER_TKIPMIC:
838 	case IEEE80211_CIPHER_CKIP:
839 	case IEEE80211_CIPHER_NONE:
840 		printf("%s: unsupported cipher %#010x\n", __func__, cipher);
841 		break;
842 	default:
843 		printf("%s: unknown cipher %#010x\n", __func__, cipher);
844 	};
845 	return (0);
846 }
847 #endif
848 
849 #ifdef __notyet__
850 static enum ieee80211_sta_state
851 lkpi_net80211_state_to_sta_state(enum ieee80211_state state)
852 {
853 
854 	/*
855 	 * XXX-BZ The net80211 states are "try to ..", the lkpi8011 states are
856 	 * "done".  Also ASSOC/AUTHORIZED are both "RUN" then?
857 	 */
858 	switch (state) {
859 	case IEEE80211_S_INIT:
860 		return (IEEE80211_STA_NOTEXIST);
861 	case IEEE80211_S_SCAN:
862 		return (IEEE80211_STA_NONE);
863 	case IEEE80211_S_AUTH:
864 		return (IEEE80211_STA_AUTH);
865 	case IEEE80211_S_ASSOC:
866 		return (IEEE80211_STA_ASSOC);
867 	case IEEE80211_S_RUN:
868 		return (IEEE80211_STA_AUTHORIZED);
869 	case IEEE80211_S_CAC:
870 	case IEEE80211_S_CSA:
871 	case IEEE80211_S_SLEEP:
872 	default:
873 		UNIMPLEMENTED;
874 	};
875 
876 	return (IEEE80211_STA_NOTEXIST);
877 }
878 #endif
879 
880 static struct linuxkpi_ieee80211_channel *
881 lkpi_find_lkpi80211_chan(struct lkpi_hw *lhw,
882     struct ieee80211_channel *c)
883 {
884 	struct ieee80211_hw *hw;
885 	struct linuxkpi_ieee80211_channel *channels;
886 	enum nl80211_band band;
887 	int i, nchans;
888 
889 	hw = LHW_TO_HW(lhw);
890 	band = lkpi_net80211_chan_to_nl80211_band(c);
891 	if (hw->wiphy->bands[band] == NULL)
892 		return (NULL);
893 
894 	nchans = hw->wiphy->bands[band]->n_channels;
895 	if (nchans <= 0)
896 		return (NULL);
897 
898 	channels = hw->wiphy->bands[band]->channels;
899 	for (i = 0; i < nchans; i++) {
900 		if (channels[i].hw_value == c->ic_ieee)
901 			return (&channels[i]);
902 	}
903 
904 	return (NULL);
905 }
906 
907 #if 0
908 static struct linuxkpi_ieee80211_channel *
909 lkpi_get_lkpi80211_chan(struct ieee80211com *ic, struct ieee80211_node *ni)
910 {
911 	struct linuxkpi_ieee80211_channel *chan;
912 	struct ieee80211_channel *c;
913 	struct lkpi_hw *lhw;
914 
915 	chan = NULL;
916 	if (ni != NULL && ni->ni_chan != IEEE80211_CHAN_ANYC)
917 		c = ni->ni_chan;
918 	else if (ic->ic_bsschan != IEEE80211_CHAN_ANYC)
919 		c = ic->ic_bsschan;
920 	else if (ic->ic_curchan != IEEE80211_CHAN_ANYC)
921 		c = ic->ic_curchan;
922 	else
923 		c = NULL;
924 
925 	if (c != NULL && c != IEEE80211_CHAN_ANYC) {
926 		lhw = ic->ic_softc;
927 		chan = lkpi_find_lkpi80211_chan(lhw, c);
928 	}
929 
930 	return (chan);
931 }
932 #endif
933 
934 struct linuxkpi_ieee80211_channel *
935 linuxkpi_ieee80211_get_channel(struct wiphy *wiphy, uint32_t freq)
936 {
937 	enum nl80211_band band;
938 
939 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
940 		struct ieee80211_supported_band *supband;
941 		struct linuxkpi_ieee80211_channel *channels;
942 		int i;
943 
944 		supband = wiphy->bands[band];
945 		if (supband == NULL || supband->n_channels == 0)
946 			continue;
947 
948 		channels = supband->channels;
949 		for (i = 0; i < supband->n_channels; i++) {
950 			if (channels[i].center_freq == freq)
951 				return (&channels[i]);
952 		}
953 	}
954 
955 	return (NULL);
956 }
957 
958 #ifdef LKPI_80211_HW_CRYPTO
959 static int
960 lkpi_sta_del_keys(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
961     struct lkpi_sta *lsta)
962 {
963 	int error;
964 
965 	if (!lkpi_hwcrypto)
966 		return (0);
967 
968 	lockdep_assert_wiphy(hw->wiphy);
969 	ieee80211_ref_node(lsta->ni);
970 
971 	error = 0;
972 	for (ieee80211_keyix keyix = 0; keyix < nitems(lsta->kc); keyix++) {
973 		struct ieee80211_key_conf *kc;
974 		int err;
975 
976 		if (lsta->kc[keyix] == NULL)
977 			continue;
978 		kc = lsta->kc[keyix];
979 
980 		err = lkpi_80211_mo_set_key(hw, DISABLE_KEY, vif,
981 		    LSTA_TO_STA(lsta), kc);
982 		if (err != 0) {
983 			ic_printf(lsta->ni->ni_ic, "%s: set_key cmd %d(%s) for "
984 			    "sta %6D failed: %d\n", __func__, DISABLE_KEY,
985 			    "DISABLE", lsta->sta.addr, ":", err);
986 			error++;
987 
988 			/*
989 			 * If we free the key here we will never be able to get it
990 			 * removed from the driver/fw which will likely make us
991 			 * crash (firmware).
992 			 */
993 			continue;
994 		}
995 #ifdef LINUXKPI_DEBUG_80211
996 		if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
997 			ic_printf(lsta->ni->ni_ic, "%s: set_key cmd %d(%s) for "
998 			    "sta %6D succeeded: keyidx %u hw_key_idx %u flags %#10x\n",
999 			    __func__, DISABLE_KEY, "DISABLE", lsta->sta.addr, ":",
1000 			    kc->keyidx, kc->hw_key_idx, kc->flags);
1001 #endif
1002 
1003 		lsta->kc[keyix] = NULL;
1004 		free(kc, M_LKPI80211);
1005 	}
1006 	ieee80211_free_node(lsta->ni);
1007 	return (error);
1008 }
1009 
1010 static int
1011 _lkpi_iv_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
1012 {
1013 	struct ieee80211com *ic;
1014 	struct lkpi_hw *lhw;
1015 	struct ieee80211_hw *hw;
1016 	struct lkpi_vif *lvif;
1017 	struct lkpi_sta *lsta;
1018 	struct ieee80211_vif *vif;
1019 	struct ieee80211_sta *sta;
1020 	struct ieee80211_node *ni;
1021 	struct ieee80211_key_conf *kc;
1022 	struct ieee80211_node_table *nt;
1023 	int error;
1024 	bool islocked;
1025 
1026 	ic = vap->iv_ic;
1027 	lhw = ic->ic_softc;
1028 	hw = LHW_TO_HW(lhw);
1029 	lvif = VAP_TO_LVIF(vap);
1030 	vif = LVIF_TO_VIF(lvif);
1031 
1032 	if (vap->iv_bss == NULL) {
1033 		ic_printf(ic, "%s: iv_bss %p for vap %p is NULL\n",
1034 		    __func__, vap->iv_bss, vap);
1035 		return (0);
1036 	}
1037 	ni = ieee80211_ref_node(vap->iv_bss);
1038 	lsta = ni->ni_drv_data;
1039 	if (lsta == NULL) {
1040 		ic_printf(ic, "%s: ni %p (%6D) with lsta NULL\n",
1041 		    __func__, ni, ni->ni_bssid, ":");
1042 		ieee80211_free_node(ni);
1043 		return (0);
1044 	}
1045 	sta = LSTA_TO_STA(lsta);
1046 
1047 	if (lsta->kc[k->wk_keyix] == NULL) {
1048 #ifdef LINUXKPI_DEBUG_80211
1049 		if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1050 			ic_printf(ic, "%s: sta %6D and no key information, "
1051 			    "keyidx %u wk_macaddr %6D; returning success\n",
1052 			    __func__, sta->addr, ":",
1053 			    k->wk_keyix, k->wk_macaddr, ":");
1054 #endif
1055 		ieee80211_free_node(ni);
1056 		return (1);
1057 	}
1058 
1059 	/* This is inconsistent net80211 locking to be fixed one day. */
1060 	nt = &ic->ic_sta;
1061 	islocked = IEEE80211_NODE_IS_LOCKED(nt);
1062 	if (islocked)
1063 		IEEE80211_NODE_UNLOCK(nt);
1064 
1065 	wiphy_lock(hw->wiphy);
1066 	kc = lsta->kc[k->wk_keyix];
1067 	/* Re-check under lock. */
1068 	if (kc == NULL) {
1069 #ifdef LINUXKPI_DEBUG_80211
1070 		if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1071 			ic_printf(ic, "%s: sta %6D and key information vanished, "
1072 			    "returning success\n", __func__, sta->addr, ":");
1073 #endif
1074 		error = 1;
1075 		goto out;
1076 	}
1077 
1078 	error = lkpi_80211_mo_set_key(hw, DISABLE_KEY, vif, sta, kc);
1079 	if (error != 0) {
1080 		ic_printf(ic, "%s: set_key cmd %d(%s) for sta %6D failed: %d\n",
1081 		    __func__, DISABLE_KEY, "DISABLE", sta->addr, ":", error);
1082 		error = 0;
1083 		goto out;
1084 	}
1085 
1086 #ifdef LINUXKPI_DEBUG_80211
1087 	if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1088 		ic_printf(ic, "%s: set_key cmd %d(%s) for sta %6D succeeded: "
1089 		    "keyidx %u hw_key_idx %u flags %#10x\n", __func__,
1090 		    DISABLE_KEY, "DISABLE", sta->addr, ":",
1091 		    kc->keyidx, kc->hw_key_idx, kc->flags);
1092 #endif
1093 	lsta->kc[k->wk_keyix] = NULL;
1094 	free(kc, M_LKPI80211);
1095 	error = 1;
1096 out:
1097 	wiphy_unlock(hw->wiphy);
1098 	if (islocked)
1099 		IEEE80211_NODE_LOCK(nt);
1100 	ieee80211_free_node(ni);
1101 	return (error);
1102 }
1103 
1104 static int
1105 lkpi_iv_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
1106 {
1107 
1108 	/* XXX-BZ one day we should replace this iterating over VIFs, or node list? */
1109 	/* See also lkpi_sta_del_keys() these days. */
1110 	return (_lkpi_iv_key_delete(vap, k));
1111 }
1112 
1113 static int
1114 _lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
1115 {
1116 	struct ieee80211com *ic;
1117 	struct lkpi_hw *lhw;
1118 	struct ieee80211_hw *hw;
1119 	struct lkpi_vif *lvif;
1120 	struct lkpi_sta *lsta;
1121 	struct ieee80211_vif *vif;
1122 	struct ieee80211_sta *sta;
1123 	struct ieee80211_node *ni;
1124 	struct ieee80211_key_conf *kc;
1125 	uint32_t lcipher;
1126 	int error;
1127 
1128 	ic = vap->iv_ic;
1129 	lhw = ic->ic_softc;
1130 	hw = LHW_TO_HW(lhw);
1131 	lvif = VAP_TO_LVIF(vap);
1132 	vif = LVIF_TO_VIF(lvif);
1133 
1134 	if (vap->iv_bss == NULL) {
1135 		ic_printf(ic, "%s: iv_bss %p for vap %p is NULL\n",
1136 		    __func__, vap->iv_bss, vap);
1137 		return (0);
1138 	}
1139 	ni = ieee80211_ref_node(vap->iv_bss);
1140 	lsta = ni->ni_drv_data;
1141 	if (lsta == NULL) {
1142 		ic_printf(ic, "%s: ni %p (%6D) with lsta NULL\n",
1143 		    __func__, ni, ni->ni_bssid, ":");
1144 		ieee80211_free_node(ni);
1145 		return (0);
1146 	}
1147 	sta = LSTA_TO_STA(lsta);
1148 
1149 	wiphy_lock(hw->wiphy);
1150 	if (lsta->kc[k->wk_keyix] != NULL) {
1151 		IMPROVE("Still in firmware? Del first. Can we assert this cannot happen?");
1152 		ic_printf(ic, "%s: sta %6D found with key information\n",
1153 		    __func__, sta->addr, ":");
1154 		kc = lsta->kc[k->wk_keyix];
1155 		lsta->kc[k->wk_keyix] = NULL;
1156 		free(kc, M_LKPI80211);
1157 		kc = NULL;	/* safeguard */
1158 	}
1159 
1160 	lcipher = lkpi_net80211_to_l80211_cipher_suite(
1161 	    k->wk_cipher->ic_cipher, k->wk_keylen);
1162 	switch (lcipher) {
1163 	case WLAN_CIPHER_SUITE_CCMP:
1164 		break;
1165 	case WLAN_CIPHER_SUITE_TKIP:
1166 	default:
1167 		ic_printf(ic, "%s: CIPHER SUITE %#x (%s) not supported\n",
1168 		    __func__, lcipher, lkpi_cipher_suite_to_name(lcipher));
1169 		IMPROVE();
1170 		wiphy_unlock(hw->wiphy);
1171 		ieee80211_free_node(ni);
1172 		return (0);
1173 	}
1174 
1175 	kc = malloc(sizeof(*kc) + k->wk_keylen, M_LKPI80211, M_WAITOK | M_ZERO);
1176 	kc->_k = k;		/* Save the pointer to net80211. */
1177 	atomic64_set(&kc->tx_pn, k->wk_keytsc);
1178 	kc->cipher = lcipher;
1179 	kc->keyidx = k->wk_keyix;
1180 #if 0
1181 	kc->hw_key_idx = /* set by hw and needs to be passed for TX */;
1182 #endif
1183 	atomic64_set(&kc->tx_pn, k->wk_keytsc);
1184 	kc->keylen = k->wk_keylen;
1185 	memcpy(kc->key, k->wk_key, k->wk_keylen);
1186 
1187 	if (k->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV))
1188 		kc->flags |= IEEE80211_KEY_FLAG_PAIRWISE;
1189 	if (k->wk_flags & IEEE80211_KEY_GROUP)
1190 		kc->flags &= ~IEEE80211_KEY_FLAG_PAIRWISE;
1191 
1192 	switch (kc->cipher) {
1193 	case WLAN_CIPHER_SUITE_CCMP:
1194 		kc->iv_len = k->wk_cipher->ic_header;
1195 		kc->icv_len = k->wk_cipher->ic_trailer;
1196 		break;
1197 	case WLAN_CIPHER_SUITE_TKIP:
1198 	default:
1199 		/* currently UNREACH */
1200 		IMPROVE();
1201 		break;
1202 	};
1203 	lsta->kc[k->wk_keyix] = kc;
1204 
1205 	error = lkpi_80211_mo_set_key(hw, SET_KEY, vif, sta, kc);
1206 	if (error != 0) {
1207 		ic_printf(ic, "%s: set_key cmd %d(%s) for sta %6D failed: %d\n",
1208 		    __func__, SET_KEY, "SET", sta->addr, ":", error);
1209 		lsta->kc[k->wk_keyix] = NULL;
1210 		free(kc, M_LKPI80211);
1211 		wiphy_unlock(hw->wiphy);
1212 		ieee80211_free_node(ni);
1213 		return (0);
1214 	}
1215 
1216 #ifdef LINUXKPI_DEBUG_80211
1217 	if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1218 		ic_printf(ic, "%s: set_key cmd %d(%s) for sta %6D succeeded: "
1219 		    "kc %p keyidx %u hw_key_idx %u flags %#010x\n", __func__,
1220 		    SET_KEY, "SET", sta->addr, ":",
1221 		    kc, kc->keyidx, kc->hw_key_idx, kc->flags);
1222 #endif
1223 
1224 	wiphy_unlock(hw->wiphy);
1225 	ieee80211_free_node(ni);
1226 	return (1);
1227 }
1228 
1229 static  int
1230 lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
1231 {
1232 
1233 	return (_lkpi_iv_key_set(vap, k));
1234 }
1235 #endif
1236 
1237 static u_int
1238 lkpi_ic_update_mcast_copy(void *arg, struct sockaddr_dl *sdl, u_int cnt)
1239 {
1240 	struct netdev_hw_addr_list *mc_list;
1241 	struct netdev_hw_addr *addr;
1242 
1243 	KASSERT(arg != NULL && sdl != NULL, ("%s: arg %p sdl %p cnt %u\n",
1244 	    __func__, arg, sdl, cnt));
1245 
1246 	mc_list = arg;
1247 	/* If it is on the list already skip it. */
1248 	netdev_hw_addr_list_for_each(addr, mc_list) {
1249 		if (!memcmp(addr->addr, LLADDR(sdl), sdl->sdl_alen))
1250 			return (0);
1251 	}
1252 
1253 	addr = malloc(sizeof(*addr), M_LKPI80211, M_NOWAIT | M_ZERO);
1254 	if (addr == NULL)
1255 		return (0);
1256 
1257 	INIT_LIST_HEAD(&addr->addr_list);
1258 	memcpy(addr->addr, LLADDR(sdl), sdl->sdl_alen);
1259 	/* XXX this should be a netdev function? */
1260 	list_add(&addr->addr_list, &mc_list->addr_list);
1261 	mc_list->count++;
1262 
1263 #ifdef LINUXKPI_DEBUG_80211
1264 	if (linuxkpi_debug_80211 & D80211_TRACE)
1265 		printf("%s:%d: mc_list count %d: added %6D\n",
1266 		    __func__, __LINE__, mc_list->count, addr->addr, ":");
1267 #endif
1268 
1269 	return (1);
1270 }
1271 
1272 static void
1273 lkpi_update_mcast_filter(struct ieee80211com *ic, bool force)
1274 {
1275 	struct lkpi_hw *lhw;
1276 	struct ieee80211_hw *hw;
1277 	struct netdev_hw_addr_list mc_list;
1278 	struct list_head *le, *next;
1279 	struct netdev_hw_addr *addr;
1280 	struct ieee80211vap *vap;
1281 	u64 mc;
1282 	unsigned int changed_flags, total_flags;
1283 
1284 	lhw = ic->ic_softc;
1285 
1286 	if (lhw->ops->prepare_multicast == NULL ||
1287 	    lhw->ops->configure_filter == NULL)
1288 		return;
1289 
1290 	if (!lhw->update_mc && !force)
1291 		return;
1292 
1293 	changed_flags = total_flags = 0;
1294 	mc_list.count = 0;
1295 	INIT_LIST_HEAD(&mc_list.addr_list);
1296 	if (ic->ic_allmulti == 0) {
1297 		TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
1298 			if_foreach_llmaddr(vap->iv_ifp,
1299 			    lkpi_ic_update_mcast_copy, &mc_list);
1300 	} else {
1301 		changed_flags |= FIF_ALLMULTI;
1302 	}
1303 
1304 	hw = LHW_TO_HW(lhw);
1305 	mc = lkpi_80211_mo_prepare_multicast(hw, &mc_list);
1306 	/*
1307 	 * XXX-BZ make sure to get this sorted what is a change,
1308 	 * what gets all set; what was already set?
1309 	 */
1310 	total_flags = changed_flags;
1311 	lkpi_80211_mo_configure_filter(hw, changed_flags, &total_flags, mc);
1312 
1313 #ifdef LINUXKPI_DEBUG_80211
1314 	if (linuxkpi_debug_80211 & D80211_TRACE)
1315 		printf("%s: changed_flags %#06x count %d total_flags %#010x\n",
1316 		    __func__, changed_flags, mc_list.count, total_flags);
1317 #endif
1318 
1319 	if (mc_list.count != 0) {
1320 		list_for_each_safe(le, next, &mc_list.addr_list) {
1321 			addr = list_entry(le, struct netdev_hw_addr, addr_list);
1322 			free(addr, M_LKPI80211);
1323 			mc_list.count--;
1324 		}
1325 	}
1326 	KASSERT(mc_list.count == 0, ("%s: mc_list %p count %d != 0\n",
1327 	    __func__, &mc_list, mc_list.count));
1328 }
1329 
1330 static enum ieee80211_bss_changed
1331 lkpi_update_dtim_tsf(struct ieee80211_vif *vif, struct ieee80211_node *ni,
1332     struct ieee80211vap *vap, const char *_f, int _l)
1333 {
1334 	enum ieee80211_bss_changed bss_changed;
1335 
1336 	bss_changed = 0;
1337 
1338 #ifdef LINUXKPI_DEBUG_80211
1339 	if (linuxkpi_debug_80211 & D80211_TRACE)
1340 		printf("%s:%d [%s:%d] assoc %d aid %d beacon_int %u "
1341 		    "dtim_period %u sync_dtim_count %u sync_tsf %ju "
1342 		    "sync_device_ts %u bss_changed %#010jx\n",
1343 			__func__, __LINE__, _f, _l,
1344 			vif->cfg.assoc, vif->cfg.aid,
1345 			vif->bss_conf.beacon_int, vif->bss_conf.dtim_period,
1346 			vif->bss_conf.sync_dtim_count,
1347 			(uintmax_t)vif->bss_conf.sync_tsf,
1348 			vif->bss_conf.sync_device_ts,
1349 			(uintmax_t)bss_changed);
1350 #endif
1351 
1352 	if (vif->bss_conf.beacon_int != ni->ni_intval) {
1353 		vif->bss_conf.beacon_int = ni->ni_intval;
1354 		/* iwlwifi FW bug workaround; iwl_mvm_mac_sta_state. */
1355 		if (vif->bss_conf.beacon_int < 16)
1356 			vif->bss_conf.beacon_int = 16;
1357 		bss_changed |= BSS_CHANGED_BEACON_INT;
1358 	}
1359 	if (vif->bss_conf.dtim_period != vap->iv_dtim_period &&
1360 	    vap->iv_dtim_period > 0) {
1361 		vif->bss_conf.dtim_period = vap->iv_dtim_period;
1362 		bss_changed |= BSS_CHANGED_BEACON_INFO;
1363 	}
1364 
1365 	vif->bss_conf.sync_dtim_count = vap->iv_dtim_count;
1366 	vif->bss_conf.sync_tsf = le64toh(ni->ni_tstamp.tsf);
1367 	/* vif->bss_conf.sync_device_ts = set in linuxkpi_ieee80211_rx. */
1368 
1369 #ifdef LINUXKPI_DEBUG_80211
1370 	if (linuxkpi_debug_80211 & D80211_TRACE)
1371 		printf("%s:%d [%s:%d] assoc %d aid %d beacon_int %u "
1372 		    "dtim_period %u sync_dtim_count %u sync_tsf %ju "
1373 		    "sync_device_ts %u bss_changed %#010jx\n",
1374 			__func__, __LINE__, _f, _l,
1375 			vif->cfg.assoc, vif->cfg.aid,
1376 			vif->bss_conf.beacon_int, vif->bss_conf.dtim_period,
1377 			vif->bss_conf.sync_dtim_count,
1378 			(uintmax_t)vif->bss_conf.sync_tsf,
1379 			vif->bss_conf.sync_device_ts,
1380 			(uintmax_t)bss_changed);
1381 #endif
1382 
1383 	return (bss_changed);
1384 }
1385 
1386 static void
1387 lkpi_stop_hw_scan(struct lkpi_hw *lhw, struct ieee80211_vif *vif)
1388 {
1389 	struct ieee80211_hw *hw;
1390 	int error;
1391 	bool cancel;
1392 
1393 	LKPI_80211_LHW_SCAN_LOCK(lhw);
1394 	cancel = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
1395 	LKPI_80211_LHW_SCAN_UNLOCK(lhw);
1396 	if (!cancel)
1397 		return;
1398 
1399 	hw = LHW_TO_HW(lhw);
1400 
1401 	IEEE80211_UNLOCK(lhw->ic);
1402 	LKPI_80211_LHW_LOCK(lhw);
1403 	/* Need to cancel the scan. */
1404 	lkpi_80211_mo_cancel_hw_scan(hw, vif);
1405 	LKPI_80211_LHW_UNLOCK(lhw);
1406 
1407 	/* Need to make sure we see ieee80211_scan_completed. */
1408 	LKPI_80211_LHW_SCAN_LOCK(lhw);
1409 	if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0)
1410 		error = msleep(lhw, &lhw->scan_mtx, 0, "lhwscanstop", hz/2);
1411 	cancel = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
1412 	LKPI_80211_LHW_SCAN_UNLOCK(lhw);
1413 
1414 	IEEE80211_LOCK(lhw->ic);
1415 
1416 	if (cancel)
1417 		ic_printf(lhw->ic, "%s: failed to cancel scan: %d (%p, %p)\n",
1418 		    __func__, error, lhw, vif);
1419 }
1420 
1421 static void
1422 lkpi_hw_conf_idle(struct ieee80211_hw *hw, bool new)
1423 {
1424 	struct lkpi_hw *lhw;
1425 	int error;
1426 	bool old;
1427 
1428 	old = hw->conf.flags & IEEE80211_CONF_IDLE;
1429 	if (old == new)
1430 		return;
1431 
1432 	hw->conf.flags ^= IEEE80211_CONF_IDLE;
1433 	error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_IDLE);
1434 	if (error != 0 && error != EOPNOTSUPP) {
1435 		lhw = HW_TO_LHW(hw);
1436 		ic_printf(lhw->ic, "ERROR: %s: config %#0x returned %d\n",
1437 		    __func__, IEEE80211_CONF_CHANGE_IDLE, error);
1438 	}
1439 }
1440 
1441 static enum ieee80211_bss_changed
1442 lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
1443     struct lkpi_hw *lhw)
1444 {
1445 	enum ieee80211_bss_changed changed;
1446 
1447 	changed = 0;
1448 	sta->aid = 0;
1449 	if (vif->cfg.assoc) {
1450 
1451 		lhw->update_mc = true;
1452 		lkpi_update_mcast_filter(lhw->ic, true);
1453 
1454 		vif->cfg.assoc = false;
1455 		vif->cfg.aid = 0;
1456 		changed |= BSS_CHANGED_ASSOC;
1457 		IMPROVE();
1458 
1459 		/*
1460 		 * Executing the bss_info_changed(BSS_CHANGED_ASSOC) with
1461 		 * assoc = false right away here will remove the sta from
1462 		 * firmware for iwlwifi.
1463 		 * We no longer do this but only return the BSS_CHNAGED value.
1464 		 * The caller is responsible for removing the sta gong to
1465 		 * IEEE80211_STA_NOTEXIST and then executing the
1466 		 * bss_info_changed() update.
1467 		 * See lkpi_sta_run_to_init() for more detailed comment.
1468 		 */
1469 	}
1470 
1471 	return (changed);
1472 }
1473 
1474 static void
1475 lkpi_wake_tx_queues(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
1476     bool dequeue_seen, bool no_emptyq)
1477 {
1478 	struct lkpi_txq *ltxq;
1479 	int tid;
1480 	bool ltxq_empty;
1481 
1482 	/* Wake up all queues to know they are allocated in the driver. */
1483 	for (tid = 0; tid < nitems(sta->txq); tid++) {
1484 
1485 		if (tid == IEEE80211_NUM_TIDS) {
1486 			IMPROVE("station specific?");
1487 			if (!ieee80211_hw_check(hw, STA_MMPDU_TXQ))
1488 				continue;
1489 		} else if (tid >= hw->queues)
1490 			continue;
1491 
1492 		if (sta->txq[tid] == NULL)
1493 			continue;
1494 
1495 		ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
1496 		if (dequeue_seen && !ltxq->seen_dequeue)
1497 			continue;
1498 
1499 		LKPI_80211_LTXQ_LOCK(ltxq);
1500 		ltxq_empty = skb_queue_empty(&ltxq->skbq);
1501 		LKPI_80211_LTXQ_UNLOCK(ltxq);
1502 		if (no_emptyq && ltxq_empty)
1503 			continue;
1504 
1505 		lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid]);
1506 	}
1507 }
1508 
1509 /*
1510  * On the way down from RUN -> ASSOC -> AUTH we may send a DISASSOC or DEAUTH
1511  * packet.  The problem is that the state machine functions tend to hold the
1512  * LHW lock which will prevent lkpi_80211_txq_tx_one() from sending the packet.
1513  * We call this after dropping the ic lock and before acquiring the LHW lock.
1514  * we make sure no further packets are queued and if they are queued the task
1515  * will finish or be cancelled.  At the end if a packet is left we manually
1516  * send it.  scan_to_auth() would re-enable sending if the lsta would be
1517  * re-used.
1518  */
1519 static void
1520 lkpi_80211_flush_tx(struct lkpi_hw *lhw, struct lkpi_sta *lsta)
1521 {
1522 	struct mbufq mq;
1523 	struct mbuf *m;
1524 	int len;
1525 
1526 	LKPI_80211_LHW_UNLOCK_ASSERT(lhw);
1527 
1528 	/* Do not accept any new packets until scan_to_auth or lsta_free(). */
1529 	LKPI_80211_LSTA_TXQ_LOCK(lsta);
1530 	lsta->txq_ready = false;
1531 	LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
1532 
1533 	while (taskqueue_cancel(taskqueue_thread, &lsta->txq_task, NULL) != 0)
1534 		taskqueue_drain(taskqueue_thread, &lsta->txq_task);
1535 
1536 	LKPI_80211_LSTA_TXQ_LOCK(lsta);
1537 	len = mbufq_len(&lsta->txq);
1538 	if (len <= 0) {
1539 		LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
1540 		return;
1541 	}
1542 
1543 	mbufq_init(&mq, IFQ_MAXLEN);
1544 	mbufq_concat(&mq, &lsta->txq);
1545 	LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
1546 
1547 	m = mbufq_dequeue(&mq);
1548 	while (m != NULL) {
1549 		lkpi_80211_txq_tx_one(lsta, m);
1550 		m = mbufq_dequeue(&mq);
1551 	}
1552 }
1553 
1554 /* -------------------------------------------------------------------------- */
1555 
1556 static int
1557 lkpi_sta_state_do_nada(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1558 {
1559 
1560 	return (0);
1561 }
1562 
1563 /* lkpi_iv_newstate() handles the stop scan case generally. */
1564 #define	lkpi_sta_scan_to_init(_v, _n, _a)	lkpi_sta_state_do_nada(_v, _n, _a)
1565 
1566 static int
1567 lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1568 {
1569 	struct linuxkpi_ieee80211_channel *chan;
1570 	struct lkpi_chanctx *lchanctx;
1571 	struct ieee80211_chanctx_conf *chanctx_conf;
1572 	struct lkpi_hw *lhw;
1573 	struct ieee80211_hw *hw;
1574 	struct lkpi_vif *lvif;
1575 	struct ieee80211_vif *vif;
1576 	struct ieee80211_node *ni;
1577 	struct lkpi_sta *lsta;
1578 	enum ieee80211_bss_changed bss_changed;
1579 	struct ieee80211_prep_tx_info prep_tx_info;
1580 	uint32_t changed;
1581 	int error;
1582 
1583 	/*
1584 	 * In here we use vap->iv_bss until lvif->lvif_bss is set.
1585 	 * For all later (STATE >= AUTH) functions we need to use the lvif
1586 	 * cache which will be tracked even through (*iv_update_bss)().
1587 	 */
1588 
1589 	if (vap->iv_bss == NULL) {
1590 		ic_printf(vap->iv_ic, "%s: no iv_bss for vap %p\n", __func__, vap);
1591 		return (EINVAL);
1592 	}
1593 	/*
1594 	 * Keep the ni alive locally.  In theory (and practice) iv_bss can change
1595 	 * once we unlock here.  This is due to net80211 allowing state changes
1596 	 * and new join1() despite having an active node as well as due to
1597 	 * the fact that the iv_bss can be swapped under the hood in (*iv_update_bss).
1598 	 */
1599 	ni = ieee80211_ref_node(vap->iv_bss);
1600 	if (ni->ni_chan == NULL || ni->ni_chan == IEEE80211_CHAN_ANYC) {
1601 		ic_printf(vap->iv_ic, "%s: no channel set for iv_bss ni %p "
1602 		    "on vap %p\n", __func__, ni, vap);
1603 		ieee80211_free_node(ni);	/* Error handling for the local ni. */
1604 		return (EINVAL);
1605 	}
1606 
1607 	lhw = vap->iv_ic->ic_softc;
1608 	chan = lkpi_find_lkpi80211_chan(lhw, ni->ni_chan);
1609 	if (chan == NULL) {
1610 		ic_printf(vap->iv_ic, "%s: failed to get LKPI channel from "
1611 		    "iv_bss ni %p on vap %p\n", __func__, ni, vap);
1612 		ieee80211_free_node(ni);	/* Error handling for the local ni. */
1613 		return (ESRCH);
1614 	}
1615 
1616 	hw = LHW_TO_HW(lhw);
1617 	lvif = VAP_TO_LVIF(vap);
1618 	vif = LVIF_TO_VIF(lvif);
1619 
1620 	LKPI_80211_LVIF_LOCK(lvif);
1621 	/* XXX-BZ KASSERT later? */
1622 	if (lvif->lvif_bss_synched || lvif->lvif_bss != NULL) {
1623 		ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
1624 		    "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
1625 		    lvif, vap, vap->iv_bss, lvif->lvif_bss,
1626 		    (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
1627 		    lvif->lvif_bss_synched);
1628 		LKPI_80211_LVIF_UNLOCK(lvif);
1629 		ieee80211_free_node(ni);	/* Error handling for the local ni. */
1630 		return (EBUSY);
1631 	}
1632 	LKPI_80211_LVIF_UNLOCK(lvif);
1633 
1634 	IEEE80211_UNLOCK(vap->iv_ic);
1635 	LKPI_80211_LHW_LOCK(lhw);
1636 
1637 	/* Add chanctx (or if exists, change it). */
1638 	if (vif->chanctx_conf != NULL) {
1639 		chanctx_conf = vif->chanctx_conf;
1640 		lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
1641 		IMPROVE("diff changes for changed, working on live copy, rcu");
1642 	} else {
1643 		/* Keep separate alloc as in Linux this is rcu managed? */
1644 		lchanctx = malloc(sizeof(*lchanctx) + hw->chanctx_data_size,
1645 		    M_LKPI80211, M_WAITOK | M_ZERO);
1646 		chanctx_conf = &lchanctx->chanctx_conf;
1647 	}
1648 
1649 	chanctx_conf->rx_chains_dynamic = 1;
1650 	chanctx_conf->rx_chains_static = 1;
1651 	chanctx_conf->radar_enabled =
1652 	    (chan->flags & IEEE80211_CHAN_RADAR) ? true : false;
1653 	chanctx_conf->def.chan = chan;
1654 	chanctx_conf->def.width = NL80211_CHAN_WIDTH_20_NOHT;
1655 	chanctx_conf->def.center_freq1 = chan->center_freq;
1656 	chanctx_conf->def.center_freq2 = 0;
1657 	IMPROVE("Check vht_cap from band not just chan?");
1658 	KASSERT(ni->ni_chan != NULL && ni->ni_chan != IEEE80211_CHAN_ANYC,
1659 	   ("%s:%d: ni %p ni_chan %p\n", __func__, __LINE__, ni, ni->ni_chan));
1660 #ifdef LKPI_80211_HT
1661 	if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) {
1662 		if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) {
1663 			chanctx_conf->def.width = NL80211_CHAN_WIDTH_40;
1664 		} else
1665 			chanctx_conf->def.width = NL80211_CHAN_WIDTH_20;
1666 	}
1667 #endif
1668 #ifdef LKPI_80211_VHT
1669 	if (IEEE80211_IS_CHAN_VHT(ni->ni_chan)) {
1670 #ifdef __notyet__
1671 		if (IEEE80211_IS_CHAN_VHT80P80(ni->ni_chan)) {
1672 			chanctx_conf->def.width = NL80211_CHAN_WIDTH_80P80;
1673 			chanctx_conf->def.center_freq2 = 0;	/* XXX */
1674 		} else
1675 #endif
1676 		if (IEEE80211_IS_CHAN_VHT160(ni->ni_chan))
1677 			chanctx_conf->def.width = NL80211_CHAN_WIDTH_160;
1678 		else if (IEEE80211_IS_CHAN_VHT80(ni->ni_chan))
1679 			chanctx_conf->def.width = NL80211_CHAN_WIDTH_80;
1680 	}
1681 #endif
1682 	/* Responder ... */
1683 	chanctx_conf->min_def.chan = chan;
1684 	chanctx_conf->min_def.width = NL80211_CHAN_WIDTH_20_NOHT;
1685 	chanctx_conf->min_def.center_freq1 = chan->center_freq;
1686 	chanctx_conf->min_def.center_freq2 = 0;
1687 	IMPROVE("currently 20_NOHT min_def only");
1688 
1689 	/* Set bss info (bss_info_changed). */
1690 	bss_changed = 0;
1691 	vif->bss_conf.bssid = ni->ni_bssid;
1692 	bss_changed |= BSS_CHANGED_BSSID;
1693 	vif->bss_conf.txpower = ni->ni_txpower;
1694 	bss_changed |= BSS_CHANGED_TXPOWER;
1695 	vif->cfg.idle = false;
1696 	bss_changed |= BSS_CHANGED_IDLE;
1697 
1698 	/* vif->bss_conf.basic_rates ? Where exactly? */
1699 
1700 	/* Should almost assert it is this. */
1701 	vif->cfg.assoc = false;
1702 	vif->cfg.aid = 0;
1703 
1704 	bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__);
1705 
1706 	error = 0;
1707 	if (vif->chanctx_conf != NULL) {
1708 		changed = IEEE80211_CHANCTX_CHANGE_MIN_WIDTH;
1709 		changed |= IEEE80211_CHANCTX_CHANGE_RADAR;
1710 		changed |= IEEE80211_CHANCTX_CHANGE_RX_CHAINS;
1711 		changed |= IEEE80211_CHANCTX_CHANGE_WIDTH;
1712 		lkpi_80211_mo_change_chanctx(hw, chanctx_conf, changed);
1713 	} else {
1714 		error = lkpi_80211_mo_add_chanctx(hw, chanctx_conf);
1715 		if (error == 0 || error == EOPNOTSUPP) {
1716 			vif->bss_conf.chanreq.oper.chan = chanctx_conf->def.chan;
1717 			vif->bss_conf.chanreq.oper.width = chanctx_conf->def.width;
1718 			vif->bss_conf.chanreq.oper.center_freq1 =
1719 			    chanctx_conf->def.center_freq1;
1720 #ifdef LKPI_80211_HT
1721 			if (vif->bss_conf.chanreq.oper.width == NL80211_CHAN_WIDTH_40) {
1722 				/* Note: it is 10 not 20. */
1723 				if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan))
1724 					vif->bss_conf.chanreq.oper.center_freq1 += 10;
1725 				else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan))
1726 					vif->bss_conf.chanreq.oper.center_freq1 -= 10;
1727 			}
1728 #endif
1729 			vif->bss_conf.chanreq.oper.center_freq2 =
1730 			    chanctx_conf->def.center_freq2;
1731 		} else {
1732 			ic_printf(vap->iv_ic, "%s:%d: mo_add_chanctx "
1733 			    "failed: %d\n", __func__, __LINE__, error);
1734 			goto out;
1735 		}
1736 
1737 		vif->bss_conf.chanctx_conf = chanctx_conf;
1738 
1739 		/* Assign vif chanctx. */
1740 		if (error == 0)
1741 			error = lkpi_80211_mo_assign_vif_chanctx(hw, vif,
1742 			    &vif->bss_conf, chanctx_conf);
1743 		if (error == EOPNOTSUPP)
1744 			error = 0;
1745 		if (error != 0) {
1746 			ic_printf(vap->iv_ic, "%s:%d: mo_assign_vif_chanctx "
1747 			    "failed: %d\n", __func__, __LINE__, error);
1748 			lkpi_80211_mo_remove_chanctx(hw, chanctx_conf);
1749 			lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
1750 			free(lchanctx, M_LKPI80211);
1751 			goto out;
1752 		}
1753 	}
1754 	IMPROVE("update radiotap chan fields too");
1755 
1756 	/* RATES */
1757 	IMPROVE("bss info: not all needs to come now and rates are missing");
1758 	lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
1759 
1760 	/*
1761 	 * Given ni and lsta are 1:1 from alloc to free we can assert that
1762 	 * ni always has lsta data attach despite net80211 node swapping
1763 	 * under the hoods.
1764 	 */
1765 	KASSERT(ni->ni_drv_data != NULL, ("%s: ni %p ni_drv_data %p\n",
1766 	    __func__, ni, ni->ni_drv_data));
1767 	lsta = ni->ni_drv_data;
1768 
1769 	/*
1770 	 * Make sure in case the sta did not change and we re-add it,
1771 	 * that we can tx again.
1772 	 */
1773 	LKPI_80211_LSTA_TXQ_LOCK(lsta);
1774 	lsta->txq_ready = true;
1775 	LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
1776 
1777 	wiphy_lock(hw->wiphy);
1778 	/* Insert the [l]sta into the list of known stations. */
1779 	list_add_tail(&lsta->lsta_list, &lvif->lsta_list);
1780 	wiphy_unlock(hw->wiphy);
1781 
1782 	/* Add (or adjust) sta and change state (from NOTEXIST) to NONE. */
1783 	KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
1784 	KASSERT(lsta->state == IEEE80211_STA_NOTEXIST, ("%s: lsta %p state not "
1785 	    "NOTEXIST: %#x\n", __func__, lsta, lsta->state));
1786 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NONE);
1787 	if (error != 0) {
1788 		IMPROVE("do we need to undo the chan ctx?");
1789 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NONE) "
1790 		    "failed: %d\n", __func__, __LINE__, error);
1791 		goto out;
1792 	}
1793 #if 0
1794 	lsta->added_to_drv = true;	/* mo manages. */
1795 #endif
1796 
1797 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
1798 
1799 #if 0
1800 	/*
1801 	 * Wakeup all queues now that sta is there so we have as much time to
1802 	 * possibly prepare the queue in the driver to be ready for the 1st
1803 	 * packet;  lkpi_80211_txq_tx_one() still has a workaround as there
1804 	 * is no guarantee or way to check.
1805 	 * XXX-BZ and by now we know that this does not work on all drivers
1806 	 * for all queues.
1807 	 */
1808 	lkpi_wake_tx_queues(hw, LSTA_TO_STA(lsta), false, false);
1809 #endif
1810 
1811 	/* Start mgd_prepare_tx. */
1812 	memset(&prep_tx_info, 0, sizeof(prep_tx_info));
1813 	prep_tx_info.duration = PREP_TX_INFO_DURATION;
1814 	lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
1815 	lsta->in_mgd = true;
1816 
1817 	/*
1818 	 * What is going to happen next:
1819 	 * - <twiddle> .. we should end up in "auth_to_assoc"
1820 	 * - event_callback
1821 	 * - update sta_state (NONE to AUTH)
1822 	 * - mgd_complete_tx
1823 	 * (ideally we'd do that on a callback for something else ...)
1824 	 */
1825 
1826 	LKPI_80211_LHW_UNLOCK(lhw);
1827 	IEEE80211_LOCK(vap->iv_ic);
1828 
1829 	LKPI_80211_LVIF_LOCK(lvif);
1830 	/* Re-check given (*iv_update_bss) could have happened while we were unlocked. */
1831 	if (lvif->lvif_bss_synched || lvif->lvif_bss != NULL ||
1832 	    lsta->ni != vap->iv_bss)
1833 		ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
1834 		    "lvif_bss->ni %p synched %d, ni %p lsta %p\n", __func__, __LINE__,
1835 		    lvif, vap, vap->iv_bss, lvif->lvif_bss,
1836 		    (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
1837 		    lvif->lvif_bss_synched, ni, lsta);
1838 
1839 	/*
1840 	 * Reference the "ni" for caching the lsta/ni in lvif->lvif_bss.
1841 	 * Given we cache lsta we use lsta->ni instead of ni here (even though
1842 	 * lsta->ni == ni) to be distinct from the rest of the code where we do
1843 	 * assume that ni == vap->iv_bss which it may or may not be.
1844 	 * So do NOT use iv_bss here anymore as that may have diverged from our
1845 	 * function local ni already while ic was unlocked and would lead to
1846 	 * inconsistencies.  Go and see if we lost a race and do not update
1847 	 * lvif_bss_synched in that case.
1848 	 */
1849 	ieee80211_ref_node(lsta->ni);
1850 	lvif->lvif_bss = lsta;
1851 	if (lsta->ni == vap->iv_bss) {
1852 		lvif->lvif_bss_synched = true;
1853 	} else {
1854 		/* Set to un-synched no matter what. */
1855 		lvif->lvif_bss_synched = false;
1856 		/*
1857 		 * We do not error as someone has to take us down.
1858 		 * If we are followed by a 2nd, new net80211::join1() going to
1859 		 * AUTH lkpi_sta_a_to_a() will error, lkpi_sta_auth_to_{scan,init}()
1860 		 * will take the lvif->lvif_bss node down eventually.
1861 		 * What happens with the vap->iv_bss node will entirely be up
1862 		 * to net80211 as we never used the node beyond alloc()/free()
1863 		 * and we do not hold an extra reference for that anymore given
1864 		 * ni : lsta == 1:1.
1865 		 */
1866 	}
1867 	LKPI_80211_LVIF_UNLOCK(lvif);
1868 	goto out_relocked;
1869 
1870 out:
1871 	LKPI_80211_LHW_UNLOCK(lhw);
1872 	IEEE80211_LOCK(vap->iv_ic);
1873 out_relocked:
1874 	/*
1875 	 * Release the reference that kept the ni stable locally
1876 	 * during the work of this function.
1877 	 */
1878 	if (ni != NULL)
1879 		ieee80211_free_node(ni);
1880 	return (error);
1881 }
1882 
1883 static int
1884 lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1885 {
1886 	struct lkpi_hw *lhw;
1887 	struct ieee80211_hw *hw;
1888 	struct lkpi_vif *lvif;
1889 	struct ieee80211_vif *vif;
1890 	struct ieee80211_node *ni;
1891 	struct lkpi_sta *lsta;
1892 	struct ieee80211_sta *sta;
1893 	struct ieee80211_prep_tx_info prep_tx_info;
1894 	int error;
1895 
1896 	lhw = vap->iv_ic->ic_softc;
1897 	hw = LHW_TO_HW(lhw);
1898 	lvif = VAP_TO_LVIF(vap);
1899 	vif = LVIF_TO_VIF(lvif);
1900 
1901 	LKPI_80211_LVIF_LOCK(lvif);
1902 #ifdef LINUXKPI_DEBUG_80211
1903 	/* XXX-BZ KASSERT later; state going down so no action. */
1904 	if (lvif->lvif_bss == NULL)
1905 		ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
1906 		    "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
1907 		    lvif, vap, vap->iv_bss, lvif->lvif_bss,
1908 		    (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
1909 		    lvif->lvif_bss_synched);
1910 #endif
1911 
1912 	lsta = lvif->lvif_bss;
1913 	LKPI_80211_LVIF_UNLOCK(lvif);
1914 	KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
1915 	    "lvif %p vap %p\n", __func__,
1916 	    lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
1917 	ni = lsta->ni;			/* Reference held for lvif_bss. */
1918 	sta = LSTA_TO_STA(lsta);
1919 
1920 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
1921 
1922 	IEEE80211_UNLOCK(vap->iv_ic);
1923 	LKPI_80211_LHW_LOCK(lhw);
1924 
1925 	/* flush, drop. */
1926 	lkpi_80211_mo_flush(hw, vif,  nitems(sta->txq), true);
1927 
1928 	/* Wake tx queues to get packet(s) out. */
1929 	lkpi_wake_tx_queues(hw, sta, false, true);
1930 
1931 	/* flush, no drop */
1932 	lkpi_80211_mo_flush(hw, vif,  nitems(sta->txq), false);
1933 
1934 	/* End mgd_complete_tx. */
1935 	if (lsta->in_mgd) {
1936 		memset(&prep_tx_info, 0, sizeof(prep_tx_info));
1937 		prep_tx_info.success = false;
1938 		lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
1939 		lsta->in_mgd = false;
1940 	}
1941 
1942 	/* sync_rx_queues */
1943 	lkpi_80211_mo_sync_rx_queues(hw);
1944 
1945 	/* sta_pre_rcu_remove */
1946         lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta);
1947 
1948 	/* Take the station down. */
1949 
1950 	/* Adjust sta and change state (from NONE) to NOTEXIST. */
1951 	KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
1952 	KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not "
1953 	    "NONE: %#x, nstate %d arg %d\n", __func__, lsta, lsta->state, nstate, arg));
1954 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NOTEXIST);
1955 	if (error != 0) {
1956 		IMPROVE("do we need to undo the chan ctx?");
1957 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NOTEXIST) "
1958 		    "failed: %d\n", __func__, __LINE__, error);
1959 		goto out;
1960 	}
1961 #if 0
1962 	lsta->added_to_drv = false;	/* mo manages. */
1963 #endif
1964 
1965 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
1966 
1967 	LKPI_80211_LVIF_LOCK(lvif);
1968 	/* Remove ni reference for this cache of lsta. */
1969 	lvif->lvif_bss = NULL;
1970 	lvif->lvif_bss_synched = false;
1971 	LKPI_80211_LVIF_UNLOCK(lvif);
1972 	lkpi_lsta_remove(lsta, lvif);
1973 	/*
1974 	 * The very last release the reference on the ni for the ni/lsta on
1975 	 * lvif->lvif_bss.  Upon return from this both ni and lsta are invalid
1976 	 * and potentially freed.
1977 	 */
1978 	ieee80211_free_node(ni);
1979 
1980 	/* conf_tx */
1981 
1982 	/* Take the chan ctx down. */
1983 	if (vif->chanctx_conf != NULL) {
1984 		struct lkpi_chanctx *lchanctx;
1985 		struct ieee80211_chanctx_conf *chanctx_conf;
1986 
1987 		chanctx_conf = vif->chanctx_conf;
1988 		/* Remove vif context. */
1989 		lkpi_80211_mo_unassign_vif_chanctx(hw, vif, &vif->bss_conf, &vif->chanctx_conf);
1990 		/* NB: vif->chanctx_conf is NULL now. */
1991 
1992 		lkpi_hw_conf_idle(hw, true);
1993 
1994 		/* Remove chan ctx. */
1995 		lkpi_80211_mo_remove_chanctx(hw, chanctx_conf);
1996 		lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
1997 		free(lchanctx, M_LKPI80211);
1998 	}
1999 
2000 out:
2001 	LKPI_80211_LHW_UNLOCK(lhw);
2002 	IEEE80211_LOCK(vap->iv_ic);
2003 	return (error);
2004 }
2005 
2006 static int
2007 lkpi_sta_auth_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2008 {
2009 	int error;
2010 
2011 	error = lkpi_sta_auth_to_scan(vap, nstate, arg);
2012 	if (error == 0)
2013 		error = lkpi_sta_scan_to_init(vap, nstate, arg);
2014 	return (error);
2015 }
2016 
2017 static int
2018 lkpi_sta_auth_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2019 {
2020 	struct lkpi_hw *lhw;
2021 	struct ieee80211_hw *hw;
2022 	struct lkpi_vif *lvif;
2023 	struct ieee80211_vif *vif;
2024 	struct lkpi_sta *lsta;
2025 	struct ieee80211_prep_tx_info prep_tx_info;
2026 	int error;
2027 
2028 	lhw = vap->iv_ic->ic_softc;
2029 	hw = LHW_TO_HW(lhw);
2030 	lvif = VAP_TO_LVIF(vap);
2031 	vif = LVIF_TO_VIF(lvif);
2032 
2033 	IEEE80211_UNLOCK(vap->iv_ic);
2034 	LKPI_80211_LHW_LOCK(lhw);
2035 
2036 	LKPI_80211_LVIF_LOCK(lvif);
2037 	/* XXX-BZ KASSERT later? */
2038 	if (!lvif->lvif_bss_synched || lvif->lvif_bss == NULL) {
2039 #ifdef LINUXKPI_DEBUG_80211
2040 		ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2041 		    "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2042 		    lvif, vap, vap->iv_bss, lvif->lvif_bss,
2043 		    (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2044 		    lvif->lvif_bss_synched);
2045 #endif
2046 		error = ENOTRECOVERABLE;
2047 		LKPI_80211_LVIF_UNLOCK(lvif);
2048 		goto out;
2049 	}
2050 	lsta = lvif->lvif_bss;
2051 	LKPI_80211_LVIF_UNLOCK(lvif);
2052 
2053 	KASSERT(lsta != NULL, ("%s: lsta %p\n", __func__, lsta));
2054 
2055 	/* Finish auth. */
2056 	IMPROVE("event callback");
2057 
2058 	/* Update sta_state (NONE to AUTH). */
2059 	KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not "
2060 	    "NONE: %#x\n", __func__, lsta, lsta->state));
2061 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_AUTH);
2062 	if (error != 0) {
2063 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(AUTH) "
2064 		    "failed: %d\n", __func__, __LINE__, error);
2065 		goto out;
2066 	}
2067 
2068 	/* End mgd_complete_tx. */
2069 	if (lsta->in_mgd) {
2070 		memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2071 		prep_tx_info.success = true;
2072 		lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
2073 		lsta->in_mgd = false;
2074 	}
2075 
2076 	/* Now start assoc. */
2077 
2078 	/* Start mgd_prepare_tx. */
2079 	if (!lsta->in_mgd) {
2080 		memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2081 		prep_tx_info.duration = PREP_TX_INFO_DURATION;
2082 		lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
2083 		lsta->in_mgd = true;
2084 	}
2085 
2086 	/* Wake tx queue to get packet out. */
2087 	lkpi_wake_tx_queues(hw, LSTA_TO_STA(lsta), false, true);
2088 
2089 	/*
2090 	 * <twiddle> .. we end up in "assoc_to_run"
2091 	 * - update sta_state (AUTH to ASSOC)
2092 	 * - conf_tx [all]
2093 	 * - bss_info_changed (assoc, aid, ssid, ..)
2094 	 * - change_chanctx (if needed)
2095 	 * - event_callback
2096 	 * - mgd_complete_tx
2097 	 */
2098 
2099 out:
2100 	LKPI_80211_LHW_UNLOCK(lhw);
2101 	IEEE80211_LOCK(vap->iv_ic);
2102 	return (error);
2103 }
2104 
2105 /* auth_to_auth, assoc_to_assoc. */
2106 static int
2107 lkpi_sta_a_to_a(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2108 {
2109 	struct lkpi_hw *lhw;
2110 	struct ieee80211_hw *hw;
2111 	struct lkpi_vif *lvif;
2112 	struct ieee80211_vif *vif;
2113 	struct lkpi_sta *lsta;
2114 	struct ieee80211_prep_tx_info prep_tx_info;
2115 	int error;
2116 
2117 	lhw = vap->iv_ic->ic_softc;
2118 	hw = LHW_TO_HW(lhw);
2119 	lvif = VAP_TO_LVIF(vap);
2120 	vif = LVIF_TO_VIF(lvif);
2121 
2122 	IEEE80211_UNLOCK(vap->iv_ic);
2123 	LKPI_80211_LHW_LOCK(lhw);
2124 
2125 	LKPI_80211_LVIF_LOCK(lvif);
2126 	/* XXX-BZ KASSERT later? */
2127 	if (!lvif->lvif_bss_synched || lvif->lvif_bss == NULL) {
2128 #ifdef LINUXKPI_DEBUG_80211
2129 		ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2130 		    "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2131 		    lvif, vap, vap->iv_bss, lvif->lvif_bss,
2132 		    (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2133 		    lvif->lvif_bss_synched);
2134 #endif
2135 		LKPI_80211_LVIF_UNLOCK(lvif);
2136 		error = ENOTRECOVERABLE;
2137 		goto out;
2138 	}
2139 	lsta = lvif->lvif_bss;
2140 	LKPI_80211_LVIF_UNLOCK(lvif);
2141 
2142 	KASSERT(lsta != NULL, ("%s: lsta %p! lvif %p vap %p\n", __func__,
2143 	    lsta, lvif, vap));
2144 
2145 	IMPROVE("event callback?");
2146 
2147 	/* End mgd_complete_tx. */
2148 	if (lsta->in_mgd) {
2149 		memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2150 		prep_tx_info.success = false;
2151 		lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
2152 		lsta->in_mgd = false;
2153 	}
2154 
2155 	/* Now start assoc. */
2156 
2157 	/* Start mgd_prepare_tx. */
2158 	if (!lsta->in_mgd) {
2159 		memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2160 		prep_tx_info.duration = PREP_TX_INFO_DURATION;
2161 		lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
2162 		lsta->in_mgd = true;
2163 	}
2164 
2165 	error = 0;
2166 out:
2167 	LKPI_80211_LHW_UNLOCK(lhw);
2168 	IEEE80211_LOCK(vap->iv_ic);
2169 
2170 	return (error);
2171 }
2172 
2173 static int
2174 _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2175 {
2176 	struct lkpi_hw *lhw;
2177 	struct ieee80211_hw *hw;
2178 	struct lkpi_vif *lvif;
2179 	struct ieee80211_vif *vif;
2180 	struct ieee80211_node *ni;
2181 	struct lkpi_sta *lsta;
2182 	struct ieee80211_sta *sta;
2183 	struct ieee80211_prep_tx_info prep_tx_info;
2184 	enum ieee80211_bss_changed bss_changed;
2185 	int error;
2186 
2187 	lhw = vap->iv_ic->ic_softc;
2188 	hw = LHW_TO_HW(lhw);
2189 	lvif = VAP_TO_LVIF(vap);
2190 	vif = LVIF_TO_VIF(lvif);
2191 
2192 	IEEE80211_UNLOCK(vap->iv_ic);
2193 	LKPI_80211_LHW_LOCK(lhw);
2194 
2195 	LKPI_80211_LVIF_LOCK(lvif);
2196 #ifdef LINUXKPI_DEBUG_80211
2197 	/* XXX-BZ KASSERT later; state going down so no action. */
2198 	if (lvif->lvif_bss == NULL)
2199 		ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2200 		    "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2201 		    lvif, vap, vap->iv_bss, lvif->lvif_bss,
2202 		    (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2203 		    lvif->lvif_bss_synched);
2204 #endif
2205 	lsta = lvif->lvif_bss;
2206 	LKPI_80211_LVIF_UNLOCK(lvif);
2207 	KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
2208 	    "lvif %p vap %p\n", __func__,
2209 	    lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
2210 
2211 	ni = lsta->ni;		/* Reference held for lvif_bss. */
2212 	sta = LSTA_TO_STA(lsta);
2213 
2214 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2215 
2216 	/* flush, drop. */
2217 	lkpi_80211_mo_flush(hw, vif,  nitems(sta->txq), true);
2218 
2219 	IMPROVE("What are the proper conditions for DEAUTH_NEED_MGD_TX_PREP?");
2220 	if (ieee80211_hw_check(hw, DEAUTH_NEED_MGD_TX_PREP) &&
2221 	    !lsta->in_mgd) {
2222 		memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2223 		prep_tx_info.duration = PREP_TX_INFO_DURATION;
2224 		prep_tx_info.was_assoc = true;
2225 		lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
2226 		lsta->in_mgd = true;
2227 	}
2228 
2229 	LKPI_80211_LHW_UNLOCK(lhw);
2230 	IEEE80211_LOCK(vap->iv_ic);
2231 
2232 	/* Call iv_newstate first so we get potential DEAUTH packet out. */
2233 	error = lvif->iv_newstate(vap, nstate, arg);
2234 	if (error != 0) {
2235 		ic_printf(vap->iv_ic, "%s:%d: iv_newstate(%p, %d, %d) "
2236 		    "failed: %d\n", __func__, __LINE__, vap, nstate, arg, error);
2237 		goto outni;
2238 	}
2239 
2240 	IEEE80211_UNLOCK(vap->iv_ic);
2241 
2242 	/* Ensure the packets get out. */
2243 	lkpi_80211_flush_tx(lhw, lsta);
2244 
2245 	LKPI_80211_LHW_LOCK(lhw);
2246 
2247 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2248 
2249 	/* Wake tx queues to get packet(s) out. */
2250 	lkpi_wake_tx_queues(hw, sta, false, true);
2251 
2252 	/* flush, no drop */
2253 	lkpi_80211_mo_flush(hw, vif,  nitems(sta->txq), false);
2254 
2255 	/* End mgd_complete_tx. */
2256 	if (lsta->in_mgd) {
2257 		memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2258 		prep_tx_info.success = false;
2259 		prep_tx_info.was_assoc = true;
2260 		lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
2261 		lsta->in_mgd = false;
2262 	}
2263 
2264 	/* sync_rx_queues */
2265 	lkpi_80211_mo_sync_rx_queues(hw);
2266 
2267 	/* sta_pre_rcu_remove */
2268         lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta);
2269 
2270 	/* Take the station down. */
2271 
2272 	/* Update sta and change state (from AUTH) to NONE. */
2273 	KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2274 	KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not "
2275 	    "AUTH: %#x\n", __func__, lsta, lsta->state));
2276 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NONE);
2277 	if (error != 0) {
2278 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NONE) "
2279 		    "failed: %d\n", __func__, __LINE__, error);
2280 		goto out;
2281 	}
2282 
2283 	/* See comment in lkpi_sta_run_to_init(). */
2284 	bss_changed = 0;
2285 	bss_changed |= lkpi_disassoc(sta, vif, lhw);
2286 
2287 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2288 
2289 	/* Adjust sta and change state (from NONE) to NOTEXIST. */
2290 	KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2291 	KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not "
2292 	    "NONE: %#x, nstate %d arg %d\n", __func__, lsta, lsta->state, nstate, arg));
2293 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NOTEXIST);
2294 	if (error != 0) {
2295 		IMPROVE("do we need to undo the chan ctx?");
2296 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NOTEXIST) "
2297 		    "failed: %d\n", __func__, __LINE__, error);
2298 		goto out;
2299 	}
2300 
2301 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);	/* sta no longer save to use. */
2302 
2303 	IMPROVE("Any bss_info changes to announce?");
2304 	vif->bss_conf.qos = 0;
2305 	bss_changed |= BSS_CHANGED_QOS;
2306 	vif->cfg.ssid_len = 0;
2307 	memset(vif->cfg.ssid, '\0', sizeof(vif->cfg.ssid));
2308 	bss_changed |= BSS_CHANGED_BSSID;
2309 	lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
2310 
2311 	LKPI_80211_LVIF_LOCK(lvif);
2312 	/* Remove ni reference for this cache of lsta. */
2313 	lvif->lvif_bss = NULL;
2314 	lvif->lvif_bss_synched = false;
2315 	LKPI_80211_LVIF_UNLOCK(lvif);
2316 	lkpi_lsta_remove(lsta, lvif);
2317 	/*
2318 	 * The very last release the reference on the ni for the ni/lsta on
2319 	 * lvif->lvif_bss.  Upon return from this both ni and lsta are invalid
2320 	 * and potentially freed.
2321 	 */
2322 	ieee80211_free_node(ni);
2323 
2324 	/* conf_tx */
2325 
2326 	/* Take the chan ctx down. */
2327 	if (vif->chanctx_conf != NULL) {
2328 		struct lkpi_chanctx *lchanctx;
2329 		struct ieee80211_chanctx_conf *chanctx_conf;
2330 
2331 		chanctx_conf = vif->chanctx_conf;
2332 		/* Remove vif context. */
2333 		lkpi_80211_mo_unassign_vif_chanctx(hw, vif, &vif->bss_conf, &vif->chanctx_conf);
2334 		/* NB: vif->chanctx_conf is NULL now. */
2335 
2336 		lkpi_hw_conf_idle(hw, true);
2337 
2338 		/* Remove chan ctx. */
2339 		lkpi_80211_mo_remove_chanctx(hw, chanctx_conf);
2340 		lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
2341 		free(lchanctx, M_LKPI80211);
2342 	}
2343 
2344 	error = EALREADY;
2345 out:
2346 	LKPI_80211_LHW_UNLOCK(lhw);
2347 	IEEE80211_LOCK(vap->iv_ic);
2348 outni:
2349 	return (error);
2350 }
2351 
2352 static int
2353 lkpi_sta_assoc_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2354 {
2355 	int error;
2356 
2357 	error = _lkpi_sta_assoc_to_down(vap, nstate, arg);
2358 	if (error != 0 && error != EALREADY)
2359 		return (error);
2360 
2361 	/* At this point iv_bss is long a new node! */
2362 
2363 	error |= lkpi_sta_scan_to_auth(vap, nstate, 0);
2364 	return (error);
2365 }
2366 
2367 static int
2368 lkpi_sta_assoc_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2369 {
2370 	int error;
2371 
2372 	error = _lkpi_sta_assoc_to_down(vap, nstate, arg);
2373 	return (error);
2374 }
2375 
2376 static int
2377 lkpi_sta_assoc_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2378 {
2379 	int error;
2380 
2381 	error = _lkpi_sta_assoc_to_down(vap, nstate, arg);
2382 	return (error);
2383 }
2384 
2385 static int
2386 lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2387 {
2388 	struct lkpi_hw *lhw;
2389 	struct ieee80211_hw *hw;
2390 	struct lkpi_vif *lvif;
2391 	struct ieee80211_vif *vif;
2392 	struct ieee80211_node *ni;
2393 	struct lkpi_sta *lsta;
2394 	struct ieee80211_sta *sta;
2395 	struct ieee80211_prep_tx_info prep_tx_info;
2396 	enum ieee80211_bss_changed bss_changed;
2397 	int error;
2398 
2399 	lhw = vap->iv_ic->ic_softc;
2400 	hw = LHW_TO_HW(lhw);
2401 	lvif = VAP_TO_LVIF(vap);
2402 	vif = LVIF_TO_VIF(lvif);
2403 
2404 	IEEE80211_UNLOCK(vap->iv_ic);
2405 	LKPI_80211_LHW_LOCK(lhw);
2406 
2407 	LKPI_80211_LVIF_LOCK(lvif);
2408 	/* XXX-BZ KASSERT later? */
2409 	if (!lvif->lvif_bss_synched || lvif->lvif_bss == NULL) {
2410 #ifdef LINUXKPI_DEBUG_80211
2411 		ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2412 		    "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2413 		    lvif, vap, vap->iv_bss, lvif->lvif_bss,
2414 		    (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2415 		    lvif->lvif_bss_synched);
2416 #endif
2417 		LKPI_80211_LVIF_UNLOCK(lvif);
2418 		error = ENOTRECOVERABLE;
2419 		goto out;
2420 	}
2421 	lsta = lvif->lvif_bss;
2422 	LKPI_80211_LVIF_UNLOCK(lvif);
2423 	KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
2424 	    "lvif %p vap %p\n", __func__,
2425 	    lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
2426 
2427 	ni = lsta->ni;		/* Reference held for lvif_bss. */
2428 
2429 	IMPROVE("ponder some of this moved to ic_newassoc, scan_assoc_success, "
2430 	    "and to lesser extend ieee80211_notify_node_join");
2431 
2432 	/* Finish assoc. */
2433 	/* Update sta_state (AUTH to ASSOC) and set aid. */
2434 	KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not "
2435 	    "AUTH: %#x\n", __func__, lsta, lsta->state));
2436 	sta = LSTA_TO_STA(lsta);
2437 	sta->aid = IEEE80211_NODE_AID(ni);
2438 #ifdef LKPI_80211_WME
2439 	if (vap->iv_flags & IEEE80211_F_WME)
2440 		sta->wme = true;
2441 #endif
2442 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_ASSOC);
2443 	if (error != 0) {
2444 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(ASSOC) "
2445 		    "failed: %d\n", __func__, __LINE__, error);
2446 		goto out;
2447 	}
2448 
2449 	IMPROVE("wme / conf_tx [all]");
2450 
2451 	/* Update bss info (bss_info_changed) (assoc, aid, ..). */
2452 	bss_changed = 0;
2453 #ifdef LKPI_80211_WME
2454 	bss_changed |= lkpi_wme_update(lhw, vap, true);
2455 #endif
2456 	if (!vif->cfg.assoc || vif->cfg.aid != IEEE80211_NODE_AID(ni)) {
2457 		vif->cfg.assoc = true;
2458 		vif->cfg.aid = IEEE80211_NODE_AID(ni);
2459 		bss_changed |= BSS_CHANGED_ASSOC;
2460 	}
2461 	/* We set SSID but this is not BSSID! */
2462 	vif->cfg.ssid_len = ni->ni_esslen;
2463 	memcpy(vif->cfg.ssid, ni->ni_essid, ni->ni_esslen);
2464 	if ((vap->iv_flags & IEEE80211_F_SHPREAMBLE) !=
2465 	    vif->bss_conf.use_short_preamble) {
2466 		vif->bss_conf.use_short_preamble ^= 1;
2467 		/* bss_changed |= BSS_CHANGED_??? */
2468 	}
2469 	if ((vap->iv_flags & IEEE80211_F_SHSLOT) !=
2470 	    vif->bss_conf.use_short_slot) {
2471 		vif->bss_conf.use_short_slot ^= 1;
2472 		/* bss_changed |= BSS_CHANGED_??? */
2473 	}
2474 	if ((ni->ni_flags & IEEE80211_NODE_QOS) !=
2475 	    vif->bss_conf.qos) {
2476 		vif->bss_conf.qos ^= 1;
2477 		bss_changed |= BSS_CHANGED_QOS;
2478 	}
2479 
2480 	bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__);
2481 
2482 	lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
2483 
2484 	/* - change_chanctx (if needed)
2485 	 * - event_callback
2486 	 */
2487 
2488 	/* End mgd_complete_tx. */
2489 	if (lsta->in_mgd) {
2490 		memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2491 		prep_tx_info.success = true;
2492 		lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
2493 		lsta->in_mgd = false;
2494 	}
2495 
2496 	lkpi_hw_conf_idle(hw, false);
2497 
2498 	/*
2499 	 * And then:
2500 	 * - (more packets)?
2501 	 * - set_key
2502 	 * - set_default_unicast_key
2503 	 * - set_key (?)
2504 	 * - ipv6_addr_change (?)
2505 	 */
2506 	/* Prepare_multicast && configure_filter. */
2507 	lhw->update_mc = true;
2508 	lkpi_update_mcast_filter(vap->iv_ic, true);
2509 
2510 	if (!ieee80211_node_is_authorized(ni)) {
2511 		IMPROVE("net80211 does not consider node authorized");
2512 	}
2513 
2514 #if defined(LKPI_80211_HT)
2515 	IMPROVE("Is this the right spot, has net80211 done all updates already?");
2516 	lkpi_sta_sync_ht_from_ni(sta, ni, NULL);
2517 #endif
2518 
2519 	/* Update sta_state (ASSOC to AUTHORIZED). */
2520 	KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2521 	KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not "
2522 	    "ASSOC: %#x\n", __func__, lsta, lsta->state));
2523 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_AUTHORIZED);
2524 	if (error != 0) {
2525 		IMPROVE("undo some changes?");
2526 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(AUTHORIZED) "
2527 		    "failed: %d\n", __func__, __LINE__, error);
2528 		goto out;
2529 	}
2530 
2531 	/* - drv_config (?)
2532 	 * - bss_info_changed
2533 	 * - set_rekey_data (?)
2534 	 *
2535 	 * And now we should be passing packets.
2536 	 */
2537 	IMPROVE("Need that bssid setting, and the keys");
2538 
2539 	bss_changed = 0;
2540 	bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__);
2541 	lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
2542 
2543 out:
2544 	LKPI_80211_LHW_UNLOCK(lhw);
2545 	IEEE80211_LOCK(vap->iv_ic);
2546 	return (error);
2547 }
2548 
2549 static int
2550 lkpi_sta_auth_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2551 {
2552 	int error;
2553 
2554 	error = lkpi_sta_auth_to_assoc(vap, nstate, arg);
2555 	if (error == 0)
2556 		error = lkpi_sta_assoc_to_run(vap, nstate, arg);
2557 	return (error);
2558 }
2559 
2560 static int
2561 lkpi_sta_run_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2562 {
2563 	struct lkpi_hw *lhw;
2564 	struct ieee80211_hw *hw;
2565 	struct lkpi_vif *lvif;
2566 	struct ieee80211_vif *vif;
2567 	struct ieee80211_node *ni;
2568 	struct lkpi_sta *lsta;
2569 	struct ieee80211_sta *sta;
2570 	struct ieee80211_prep_tx_info prep_tx_info;
2571 #if 0
2572 	enum ieee80211_bss_changed bss_changed;
2573 #endif
2574 	int error;
2575 
2576 	lhw = vap->iv_ic->ic_softc;
2577 	hw = LHW_TO_HW(lhw);
2578 	lvif = VAP_TO_LVIF(vap);
2579 	vif = LVIF_TO_VIF(lvif);
2580 
2581 	LKPI_80211_LVIF_LOCK(lvif);
2582 #ifdef LINUXKPI_DEBUG_80211
2583 	/* XXX-BZ KASSERT later; state going down so no action. */
2584 	if (lvif->lvif_bss == NULL)
2585 		ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2586 		    "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2587 		    lvif, vap, vap->iv_bss, lvif->lvif_bss,
2588 		    (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2589 		    lvif->lvif_bss_synched);
2590 #endif
2591 	lsta = lvif->lvif_bss;
2592 	LKPI_80211_LVIF_UNLOCK(lvif);
2593 	KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
2594 	    "lvif %p vap %p\n", __func__,
2595 	    lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
2596 
2597 	ni = lsta->ni;		/* Reference held for lvif_bss. */
2598 	sta = LSTA_TO_STA(lsta);
2599 
2600 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2601 
2602 	IEEE80211_UNLOCK(vap->iv_ic);
2603 	LKPI_80211_LHW_LOCK(lhw);
2604 
2605 	/* flush, drop. */
2606 	lkpi_80211_mo_flush(hw, vif,  nitems(sta->txq), true);
2607 
2608 	IMPROVE("What are the proper conditions for DEAUTH_NEED_MGD_TX_PREP?");
2609 	if (ieee80211_hw_check(hw, DEAUTH_NEED_MGD_TX_PREP) &&
2610 	    !lsta->in_mgd) {
2611 		memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2612 		prep_tx_info.duration = PREP_TX_INFO_DURATION;
2613 		prep_tx_info.was_assoc = true;
2614 		lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
2615 		lsta->in_mgd = true;
2616 	}
2617 
2618 	LKPI_80211_LHW_UNLOCK(lhw);
2619 	IEEE80211_LOCK(vap->iv_ic);
2620 
2621 	/* Call iv_newstate first so we get potential DISASSOC packet out. */
2622 	error = lvif->iv_newstate(vap, nstate, arg);
2623 	if (error != 0) {
2624 		ic_printf(vap->iv_ic, "%s:%d: iv_newstate(%p, %d, %d) "
2625 		    "failed: %d\n", __func__, __LINE__, vap, nstate, arg, error);
2626 		goto outni;
2627 	}
2628 
2629 	IEEE80211_UNLOCK(vap->iv_ic);
2630 
2631 	/* Ensure the packets get out. */
2632 	lkpi_80211_flush_tx(lhw, lsta);
2633 
2634 	LKPI_80211_LHW_LOCK(lhw);
2635 
2636 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2637 
2638 	/* Wake tx queues to get packet(s) out. */
2639 	lkpi_wake_tx_queues(hw, sta, false, true);
2640 
2641 	/* flush, no drop */
2642 	lkpi_80211_mo_flush(hw, vif,  nitems(sta->txq), false);
2643 
2644 	/* End mgd_complete_tx. */
2645 	if (lsta->in_mgd) {
2646 		memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2647 		prep_tx_info.success = false;
2648 		prep_tx_info.was_assoc = true;
2649 		lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
2650 		lsta->in_mgd = false;
2651 	}
2652 
2653 #if 0
2654 	/* sync_rx_queues */
2655 	lkpi_80211_mo_sync_rx_queues(hw);
2656 
2657 	/* sta_pre_rcu_remove */
2658         lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta);
2659 #endif
2660 
2661 	/* Take the station down. */
2662 
2663 	/* Adjust sta and change state (from AUTHORIZED) to ASSOC. */
2664 	KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2665 	KASSERT(lsta->state == IEEE80211_STA_AUTHORIZED, ("%s: lsta %p state not "
2666 	    "AUTHORIZED: %#x\n", __func__, lsta, lsta->state));
2667 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_ASSOC);
2668 	if (error != 0) {
2669 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(ASSOC) "
2670 		    "failed: %d\n", __func__, __LINE__, error);
2671 		goto out;
2672 	}
2673 
2674 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2675 
2676 #ifdef LKPI_80211_HW_CRYPTO
2677 	if (lkpi_hwcrypto) {
2678 		wiphy_lock(hw->wiphy);
2679 		error = lkpi_sta_del_keys(hw, vif, lsta);
2680 		wiphy_unlock(hw->wiphy);
2681 		if (error != 0) {
2682 			ic_printf(vap->iv_ic, "%s:%d: lkpi_sta_del_keys "
2683 			    "failed: %d\n", __func__, __LINE__, error);
2684 			/*
2685 			 * Either drv/fw will crash or cleanup itself,
2686 			 * otherwise net80211 will delete the keys (at a
2687 			 * less appropriate time).
2688 			 */
2689 			/* goto out; */
2690 		}
2691 	}
2692 #endif
2693 
2694 	/* Update sta_state (ASSOC to AUTH). */
2695 	KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2696 	KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not "
2697 	    "ASSOC: %#x\n", __func__, lsta, lsta->state));
2698 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_AUTH);
2699 	if (error != 0) {
2700 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(AUTH) "
2701 		    "failed: %d\n", __func__, __LINE__, error);
2702 		goto out;
2703 	}
2704 
2705 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2706 
2707 #if 0
2708 	/* Update bss info (bss_info_changed) (assoc, aid, ..). */
2709 	lkpi_disassoc(sta, vif, lhw);
2710 #endif
2711 
2712 	error = EALREADY;
2713 out:
2714 	LKPI_80211_LHW_UNLOCK(lhw);
2715 	IEEE80211_LOCK(vap->iv_ic);
2716 outni:
2717 	return (error);
2718 }
2719 
2720 static int
2721 lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2722 {
2723 	struct lkpi_hw *lhw;
2724 	struct ieee80211_hw *hw;
2725 	struct lkpi_vif *lvif;
2726 	struct ieee80211_vif *vif;
2727 	struct ieee80211_node *ni;
2728 	struct lkpi_sta *lsta;
2729 	struct ieee80211_sta *sta;
2730 	struct ieee80211_prep_tx_info prep_tx_info;
2731 	enum ieee80211_bss_changed bss_changed;
2732 	int error;
2733 
2734 	lhw = vap->iv_ic->ic_softc;
2735 	hw = LHW_TO_HW(lhw);
2736 	lvif = VAP_TO_LVIF(vap);
2737 	vif = LVIF_TO_VIF(lvif);
2738 
2739 	IEEE80211_UNLOCK(vap->iv_ic);
2740 	LKPI_80211_LHW_LOCK(lhw);
2741 
2742 	LKPI_80211_LVIF_LOCK(lvif);
2743 #ifdef LINUXKPI_DEBUG_80211
2744 	/* XXX-BZ KASSERT later; state going down so no action. */
2745 	if (lvif->lvif_bss == NULL)
2746 		ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2747 		    "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2748 		    lvif, vap, vap->iv_bss, lvif->lvif_bss,
2749 		    (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2750 		    lvif->lvif_bss_synched);
2751 #endif
2752 	lsta = lvif->lvif_bss;
2753 	LKPI_80211_LVIF_UNLOCK(lvif);
2754 	KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
2755 	    "lvif %p vap %p\n", __func__,
2756 	    lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
2757 
2758 	ni = lsta->ni;		/* Reference held for lvif_bss. */
2759 	sta = LSTA_TO_STA(lsta);
2760 
2761 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2762 
2763 	/* flush, drop. */
2764 	lkpi_80211_mo_flush(hw, vif,  nitems(sta->txq), true);
2765 
2766 	IMPROVE("What are the proper conditions for DEAUTH_NEED_MGD_TX_PREP?");
2767 	if (ieee80211_hw_check(hw, DEAUTH_NEED_MGD_TX_PREP) &&
2768 	    !lsta->in_mgd) {
2769 		memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2770 		prep_tx_info.duration = PREP_TX_INFO_DURATION;
2771 		prep_tx_info.was_assoc = true;
2772 		lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
2773 		lsta->in_mgd = true;
2774 	}
2775 
2776 	LKPI_80211_LHW_UNLOCK(lhw);
2777 	IEEE80211_LOCK(vap->iv_ic);
2778 
2779 	/* Call iv_newstate first so we get potential DISASSOC packet out. */
2780 	error = lvif->iv_newstate(vap, nstate, arg);
2781 	if (error != 0) {
2782 		ic_printf(vap->iv_ic, "%s:%d: iv_newstate(%p, %d, %d) "
2783 		    "failed: %d\n", __func__, __LINE__, vap, nstate, arg, error);
2784 		goto outni;
2785 	}
2786 
2787 	IEEE80211_UNLOCK(vap->iv_ic);
2788 
2789 	/* Ensure the packets get out. */
2790 	lkpi_80211_flush_tx(lhw, lsta);
2791 
2792 	LKPI_80211_LHW_LOCK(lhw);
2793 
2794 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2795 
2796 	/* Wake tx queues to get packet(s) out. */
2797 	lkpi_wake_tx_queues(hw, sta, false, true);
2798 
2799 	/* flush, no drop */
2800 	lkpi_80211_mo_flush(hw, vif,  nitems(sta->txq), false);
2801 
2802 	/* End mgd_complete_tx. */
2803 	if (lsta->in_mgd) {
2804 		memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2805 		prep_tx_info.success = false;
2806 		prep_tx_info.was_assoc = true;
2807 		lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
2808 		lsta->in_mgd = false;
2809 	}
2810 
2811 	/* sync_rx_queues */
2812 	lkpi_80211_mo_sync_rx_queues(hw);
2813 
2814 	/* sta_pre_rcu_remove */
2815         lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta);
2816 
2817 	/* Take the station down. */
2818 
2819 	/* Adjust sta and change state (from AUTHORIZED) to ASSOC. */
2820 	KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2821 	KASSERT(lsta->state == IEEE80211_STA_AUTHORIZED, ("%s: lsta %p state not "
2822 	    "AUTHORIZED: %#x\n", __func__, lsta, lsta->state));
2823 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_ASSOC);
2824 	if (error != 0) {
2825 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(ASSOC) "
2826 		    "failed: %d\n", __func__, __LINE__, error);
2827 		goto out;
2828 	}
2829 
2830 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2831 
2832 #ifdef LKPI_80211_HW_CRYPTO
2833 	if (lkpi_hwcrypto) {
2834 		wiphy_lock(hw->wiphy);
2835 		error = lkpi_sta_del_keys(hw, vif, lsta);
2836 		wiphy_unlock(hw->wiphy);
2837 		if (error != 0) {
2838 			ic_printf(vap->iv_ic, "%s:%d: lkpi_sta_del_keys "
2839 			    "failed: %d\n", __func__, __LINE__, error);
2840 			/*
2841 			 * Either drv/fw will crash or cleanup itself,
2842 			 * otherwise net80211 will delete the keys (at a
2843 			 * less appropriate time).
2844 			 */
2845 			/* goto out; */
2846 		}
2847 	}
2848 #endif
2849 
2850 	/* Update sta_state (ASSOC to AUTH). */
2851 	KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2852 	KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not "
2853 	    "ASSOC: %#x\n", __func__, lsta, lsta->state));
2854 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_AUTH);
2855 	if (error != 0) {
2856 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(AUTH) "
2857 		    "failed: %d\n", __func__, __LINE__, error);
2858 		goto out;
2859 	}
2860 
2861 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2862 
2863 	/* Update sta and change state (from AUTH) to NONE. */
2864 	KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2865 	KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not "
2866 	    "AUTH: %#x\n", __func__, lsta, lsta->state));
2867 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NONE);
2868 	if (error != 0) {
2869 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NONE) "
2870 		    "failed: %d\n", __func__, __LINE__, error);
2871 		goto out;
2872 	}
2873 
2874 	bss_changed = 0;
2875 	/*
2876 	 * Start updating bss info (bss_info_changed) (assoc, aid, ..).
2877 	 *
2878 	 * One would expect this to happen when going off AUTHORIZED.
2879 	 * See comment there; removes the sta from fw if not careful
2880 	 * (bss_info_changed() change is executed right away).
2881 	 *
2882 	 * We need to do this now, before sta changes to IEEE80211_STA_NOTEXIST
2883 	 * as otherwise drivers (iwlwifi at least) will silently not remove
2884 	 * the sta from the firmware and when we will add a new one trigger
2885 	 * a fw assert.
2886 	 *
2887 	 * The order which works best so far avoiding early removal or silent
2888 	 * non-removal seems to be (for iwlwifi::mld-mac80211.c cases;
2889 	 * the iwlwifi:mac80211.c case still to be tested):
2890 	 * 1) lkpi_disassoc(): set vif->cfg.assoc = false (aid=0 side effect here)
2891 	 * 2) call the last sta_state update -> IEEE80211_STA_NOTEXIST
2892 	 *    (removes the sta given assoc is false)
2893 	 * 3) add the remaining BSS_CHANGED changes and call bss_info_changed()
2894 	 * 4) call unassign_vif_chanctx
2895 	 * 5) call lkpi_hw_conf_idle
2896 	 * 6) call remove_chanctx
2897 	 */
2898 	bss_changed |= lkpi_disassoc(sta, vif, lhw);
2899 
2900 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2901 
2902 	/* Adjust sta and change state (from NONE) to NOTEXIST. */
2903 	KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2904 	KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not "
2905 	    "NONE: %#x, nstate %d arg %d\n", __func__, lsta, lsta->state, nstate, arg));
2906 	error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NOTEXIST);
2907 	if (error != 0) {
2908 		IMPROVE("do we need to undo the chan ctx?");
2909 		ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NOTEXIST) "
2910 		    "failed: %d\n", __func__, __LINE__, error);
2911 		goto out;
2912 	}
2913 
2914 	lkpi_lsta_remove(lsta, lvif);
2915 
2916 	lkpi_lsta_dump(lsta, ni, __func__, __LINE__);	/* sta no longer save to use. */
2917 
2918 	IMPROVE("Any bss_info changes to announce?");
2919 	vif->bss_conf.qos = 0;
2920 	bss_changed |= BSS_CHANGED_QOS;
2921 	vif->cfg.ssid_len = 0;
2922 	memset(vif->cfg.ssid, '\0', sizeof(vif->cfg.ssid));
2923 	bss_changed |= BSS_CHANGED_BSSID;
2924 	vif->bss_conf.use_short_preamble = false;
2925 	vif->bss_conf.qos = false;
2926 	/* XXX BSS_CHANGED_???? */
2927 	lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
2928 
2929 	LKPI_80211_LVIF_LOCK(lvif);
2930 	/* Remove ni reference for this cache of lsta. */
2931 	lvif->lvif_bss = NULL;
2932 	lvif->lvif_bss_synched = false;
2933 	LKPI_80211_LVIF_UNLOCK(lvif);
2934 	/*
2935 	 * The very last release the reference on the ni for the ni/lsta on
2936 	 * lvif->lvif_bss.  Upon return from this both ni and lsta are invalid
2937 	 * and potentially freed.
2938 	 */
2939 	ieee80211_free_node(ni);
2940 
2941 	/* conf_tx */
2942 
2943 	/* Take the chan ctx down. */
2944 	if (vif->chanctx_conf != NULL) {
2945 		struct lkpi_chanctx *lchanctx;
2946 		struct ieee80211_chanctx_conf *chanctx_conf;
2947 
2948 		chanctx_conf = vif->chanctx_conf;
2949 		/* Remove vif context. */
2950 		lkpi_80211_mo_unassign_vif_chanctx(hw, vif, &vif->bss_conf, &vif->chanctx_conf);
2951 		/* NB: vif->chanctx_conf is NULL now. */
2952 
2953 		lkpi_hw_conf_idle(hw, true);
2954 
2955 		/* Remove chan ctx. */
2956 		lkpi_80211_mo_remove_chanctx(hw, chanctx_conf);
2957 		lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
2958 		free(lchanctx, M_LKPI80211);
2959 	}
2960 
2961 	error = EALREADY;
2962 out:
2963 	LKPI_80211_LHW_UNLOCK(lhw);
2964 	IEEE80211_LOCK(vap->iv_ic);
2965 outni:
2966 	return (error);
2967 }
2968 
2969 static int
2970 lkpi_sta_run_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2971 {
2972 
2973 	return (lkpi_sta_run_to_init(vap, nstate, arg));
2974 }
2975 
2976 static int
2977 lkpi_sta_run_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2978 {
2979 	int error;
2980 
2981 	error = lkpi_sta_run_to_init(vap, nstate, arg);
2982 	if (error != 0 && error != EALREADY)
2983 		return (error);
2984 
2985 	/* At this point iv_bss is long a new node! */
2986 
2987 	error |= lkpi_sta_scan_to_auth(vap, nstate, 0);
2988 	return (error);
2989 }
2990 
2991 /* -------------------------------------------------------------------------- */
2992 
2993 /*
2994  * The matches the documented state changes in net80211::sta_newstate().
2995  * XXX (1) without CSA and SLEEP yet, * XXX (2) not all unhandled cases
2996  * there are "invalid" (so there is a room for failure here).
2997  */
2998 struct fsm_state {
2999 	/* INIT, SCAN, AUTH, ASSOC, CAC, RUN, CSA, SLEEP */
3000 	enum ieee80211_state ostate;
3001 	enum ieee80211_state nstate;
3002 	int (*handler)(struct ieee80211vap *, enum ieee80211_state, int);
3003 } sta_state_fsm[] = {
3004 	{ IEEE80211_S_INIT,	IEEE80211_S_INIT, lkpi_sta_state_do_nada },
3005 	{ IEEE80211_S_SCAN,	IEEE80211_S_INIT, lkpi_sta_state_do_nada },	/* scan_to_init */
3006 	{ IEEE80211_S_AUTH,	IEEE80211_S_INIT, lkpi_sta_auth_to_init },	/* not explicitly in sta_newstate() */
3007 	{ IEEE80211_S_ASSOC,	IEEE80211_S_INIT, lkpi_sta_assoc_to_init },	/* Send DEAUTH. */
3008 	{ IEEE80211_S_RUN,	IEEE80211_S_INIT, lkpi_sta_run_to_init },	/* Send DISASSOC. */
3009 
3010 	{ IEEE80211_S_INIT,	IEEE80211_S_SCAN, lkpi_sta_state_do_nada },
3011 	{ IEEE80211_S_SCAN,	IEEE80211_S_SCAN, lkpi_sta_state_do_nada },
3012 	{ IEEE80211_S_AUTH,	IEEE80211_S_SCAN, lkpi_sta_auth_to_scan },
3013 	{ IEEE80211_S_ASSOC,	IEEE80211_S_SCAN, lkpi_sta_assoc_to_scan },
3014 	{ IEEE80211_S_RUN,	IEEE80211_S_SCAN, lkpi_sta_run_to_scan },	/* Beacon miss. */
3015 
3016 	{ IEEE80211_S_INIT,	IEEE80211_S_AUTH, lkpi_sta_scan_to_auth },	/* Send AUTH. */
3017 	{ IEEE80211_S_SCAN,	IEEE80211_S_AUTH, lkpi_sta_scan_to_auth },	/* Send AUTH. */
3018 	{ IEEE80211_S_AUTH,	IEEE80211_S_AUTH, lkpi_sta_a_to_a },		/* Send ?AUTH. */
3019 	{ IEEE80211_S_ASSOC,	IEEE80211_S_AUTH, lkpi_sta_assoc_to_auth },	/* Send ?AUTH. */
3020 	{ IEEE80211_S_RUN,	IEEE80211_S_AUTH, lkpi_sta_run_to_auth },	/* Send ?AUTH. */
3021 
3022 	{ IEEE80211_S_AUTH,	IEEE80211_S_ASSOC, lkpi_sta_auth_to_assoc },	/* Send ASSOCREQ. */
3023 	{ IEEE80211_S_ASSOC,	IEEE80211_S_ASSOC, lkpi_sta_a_to_a },		/* Send ASSOCREQ. */
3024 	{ IEEE80211_S_RUN,	IEEE80211_S_ASSOC, lkpi_sta_run_to_assoc },	/* Send ASSOCREQ/REASSOCREQ. */
3025 
3026 	{ IEEE80211_S_AUTH,	IEEE80211_S_RUN, lkpi_sta_auth_to_run },
3027 	{ IEEE80211_S_ASSOC,	IEEE80211_S_RUN, lkpi_sta_assoc_to_run },
3028 	{ IEEE80211_S_RUN,	IEEE80211_S_RUN, lkpi_sta_state_do_nada },
3029 
3030 	/* Dummy at the end without handler. */
3031 	{ IEEE80211_S_INIT,	IEEE80211_S_INIT, NULL },
3032 };
3033 
3034 static int
3035 lkpi_iv_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3036 {
3037 	struct ieee80211com *ic;
3038 	struct lkpi_hw *lhw;
3039 	struct lkpi_vif *lvif;
3040 	struct ieee80211_vif *vif;
3041 	struct fsm_state *s;
3042 	enum ieee80211_state ostate;
3043 	int error;
3044 
3045 	ic = vap->iv_ic;
3046 	IEEE80211_LOCK_ASSERT(ic);
3047 	ostate = vap->iv_state;
3048 
3049 #ifdef LINUXKPI_DEBUG_80211
3050 	if (linuxkpi_debug_80211 & D80211_TRACE)
3051 		ic_printf(vap->iv_ic, "%s:%d: vap %p nstate %#x arg %#x\n",
3052 		    __func__, __LINE__, vap, nstate, arg);
3053 #endif
3054 
3055 	if (vap->iv_opmode == IEEE80211_M_STA) {
3056 
3057 		lhw = ic->ic_softc;
3058 		lvif = VAP_TO_LVIF(vap);
3059 		vif = LVIF_TO_VIF(lvif);
3060 
3061 		/* No need to replicate this in most state handlers. */
3062 		if (ostate == IEEE80211_S_SCAN && nstate != IEEE80211_S_SCAN)
3063 			lkpi_stop_hw_scan(lhw, vif);
3064 
3065 		s = sta_state_fsm;
3066 
3067 	} else {
3068 		ic_printf(vap->iv_ic, "%s: only station mode currently supported: "
3069 		    "cap %p iv_opmode %d\n", __func__, vap, vap->iv_opmode);
3070 		return (ENOSYS);
3071 	}
3072 
3073 	error = 0;
3074 	for (; s->handler != NULL; s++) {
3075 		if (ostate == s->ostate && nstate == s->nstate) {
3076 #ifdef LINUXKPI_DEBUG_80211
3077 			if (linuxkpi_debug_80211 & D80211_TRACE)
3078 				ic_printf(vap->iv_ic, "%s: new state %d (%s) ->"
3079 				    " %d (%s): arg %d.\n", __func__,
3080 				    ostate, ieee80211_state_name[ostate],
3081 				    nstate, ieee80211_state_name[nstate], arg);
3082 #endif
3083 			error = s->handler(vap, nstate, arg);
3084 			break;
3085 		}
3086 	}
3087 	IEEE80211_LOCK_ASSERT(vap->iv_ic);
3088 
3089 	if (s->handler == NULL) {
3090 		IMPROVE("turn this into a KASSERT\n");
3091 		ic_printf(vap->iv_ic, "%s: unsupported state transition "
3092 		    "%d (%s) -> %d (%s)\n", __func__,
3093 		    ostate, ieee80211_state_name[ostate],
3094 		    nstate, ieee80211_state_name[nstate]);
3095 		return (ENOSYS);
3096 	}
3097 
3098 	if (error == EALREADY) {
3099 #ifdef LINUXKPI_DEBUG_80211
3100 		if (linuxkpi_debug_80211 & D80211_TRACE)
3101 			ic_printf(vap->iv_ic, "%s: state transition %d (%s) -> "
3102 			    "%d (%s): iv_newstate already handled: %d.\n",
3103 			    __func__, ostate, ieee80211_state_name[ostate],
3104 			    nstate, ieee80211_state_name[nstate], error);
3105 #endif
3106 		return (0);
3107 	}
3108 
3109 	if (error != 0) {
3110 		ic_printf(vap->iv_ic, "%s: error %d during state transition "
3111 		    "%d (%s) -> %d (%s)\n", __func__, error,
3112 		    ostate, ieee80211_state_name[ostate],
3113 		    nstate, ieee80211_state_name[nstate]);
3114 		return (error);
3115 	}
3116 
3117 #ifdef LINUXKPI_DEBUG_80211
3118 	if (linuxkpi_debug_80211 & D80211_TRACE)
3119 		ic_printf(vap->iv_ic, "%s:%d: vap %p nstate %#x arg %#x "
3120 		    "calling net80211 parent\n",
3121 		    __func__, __LINE__, vap, nstate, arg);
3122 #endif
3123 
3124 	return (lvif->iv_newstate(vap, nstate, arg));
3125 }
3126 
3127 /* -------------------------------------------------------------------------- */
3128 
3129 /*
3130  * We overload (*iv_update_bss) as otherwise we have cases in, e.g.,
3131  * net80211::ieee80211_sta_join1() where vap->iv_bss gets replaced by a
3132  * new node without us knowing and thus our ni/lsta are out of sync.
3133  */
3134 static struct ieee80211_node *
3135 lkpi_iv_update_bss(struct ieee80211vap *vap, struct ieee80211_node *ni)
3136 {
3137 	struct lkpi_vif *lvif;
3138 	struct ieee80211_node *rni;
3139 
3140 	IEEE80211_LOCK_ASSERT(vap->iv_ic);
3141 
3142 	lvif = VAP_TO_LVIF(vap);
3143 
3144 	LKPI_80211_LVIF_LOCK(lvif);
3145 	lvif->lvif_bss_synched = false;
3146 	LKPI_80211_LVIF_UNLOCK(lvif);
3147 
3148 	rni = lvif->iv_update_bss(vap, ni);
3149 	return (rni);
3150 }
3151 
3152 #ifdef LKPI_80211_WME
3153 static int
3154 lkpi_wme_update(struct lkpi_hw *lhw, struct ieee80211vap *vap, bool planned)
3155 {
3156 	struct ieee80211com *ic;
3157 	struct ieee80211_hw *hw;
3158 	struct lkpi_vif *lvif;
3159 	struct ieee80211_vif *vif;
3160 	struct chanAccParams chp;
3161 	struct wmeParams wmeparr[WME_NUM_AC];
3162 	struct ieee80211_tx_queue_params txqp;
3163 	enum ieee80211_bss_changed changed;
3164 	int error;
3165 	uint16_t ac;
3166 
3167 	IMPROVE();
3168 	KASSERT(WME_NUM_AC == IEEE80211_NUM_ACS, ("%s: WME_NUM_AC %d != "
3169 	    "IEEE80211_NUM_ACS %d\n", __func__, WME_NUM_AC, IEEE80211_NUM_ACS));
3170 
3171 	if (vap == NULL)
3172 		return (0);
3173 
3174 	if ((vap->iv_flags & IEEE80211_F_WME) == 0)
3175 		return (0);
3176 
3177 	if (lhw->ops->conf_tx == NULL)
3178 		return (0);
3179 
3180 	if (!planned && (vap->iv_state != IEEE80211_S_RUN)) {
3181 		lhw->update_wme = true;
3182 		return (0);
3183 	}
3184 	lhw->update_wme = false;
3185 
3186 	ic = lhw->ic;
3187 	ieee80211_wme_ic_getparams(ic, &chp);
3188 	IEEE80211_LOCK(ic);
3189 	for (ac = 0; ac < WME_NUM_AC; ac++)
3190 		wmeparr[ac] = chp.cap_wmeParams[ac];
3191 	IEEE80211_UNLOCK(ic);
3192 
3193 	hw = LHW_TO_HW(lhw);
3194 	lvif = VAP_TO_LVIF(vap);
3195 	vif = LVIF_TO_VIF(lvif);
3196 
3197 	/* Configure tx queues (conf_tx) & send BSS_CHANGED_QOS. */
3198 	LKPI_80211_LHW_LOCK(lhw);
3199 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
3200 		struct wmeParams *wmep;
3201 
3202 		wmep = &wmeparr[ac];
3203 		bzero(&txqp, sizeof(txqp));
3204 		txqp.cw_min = wmep->wmep_logcwmin;
3205 		txqp.cw_max = wmep->wmep_logcwmax;
3206 		txqp.txop = wmep->wmep_txopLimit;
3207 		txqp.aifs = wmep->wmep_aifsn;
3208 		error = lkpi_80211_mo_conf_tx(hw, vif, /* link_id */0, ac, &txqp);
3209 		if (error != 0)
3210 			ic_printf(ic, "%s: conf_tx ac %u failed %d\n",
3211 			    __func__, ac, error);
3212 	}
3213 	LKPI_80211_LHW_UNLOCK(lhw);
3214 	changed = BSS_CHANGED_QOS;
3215 	if (!planned)
3216 		lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed);
3217 
3218 	return (changed);
3219 }
3220 #endif
3221 
3222 static int
3223 lkpi_ic_wme_update(struct ieee80211com *ic)
3224 {
3225 #ifdef LKPI_80211_WME
3226 	struct ieee80211vap *vap;
3227 	struct lkpi_hw *lhw;
3228 
3229 	IMPROVE("Use the per-VAP callback in net80211.");
3230 	vap = TAILQ_FIRST(&ic->ic_vaps);
3231 	if (vap == NULL)
3232 		return (0);
3233 
3234 	lhw = ic->ic_softc;
3235 
3236 	lkpi_wme_update(lhw, vap, false);
3237 #endif
3238 	return (0);	/* unused */
3239 }
3240 
3241 /*
3242  * Change link-layer address on the vif (if the vap is not started/"UP").
3243  * This can happen if a user changes 'ether' using ifconfig.
3244  * The code is based on net80211/ieee80211_freebsd.c::wlan_iflladdr() but
3245  * we do use a per-[l]vif event handler to be sure we exist as we
3246  * cannot assume that from every vap derives a vif and we have a hard
3247  * time checking based on net80211 information.
3248  * Should this ever become a real problem we could add a callback function
3249  * to wlan_iflladdr() to be set optionally but that would be for a
3250  * single-consumer (or needs a list) -- was just too complicated for an
3251  * otherwise perfect mechanism FreeBSD already provides.
3252  */
3253 static void
3254 lkpi_vif_iflladdr(void *arg, struct ifnet *ifp)
3255 {
3256 	struct epoch_tracker et;
3257 	struct ieee80211_vif *vif;
3258 
3259 	NET_EPOCH_ENTER(et);
3260 	/* NB: identify vap's by if_transmit; left as an extra check. */
3261 	if (if_gettransmitfn(ifp) != ieee80211_vap_transmit ||
3262 	    (if_getflags(ifp) & IFF_UP) != 0) {
3263 		NET_EPOCH_EXIT(et);
3264 		return;
3265 	}
3266 
3267 	vif = arg;
3268 	IEEE80211_ADDR_COPY(vif->bss_conf.addr, if_getlladdr(ifp));
3269 	NET_EPOCH_EXIT(et);
3270 }
3271 
3272 static struct ieee80211vap *
3273 lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
3274     int unit, enum ieee80211_opmode opmode, int flags,
3275     const uint8_t bssid[IEEE80211_ADDR_LEN],
3276     const uint8_t mac[IEEE80211_ADDR_LEN])
3277 {
3278 	struct lkpi_hw *lhw;
3279 	struct ieee80211_hw *hw;
3280 	struct lkpi_vif *lvif;
3281 	struct ieee80211vap *vap;
3282 	struct ieee80211_vif *vif;
3283 	struct ieee80211_tx_queue_params txqp;
3284 	enum ieee80211_bss_changed changed;
3285 	struct sysctl_oid *node;
3286 	size_t len;
3287 	int error, i;
3288 	uint16_t ac;
3289 
3290 	if (!TAILQ_EMPTY(&ic->ic_vaps))	/* 1 so far. Add <n> once this works. */
3291 		return (NULL);
3292 
3293 	lhw = ic->ic_softc;
3294 	hw = LHW_TO_HW(lhw);
3295 
3296 	len = sizeof(*lvif);
3297 	len += hw->vif_data_size;	/* vif->drv_priv */
3298 
3299 	lvif = malloc(len, M_80211_VAP, M_WAITOK | M_ZERO);
3300 	mtx_init(&lvif->mtx, "lvif", NULL, MTX_DEF);
3301 	INIT_LIST_HEAD(&lvif->lsta_list);
3302 	lvif->lvif_bss = NULL;
3303 	lvif->lvif_bss_synched = false;
3304 	vap = LVIF_TO_VAP(lvif);
3305 
3306 	vif = LVIF_TO_VIF(lvif);
3307 	memcpy(vif->addr, mac, IEEE80211_ADDR_LEN);
3308 	vif->p2p = false;
3309 	vif->probe_req_reg = false;
3310 	vif->type = lkpi_opmode_to_vif_type(opmode);
3311 	lvif->wdev.iftype = vif->type;
3312 	/* Need to fill in other fields as well. */
3313 	IMPROVE();
3314 
3315 	/* XXX-BZ hardcoded for now! */
3316 #if 1
3317 	vif->chanctx_conf = NULL;
3318 	vif->bss_conf.vif = vif;
3319 	/* vap->iv_myaddr is not set until net80211::vap_setup or vap_attach. */
3320 	IEEE80211_ADDR_COPY(vif->bss_conf.addr, mac);
3321 	lvif->lvif_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
3322 	    lkpi_vif_iflladdr, vif, EVENTHANDLER_PRI_ANY);
3323 	vif->bss_conf.link_id = 0;	/* Non-MLO operation. */
3324 	vif->bss_conf.chanreq.oper.width = NL80211_CHAN_WIDTH_20_NOHT;
3325 	vif->bss_conf.use_short_preamble = false;	/* vap->iv_flags IEEE80211_F_SHPREAMBLE */
3326 	vif->bss_conf.use_short_slot = false;		/* vap->iv_flags IEEE80211_F_SHSLOT */
3327 	vif->bss_conf.qos = false;
3328 	vif->bss_conf.use_cts_prot = false;		/* vap->iv_protmode */
3329 	vif->bss_conf.ht_operation_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
3330 	vif->cfg.aid = 0;
3331 	vif->cfg.assoc = false;
3332 	vif->cfg.idle = true;
3333 	vif->cfg.ps = false;
3334 	IMPROVE("Check other fields and then figure out whats is left elsewhere of them");
3335 	/*
3336 	 * We need to initialize it to something as the bss_info_changed call
3337 	 * will try to copy from it in iwlwifi and NULL is a panic.
3338 	 * We will set the proper one in scan_to_auth() before being assoc.
3339 	 */
3340 	vif->bss_conf.bssid = ieee80211broadcastaddr;
3341 #endif
3342 #if 0
3343 	vif->bss_conf.dtim_period = 0; /* IEEE80211_DTIM_DEFAULT ; must stay 0. */
3344 	IEEE80211_ADDR_COPY(vif->bss_conf.bssid, bssid);
3345 	vif->bss_conf.beacon_int = ic->ic_bintval;
3346 	/* iwlwifi bug. */
3347 	if (vif->bss_conf.beacon_int < 16)
3348 		vif->bss_conf.beacon_int = 16;
3349 #endif
3350 
3351 	/* Link Config */
3352 	vif->link_conf[0] = &vif->bss_conf;
3353 	for (i = 0; i < nitems(vif->link_conf); i++) {
3354 		IMPROVE("more than 1 link one day");
3355 	}
3356 
3357 	/* Setup queue defaults; driver may override in (*add_interface). */
3358 	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
3359 		if (ieee80211_hw_check(hw, QUEUE_CONTROL))
3360 			vif->hw_queue[i] = IEEE80211_INVAL_HW_QUEUE;
3361 		else if (hw->queues >= IEEE80211_NUM_ACS)
3362 			vif->hw_queue[i] = i;
3363 		else
3364 			vif->hw_queue[i] = 0;
3365 
3366 		/* Initialize the queue to running. Stopped? */
3367 		lvif->hw_queue_stopped[i] = false;
3368 	}
3369 	vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
3370 
3371 	IMPROVE();
3372 
3373 	error = lkpi_80211_mo_start(hw);
3374 	if (error != 0) {
3375 		ic_printf(ic, "%s: failed to start hw: %d\n", __func__, error);
3376 		mtx_destroy(&lvif->mtx);
3377 		free(lvif, M_80211_VAP);
3378 		return (NULL);
3379 	}
3380 
3381 	error = lkpi_80211_mo_add_interface(hw, vif);
3382 	if (error != 0) {
3383 		IMPROVE();	/* XXX-BZ mo_stop()? */
3384 		ic_printf(ic, "%s: failed to add interface: %d\n", __func__, error);
3385 		mtx_destroy(&lvif->mtx);
3386 		free(lvif, M_80211_VAP);
3387 		return (NULL);
3388 	}
3389 
3390 	LKPI_80211_LHW_LVIF_LOCK(lhw);
3391 	TAILQ_INSERT_TAIL(&lhw->lvif_head, lvif, lvif_entry);
3392 	LKPI_80211_LHW_LVIF_UNLOCK(lhw);
3393 
3394 	/* Set bss_info. */
3395 	changed = 0;
3396 	lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed);
3397 
3398 	/* Configure tx queues (conf_tx), default WME & send BSS_CHANGED_QOS. */
3399 	IMPROVE("Hardcoded values; to fix see 802.11-2016, 9.4.2.29 EDCA Parameter Set element");
3400 	LKPI_80211_LHW_LOCK(lhw);
3401 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
3402 
3403 		bzero(&txqp, sizeof(txqp));
3404 		txqp.cw_min = 15;
3405 		txqp.cw_max = 1023;
3406 		txqp.txop = 0;
3407 		txqp.aifs = 2;
3408 		error = lkpi_80211_mo_conf_tx(hw, vif, /* link_id */0, ac, &txqp);
3409 		if (error != 0)
3410 			ic_printf(ic, "%s: conf_tx ac %u failed %d\n",
3411 			    __func__, ac, error);
3412 	}
3413 	LKPI_80211_LHW_UNLOCK(lhw);
3414 	changed = BSS_CHANGED_QOS;
3415 	lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed);
3416 
3417 	/* Force MC init. */
3418 	lkpi_update_mcast_filter(ic, true);
3419 
3420 	IMPROVE();
3421 
3422 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
3423 
3424 	/* Override with LinuxKPI method so we can drive mac80211/cfg80211. */
3425 	lvif->iv_newstate = vap->iv_newstate;
3426 	vap->iv_newstate = lkpi_iv_newstate;
3427 	lvif->iv_update_bss = vap->iv_update_bss;
3428 	vap->iv_update_bss = lkpi_iv_update_bss;
3429 
3430 #ifdef LKPI_80211_HW_CRYPTO
3431 	/* Key management. */
3432 	if (lkpi_hwcrypto && lhw->ops->set_key != NULL) {
3433 		vap->iv_key_set = lkpi_iv_key_set;
3434 		vap->iv_key_delete = lkpi_iv_key_delete;
3435 	}
3436 #endif
3437 
3438 #ifdef LKPI_80211_HT
3439 	/* Stay with the iv_ampdu_rxmax,limit / iv_ampdu_density defaults until later. */
3440 #endif
3441 
3442 	ieee80211_ratectl_init(vap);
3443 
3444 	/* Complete setup. */
3445 	ieee80211_vap_attach(vap, ieee80211_media_change,
3446 	    ieee80211_media_status, mac);
3447 
3448 #ifdef LKPI_80211_HT
3449 	/*
3450 	 * Modern chipset/fw/drv will do A-MPDU in drv/fw and fail
3451 	 * to do so if they cannot do the crypto too.
3452 	 */
3453 	if (!lkpi_hwcrypto && ieee80211_hw_check(hw, AMPDU_AGGREGATION))
3454 		vap->iv_flags_ht &= ~IEEE80211_FHT_AMPDU_RX;
3455 #endif
3456 
3457 	if (hw->max_listen_interval == 0)
3458 		hw->max_listen_interval = 7 * (ic->ic_lintval / ic->ic_bintval);
3459 	hw->conf.listen_interval = hw->max_listen_interval;
3460 	ic->ic_set_channel(ic);
3461 
3462 	/* XXX-BZ do we need to be able to update these? */
3463 	hw->wiphy->frag_threshold = vap->iv_fragthreshold;
3464 	lkpi_80211_mo_set_frag_threshold(hw, vap->iv_fragthreshold);
3465 	hw->wiphy->rts_threshold = vap->iv_rtsthreshold;
3466 	lkpi_80211_mo_set_rts_threshold(hw, vap->iv_rtsthreshold);
3467 	/* any others? */
3468 
3469 	/* Add per-VIF/VAP sysctls. */
3470 	sysctl_ctx_init(&lvif->sysctl_ctx);
3471 
3472 	node = SYSCTL_ADD_NODE(&lvif->sysctl_ctx,
3473 	    SYSCTL_CHILDREN(&sysctl___compat_linuxkpi_80211),
3474 	    OID_AUTO, if_name(vap->iv_ifp),
3475 	    CTLFLAG_RD | CTLFLAG_SKIP | CTLFLAG_MPSAFE, NULL, "VIF Information");
3476 
3477 	SYSCTL_ADD_PROC(&lvif->sysctl_ctx,
3478 	    SYSCTL_CHILDREN(node), OID_AUTO, "dump_stas",
3479 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, lvif, 0,
3480 	    lkpi_80211_dump_stas, "A", "Dump sta statistics of this vif");
3481 
3482 	IMPROVE();
3483 
3484 	return (vap);
3485 }
3486 
3487 void
3488 linuxkpi_ieee80211_unregister_hw(struct ieee80211_hw *hw)
3489 {
3490 
3491 	wiphy_unregister(hw->wiphy);
3492 	linuxkpi_ieee80211_ifdetach(hw);
3493 
3494 	IMPROVE();
3495 }
3496 
3497 void
3498 linuxkpi_ieee80211_restart_hw(struct ieee80211_hw *hw)
3499 {
3500 
3501 	TODO();
3502 }
3503 
3504 static void
3505 lkpi_ic_vap_delete(struct ieee80211vap *vap)
3506 {
3507 	struct ieee80211com *ic;
3508 	struct lkpi_hw *lhw;
3509 	struct ieee80211_hw *hw;
3510 	struct lkpi_vif *lvif;
3511 	struct ieee80211_vif *vif;
3512 
3513 	lvif = VAP_TO_LVIF(vap);
3514 	vif = LVIF_TO_VIF(lvif);
3515 	ic = vap->iv_ic;
3516 	lhw = ic->ic_softc;
3517 	hw = LHW_TO_HW(lhw);
3518 
3519 	EVENTHANDLER_DEREGISTER(iflladdr_event, lvif->lvif_ifllevent);
3520 
3521 	/* Clear up per-VIF/VAP sysctls. */
3522 	sysctl_ctx_free(&lvif->sysctl_ctx);
3523 
3524 	LKPI_80211_LHW_LVIF_LOCK(lhw);
3525 	TAILQ_REMOVE(&lhw->lvif_head, lvif, lvif_entry);
3526 	LKPI_80211_LHW_LVIF_UNLOCK(lhw);
3527 
3528 	ieee80211_ratectl_deinit(vap);
3529 	ieee80211_vap_detach(vap);
3530 
3531 	IMPROVE("clear up other bits in this state");
3532 
3533 	lkpi_80211_mo_remove_interface(hw, vif);
3534 
3535 	/* Single VAP, so we can do this here. */
3536 	lkpi_80211_mo_stop(hw, false);			/* XXX SUSPEND */
3537 
3538 	mtx_destroy(&lvif->mtx);
3539 	free(lvif, M_80211_VAP);
3540 }
3541 
3542 static void
3543 lkpi_ic_update_mcast(struct ieee80211com *ic)
3544 {
3545 
3546 	lkpi_update_mcast_filter(ic, false);
3547 	TRACEOK();
3548 }
3549 
3550 static void
3551 lkpi_ic_update_promisc(struct ieee80211com *ic)
3552 {
3553 
3554 	UNIMPLEMENTED;
3555 }
3556 
3557 static void
3558 lkpi_ic_update_chw(struct ieee80211com *ic)
3559 {
3560 
3561 	UNIMPLEMENTED;
3562 }
3563 
3564 /* Start / stop device. */
3565 static void
3566 lkpi_ic_parent(struct ieee80211com *ic)
3567 {
3568 	struct lkpi_hw *lhw;
3569 #ifdef HW_START_STOP
3570 	struct ieee80211_hw *hw;
3571 	int error;
3572 #endif
3573 	bool start_all;
3574 
3575 	IMPROVE();
3576 
3577 	lhw = ic->ic_softc;
3578 #ifdef HW_START_STOP
3579 	hw = LHW_TO_HW(lhw);
3580 #endif
3581 	start_all = false;
3582 
3583 	/* IEEE80211_UNLOCK(ic); */
3584 	LKPI_80211_LHW_LOCK(lhw);
3585 	if (ic->ic_nrunning > 0) {
3586 #ifdef HW_START_STOP
3587 		error = lkpi_80211_mo_start(hw);
3588 		if (error == 0)
3589 #endif
3590 			start_all = true;
3591 	} else {
3592 #ifdef HW_START_STOP
3593 		lkpi_80211_mo_stop(hw, false);		/* XXX SUSPEND */
3594 #endif
3595 	}
3596 	LKPI_80211_LHW_UNLOCK(lhw);
3597 	/* IEEE80211_LOCK(ic); */
3598 
3599 	if (start_all)
3600 		ieee80211_start_all(ic);
3601 }
3602 
3603 bool
3604 linuxkpi_ieee80211_is_ie_id_in_ie_buf(const u8 ie, const u8 *ie_ids,
3605     size_t ie_ids_len)
3606 {
3607 	int i;
3608 
3609 	for (i = 0; i < ie_ids_len; i++) {
3610 		if (ie == *ie_ids)
3611 			return (true);
3612 	}
3613 
3614 	return (false);
3615 }
3616 
3617 /* Return true if skipped; false if error. */
3618 bool
3619 linuxkpi_ieee80211_ie_advance(size_t *xp, const u8 *ies, size_t ies_len)
3620 {
3621 	size_t x;
3622 	uint8_t l;
3623 
3624 	x = *xp;
3625 
3626 	KASSERT(x < ies_len, ("%s: x %zu ies_len %zu ies %p\n",
3627 	    __func__, x, ies_len, ies));
3628 	l = ies[x + 1];
3629 	x += 2 + l;
3630 
3631 	if (x > ies_len)
3632 		return (false);
3633 
3634 	*xp = x;
3635 	return (true);
3636 }
3637 
3638 static uint8_t *
3639 lkpi_scan_ies_add(uint8_t *p, struct ieee80211_scan_ies *scan_ies,
3640     uint32_t band_mask, struct ieee80211vap *vap, struct ieee80211_hw *hw)
3641 {
3642 	struct ieee80211_supported_band *supband;
3643 	struct linuxkpi_ieee80211_channel *channels;
3644 	struct ieee80211com *ic;
3645 	const struct ieee80211_channel *chan;
3646 	const struct ieee80211_rateset *rs;
3647 	uint8_t *pb;
3648 	int band, i;
3649 
3650 	ic = vap->iv_ic;
3651 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
3652 		if ((band_mask & (1 << band)) == 0)
3653 			continue;
3654 
3655 		supband = hw->wiphy->bands[band];
3656 		/*
3657 		 * This should not happen;
3658 		 * band_mask is a bitmask of valid bands to scan on.
3659 		 */
3660 		if (supband == NULL || supband->n_channels == 0)
3661 			continue;
3662 
3663 		/* Find a first channel to get the mode and rates from. */
3664 		channels = supband->channels;
3665 		chan = NULL;
3666 		for (i = 0; i < supband->n_channels; i++) {
3667 
3668 			if (channels[i].flags & IEEE80211_CHAN_DISABLED)
3669 				continue;
3670 
3671 			chan = ieee80211_find_channel(ic,
3672 			    channels[i].center_freq, 0);
3673 			if (chan != NULL)
3674 				break;
3675 		}
3676 
3677 		/* This really should not happen. */
3678 		if (chan == NULL)
3679 			continue;
3680 
3681 		pb = p;
3682 		rs = ieee80211_get_suprates(ic, chan);	/* calls chan2mode */
3683 		p = ieee80211_add_rates(p, rs);
3684 		p = ieee80211_add_xrates(p, rs);
3685 
3686 #if defined(LKPI_80211_HT)
3687 		if ((vap->iv_flags_ht & IEEE80211_FHT_HT) != 0) {
3688 			struct ieee80211_channel *c;
3689 
3690 			c = ieee80211_ht_adjust_channel(ic, ic->ic_curchan,
3691 			    vap->iv_flags_ht);
3692 			p = ieee80211_add_htcap_ch(p, vap, c);
3693 		}
3694 #endif
3695 #if defined(LKPI_80211_VHT)
3696 		if ((vap->iv_vht_flags & IEEE80211_FVHT_VHT) != 0) {
3697 			struct ieee80211_channel *c;
3698 
3699 			c = ieee80211_ht_adjust_channel(ic, ic->ic_curchan,
3700 			    vap->iv_flags_ht);
3701 			c = ieee80211_vht_adjust_channel(ic, c,
3702 			    vap->iv_vht_flags);
3703 			p = ieee80211_add_vhtcap_ch(p, vap, c);
3704 		}
3705 #endif
3706 
3707 		scan_ies->ies[band] = pb;
3708 		scan_ies->len[band] = p - pb;
3709 	}
3710 
3711 	/* Add common_ies */
3712 	pb = p;
3713 	if ((vap->iv_flags & IEEE80211_F_WPA1) != 0 &&
3714 	    vap->iv_wpa_ie != NULL) {
3715 		memcpy(p, vap->iv_wpa_ie, 2 + vap->iv_wpa_ie[1]);
3716 		p += 2 + vap->iv_wpa_ie[1];
3717 	}
3718 	if (vap->iv_appie_probereq != NULL) {
3719 		memcpy(p, vap->iv_appie_probereq->ie_data,
3720 		    vap->iv_appie_probereq->ie_len);
3721 		p += vap->iv_appie_probereq->ie_len;
3722 	}
3723 	scan_ies->common_ies = pb;
3724 	scan_ies->common_ie_len = p - pb;
3725 
3726 	return (p);
3727 }
3728 
3729 static void
3730 lkpi_ic_scan_start(struct ieee80211com *ic)
3731 {
3732 	struct lkpi_hw *lhw;
3733 	struct ieee80211_hw *hw;
3734 	struct lkpi_vif *lvif;
3735 	struct ieee80211_vif *vif;
3736 	struct ieee80211_scan_state *ss;
3737 	struct ieee80211vap *vap;
3738 	int error;
3739 	bool is_hw_scan;
3740 
3741 	lhw = ic->ic_softc;
3742 	LKPI_80211_LHW_SCAN_LOCK(lhw);
3743 	if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0) {
3744 		/* A scan is still running. */
3745 		LKPI_80211_LHW_SCAN_UNLOCK(lhw);
3746 		return;
3747 	}
3748 	is_hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
3749 	LKPI_80211_LHW_SCAN_UNLOCK(lhw);
3750 
3751 	ss = ic->ic_scan;
3752 	vap = ss->ss_vap;
3753 	if (vap->iv_state != IEEE80211_S_SCAN) {
3754 		IMPROVE("We need to be able to scan if not in S_SCAN");
3755 		return;
3756 	}
3757 
3758 	hw = LHW_TO_HW(lhw);
3759 	if (!is_hw_scan) {
3760 		/* If hw_scan is cleared clear FEXT_SCAN_OFFLOAD too. */
3761 		vap->iv_flags_ext &= ~IEEE80211_FEXT_SCAN_OFFLOAD;
3762 sw_scan:
3763 		lvif = VAP_TO_LVIF(vap);
3764 		vif = LVIF_TO_VIF(lvif);
3765 
3766 		if (vap->iv_state == IEEE80211_S_SCAN)
3767 			lkpi_hw_conf_idle(hw, false);
3768 
3769 		lkpi_80211_mo_sw_scan_start(hw, vif, vif->addr);
3770 		/* net80211::scan_start() handled PS for us. */
3771 		IMPROVE();
3772 		/* XXX Also means it is too late to flush queues?
3773 		 * need to check iv_sta_ps or overload? */
3774 		/* XXX want to adjust ss end time/ maxdwell? */
3775 
3776 	} else {
3777 		struct ieee80211_scan_request *hw_req;
3778 		struct linuxkpi_ieee80211_channel *lc, **cpp;
3779 		struct cfg80211_ssid *ssids;
3780 		struct cfg80211_scan_6ghz_params *s6gp;
3781 		size_t chan_len, nchan, ssids_len, s6ghzlen;
3782 		int band, i, ssid_count, common_ie_len;
3783 		uint32_t band_mask;
3784 		uint8_t *ie, *ieend;
3785 		bool running;
3786 
3787 		ssid_count = min(ss->ss_nssid, hw->wiphy->max_scan_ssids);
3788 		ssids_len = ssid_count * sizeof(*ssids);
3789 		s6ghzlen = 0 * (sizeof(*s6gp));			/* XXX-BZ */
3790 
3791 		band_mask = 0;
3792 		nchan = 0;
3793 		if (ieee80211_hw_check(hw, SINGLE_SCAN_ON_ALL_BANDS)) {
3794 #if 0	/* Avoid net80211 scan lists until it has proper scan offload support. */
3795 			for (i = ss->ss_next; i < ss->ss_last; i++) {
3796 				nchan++;
3797 				band = lkpi_net80211_chan_to_nl80211_band(
3798 				    ss->ss_chans[ss->ss_next + i]);
3799 				band_mask |= (1 << band);
3800 			}
3801 #else
3802 			/* Instead we scan for all channels all the time. */
3803 			for (band = 0; band < NUM_NL80211_BANDS; band++) {
3804 				switch (band) {
3805 				case NL80211_BAND_2GHZ:
3806 				case NL80211_BAND_5GHZ:
3807 					break;
3808 				default:
3809 					continue;
3810 				}
3811 				if (hw->wiphy->bands[band] != NULL) {
3812 					nchan += hw->wiphy->bands[band]->n_channels;
3813 					band_mask |= (1 << band);
3814 				}
3815 			}
3816 #endif
3817 		} else {
3818 			IMPROVE("individual band scans not yet supported, only scanning first band");
3819 			/* In theory net80211 should drive this. */
3820 			/* Probably we need to add local logic for now;
3821 			 * need to deal with scan_complete
3822 			 * and cancel_scan and keep local state.
3823 			 * Also cut the nchan down above.
3824 			 */
3825 			/* XXX-BZ ath10k does not set this but still does it? &$%^ */
3826 		}
3827 
3828 		chan_len = nchan * (sizeof(lc) + sizeof(*lc));
3829 
3830 		common_ie_len = 0;
3831 		if ((vap->iv_flags & IEEE80211_F_WPA1) != 0 &&
3832 		    vap->iv_wpa_ie != NULL)
3833 			common_ie_len += vap->iv_wpa_ie[1];
3834 		if (vap->iv_appie_probereq != NULL)
3835 			common_ie_len += vap->iv_appie_probereq->ie_len;
3836 
3837 		/* We would love to check this at an earlier stage... */
3838 		if (common_ie_len >  hw->wiphy->max_scan_ie_len) {
3839 			ic_printf(ic, "WARNING: %s: common_ie_len %d > "
3840 			    "wiphy->max_scan_ie_len %d\n", __func__,
3841 			    common_ie_len, hw->wiphy->max_scan_ie_len);
3842 		}
3843 
3844 		hw_req = malloc(sizeof(*hw_req) + ssids_len +
3845 		    s6ghzlen + chan_len + lhw->supbands * lhw->scan_ie_len +
3846 		    common_ie_len, M_LKPI80211, M_WAITOK | M_ZERO);
3847 
3848 		hw_req->req.flags = 0;			/* XXX ??? */
3849 		/* hw_req->req.wdev */
3850 		hw_req->req.wiphy = hw->wiphy;
3851 		hw_req->req.no_cck = false;		/* XXX */
3852 #if 0
3853 		/* This seems to pessimise default scanning behaviour. */
3854 		hw_req->req.duration_mandatory = TICKS_2_USEC(ss->ss_mindwell);
3855 		hw_req->req.duration = TICKS_2_USEC(ss->ss_maxdwell);
3856 #endif
3857 #ifdef __notyet__
3858 		hw_req->req.flags |= NL80211_SCAN_FLAG_RANDOM_ADDR;
3859 		memcpy(hw_req->req.mac_addr, xxx, IEEE80211_ADDR_LEN);
3860 		memset(hw_req->req.mac_addr_mask, 0xxx, IEEE80211_ADDR_LEN);
3861 #endif
3862 		eth_broadcast_addr(hw_req->req.bssid);
3863 
3864 		hw_req->req.n_channels = nchan;
3865 		cpp = (struct linuxkpi_ieee80211_channel **)(hw_req + 1);
3866 		lc = (struct linuxkpi_ieee80211_channel *)(cpp + nchan);
3867 		for (i = 0; i < nchan; i++) {
3868 			*(cpp + i) =
3869 			    (struct linuxkpi_ieee80211_channel *)(lc + i);
3870 		}
3871 #if 0	/* Avoid net80211 scan lists until it has proper scan offload support. */
3872 		for (i = 0; i < nchan; i++) {
3873 			struct ieee80211_channel *c;
3874 
3875 			c = ss->ss_chans[ss->ss_next + i];
3876 			lc->hw_value = c->ic_ieee;
3877 			lc->center_freq = c->ic_freq;	/* XXX */
3878 			/* lc->flags */
3879 			lc->band = lkpi_net80211_chan_to_nl80211_band(c);
3880 			lc->max_power = c->ic_maxpower;
3881 			/* lc-> ... */
3882 			lc++;
3883 		}
3884 #else
3885 		for (band = 0; band < NUM_NL80211_BANDS; band++) {
3886 			struct ieee80211_supported_band *supband;
3887 			struct linuxkpi_ieee80211_channel *channels;
3888 
3889 			/* Band disabled for scanning? */
3890 			if ((band_mask & (1 << band)) == 0)
3891 				continue;
3892 
3893 			/* Nothing to scan in band? */
3894 			supband = hw->wiphy->bands[band];
3895 			if (supband == NULL || supband->n_channels == 0)
3896 				continue;
3897 
3898 			channels = supband->channels;
3899 			for (i = 0; i < supband->n_channels; i++) {
3900 				*lc = channels[i];
3901 				lc++;
3902 			}
3903 		}
3904 #endif
3905 
3906 		hw_req->req.n_ssids = ssid_count;
3907 		if (hw_req->req.n_ssids > 0) {
3908 			ssids = (struct cfg80211_ssid *)lc;
3909 			hw_req->req.ssids = ssids;
3910 			for (i = 0; i < ssid_count; i++) {
3911 				ssids->ssid_len = ss->ss_ssid[i].len;
3912 				memcpy(ssids->ssid, ss->ss_ssid[i].ssid,
3913 				    ss->ss_ssid[i].len);
3914 				ssids++;
3915 			}
3916 			s6gp = (struct cfg80211_scan_6ghz_params *)ssids;
3917 		} else {
3918 			s6gp = (struct cfg80211_scan_6ghz_params *)lc;
3919 		}
3920 
3921 		/* 6GHz one day. */
3922 		hw_req->req.n_6ghz_params = 0;
3923 		hw_req->req.scan_6ghz_params = NULL;
3924 		hw_req->req.scan_6ghz = false;	/* Weird boolean; not what you think. */
3925 		/* s6gp->... */
3926 
3927 		ie = ieend = (uint8_t *)s6gp;
3928 		/* Copy per-band IEs, copy common IEs */
3929 		ieend = lkpi_scan_ies_add(ie, &hw_req->ies, band_mask, vap, hw);
3930 		hw_req->req.ie = ie;
3931 		hw_req->req.ie_len = ieend - ie;
3932 
3933 		lvif = VAP_TO_LVIF(vap);
3934 		vif = LVIF_TO_VIF(lvif);
3935 
3936 		LKPI_80211_LHW_SCAN_LOCK(lhw);
3937 		/* Re-check under lock. */
3938 		running = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
3939 		if (!running) {
3940 			KASSERT(lhw->hw_req == NULL, ("%s: ic %p lhw %p hw_req %p "
3941 			    "!= NULL\n", __func__, ic, lhw, lhw->hw_req));
3942 
3943 			lhw->scan_flags |= LKPI_LHW_SCAN_RUNNING;
3944 			lhw->hw_req = hw_req;
3945 		}
3946 		LKPI_80211_LHW_SCAN_UNLOCK(lhw);
3947 		if (running) {
3948 			free(hw_req, M_LKPI80211);
3949 			return;
3950 		}
3951 
3952 		error = lkpi_80211_mo_hw_scan(hw, vif, hw_req);
3953 		if (error != 0) {
3954 			ieee80211_cancel_scan(vap);
3955 
3956 			/*
3957 			 * ieee80211_scan_completed must be called in either
3958 			 * case of error or none.  So let the free happen there
3959 			 * and only there.
3960 			 * That would be fine in theory but in practice drivers
3961 			 * behave differently:
3962 			 * ath10k does not return hw_scan until after scan_complete
3963 			 *        and can then still return an error.
3964 			 * rtw88 can return 1 or -EBUSY without scan_complete
3965 			 * iwlwifi can return various errors before scan starts
3966 			 * ...
3967 			 * So we cannot rely on that behaviour and have to check
3968 			 * and balance between both code paths.
3969 			 */
3970 			LKPI_80211_LHW_SCAN_LOCK(lhw);
3971 			if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0) {
3972 				free(lhw->hw_req, M_LKPI80211);
3973 				lhw->hw_req = NULL;
3974 				lhw->scan_flags &= ~LKPI_LHW_SCAN_RUNNING;
3975 			}
3976 			LKPI_80211_LHW_SCAN_UNLOCK(lhw);
3977 
3978 			/*
3979 			 * XXX-SIGH magic number.
3980 			 * rtw88 has a magic "return 1" if offloading scan is
3981 			 * not possible.  Fall back to sw scan in that case.
3982 			 */
3983 			if (error == 1) {
3984 				LKPI_80211_LHW_SCAN_LOCK(lhw);
3985 				lhw->scan_flags &= ~LKPI_LHW_SCAN_HW;
3986 				LKPI_80211_LHW_SCAN_UNLOCK(lhw);
3987 				/*
3988 				 * XXX If we clear this now and later a driver
3989 				 * thinks it * can do a hw_scan again, we will
3990 				 * currently not re-enable it?
3991 				 */
3992 				vap->iv_flags_ext &= ~IEEE80211_FEXT_SCAN_OFFLOAD;
3993 				ieee80211_start_scan(vap,
3994 				    IEEE80211_SCAN_ACTIVE |
3995 				    IEEE80211_SCAN_NOPICK |
3996 				    IEEE80211_SCAN_ONCE,
3997 				    IEEE80211_SCAN_FOREVER,
3998 				    ss->ss_mindwell ? ss->ss_mindwell : msecs_to_ticks(20),
3999 				    ss->ss_maxdwell ? ss->ss_maxdwell : msecs_to_ticks(200),
4000 				    vap->iv_des_nssid, vap->iv_des_ssid);
4001 				goto sw_scan;
4002 			}
4003 
4004 			ic_printf(ic, "ERROR: %s: hw_scan returned %d\n",
4005 			    __func__, error);
4006 		}
4007 	}
4008 }
4009 
4010 static void
4011 lkpi_ic_scan_end(struct ieee80211com *ic)
4012 {
4013 	struct lkpi_hw *lhw;
4014 	bool is_hw_scan;
4015 
4016 	lhw = ic->ic_softc;
4017 	LKPI_80211_LHW_SCAN_LOCK(lhw);
4018 	if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) == 0) {
4019 		LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4020 		return;
4021 	}
4022 	is_hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
4023 	LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4024 
4025 	if (!is_hw_scan) {
4026 		struct ieee80211_scan_state *ss;
4027 		struct ieee80211vap *vap;
4028 		struct ieee80211_hw *hw;
4029 		struct lkpi_vif *lvif;
4030 		struct ieee80211_vif *vif;
4031 
4032 		ss = ic->ic_scan;
4033 		vap = ss->ss_vap;
4034 		hw = LHW_TO_HW(lhw);
4035 		lvif = VAP_TO_LVIF(vap);
4036 		vif = LVIF_TO_VIF(lvif);
4037 
4038 		lkpi_80211_mo_sw_scan_complete(hw, vif);
4039 
4040 		/* Send PS to stop buffering if n80211 does not for us? */
4041 
4042 		if (vap->iv_state == IEEE80211_S_SCAN)
4043 			lkpi_hw_conf_idle(hw, true);
4044 	}
4045 }
4046 
4047 static void
4048 lkpi_ic_scan_curchan(struct ieee80211_scan_state *ss,
4049     unsigned long maxdwell)
4050 {
4051 	struct lkpi_hw *lhw;
4052 	bool is_hw_scan;
4053 
4054 	lhw = ss->ss_ic->ic_softc;
4055 	LKPI_80211_LHW_SCAN_LOCK(lhw);
4056 	is_hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
4057 	LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4058 	if (!is_hw_scan)
4059 		lhw->ic_scan_curchan(ss, maxdwell);
4060 }
4061 
4062 static void
4063 lkpi_ic_scan_mindwell(struct ieee80211_scan_state *ss)
4064 {
4065 	struct lkpi_hw *lhw;
4066 	bool is_hw_scan;
4067 
4068 	lhw = ss->ss_ic->ic_softc;
4069 	LKPI_80211_LHW_SCAN_LOCK(lhw);
4070 	is_hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
4071 	LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4072 	if (!is_hw_scan)
4073 		lhw->ic_scan_mindwell(ss);
4074 }
4075 
4076 static void
4077 lkpi_ic_set_channel(struct ieee80211com *ic)
4078 {
4079 	struct lkpi_hw *lhw;
4080 	struct ieee80211_hw *hw;
4081 	struct ieee80211_channel *c;
4082 	struct linuxkpi_ieee80211_channel *chan;
4083 	int error;
4084 	bool hw_scan_running;
4085 
4086 	lhw = ic->ic_softc;
4087 
4088 	/* If we do not support (*config)() save us the work. */
4089 	if (lhw->ops->config == NULL)
4090 		return;
4091 
4092 	/* If we have a hw_scan running do not switch channels. */
4093 	LKPI_80211_LHW_SCAN_LOCK(lhw);
4094 	hw_scan_running =
4095 	    (lhw->scan_flags & (LKPI_LHW_SCAN_RUNNING|LKPI_LHW_SCAN_HW)) ==
4096 		(LKPI_LHW_SCAN_RUNNING|LKPI_LHW_SCAN_HW);
4097 	LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4098 	if (hw_scan_running)
4099 		return;
4100 
4101 	c = ic->ic_curchan;
4102 	if (c == NULL || c == IEEE80211_CHAN_ANYC) {
4103 		ic_printf(ic, "%s: c %p ops->config %p\n", __func__,
4104 		    c, lhw->ops->config);
4105 		return;
4106 	}
4107 
4108 	chan = lkpi_find_lkpi80211_chan(lhw, c);
4109 	if (chan == NULL) {
4110 		ic_printf(ic, "%s: c %p chan %p\n", __func__,
4111 		    c, chan);
4112 		return;
4113 	}
4114 
4115 	/* XXX max power for scanning? */
4116 	IMPROVE();
4117 
4118 	hw = LHW_TO_HW(lhw);
4119 	cfg80211_chandef_create(&hw->conf.chandef, chan,
4120 #ifdef LKPI_80211_HT
4121 	    (ic->ic_htcaps & IEEE80211_HTC_HT) ? 0 :
4122 #endif
4123 	    NL80211_CHAN_NO_HT);
4124 
4125 	error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_CHANNEL);
4126 	if (error != 0 && error != EOPNOTSUPP) {
4127 		ic_printf(ic, "ERROR: %s: config %#0x returned %d\n",
4128 		    __func__, IEEE80211_CONF_CHANGE_CHANNEL, error);
4129 		/* XXX should we unroll to the previous chandef? */
4130 		IMPROVE();
4131 	} else {
4132 		/* Update radiotap channels as well. */
4133 		lhw->rtap_tx.wt_chan_freq = htole16(c->ic_freq);
4134 		lhw->rtap_tx.wt_chan_flags = htole16(c->ic_flags);
4135 		lhw->rtap_rx.wr_chan_freq = htole16(c->ic_freq);
4136 		lhw->rtap_rx.wr_chan_flags = htole16(c->ic_flags);
4137 	}
4138 
4139 	/* Currently PS is hard coded off! Not sure it belongs here. */
4140 	IMPROVE();
4141 	if (ieee80211_hw_check(hw, SUPPORTS_PS) &&
4142 	    (hw->conf.flags & IEEE80211_CONF_PS) != 0) {
4143 		hw->conf.flags &= ~IEEE80211_CONF_PS;
4144 		error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_PS);
4145 		if (error != 0 && error != EOPNOTSUPP)
4146 			ic_printf(ic, "ERROR: %s: config %#0x returned "
4147 			    "%d\n", __func__, IEEE80211_CONF_CHANGE_PS,
4148 			    error);
4149 	}
4150 }
4151 
4152 static struct ieee80211_node *
4153 lkpi_ic_node_alloc(struct ieee80211vap *vap,
4154     const uint8_t mac[IEEE80211_ADDR_LEN])
4155 {
4156 	struct ieee80211com *ic;
4157 	struct lkpi_hw *lhw;
4158 	struct ieee80211_node *ni;
4159 	struct ieee80211_hw *hw;
4160 	struct lkpi_sta *lsta;
4161 
4162 	ic = vap->iv_ic;
4163 	lhw = ic->ic_softc;
4164 
4165 	/* We keep allocations de-coupled so we can deal with the two worlds. */
4166 	if (lhw->ic_node_alloc == NULL)
4167 		return (NULL);
4168 
4169 	ni = lhw->ic_node_alloc(vap, mac);
4170 	if (ni == NULL)
4171 		return (NULL);
4172 
4173 	hw = LHW_TO_HW(lhw);
4174 	lsta = lkpi_lsta_alloc(vap, mac, hw, ni);
4175 	if (lsta == NULL) {
4176 		if (lhw->ic_node_free != NULL)
4177 			lhw->ic_node_free(ni);
4178 		return (NULL);
4179 	}
4180 
4181 	return (ni);
4182 }
4183 
4184 static int
4185 lkpi_ic_node_init(struct ieee80211_node *ni)
4186 {
4187 	struct ieee80211com *ic;
4188 	struct lkpi_hw *lhw;
4189 	int error;
4190 
4191 	ic = ni->ni_ic;
4192 	lhw = ic->ic_softc;
4193 
4194 	if (lhw->ic_node_init != NULL) {
4195 		error = lhw->ic_node_init(ni);
4196 		if (error != 0)
4197 			return (error);
4198 	}
4199 
4200 	/* XXX-BZ Sync other state over. */
4201 	IMPROVE();
4202 
4203 	return (0);
4204 }
4205 
4206 static void
4207 lkpi_ic_node_cleanup(struct ieee80211_node *ni)
4208 {
4209 	struct ieee80211com *ic;
4210 	struct lkpi_hw *lhw;
4211 
4212 	ic = ni->ni_ic;
4213 	lhw = ic->ic_softc;
4214 
4215 	/* XXX-BZ remove from driver, ... */
4216 	IMPROVE();
4217 
4218 	if (lhw->ic_node_cleanup != NULL)
4219 		lhw->ic_node_cleanup(ni);
4220 }
4221 
4222 static void
4223 lkpi_ic_node_free(struct ieee80211_node *ni)
4224 {
4225 	struct ieee80211com *ic;
4226 	struct lkpi_hw *lhw;
4227 	struct lkpi_sta *lsta;
4228 
4229 	ic = ni->ni_ic;
4230 	lhw = ic->ic_softc;
4231 	lsta = ni->ni_drv_data;
4232 
4233 	/* KASSERT lsta is not NULL here. Print ni/ni__refcnt. */
4234 
4235 	/*
4236 	 * Pass in the original ni just in case of error we could check that
4237 	 * it is the same as lsta->ni.
4238 	 */
4239 	lkpi_lsta_free(lsta, ni);
4240 
4241 	if (lhw->ic_node_free != NULL)
4242 		lhw->ic_node_free(ni);
4243 }
4244 
4245 static int
4246 lkpi_ic_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
4247         const struct ieee80211_bpf_params *params __unused)
4248 {
4249 	struct lkpi_sta *lsta;
4250 
4251 	lsta = ni->ni_drv_data;
4252 	LKPI_80211_LSTA_TXQ_LOCK(lsta);
4253 #if 0
4254 	if (!lsta->added_to_drv || !lsta->txq_ready) {
4255 #else
4256 	/*
4257 	 * Backout this part of 886653492945f which breaks rtw88 or
4258 	 * in general drivers without (*sta_state)() but only the
4259 	 * legacy fallback to (*sta_add)().
4260 	 */
4261 	if (!lsta->txq_ready) {
4262 #endif
4263 		LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
4264 		/*
4265 		 * Free the mbuf (do NOT release ni ref for the m_pkthdr.rcvif!
4266 		 * ieee80211_raw_output() does that in case of error).
4267 		 */
4268 		m_free(m);
4269 		return (ENETDOWN);
4270 	}
4271 
4272 	/* Queue the packet and enqueue the task to handle it. */
4273 	mbufq_enqueue(&lsta->txq, m);
4274 	taskqueue_enqueue(taskqueue_thread, &lsta->txq_task);
4275 	LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
4276 
4277 #ifdef LINUXKPI_DEBUG_80211
4278 	if (linuxkpi_debug_80211 & D80211_TRACE_TX)
4279 		printf("%s:%d lsta %p ni %p %6D mbuf_qlen %d\n",
4280 		    __func__, __LINE__, lsta, ni, ni->ni_macaddr, ":",
4281 		    mbufq_len(&lsta->txq));
4282 #endif
4283 
4284 	return (0);
4285 }
4286 
4287 #ifdef LKPI_80211_HW_CRYPTO
4288 static int
4289 lkpi_hw_crypto_prepare(struct lkpi_sta *lsta, struct ieee80211_key *k,
4290     struct sk_buff *skb)
4291 {
4292 	struct ieee80211_tx_info *info;
4293 	struct ieee80211_key_conf *kc;
4294 	struct ieee80211_hdr *hdr;
4295 	uint32_t hlen, hdrlen;
4296 	uint8_t *p;
4297 
4298 	KASSERT(lsta != NULL, ("%s: lsta is NULL", __func__));
4299 	KASSERT(k != NULL, ("%s: key is NULL", __func__));
4300 	KASSERT(skb != NULL, ("%s: skb is NULL", __func__));
4301 
4302 	kc = lsta->kc[k->wk_keyix];
4303 
4304 	info = IEEE80211_SKB_CB(skb);
4305 	info->control.hw_key = kc;
4306 
4307 	/* MUST NOT happen. KASSERT? */
4308 	if (kc == NULL) {
4309 		ic_printf(lsta->ni->ni_ic, "%s: lsta %p k %p skb %p, "
4310 		    "kc is NULL on hw crypto offload\n", __func__, lsta, k, skb);
4311 		return (ENXIO);
4312 	}
4313 
4314 
4315 	IMPROVE("the following should be WLAN_CIPHER_SUITE specific");
4316 	/* We currently only support CCMP so we hardcode things here. */
4317 
4318 	hdr = (void *)skb->data;
4319 
4320 	/*
4321 	 * Check if we have anythig to do as requested by driver
4322 	 * or if we are done?
4323 	 */
4324 	if ((kc->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) == 0 &&
4325 	    (kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV) == 0 &&
4326 	    /* MFP */
4327 	    !((kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) != 0 &&
4328 		ieee80211_is_mgmt(hdr->frame_control)))
4329 			return (0);
4330 
4331 	hlen = k->wk_cipher->ic_header;
4332 	if (skb_headroom(skb) < hlen)
4333 		return (ENOSPC);
4334 
4335 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
4336 	p = skb_push(skb, hlen);
4337 	memmove(p, p + hlen, hdrlen);
4338 
4339 	/* If driver request space only we are done. */
4340 	if ((kc->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) != 0)
4341 		return (0);
4342 
4343 	p += hdrlen;
4344 	k->wk_cipher->ic_setiv(k, p);
4345 
4346 	return (0);
4347 }
4348 #endif
4349 
4350 static void
4351 lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
4352 {
4353 	struct ieee80211_node *ni;
4354 	struct ieee80211_frame *wh;
4355 	struct ieee80211_key *k;
4356 	struct sk_buff *skb;
4357 	struct ieee80211com *ic;
4358 	struct lkpi_hw *lhw;
4359 	struct ieee80211_hw *hw;
4360 	struct lkpi_vif *lvif;
4361 	struct ieee80211_vif *vif;
4362 	struct ieee80211_channel *c;
4363 	struct ieee80211_tx_control control;
4364 	struct ieee80211_tx_info *info;
4365 	struct ieee80211_sta *sta;
4366 	struct ieee80211_hdr *hdr;
4367 	struct lkpi_txq *ltxq;
4368 	void *buf;
4369 	ieee80211_keyix keyix;
4370 	uint8_t ac, tid;
4371 
4372 	M_ASSERTPKTHDR(m);
4373 #ifdef LINUXKPI_DEBUG_80211
4374 	if (linuxkpi_debug_80211 & D80211_TRACE_TX_DUMP)
4375 		hexdump(mtod(m, const void *), m->m_len, "RAW TX (plain) ", 0);
4376 #endif
4377 
4378 	ni = lsta->ni;
4379 	k = NULL;
4380 	keyix = IEEE80211_KEYIX_NONE;
4381 	wh = mtod(m, struct ieee80211_frame *);
4382 	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
4383 
4384 #ifdef LKPI_80211_HW_CRYPTO
4385 		if (lkpi_hwcrypto) {
4386 			k = ieee80211_crypto_get_txkey(ni, m);
4387 			if (k != NULL && lsta->kc[k->wk_keyix] != NULL)
4388 				keyix = k->wk_keyix;
4389 		}
4390 #endif
4391 
4392 		/* Encrypt the frame if need be. */
4393 		if (keyix == IEEE80211_KEYIX_NONE) {
4394 			/* Retrieve key for TX && do software encryption. */
4395 			k = ieee80211_crypto_encap(ni, m);
4396 			if (k == NULL) {
4397 				ieee80211_free_node(ni);
4398 				m_freem(m);
4399 				return;
4400 			}
4401 		}
4402 	}
4403 
4404 	ic = ni->ni_ic;
4405 	lhw = ic->ic_softc;
4406 	hw = LHW_TO_HW(lhw);
4407 	c = ni->ni_chan;
4408 
4409 	if (ieee80211_radiotap_active_vap(ni->ni_vap)) {
4410 		struct lkpi_radiotap_tx_hdr *rtap;
4411 
4412 		rtap = &lhw->rtap_tx;
4413 		rtap->wt_flags = 0;
4414 		if (k != NULL)
4415 			rtap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
4416 		if (m->m_flags & M_FRAG)
4417 			rtap->wt_flags |= IEEE80211_RADIOTAP_F_FRAG;
4418 		IMPROVE();
4419 		rtap->wt_rate = 0;
4420 		if (c != NULL && c != IEEE80211_CHAN_ANYC) {
4421 			rtap->wt_chan_freq = htole16(c->ic_freq);
4422 			rtap->wt_chan_flags = htole16(c->ic_flags);
4423 		}
4424 
4425 		ieee80211_radiotap_tx(ni->ni_vap, m);
4426 	}
4427 
4428 	/*
4429 	 * net80211 should handle hw->extra_tx_headroom.
4430 	 * Though for as long as we are copying we don't mind.
4431 	 * XXX-BZ rtw88 asks for too much headroom for ipv6+tcp:
4432 	 * https://lists.freebsd.org/archives/freebsd-transport/2022-February/000012.html
4433 	 */
4434 	skb = dev_alloc_skb(hw->extra_tx_headroom + m->m_pkthdr.len);
4435 	if (skb == NULL) {
4436 		static uint8_t skb_alloc_failures = 0;
4437 
4438 		if (skb_alloc_failures++ == 0) {
4439 			int tid;
4440 
4441 			sta = LSTA_TO_STA(lsta);
4442 			ic_printf(ic, "ERROR %s: skb alloc failed %d + %d, lsta %p sta %p ni %p\n",
4443 			    __func__, hw->extra_tx_headroom, m->m_pkthdr.len, lsta, sta, ni);
4444 			for (tid = 0; tid < nitems(sta->txq); tid++) {
4445 				if (sta->txq[tid] == NULL)
4446 					continue;
4447 				ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
4448 				ic_printf(ic, "  tid %d ltxq %p seen_dequeue %d stopped %d skb_queue_len %u\n",
4449 				    tid, ltxq, ltxq->seen_dequeue, ltxq->stopped, skb_queue_len(&ltxq->skbq));
4450 			}
4451 		}
4452 		ieee80211_free_node(ni);
4453 		m_freem(m);
4454 		return;
4455 	}
4456 	skb_reserve(skb, hw->extra_tx_headroom);
4457 
4458 	/* XXX-BZ we need a SKB version understanding mbuf. */
4459 	/* Save the mbuf for ieee80211_tx_complete(). */
4460 	skb->m_free_func = lkpi_ieee80211_free_skb_mbuf;
4461 	skb->m = m;
4462 #if 0
4463 	skb_put_data(skb, m->m_data, m->m_pkthdr.len);
4464 #else
4465 	buf = skb_put(skb, m->m_pkthdr.len);
4466 	m_copydata(m, 0, m->m_pkthdr.len, buf);
4467 #endif
4468 	/* Save the ni. */
4469 	m->m_pkthdr.PH_loc.ptr = ni;
4470 
4471 	lvif = VAP_TO_LVIF(ni->ni_vap);
4472 	vif = LVIF_TO_VIF(lvif);
4473 
4474 	hdr = (void *)skb->data;
4475 	tid = linuxkpi_ieee80211_get_tid(hdr, true);
4476 	if (tid == IEEE80211_NONQOS_TID) { /* == IEEE80211_NUM_TIDS */
4477 		if (!ieee80211_is_data(hdr->frame_control)) {
4478 			/* MGMT and CTRL frames go on TID 7/VO. */
4479 			skb->priority = 7;
4480 			ac = IEEE80211_AC_VO;
4481 		} else {
4482 			/* Other non-QOS traffic goes to BE. */
4483 			/* Contrary to net80211 we MUST NOT promote M_EAPOL. */
4484 			skb->priority = 0;
4485 			ac = IEEE80211_AC_BE;
4486 		}
4487 	} else {
4488 		skb->priority = tid & IEEE80211_QOS_CTL_TID_MASK;
4489 		ac = ieee80211e_up_to_ac[tid & 7];
4490 	}
4491 	skb_set_queue_mapping(skb, ac);
4492 
4493 	info = IEEE80211_SKB_CB(skb);
4494 	info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
4495 	/* Slight delay; probably only happens on scanning so fine? */
4496 	if (c == NULL || c == IEEE80211_CHAN_ANYC)
4497 		c = ic->ic_curchan;
4498 	info->band = lkpi_net80211_chan_to_nl80211_band(c);
4499 	info->hw_queue = vif->hw_queue[ac];
4500 	if (m->m_flags & M_EAPOL)
4501 		info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
4502 	info->control.vif = vif;
4503 	/* XXX-BZ info->control.rates */
4504 #ifdef __notyet__
4505 #ifdef LKPI_80211_HT
4506 	info->control.rts_cts_rate_idx=
4507 	info->control.use_rts= /* RTS */
4508 	info->control.use_cts_prot= /* RTS/CTS*/
4509 #endif
4510 #endif
4511 
4512 	sta = LSTA_TO_STA(lsta);
4513 #ifdef LKPI_80211_HW_CRYPTO
4514 	if (lkpi_hwcrypto && keyix != IEEE80211_KEYIX_NONE) {
4515 		int error;
4516 
4517 		error = lkpi_hw_crypto_prepare(lsta, k, skb);
4518 		if (error != 0) {
4519 			/*
4520 			 * We only have to free the skb which will free the
4521 			 * mbuf and release the reference on the ni.
4522 			 */
4523 			dev_kfree_skb(skb);
4524 			return;
4525 		}
4526 	}
4527 #endif
4528 
4529 	IMPROVE();
4530 
4531 	ltxq = NULL;
4532 	if (!ieee80211_is_data_present(hdr->frame_control)) {
4533 		if (vif->type == NL80211_IFTYPE_STATION &&
4534 		    lsta->added_to_drv &&
4535 		    sta->txq[IEEE80211_NUM_TIDS] != NULL)
4536 			ltxq = TXQ_TO_LTXQ(sta->txq[IEEE80211_NUM_TIDS]);
4537 	} else if (lsta->added_to_drv &&
4538 	    sta->txq[skb->priority] != NULL) {
4539 		ltxq = TXQ_TO_LTXQ(sta->txq[skb->priority]);
4540 	}
4541 	if (ltxq == NULL)
4542 		goto ops_tx;
4543 
4544 	KASSERT(ltxq != NULL, ("%s: lsta %p sta %p m %p skb %p "
4545 	    "ltxq %p != NULL\n", __func__, lsta, sta, m, skb, ltxq));
4546 
4547 	LKPI_80211_LTXQ_LOCK(ltxq);
4548 	skb_queue_tail(&ltxq->skbq, skb);
4549 #ifdef LINUXKPI_DEBUG_80211
4550 	if (linuxkpi_debug_80211 & D80211_TRACE_TX)
4551 		printf("%s:%d mo_wake_tx_queue :: %d %u lsta %p sta %p "
4552 		    "ni %p %6D skb %p lxtq %p { qlen %u, ac %d tid %u } "
4553 		    "WAKE_TX_Q ac %d prio %u qmap %u\n",
4554 		    __func__, __LINE__,
4555 		    curthread->td_tid, (unsigned int)ticks,
4556 		    lsta, sta, ni, ni->ni_macaddr, ":", skb, ltxq,
4557 		    skb_queue_len(&ltxq->skbq), ltxq->txq.ac,
4558 		    ltxq->txq.tid, ac, skb->priority, skb->qmap);
4559 #endif
4560 	LKPI_80211_LTXQ_UNLOCK(ltxq);
4561 	LKPI_80211_LHW_LOCK(lhw);
4562 	lkpi_80211_mo_wake_tx_queue(hw, &ltxq->txq);
4563 	LKPI_80211_LHW_UNLOCK(lhw);
4564 	return;
4565 
4566 ops_tx:
4567 #ifdef LINUXKPI_DEBUG_80211
4568 	if (linuxkpi_debug_80211 & D80211_TRACE_TX)
4569 		printf("%s:%d mo_tx :: lsta %p sta %p ni %p %6D skb %p "
4570 		    "TX ac %d prio %u qmap %u\n",
4571 		    __func__, __LINE__, lsta, sta, ni, ni->ni_macaddr, ":",
4572 		    skb, ac, skb->priority, skb->qmap);
4573 #endif
4574 	memset(&control, 0, sizeof(control));
4575 	control.sta = sta;
4576 	LKPI_80211_LHW_LOCK(lhw);
4577 	lkpi_80211_mo_tx(hw, &control, skb);
4578 	LKPI_80211_LHW_UNLOCK(lhw);
4579 }
4580 
4581 static void
4582 lkpi_80211_txq_task(void *ctx, int pending)
4583 {
4584 	struct lkpi_sta *lsta;
4585 	struct mbufq mq;
4586 	struct mbuf *m;
4587 	bool shall_tx;
4588 
4589 	lsta = ctx;
4590 
4591 #ifdef LINUXKPI_DEBUG_80211
4592 	if (linuxkpi_debug_80211 & D80211_TRACE_TX)
4593 		printf("%s:%d lsta %p ni %p %6D pending %d mbuf_qlen %d\n",
4594 		    __func__, __LINE__, lsta, lsta->ni, lsta->ni->ni_macaddr, ":",
4595 		    pending, mbufq_len(&lsta->txq));
4596 #endif
4597 
4598 	mbufq_init(&mq, IFQ_MAXLEN);
4599 
4600 	LKPI_80211_LSTA_TXQ_LOCK(lsta);
4601 	/*
4602 	 * Do not re-check lsta->txq_ready here; we may have a pending
4603 	 * disassoc/deauth frame still.  On the contrary if txq_ready is
4604 	 * false we do not have a valid sta anymore in the firmware so no
4605 	 * point to try to TX.
4606 	 * We also use txq_ready as a semaphore and will drain the txq manually
4607 	 * if needed on our way towards SCAN/INIT in the state machine.
4608 	 */
4609 #if 0
4610 	shall_tx = lsta->added_to_drv && lsta->txq_ready;
4611 #else
4612 	/*
4613 	 * Backout this part of 886653492945f which breaks rtw88 or
4614 	 * in general drivers without (*sta_state)() but only the
4615 	 * legacy fallback to (*sta_add)().
4616 	 */
4617 	shall_tx = lsta->txq_ready;
4618 #endif
4619 	if (__predict_true(shall_tx))
4620 		mbufq_concat(&mq, &lsta->txq);
4621 	/*
4622 	 * else a state change will push the packets out manually or
4623 	 * lkpi_lsta_free() will drain the lsta->txq and free the mbufs.
4624 	 */
4625 	LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
4626 
4627 	m = mbufq_dequeue(&mq);
4628 	while (m != NULL) {
4629 		lkpi_80211_txq_tx_one(lsta, m);
4630 		m = mbufq_dequeue(&mq);
4631 	}
4632 }
4633 
4634 static int
4635 lkpi_ic_transmit(struct ieee80211com *ic, struct mbuf *m)
4636 {
4637 
4638 	/* XXX TODO */
4639 	IMPROVE();
4640 
4641 	/* Quick and dirty cheating hack. */
4642 	struct ieee80211_node *ni;
4643 
4644 	ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
4645 	return (lkpi_ic_raw_xmit(ni, m, NULL));
4646 }
4647 
4648 #ifdef LKPI_80211_HT
4649 static int
4650 lkpi_ic_recv_action(struct ieee80211_node *ni, const struct ieee80211_frame *wh,
4651     const uint8_t *frm, const uint8_t *efrm)
4652 {
4653 	struct ieee80211com *ic;
4654 	struct lkpi_hw *lhw;
4655 
4656 	ic = ni->ni_ic;
4657 	lhw = ic->ic_softc;
4658 
4659 	IMPROVE_HT("recv_action called; nothing to do in lkpi; make debugging");
4660 
4661 	return (lhw->ic_recv_action(ni, wh, frm, efrm));
4662 }
4663 
4664 static int
4665 lkpi_ic_send_action(struct ieee80211_node *ni, int category, int action, void *sa)
4666 {
4667 	struct ieee80211com *ic;
4668 	struct lkpi_hw *lhw;
4669 
4670 	ic = ni->ni_ic;
4671 	lhw = ic->ic_softc;
4672 
4673 	IMPROVE_HT("send_action called; nothing to do in lkpi; make debugging");
4674 
4675 	return (lhw->ic_send_action(ni, category, action, sa));
4676 }
4677 
4678 
4679 static int
4680 lkpi_ic_ampdu_enable(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
4681 {
4682 	struct ieee80211com *ic;
4683 	struct lkpi_hw *lhw;
4684 
4685 	ic = ni->ni_ic;
4686 	lhw = ic->ic_softc;
4687 
4688 	IMPROVE_HT("ieee80211_ampdu_enable called; nothing to do in lkpi for now; make debugging");
4689 
4690 	return (lhw->ic_ampdu_enable(ni, tap));
4691 }
4692 
4693 /*
4694  * (*ic_addba_request)() is called by ieee80211_ampdu_request() before
4695  * calling send_action(CAT_BA, BA_ADDBA_REQUEST).
4696  *
4697  * NB: returns 0 on ERROR!
4698  */
4699 static int
4700 lkpi_ic_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
4701     int dialogtoken, int baparamset, int batimeout)
4702 {
4703 	struct ieee80211com *ic;
4704 	struct lkpi_hw *lhw;
4705 	struct ieee80211_hw *hw;
4706 	struct ieee80211vap *vap;
4707 	struct lkpi_vif *lvif;
4708 	struct ieee80211_vif *vif;
4709 	struct lkpi_sta *lsta;
4710 	struct ieee80211_sta *sta;
4711 	struct ieee80211_ampdu_params params = { };
4712 	int error;
4713 
4714 	ic = ni->ni_ic;
4715 	lhw = ic->ic_softc;
4716 	hw = LHW_TO_HW(lhw);
4717 	vap = ni->ni_vap;
4718 	lvif = VAP_TO_LVIF(vap);
4719 	vif = LVIF_TO_VIF(lvif);
4720 	lsta = ni->ni_drv_data;
4721 	sta = LSTA_TO_STA(lsta);
4722 
4723 	if (!lsta->added_to_drv) {
4724 		ic_printf(ic, "%s: lsta %p ni %p, sta %p not added to firmware\n",
4725 		    __func__, lsta, ni, sta);
4726 		return (0);
4727 	}
4728 
4729 	params.sta = sta;
4730 	params.action = IEEE80211_AMPDU_TX_START;
4731 	/* Keep 0 here! */
4732 	params.buf_size = 0;
4733 	params.timeout = 0;
4734 	params.ssn = tap->txa_start & (IEEE80211_SEQ_RANGE-1);
4735 	params.tid = tap->txa_tid;
4736 	params.amsdu = false;
4737 
4738 	IEEE80211_UNLOCK(ic);
4739 	LKPI_80211_LHW_LOCK(lhw);
4740 	error = lkpi_80211_mo_ampdu_action(hw, vif, &params);
4741 	LKPI_80211_LHW_UNLOCK(lhw);
4742 	IEEE80211_LOCK(ic);
4743 	if (error != 0) {
4744 		ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p tap %p\n",
4745 		    __func__, error, ni, tap);
4746 		return (0);
4747 	}
4748 
4749 	return (lhw->ic_addba_request(ni, tap, dialogtoken, baparamset, batimeout));
4750 }
4751 
4752 /*
4753  * (*ic_addba_response)() is called from ht_recv_action_ba_addba_response()
4754  * and calls the default ieee80211_addba_response() which always returns 1.
4755  *
4756  * NB: No error checking in net80211!
4757  * Staying with 0 is an error.
4758  */
4759 static int
4760 lkpi_ic_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
4761     int status, int baparamset, int batimeout)
4762 {
4763 	struct ieee80211com *ic;
4764 	struct lkpi_hw *lhw;
4765 	struct ieee80211_hw *hw;
4766 	struct ieee80211vap *vap;
4767 	struct lkpi_vif *lvif;
4768 	struct ieee80211_vif *vif;
4769 	struct lkpi_sta *lsta;
4770 	struct ieee80211_sta *sta;
4771 	struct ieee80211_ampdu_params params = { };
4772 	int error;
4773 
4774 	ic = ni->ni_ic;
4775 	lhw = ic->ic_softc;
4776 	hw = LHW_TO_HW(lhw);
4777 	vap = ni->ni_vap;
4778 	lvif = VAP_TO_LVIF(vap);
4779 	vif = LVIF_TO_VIF(lvif);
4780 	lsta = ni->ni_drv_data;
4781 	sta = LSTA_TO_STA(lsta);
4782 
4783 	if (!lsta->added_to_drv) {
4784 		ic_printf(ic, "%s: lsta %p ni %p, sta %p not added to firmware\n",
4785 		    __func__, lsta, ni, sta);
4786 		return (0);
4787 	}
4788 
4789 	if (status == IEEE80211_STATUS_SUCCESS) {
4790 		params.sta = sta;
4791 		params.action = IEEE80211_AMPDU_TX_OPERATIONAL;
4792 		params.buf_size = tap->txa_wnd;
4793 		params.timeout = 0;
4794 		params.ssn = 0;
4795 		params.tid = tap->txa_tid;
4796 		if ((tap->txa_flags & IEEE80211_AGGR_AMSDU) != 0)
4797 			params.amsdu = true;
4798 		else
4799 			params.amsdu = false;
4800 	} else {
4801 		/* We need to free the allocated resources. */
4802 		params.sta = sta;
4803 		switch (status) {
4804 			/* params.action = FLUSH, FLUSH_CONT */
4805 		default:
4806 			params.action = IEEE80211_AMPDU_TX_STOP_CONT;
4807 			break;
4808 		}
4809 		params.buf_size = 0;
4810 		params.timeout = 0;
4811 		params.ssn = 0;
4812 		params.tid = tap->txa_tid;
4813 		params.amsdu = false;
4814 	}
4815 
4816 	IEEE80211_UNLOCK(ic);
4817 	LKPI_80211_LHW_LOCK(lhw);
4818 	error = lkpi_80211_mo_ampdu_action(hw, vif, &params);
4819 	LKPI_80211_LHW_UNLOCK(lhw);
4820 	IEEE80211_LOCK(ic);
4821 	if (error != 0) {
4822 		ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p tap %p\n",
4823 		    __func__, error, ni, tap);
4824 		return (0);
4825 	}
4826 
4827 	IMPROVE_HT("who unleashes the TXQ? and when?, do we need to ni->ni_txseqs[tid] = tap->txa_start & 0xfff;");
4828 
4829 	return (lhw->ic_addba_response(ni, tap, status, baparamset, batimeout));
4830 }
4831 
4832 /*
4833  * (*ic_addba_stop)() is called from ampdu_tx_stop(), ht_recv_action_ba_delba(),
4834  * and ieee80211_ampdu_stop() and calls the default ieee80211_addba_stop().
4835  */
4836 static void
4837 lkpi_ic_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
4838 {
4839 	struct ieee80211com *ic;
4840 	struct lkpi_hw *lhw;
4841 	struct ieee80211_hw *hw;
4842 	struct ieee80211vap *vap;
4843 	struct lkpi_vif *lvif;
4844 	struct ieee80211_vif *vif;
4845 	struct lkpi_sta *lsta;
4846 	struct ieee80211_sta *sta;
4847 	struct ieee80211_ampdu_params params = { };
4848 	int error;
4849 
4850 	ic = ni->ni_ic;
4851 	lhw = ic->ic_softc;
4852 	hw = LHW_TO_HW(lhw);
4853 	vap = ni->ni_vap;
4854 	lvif = VAP_TO_LVIF(vap);
4855 	vif = LVIF_TO_VIF(lvif);
4856 	lsta = ni->ni_drv_data;
4857 	sta = LSTA_TO_STA(lsta);
4858 
4859 	if (!lsta->added_to_drv) {
4860 		ic_printf(ic, "%s: lsta %p ni %p, sta %p not added to firmware\n",
4861 		    __func__, lsta, ni, sta);
4862 		goto n80211;
4863 	}
4864 
4865 	/* We need to free the allocated resources. */
4866 	params.sta = sta;
4867 	IMPROVE("net80211 does not provide a reason to us");
4868 	params.action = IEEE80211_AMPDU_TX_STOP_CONT; /* params.action = FLUSH, FLUSH_CONT */
4869 	params.buf_size = 0;
4870 	params.timeout = 0;
4871 	params.ssn = 0;
4872 	params.tid = tap->txa_tid;
4873 	params.amsdu = false;
4874 
4875 	IEEE80211_UNLOCK(ic);
4876 	LKPI_80211_LHW_LOCK(lhw);
4877 	error = lkpi_80211_mo_ampdu_action(hw, vif, &params);
4878 	LKPI_80211_LHW_UNLOCK(lhw);
4879 	IEEE80211_LOCK(ic);
4880 	if (error != 0) {
4881 		ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p tap %p\n",
4882 		    __func__, error, ni, tap);
4883 		goto n80211;
4884 	}
4885 
4886 	IMPROVE_HT("anyting else?");
4887 
4888 n80211:
4889 	lhw->ic_addba_stop(ni, tap);
4890 }
4891 
4892 static void
4893 lkpi_ic_addba_response_timeout(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
4894 {
4895 	struct ieee80211com *ic;
4896 	struct lkpi_hw *lhw;
4897 
4898 	ic = ni->ni_ic;
4899 	lhw = ic->ic_softc;
4900 
4901 	IMPROVE_HT();
4902 
4903 	lhw->ic_addba_response_timeout(ni, tap);
4904 }
4905 
4906 static void
4907 lkpi_ic_bar_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
4908     int status)
4909 {
4910 	struct ieee80211com *ic;
4911 	struct lkpi_hw *lhw;
4912 
4913 	ic = ni->ni_ic;
4914 	lhw = ic->ic_softc;
4915 
4916 	IMPROVE_HT();
4917 
4918 	lhw->ic_bar_response(ni, tap, status);
4919 }
4920 
4921 static int
4922 lkpi_ic_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
4923     int baparamset, int batimeout, int baseqctl)
4924 {
4925 	struct ieee80211com *ic;
4926 	struct lkpi_hw *lhw;
4927 	struct ieee80211_hw *hw;
4928 	struct ieee80211vap *vap;
4929 	struct lkpi_vif *lvif;
4930 	struct ieee80211_vif *vif;
4931 	struct lkpi_sta *lsta;
4932 	struct ieee80211_sta *sta;
4933 	struct ieee80211_ampdu_params params = { };
4934 	int error;
4935 
4936 	ic = ni->ni_ic;
4937 	lhw = ic->ic_softc;
4938 	hw = LHW_TO_HW(lhw);
4939 	vap = ni->ni_vap;
4940 	lvif = VAP_TO_LVIF(vap);
4941 	vif = LVIF_TO_VIF(lvif);
4942 	lsta = ni->ni_drv_data;
4943 	sta = LSTA_TO_STA(lsta);
4944 
4945 	IEEE80211_UNLOCK_ASSERT(ic);
4946 
4947 	if (!lsta->added_to_drv) {
4948 		ic_printf(ic, "%s: lsta %p ni %p vap %p, sta %p not added to firmware\n",
4949 		    __func__, lsta, ni, vap, sta);
4950 		return (-ENXIO);
4951 	}
4952 
4953 	params.sta = sta;
4954 	params.action = IEEE80211_AMPDU_RX_START;
4955 	params.buf_size = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_BUFSIZ);
4956 	if (params.buf_size == 0)
4957 		params.buf_size = IEEE80211_MAX_AMPDU_BUF_HT;
4958 	else
4959 		params.buf_size = min(params.buf_size, IEEE80211_MAX_AMPDU_BUF_HT);
4960 	if (hw->max_rx_aggregation_subframes > 0 &&
4961 	    params.buf_size > hw->max_rx_aggregation_subframes)
4962 		params.buf_size = hw->max_rx_aggregation_subframes;
4963 	params.timeout = le16toh(batimeout);
4964 	params.ssn = _IEEE80211_MASKSHIFT(le16toh(baseqctl), IEEE80211_BASEQ_START);
4965 	params.tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID);
4966 
4967 	/* Based on net80211::ampdu_rx_start(). */
4968 	if ((vap->iv_htcaps & IEEE80211_HTC_RX_AMSDU_AMPDU) &&
4969 	    (_IEEE80211_MASKSHIFT(baparamset, IEEE80211_BAPS_AMSDU)))
4970 		params.amsdu = true;
4971 	else
4972 		params.amsdu = false;
4973 
4974 	LKPI_80211_LHW_LOCK(lhw);
4975 	error = lkpi_80211_mo_ampdu_action(hw, vif, &params);
4976 	LKPI_80211_LHW_UNLOCK(lhw);
4977 	if (error != 0) {
4978 		ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p rap %p\n",
4979 		    __func__, error, ni, rap);
4980 		return (error);
4981 	}
4982 
4983 	if (!ieee80211_hw_check(hw, SUPPORTS_REORDERING_BUFFER)) {
4984 		IMPROVE("%s: TODO: SUPPORTS_REORDERING_BUFFER not set; check net80211\n", __func__);
4985 	}
4986 
4987 	IMPROVE_HT("net80211 is missing the error check on return and assumes success");
4988 
4989 	error = lhw->ic_ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl);
4990 	return (error);
4991 }
4992 
4993 static void
4994 lkpi_ic_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
4995 {
4996 	struct ieee80211com *ic;
4997 	struct lkpi_hw *lhw;
4998 	struct ieee80211_hw *hw;
4999 	struct ieee80211vap *vap;
5000 	struct lkpi_vif *lvif;
5001 	struct ieee80211_vif *vif;
5002 	struct lkpi_sta *lsta;
5003 	struct ieee80211_sta *sta;
5004 	struct ieee80211_ampdu_params params = { };
5005 	int error;
5006 	uint8_t tid;
5007 
5008 	ic = ni->ni_ic;
5009 	lhw = ic->ic_softc;
5010 
5011 	/*
5012 	 * We should not (cannot) call into mac80211 ops with AMPDU_RX_STOP if
5013 	 * we did not START.  Some drivers pass it down to firmware which will
5014 	 * simply barf and net80211 calls ieee80211_ht_node_cleanup() from
5015 	 * ieee80211_ht_node_init() amongst others which will iterate over all
5016 	 * tid and call ic_ampdu_rx_stop() unconditionally.
5017 	 * XXX net80211 should probably be more "gentle" in these cases and
5018 	 * track some state itself.
5019 	 */
5020 	if ((rap->rxa_flags & IEEE80211_AGGR_RUNNING) == 0)
5021 		goto net80211_only;
5022 
5023 	hw = LHW_TO_HW(lhw);
5024 	vap = ni->ni_vap;
5025 	lvif = VAP_TO_LVIF(vap);
5026 	vif = LVIF_TO_VIF(lvif);
5027 	lsta = ni->ni_drv_data;
5028 	sta = LSTA_TO_STA(lsta);
5029 
5030 	IMPROVE_HT("This really should be passed from ht_recv_action_ba_delba.");
5031 	for (tid = 0; tid < WME_NUM_TID; tid++) {
5032 		if (&ni->ni_rx_ampdu[tid] == rap)
5033 			break;
5034 	}
5035 
5036 	params.sta = sta;
5037 	params.action = IEEE80211_AMPDU_RX_STOP;
5038 	params.buf_size = 0;
5039 	params.timeout = 0;
5040 	params.ssn = 0;
5041 	params.tid = tid;
5042 	params.amsdu = false;
5043 
5044 	// IEEE80211_UNLOCK(ic);
5045 	LKPI_80211_LHW_LOCK(lhw);
5046 	error = lkpi_80211_mo_ampdu_action(hw, vif, &params);
5047 	LKPI_80211_LHW_UNLOCK(lhw);
5048 	// IEEE80211_LOCK(ic);
5049 	if (error != 0)
5050 		ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p rap %p\n",
5051 		    __func__, error, ni, rap);
5052 
5053 net80211_only:
5054 	lhw->ic_ampdu_rx_stop(ni, rap);
5055 }
5056 #endif
5057 
5058 static void
5059 lkpi_ic_getradiocaps_ht(struct ieee80211com *ic, struct ieee80211_hw *hw,
5060     uint8_t *bands, int *chan_flags, enum nl80211_band band)
5061 {
5062 #ifdef LKPI_80211_HT
5063 	struct ieee80211_sta_ht_cap *ht_cap;
5064 
5065 	ht_cap = &hw->wiphy->bands[band]->ht_cap;
5066 	if (!ht_cap->ht_supported)
5067 		return;
5068 
5069 	switch (band) {
5070 	case NL80211_BAND_2GHZ:
5071 		setbit(bands, IEEE80211_MODE_11NG);
5072 		break;
5073 	case NL80211_BAND_5GHZ:
5074 		setbit(bands, IEEE80211_MODE_11NA);
5075 		break;
5076 	default:
5077 		IMPROVE("Unsupported band %d", band);
5078 		return;
5079 	}
5080 
5081 	ic->ic_htcaps = IEEE80211_HTC_HT;	/* HT operation */
5082 
5083 	/*
5084 	 * Rather than manually checking each flag and
5085 	 * translating IEEE80211_HT_CAP_ to IEEE80211_HTCAP_,
5086 	 * simply copy the 16bits.
5087 	 */
5088 	ic->ic_htcaps |= ht_cap->cap;
5089 
5090 	/* Then deal with the other flags. */
5091 	if (ieee80211_hw_check(hw, AMPDU_AGGREGATION))
5092 		ic->ic_htcaps |= IEEE80211_HTC_AMPDU;
5093 #ifdef __notyet__
5094 	if (ieee80211_hw_check(hw, TX_AMSDU))
5095 		ic->ic_htcaps |= IEEE80211_HTC_AMSDU;
5096 	if (ieee80211_hw_check(hw, SUPPORTS_AMSDU_IN_AMPDU))
5097 		ic->ic_htcaps |= (IEEE80211_HTC_RX_AMSDU_AMPDU |
5098 		    IEEE80211_HTC_TX_AMSDU_AMPDU);
5099 #endif
5100 
5101 	IMPROVE("PS, ampdu_*, ht_cap.mcs.tx_params, ...");
5102 	ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_OFF;
5103 
5104 	/* Only add HT40 channels if supported. */
5105 	if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) != 0 &&
5106 	    chan_flags != NULL)
5107 		*chan_flags |= NET80211_CBW_FLAG_HT40;
5108 #endif
5109 }
5110 
5111 static void
5112 lkpi_ic_getradiocaps(struct ieee80211com *ic, int maxchan,
5113     int *n, struct ieee80211_channel *c)
5114 {
5115 	struct lkpi_hw *lhw;
5116 	struct ieee80211_hw *hw;
5117 	struct linuxkpi_ieee80211_channel *channels;
5118 	uint8_t bands[IEEE80211_MODE_BYTES];
5119 	int chan_flags, error, i, nchans;
5120 
5121 	/* Channels */
5122 	lhw = ic->ic_softc;
5123 	hw = LHW_TO_HW(lhw);
5124 
5125 	/* NL80211_BAND_2GHZ */
5126 	nchans = 0;
5127 	if (hw->wiphy->bands[NL80211_BAND_2GHZ] != NULL)
5128 		nchans = hw->wiphy->bands[NL80211_BAND_2GHZ]->n_channels;
5129 	if (nchans > 0) {
5130 		memset(bands, 0, sizeof(bands));
5131 		chan_flags = 0;
5132 		setbit(bands, IEEE80211_MODE_11B);
5133 		/* XXX-BZ unclear how to check for 11g. */
5134 
5135 		IMPROVE("the bitrates may have flags?");
5136 		setbit(bands, IEEE80211_MODE_11G);
5137 
5138 		lkpi_ic_getradiocaps_ht(ic, hw, bands, &chan_flags,
5139 		    NL80211_BAND_2GHZ);
5140 
5141 		channels = hw->wiphy->bands[NL80211_BAND_2GHZ]->channels;
5142 		for (i = 0; i < nchans && *n < maxchan; i++) {
5143 			uint32_t nflags = 0;
5144 			int cflags = chan_flags;
5145 
5146 			if (channels[i].flags & IEEE80211_CHAN_DISABLED) {
5147 				ic_printf(ic, "%s: Skipping disabled chan "
5148 				    "[%u/%u/%#x]\n", __func__,
5149 				    channels[i].hw_value,
5150 				    channels[i].center_freq, channels[i].flags);
5151 				continue;
5152 			}
5153 			if (channels[i].flags & IEEE80211_CHAN_NO_IR)
5154 				nflags |= (IEEE80211_CHAN_NOADHOC|IEEE80211_CHAN_PASSIVE);
5155 			if (channels[i].flags & IEEE80211_CHAN_RADAR)
5156 				nflags |= IEEE80211_CHAN_DFS;
5157 			if (channels[i].flags & IEEE80211_CHAN_NO_160MHZ)
5158 				cflags &= ~(NET80211_CBW_FLAG_VHT160|NET80211_CBW_FLAG_VHT80P80);
5159 			if (channels[i].flags & IEEE80211_CHAN_NO_80MHZ)
5160 				cflags &= ~NET80211_CBW_FLAG_VHT80;
5161 			/* XXX how to map the remaining enum ieee80211_channel_flags? */
5162 			if (channels[i].flags & IEEE80211_CHAN_NO_HT40)
5163 				cflags &= ~NET80211_CBW_FLAG_HT40;
5164 
5165 			error = ieee80211_add_channel_cbw(c, maxchan, n,
5166 			    channels[i].hw_value, channels[i].center_freq,
5167 			    channels[i].max_power,
5168 			    nflags, bands, cflags);
5169 			/* net80211::ENOBUFS: *n >= maxchans */
5170 			if (error != 0 && error != ENOBUFS)
5171 				ic_printf(ic, "%s: Adding chan %u/%u/%#x/%#x/%#x/%#x "
5172 				    "returned error %d\n",
5173 				    __func__, channels[i].hw_value,
5174 				    channels[i].center_freq, channels[i].flags,
5175 				    nflags, chan_flags, cflags, error);
5176 			if (error != 0)
5177 				break;
5178 		}
5179 	}
5180 
5181 	/* NL80211_BAND_5GHZ */
5182 	nchans = 0;
5183 	if (hw->wiphy->bands[NL80211_BAND_5GHZ] != NULL)
5184 		nchans = hw->wiphy->bands[NL80211_BAND_5GHZ]->n_channels;
5185 	if (nchans > 0) {
5186 		memset(bands, 0, sizeof(bands));
5187 		chan_flags = 0;
5188 		setbit(bands, IEEE80211_MODE_11A);
5189 
5190 		lkpi_ic_getradiocaps_ht(ic, hw, bands, &chan_flags,
5191 		    NL80211_BAND_5GHZ);
5192 
5193 #ifdef LKPI_80211_VHT
5194 		if (hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.vht_supported){
5195 
5196 			ic->ic_flags_ext |= IEEE80211_FEXT_VHT;
5197 			ic->ic_vht_cap.vht_cap_info =
5198 			    hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.cap;
5199 			ic->ic_vht_cap.supp_mcs =
5200 			    hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.vht_mcs;
5201 
5202 			setbit(bands, IEEE80211_MODE_VHT_5GHZ);
5203 			chan_flags |= NET80211_CBW_FLAG_VHT80;
5204 			if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ(
5205 			    ic->ic_vht_cap.vht_cap_info))
5206 				chan_flags |= NET80211_CBW_FLAG_VHT160;
5207 			if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160_80P80MHZ(
5208 			    ic->ic_vht_cap.vht_cap_info))
5209 				chan_flags |= NET80211_CBW_FLAG_VHT80P80;
5210 		}
5211 #endif
5212 
5213 		channels = hw->wiphy->bands[NL80211_BAND_5GHZ]->channels;
5214 		for (i = 0; i < nchans && *n < maxchan; i++) {
5215 			uint32_t nflags = 0;
5216 			int cflags = chan_flags;
5217 
5218 			if (channels[i].flags & IEEE80211_CHAN_DISABLED) {
5219 				ic_printf(ic, "%s: Skipping disabled chan "
5220 				    "[%u/%u/%#x]\n", __func__,
5221 				    channels[i].hw_value,
5222 				    channels[i].center_freq, channels[i].flags);
5223 				continue;
5224 			}
5225 			if (channels[i].flags & IEEE80211_CHAN_NO_IR)
5226 				nflags |= (IEEE80211_CHAN_NOADHOC|IEEE80211_CHAN_PASSIVE);
5227 			if (channels[i].flags & IEEE80211_CHAN_RADAR)
5228 				nflags |= IEEE80211_CHAN_DFS;
5229 			if (channels[i].flags & IEEE80211_CHAN_NO_160MHZ)
5230 				cflags &= ~(NET80211_CBW_FLAG_VHT160|NET80211_CBW_FLAG_VHT80P80);
5231 			if (channels[i].flags & IEEE80211_CHAN_NO_80MHZ)
5232 				cflags &= ~NET80211_CBW_FLAG_VHT80;
5233 			/* XXX hwo to map the remaining enum ieee80211_channel_flags? */
5234 			if (channels[i].flags & IEEE80211_CHAN_NO_HT40)
5235 				cflags &= ~NET80211_CBW_FLAG_HT40;
5236 
5237 			error = ieee80211_add_channel_cbw(c, maxchan, n,
5238 			    channels[i].hw_value, channels[i].center_freq,
5239 			    channels[i].max_power,
5240 			    nflags, bands, cflags);
5241 			/* net80211::ENOBUFS: *n >= maxchans */
5242 			if (error != 0 && error != ENOBUFS)
5243 				ic_printf(ic, "%s: Adding chan %u/%u/%#x/%#x/%#x/%#x "
5244 				    "returned error %d\n",
5245 				    __func__, channels[i].hw_value,
5246 				    channels[i].center_freq, channels[i].flags,
5247 				    nflags, chan_flags, cflags, error);
5248 			if (error != 0)
5249 				break;
5250 		}
5251 	}
5252 }
5253 
5254 static void *
5255 lkpi_ieee80211_ifalloc(void)
5256 {
5257 	struct ieee80211com *ic;
5258 
5259 	ic = malloc(sizeof(*ic), M_LKPI80211, M_WAITOK | M_ZERO);
5260 
5261 	/* Setting these happens later when we have device information. */
5262 	ic->ic_softc = NULL;
5263 	ic->ic_name = "linuxkpi";
5264 
5265 	return (ic);
5266 }
5267 
5268 struct ieee80211_hw *
5269 linuxkpi_ieee80211_alloc_hw(size_t priv_len, const struct ieee80211_ops *ops)
5270 {
5271 	struct ieee80211_hw *hw;
5272 	struct lkpi_hw *lhw;
5273 	struct wiphy *wiphy;
5274 	int ac;
5275 
5276 	/* Get us and the driver data also allocated. */
5277 	wiphy = wiphy_new(&linuxkpi_mac80211cfgops, sizeof(*lhw) + priv_len);
5278 	if (wiphy == NULL)
5279 		return (NULL);
5280 
5281 	lhw = wiphy_priv(wiphy);
5282 	lhw->ops = ops;
5283 
5284 	LKPI_80211_LHW_LOCK_INIT(lhw);
5285 	LKPI_80211_LHW_SCAN_LOCK_INIT(lhw);
5286 	LKPI_80211_LHW_TXQ_LOCK_INIT(lhw);
5287 	sx_init_flags(&lhw->lvif_sx, "lhw-lvif", SX_RECURSE | SX_DUPOK);
5288 	TAILQ_INIT(&lhw->lvif_head);
5289 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
5290 		lhw->txq_generation[ac] = 1;
5291 		TAILQ_INIT(&lhw->scheduled_txqs[ac]);
5292 	}
5293 
5294 	/* Deferred RX path. */
5295 	LKPI_80211_LHW_RXQ_LOCK_INIT(lhw);
5296 	TASK_INIT(&lhw->rxq_task, 0, lkpi_80211_lhw_rxq_task, lhw);
5297 	mbufq_init(&lhw->rxq, IFQ_MAXLEN);
5298 	lhw->rxq_stopped = false;
5299 
5300 	/*
5301 	 * XXX-BZ TODO make sure there is a "_null" function to all ops
5302 	 * not initialized.
5303 	 */
5304 	hw = LHW_TO_HW(lhw);
5305 	hw->wiphy = wiphy;
5306 	hw->conf.flags |= IEEE80211_CONF_IDLE;
5307 	hw->priv = (void *)(lhw + 1);
5308 
5309 	/* BSD Specific. */
5310 	lhw->ic = lkpi_ieee80211_ifalloc();
5311 
5312 	IMPROVE();
5313 
5314 	return (hw);
5315 }
5316 
5317 void
5318 linuxkpi_ieee80211_iffree(struct ieee80211_hw *hw)
5319 {
5320 	struct lkpi_hw *lhw;
5321 	struct mbuf *m;
5322 
5323 	lhw = HW_TO_LHW(hw);
5324 	free(lhw->ic, M_LKPI80211);
5325 	lhw->ic = NULL;
5326 
5327 	/*
5328 	 * Drain the deferred RX path.
5329 	 */
5330 	LKPI_80211_LHW_RXQ_LOCK(lhw);
5331 	lhw->rxq_stopped = true;
5332 	LKPI_80211_LHW_RXQ_UNLOCK(lhw);
5333 
5334 	/* Drain taskq, won't be restarted due to rxq_stopped being set. */
5335 	while (taskqueue_cancel(taskqueue_thread, &lhw->rxq_task, NULL) != 0)
5336 		taskqueue_drain(taskqueue_thread, &lhw->rxq_task);
5337 
5338 	/* Flush mbufq (make sure to release ni refs!). */
5339 	m = mbufq_dequeue(&lhw->rxq);
5340 	while (m != NULL) {
5341 		struct m_tag *mtag;
5342 
5343 		mtag = m_tag_locate(m, MTAG_ABI_LKPI80211, LKPI80211_TAG_RXNI, NULL);
5344 		if (mtag != NULL) {
5345 			struct lkpi_80211_tag_rxni *rxni;
5346 
5347 			rxni = (struct lkpi_80211_tag_rxni *)(mtag + 1);
5348 			ieee80211_free_node(rxni->ni);
5349 		}
5350 		m_freem(m);
5351 		m = mbufq_dequeue(&lhw->rxq);
5352 	}
5353 	KASSERT(mbufq_empty(&lhw->rxq), ("%s: lhw %p has rxq len %d != 0\n",
5354 	    __func__, lhw, mbufq_len(&lhw->rxq)));
5355 	LKPI_80211_LHW_RXQ_LOCK_DESTROY(lhw);
5356 
5357 	/* Cleanup more of lhw here or in wiphy_free()? */
5358 	LKPI_80211_LHW_TXQ_LOCK_DESTROY(lhw);
5359 	LKPI_80211_LHW_SCAN_LOCK_DESTROY(lhw);
5360 	LKPI_80211_LHW_LOCK_DESTROY(lhw);
5361 	sx_destroy(&lhw->lvif_sx);
5362 	IMPROVE();
5363 }
5364 
5365 void
5366 linuxkpi_set_ieee80211_dev(struct ieee80211_hw *hw, char *name)
5367 {
5368 	struct lkpi_hw *lhw;
5369 	struct ieee80211com *ic;
5370 
5371 	lhw = HW_TO_LHW(hw);
5372 	ic = lhw->ic;
5373 
5374 	/* Now set a proper name before ieee80211_ifattach(). */
5375 	ic->ic_softc = lhw;
5376 	ic->ic_name = name;
5377 
5378 	/* XXX-BZ do we also need to set wiphy name? */
5379 }
5380 
5381 struct ieee80211_hw *
5382 linuxkpi_wiphy_to_ieee80211_hw(struct wiphy *wiphy)
5383 {
5384 	struct lkpi_hw *lhw;
5385 
5386 	lhw = wiphy_priv(wiphy);
5387 	return (LHW_TO_HW(lhw));
5388 }
5389 
5390 static void
5391 lkpi_radiotap_attach(struct lkpi_hw *lhw)
5392 {
5393 	struct ieee80211com *ic;
5394 
5395 	ic = lhw->ic;
5396 	ieee80211_radiotap_attach(ic,
5397 	    &lhw->rtap_tx.wt_ihdr, sizeof(lhw->rtap_tx),
5398 	    LKPI_RTAP_TX_FLAGS_PRESENT,
5399 	    &lhw->rtap_rx.wr_ihdr, sizeof(lhw->rtap_rx),
5400 	    LKPI_RTAP_RX_FLAGS_PRESENT);
5401 }
5402 
5403 int
5404 linuxkpi_ieee80211_ifattach(struct ieee80211_hw *hw)
5405 {
5406 	struct ieee80211com *ic;
5407 	struct lkpi_hw *lhw;
5408 	int band, i;
5409 
5410 	lhw = HW_TO_LHW(hw);
5411 	ic = lhw->ic;
5412 
5413 	/* We do it this late as wiphy->dev should be set for the name. */
5414 	lhw->workq = alloc_ordered_workqueue(wiphy_name(hw->wiphy), 0);
5415 	if (lhw->workq == NULL)
5416 		return (-EAGAIN);
5417 
5418 	/* XXX-BZ figure this out how they count his... */
5419 	if (!is_zero_ether_addr(hw->wiphy->perm_addr)) {
5420 		IEEE80211_ADDR_COPY(ic->ic_macaddr,
5421 		    hw->wiphy->perm_addr);
5422 	} else if (hw->wiphy->n_addresses > 0) {
5423 		/* We take the first one. */
5424 		IEEE80211_ADDR_COPY(ic->ic_macaddr,
5425 		    hw->wiphy->addresses[0].addr);
5426 	} else {
5427 		ic_printf(ic, "%s: warning, no hardware address!\n", __func__);
5428 	}
5429 
5430 #ifdef __not_yet__
5431 	/* See comment in lkpi_80211_txq_tx_one(). */
5432 	ic->ic_headroom = hw->extra_tx_headroom;
5433 #endif
5434 
5435 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
5436 	ic->ic_opmode = IEEE80211_M_STA;
5437 
5438 	/* Set device capabilities. */
5439 	/* XXX-BZ we need to get these from linux80211/drivers and convert. */
5440 	ic->ic_caps =
5441 	    IEEE80211_C_STA |
5442 	    IEEE80211_C_MONITOR |
5443 	    IEEE80211_C_WPA |		/* WPA/RSN */
5444 #ifdef LKPI_80211_WME
5445 	    IEEE80211_C_WME |
5446 #endif
5447 #if 0
5448 	    IEEE80211_C_PMGT |
5449 #endif
5450 	    IEEE80211_C_SHSLOT |	/* short slot time supported */
5451 	    IEEE80211_C_SHPREAMBLE	/* short preamble supported */
5452 	    ;
5453 #if 0
5454 	/* Scanning is a different kind of beast to re-work. */
5455 	ic->ic_caps |= IEEE80211_C_BGSCAN;
5456 #endif
5457 	if (lhw->ops->hw_scan) {
5458 		/*
5459 		 * Advertise full-offload scanning.
5460 		 *
5461 		 * Not limiting to SINGLE_SCAN_ON_ALL_BANDS here as otherwise
5462 		 * we essentially disable hw_scan for all drivers not setting
5463 		 * the flag.
5464 		 */
5465 		ic->ic_flags_ext |= IEEE80211_FEXT_SCAN_OFFLOAD;
5466 		lhw->scan_flags |= LKPI_LHW_SCAN_HW;
5467 	}
5468 
5469 	/*
5470 	 * The wiphy variables report bitmasks of avail antennas.
5471 	 * (*get_antenna) get the current bitmask sets which can be
5472 	 * altered by (*set_antenna) for some drivers.
5473 	 * XXX-BZ will the count alone do us much good long-term in net80211?
5474 	 */
5475 	if (hw->wiphy->available_antennas_rx ||
5476 	    hw->wiphy->available_antennas_tx) {
5477 		uint32_t rxs, txs;
5478 
5479 		if (lkpi_80211_mo_get_antenna(hw, &txs, &rxs) == 0) {
5480 			ic->ic_rxstream = bitcount32(rxs);
5481 			ic->ic_txstream = bitcount32(txs);
5482 		}
5483 	}
5484 
5485 	ic->ic_cryptocaps = 0;
5486 #ifdef LKPI_80211_HW_CRYPTO
5487 	if (lkpi_hwcrypto && hw->wiphy->n_cipher_suites > 0) {
5488 		for (i = 0; i < hw->wiphy->n_cipher_suites; i++)
5489 			ic->ic_cryptocaps |= lkpi_l80211_to_net80211_cyphers(
5490 			    hw->wiphy->cipher_suites[i]);
5491 	}
5492 #endif
5493 
5494 	lkpi_ic_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
5495 	    ic->ic_channels);
5496 
5497 	ieee80211_ifattach(ic);
5498 
5499 	ic->ic_update_mcast = lkpi_ic_update_mcast;
5500 	ic->ic_update_promisc = lkpi_ic_update_promisc;
5501 	ic->ic_update_chw = lkpi_ic_update_chw;
5502 	ic->ic_parent = lkpi_ic_parent;
5503 	ic->ic_scan_start = lkpi_ic_scan_start;
5504 	ic->ic_scan_end = lkpi_ic_scan_end;
5505 	ic->ic_set_channel = lkpi_ic_set_channel;
5506 	ic->ic_transmit = lkpi_ic_transmit;
5507 	ic->ic_raw_xmit = lkpi_ic_raw_xmit;
5508 	ic->ic_vap_create = lkpi_ic_vap_create;
5509 	ic->ic_vap_delete = lkpi_ic_vap_delete;
5510 	ic->ic_getradiocaps = lkpi_ic_getradiocaps;
5511 	ic->ic_wme.wme_update = lkpi_ic_wme_update;
5512 
5513 	lhw->ic_scan_curchan = ic->ic_scan_curchan;
5514 	ic->ic_scan_curchan = lkpi_ic_scan_curchan;
5515 	lhw->ic_scan_mindwell = ic->ic_scan_mindwell;
5516 	ic->ic_scan_mindwell = lkpi_ic_scan_mindwell;
5517 
5518 	lhw->ic_node_alloc = ic->ic_node_alloc;
5519 	ic->ic_node_alloc = lkpi_ic_node_alloc;
5520 	lhw->ic_node_init = ic->ic_node_init;
5521 	ic->ic_node_init = lkpi_ic_node_init;
5522 	lhw->ic_node_cleanup = ic->ic_node_cleanup;
5523 	ic->ic_node_cleanup = lkpi_ic_node_cleanup;
5524 	lhw->ic_node_free = ic->ic_node_free;
5525 	ic->ic_node_free = lkpi_ic_node_free;
5526 
5527 #ifdef LKPI_80211_HT
5528 	/*
5529 	 * Only attach if the driver/firmware supports (*ampdu_action)().
5530 	 * Otherwise it is in the hands of net80211.
5531 	 */
5532 	if (lhw->ops->ampdu_action != NULL) {
5533 		lhw->ic_recv_action = ic->ic_recv_action;
5534 		ic->ic_recv_action = lkpi_ic_recv_action;
5535 		lhw->ic_send_action = ic->ic_send_action;
5536 		ic->ic_send_action = lkpi_ic_send_action;
5537 
5538 		lhw->ic_ampdu_enable = ic->ic_ampdu_enable;
5539 		ic->ic_ampdu_enable = lkpi_ic_ampdu_enable;
5540 
5541 		lhw->ic_addba_request = ic->ic_addba_request;
5542 		ic->ic_addba_request = lkpi_ic_addba_request;
5543 		lhw->ic_addba_response = ic->ic_addba_response;
5544 		ic->ic_addba_response = lkpi_ic_addba_response;
5545 		lhw->ic_addba_stop = ic->ic_addba_stop;
5546 		ic->ic_addba_stop = lkpi_ic_addba_stop;
5547 		lhw->ic_addba_response_timeout = ic->ic_addba_response_timeout;
5548 		ic->ic_addba_response_timeout = lkpi_ic_addba_response_timeout;
5549 
5550 		lhw->ic_bar_response = ic->ic_bar_response;
5551 		ic->ic_bar_response = lkpi_ic_bar_response;
5552 
5553 		lhw->ic_ampdu_rx_start = ic->ic_ampdu_rx_start;
5554 		ic->ic_ampdu_rx_start = lkpi_ic_ampdu_rx_start;
5555 		lhw->ic_ampdu_rx_stop = ic->ic_ampdu_rx_stop;
5556 		ic->ic_ampdu_rx_stop = lkpi_ic_ampdu_rx_stop;
5557 	}
5558 #endif
5559 
5560 	lkpi_radiotap_attach(lhw);
5561 
5562 	/*
5563 	 * Assign the first possible channel for now;  seems Realtek drivers
5564 	 * expect one.
5565 	 * Also remember the amount of bands we support and the most rates
5566 	 * in any band so we can scale [(ext) sup rates] IE(s) accordingly.
5567 	 */
5568 	lhw->supbands = lhw->max_rates = 0;
5569 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
5570 		struct ieee80211_supported_band *supband;
5571 		struct linuxkpi_ieee80211_channel *channels;
5572 
5573 		supband = hw->wiphy->bands[band];
5574 		if (supband == NULL || supband->n_channels == 0)
5575 			continue;
5576 
5577 		lhw->supbands++;
5578 		lhw->max_rates = max(lhw->max_rates, supband->n_bitrates);
5579 
5580 		/* If we have a channel, we need to keep counting supbands. */
5581 		if (hw->conf.chandef.chan != NULL)
5582 			continue;
5583 
5584 		channels = supband->channels;
5585 		for (i = 0; i < supband->n_channels; i++) {
5586 
5587 			if (channels[i].flags & IEEE80211_CHAN_DISABLED)
5588 				continue;
5589 
5590 			cfg80211_chandef_create(&hw->conf.chandef, &channels[i],
5591 #ifdef LKPI_80211_HT
5592 			    (ic->ic_htcaps & IEEE80211_HTC_HT) ? 0 :
5593 #endif
5594 			    NL80211_CHAN_NO_HT);
5595 			break;
5596 		}
5597 	}
5598 
5599 	IMPROVE("see net80211::ieee80211_chan_init vs. wiphy->bands[].bitrates possibly in lkpi_ic_getradiocaps?");
5600 
5601 	/* Make sure we do not support more than net80211 is willing to take. */
5602 	if (lhw->max_rates > IEEE80211_RATE_MAXSIZE) {
5603 		ic_printf(ic, "%s: limiting max_rates %d to %d!\n", __func__,
5604 		    lhw->max_rates, IEEE80211_RATE_MAXSIZE);
5605 		lhw->max_rates = IEEE80211_RATE_MAXSIZE;
5606 	}
5607 
5608 	/*
5609 	 * The maximum supported bitrates on any band + size for
5610 	 * DSSS Parameter Set give our per-band IE size.
5611 	 * SSID is the responsibility of the driver and goes on the side.
5612 	 * The user specified bits coming from the vap go into the
5613 	 * "common ies" fields.
5614 	 */
5615 	lhw->scan_ie_len = 2 + IEEE80211_RATE_SIZE;
5616 	if (lhw->max_rates > IEEE80211_RATE_SIZE)
5617 		lhw->scan_ie_len += 2 + (lhw->max_rates - IEEE80211_RATE_SIZE);
5618 
5619 	if (hw->wiphy->features & NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) {
5620 		/*
5621 		 * net80211 does not seem to support the DSSS Parameter Set but
5622 		 * some of the drivers insert it so calculate the extra fixed
5623 		 * space in.
5624 		 */
5625 		lhw->scan_ie_len += 2 + 1;
5626 	}
5627 
5628 #if defined(LKPI_80211_HT)
5629 	if ((ic->ic_htcaps & IEEE80211_HTC_HT) != 0)
5630 		lhw->scan_ie_len += sizeof(struct ieee80211_ie_htcap);
5631 #endif
5632 #if defined(LKPI_80211_VHT)
5633 	if ((ic->ic_flags_ext & IEEE80211_FEXT_VHT) != 0)
5634 		lhw->scan_ie_len += 2 + sizeof(struct ieee80211_vht_cap);
5635 #endif
5636 
5637 	/* Reduce the max_scan_ie_len "left" by the amount we consume already. */
5638 	if (hw->wiphy->max_scan_ie_len > 0) {
5639 		if (lhw->scan_ie_len > hw->wiphy->max_scan_ie_len)
5640 			goto err;
5641 		hw->wiphy->max_scan_ie_len -= lhw->scan_ie_len;
5642 	}
5643 
5644 	if (bootverbose)
5645 		ieee80211_announce(ic);
5646 
5647 	return (0);
5648 err:
5649 	IMPROVE("TODO FIXME CLEANUP");
5650 	return (-EAGAIN);
5651 }
5652 
5653 void
5654 linuxkpi_ieee80211_ifdetach(struct ieee80211_hw *hw)
5655 {
5656 	struct lkpi_hw *lhw;
5657 	struct ieee80211com *ic;
5658 
5659 	lhw = HW_TO_LHW(hw);
5660 	ic = lhw->ic;
5661 	ieee80211_ifdetach(ic);
5662 }
5663 
5664 void
5665 linuxkpi_ieee80211_iterate_interfaces(struct ieee80211_hw *hw,
5666     enum ieee80211_iface_iter flags,
5667     void(*iterfunc)(void *, uint8_t *, struct ieee80211_vif *),
5668     void *arg)
5669 {
5670 	struct lkpi_hw *lhw;
5671 	struct lkpi_vif *lvif;
5672 	struct ieee80211_vif *vif;
5673 	bool active, atomic, nin_drv;
5674 
5675 	lhw = HW_TO_LHW(hw);
5676 
5677 	if (flags & ~(IEEE80211_IFACE_ITER_NORMAL|
5678 	    IEEE80211_IFACE_ITER_RESUME_ALL|
5679 	    IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER|
5680 	    IEEE80211_IFACE_ITER_ACTIVE|IEEE80211_IFACE_ITER__ATOMIC)) {
5681 		ic_printf(lhw->ic, "XXX TODO %s flags(%#x) not yet supported.\n",
5682 		    __func__, flags);
5683 	}
5684 
5685 	active = (flags & IEEE80211_IFACE_ITER_ACTIVE) != 0;
5686 	atomic = (flags & IEEE80211_IFACE_ITER__ATOMIC) != 0;
5687 	nin_drv = (flags & IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER) != 0;
5688 
5689 	if (atomic)
5690 		LKPI_80211_LHW_LVIF_LOCK(lhw);
5691 	TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
5692 		struct ieee80211vap *vap;
5693 
5694 		vif = LVIF_TO_VIF(lvif);
5695 
5696 		/*
5697 		 * If we want "active" interfaces, we need to distinguish on
5698 		 * whether the driver knows about them or not to be able to
5699 		 * handle the "resume" case correctly.  Skip the ones the
5700 		 * driver does not know about.
5701 		 */
5702 		if (active && !lvif->added_to_drv &&
5703 		    (flags & IEEE80211_IFACE_ITER_RESUME_ALL) != 0)
5704 			continue;
5705 
5706 		/*
5707 		 * If we shall skip interfaces not added to the driver do so
5708 		 * if we haven't yet.
5709 		 */
5710 		if (nin_drv && !lvif->added_to_drv)
5711 			continue;
5712 
5713 		/*
5714 		 * Run the iterator function if we are either not asking
5715 		 * asking for active only or if the VAP is "running".
5716 		 */
5717 		/* XXX-BZ probably should have state in the lvif as well. */
5718 		vap = LVIF_TO_VAP(lvif);
5719 		if (!active || (vap->iv_state != IEEE80211_S_INIT))
5720 			iterfunc(arg, vif->addr, vif);
5721 	}
5722 	if (atomic)
5723 		LKPI_80211_LHW_LVIF_UNLOCK(lhw);
5724 }
5725 
5726 static void
5727 lkpi_ieee80211_iterate_keys(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5728     ieee80211_keyix keyix, struct lkpi_sta *lsta,
5729     void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *,
5730 	struct ieee80211_sta *, struct ieee80211_key_conf *, void *),
5731     void *arg)
5732 {
5733 	if (!lsta->added_to_drv)
5734 		return;
5735 
5736 	if (lsta->kc[keyix] == NULL)
5737 		return;
5738 
5739 	iterfunc(hw, vif, LSTA_TO_STA(lsta), lsta->kc[keyix], arg);
5740 }
5741 
5742 void
5743 linuxkpi_ieee80211_iterate_keys(struct ieee80211_hw *hw,
5744     struct ieee80211_vif *vif,
5745     void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *,
5746         struct ieee80211_sta *, struct ieee80211_key_conf *, void *),
5747     void *arg, bool rcu)
5748 {
5749 	struct lkpi_sta *lsta;
5750 	struct lkpi_vif *lvif;
5751 
5752 	lvif = VIF_TO_LVIF(vif);
5753 
5754 	if (rcu) {
5755 		rcu_read_lock_held();		/* XXX-BZ is this correct? */
5756 
5757 		if (vif == NULL) {
5758 			TODO();
5759 		} else {
5760 			list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
5761 				for (ieee80211_keyix keyix = 0; keyix < nitems(lsta->kc);
5762 				    keyix++)
5763 					lkpi_ieee80211_iterate_keys(hw, vif,
5764 					    keyix, lsta, iterfunc, arg);
5765 			}
5766 		}
5767 	} else {
5768 		TODO("Used by suspend/resume; order of keys as installed to "
5769 		"firmware is important; we'll need to rewrite some code for that");
5770 		lockdep_assert_wiphy(hw->wiphy);
5771 
5772 		if (vif == NULL) {
5773 			TODO();
5774 		} else {
5775 			list_for_each_entry(lsta, &lvif->lsta_list, lsta_list) {
5776 				for (ieee80211_keyix keyix = 0; keyix < nitems(lsta->kc);
5777 				    keyix++)
5778 					lkpi_ieee80211_iterate_keys(hw, vif,
5779 					    keyix, lsta, iterfunc, arg);
5780 			}
5781 		}
5782 	}
5783 }
5784 
5785 void
5786 linuxkpi_ieee80211_iterate_chan_contexts(struct ieee80211_hw *hw,
5787     void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *,
5788 	void *),
5789     void *arg)
5790 {
5791 	struct lkpi_hw *lhw;
5792 	struct lkpi_vif *lvif;
5793 	struct ieee80211_vif *vif;
5794 	struct lkpi_chanctx *lchanctx;
5795 
5796 	KASSERT(hw != NULL && iterfunc != NULL,
5797 	    ("%s: hw %p iterfunc %p arg %p\n", __func__, hw, iterfunc, arg));
5798 
5799 	lhw = HW_TO_LHW(hw);
5800 
5801 	IMPROVE("lchanctx should be its own list somewhere");
5802 
5803 	LKPI_80211_LHW_LVIF_LOCK(lhw);
5804 	TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
5805 
5806 		vif = LVIF_TO_VIF(lvif);
5807 		if (vif->chanctx_conf == NULL)
5808 			continue;
5809 
5810 		lchanctx = CHANCTX_CONF_TO_LCHANCTX(vif->chanctx_conf);
5811 		if (!lchanctx->added_to_drv)
5812 			continue;
5813 
5814 		iterfunc(hw, &lchanctx->chanctx_conf, arg);
5815 	}
5816 	LKPI_80211_LHW_LVIF_UNLOCK(lhw);
5817 }
5818 
5819 void
5820 linuxkpi_ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
5821    void (*iterfunc)(void *, struct ieee80211_sta *), void *arg)
5822 {
5823 	struct lkpi_hw *lhw;
5824 	struct lkpi_vif *lvif;
5825 	struct lkpi_sta *lsta;
5826 	struct ieee80211_sta *sta;
5827 
5828 	KASSERT(hw != NULL && iterfunc != NULL,
5829 	    ("%s: hw %p iterfunc %p arg %p\n", __func__, hw, iterfunc, arg));
5830 
5831 	lhw = HW_TO_LHW(hw);
5832 
5833 	LKPI_80211_LHW_LVIF_LOCK(lhw);
5834 	TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
5835 
5836 		rcu_read_lock();
5837 		list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
5838 			if (!lsta->added_to_drv)
5839 				continue;
5840 			sta = LSTA_TO_STA(lsta);
5841 			iterfunc(arg, sta);
5842 		}
5843 		rcu_read_unlock();
5844 	}
5845 	LKPI_80211_LHW_LVIF_UNLOCK(lhw);
5846 }
5847 
5848 struct linuxkpi_ieee80211_regdomain *
5849 lkpi_get_linuxkpi_ieee80211_regdomain(size_t n)
5850 {
5851 	struct linuxkpi_ieee80211_regdomain *regd;
5852 
5853 	regd = kzalloc(sizeof(*regd) + n * sizeof(struct ieee80211_reg_rule),
5854 	    GFP_KERNEL);
5855 	return (regd);
5856 }
5857 
5858 int
5859 linuxkpi_regulatory_set_wiphy_regd_sync(struct wiphy *wiphy,
5860     struct linuxkpi_ieee80211_regdomain *regd)
5861 {
5862 	struct lkpi_hw *lhw;
5863 	struct ieee80211com *ic;
5864 	struct ieee80211_regdomain *rd;
5865 
5866 	lhw = wiphy_priv(wiphy);
5867 	ic = lhw->ic;
5868 
5869 	rd = &ic->ic_regdomain;
5870 	if (rd->isocc[0] == '\0') {
5871 		rd->isocc[0] = regd->alpha2[0];
5872 		rd->isocc[1] = regd->alpha2[1];
5873 	}
5874 
5875 	TODO();
5876 	/* XXX-BZ finish the rest. */
5877 
5878 	return (0);
5879 }
5880 
5881 void
5882 linuxkpi_ieee80211_scan_completed(struct ieee80211_hw *hw,
5883     struct cfg80211_scan_info *info)
5884 {
5885 	struct lkpi_hw *lhw;
5886 	struct ieee80211com *ic;
5887 	struct ieee80211_scan_state *ss;
5888 
5889 	lhw = wiphy_priv(hw->wiphy);
5890 	ic = lhw->ic;
5891 	ss = ic->ic_scan;
5892 
5893 	ieee80211_scan_done(ss->ss_vap);
5894 
5895 	LKPI_80211_LHW_SCAN_LOCK(lhw);
5896 	free(lhw->hw_req, M_LKPI80211);
5897 	lhw->hw_req = NULL;
5898 	lhw->scan_flags &= ~LKPI_LHW_SCAN_RUNNING;
5899 	wakeup(lhw);
5900 	LKPI_80211_LHW_SCAN_UNLOCK(lhw);
5901 
5902 	return;
5903 }
5904 
5905 static void
5906 lkpi_80211_lhw_rxq_rx_one(struct lkpi_hw *lhw, struct mbuf *m)
5907 {
5908 	struct ieee80211_node *ni;
5909 	struct m_tag *mtag;
5910 	int ok;
5911 
5912 	ni = NULL;
5913         mtag = m_tag_locate(m, MTAG_ABI_LKPI80211, LKPI80211_TAG_RXNI, NULL);
5914 	if (mtag != NULL) {
5915 		struct lkpi_80211_tag_rxni *rxni;
5916 
5917 		rxni = (struct lkpi_80211_tag_rxni *)(mtag + 1);
5918 		ni = rxni->ni;
5919 	}
5920 
5921 	if (ni != NULL) {
5922 		ok = ieee80211_input_mimo(ni, m);
5923 		ieee80211_free_node(ni);		/* Release the reference. */
5924 		if (ok < 0)
5925 			m_freem(m);
5926 	} else {
5927 		ok = ieee80211_input_mimo_all(lhw->ic, m);
5928 		/* mbuf got consumed. */
5929 	}
5930 
5931 #ifdef LINUXKPI_DEBUG_80211
5932 	if (linuxkpi_debug_80211 & D80211_TRACE_RX)
5933 		printf("TRACE-RX: %s: handled frame type %#0x\n", __func__, ok);
5934 #endif
5935 }
5936 
5937 static void
5938 lkpi_80211_lhw_rxq_task(void *ctx, int pending)
5939 {
5940 	struct lkpi_hw *lhw;
5941 	struct mbufq mq;
5942 	struct mbuf *m;
5943 
5944 	lhw = ctx;
5945 
5946 #ifdef LINUXKPI_DEBUG_80211
5947 	if (linuxkpi_debug_80211 & D80211_TRACE_RX)
5948 		printf("TRACE-RX: %s: lhw %p pending %d mbuf_qlen %d\n",
5949 		    __func__, lhw, pending, mbufq_len(&lhw->rxq));
5950 #endif
5951 
5952 	mbufq_init(&mq, IFQ_MAXLEN);
5953 
5954 	LKPI_80211_LHW_RXQ_LOCK(lhw);
5955 	mbufq_concat(&mq, &lhw->rxq);
5956 	LKPI_80211_LHW_RXQ_UNLOCK(lhw);
5957 
5958 	m = mbufq_dequeue(&mq);
5959 	while (m != NULL) {
5960 		lkpi_80211_lhw_rxq_rx_one(lhw, m);
5961 		m = mbufq_dequeue(&mq);
5962 	}
5963 }
5964 
5965 static void
5966 lkpi_convert_rx_status(struct ieee80211_hw *hw,
5967     struct ieee80211_rx_status *rx_status,
5968     struct ieee80211_rx_stats *rx_stats,
5969     uint8_t *rssip)
5970 {
5971 	struct ieee80211_supported_band *supband;
5972 	int i;
5973 	uint8_t rssi;
5974 
5975 	memset(rx_stats, 0, sizeof(*rx_stats));
5976 	rx_stats->r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI;
5977 	/* XXX-BZ correct hardcoded noise floor, survey data? */
5978 	rx_stats->c_nf = -96;
5979 	if (ieee80211_hw_check(hw, SIGNAL_DBM) &&
5980 	    !(rx_status->flag & RX_FLAG_NO_SIGNAL_VAL))
5981 		rssi = rx_status->signal;
5982 	else
5983 		rssi = rx_stats->c_nf;
5984 	/*
5985 	 * net80211 signal strength data are in .5 dBm units relative to
5986 	 * the current noise floor (see comment in ieee80211_node.h).
5987 	 */
5988 	rssi -= rx_stats->c_nf;
5989 	if (rssip != NULL)
5990 		*rssip = rssi;
5991 	rx_stats->c_rssi = rssi * 2;
5992 	rx_stats->r_flags |= IEEE80211_R_BAND;
5993 	rx_stats->c_band =
5994 	    lkpi_nl80211_band_to_net80211_band(rx_status->band);
5995 	rx_stats->r_flags |= IEEE80211_R_FREQ | IEEE80211_R_IEEE;
5996 	rx_stats->c_freq = rx_status->freq;
5997 	rx_stats->c_ieee = ieee80211_mhz2ieee(rx_stats->c_freq, rx_stats->c_band);
5998 
5999 	rx_stats->c_rx_tsf = rx_status->mactime;
6000 
6001 	/* XXX RX_FLAG_MACTIME_IS_RTAP_TS64 ? */
6002 	if ((rx_status->flag & RX_FLAG_MACTIME) ==
6003 	    (RX_FLAG_MACTIME_START|RX_FLAG_MACTIME_END)) {
6004 		rx_stats->r_flags |= IEEE80211_R_TSF64;
6005 		/* XXX RX_FLAG_MACTIME_PLCP_START ? */
6006 		if ((rx_status->flag & RX_FLAG_MACTIME) == RX_FLAG_MACTIME_START)
6007 			rx_stats->r_flags |= IEEE80211_R_TSF_START;
6008 		if ((rx_status->flag & RX_FLAG_MACTIME) == RX_FLAG_MACTIME_END)
6009 			rx_stats->r_flags |= IEEE80211_R_TSF_END;
6010 		/* XXX-BZ if TSF_END will net80211 do the unwind of time? */
6011 	}
6012 
6013 	if (rx_status->chains != 0) {
6014 		int cc;
6015 		int8_t crssi;
6016 
6017 		rx_stats->c_chain = rx_status->chains;
6018 		rx_stats->r_flags |= IEEE80211_R_C_CHAIN;
6019 
6020 		cc = 0;
6021 		for (i = 0; i < nitems(rx_status->chain_signal); i++) {
6022 			if (!(rx_status->chains & BIT(i)))
6023 				continue;
6024 			crssi = rx_status->chain_signal[i];
6025 			crssi -= rx_stats->c_nf;
6026 			rx_stats->c_rssi_ctl[i] = crssi * 2;
6027 			rx_stats->c_rssi_ext[i] = crssi * 2;	/* XXX _ext ??? ATH thing? */
6028 			/* We currently only have the global noise floor value. */
6029 			rx_stats->c_nf_ctl[i] = rx_stats->c_nf;
6030 			rx_stats->c_nf_ext[i] = rx_stats->c_nf;
6031 			cc++;
6032 		}
6033 		if (cc > 0)
6034 			 rx_stats->r_flags |= (IEEE80211_R_C_NF | IEEE80211_R_C_RSSI);
6035 	}
6036 
6037 	/* XXX-NET80211 We are not going to populate c_phytype! */
6038 
6039 	switch (rx_status->encoding) {
6040 	case RX_ENC_LEGACY:
6041 		supband = hw->wiphy->bands[rx_status->band];
6042 		if (supband != NULL)
6043 			rx_stats->c_rate = supband->bitrates[rx_status->rate_idx].bitrate;
6044 		/* Is there a LinuxKPI way of reporting IEEE80211_RX_F_CCK / _OFDM? */
6045 		break;
6046 	case RX_ENC_HT:
6047 		rx_stats->c_pktflags |= IEEE80211_RX_F_HT;
6048 		if ((rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI) != 0)
6049 			rx_stats->c_pktflags |= IEEE80211_RX_F_SHORTGI;
6050 		rx_stats->c_rate = rx_status->rate_idx;		/* mcs */
6051 		break;
6052 	case RX_ENC_VHT:
6053 		rx_stats->c_pktflags |= IEEE80211_RX_F_VHT;
6054 		if ((rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI) != 0)
6055 			rx_stats->c_pktflags |= IEEE80211_RX_F_SHORTGI;
6056 		rx_stats->c_rate = rx_status->rate_idx;		/* mcs */
6057 		rx_stats->c_vhtnss = rx_status->nss;
6058 		break;
6059 	case RX_ENC_HE:
6060 	case RX_ENC_EHT:
6061 		TODO("net80211 has not matching encoding for %u", rx_status->encoding);
6062 		break;
6063 	}
6064 
6065 	switch (rx_status->bw) {
6066 	case RATE_INFO_BW_20:
6067 		rx_stats->c_width = IEEE80211_RX_FW_20MHZ;
6068 		break;
6069 	case RATE_INFO_BW_40:
6070 		rx_stats->c_width = IEEE80211_RX_FW_40MHZ;
6071 		break;
6072 	case RATE_INFO_BW_80:
6073 		rx_stats->c_width = IEEE80211_RX_FW_80MHZ;
6074 		break;
6075 	case RATE_INFO_BW_160:
6076 		rx_stats->c_width = IEEE80211_RX_FW_160MHZ;
6077 		break;
6078 	case RATE_INFO_BW_320:
6079 	case RATE_INFO_BW_HE_RU:
6080 	case RATE_INFO_BW_EHT_RU:
6081 	case RATE_INFO_BW_5:
6082 	case RATE_INFO_BW_10:
6083 		TODO("net80211 has not matching bandwidth for %u", rx_status->bw);
6084 		break;
6085 	}
6086 
6087 	if ((rx_status->enc_flags & RX_ENC_FLAG_LDPC) != 0)
6088 		rx_stats->c_pktflags |= IEEE80211_RX_F_LDPC;
6089 	if ((rx_status->enc_flags & RX_ENC_FLAG_STBC_MASK) != 0)
6090 		 rx_stats->c_pktflags |= IEEE80211_RX_F_STBC;
6091 
6092 	/*
6093 	 * We only need these for LKPI_80211_HW_CRYPTO in theory but in
6094 	 * case the hardware does something we do not expect always leave
6095 	 * these enabled.  Leaving this commant as documentation for the || 1.
6096 	 */
6097 #if defined(LKPI_80211_HW_CRYPTO) || 1
6098 	if (rx_status->flag & RX_FLAG_DECRYPTED) {
6099 		rx_stats->c_pktflags |= IEEE80211_RX_F_DECRYPTED;
6100 		/* Only valid if decrypted is set. */
6101 		if (rx_status->flag & RX_FLAG_PN_VALIDATED)
6102 			rx_stats->c_pktflags |= IEEE80211_RX_F_PN_VALIDATED;
6103 	}
6104 	if (rx_status->flag & RX_FLAG_MMIC_STRIPPED)
6105 		rx_stats->c_pktflags |= IEEE80211_RX_F_MMIC_STRIP;
6106 	if (rx_status->flag & RX_FLAG_MIC_STRIPPED) {
6107 		/* net80211 re-uses M[ichael]MIC for MIC too. Confusing. */
6108 		rx_stats->c_pktflags |= IEEE80211_RX_F_MMIC_STRIP;
6109 	}
6110 	if (rx_status->flag & RX_FLAG_IV_STRIPPED)
6111 		rx_stats->c_pktflags |= IEEE80211_RX_F_IV_STRIP;
6112 	if (rx_status->flag & RX_FLAG_MMIC_ERROR)
6113 		rx_stats->c_pktflags |= IEEE80211_RX_F_FAIL_MIC;
6114 	if (rx_status->flag & RX_FLAG_FAILED_FCS_CRC)
6115 		rx_stats->c_pktflags |= IEEE80211_RX_F_FAIL_FCSCRC;
6116 #endif
6117 }
6118 
6119 /* For %list see comment towards the end of the function. */
6120 void
6121 linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
6122     struct ieee80211_sta *sta, struct napi_struct *napi __unused,
6123     struct list_head *list __unused)
6124 {
6125 	struct lkpi_hw *lhw;
6126 	struct ieee80211com *ic;
6127 	struct mbuf *m;
6128 	struct skb_shared_info *shinfo;
6129 	struct ieee80211_rx_status *rx_status;
6130 	struct ieee80211_rx_stats rx_stats;
6131 	struct ieee80211_node *ni;
6132 	struct ieee80211vap *vap;
6133 	struct ieee80211_hdr *hdr;
6134 	struct lkpi_sta *lsta;
6135 	int i, offset, ok;
6136 	uint8_t rssi;
6137 	bool is_beacon;
6138 
6139 	if (skb->len < 2) {
6140 		/* Need 80211 stats here. */
6141 		IMPROVE();
6142 		goto err;
6143 	}
6144 
6145 	/*
6146 	 * For now do the data copy; we can later improve things. Might even
6147 	 * have an mbuf backing the skb data then?
6148 	 */
6149 	m = m_get2(skb->len, M_NOWAIT, MT_DATA, M_PKTHDR);
6150 	if (m == NULL)
6151 		goto err;
6152 	m_copyback(m, 0, skb->tail - skb->data, skb->data);
6153 
6154 	shinfo = skb_shinfo(skb);
6155 	offset = m->m_len;
6156 	for (i = 0; i < shinfo->nr_frags; i++) {
6157 		m_copyback(m, offset, shinfo->frags[i].size,
6158 		    (uint8_t *)linux_page_address(shinfo->frags[i].page) +
6159 		    shinfo->frags[i].offset);
6160 		offset += shinfo->frags[i].size;
6161 	}
6162 
6163 	rx_status = IEEE80211_SKB_RXCB(skb);
6164 
6165 	hdr = (void *)skb->data;
6166 	is_beacon = ieee80211_is_beacon(hdr->frame_control);
6167 
6168 #ifdef LINUXKPI_DEBUG_80211
6169 	if (is_beacon && (linuxkpi_debug_80211 & D80211_TRACE_RX_BEACONS) == 0)
6170 		goto no_trace_beacons;
6171 
6172 	if (linuxkpi_debug_80211 & D80211_TRACE_RX)
6173 		printf("TRACE-RX: %s: skb %p a/l/d/t-len (%u/%u/%u/%u) "
6174 		    "h %p d %p t %p e %p sh %p (%u) m %p plen %u len %u%s\n",
6175 		    __func__, skb, skb->_alloc_len, skb->len, skb->data_len,
6176 		    skb->truesize, skb->head, skb->data, skb->tail, skb->end,
6177 		    shinfo, shinfo->nr_frags,
6178 		    m, m->m_pkthdr.len, m->m_len, is_beacon ? " beacon" : "");
6179 
6180 	if (linuxkpi_debug_80211 & D80211_TRACE_RX_DUMP)
6181 		hexdump(mtod(m, const void *), m->m_len, "RX (raw) ", 0);
6182 
6183 	/* Implement a dump_rxcb() !!! */
6184 	if (linuxkpi_debug_80211 & D80211_TRACE_RX)
6185 		printf("TRACE-RX: %s: RXCB: %ju %ju %u, %b, %u, %#0x, %#0x, "
6186 		    "%u band %u, %u { %d %d %d %d }, %d, %#x %#x %#x %#x %u %u %u\n",
6187 			__func__,
6188 			(uintmax_t)rx_status->boottime_ns,
6189 			(uintmax_t)rx_status->mactime,
6190 			rx_status->device_timestamp,
6191 			rx_status->flag, IEEE80211_RX_STATUS_FLAGS_BITS,
6192 			rx_status->freq,
6193 			rx_status->bw,
6194 			rx_status->encoding,
6195 			rx_status->ampdu_reference,
6196 			rx_status->band,
6197 			rx_status->chains,
6198 			rx_status->chain_signal[0],
6199 			rx_status->chain_signal[1],
6200 			rx_status->chain_signal[2],
6201 			rx_status->chain_signal[3],
6202 			rx_status->signal,
6203 			rx_status->enc_flags,
6204 			rx_status->he_dcm,
6205 			rx_status->he_gi,
6206 			rx_status->he_ru,
6207 			rx_status->zero_length_psdu_type,
6208 			rx_status->nss,
6209 			rx_status->rate_idx);
6210 no_trace_beacons:
6211 #endif
6212 
6213 	rssi = 0;
6214 	lkpi_convert_rx_status(hw, rx_status, &rx_stats, &rssi);
6215 
6216 	lhw = HW_TO_LHW(hw);
6217 	ic = lhw->ic;
6218 
6219 	ok = ieee80211_add_rx_params(m, &rx_stats);
6220 	if (ok == 0) {
6221 		m_freem(m);
6222 		counter_u64_add(ic->ic_ierrors, 1);
6223 		goto err;
6224 	}
6225 
6226 	lsta = NULL;
6227 	if (sta != NULL) {
6228 		lsta = STA_TO_LSTA(sta);
6229 		ni = ieee80211_ref_node(lsta->ni);
6230 	} else {
6231 		struct ieee80211_frame_min *wh;
6232 
6233 		wh = mtod(m, struct ieee80211_frame_min *);
6234 		ni = ieee80211_find_rxnode(ic, wh);
6235 		if (ni != NULL)
6236 			lsta = ni->ni_drv_data;
6237 	}
6238 
6239 	if (ni != NULL)
6240 		vap = ni->ni_vap;
6241 	else
6242 		/*
6243 		 * XXX-BZ can we improve this by looking at the frame hdr
6244 		 * or other meta-data passed up?
6245 		 */
6246 		vap = TAILQ_FIRST(&ic->ic_vaps);
6247 
6248 #ifdef LINUXKPI_DEBUG_80211
6249 	if (linuxkpi_debug_80211 & D80211_TRACE_RX)
6250 		printf("TRACE-RX: %s: sta %p lsta %p state %d ni %p vap %p%s\n",
6251 		    __func__, sta, lsta, (lsta != NULL) ? lsta->state : -1,
6252 		    ni, vap, is_beacon ? " beacon" : "");
6253 #endif
6254 
6255 	if (ni != NULL && vap != NULL && is_beacon &&
6256 	    rx_status->device_timestamp > 0 &&
6257 	    m->m_pkthdr.len >= sizeof(struct ieee80211_frame)) {
6258 		struct lkpi_vif *lvif;
6259 		struct ieee80211_vif *vif;
6260 		struct ieee80211_frame *wh;
6261 
6262 		wh = mtod(m, struct ieee80211_frame *);
6263 		if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))
6264 			goto skip_device_ts;
6265 
6266 		lvif = VAP_TO_LVIF(vap);
6267 		vif = LVIF_TO_VIF(lvif);
6268 
6269 		IMPROVE("TIMING_BEACON_ONLY?");
6270 		/* mac80211 specific (not net80211) so keep it here. */
6271 		vif->bss_conf.sync_device_ts = rx_status->device_timestamp;
6272 		/*
6273 		 * net80211 should take care of the other information (sync_tsf,
6274 		 * sync_dtim_count) as otherwise we need to parse the beacon.
6275 		 */
6276 skip_device_ts:
6277 		;
6278 	}
6279 
6280 	if (vap != NULL && vap->iv_state > IEEE80211_S_INIT &&
6281 	    ieee80211_radiotap_active_vap(vap)) {
6282 		struct lkpi_radiotap_rx_hdr *rtap;
6283 
6284 		rtap = &lhw->rtap_rx;
6285 		rtap->wr_tsft = rx_status->device_timestamp;
6286 		rtap->wr_flags = 0;
6287 		if (rx_status->enc_flags & RX_ENC_FLAG_SHORTPRE)
6288 			rtap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
6289 		if (rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI)
6290 			rtap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI;
6291 #if 0	/* .. or it does not given we strip it below. */
6292 		if (ieee80211_hw_check(hw, RX_INCLUDES_FCS))
6293 			rtap->wr_flags |= IEEE80211_RADIOTAP_F_FCS;
6294 #endif
6295 		if (rx_status->flag & RX_FLAG_FAILED_FCS_CRC)
6296 			rtap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
6297 		rtap->wr_rate = 0;
6298 		IMPROVE();
6299 		/* XXX TODO status->encoding / rate_index / bw */
6300 		rtap->wr_chan_freq = htole16(rx_stats.c_freq);
6301 		if (ic->ic_curchan->ic_ieee == rx_stats.c_ieee)
6302 			rtap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
6303 		rtap->wr_dbm_antsignal = rssi;
6304 		rtap->wr_dbm_antnoise = rx_stats.c_nf;
6305 	}
6306 
6307 	if (ieee80211_hw_check(hw, RX_INCLUDES_FCS))
6308 		m_adj(m, -IEEE80211_CRC_LEN);
6309 
6310 #if 0
6311 	if (list != NULL) {
6312 		/*
6313 		* Normally this would be queued up and delivered by
6314 		* netif_receive_skb_list(), napi_gro_receive(), or the like.
6315 		* See mt76::mac80211.c as only current possible consumer.
6316 		*/
6317 		IMPROVE("we simply pass the packet to net80211 to deal with.");
6318 	}
6319 #endif
6320 
6321 	/*
6322 	 * Attach meta-information to the mbuf for the deferred RX path.
6323 	 * Currently this is best-effort.  Should we need to be hard,
6324 	 * drop the frame and goto err;
6325 	 */
6326 	if (ni != NULL) {
6327 		struct m_tag *mtag;
6328 		struct lkpi_80211_tag_rxni *rxni;
6329 
6330 		mtag = m_tag_alloc(MTAG_ABI_LKPI80211, LKPI80211_TAG_RXNI,
6331 		    sizeof(*rxni), IEEE80211_M_NOWAIT);
6332 		if (mtag != NULL) {
6333 			rxni = (struct lkpi_80211_tag_rxni *)(mtag + 1);
6334 			rxni->ni = ni;		/* We hold a reference. */
6335 			m_tag_prepend(m, mtag);
6336 		}
6337 	}
6338 
6339 	LKPI_80211_LHW_RXQ_LOCK(lhw);
6340 	if (lhw->rxq_stopped) {
6341 		LKPI_80211_LHW_RXQ_UNLOCK(lhw);
6342 		m_freem(m);
6343 		goto err;
6344 	}
6345 
6346 	mbufq_enqueue(&lhw->rxq, m);
6347 	taskqueue_enqueue(taskqueue_thread, &lhw->rxq_task);
6348 	LKPI_80211_LHW_RXQ_UNLOCK(lhw);
6349 
6350 	IMPROVE();
6351 
6352 err:
6353 	/* The skb is ours so we can free it :-) */
6354 	kfree_skb(skb);
6355 }
6356 
6357 uint8_t
6358 linuxkpi_ieee80211_get_tid(struct ieee80211_hdr *hdr, bool nonqos_ok)
6359 {
6360 	const struct ieee80211_frame *wh;
6361 	uint8_t tid;
6362 
6363 	/* Linux seems to assume this is a QOS-Data-Frame */
6364 	KASSERT(nonqos_ok || ieee80211_is_data_qos(hdr->frame_control),
6365 	   ("%s: hdr %p fc %#06x not qos_data\n", __func__, hdr,
6366 	   hdr->frame_control));
6367 
6368 	wh = (const struct ieee80211_frame *)hdr;
6369 	tid = ieee80211_gettid(wh);
6370 	KASSERT(nonqos_ok || tid == (tid & IEEE80211_QOS_TID), ("%s: tid %u "
6371 	   "not expected (%u?)\n", __func__, tid, IEEE80211_NONQOS_TID));
6372 
6373 	return (tid);
6374 }
6375 
6376 /* -------------------------------------------------------------------------- */
6377 
6378 static void
6379 lkpi_wiphy_work(struct work_struct *work)
6380 {
6381 	struct lkpi_wiphy *lwiphy;
6382 	struct wiphy *wiphy;
6383 	struct wiphy_work *wk;
6384 
6385 	lwiphy = container_of(work, struct lkpi_wiphy, wwk);
6386 	wiphy = LWIPHY_TO_WIPHY(lwiphy);
6387 
6388 	wiphy_lock(wiphy);
6389 
6390 	LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
6391 	wk = list_first_entry_or_null(&lwiphy->wwk_list, struct wiphy_work, entry);
6392 	/* If there is nothing we do nothing. */
6393 	if (wk == NULL) {
6394 		LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
6395 		wiphy_unlock(wiphy);
6396 		return;
6397 	}
6398 	list_del_init(&wk->entry);
6399 
6400 	/* More work to do? */
6401 	if (!list_empty(&lwiphy->wwk_list))
6402 		schedule_work(work);
6403 	LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
6404 
6405 	/* Finally call the (*wiphy_work_fn)() function. */
6406 	wk->fn(wiphy, wk);
6407 
6408 	wiphy_unlock(wiphy);
6409 }
6410 
6411 void
6412 linuxkpi_wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *wwk)
6413 {
6414 	struct lkpi_wiphy *lwiphy;
6415 
6416 	lwiphy = WIPHY_TO_LWIPHY(wiphy);
6417 
6418 	LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
6419 	/* Do not double-queue. */
6420 	if (list_empty(&wwk->entry))
6421 		list_add_tail(&wwk->entry, &lwiphy->wwk_list);
6422 	LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
6423 
6424 	/*
6425 	 * See how ieee80211_queue_work() work continues in Linux or if things
6426 	 * migrate here over time?
6427 	 * Use a system queue from linux/workqueue.h for now.
6428 	 */
6429 	queue_work(system_wq, &lwiphy->wwk);
6430 }
6431 
6432 void
6433 linuxkpi_wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *wwk)
6434 {
6435 	struct lkpi_wiphy *lwiphy;
6436 
6437 	lwiphy = WIPHY_TO_LWIPHY(wiphy);
6438 
6439 	LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
6440 	/* Only cancel if queued. */
6441 	if (!list_empty(&wwk->entry))
6442 		list_del_init(&wwk->entry);
6443 	LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
6444 }
6445 
6446 void
6447 linuxkpi_wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *wwk)
6448 {
6449 	struct lkpi_wiphy *lwiphy;
6450 	struct wiphy_work *wk;
6451 
6452 	lwiphy = WIPHY_TO_LWIPHY(wiphy);
6453 	LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
6454 	/* If wwk is unset, flush everything; called when wiphy is shut down. */
6455 	if (wwk != NULL && list_empty(&wwk->entry)) {
6456 		LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
6457 		return;
6458 	}
6459 
6460 	while (!list_empty(&lwiphy->wwk_list)) {
6461 
6462 		wk = list_first_entry(&lwiphy->wwk_list, struct wiphy_work,
6463 		    entry);
6464 		list_del_init(&wk->entry);
6465 		LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
6466 		wk->fn(wiphy, wk);
6467 		LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
6468 		if (wk == wwk)
6469 			break;
6470 	}
6471 	LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
6472 }
6473 
6474 void
6475 lkpi_wiphy_delayed_work_timer(struct timer_list *tl)
6476 {
6477 	struct wiphy_delayed_work *wdwk;
6478 
6479 	wdwk = from_timer(wdwk, tl, timer);
6480         wiphy_work_queue(wdwk->wiphy, &wdwk->work);
6481 }
6482 
6483 void
6484 linuxkpi_wiphy_delayed_work_queue(struct wiphy *wiphy,
6485     struct wiphy_delayed_work *wdwk, unsigned long delay)
6486 {
6487 	if (delay == 0) {
6488 		/* Run right away. */
6489 		del_timer(&wdwk->timer);
6490 		wiphy_work_queue(wiphy, &wdwk->work);
6491 	} else {
6492 		wdwk->wiphy = wiphy;
6493 		mod_timer(&wdwk->timer, jiffies + delay);
6494 	}
6495 }
6496 
6497 void
6498 linuxkpi_wiphy_delayed_work_cancel(struct wiphy *wiphy,
6499     struct wiphy_delayed_work *wdwk)
6500 {
6501 	del_timer_sync(&wdwk->timer);
6502 	wiphy_work_cancel(wiphy, &wdwk->work);
6503 }
6504 
6505 /* -------------------------------------------------------------------------- */
6506 
6507 struct wiphy *
6508 linuxkpi_wiphy_new(const struct cfg80211_ops *ops, size_t priv_len)
6509 {
6510 	struct lkpi_wiphy *lwiphy;
6511 	struct wiphy *wiphy;
6512 
6513 	lwiphy = kzalloc(sizeof(*lwiphy) + priv_len, GFP_KERNEL);
6514 	if (lwiphy == NULL)
6515 		return (NULL);
6516 	lwiphy->ops = ops;
6517 
6518 	LKPI_80211_LWIPHY_WORK_LOCK_INIT(lwiphy);
6519 	INIT_LIST_HEAD(&lwiphy->wwk_list);
6520 	INIT_WORK(&lwiphy->wwk, lkpi_wiphy_work);
6521 
6522 	wiphy = LWIPHY_TO_WIPHY(lwiphy);
6523 
6524 	mutex_init(&wiphy->mtx);
6525 	TODO();
6526 
6527 	return (wiphy);
6528 }
6529 
6530 void
6531 linuxkpi_wiphy_free(struct wiphy *wiphy)
6532 {
6533 	struct lkpi_wiphy *lwiphy;
6534 
6535 	if (wiphy == NULL)
6536 		return;
6537 
6538 	linuxkpi_wiphy_work_flush(wiphy, NULL);
6539 	mutex_destroy(&wiphy->mtx);
6540 
6541 	lwiphy = WIPHY_TO_LWIPHY(wiphy);
6542 	LKPI_80211_LWIPHY_WORK_LOCK_DESTROY(lwiphy);
6543 
6544 	kfree(lwiphy);
6545 }
6546 
6547 static uint32_t
6548 lkpi_cfg80211_calculate_bitrate_ht(struct rate_info *rate)
6549 {
6550 	TODO("cfg80211_calculate_bitrate_ht");
6551 	return (rate->legacy);
6552 }
6553 
6554 static uint32_t
6555 lkpi_cfg80211_calculate_bitrate_vht(struct rate_info *rate)
6556 {
6557 	TODO("cfg80211_calculate_bitrate_vht");
6558 	return (rate->legacy);
6559 }
6560 
6561 uint32_t
6562 linuxkpi_cfg80211_calculate_bitrate(struct rate_info *rate)
6563 {
6564 
6565 	/* Beware: order! */
6566 	if (rate->flags & RATE_INFO_FLAGS_MCS)
6567 		return (lkpi_cfg80211_calculate_bitrate_ht(rate));
6568 
6569 	if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
6570 		return (lkpi_cfg80211_calculate_bitrate_vht(rate));
6571 
6572 	IMPROVE("HE/EHT/...");
6573 
6574 	return (rate->legacy);
6575 }
6576 
6577 uint32_t
6578 linuxkpi_ieee80211_channel_to_frequency(uint32_t channel,
6579     enum nl80211_band band)
6580 {
6581 
6582 	switch (band) {
6583 	case NL80211_BAND_2GHZ:
6584 		return (ieee80211_ieee2mhz(channel, IEEE80211_CHAN_2GHZ));
6585 		break;
6586 	case NL80211_BAND_5GHZ:
6587 		return (ieee80211_ieee2mhz(channel, IEEE80211_CHAN_5GHZ));
6588 		break;
6589 	default:
6590 		/* XXX abort, retry, error, panic? */
6591 		break;
6592 	}
6593 
6594 	return (0);
6595 }
6596 
6597 uint32_t
6598 linuxkpi_ieee80211_frequency_to_channel(uint32_t freq, uint32_t flags __unused)
6599 {
6600 
6601 	return (ieee80211_mhz2ieee(freq, 0));
6602 }
6603 
6604 #if 0
6605 static struct lkpi_sta *
6606 lkpi_find_lsta_by_ni(struct lkpi_vif *lvif, struct ieee80211_node *ni)
6607 {
6608 	struct lkpi_sta *lsta, *temp;
6609 
6610 	rcu_read_lock();
6611 	list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
6612 		if (lsta->ni == ni) {
6613 			rcu_read_unlock();
6614 			return (lsta);
6615 		}
6616 	}
6617 	rcu_read_unlock();
6618 
6619 	return (NULL);
6620 }
6621 #endif
6622 
6623 struct ieee80211_sta *
6624 linuxkpi_ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *peer)
6625 {
6626 	struct lkpi_vif *lvif;
6627 	struct lkpi_sta *lsta;
6628 	struct ieee80211_sta *sta;
6629 
6630 	lvif = VIF_TO_LVIF(vif);
6631 
6632 	rcu_read_lock();
6633 	list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
6634 		sta = LSTA_TO_STA(lsta);
6635 		if (IEEE80211_ADDR_EQ(sta->addr, peer)) {
6636 			rcu_read_unlock();
6637 			return (sta);
6638 		}
6639 	}
6640 	rcu_read_unlock();
6641 	return (NULL);
6642 }
6643 
6644 struct ieee80211_sta *
6645 linuxkpi_ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw,
6646     const uint8_t *addr, const uint8_t *ourvifaddr)
6647 {
6648 	struct lkpi_hw *lhw;
6649 	struct lkpi_vif *lvif;
6650 	struct lkpi_sta *lsta;
6651 	struct ieee80211_vif *vif;
6652 	struct ieee80211_sta *sta;
6653 
6654 	lhw = wiphy_priv(hw->wiphy);
6655 	sta = NULL;
6656 
6657 	LKPI_80211_LHW_LVIF_LOCK(lhw);
6658 	TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
6659 
6660 		/* XXX-BZ check our address from the vif. */
6661 
6662 		vif = LVIF_TO_VIF(lvif);
6663 		if (ourvifaddr != NULL &&
6664 		    !IEEE80211_ADDR_EQ(vif->addr, ourvifaddr))
6665 			continue;
6666 		sta = linuxkpi_ieee80211_find_sta(vif, addr);
6667 		if (sta != NULL)
6668 			break;
6669 	}
6670 	LKPI_80211_LHW_LVIF_UNLOCK(lhw);
6671 
6672 	if (sta != NULL) {
6673 		lsta = STA_TO_LSTA(sta);
6674 		if (!lsta->added_to_drv)
6675 			return (NULL);
6676 	}
6677 
6678 	return (sta);
6679 }
6680 
6681 struct sk_buff *
6682 linuxkpi_ieee80211_tx_dequeue(struct ieee80211_hw *hw,
6683     struct ieee80211_txq *txq)
6684 {
6685 	struct lkpi_txq *ltxq;
6686 	struct lkpi_vif *lvif;
6687 	struct sk_buff *skb;
6688 
6689 	skb = NULL;
6690 	ltxq = TXQ_TO_LTXQ(txq);
6691 	ltxq->seen_dequeue = true;
6692 
6693 	if (ltxq->stopped)
6694 		goto stopped;
6695 
6696 	lvif = VIF_TO_LVIF(ltxq->txq.vif);
6697 	if (lvif->hw_queue_stopped[ltxq->txq.ac]) {
6698 		ltxq->stopped = true;
6699 		goto stopped;
6700 	}
6701 
6702 	IMPROVE("hw(TX_FRAG_LIST)");
6703 
6704 	LKPI_80211_LTXQ_LOCK(ltxq);
6705 	skb = skb_dequeue(&ltxq->skbq);
6706 	LKPI_80211_LTXQ_UNLOCK(ltxq);
6707 
6708 stopped:
6709 	return (skb);
6710 }
6711 
6712 void
6713 linuxkpi_ieee80211_txq_get_depth(struct ieee80211_txq *txq,
6714     unsigned long *frame_cnt, unsigned long *byte_cnt)
6715 {
6716 	struct lkpi_txq *ltxq;
6717 	struct sk_buff *skb;
6718 	unsigned long fc, bc;
6719 
6720 	ltxq = TXQ_TO_LTXQ(txq);
6721 
6722 	fc = bc = 0;
6723 	LKPI_80211_LTXQ_LOCK(ltxq);
6724 	skb_queue_walk(&ltxq->skbq, skb) {
6725 		fc++;
6726 		bc += skb->len;
6727 	}
6728 	LKPI_80211_LTXQ_UNLOCK(ltxq);
6729 	if (frame_cnt)
6730 		*frame_cnt = fc;
6731 	if (byte_cnt)
6732 		*byte_cnt = bc;
6733 
6734 	/* Validate that this is doing the correct thing. */
6735 	/* Should we keep track on en/dequeue? */
6736 	IMPROVE();
6737 }
6738 
6739 /*
6740  * We are called from ieee80211_free_txskb() or ieee80211_tx_status().
6741  * The latter tries to derive the success status from the info flags
6742  * passed back from the driver.  rawx_mit() saves the ni on the m and the
6743  * m on the skb for us to be able to give feedback to net80211.
6744  */
6745 static void
6746 _lkpi_ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb,
6747     int status)
6748 {
6749 	struct ieee80211_node *ni;
6750 	struct mbuf *m;
6751 
6752 	m = skb->m;
6753 	skb->m = NULL;
6754 
6755 	if (m != NULL) {
6756 		ni = m->m_pkthdr.PH_loc.ptr;
6757 		/* Status: 0 is ok, != 0 is error. */
6758 		ieee80211_tx_complete(ni, m, status);
6759 		/* ni & mbuf were consumed. */
6760 	}
6761 }
6762 
6763 void
6764 linuxkpi_ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb,
6765     int status)
6766 {
6767 
6768 	_lkpi_ieee80211_free_txskb(hw, skb, status);
6769 	kfree_skb(skb);
6770 }
6771 
6772 void
6773 linuxkpi_ieee80211_tx_status_ext(struct ieee80211_hw *hw,
6774     struct ieee80211_tx_status *txstat)
6775 {
6776 	struct sk_buff *skb;
6777 	struct ieee80211_tx_info *info;
6778 	struct ieee80211_ratectl_tx_status txs;
6779 	struct ieee80211_node *ni;
6780 	int status;
6781 
6782 	skb = txstat->skb;
6783 	if (skb->m != NULL) {
6784 		struct mbuf *m;
6785 
6786 		m = skb->m;
6787 		ni = m->m_pkthdr.PH_loc.ptr;
6788 		memset(&txs, 0, sizeof(txs));
6789 	} else {
6790 		ni = NULL;
6791 	}
6792 
6793 	info = txstat->info;
6794 	if (info->flags & IEEE80211_TX_STAT_ACK) {
6795 		status = 0;	/* No error. */
6796 		txs.status = IEEE80211_RATECTL_TX_SUCCESS;
6797 	} else {
6798 		status = 1;
6799 		txs.status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED;
6800 	}
6801 
6802 	if (ni != NULL) {
6803 		int ridx __unused;
6804 #ifdef LINUXKPI_DEBUG_80211
6805 		int old_rate;
6806 
6807 		old_rate = ni->ni_vap->iv_bss->ni_txrate;
6808 #endif
6809 		txs.pktlen = skb->len;
6810 		txs.flags |= IEEE80211_RATECTL_STATUS_PKTLEN;
6811 		if (info->status.rates[0].count > 1) {
6812 			txs.long_retries = info->status.rates[0].count - 1;	/* 1 + retries in drivers. */
6813 			txs.flags |= IEEE80211_RATECTL_STATUS_LONG_RETRY;
6814 		}
6815 #if 0		/* Unused in net80211 currently. */
6816 		/* XXX-BZ convert check .flags for MCS/VHT/.. */
6817 		txs.final_rate = info->status.rates[0].idx;
6818 		txs.flags |= IEEE80211_RATECTL_STATUS_FINAL_RATE;
6819 #endif
6820 		if (info->status.flags & IEEE80211_TX_STATUS_ACK_SIGNAL_VALID) {
6821 			txs.rssi = info->status.ack_signal;		/* XXX-BZ CONVERT? */
6822 			txs.flags |= IEEE80211_RATECTL_STATUS_RSSI;
6823 		}
6824 
6825 		IMPROVE("only update of rate matches but that requires us to get a proper rate");
6826 		ieee80211_ratectl_tx_complete(ni, &txs);
6827 		ridx = ieee80211_ratectl_rate(ni->ni_vap->iv_bss, NULL, 0);
6828 
6829 #ifdef LINUXKPI_DEBUG_80211
6830 		if (linuxkpi_debug_80211 & D80211_TRACE_TX) {
6831 			printf("TX-RATE: %s: old %d new %d ridx %d, "
6832 			    "long_retries %d\n", __func__,
6833 			    old_rate, ni->ni_vap->iv_bss->ni_txrate,
6834 			    ridx, txs.long_retries);
6835 		}
6836 #endif
6837 	}
6838 
6839 #ifdef LINUXKPI_DEBUG_80211
6840 	if (linuxkpi_debug_80211 & D80211_TRACE_TX)
6841 		printf("TX-STATUS: %s: hw %p skb %p status %d : flags %#x "
6842 		    "band %u hw_queue %u tx_time_est %d : "
6843 		    "rates [ %u %u %#x, %u %u %#x, %u %u %#x, %u %u %#x ] "
6844 		    "ack_signal %u ampdu_ack_len %u ampdu_len %u antenna %u "
6845 		    "tx_time %u flags %#x "
6846 		    "status_driver_data [ %p %p ]\n",
6847 		    __func__, hw, skb, status, info->flags,
6848 		    info->band, info->hw_queue, info->tx_time_est,
6849 		    info->status.rates[0].idx, info->status.rates[0].count,
6850 		    info->status.rates[0].flags,
6851 		    info->status.rates[1].idx, info->status.rates[1].count,
6852 		    info->status.rates[1].flags,
6853 		    info->status.rates[2].idx, info->status.rates[2].count,
6854 		    info->status.rates[2].flags,
6855 		    info->status.rates[3].idx, info->status.rates[3].count,
6856 		    info->status.rates[3].flags,
6857 		    info->status.ack_signal, info->status.ampdu_ack_len,
6858 		    info->status.ampdu_len, info->status.antenna,
6859 		    info->status.tx_time, info->status.flags,
6860 		    info->status.status_driver_data[0],
6861 		    info->status.status_driver_data[1]);
6862 #endif
6863 
6864 	if (txstat->free_list) {
6865 		_lkpi_ieee80211_free_txskb(hw, skb, status);
6866 		list_add_tail(&skb->list, txstat->free_list);
6867 	} else {
6868 		linuxkpi_ieee80211_free_txskb(hw, skb, status);
6869 	}
6870 }
6871 
6872 void
6873 linuxkpi_ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
6874 {
6875 	struct ieee80211_tx_status status;
6876 
6877 	memset(&status, 0, sizeof(status));
6878 	status.info = IEEE80211_SKB_CB(skb);
6879 	status.skb = skb;
6880 	/* sta, n_rates, rates, free_list? */
6881 
6882 	ieee80211_tx_status_ext(hw, &status);
6883 }
6884 
6885 /*
6886  * This is an internal bandaid for the moment for the way we glue
6887  * skbs and mbufs together for TX.  Once we have skbs backed by
6888  * mbufs this should go away.
6889  * This is a public function but kept on the private KPI (lkpi_)
6890  * and is not exposed by a header file.
6891  */
6892 static void
6893 lkpi_ieee80211_free_skb_mbuf(void *p)
6894 {
6895 	struct ieee80211_node *ni;
6896 	struct mbuf *m;
6897 
6898 	if (p == NULL)
6899 		return;
6900 
6901 	m = (struct mbuf *)p;
6902 	M_ASSERTPKTHDR(m);
6903 
6904 	ni = m->m_pkthdr.PH_loc.ptr;
6905 	m->m_pkthdr.PH_loc.ptr = NULL;
6906 	if (ni != NULL)
6907 		ieee80211_free_node(ni);
6908 	m_freem(m);
6909 }
6910 
6911 void
6912 linuxkpi_ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
6913     struct delayed_work *w, int delay)
6914 {
6915 	struct lkpi_hw *lhw;
6916 
6917 	/* Need to make sure hw is in a stable (non-suspended) state. */
6918 	IMPROVE();
6919 
6920 	lhw = HW_TO_LHW(hw);
6921 	queue_delayed_work(lhw->workq, w, delay);
6922 }
6923 
6924 void
6925 linuxkpi_ieee80211_queue_work(struct ieee80211_hw *hw,
6926     struct work_struct *w)
6927 {
6928 	struct lkpi_hw *lhw;
6929 
6930 	/* Need to make sure hw is in a stable (non-suspended) state. */
6931 	IMPROVE();
6932 
6933 	lhw = HW_TO_LHW(hw);
6934 	queue_work(lhw->workq, w);
6935 }
6936 
6937 struct sk_buff *
6938 linuxkpi_ieee80211_probereq_get(struct ieee80211_hw *hw, uint8_t *addr,
6939     uint8_t *ssid, size_t ssid_len, size_t tailroom)
6940 {
6941 	struct sk_buff *skb;
6942 	struct ieee80211_frame *wh;
6943 	uint8_t *p;
6944 	size_t len;
6945 
6946 	len = sizeof(*wh);
6947 	len += 2 + ssid_len;
6948 
6949 	skb = dev_alloc_skb(hw->extra_tx_headroom + len + tailroom);
6950 	if (skb == NULL)
6951 		return (NULL);
6952 
6953 	skb_reserve(skb, hw->extra_tx_headroom);
6954 
6955 	wh = skb_put_zero(skb, sizeof(*wh));
6956 	wh->i_fc[0] = IEEE80211_FC0_VERSION_0;
6957 	wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_PROBE_REQ | IEEE80211_FC0_TYPE_MGT;
6958 	IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr);
6959 	IEEE80211_ADDR_COPY(wh->i_addr2, addr);
6960 	IEEE80211_ADDR_COPY(wh->i_addr3, ieee80211broadcastaddr);
6961 
6962 	p = skb_put(skb, 2 + ssid_len);
6963 	*p++ = IEEE80211_ELEMID_SSID;
6964 	*p++ = ssid_len;
6965 	if (ssid_len > 0)
6966 		memcpy(p, ssid, ssid_len);
6967 
6968 	return (skb);
6969 }
6970 
6971 struct sk_buff *
6972 linuxkpi_ieee80211_pspoll_get(struct ieee80211_hw *hw,
6973     struct ieee80211_vif *vif)
6974 {
6975 	struct lkpi_vif *lvif;
6976 	struct ieee80211vap *vap;
6977 	struct sk_buff *skb;
6978 	struct ieee80211_frame_pspoll *psp;
6979 	uint16_t v;
6980 
6981 	skb = dev_alloc_skb(hw->extra_tx_headroom + sizeof(*psp));
6982 	if (skb == NULL)
6983 		return (NULL);
6984 
6985 	skb_reserve(skb, hw->extra_tx_headroom);
6986 
6987 	lvif = VIF_TO_LVIF(vif);
6988 	vap = LVIF_TO_VAP(lvif);
6989 
6990 	psp = skb_put_zero(skb, sizeof(*psp));
6991 	psp->i_fc[0] = IEEE80211_FC0_VERSION_0;
6992 	psp->i_fc[0] |= IEEE80211_FC0_SUBTYPE_PS_POLL | IEEE80211_FC0_TYPE_CTL;
6993 	v = htole16(vif->cfg.aid | 1<<15 | 1<<16);
6994 	memcpy(&psp->i_aid, &v, sizeof(v));
6995 	IEEE80211_ADDR_COPY(psp->i_bssid, vap->iv_bss->ni_macaddr);
6996 	IEEE80211_ADDR_COPY(psp->i_ta, vif->addr);
6997 
6998 	return (skb);
6999 }
7000 
7001 struct sk_buff *
7002 linuxkpi_ieee80211_nullfunc_get(struct ieee80211_hw *hw,
7003     struct ieee80211_vif *vif, int linkid, bool qos)
7004 {
7005 	struct lkpi_vif *lvif;
7006 	struct ieee80211vap *vap;
7007 	struct sk_buff *skb;
7008 	struct ieee80211_frame *nullf;
7009 
7010 	IMPROVE("linkid");
7011 
7012 	skb = dev_alloc_skb(hw->extra_tx_headroom + sizeof(*nullf));
7013 	if (skb == NULL)
7014 		return (NULL);
7015 
7016 	skb_reserve(skb, hw->extra_tx_headroom);
7017 
7018 	lvif = VIF_TO_LVIF(vif);
7019 	vap = LVIF_TO_VAP(lvif);
7020 
7021 	nullf = skb_put_zero(skb, sizeof(*nullf));
7022 	nullf->i_fc[0] = IEEE80211_FC0_VERSION_0;
7023 	nullf->i_fc[0] |= IEEE80211_FC0_SUBTYPE_NODATA | IEEE80211_FC0_TYPE_DATA;
7024 	nullf->i_fc[1] = IEEE80211_FC1_DIR_TODS;
7025 
7026 	IEEE80211_ADDR_COPY(nullf->i_addr1, vap->iv_bss->ni_bssid);
7027 	IEEE80211_ADDR_COPY(nullf->i_addr2, vif->addr);
7028 	IEEE80211_ADDR_COPY(nullf->i_addr3, vap->iv_bss->ni_macaddr);
7029 
7030 	return (skb);
7031 }
7032 
7033 struct wireless_dev *
7034 linuxkpi_ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
7035 {
7036 	struct lkpi_vif *lvif;
7037 
7038 	lvif = VIF_TO_LVIF(vif);
7039 	return (&lvif->wdev);
7040 }
7041 
7042 void
7043 linuxkpi_ieee80211_connection_loss(struct ieee80211_vif *vif)
7044 {
7045 	struct lkpi_vif *lvif;
7046 	struct ieee80211vap *vap;
7047 	enum ieee80211_state nstate;
7048 	int arg;
7049 
7050 	lvif = VIF_TO_LVIF(vif);
7051 	vap = LVIF_TO_VAP(lvif);
7052 
7053 	/*
7054 	 * Go to init; otherwise we need to elaborately check state and
7055 	 * handle accordingly, e.g., if in RUN we could call iv_bmiss.
7056 	 * Let the statemachine handle all neccessary changes.
7057 	 */
7058 	nstate = IEEE80211_S_INIT;
7059 	arg = 0;	/* Not a valid reason. */
7060 
7061 	ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s\n", __func__,
7062 	    vif, vap, ieee80211_state_name[vap->iv_state]);
7063 	ieee80211_new_state(vap, nstate, arg);
7064 }
7065 
7066 void
7067 linuxkpi_ieee80211_beacon_loss(struct ieee80211_vif *vif)
7068 {
7069 	struct lkpi_vif *lvif;
7070 	struct ieee80211vap *vap;
7071 
7072 	lvif = VIF_TO_LVIF(vif);
7073 	vap = LVIF_TO_VAP(lvif);
7074 
7075 	ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s\n", __func__,
7076 	    vif, vap, ieee80211_state_name[vap->iv_state]);
7077 	ieee80211_beacon_miss(vap->iv_ic);
7078 }
7079 
7080 /* -------------------------------------------------------------------------- */
7081 
7082 void
7083 linuxkpi_ieee80211_stop_queue(struct ieee80211_hw *hw, int qnum)
7084 {
7085 	struct lkpi_hw *lhw;
7086 	struct lkpi_vif *lvif;
7087 	struct ieee80211_vif *vif;
7088 	int ac_count, ac;
7089 
7090 	KASSERT(qnum < hw->queues, ("%s: qnum %d >= hw->queues %d, hw %p\n",
7091 	    __func__, qnum, hw->queues, hw));
7092 
7093 	lhw = wiphy_priv(hw->wiphy);
7094 
7095 	/* See lkpi_ic_vap_create(). */
7096 	if (hw->queues >= IEEE80211_NUM_ACS)
7097 		ac_count = IEEE80211_NUM_ACS;
7098 	else
7099 		ac_count = 1;
7100 
7101 	LKPI_80211_LHW_LVIF_LOCK(lhw);
7102 	TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
7103 
7104 		vif = LVIF_TO_VIF(lvif);
7105 		for (ac = 0; ac < ac_count; ac++) {
7106 			IMPROVE_TXQ("LOCKING");
7107 			if (qnum == vif->hw_queue[ac]) {
7108 #ifdef LINUXKPI_DEBUG_80211
7109 				/*
7110 				 * For now log this to better understand
7111 				 * how this is supposed to work.
7112 				 */
7113 				if (lvif->hw_queue_stopped[ac] &&
7114 				    (linuxkpi_debug_80211 & D80211_IMPROVE_TXQ) != 0)
7115 					ic_printf(lhw->ic, "%s:%d: lhw %p hw %p "
7116 					    "lvif %p vif %p ac %d qnum %d already "
7117 					    "stopped\n", __func__, __LINE__,
7118 					    lhw, hw, lvif, vif, ac, qnum);
7119 #endif
7120 				lvif->hw_queue_stopped[ac] = true;
7121 			}
7122 		}
7123 	}
7124 	LKPI_80211_LHW_LVIF_UNLOCK(lhw);
7125 }
7126 
7127 void
7128 linuxkpi_ieee80211_stop_queues(struct ieee80211_hw *hw)
7129 {
7130 	int i;
7131 
7132 	IMPROVE_TXQ("Locking; do we need further info?");
7133 	for (i = 0; i < hw->queues; i++)
7134 		linuxkpi_ieee80211_stop_queue(hw, i);
7135 }
7136 
7137 
7138 static void
7139 lkpi_ieee80211_wake_queues(struct ieee80211_hw *hw, int hwq)
7140 {
7141 	struct lkpi_hw *lhw;
7142 	struct lkpi_vif *lvif;
7143 	struct lkpi_sta *lsta;
7144 	int ac_count, ac, tid;
7145 
7146 	/* See lkpi_ic_vap_create(). */
7147 	if (hw->queues >= IEEE80211_NUM_ACS)
7148 		ac_count = IEEE80211_NUM_ACS;
7149 	else
7150 		ac_count = 1;
7151 
7152 	lhw = wiphy_priv(hw->wiphy);
7153 
7154 	IMPROVE_TXQ("Locking");
7155 	LKPI_80211_LHW_LVIF_LOCK(lhw);
7156 	TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
7157 		struct ieee80211_vif *vif;
7158 
7159 		vif = LVIF_TO_VIF(lvif);
7160 		for (ac = 0; ac < ac_count; ac++) {
7161 
7162 			if (hwq == vif->hw_queue[ac]) {
7163 
7164 				/* XXX-BZ what about software scan? */
7165 
7166 #ifdef LINUXKPI_DEBUG_80211
7167 				/*
7168 				 * For now log this to better understand
7169 				 * how this is supposed to work.
7170 				 */
7171 				if (!lvif->hw_queue_stopped[ac] &&
7172 				    (linuxkpi_debug_80211 & D80211_IMPROVE_TXQ) != 0)
7173 					ic_printf(lhw->ic, "%s:%d: lhw %p hw %p "
7174 					    "lvif %p vif %p ac %d hw_q not stopped\n",
7175 					    __func__, __LINE__,
7176 					    lhw, hw, lvif, vif, ac);
7177 #endif
7178 				lvif->hw_queue_stopped[ac] = false;
7179 
7180 				rcu_read_lock();
7181 				list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
7182 					struct ieee80211_sta *sta;
7183 
7184 					sta = LSTA_TO_STA(lsta);
7185 					for (tid = 0; tid < nitems(sta->txq); tid++) {
7186 						struct lkpi_txq *ltxq;
7187 
7188 						if (sta->txq[tid] == NULL)
7189 							continue;
7190 
7191 						if (sta->txq[tid]->ac != ac)
7192 							continue;
7193 
7194 						ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
7195 						if (!ltxq->stopped)
7196 							continue;
7197 
7198 						ltxq->stopped = false;
7199 
7200 						/* XXX-BZ see when this explodes with all the locking. taskq? */
7201 						lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid]);
7202 					}
7203 				}
7204 				rcu_read_unlock();
7205 			}
7206 		}
7207 	}
7208 	LKPI_80211_LHW_LVIF_UNLOCK(lhw);
7209 }
7210 
7211 void
7212 linuxkpi_ieee80211_wake_queues(struct ieee80211_hw *hw)
7213 {
7214 	int i;
7215 
7216 	IMPROVE_TXQ("Is this all/enough here?");
7217 	for (i = 0; i < hw->queues; i++)
7218 		lkpi_ieee80211_wake_queues(hw, i);
7219 }
7220 
7221 void
7222 linuxkpi_ieee80211_wake_queue(struct ieee80211_hw *hw, int qnum)
7223 {
7224 
7225 	KASSERT(qnum < hw->queues, ("%s: qnum %d >= hw->queues %d, hw %p\n",
7226 	    __func__, qnum, hw->queues, hw));
7227 
7228 	lkpi_ieee80211_wake_queues(hw, qnum);
7229 }
7230 
7231 /* This is just hardware queues. */
7232 void
7233 linuxkpi_ieee80211_txq_schedule_start(struct ieee80211_hw *hw, uint8_t ac)
7234 {
7235 	struct lkpi_hw *lhw;
7236 
7237 	lhw = HW_TO_LHW(hw);
7238 
7239 	IMPROVE_TXQ("Are there reasons why we wouldn't schedule?");
7240 	IMPROVE_TXQ("LOCKING");
7241 	if (++lhw->txq_generation[ac] == 0)
7242 		lhw->txq_generation[ac]++;
7243 }
7244 
7245 struct ieee80211_txq *
7246 linuxkpi_ieee80211_next_txq(struct ieee80211_hw *hw, uint8_t ac)
7247 {
7248 	struct lkpi_hw *lhw;
7249 	struct ieee80211_txq *txq;
7250 	struct lkpi_txq *ltxq;
7251 
7252 	lhw = HW_TO_LHW(hw);
7253 	txq = NULL;
7254 
7255 	IMPROVE_TXQ("LOCKING");
7256 
7257 	/* Check that we are scheduled. */
7258 	if (lhw->txq_generation[ac] == 0)
7259 		goto out;
7260 
7261 	ltxq = TAILQ_FIRST(&lhw->scheduled_txqs[ac]);
7262 	if (ltxq == NULL)
7263 		goto out;
7264 	if (ltxq->txq_generation == lhw->txq_generation[ac])
7265 		goto out;
7266 
7267 	ltxq->txq_generation = lhw->txq_generation[ac];
7268 	TAILQ_REMOVE(&lhw->scheduled_txqs[ac], ltxq, txq_entry);
7269 	txq = &ltxq->txq;
7270 	TAILQ_ELEM_INIT(ltxq, txq_entry);
7271 
7272 out:
7273 	return (txq);
7274 }
7275 
7276 void linuxkpi_ieee80211_schedule_txq(struct ieee80211_hw *hw,
7277     struct ieee80211_txq *txq, bool withoutpkts)
7278 {
7279 	struct lkpi_hw *lhw;
7280 	struct lkpi_txq *ltxq;
7281 	bool ltxq_empty;
7282 
7283 	ltxq = TXQ_TO_LTXQ(txq);
7284 
7285 	IMPROVE_TXQ("LOCKING");
7286 
7287 	/* Only schedule if work to do or asked to anyway. */
7288 	LKPI_80211_LTXQ_LOCK(ltxq);
7289 	ltxq_empty = skb_queue_empty(&ltxq->skbq);
7290 	LKPI_80211_LTXQ_UNLOCK(ltxq);
7291 	if (!withoutpkts && ltxq_empty)
7292 		goto out;
7293 
7294 	/*
7295 	 * Make sure we do not double-schedule. We do this by checking tqe_prev,
7296 	 * the previous entry in our tailq. tqe_prev is always valid if this entry
7297 	 * is queued, tqe_next may be NULL if this is the only element in the list.
7298 	 */
7299 	if (ltxq->txq_entry.tqe_prev != NULL)
7300 		goto out;
7301 
7302 	lhw = HW_TO_LHW(hw);
7303 	TAILQ_INSERT_TAIL(&lhw->scheduled_txqs[txq->ac], ltxq, txq_entry);
7304 out:
7305 	return;
7306 }
7307 
7308 void
7309 linuxkpi_ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
7310     struct ieee80211_txq *txq)
7311 {
7312 	struct lkpi_hw *lhw;
7313 	struct ieee80211_txq *ntxq;
7314 	struct ieee80211_tx_control control;
7315         struct sk_buff *skb;
7316 
7317 	lhw = HW_TO_LHW(hw);
7318 
7319 	LKPI_80211_LHW_TXQ_LOCK(lhw);
7320 	ieee80211_txq_schedule_start(hw, txq->ac);
7321 	do {
7322 		ntxq = ieee80211_next_txq(hw, txq->ac);
7323 		if (ntxq == NULL)
7324 			break;
7325 
7326 		memset(&control, 0, sizeof(control));
7327 		control.sta = ntxq->sta;
7328 		do {
7329 			skb = linuxkpi_ieee80211_tx_dequeue(hw, ntxq);
7330 			if (skb == NULL)
7331 				break;
7332 			lkpi_80211_mo_tx(hw, &control, skb);
7333 		} while(1);
7334 
7335 		ieee80211_return_txq(hw, ntxq, false);
7336 	} while (1);
7337 	ieee80211_txq_schedule_end(hw, txq->ac);
7338 	LKPI_80211_LHW_TXQ_UNLOCK(lhw);
7339 }
7340 
7341 /* -------------------------------------------------------------------------- */
7342 
7343 struct lkpi_cfg80211_bss {
7344 	u_int refcnt;
7345 	struct cfg80211_bss bss;
7346 };
7347 
7348 struct lkpi_cfg80211_get_bss_iter_lookup {
7349 	struct wiphy *wiphy;
7350 	struct linuxkpi_ieee80211_channel *chan;
7351 	const uint8_t *bssid;
7352 	const uint8_t *ssid;
7353 	size_t ssid_len;
7354 	enum ieee80211_bss_type bss_type;
7355 	enum ieee80211_privacy privacy;
7356 
7357 	/*
7358 	 * Something to store a copy of the result as the net80211 scan cache
7359 	 * is not refoucnted so a scan entry might go away any time.
7360 	 */
7361 	bool match;
7362 	struct cfg80211_bss *bss;
7363 };
7364 
7365 static void
7366 lkpi_cfg80211_get_bss_iterf(void *arg, const struct ieee80211_scan_entry *se)
7367 {
7368 	struct lkpi_cfg80211_get_bss_iter_lookup *lookup;
7369 	size_t ielen;
7370 
7371 	lookup = arg;
7372 
7373 	/* Do not try to find another match. */
7374 	if (lookup->match)
7375 		return;
7376 
7377 	/* Nothing to store result. */
7378 	if (lookup->bss == NULL)
7379 		return;
7380 
7381 	if (lookup->privacy != IEEE80211_PRIVACY_ANY) {
7382 		/* if (se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) */
7383 		/* We have no idea what to compare to as the drivers only request ANY */
7384 		return;
7385 	}
7386 
7387 	if (lookup->bss_type != IEEE80211_BSS_TYPE_ANY) {
7388 		/* if (se->se_capinfo & (IEEE80211_CAPINFO_IBSS|IEEE80211_CAPINFO_ESS)) */
7389 		/* We have no idea what to compare to as the drivers only request ANY */
7390 		return;
7391 	}
7392 
7393 	if (lookup->chan != NULL) {
7394 		struct linuxkpi_ieee80211_channel *chan;
7395 
7396 		chan = linuxkpi_ieee80211_get_channel(lookup->wiphy,
7397 		    se->se_chan->ic_freq);
7398 		if (chan == NULL || chan != lookup->chan)
7399 			return;
7400 	}
7401 
7402 	if (lookup->bssid && !IEEE80211_ADDR_EQ(lookup->bssid, se->se_bssid))
7403 		return;
7404 
7405 	if (lookup->ssid) {
7406 		if (lookup->ssid_len != se->se_ssid[1] ||
7407 		    se->se_ssid[1] == 0)
7408 			return;
7409 		if (memcmp(lookup->ssid, se->se_ssid+2, lookup->ssid_len) != 0)
7410 			return;
7411 	}
7412 
7413 	ielen = se->se_ies.len;
7414 
7415 	lookup->bss->ies = malloc(sizeof(*lookup->bss->ies) + ielen,
7416 	    M_LKPI80211, M_NOWAIT | M_ZERO);
7417 	if (lookup->bss->ies == NULL)
7418 		return;
7419 
7420 	lookup->bss->ies->data = (uint8_t *)lookup->bss->ies + sizeof(*lookup->bss->ies);
7421 	lookup->bss->ies->len = ielen;
7422 	if (ielen)
7423 		memcpy(lookup->bss->ies->data, se->se_ies.data, ielen);
7424 
7425 	lookup->match = true;
7426 }
7427 
7428 struct cfg80211_bss *
7429 linuxkpi_cfg80211_get_bss(struct wiphy *wiphy, struct linuxkpi_ieee80211_channel *chan,
7430     const uint8_t *bssid, const uint8_t *ssid, size_t ssid_len,
7431     enum ieee80211_bss_type bss_type, enum ieee80211_privacy privacy)
7432 {
7433 	struct lkpi_cfg80211_bss *lbss;
7434 	struct lkpi_cfg80211_get_bss_iter_lookup lookup;
7435 	struct lkpi_hw *lhw;
7436 	struct ieee80211vap *vap;
7437 
7438 	lhw = wiphy_priv(wiphy);
7439 
7440 	/* Let's hope we can alloc. */
7441 	lbss = malloc(sizeof(*lbss), M_LKPI80211, M_NOWAIT | M_ZERO);
7442 	if (lbss == NULL) {
7443 		ic_printf(lhw->ic, "%s: alloc failed.\n", __func__);
7444 		return (NULL);
7445 	}
7446 
7447 	lookup.wiphy = wiphy;
7448 	lookup.chan = chan;
7449 	lookup.bssid = bssid;
7450 	lookup.ssid = ssid;
7451 	lookup.ssid_len = ssid_len;
7452 	lookup.bss_type = bss_type;
7453 	lookup.privacy = privacy;
7454 	lookup.match = false;
7455 	lookup.bss = &lbss->bss;
7456 
7457 	IMPROVE("Iterate over all VAPs comparing perm_addr and addresses?");
7458 	vap = TAILQ_FIRST(&lhw->ic->ic_vaps);
7459 	ieee80211_scan_iterate(vap, lkpi_cfg80211_get_bss_iterf, &lookup);
7460 	if (!lookup.match) {
7461 		free(lbss, M_LKPI80211);
7462 		return (NULL);
7463 	}
7464 
7465 	refcount_init(&lbss->refcnt, 1);
7466 	return (&lbss->bss);
7467 }
7468 
7469 void
7470 linuxkpi_cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss)
7471 {
7472 	struct lkpi_cfg80211_bss *lbss;
7473 
7474 	lbss = container_of(bss, struct lkpi_cfg80211_bss, bss);
7475 
7476 	/* Free everything again on refcount ... */
7477 	if (refcount_release(&lbss->refcnt)) {
7478 		free(lbss->bss.ies, M_LKPI80211);
7479 		free(lbss, M_LKPI80211);
7480 	}
7481 }
7482 
7483 void
7484 linuxkpi_cfg80211_bss_flush(struct wiphy *wiphy)
7485 {
7486 	struct lkpi_hw *lhw;
7487 	struct ieee80211com *ic;
7488 	struct ieee80211vap *vap;
7489 
7490 	lhw = wiphy_priv(wiphy);
7491 	ic = lhw->ic;
7492 
7493 	/*
7494 	 * If we haven't called ieee80211_ifattach() yet
7495 	 * or there is no VAP, there are no scans to flush.
7496 	 */
7497 	if (ic == NULL ||
7498 	    (lhw->sc_flags & LKPI_MAC80211_DRV_STARTED) == 0)
7499 		return;
7500 
7501 	/* Should only happen on the current one? Not seen it late enough. */
7502 	IEEE80211_LOCK(ic);
7503 	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
7504 		ieee80211_scan_flush(vap);
7505 	IEEE80211_UNLOCK(ic);
7506 }
7507 
7508 /* -------------------------------------------------------------------------- */
7509 
7510 /*
7511  * hw->conf get initialized/set in various places for us:
7512  * - linuxkpi_ieee80211_alloc_hw(): flags
7513  * - linuxkpi_ieee80211_ifattach(): chandef
7514  * - lkpi_ic_vap_create(): listen_interval
7515  * - lkpi_ic_set_channel(): chandef, flags
7516  */
7517 
7518 int lkpi_80211_update_chandef(struct ieee80211_hw *hw,
7519     struct ieee80211_chanctx_conf *new)
7520 {
7521 	struct cfg80211_chan_def *cd;
7522 	uint32_t changed;
7523 	int error;
7524 
7525 	changed = 0;
7526 	if (new == NULL || new->def.chan == NULL)
7527 		cd = NULL;
7528 	else
7529 		cd = &new->def;
7530 
7531 	if (cd && cd->chan != hw->conf.chandef.chan) {
7532 		/* Copy; the chan pointer is fine and will stay valid. */
7533 		hw->conf.chandef = *cd;
7534 		changed |= IEEE80211_CONF_CHANGE_CHANNEL;
7535 	}
7536 	IMPROVE("IEEE80211_CONF_CHANGE_PS, IEEE80211_CONF_CHANGE_POWER");
7537 
7538 	if (changed == 0)
7539 		return (0);
7540 
7541 	error = lkpi_80211_mo_config(hw, changed);
7542 	return (error);
7543 }
7544 
7545 /* -------------------------------------------------------------------------- */
7546 
7547 MODULE_VERSION(linuxkpi_wlan, 1);
7548 MODULE_DEPEND(linuxkpi_wlan, linuxkpi, 1, 1, 1);
7549 MODULE_DEPEND(linuxkpi_wlan, wlan, 1, 1, 1);
7550