xref: /freebsd/sys/dev/iwx/if_iwx.c (revision c4fde87a3236b500246d4fce76dbca2a3d64f73a)
1 /*-
2  * SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) AND ISC
3  */
4 
5 /*	$OpenBSD: if_iwx.c,v 1.184 2024/05/08 14:03:54 stsp Exp $	*/
6 
7 /*
8  *
9  * Copyright (c) 2025 The FreeBSD Foundation
10  *
11  * Portions of this software were developed by Tom Jones <thj@FreeBSD.org>
12  * under sponsorship from the FreeBSD Foundation.
13  *
14  * Permission to use, copy, modify, and distribute this software for any
15  * purpose with or without fee is hereby granted, provided that the above
16  * copyright notice and this permission notice appear in all copies.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
19  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
21  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
23  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
24  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25  *
26  */
27 
28 /*-
29  * Copyright (c) 2024 Future Crew, LLC
30  *   Author: Mikhail Pchelin <misha@FreeBSD.org>
31  *
32  * Permission to use, copy, modify, and distribute this software for any
33  * purpose with or without fee is hereby granted, provided that the above
34  * copyright notice and this permission notice appear in all copies.
35  *
36  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
37  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
38  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
39  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
41  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
42  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
43  */
44 
45 /*
46  * Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
47  *   Author: Stefan Sperling <stsp@openbsd.org>
48  * Copyright (c) 2014 Fixup Software Ltd.
49  * Copyright (c) 2017, 2019, 2020 Stefan Sperling <stsp@openbsd.org>
50  *
51  * Permission to use, copy, modify, and distribute this software for any
52  * purpose with or without fee is hereby granted, provided that the above
53  * copyright notice and this permission notice appear in all copies.
54  *
55  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
56  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
57  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
58  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
59  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
60  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
61  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
62  */
63 
64 /*-
65  * Based on BSD-licensed source modules in the Linux iwlwifi driver,
66  * which were used as the reference documentation for this implementation.
67  *
68  ******************************************************************************
69  *
70  * This file is provided under a dual BSD/GPLv2 license.  When using or
71  * redistributing this file, you may do so under either license.
72  *
73  * GPL LICENSE SUMMARY
74  *
75  * Copyright(c) 2017 Intel Deutschland GmbH
76  * Copyright(c) 2018 - 2019 Intel Corporation
77  *
78  * This program is free software; you can redistribute it and/or modify
79  * it under the terms of version 2 of the GNU General Public License as
80  * published by the Free Software Foundation.
81  *
82  * This program is distributed in the hope that it will be useful, but
83  * WITHOUT ANY WARRANTY; without even the implied warranty of
84  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
85  * General Public License for more details.
86  *
87  * BSD LICENSE
88  *
89  * Copyright(c) 2017 Intel Deutschland GmbH
90  * Copyright(c) 2018 - 2019 Intel Corporation
91  * All rights reserved.
92  *
93  * Redistribution and use in source and binary forms, with or without
94  * modification, are permitted provided that the following conditions
95  * are met:
96  *
97  *  * Redistributions of source code must retain the above copyright
98  *    notice, this list of conditions and the following disclaimer.
99  *  * Redistributions in binary form must reproduce the above copyright
100  *    notice, this list of conditions and the following disclaimer in
101  *    the documentation and/or other materials provided with the
102  *    distribution.
103  *  * Neither the name Intel Corporation nor the names of its
104  *    contributors may be used to endorse or promote products derived
105  *    from this software without specific prior written permission.
106  *
107  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
108  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
109  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
110  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
111  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
112  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
113  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
114  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
115  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
116  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
117  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118  *
119  *****************************************************************************
120  */
121 
122 /*-
123  * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
124  *
125  * Permission to use, copy, modify, and distribute this software for any
126  * purpose with or without fee is hereby granted, provided that the above
127  * copyright notice and this permission notice appear in all copies.
128  *
129  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
130  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
131  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
132  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
133  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
134  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
135  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
136  */
137 
138 #include <sys/param.h>
139 #include <sys/bus.h>
140 #include <sys/module.h>
141 #include <sys/conf.h>
142 #include <sys/kernel.h>
143 #include <sys/malloc.h>
144 #include <sys/mbuf.h>
145 #include <sys/mutex.h>
146 #include <sys/proc.h>
147 #include <sys/rman.h>
148 #include <sys/rwlock.h>
149 #include <sys/socket.h>
150 #include <sys/sockio.h>
151 #include <sys/systm.h>
152 #include <sys/endian.h>
153 #include <sys/linker.h>
154 #include <sys/firmware.h>
155 #include <sys/epoch.h>
156 #include <sys/kdb.h>
157 
158 #include <machine/_inttypes.h>
159 #include <machine/bus.h>
160 #include <machine/endian.h>
161 #include <machine/resource.h>
162 
163 #include <dev/pci/pcireg.h>
164 #include <dev/pci/pcivar.h>
165 
166 #include <net/bpf.h>
167 
168 #include <net/if.h>
169 #include <net/if_var.h>
170 #include <net/if_dl.h>
171 #include <net/if_media.h>
172 
173 #include <netinet/in.h>
174 #include <netinet/if_ether.h>
175 
176 #include <net80211/ieee80211_var.h>
177 #include <net80211/ieee80211_radiotap.h>
178 #include <net80211/ieee80211_regdomain.h>
179 #include <net80211/ieee80211_ratectl.h>
180 #include <net80211/ieee80211_vht.h>
181 
182 int iwx_himark = 224;
183 int iwx_lomark = 192;
184 
185 #define IWX_FBSD_RSP_V3 3
186 #define IWX_FBSD_RSP_V4 4
187 
188 #define DEVNAME(_sc)    (device_get_nameunit((_sc)->sc_dev))
189 #define IC2IFP(ic) (((struct ieee80211vap *)TAILQ_FIRST(&(ic)->ic_vaps))->iv_ifp)
190 
191 #define le16_to_cpup(_a_) (le16toh(*(const uint16_t *)(_a_)))
192 #define le32_to_cpup(_a_) (le32toh(*(const uint32_t *)(_a_)))
193 
194 #include <dev/iwx/if_iwxreg.h>
195 #include <dev/iwx/if_iwxvar.h>
196 
197 #include <dev/iwx/if_iwx_debug.h>
198 
199 #define	PCI_CFG_RETRY_TIMEOUT	0x41
200 
201 #define PCI_VENDOR_INTEL		0x8086
202 #define	PCI_PRODUCT_INTEL_WL_22500_1	0x2723		/* Wi-Fi 6 AX200 */
203 #define	PCI_PRODUCT_INTEL_WL_22500_2	0x02f0		/* Wi-Fi 6 AX201 */
204 #define	PCI_PRODUCT_INTEL_WL_22500_3	0xa0f0		/* Wi-Fi 6 AX201 */
205 #define	PCI_PRODUCT_INTEL_WL_22500_4	0x34f0		/* Wi-Fi 6 AX201 */
206 #define	PCI_PRODUCT_INTEL_WL_22500_5	0x06f0		/* Wi-Fi 6 AX201 */
207 #define	PCI_PRODUCT_INTEL_WL_22500_6	0x43f0		/* Wi-Fi 6 AX201 */
208 #define	PCI_PRODUCT_INTEL_WL_22500_7	0x3df0		/* Wi-Fi 6 AX201 */
209 #define	PCI_PRODUCT_INTEL_WL_22500_8	0x4df0		/* Wi-Fi 6 AX201 */
210 #define	PCI_PRODUCT_INTEL_WL_22500_9	0x2725		/* Wi-Fi 6 AX210 */
211 #define	PCI_PRODUCT_INTEL_WL_22500_10	0x2726		/* Wi-Fi 6 AX211 */
212 #define	PCI_PRODUCT_INTEL_WL_22500_11	0x51f0		/* Wi-Fi 6 AX211 */
213 #define	PCI_PRODUCT_INTEL_WL_22500_12	0x7a70		/* Wi-Fi 6 AX211 */
214 #define	PCI_PRODUCT_INTEL_WL_22500_13	0x7af0		/* Wi-Fi 6 AX211 */
215 #define	PCI_PRODUCT_INTEL_WL_22500_14	0x7e40		/* Wi-Fi 6 AX210 */
216 #define	PCI_PRODUCT_INTEL_WL_22500_15	0x7f70		/* Wi-Fi 6 AX211 */
217 #define	PCI_PRODUCT_INTEL_WL_22500_16	0x54f0		/* Wi-Fi 6 AX211 */
218 #define	PCI_PRODUCT_INTEL_WL_22500_17	0x51f1		/* Wi-Fi 6 AX211 */
219 
220 static const struct iwx_devices {
221 	uint16_t		device;
222 	char			*name;
223 } iwx_devices[] = {
224 	{ PCI_PRODUCT_INTEL_WL_22500_1,		"Wi-Fi 6 AX200"	},
225 	{ PCI_PRODUCT_INTEL_WL_22500_2,		"Wi-Fi 6 AX201"	},
226 	{ PCI_PRODUCT_INTEL_WL_22500_3,		"Wi-Fi 6 AX201"	},
227 	{ PCI_PRODUCT_INTEL_WL_22500_4,		"Wi-Fi 6 AX201"	},
228 	{ PCI_PRODUCT_INTEL_WL_22500_5,		"Wi-Fi 6 AX201"	},
229 	{ PCI_PRODUCT_INTEL_WL_22500_6,		"Wi-Fi 6 AX201"	},
230 	{ PCI_PRODUCT_INTEL_WL_22500_7,		"Wi-Fi 6 AX201"	},
231 	{ PCI_PRODUCT_INTEL_WL_22500_8,		"Wi-Fi 6 AX201"	},
232 	{ PCI_PRODUCT_INTEL_WL_22500_9,		"Wi-Fi 6 AX210"	},
233 	{ PCI_PRODUCT_INTEL_WL_22500_10,	"Wi-Fi 6 AX211"	},
234 	{ PCI_PRODUCT_INTEL_WL_22500_11,	"Wi-Fi 6 AX211"	},
235 	{ PCI_PRODUCT_INTEL_WL_22500_12,	"Wi-Fi 6 AX211"	},
236 	{ PCI_PRODUCT_INTEL_WL_22500_13,	"Wi-Fi 6 AX211"	},
237 	{ PCI_PRODUCT_INTEL_WL_22500_14,	"Wi-Fi 6 AX210"	},
238 	{ PCI_PRODUCT_INTEL_WL_22500_15,	"Wi-Fi 6 AX211"	},
239 	{ PCI_PRODUCT_INTEL_WL_22500_16,	"Wi-Fi 6 AX211"	},
240 	{ PCI_PRODUCT_INTEL_WL_22500_17,	"Wi-Fi 6 AX211"	},
241 };
242 
243 static const uint8_t iwx_nvm_channels_8000[] = {
244 	/* 2.4 GHz */
245 	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
246 	/* 5 GHz */
247 	36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
248 	96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
249 	149, 153, 157, 161, 165, 169, 173, 177, 181
250 };
251 
252 static const uint8_t iwx_nvm_channels_uhb[] = {
253 	/* 2.4 GHz */
254 	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
255 	/* 5 GHz */
256 	36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
257 	96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
258 	149, 153, 157, 161, 165, 169, 173, 177, 181,
259 	/* 6-7 GHz */
260 	1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69,
261 	73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129,
262 	133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185,
263 	189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233
264 };
265 
266 #define IWX_NUM_2GHZ_CHANNELS	14
267 #define IWX_NUM_5GHZ_CHANNELS	37
268 
269 const struct iwx_rate {
270 	uint16_t rate;
271 	uint8_t plcp;
272 	uint8_t ht_plcp;
273 } iwx_rates[] = {
274 		/* Legacy */		/* HT */
275 	{   2,	IWX_RATE_1M_PLCP,	IWX_RATE_HT_SISO_MCS_INV_PLCP  },
276 	{   4,	IWX_RATE_2M_PLCP,	IWX_RATE_HT_SISO_MCS_INV_PLCP },
277 	{  11,	IWX_RATE_5M_PLCP,	IWX_RATE_HT_SISO_MCS_INV_PLCP  },
278 	{  22,	IWX_RATE_11M_PLCP,	IWX_RATE_HT_SISO_MCS_INV_PLCP },
279 	{  12,	IWX_RATE_6M_PLCP,	IWX_RATE_HT_SISO_MCS_0_PLCP },
280 	{  18,	IWX_RATE_9M_PLCP,	IWX_RATE_HT_SISO_MCS_INV_PLCP  },
281 	{  24,	IWX_RATE_12M_PLCP,	IWX_RATE_HT_SISO_MCS_1_PLCP },
282 	{  26,	IWX_RATE_INVM_PLCP,	IWX_RATE_HT_MIMO2_MCS_8_PLCP },
283 	{  36,	IWX_RATE_18M_PLCP,	IWX_RATE_HT_SISO_MCS_2_PLCP },
284 	{  48,	IWX_RATE_24M_PLCP,	IWX_RATE_HT_SISO_MCS_3_PLCP },
285 	{  52,	IWX_RATE_INVM_PLCP,	IWX_RATE_HT_MIMO2_MCS_9_PLCP },
286 	{  72,	IWX_RATE_36M_PLCP,	IWX_RATE_HT_SISO_MCS_4_PLCP },
287 	{  78,	IWX_RATE_INVM_PLCP,	IWX_RATE_HT_MIMO2_MCS_10_PLCP },
288 	{  96,	IWX_RATE_48M_PLCP,	IWX_RATE_HT_SISO_MCS_5_PLCP },
289 	{ 104,	IWX_RATE_INVM_PLCP,	IWX_RATE_HT_MIMO2_MCS_11_PLCP },
290 	{ 108,	IWX_RATE_54M_PLCP,	IWX_RATE_HT_SISO_MCS_6_PLCP },
291 	{ 128,	IWX_RATE_INVM_PLCP,	IWX_RATE_HT_SISO_MCS_7_PLCP },
292 	{ 156,	IWX_RATE_INVM_PLCP,	IWX_RATE_HT_MIMO2_MCS_12_PLCP },
293 	{ 208,	IWX_RATE_INVM_PLCP,	IWX_RATE_HT_MIMO2_MCS_13_PLCP },
294 	{ 234,	IWX_RATE_INVM_PLCP,	IWX_RATE_HT_MIMO2_MCS_14_PLCP },
295 	{ 260,	IWX_RATE_INVM_PLCP,	IWX_RATE_HT_MIMO2_MCS_15_PLCP },
296 };
297 #define IWX_RIDX_CCK	0
298 #define IWX_RIDX_OFDM	4
299 #define IWX_RIDX_MAX	(nitems(iwx_rates)-1)
300 #define IWX_RIDX_IS_CCK(_i_) ((_i_) < IWX_RIDX_OFDM)
301 #define IWX_RIDX_IS_OFDM(_i_) ((_i_) >= IWX_RIDX_OFDM)
302 #define IWX_RVAL_IS_OFDM(_i_) ((_i_) >= 12 && (_i_) != 22)
303 
304 /* Convert an MCS index into an iwx_rates[] index. */
305 const int iwx_mcs2ridx[] = {
306 	IWX_RATE_MCS_0_INDEX,
307 	IWX_RATE_MCS_1_INDEX,
308 	IWX_RATE_MCS_2_INDEX,
309 	IWX_RATE_MCS_3_INDEX,
310 	IWX_RATE_MCS_4_INDEX,
311 	IWX_RATE_MCS_5_INDEX,
312 	IWX_RATE_MCS_6_INDEX,
313 	IWX_RATE_MCS_7_INDEX,
314 	IWX_RATE_MCS_8_INDEX,
315 	IWX_RATE_MCS_9_INDEX,
316 	IWX_RATE_MCS_10_INDEX,
317 	IWX_RATE_MCS_11_INDEX,
318 	IWX_RATE_MCS_12_INDEX,
319 	IWX_RATE_MCS_13_INDEX,
320 	IWX_RATE_MCS_14_INDEX,
321 	IWX_RATE_MCS_15_INDEX,
322 };
323 
324 static uint8_t	iwx_lookup_cmd_ver(struct iwx_softc *, uint8_t, uint8_t);
325 static uint8_t	iwx_lookup_notif_ver(struct iwx_softc *, uint8_t, uint8_t);
326 static int	iwx_store_cscheme(struct iwx_softc *, const uint8_t *, size_t);
327 #if 0
328 static int	iwx_alloc_fw_monitor_block(struct iwx_softc *, uint8_t, uint8_t);
329 static int	iwx_alloc_fw_monitor(struct iwx_softc *, uint8_t);
330 #endif
331 static int	iwx_apply_debug_destination(struct iwx_softc *);
332 static void	iwx_set_ltr(struct iwx_softc *);
333 static int	iwx_ctxt_info_init(struct iwx_softc *, const struct iwx_fw_sects *);
334 static int	iwx_ctxt_info_gen3_init(struct iwx_softc *,
335 	    const struct iwx_fw_sects *);
336 static void	iwx_ctxt_info_free_fw_img(struct iwx_softc *);
337 static void	iwx_ctxt_info_free_paging(struct iwx_softc *);
338 static int	iwx_init_fw_sec(struct iwx_softc *, const struct iwx_fw_sects *,
339 	    struct iwx_context_info_dram *);
340 static void	iwx_fw_version_str(char *, size_t, uint32_t, uint32_t, uint32_t);
341 static int	iwx_firmware_store_section(struct iwx_softc *, enum iwx_ucode_type,
342 	    const uint8_t *, size_t);
343 static int	iwx_set_default_calib(struct iwx_softc *, const void *);
344 static void	iwx_fw_info_free(struct iwx_fw_info *);
345 static int	iwx_read_firmware(struct iwx_softc *);
346 static uint32_t iwx_prph_addr_mask(struct iwx_softc *);
347 static uint32_t iwx_read_prph_unlocked(struct iwx_softc *, uint32_t);
348 static uint32_t iwx_read_prph(struct iwx_softc *, uint32_t);
349 static void	iwx_write_prph_unlocked(struct iwx_softc *, uint32_t, uint32_t);
350 static void	iwx_write_prph(struct iwx_softc *, uint32_t, uint32_t);
351 static uint32_t iwx_read_umac_prph(struct iwx_softc *, uint32_t);
352 static void	iwx_write_umac_prph(struct iwx_softc *, uint32_t, uint32_t);
353 static int	iwx_read_mem(struct iwx_softc *, uint32_t, void *, int);
354 static int	iwx_poll_bit(struct iwx_softc *, int, uint32_t, uint32_t, int);
355 static int	iwx_nic_lock(struct iwx_softc *);
356 static void	iwx_nic_assert_locked(struct iwx_softc *);
357 static void	iwx_nic_unlock(struct iwx_softc *);
358 static int	iwx_set_bits_mask_prph(struct iwx_softc *, uint32_t, uint32_t,
359 	    uint32_t);
360 static int	iwx_set_bits_prph(struct iwx_softc *, uint32_t, uint32_t);
361 static int	iwx_clear_bits_prph(struct iwx_softc *, uint32_t, uint32_t);
362 static void iwx_dma_map_addr(void *, bus_dma_segment_t *, int, int);
363 static int iwx_dma_contig_alloc(bus_dma_tag_t, struct iwx_dma_info *,
364     bus_size_t, bus_size_t);
365 static void iwx_dma_contig_free(struct iwx_dma_info *);
366 static int iwx_alloc_rx_ring(struct iwx_softc *, struct iwx_rx_ring *);
367 static void	iwx_disable_rx_dma(struct iwx_softc *);
368 static void	iwx_reset_rx_ring(struct iwx_softc *, struct iwx_rx_ring *);
369 static void	iwx_free_rx_ring(struct iwx_softc *, struct iwx_rx_ring *);
370 static int iwx_alloc_tx_ring(struct iwx_softc *, struct iwx_tx_ring *, int);
371 static void	iwx_reset_tx_ring(struct iwx_softc *, struct iwx_tx_ring *);
372 static void	iwx_free_tx_ring(struct iwx_softc *, struct iwx_tx_ring *);
373 static void	iwx_enable_rfkill_int(struct iwx_softc *);
374 static int	iwx_check_rfkill(struct iwx_softc *);
375 static void	iwx_enable_interrupts(struct iwx_softc *);
376 static void	iwx_enable_fwload_interrupt(struct iwx_softc *);
377 #if 0
378 static void	iwx_restore_interrupts(struct iwx_softc *);
379 #endif
380 static void	iwx_disable_interrupts(struct iwx_softc *);
381 static void	iwx_ict_reset(struct iwx_softc *);
382 static int	iwx_set_hw_ready(struct iwx_softc *);
383 static int	iwx_prepare_card_hw(struct iwx_softc *);
384 static int	iwx_force_power_gating(struct iwx_softc *);
385 static void	iwx_apm_config(struct iwx_softc *);
386 static int	iwx_apm_init(struct iwx_softc *);
387 static void	iwx_apm_stop(struct iwx_softc *);
388 static int	iwx_allow_mcast(struct iwx_softc *);
389 static void	iwx_init_msix_hw(struct iwx_softc *);
390 static void	iwx_conf_msix_hw(struct iwx_softc *, int);
391 static int	iwx_clear_persistence_bit(struct iwx_softc *);
392 static int	iwx_start_hw(struct iwx_softc *);
393 static void	iwx_stop_device(struct iwx_softc *);
394 static void	iwx_nic_config(struct iwx_softc *);
395 static int	iwx_nic_rx_init(struct iwx_softc *);
396 static int	iwx_nic_init(struct iwx_softc *);
397 static int	iwx_enable_txq(struct iwx_softc *, int, int, int, int);
398 static int	iwx_disable_txq(struct iwx_softc *sc, int, int, uint8_t);
399 static void	iwx_post_alive(struct iwx_softc *);
400 static int	iwx_schedule_session_protection(struct iwx_softc *,
401     struct iwx_node *, uint32_t);
402 static void	iwx_unprotect_session(struct iwx_softc *, struct iwx_node *);
403 static void	iwx_init_channel_map(struct ieee80211com *, int, int *,
404     struct ieee80211_channel[]);
405 static int	iwx_mimo_enabled(struct iwx_softc *);
406 static void	iwx_init_reorder_buffer(struct iwx_reorder_buffer *, uint16_t,
407 	    uint16_t);
408 static void	iwx_clear_reorder_buffer(struct iwx_softc *, struct iwx_rxba_data *);
409 static void	iwx_sta_rx_agg(struct iwx_softc *, struct ieee80211_node *, uint8_t,
410 	    uint16_t, uint16_t, int, int);
411 static void	iwx_sta_tx_agg_start(struct iwx_softc *,
412     struct ieee80211_node *, uint8_t);
413 static void	iwx_ba_rx_task(void *, int);
414 static void	iwx_ba_tx_task(void *, int);
415 static void	iwx_set_mac_addr_from_csr(struct iwx_softc *, struct iwx_nvm_data *);
416 static int	iwx_is_valid_mac_addr(const uint8_t *);
417 static void	iwx_flip_hw_address(uint32_t, uint32_t, uint8_t *);
418 static int	iwx_nvm_get(struct iwx_softc *);
419 static int	iwx_load_firmware(struct iwx_softc *);
420 static int	iwx_start_fw(struct iwx_softc *);
421 static int	iwx_pnvm_handle_section(struct iwx_softc *, const uint8_t *, size_t);
422 static int	iwx_pnvm_parse(struct iwx_softc *, const uint8_t *, size_t);
423 static void	iwx_ctxt_info_gen3_set_pnvm(struct iwx_softc *);
424 static int	iwx_load_pnvm(struct iwx_softc *);
425 static int	iwx_send_tx_ant_cfg(struct iwx_softc *, uint8_t);
426 static int	iwx_send_phy_cfg_cmd(struct iwx_softc *);
427 static int	iwx_load_ucode_wait_alive(struct iwx_softc *);
428 static int	iwx_send_dqa_cmd(struct iwx_softc *);
429 static int	iwx_run_init_mvm_ucode(struct iwx_softc *, int);
430 static int	iwx_config_ltr(struct iwx_softc *);
431 static void 	iwx_update_rx_desc(struct iwx_softc *, struct iwx_rx_ring *, int, bus_dma_segment_t *);
432 static int 	iwx_rx_addbuf(struct iwx_softc *, int, int);
433 static int	iwx_rxmq_get_signal_strength(struct iwx_softc *, struct iwx_rx_mpdu_desc *);
434 static void	iwx_rx_rx_phy_cmd(struct iwx_softc *, struct iwx_rx_packet *,
435     struct iwx_rx_data *);
436 static int	iwx_get_noise(struct iwx_softc *, const struct iwx_statistics_rx_non_phy *);
437 static int	iwx_rx_hwdecrypt(struct iwx_softc *, struct mbuf *, uint32_t);
438 #if 0
439 int	iwx_ccmp_decap(struct iwx_softc *, struct mbuf *,
440 	    struct ieee80211_node *, struct ieee80211_rxinfo *);
441 #endif
442 static void	iwx_rx_frame(struct iwx_softc *, struct mbuf *, int, uint32_t,
443     int, int, uint32_t, uint8_t);
444 static void	iwx_clear_tx_desc(struct iwx_softc *, struct iwx_tx_ring *, int);
445 static void	iwx_txd_done(struct iwx_softc *, struct iwx_tx_ring *,
446     struct iwx_tx_data *);
447 static void	iwx_txq_advance(struct iwx_softc *, struct iwx_tx_ring *, uint16_t);
448 static void	iwx_rx_tx_cmd(struct iwx_softc *, struct iwx_rx_packet *,
449 	    struct iwx_rx_data *);
450 static void	iwx_clear_oactive(struct iwx_softc *, struct iwx_tx_ring *);
451 static void	iwx_rx_bmiss(struct iwx_softc *, struct iwx_rx_packet *,
452     struct iwx_rx_data *);
453 static int	iwx_binding_cmd(struct iwx_softc *, struct iwx_node *, uint32_t);
454 static uint8_t	iwx_get_vht_ctrl_pos(struct ieee80211com *, struct ieee80211_channel *);
455 static int	iwx_phy_ctxt_cmd_uhb_v3_v4(struct iwx_softc *,
456     struct iwx_phy_ctxt *, uint8_t, uint8_t, uint32_t, uint8_t, uint8_t, int);
457 #if 0
458 static int	iwx_phy_ctxt_cmd_v3_v4(struct iwx_softc *, struct iwx_phy_ctxt *,
459     uint8_t, uint8_t, uint32_t, uint8_t, uint8_t, int);
460 #endif
461 static int	iwx_phy_ctxt_cmd(struct iwx_softc *, struct iwx_phy_ctxt *,
462     uint8_t, uint8_t, uint32_t, uint32_t, uint8_t, uint8_t);
463 static int	iwx_send_cmd(struct iwx_softc *, struct iwx_host_cmd *);
464 static int	iwx_send_cmd_pdu(struct iwx_softc *, uint32_t, uint32_t, uint16_t,
465 	    const void *);
466 static int	iwx_send_cmd_status(struct iwx_softc *, struct iwx_host_cmd *,
467 	    uint32_t *);
468 static int	iwx_send_cmd_pdu_status(struct iwx_softc *, uint32_t, uint16_t,
469 	    const void *, uint32_t *);
470 static void	iwx_free_resp(struct iwx_softc *, struct iwx_host_cmd *);
471 static void	iwx_cmd_done(struct iwx_softc *, int, int, int);
472 static uint32_t iwx_fw_rateidx_ofdm(uint8_t);
473 static uint32_t iwx_fw_rateidx_cck(uint8_t);
474 static const struct iwx_rate *iwx_tx_fill_cmd(struct iwx_softc *,
475     struct iwx_node *, struct ieee80211_frame *, uint16_t *, uint32_t *,
476     struct mbuf *);
477 static void	iwx_tx_update_byte_tbl(struct iwx_softc *, struct iwx_tx_ring *, int,
478 	    uint16_t, uint16_t);
479 static int	iwx_tx(struct iwx_softc *, struct mbuf *,
480     struct ieee80211_node *);
481 static int	iwx_flush_sta_tids(struct iwx_softc *, int, uint16_t);
482 static int	iwx_drain_sta(struct iwx_softc *sc, struct iwx_node *, int);
483 static int	iwx_flush_sta(struct iwx_softc *, struct iwx_node *);
484 static int	iwx_beacon_filter_send_cmd(struct iwx_softc *,
485 	    struct iwx_beacon_filter_cmd *);
486 static int	iwx_update_beacon_abort(struct iwx_softc *, struct iwx_node *,
487     int);
488 static void	iwx_power_build_cmd(struct iwx_softc *, struct iwx_node *,
489 	    struct iwx_mac_power_cmd *);
490 static int	iwx_power_mac_update_mode(struct iwx_softc *, struct iwx_node *);
491 static int	iwx_power_update_device(struct iwx_softc *);
492 #if 0
493 static int	iwx_enable_beacon_filter(struct iwx_softc *, struct iwx_node *);
494 #endif
495 static int	iwx_disable_beacon_filter(struct iwx_softc *);
496 static int	iwx_add_sta_cmd(struct iwx_softc *, struct iwx_node *, int);
497 static int	iwx_rm_sta_cmd(struct iwx_softc *, struct iwx_node *);
498 static int	iwx_rm_sta(struct iwx_softc *, struct iwx_node *);
499 static int	iwx_fill_probe_req(struct iwx_softc *,
500     struct iwx_scan_probe_req *);
501 static int	iwx_config_umac_scan_reduced(struct iwx_softc *);
502 static uint16_t iwx_scan_umac_flags_v2(struct iwx_softc *, int);
503 static void	iwx_scan_umac_dwell_v10(struct iwx_softc *,
504 	    struct iwx_scan_general_params_v10 *, int);
505 static void	iwx_scan_umac_fill_general_p_v10(struct iwx_softc *,
506 	    struct iwx_scan_general_params_v10 *, uint16_t, int);
507 static void	iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *,
508 	    struct iwx_scan_channel_params_v6 *, uint32_t, int);
509 static int	iwx_umac_scan_v14(struct iwx_softc *, int);
510 static void	iwx_mcc_update(struct iwx_softc *, struct iwx_mcc_chub_notif *);
511 static uint8_t	iwx_ridx2rate(struct ieee80211_rateset *, int);
512 static int	iwx_rval2ridx(int);
513 static void	iwx_ack_rates(struct iwx_softc *, struct iwx_node *, int *,
514     int *);
515 static void	iwx_mac_ctxt_cmd_common(struct iwx_softc *, struct iwx_node *,
516 	    struct iwx_mac_ctx_cmd *, uint32_t);
517 static void	iwx_mac_ctxt_cmd_fill_sta(struct iwx_softc *, struct iwx_node *,
518 	    struct iwx_mac_data_sta *, int);
519 static int	iwx_mac_ctxt_cmd(struct iwx_softc *, struct iwx_node *,
520     uint32_t, int);
521 static int	iwx_clear_statistics(struct iwx_softc *);
522 static int	iwx_scan(struct iwx_softc *);
523 static int	iwx_bgscan(struct ieee80211com *);
524 static int	iwx_enable_mgmt_queue(struct iwx_softc *);
525 static int	iwx_disable_mgmt_queue(struct iwx_softc *);
526 static int	iwx_rs_rval2idx(uint8_t);
527 static uint16_t iwx_rs_ht_rates(struct iwx_softc *, struct ieee80211_node *,
528     int);
529 static uint16_t iwx_rs_vht_rates(struct iwx_softc *, struct ieee80211_node *, int);
530 static int	iwx_rs_init_v3(struct iwx_softc *, struct iwx_node *);
531 static int	iwx_rs_init_v4(struct iwx_softc *, struct iwx_node *);
532 static int	iwx_rs_init(struct iwx_softc *, struct iwx_node *);
533 static int	iwx_phy_send_rlc(struct iwx_softc *, struct iwx_phy_ctxt *,
534 	    uint8_t, uint8_t);
535 static int	iwx_phy_ctxt_update(struct iwx_softc *, struct iwx_phy_ctxt *,
536 	    struct ieee80211_channel *, uint8_t, uint8_t, uint32_t, uint8_t,
537 	    uint8_t);
538 static int	iwx_auth(struct ieee80211vap *, struct iwx_softc *);
539 static int	iwx_deauth(struct iwx_softc *);
540 static int	iwx_run(struct ieee80211vap *, struct iwx_softc *);
541 static int	iwx_run_stop(struct iwx_softc *);
542 static struct ieee80211_node * iwx_node_alloc(struct ieee80211vap *,
543     const uint8_t[IEEE80211_ADDR_LEN]);
544 #if 0
545 int	iwx_set_key(struct ieee80211com *, struct ieee80211_node *,
546 	    struct ieee80211_key *);
547 void	iwx_setkey_task(void *);
548 void	iwx_delete_key(struct ieee80211com *,
549 	    struct ieee80211_node *, struct ieee80211_key *);
550 #endif
551 static int	iwx_newstate(struct ieee80211vap *, enum ieee80211_state, int);
552 static void	iwx_endscan(struct iwx_softc *);
553 static void	iwx_fill_sf_command(struct iwx_softc *, struct iwx_sf_cfg_cmd *,
554 	    struct ieee80211_node *);
555 static int	iwx_sf_config(struct iwx_softc *, int);
556 static int	iwx_send_bt_init_conf(struct iwx_softc *);
557 static int	iwx_send_soc_conf(struct iwx_softc *);
558 static int	iwx_send_update_mcc_cmd(struct iwx_softc *, const char *);
559 static int	iwx_send_temp_report_ths_cmd(struct iwx_softc *);
560 static int	iwx_init_hw(struct iwx_softc *);
561 static int	iwx_init(struct iwx_softc *);
562 static void	iwx_stop(struct iwx_softc *);
563 static void	iwx_watchdog(void *);
564 static const char *iwx_desc_lookup(uint32_t);
565 static void	iwx_nic_error(struct iwx_softc *);
566 static void	iwx_dump_driver_status(struct iwx_softc *);
567 static void	iwx_nic_umac_error(struct iwx_softc *);
568 static void	iwx_rx_mpdu_mq(struct iwx_softc *, struct mbuf *, void *, size_t);
569 static int	iwx_rx_pkt_valid(struct iwx_rx_packet *);
570 static void	iwx_rx_pkt(struct iwx_softc *, struct iwx_rx_data *,
571 	    struct mbuf *);
572 static void	iwx_notif_intr(struct iwx_softc *);
573 #if 0
574 /* XXX-THJ - I don't have hardware for this */
575 static int	iwx_intr(void *);
576 #endif
577 static void	iwx_intr_msix(void *);
578 static int	iwx_preinit(struct iwx_softc *);
579 static void	iwx_attach_hook(void *);
580 static const struct iwx_device_cfg *iwx_find_device_cfg(struct iwx_softc *);
581 static int	iwx_probe(device_t);
582 static int	iwx_attach(device_t);
583 static int	iwx_detach(device_t);
584 
585 /* FreeBSD specific glue */
586 u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN] =
587     { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
588 
589 u_int8_t etheranyaddr[ETHER_ADDR_LEN] =
590     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
591 
592 #if IWX_DEBUG
593 #define DPRINTF(x)	do { if (sc->sc_debug == IWX_DEBUG_ANY) { printf x; } } while (0)
594 #else
595 #define DPRINTF(x)	do { ; } while (0)
596 #endif
597 
598 /* FreeBSD specific functions */
599 static struct	ieee80211vap * iwx_vap_create(struct ieee80211com *,
600     const char[IFNAMSIZ], int, enum ieee80211_opmode, int,
601     const uint8_t[IEEE80211_ADDR_LEN], const uint8_t[IEEE80211_ADDR_LEN]);
602 static void	iwx_vap_delete(struct ieee80211vap *);
603 static void	iwx_parent(struct ieee80211com *);
604 static void	iwx_scan_start(struct ieee80211com *);
605 static void	iwx_scan_end(struct ieee80211com *);
606 static void	iwx_update_mcast(struct ieee80211com *ic);
607 static void	iwx_scan_curchan(struct ieee80211_scan_state *, unsigned long);
608 static void	iwx_scan_mindwell(struct ieee80211_scan_state *);
609 static void	iwx_set_channel(struct ieee80211com *);
610 static void	iwx_endscan_cb(void *, int );
611 static int	iwx_wme_update(struct ieee80211com *);
612 static int	iwx_raw_xmit(struct ieee80211_node *, struct mbuf *,
613     const struct ieee80211_bpf_params *);
614 static int	iwx_transmit(struct ieee80211com *, struct mbuf *);
615 static void	iwx_start(struct iwx_softc *);
616 static int	iwx_ampdu_rx_start(struct ieee80211_node *,
617     struct ieee80211_rx_ampdu *, int, int, int);
618 static void	iwx_ampdu_rx_stop(struct ieee80211_node *,
619     struct ieee80211_rx_ampdu *);
620 static int	iwx_addba_request(struct ieee80211_node *,
621     struct ieee80211_tx_ampdu *, int, int, int);
622 static int	iwx_addba_response(struct ieee80211_node *,
623     struct ieee80211_tx_ampdu *, int, int, int);
624 static void	iwx_key_update_begin(struct ieee80211vap *);
625 static void	iwx_key_update_end(struct ieee80211vap *);
626 static int	iwx_key_alloc(struct ieee80211vap *, struct ieee80211_key *,
627     ieee80211_keyix *,ieee80211_keyix *);
628 static int	iwx_key_set(struct ieee80211vap *, const struct ieee80211_key *);
629 static int	iwx_key_delete(struct ieee80211vap *,
630     const struct ieee80211_key *);
631 static int	iwx_suspend(device_t);
632 static int	iwx_resume(device_t);
633 static void	iwx_radiotap_attach(struct iwx_softc *);
634 
635 /* OpenBSD compat defines */
636 #define IEEE80211_HTOP0_SCO_SCN 0
637 #define IEEE80211_VHTOP0_CHAN_WIDTH_HT 0
638 #define IEEE80211_VHTOP0_CHAN_WIDTH_80 1
639 
640 #define IEEE80211_HT_RATESET_SISO 0
641 #define IEEE80211_HT_RATESET_MIMO2 2
642 
643 const struct ieee80211_rateset ieee80211_std_rateset_11a =
644 	{ 8, { 12, 18, 24, 36, 48, 72, 96, 108 } };
645 
646 const struct ieee80211_rateset ieee80211_std_rateset_11b =
647 	{ 4, { 2, 4, 11, 22 } };
648 
649 const struct ieee80211_rateset ieee80211_std_rateset_11g =
650 	{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
651 
652 inline int
653 ieee80211_has_addr4(const struct ieee80211_frame *wh)
654 {
655 	return (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) ==
656 	    IEEE80211_FC1_DIR_DSTODS;
657 }
658 
659 static uint8_t
660 iwx_lookup_cmd_ver(struct iwx_softc *sc, uint8_t grp, uint8_t cmd)
661 {
662 	const struct iwx_fw_cmd_version *entry;
663 	int i;
664 
665 	for (i = 0; i < sc->n_cmd_versions; i++) {
666 		entry = &sc->cmd_versions[i];
667 		if (entry->group == grp && entry->cmd == cmd)
668 			return entry->cmd_ver;
669 	}
670 
671 	return IWX_FW_CMD_VER_UNKNOWN;
672 }
673 
674 uint8_t
675 iwx_lookup_notif_ver(struct iwx_softc *sc, uint8_t grp, uint8_t cmd)
676 {
677 	const struct iwx_fw_cmd_version *entry;
678 	int i;
679 
680 	for (i = 0; i < sc->n_cmd_versions; i++) {
681 		entry = &sc->cmd_versions[i];
682 		if (entry->group == grp && entry->cmd == cmd)
683 			return entry->notif_ver;
684 	}
685 
686 	return IWX_FW_CMD_VER_UNKNOWN;
687 }
688 
689 static int
690 iwx_store_cscheme(struct iwx_softc *sc, const uint8_t *data, size_t dlen)
691 {
692 	const struct iwx_fw_cscheme_list *l = (const void *)data;
693 
694 	if (dlen < sizeof(*l) ||
695 	    dlen < sizeof(l->size) + l->size * sizeof(*l->cs))
696 		return EINVAL;
697 
698 	/* we don't actually store anything for now, always use s/w crypto */
699 
700 	return 0;
701 }
702 
703 static int
704 iwx_ctxt_info_alloc_dma(struct iwx_softc *sc,
705     const struct iwx_fw_onesect *sec, struct iwx_dma_info *dram)
706 {
707 	int err = iwx_dma_contig_alloc(sc->sc_dmat, dram, sec->fws_len, 1);
708 	if (err) {
709 		printf("%s: could not allocate context info DMA memory\n",
710 		    DEVNAME(sc));
711 		return err;
712 	}
713 
714 	memcpy(dram->vaddr, sec->fws_data, sec->fws_len);
715 
716 	return 0;
717 }
718 
719 static void
720 iwx_ctxt_info_free_paging(struct iwx_softc *sc)
721 {
722 	struct iwx_self_init_dram *dram = &sc->init_dram;
723 	int i;
724 
725 	if (!dram->paging)
726 		return;
727 
728 	/* free paging*/
729 	for (i = 0; i < dram->paging_cnt; i++)
730 		iwx_dma_contig_free(&dram->paging[i]);
731 
732 	free(dram->paging, M_DEVBUF);
733 	dram->paging_cnt = 0;
734 	dram->paging = NULL;
735 }
736 
737 static int
738 iwx_get_num_sections(const struct iwx_fw_sects *fws, int start)
739 {
740 	int i = 0;
741 
742 	while (start < fws->fw_count &&
743 	       fws->fw_sect[start].fws_devoff != IWX_CPU1_CPU2_SEPARATOR_SECTION &&
744 	       fws->fw_sect[start].fws_devoff != IWX_PAGING_SEPARATOR_SECTION) {
745 		start++;
746 		i++;
747 	}
748 
749 	return i;
750 }
751 
752 static int
753 iwx_init_fw_sec(struct iwx_softc *sc, const struct iwx_fw_sects *fws,
754     struct iwx_context_info_dram *ctxt_dram)
755 {
756 	struct iwx_self_init_dram *dram = &sc->init_dram;
757 	int i, ret, fw_cnt = 0;
758 
759 	KASSERT(dram->paging == NULL, ("iwx_init_fw_sec"));
760 
761 	dram->lmac_cnt = iwx_get_num_sections(fws, 0);
762 	/* add 1 due to separator */
763 	dram->umac_cnt = iwx_get_num_sections(fws, dram->lmac_cnt + 1);
764 	/* add 2 due to separators */
765 	dram->paging_cnt = iwx_get_num_sections(fws,
766 	    dram->lmac_cnt + dram->umac_cnt + 2);
767 
768 	IWX_UNLOCK(sc);
769 	dram->fw = mallocarray(dram->umac_cnt + dram->lmac_cnt,
770 	    sizeof(*dram->fw), M_DEVBUF,  M_ZERO | M_NOWAIT);
771 	if (!dram->fw) {
772 		printf("%s: could not allocate memory for firmware sections\n",
773 		    DEVNAME(sc));
774 		IWX_LOCK(sc);
775 		return ENOMEM;
776 	}
777 
778 	dram->paging = mallocarray(dram->paging_cnt, sizeof(*dram->paging),
779 	    M_DEVBUF, M_ZERO | M_WAITOK);
780 	IWX_LOCK(sc);
781 	if (!dram->paging) {
782 		printf("%s: could not allocate memory for firmware paging\n",
783 		    DEVNAME(sc));
784 		return ENOMEM;
785 	}
786 
787 	/* initialize lmac sections */
788 	for (i = 0; i < dram->lmac_cnt; i++) {
789 		ret = iwx_ctxt_info_alloc_dma(sc, &fws->fw_sect[i],
790 						   &dram->fw[fw_cnt]);
791 		if (ret)
792 			return ret;
793 		ctxt_dram->lmac_img[i] =
794 			htole64(dram->fw[fw_cnt].paddr);
795 		IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV,
796 		    "%s: firmware LMAC section %d at 0x%llx size %lld\n",
797 		    __func__, i,
798 		    (unsigned long long)dram->fw[fw_cnt].paddr,
799 		    (unsigned long long)dram->fw[fw_cnt].size);
800 		fw_cnt++;
801 	}
802 
803 	/* initialize umac sections */
804 	for (i = 0; i < dram->umac_cnt; i++) {
805 		/* access FW with +1 to make up for lmac separator */
806 		ret = iwx_ctxt_info_alloc_dma(sc,
807 		    &fws->fw_sect[fw_cnt + 1], &dram->fw[fw_cnt]);
808 		if (ret)
809 			return ret;
810 		ctxt_dram->umac_img[i] =
811 			htole64(dram->fw[fw_cnt].paddr);
812 		IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV,
813 		    "%s: firmware UMAC section %d at 0x%llx size %lld\n",
814 		    __func__, i,
815 		    (unsigned long long)dram->fw[fw_cnt].paddr,
816 		    (unsigned long long)dram->fw[fw_cnt].size);
817 		fw_cnt++;
818 	}
819 
820 	/*
821 	 * Initialize paging.
822 	 * Paging memory isn't stored in dram->fw as the umac and lmac - it is
823 	 * stored separately.
824 	 * This is since the timing of its release is different -
825 	 * while fw memory can be released on alive, the paging memory can be
826 	 * freed only when the device goes down.
827 	 * Given that, the logic here in accessing the fw image is a bit
828 	 * different - fw_cnt isn't changing so loop counter is added to it.
829 	 */
830 	for (i = 0; i < dram->paging_cnt; i++) {
831 		/* access FW with +2 to make up for lmac & umac separators */
832 		int fw_idx = fw_cnt + i + 2;
833 
834 		ret = iwx_ctxt_info_alloc_dma(sc,
835 		    &fws->fw_sect[fw_idx], &dram->paging[i]);
836 		if (ret)
837 			return ret;
838 
839 		ctxt_dram->virtual_img[i] = htole64(dram->paging[i].paddr);
840 		IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV,
841 		    "%s: firmware paging section %d at 0x%llx size %lld\n",
842 		    __func__, i,
843 		    (unsigned long long)dram->paging[i].paddr,
844 		    (unsigned long long)dram->paging[i].size);
845 	}
846 
847 	return 0;
848 }
849 
850 static void
851 iwx_fw_version_str(char *buf, size_t bufsize,
852     uint32_t major, uint32_t minor, uint32_t api)
853 {
854 	/*
855 	 * Starting with major version 35 the Linux driver prints the minor
856 	 * version in hexadecimal.
857 	 */
858 	if (major >= 35)
859 		snprintf(buf, bufsize, "%u.%08x.%u", major, minor, api);
860 	else
861 		snprintf(buf, bufsize, "%u.%u.%u", major, minor, api);
862 }
863 #if 0
864 static int
865 iwx_alloc_fw_monitor_block(struct iwx_softc *sc, uint8_t max_power,
866     uint8_t min_power)
867 {
868 	struct iwx_dma_info *fw_mon = &sc->fw_mon;
869 	uint32_t size = 0;
870 	uint8_t power;
871 	int err;
872 
873 	if (fw_mon->size)
874 		return 0;
875 
876 	for (power = max_power; power >= min_power; power--) {
877 		size = (1 << power);
878 
879 		err = iwx_dma_contig_alloc(sc->sc_dmat, fw_mon, size, 0);
880 		if (err)
881 			continue;
882 
883 		IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV,
884 		    "%s: allocated 0x%08x bytes for firmware monitor.\n",
885 		    DEVNAME(sc), size);
886 		break;
887 	}
888 
889 	if (err) {
890 		fw_mon->size = 0;
891 		return err;
892 	}
893 
894 	if (power != max_power)
895 		IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV,
896 		    "%s: Sorry - debug buffer is only %luK while you requested %luK\n",
897 		    DEVNAME(sc), (unsigned long)(1 << (power - 10)),
898 		    (unsigned long)(1 << (max_power - 10)));
899 
900 	return 0;
901 }
902 
903 static int
904 iwx_alloc_fw_monitor(struct iwx_softc *sc, uint8_t max_power)
905 {
906 	if (!max_power) {
907 		/* default max_power is maximum */
908 		max_power = 26;
909 	} else {
910 		max_power += 11;
911 	}
912 
913 	if (max_power > 26) {
914 		IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV,
915 		     "%s: External buffer size for monitor is too big %d, "
916 		     "check the FW TLV\n", DEVNAME(sc), max_power);
917 		return 0;
918 	}
919 
920 	if (sc->fw_mon.size)
921 		return 0;
922 
923 	return iwx_alloc_fw_monitor_block(sc, max_power, 11);
924 }
925 #endif
926 
927 static int
928 iwx_apply_debug_destination(struct iwx_softc *sc)
929 {
930 #if 0
931 	struct iwx_fw_dbg_dest_tlv_v1 *dest_v1;
932 	int i, err;
933 	uint8_t mon_mode, size_power, base_shift, end_shift;
934 	uint32_t base_reg, end_reg;
935 
936 	dest_v1 = sc->sc_fw.dbg_dest_tlv_v1;
937 	mon_mode = dest_v1->monitor_mode;
938 	size_power = dest_v1->size_power;
939 	base_reg = le32toh(dest_v1->base_reg);
940 	end_reg = le32toh(dest_v1->end_reg);
941 	base_shift = dest_v1->base_shift;
942 	end_shift = dest_v1->end_shift;
943 
944 	DPRINTF(("%s: applying debug destination %d\n", DEVNAME(sc), mon_mode));
945 
946 	if (mon_mode == EXTERNAL_MODE) {
947 		err = iwx_alloc_fw_monitor(sc, size_power);
948 		if (err)
949 			return err;
950 	}
951 
952 	if (!iwx_nic_lock(sc))
953 		return EBUSY;
954 
955 	for (i = 0; i < sc->sc_fw.n_dest_reg; i++) {
956 		uint32_t addr, val;
957 		uint8_t op;
958 
959 		addr = le32toh(dest_v1->reg_ops[i].addr);
960 		val = le32toh(dest_v1->reg_ops[i].val);
961 		op = dest_v1->reg_ops[i].op;
962 
963 		DPRINTF(("%s: op=%u addr=%u val=%u\n", __func__, op, addr, val));
964 		switch (op) {
965 		case CSR_ASSIGN:
966 			IWX_WRITE(sc, addr, val);
967 			break;
968 		case CSR_SETBIT:
969 			IWX_SETBITS(sc, addr, (1 << val));
970 			break;
971 		case CSR_CLEARBIT:
972 			IWX_CLRBITS(sc, addr, (1 << val));
973 			break;
974 		case PRPH_ASSIGN:
975 			iwx_write_prph(sc, addr, val);
976 			break;
977 		case PRPH_SETBIT:
978 			err = iwx_set_bits_prph(sc, addr, (1 << val));
979 			if (err)
980 				return err;
981 			break;
982 		case PRPH_CLEARBIT:
983 			err = iwx_clear_bits_prph(sc, addr, (1 << val));
984 			if (err)
985 				return err;
986 			break;
987 		case PRPH_BLOCKBIT:
988 			if (iwx_read_prph(sc, addr) & (1 << val))
989 				goto monitor;
990 			break;
991 		default:
992 			DPRINTF(("%s: FW debug - unknown OP %d\n",
993 			    DEVNAME(sc), op));
994 			break;
995 		}
996 	}
997 
998 monitor:
999 	if (mon_mode == EXTERNAL_MODE && sc->fw_mon.size) {
1000 		iwx_write_prph(sc, le32toh(base_reg),
1001 		    sc->fw_mon.paddr >> base_shift);
1002 		iwx_write_prph(sc, end_reg,
1003 		    (sc->fw_mon.paddr + sc->fw_mon.size - 256)
1004 		    >> end_shift);
1005 	}
1006 
1007 	iwx_nic_unlock(sc);
1008 	return 0;
1009 #else
1010 	return 0;
1011 #endif
1012 }
1013 
1014 static void
1015 iwx_set_ltr(struct iwx_softc *sc)
1016 {
1017 	uint32_t ltr_val = IWX_CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ |
1018 	    ((IWX_CSR_LTR_LONG_VAL_AD_SCALE_USEC <<
1019 	    IWX_CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE_SHIFT) &
1020 	    IWX_CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE_MASK) |
1021 	    ((250 << IWX_CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL_SHIFT) &
1022 	    IWX_CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL_MASK) |
1023 	    IWX_CSR_LTR_LONG_VAL_AD_SNOOP_REQ |
1024 	    ((IWX_CSR_LTR_LONG_VAL_AD_SCALE_USEC <<
1025 	    IWX_CSR_LTR_LONG_VAL_AD_SNOOP_SCALE_SHIFT) &
1026 	    IWX_CSR_LTR_LONG_VAL_AD_SNOOP_SCALE_MASK) |
1027 	    (250 & IWX_CSR_LTR_LONG_VAL_AD_SNOOP_VAL);
1028 
1029 	/*
1030 	 * To workaround hardware latency issues during the boot process,
1031 	 * initialize the LTR to ~250 usec (see ltr_val above).
1032 	 * The firmware initializes this again later (to a smaller value).
1033 	 */
1034 	if (!sc->sc_integrated) {
1035 		IWX_WRITE(sc, IWX_CSR_LTR_LONG_VAL_AD, ltr_val);
1036 	} else if (sc->sc_integrated &&
1037 		   sc->sc_device_family == IWX_DEVICE_FAMILY_22000) {
1038 		iwx_write_prph(sc, IWX_HPM_MAC_LTR_CSR,
1039 		    IWX_HPM_MAC_LRT_ENABLE_ALL);
1040 		iwx_write_prph(sc, IWX_HPM_UMAC_LTR, ltr_val);
1041 	}
1042 }
1043 
1044 int
1045 iwx_ctxt_info_init(struct iwx_softc *sc, const struct iwx_fw_sects *fws)
1046 {
1047 	struct iwx_context_info *ctxt_info;
1048 	struct iwx_context_info_rbd_cfg *rx_cfg;
1049 	uint32_t control_flags = 0;
1050 	uint64_t paddr;
1051 	int err;
1052 
1053 	ctxt_info = sc->ctxt_info_dma.vaddr;
1054 	memset(ctxt_info, 0, sizeof(*ctxt_info));
1055 
1056 	ctxt_info->version.version = 0;
1057 	ctxt_info->version.mac_id =
1058 		htole16((uint16_t)IWX_READ(sc, IWX_CSR_HW_REV));
1059 	/* size is in DWs */
1060 	ctxt_info->version.size = htole16(sizeof(*ctxt_info) / 4);
1061 
1062 	KASSERT(IWX_RX_QUEUE_CB_SIZE(IWX_MQ_RX_TABLE_SIZE) < 0xF,
1063 	    ("IWX_RX_QUEUE_CB_SIZE exceeds rate table size"));
1064 
1065 	control_flags = IWX_CTXT_INFO_TFD_FORMAT_LONG |
1066 			(IWX_RX_QUEUE_CB_SIZE(IWX_MQ_RX_TABLE_SIZE) <<
1067 			 IWX_CTXT_INFO_RB_CB_SIZE_POS) |
1068 			(IWX_CTXT_INFO_RB_SIZE_4K << IWX_CTXT_INFO_RB_SIZE_POS);
1069 	ctxt_info->control.control_flags = htole32(control_flags);
1070 
1071 	/* initialize RX default queue */
1072 	rx_cfg = &ctxt_info->rbd_cfg;
1073 	rx_cfg->free_rbd_addr = htole64(sc->rxq.free_desc_dma.paddr);
1074 	rx_cfg->used_rbd_addr = htole64(sc->rxq.used_desc_dma.paddr);
1075 	rx_cfg->status_wr_ptr = htole64(sc->rxq.stat_dma.paddr);
1076 
1077 	/* initialize TX command queue */
1078 	ctxt_info->hcmd_cfg.cmd_queue_addr =
1079 	    htole64(sc->txq[IWX_DQA_CMD_QUEUE].desc_dma.paddr);
1080 	ctxt_info->hcmd_cfg.cmd_queue_size =
1081 		IWX_TFD_QUEUE_CB_SIZE(IWX_TX_RING_COUNT);
1082 
1083 	/* allocate ucode sections in dram and set addresses */
1084 	err = iwx_init_fw_sec(sc, fws, &ctxt_info->dram);
1085 	if (err) {
1086 		iwx_ctxt_info_free_fw_img(sc);
1087 		return err;
1088 	}
1089 
1090 	/* Configure debug, if exists */
1091 	if (sc->sc_fw.dbg_dest_tlv_v1) {
1092 #if 1
1093 		err = iwx_apply_debug_destination(sc);
1094 		if (err) {
1095 			iwx_ctxt_info_free_fw_img(sc);
1096 			return err;
1097 		}
1098 #endif
1099 	}
1100 
1101 	/*
1102 	 * Write the context info DMA base address. The device expects a
1103 	 * 64-bit address but a simple bus_space_write_8 to this register
1104 	 * won't work on some devices, such as the AX201.
1105 	 */
1106 	paddr = sc->ctxt_info_dma.paddr;
1107 	IWX_WRITE(sc, IWX_CSR_CTXT_INFO_BA, paddr & 0xffffffff);
1108 	IWX_WRITE(sc, IWX_CSR_CTXT_INFO_BA + 4, paddr >> 32);
1109 
1110 	/* kick FW self load */
1111 	if (!iwx_nic_lock(sc)) {
1112 		iwx_ctxt_info_free_fw_img(sc);
1113 		return EBUSY;
1114 	}
1115 
1116 	iwx_set_ltr(sc);
1117 	iwx_write_prph(sc, IWX_UREG_CPU_INIT_RUN, 1);
1118 	iwx_nic_unlock(sc);
1119 
1120 	/* Context info will be released upon alive or failure to get one */
1121 
1122 	return 0;
1123 }
1124 
1125 static int
1126 iwx_ctxt_info_gen3_init(struct iwx_softc *sc, const struct iwx_fw_sects *fws)
1127 {
1128 	struct iwx_context_info_gen3 *ctxt_info_gen3;
1129 	struct iwx_prph_scratch *prph_scratch;
1130 	struct iwx_prph_scratch_ctrl_cfg *prph_sc_ctrl;
1131 	uint16_t cb_size;
1132 	uint32_t control_flags, scratch_size;
1133 	uint64_t paddr;
1134 	int err;
1135 
1136 	if (sc->sc_fw.iml == NULL || sc->sc_fw.iml_len == 0) {
1137 		printf("%s: no image loader found in firmware file\n",
1138 		    DEVNAME(sc));
1139 		iwx_ctxt_info_free_fw_img(sc);
1140 		return EINVAL;
1141 	}
1142 
1143 	err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->iml_dma,
1144 	    sc->sc_fw.iml_len, 1);
1145 	if (err) {
1146 		printf("%s: could not allocate DMA memory for "
1147 		    "firmware image loader\n", DEVNAME(sc));
1148 		iwx_ctxt_info_free_fw_img(sc);
1149 		return ENOMEM;
1150 	}
1151 
1152 	prph_scratch = sc->prph_scratch_dma.vaddr;
1153 	memset(prph_scratch, 0, sizeof(*prph_scratch));
1154 	prph_sc_ctrl = &prph_scratch->ctrl_cfg;
1155 	prph_sc_ctrl->version.version = 0;
1156 	prph_sc_ctrl->version.mac_id = htole16(IWX_READ(sc, IWX_CSR_HW_REV));
1157 	prph_sc_ctrl->version.size = htole16(sizeof(*prph_scratch) / 4);
1158 
1159 	control_flags = IWX_PRPH_SCRATCH_RB_SIZE_4K |
1160 	    IWX_PRPH_SCRATCH_MTR_MODE |
1161 	    (IWX_PRPH_MTR_FORMAT_256B & IWX_PRPH_SCRATCH_MTR_FORMAT);
1162 	if (sc->sc_imr_enabled)
1163 		control_flags |= IWX_PRPH_SCRATCH_IMR_DEBUG_EN;
1164 	prph_sc_ctrl->control.control_flags = htole32(control_flags);
1165 
1166 	/* initialize RX default queue */
1167 	prph_sc_ctrl->rbd_cfg.free_rbd_addr =
1168 	    htole64(sc->rxq.free_desc_dma.paddr);
1169 
1170 	/* allocate ucode sections in dram and set addresses */
1171 	err = iwx_init_fw_sec(sc, fws, &prph_scratch->dram);
1172 	if (err) {
1173 		iwx_dma_contig_free(&sc->iml_dma);
1174 		iwx_ctxt_info_free_fw_img(sc);
1175 		return err;
1176 	}
1177 
1178 	ctxt_info_gen3 = sc->ctxt_info_dma.vaddr;
1179 	memset(ctxt_info_gen3, 0, sizeof(*ctxt_info_gen3));
1180 	ctxt_info_gen3->prph_info_base_addr = htole64(sc->prph_info_dma.paddr);
1181 	ctxt_info_gen3->prph_scratch_base_addr =
1182 	    htole64(sc->prph_scratch_dma.paddr);
1183 	scratch_size = sizeof(*prph_scratch);
1184 	ctxt_info_gen3->prph_scratch_size = htole32(scratch_size);
1185 	ctxt_info_gen3->cr_head_idx_arr_base_addr =
1186 	    htole64(sc->rxq.stat_dma.paddr);
1187 	ctxt_info_gen3->tr_tail_idx_arr_base_addr =
1188 	    htole64(sc->prph_info_dma.paddr + PAGE_SIZE / 2);
1189 	ctxt_info_gen3->cr_tail_idx_arr_base_addr =
1190 	    htole64(sc->prph_info_dma.paddr + 3 * PAGE_SIZE / 4);
1191 	ctxt_info_gen3->mtr_base_addr =
1192 	    htole64(sc->txq[IWX_DQA_CMD_QUEUE].desc_dma.paddr);
1193 	ctxt_info_gen3->mcr_base_addr = htole64(sc->rxq.used_desc_dma.paddr);
1194 	cb_size = IWX_TFD_QUEUE_CB_SIZE(IWX_TX_RING_COUNT);
1195 	ctxt_info_gen3->mtr_size = htole16(cb_size);
1196 	cb_size = IWX_RX_QUEUE_CB_SIZE(IWX_MQ_RX_TABLE_SIZE);
1197 	ctxt_info_gen3->mcr_size = htole16(cb_size);
1198 
1199 	memcpy(sc->iml_dma.vaddr, sc->sc_fw.iml, sc->sc_fw.iml_len);
1200 
1201 	paddr = sc->ctxt_info_dma.paddr;
1202 	IWX_WRITE(sc, IWX_CSR_CTXT_INFO_ADDR, paddr & 0xffffffff);
1203 	IWX_WRITE(sc, IWX_CSR_CTXT_INFO_ADDR + 4, paddr >> 32);
1204 
1205 	paddr = sc->iml_dma.paddr;
1206 	IWX_WRITE(sc, IWX_CSR_IML_DATA_ADDR, paddr & 0xffffffff);
1207 	IWX_WRITE(sc, IWX_CSR_IML_DATA_ADDR + 4, paddr >> 32);
1208 	IWX_WRITE(sc, IWX_CSR_IML_SIZE_ADDR, sc->sc_fw.iml_len);
1209 
1210 	IWX_SETBITS(sc, IWX_CSR_CTXT_INFO_BOOT_CTRL,
1211 		    IWX_CSR_AUTO_FUNC_BOOT_ENA);
1212 
1213 	IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV,
1214 	    "%s:%d kicking fw to get going\n", __func__, __LINE__);
1215 
1216 	/* kick FW self load */
1217 	if (!iwx_nic_lock(sc)) {
1218 		iwx_dma_contig_free(&sc->iml_dma);
1219 		iwx_ctxt_info_free_fw_img(sc);
1220 		return EBUSY;
1221 	}
1222 	iwx_set_ltr(sc);
1223 	iwx_write_umac_prph(sc, IWX_UREG_CPU_INIT_RUN, 1);
1224 	iwx_nic_unlock(sc);
1225 
1226 	/* Context info will be released upon alive or failure to get one */
1227 	return 0;
1228 }
1229 
1230 static void
1231 iwx_ctxt_info_free_fw_img(struct iwx_softc *sc)
1232 {
1233 	struct iwx_self_init_dram *dram = &sc->init_dram;
1234 	int i;
1235 
1236 	if (!dram->fw)
1237 		return;
1238 
1239 	for (i = 0; i < dram->lmac_cnt + dram->umac_cnt; i++)
1240 		iwx_dma_contig_free(&dram->fw[i]);
1241 
1242 	free(dram->fw, M_DEVBUF);
1243 	dram->lmac_cnt = 0;
1244 	dram->umac_cnt = 0;
1245 	dram->fw = NULL;
1246 }
1247 
1248 static int
1249 iwx_firmware_store_section(struct iwx_softc *sc, enum iwx_ucode_type type,
1250     const uint8_t *data, size_t dlen)
1251 {
1252 	struct iwx_fw_sects *fws;
1253 	struct iwx_fw_onesect *fwone;
1254 
1255 	if (type >= IWX_UCODE_TYPE_MAX)
1256 		return EINVAL;
1257 	if (dlen < sizeof(uint32_t))
1258 		return EINVAL;
1259 
1260 	fws = &sc->sc_fw.fw_sects[type];
1261 	IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV,
1262 	    "%s: ucode type %d section %d\n", DEVNAME(sc), type, fws->fw_count);
1263 	if (fws->fw_count >= IWX_UCODE_SECT_MAX)
1264 		return EINVAL;
1265 
1266 	fwone = &fws->fw_sect[fws->fw_count];
1267 
1268 	/* first 32bit are device load offset */
1269 	memcpy(&fwone->fws_devoff, data, sizeof(uint32_t));
1270 
1271 	/* rest is data */
1272 	fwone->fws_data = data + sizeof(uint32_t);
1273 	fwone->fws_len = dlen - sizeof(uint32_t);
1274 
1275 	fws->fw_count++;
1276 	fws->fw_totlen += fwone->fws_len;
1277 
1278 	return 0;
1279 }
1280 
1281 #define IWX_DEFAULT_SCAN_CHANNELS	40
1282 /* Newer firmware might support more channels. Raise this value if needed. */
1283 #define IWX_MAX_SCAN_CHANNELS		67 /* as of iwx-cc-a0-62 firmware */
1284 
1285 struct iwx_tlv_calib_data {
1286 	uint32_t ucode_type;
1287 	struct iwx_tlv_calib_ctrl calib;
1288 } __packed;
1289 
1290 static int
1291 iwx_set_default_calib(struct iwx_softc *sc, const void *data)
1292 {
1293 	const struct iwx_tlv_calib_data *def_calib = data;
1294 	uint32_t ucode_type = le32toh(def_calib->ucode_type);
1295 
1296 	if (ucode_type >= IWX_UCODE_TYPE_MAX)
1297 		return EINVAL;
1298 
1299 	sc->sc_default_calib[ucode_type].flow_trigger =
1300 	    def_calib->calib.flow_trigger;
1301 	sc->sc_default_calib[ucode_type].event_trigger =
1302 	    def_calib->calib.event_trigger;
1303 
1304 	return 0;
1305 }
1306 
1307 static void
1308 iwx_fw_info_free(struct iwx_fw_info *fw)
1309 {
1310 	free(fw->fw_rawdata, M_DEVBUF);
1311 	fw->fw_rawdata = NULL;
1312 	fw->fw_rawsize = 0;
1313 	/* don't touch fw->fw_status */
1314 	memset(fw->fw_sects, 0, sizeof(fw->fw_sects));
1315 	free(fw->iml, M_DEVBUF);
1316 	fw->iml = NULL;
1317 	fw->iml_len = 0;
1318 }
1319 
1320 #define IWX_FW_ADDR_CACHE_CONTROL 0xC0000000
1321 
1322 static int
1323 iwx_read_firmware(struct iwx_softc *sc)
1324 {
1325 	struct iwx_fw_info *fw = &sc->sc_fw;
1326 	const struct iwx_tlv_ucode_header *uhdr;
1327 	struct iwx_ucode_tlv tlv;
1328 	uint32_t tlv_type;
1329 	const uint8_t *data;
1330 	int err = 0;
1331 	size_t len;
1332 	const struct firmware *fwp;
1333 
1334 	if (fw->fw_status == IWX_FW_STATUS_DONE)
1335 		return 0;
1336 
1337 	fw->fw_status = IWX_FW_STATUS_INPROGRESS;
1338 	fwp = firmware_get(sc->sc_fwname);
1339 	sc->sc_fwp = fwp;
1340 
1341 	if (fwp == NULL) {
1342 		printf("%s: could not read firmware %s\n",
1343 		    DEVNAME(sc), sc->sc_fwname);
1344 		err = ENOENT;
1345 		goto out;
1346 	}
1347 
1348 	IWX_DPRINTF(sc, IWX_DEBUG_FW, "%s:%d %s: using firmware %s\n",
1349 		__func__, __LINE__, DEVNAME(sc), sc->sc_fwname);
1350 
1351 
1352 	sc->sc_capaflags = 0;
1353 	sc->sc_capa_n_scan_channels = IWX_DEFAULT_SCAN_CHANNELS;
1354 	memset(sc->sc_enabled_capa, 0, sizeof(sc->sc_enabled_capa));
1355 	memset(sc->sc_ucode_api, 0, sizeof(sc->sc_ucode_api));
1356 	sc->n_cmd_versions = 0;
1357 
1358 	uhdr = (const void *)(fwp->data);
1359 	if (*(const uint32_t *)fwp->data != 0
1360 	    || le32toh(uhdr->magic) != IWX_TLV_UCODE_MAGIC) {
1361 		printf("%s: invalid firmware %s\n",
1362 		    DEVNAME(sc), sc->sc_fwname);
1363 		err = EINVAL;
1364 		goto out;
1365 	}
1366 
1367 	iwx_fw_version_str(sc->sc_fwver, sizeof(sc->sc_fwver),
1368 	    IWX_UCODE_MAJOR(le32toh(uhdr->ver)),
1369 	    IWX_UCODE_MINOR(le32toh(uhdr->ver)),
1370 	    IWX_UCODE_API(le32toh(uhdr->ver)));
1371 
1372 	data = uhdr->data;
1373 	len = fwp->datasize - sizeof(*uhdr);
1374 
1375 	while (len >= sizeof(tlv)) {
1376 		size_t tlv_len;
1377 		const void *tlv_data;
1378 
1379 		memcpy(&tlv, data, sizeof(tlv));
1380 		tlv_len = le32toh(tlv.length);
1381 		tlv_type = le32toh(tlv.type);
1382 
1383 		len -= sizeof(tlv);
1384 		data += sizeof(tlv);
1385 		tlv_data = data;
1386 
1387 		if (len < tlv_len) {
1388 			printf("%s: firmware too short: %zu bytes\n",
1389 			    DEVNAME(sc), len);
1390 			err = EINVAL;
1391 			goto parse_out;
1392 		}
1393 
1394 		switch (tlv_type) {
1395 		case IWX_UCODE_TLV_PROBE_MAX_LEN:
1396 			if (tlv_len < sizeof(uint32_t)) {
1397 				err = EINVAL;
1398 				goto parse_out;
1399 			}
1400 			sc->sc_capa_max_probe_len
1401 			    = le32toh(*(const uint32_t *)tlv_data);
1402 			if (sc->sc_capa_max_probe_len >
1403 			    IWX_SCAN_OFFLOAD_PROBE_REQ_SIZE) {
1404 				err = EINVAL;
1405 				goto parse_out;
1406 			}
1407 			break;
1408 		case IWX_UCODE_TLV_PAN:
1409 			if (tlv_len) {
1410 				err = EINVAL;
1411 				goto parse_out;
1412 			}
1413 			sc->sc_capaflags |= IWX_UCODE_TLV_FLAGS_PAN;
1414 			break;
1415 		case IWX_UCODE_TLV_FLAGS:
1416 			if (tlv_len < sizeof(uint32_t)) {
1417 				err = EINVAL;
1418 				goto parse_out;
1419 			}
1420 			/*
1421 			 * Apparently there can be many flags, but Linux driver
1422 			 * parses only the first one, and so do we.
1423 			 *
1424 			 * XXX: why does this override IWX_UCODE_TLV_PAN?
1425 			 * Intentional or a bug?  Observations from
1426 			 * current firmware file:
1427 			 *  1) TLV_PAN is parsed first
1428 			 *  2) TLV_FLAGS contains TLV_FLAGS_PAN
1429 			 * ==> this resets TLV_PAN to itself... hnnnk
1430 			 */
1431 			sc->sc_capaflags = le32toh(*(const uint32_t *)tlv_data);
1432 			break;
1433 		case IWX_UCODE_TLV_CSCHEME:
1434 			err = iwx_store_cscheme(sc, tlv_data, tlv_len);
1435 			if (err)
1436 				goto parse_out;
1437 			break;
1438 		case IWX_UCODE_TLV_NUM_OF_CPU: {
1439 			uint32_t num_cpu;
1440 			if (tlv_len != sizeof(uint32_t)) {
1441 				err = EINVAL;
1442 				goto parse_out;
1443 			}
1444 			num_cpu = le32toh(*(const uint32_t *)tlv_data);
1445 			if (num_cpu < 1 || num_cpu > 2) {
1446 				err = EINVAL;
1447 				goto parse_out;
1448 			}
1449 			break;
1450 		}
1451 		case IWX_UCODE_TLV_SEC_RT:
1452 			err = iwx_firmware_store_section(sc,
1453 			    IWX_UCODE_TYPE_REGULAR, tlv_data, tlv_len);
1454 			if (err)
1455 				goto parse_out;
1456 			break;
1457 		case IWX_UCODE_TLV_SEC_INIT:
1458 			err = iwx_firmware_store_section(sc,
1459 			    IWX_UCODE_TYPE_INIT, tlv_data, tlv_len);
1460 			if (err)
1461 				goto parse_out;
1462 			break;
1463 		case IWX_UCODE_TLV_SEC_WOWLAN:
1464 			err = iwx_firmware_store_section(sc,
1465 			    IWX_UCODE_TYPE_WOW, tlv_data, tlv_len);
1466 			if (err)
1467 				goto parse_out;
1468 			break;
1469 		case IWX_UCODE_TLV_DEF_CALIB:
1470 			if (tlv_len != sizeof(struct iwx_tlv_calib_data)) {
1471 				err = EINVAL;
1472 				goto parse_out;
1473 			}
1474 			err = iwx_set_default_calib(sc, tlv_data);
1475 			if (err)
1476 				goto parse_out;
1477 			break;
1478 		case IWX_UCODE_TLV_PHY_SKU:
1479 			if (tlv_len != sizeof(uint32_t)) {
1480 				err = EINVAL;
1481 				goto parse_out;
1482 			}
1483 			sc->sc_fw_phy_config = le32toh(*(const uint32_t *)tlv_data);
1484 			break;
1485 
1486 		case IWX_UCODE_TLV_API_CHANGES_SET: {
1487 			const struct iwx_ucode_api *api;
1488 			int idx, i;
1489 			if (tlv_len != sizeof(*api)) {
1490 				err = EINVAL;
1491 				goto parse_out;
1492 			}
1493 			api = (const struct iwx_ucode_api *)tlv_data;
1494 			idx = le32toh(api->api_index);
1495 			if (idx >= howmany(IWX_NUM_UCODE_TLV_API, 32)) {
1496 				err = EINVAL;
1497 				goto parse_out;
1498 			}
1499 			for (i = 0; i < 32; i++) {
1500 				if ((le32toh(api->api_flags) & (1 << i)) == 0)
1501 					continue;
1502 				setbit(sc->sc_ucode_api, i + (32 * idx));
1503 			}
1504 			break;
1505 		}
1506 
1507 		case IWX_UCODE_TLV_ENABLED_CAPABILITIES: {
1508 			const struct iwx_ucode_capa *capa;
1509 			int idx, i;
1510 			if (tlv_len != sizeof(*capa)) {
1511 				err = EINVAL;
1512 				goto parse_out;
1513 			}
1514 			capa = (const struct iwx_ucode_capa *)tlv_data;
1515 			idx = le32toh(capa->api_index);
1516 			if (idx >= howmany(IWX_NUM_UCODE_TLV_CAPA, 32)) {
1517 				goto parse_out;
1518 			}
1519 			for (i = 0; i < 32; i++) {
1520 				if ((le32toh(capa->api_capa) & (1 << i)) == 0)
1521 					continue;
1522 				setbit(sc->sc_enabled_capa, i + (32 * idx));
1523 			}
1524 			break;
1525 		}
1526 
1527 		case IWX_UCODE_TLV_SDIO_ADMA_ADDR:
1528 		case IWX_UCODE_TLV_FW_GSCAN_CAPA:
1529 			/* ignore, not used by current driver */
1530 			break;
1531 
1532 		case IWX_UCODE_TLV_SEC_RT_USNIFFER:
1533 			err = iwx_firmware_store_section(sc,
1534 			    IWX_UCODE_TYPE_REGULAR_USNIFFER, tlv_data,
1535 			    tlv_len);
1536 			if (err)
1537 				goto parse_out;
1538 			break;
1539 
1540 		case IWX_UCODE_TLV_PAGING:
1541 			if (tlv_len != sizeof(uint32_t)) {
1542 				err = EINVAL;
1543 				goto parse_out;
1544 			}
1545 			break;
1546 
1547 		case IWX_UCODE_TLV_N_SCAN_CHANNELS:
1548 			if (tlv_len != sizeof(uint32_t)) {
1549 				err = EINVAL;
1550 				goto parse_out;
1551 			}
1552 			sc->sc_capa_n_scan_channels =
1553 			  le32toh(*(const uint32_t *)tlv_data);
1554 			if (sc->sc_capa_n_scan_channels > IWX_MAX_SCAN_CHANNELS) {
1555 				err = ERANGE;
1556 				goto parse_out;
1557 			}
1558 			break;
1559 
1560 		case IWX_UCODE_TLV_FW_VERSION:
1561 			if (tlv_len != sizeof(uint32_t) * 3) {
1562 				err = EINVAL;
1563 				goto parse_out;
1564 			}
1565 
1566 			iwx_fw_version_str(sc->sc_fwver, sizeof(sc->sc_fwver),
1567 			    le32toh(((const uint32_t *)tlv_data)[0]),
1568 			    le32toh(((const uint32_t *)tlv_data)[1]),
1569 			    le32toh(((const uint32_t *)tlv_data)[2]));
1570 			break;
1571 
1572 		case IWX_UCODE_TLV_FW_DBG_DEST: {
1573 			const struct iwx_fw_dbg_dest_tlv_v1 *dest_v1 = NULL;
1574 
1575 			fw->dbg_dest_ver = (const uint8_t *)tlv_data;
1576 			if (*fw->dbg_dest_ver != 0) {
1577 				err = EINVAL;
1578 				goto parse_out;
1579 			}
1580 
1581 			if (fw->dbg_dest_tlv_init)
1582 				break;
1583 			fw->dbg_dest_tlv_init = true;
1584 
1585 			dest_v1 = (const void *)tlv_data;
1586 			fw->dbg_dest_tlv_v1 = dest_v1;
1587 			fw->n_dest_reg = tlv_len -
1588 			    offsetof(struct iwx_fw_dbg_dest_tlv_v1, reg_ops);
1589 			fw->n_dest_reg /= sizeof(dest_v1->reg_ops[0]);
1590 			IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV,
1591 			    "%s: found debug dest; n_dest_reg=%d\n",
1592 			    __func__, fw->n_dest_reg);
1593 			break;
1594 		}
1595 
1596 		case IWX_UCODE_TLV_FW_DBG_CONF: {
1597 			const struct iwx_fw_dbg_conf_tlv *conf = (const void *)tlv_data;
1598 
1599 			if (!fw->dbg_dest_tlv_init ||
1600 			    conf->id >= nitems(fw->dbg_conf_tlv) ||
1601 			    fw->dbg_conf_tlv[conf->id] != NULL)
1602 				break;
1603 
1604 			IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV,
1605 			    "Found debug configuration: %d\n", conf->id);
1606 			fw->dbg_conf_tlv[conf->id] = conf;
1607 			fw->dbg_conf_tlv_len[conf->id] = tlv_len;
1608 			break;
1609 		}
1610 
1611 		case IWX_UCODE_TLV_UMAC_DEBUG_ADDRS: {
1612 			const struct iwx_umac_debug_addrs *dbg_ptrs =
1613 				(const void *)tlv_data;
1614 
1615 			if (tlv_len != sizeof(*dbg_ptrs)) {
1616 				err = EINVAL;
1617 				goto parse_out;
1618 			}
1619 			if (sc->sc_device_family < IWX_DEVICE_FAMILY_22000)
1620 				break;
1621 			sc->sc_uc.uc_umac_error_event_table =
1622 				le32toh(dbg_ptrs->error_info_addr) &
1623 				~IWX_FW_ADDR_CACHE_CONTROL;
1624 			sc->sc_uc.error_event_table_tlv_status |=
1625 				IWX_ERROR_EVENT_TABLE_UMAC;
1626 			break;
1627 		}
1628 
1629 		case IWX_UCODE_TLV_LMAC_DEBUG_ADDRS: {
1630 			const struct iwx_lmac_debug_addrs *dbg_ptrs =
1631 				(const void *)tlv_data;
1632 
1633 			if (tlv_len != sizeof(*dbg_ptrs)) {
1634 				err = EINVAL;
1635 				goto parse_out;
1636 			}
1637 			if (sc->sc_device_family < IWX_DEVICE_FAMILY_22000)
1638 				break;
1639 			sc->sc_uc.uc_lmac_error_event_table[0] =
1640 				le32toh(dbg_ptrs->error_event_table_ptr) &
1641 				~IWX_FW_ADDR_CACHE_CONTROL;
1642 			sc->sc_uc.error_event_table_tlv_status |=
1643 				IWX_ERROR_EVENT_TABLE_LMAC1;
1644 			break;
1645 		}
1646 
1647 		case IWX_UCODE_TLV_FW_MEM_SEG:
1648 			break;
1649 
1650 		case IWX_UCODE_TLV_IML:
1651 			if (sc->sc_fw.iml != NULL) {
1652 				free(fw->iml, M_DEVBUF);
1653 				fw->iml_len = 0;
1654 			}
1655 			sc->sc_fw.iml = malloc(tlv_len, M_DEVBUF,
1656 			    M_WAITOK | M_ZERO);
1657 			if (sc->sc_fw.iml == NULL) {
1658 				err = ENOMEM;
1659 				goto parse_out;
1660 			}
1661 			memcpy(sc->sc_fw.iml, tlv_data, tlv_len);
1662 			sc->sc_fw.iml_len = tlv_len;
1663 			break;
1664 
1665 		case IWX_UCODE_TLV_CMD_VERSIONS:
1666 			if (tlv_len % sizeof(struct iwx_fw_cmd_version)) {
1667 				tlv_len /= sizeof(struct iwx_fw_cmd_version);
1668 				tlv_len *= sizeof(struct iwx_fw_cmd_version);
1669 			}
1670 			if (sc->n_cmd_versions != 0) {
1671 				err = EINVAL;
1672 				goto parse_out;
1673 			}
1674 			if (tlv_len > sizeof(sc->cmd_versions)) {
1675 				err = EINVAL;
1676 				goto parse_out;
1677 			}
1678 			memcpy(&sc->cmd_versions[0], tlv_data, tlv_len);
1679 			sc->n_cmd_versions = tlv_len / sizeof(struct iwx_fw_cmd_version);
1680 			break;
1681 
1682 		case IWX_UCODE_TLV_FW_RECOVERY_INFO:
1683 			break;
1684 
1685 		case IWX_UCODE_TLV_FW_FSEQ_VERSION:
1686 		case IWX_UCODE_TLV_PHY_INTEGRATION_VERSION:
1687 		case IWX_UCODE_TLV_FW_NUM_STATIONS:
1688 		case IWX_UCODE_TLV_FW_NUM_BEACONS:
1689 			break;
1690 
1691 		/* undocumented TLVs found in iwx-cc-a0-46 image */
1692 		case 58:
1693 		case 0x1000003:
1694 		case 0x1000004:
1695 			break;
1696 
1697 		/* undocumented TLVs found in iwx-cc-a0-48 image */
1698 		case 0x1000000:
1699 		case 0x1000002:
1700 			break;
1701 
1702 		case IWX_UCODE_TLV_TYPE_DEBUG_INFO:
1703 		case IWX_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
1704 		case IWX_UCODE_TLV_TYPE_HCMD:
1705 		case IWX_UCODE_TLV_TYPE_REGIONS:
1706 		case IWX_UCODE_TLV_TYPE_TRIGGERS:
1707 		case IWX_UCODE_TLV_TYPE_CONF_SET:
1708 		case IWX_UCODE_TLV_SEC_TABLE_ADDR:
1709 		case IWX_UCODE_TLV_D3_KEK_KCK_ADDR:
1710 		case IWX_UCODE_TLV_CURRENT_PC:
1711 			break;
1712 
1713 		/* undocumented TLV found in iwx-cc-a0-67 image */
1714 		case 0x100000b:
1715 			break;
1716 
1717 		/* undocumented TLV found in iwx-ty-a0-gf-a0-73 image */
1718 		case 0x101:
1719 			break;
1720 
1721 		/* undocumented TLV found in iwx-ty-a0-gf-a0-77 image */
1722 		case 0x100000c:
1723 			break;
1724 
1725 		/* undocumented TLV found in iwx-ty-a0-gf-a0-89 image */
1726 		case 69:
1727 			break;
1728 
1729 		default:
1730 			err = EINVAL;
1731 			goto parse_out;
1732 		}
1733 
1734 		/*
1735 		 * Check for size_t overflow and ignore missing padding at
1736 		 * end of firmware file.
1737 		 */
1738 		if (roundup(tlv_len, 4) > len)
1739 			break;
1740 
1741 		len -= roundup(tlv_len, 4);
1742 		data += roundup(tlv_len, 4);
1743 	}
1744 
1745 	KASSERT(err == 0, ("unhandled fw parse error"));
1746 
1747 parse_out:
1748 	if (err) {
1749 		printf("%s: firmware parse error %d, "
1750 		    "section type %d\n", DEVNAME(sc), err, tlv_type);
1751 	}
1752 
1753 out:
1754 	if (err) {
1755 		fw->fw_status = IWX_FW_STATUS_NONE;
1756 		if (fw->fw_rawdata != NULL)
1757 			iwx_fw_info_free(fw);
1758 	} else
1759 		fw->fw_status = IWX_FW_STATUS_DONE;
1760 	return err;
1761 }
1762 
1763 static uint32_t
1764 iwx_prph_addr_mask(struct iwx_softc *sc)
1765 {
1766 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
1767 		return 0x00ffffff;
1768 	else
1769 		return 0x000fffff;
1770 }
1771 
1772 static uint32_t
1773 iwx_read_prph_unlocked(struct iwx_softc *sc, uint32_t addr)
1774 {
1775 	uint32_t mask = iwx_prph_addr_mask(sc);
1776 	IWX_WRITE(sc, IWX_HBUS_TARG_PRPH_RADDR, ((addr & mask) | (3 << 24)));
1777 	IWX_BARRIER_READ_WRITE(sc);
1778 	return IWX_READ(sc, IWX_HBUS_TARG_PRPH_RDAT);
1779 }
1780 
1781 uint32_t
1782 iwx_read_prph(struct iwx_softc *sc, uint32_t addr)
1783 {
1784 	iwx_nic_assert_locked(sc);
1785 	return iwx_read_prph_unlocked(sc, addr);
1786 }
1787 
1788 static void
1789 iwx_write_prph_unlocked(struct iwx_softc *sc, uint32_t addr, uint32_t val)
1790 {
1791 	uint32_t mask = iwx_prph_addr_mask(sc);
1792 	IWX_WRITE(sc, IWX_HBUS_TARG_PRPH_WADDR, ((addr & mask) | (3 << 24)));
1793 	IWX_BARRIER_WRITE(sc);
1794 	IWX_WRITE(sc, IWX_HBUS_TARG_PRPH_WDAT, val);
1795 }
1796 
1797 static void
1798 iwx_write_prph(struct iwx_softc *sc, uint32_t addr, uint32_t val)
1799 {
1800 	iwx_nic_assert_locked(sc);
1801 	iwx_write_prph_unlocked(sc, addr, val);
1802 }
1803 
1804 static uint32_t
1805 iwx_read_umac_prph(struct iwx_softc *sc, uint32_t addr)
1806 {
1807 	return iwx_read_prph(sc, addr + sc->sc_umac_prph_offset);
1808 }
1809 
1810 static void
1811 iwx_write_umac_prph(struct iwx_softc *sc, uint32_t addr, uint32_t val)
1812 {
1813 	iwx_write_prph(sc, addr + sc->sc_umac_prph_offset, val);
1814 }
1815 
1816 static int
1817 iwx_read_mem(struct iwx_softc *sc, uint32_t addr, void *buf, int dwords)
1818 {
1819 	int offs, err = 0;
1820 	uint32_t *vals = buf;
1821 
1822 	if (iwx_nic_lock(sc)) {
1823 		IWX_WRITE(sc, IWX_HBUS_TARG_MEM_RADDR, addr);
1824 		for (offs = 0; offs < dwords; offs++)
1825 			vals[offs] = le32toh(IWX_READ(sc, IWX_HBUS_TARG_MEM_RDAT));
1826 		iwx_nic_unlock(sc);
1827 	} else {
1828 		err = EBUSY;
1829 	}
1830 	return err;
1831 }
1832 
1833 static int
1834 iwx_poll_bit(struct iwx_softc *sc, int reg, uint32_t bits, uint32_t mask,
1835     int timo)
1836 {
1837 	for (;;) {
1838 		if ((IWX_READ(sc, reg) & mask) == (bits & mask)) {
1839 			return 1;
1840 		}
1841 		if (timo < 10) {
1842 			return 0;
1843 		}
1844 		timo -= 10;
1845 		DELAY(10);
1846 	}
1847 }
1848 
1849 static int
1850 iwx_nic_lock(struct iwx_softc *sc)
1851 {
1852 	if (sc->sc_nic_locks > 0) {
1853 		iwx_nic_assert_locked(sc);
1854 		sc->sc_nic_locks++;
1855 		return 1; /* already locked */
1856 	}
1857 
1858 	IWX_SETBITS(sc, IWX_CSR_GP_CNTRL,
1859 	    IWX_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1860 
1861 	DELAY(2);
1862 
1863 	if (iwx_poll_bit(sc, IWX_CSR_GP_CNTRL,
1864 	    IWX_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
1865 	    IWX_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
1866 	     | IWX_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP, 150000)) {
1867 		sc->sc_nic_locks++;
1868 		return 1;
1869 	}
1870 
1871 	printf("%s: acquiring device failed\n", DEVNAME(sc));
1872 	return 0;
1873 }
1874 
1875 static void
1876 iwx_nic_assert_locked(struct iwx_softc *sc)
1877 {
1878 	if (sc->sc_nic_locks <= 0)
1879 		panic("%s: nic locks counter %d", DEVNAME(sc), sc->sc_nic_locks);
1880 }
1881 
1882 static void
1883 iwx_nic_unlock(struct iwx_softc *sc)
1884 {
1885 	if (sc->sc_nic_locks > 0) {
1886 		if (--sc->sc_nic_locks == 0)
1887 			IWX_CLRBITS(sc, IWX_CSR_GP_CNTRL,
1888 			    IWX_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1889 	} else
1890 		printf("%s: NIC already unlocked\n", DEVNAME(sc));
1891 }
1892 
1893 static int
1894 iwx_set_bits_mask_prph(struct iwx_softc *sc, uint32_t reg, uint32_t bits,
1895     uint32_t mask)
1896 {
1897 	uint32_t val;
1898 
1899 	if (iwx_nic_lock(sc)) {
1900 		val = iwx_read_prph(sc, reg) & mask;
1901 		val |= bits;
1902 		iwx_write_prph(sc, reg, val);
1903 		iwx_nic_unlock(sc);
1904 		return 0;
1905 	}
1906 	return EBUSY;
1907 }
1908 
1909 static int
1910 iwx_set_bits_prph(struct iwx_softc *sc, uint32_t reg, uint32_t bits)
1911 {
1912 	return iwx_set_bits_mask_prph(sc, reg, bits, ~0);
1913 }
1914 
1915 static int
1916 iwx_clear_bits_prph(struct iwx_softc *sc, uint32_t reg, uint32_t bits)
1917 {
1918 	return iwx_set_bits_mask_prph(sc, reg, 0, ~bits);
1919 }
1920 
1921 static void
1922 iwx_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
1923 {
1924         if (error != 0)
1925                 return;
1926 	KASSERT(nsegs == 1, ("too many DMA segments, %d should be 1", nsegs));
1927 	*(bus_addr_t *)arg = segs[0].ds_addr;
1928 }
1929 
1930 static int
1931 iwx_dma_contig_alloc(bus_dma_tag_t tag, struct iwx_dma_info *dma,
1932     bus_size_t size, bus_size_t alignment)
1933 {
1934 	int error;
1935 
1936 	dma->tag = NULL;
1937 	dma->map = NULL;
1938 	dma->size = size;
1939 	dma->vaddr = NULL;
1940 
1941 	error = bus_dma_tag_create(tag, alignment,
1942             0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size,
1943             1, size, 0, NULL, NULL, &dma->tag);
1944         if (error != 0)
1945                 goto fail;
1946 
1947         error = bus_dmamem_alloc(dma->tag, (void **)&dma->vaddr,
1948             BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &dma->map);
1949         if (error != 0)
1950                 goto fail;
1951 
1952         error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr, size,
1953             iwx_dma_map_addr, &dma->paddr, BUS_DMA_NOWAIT);
1954         if (error != 0) {
1955 		bus_dmamem_free(dma->tag, dma->vaddr, dma->map);
1956 		dma->vaddr = NULL;
1957 		goto fail;
1958 	}
1959 
1960 	bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
1961 
1962 	return 0;
1963 
1964 fail:
1965 	iwx_dma_contig_free(dma);
1966 	return error;
1967 }
1968 
1969 static void
1970 iwx_dma_contig_free(struct iwx_dma_info *dma)
1971 {
1972 	if (dma->vaddr != NULL) {
1973 		bus_dmamap_sync(dma->tag, dma->map,
1974 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1975 		bus_dmamap_unload(dma->tag, dma->map);
1976 		bus_dmamem_free(dma->tag, dma->vaddr, dma->map);
1977 		dma->vaddr = NULL;
1978 	}
1979 	if (dma->tag != NULL) {
1980 		bus_dma_tag_destroy(dma->tag);
1981 		dma->tag = NULL;
1982 	}
1983 }
1984 
1985 static int
1986 iwx_alloc_rx_ring(struct iwx_softc *sc, struct iwx_rx_ring *ring)
1987 {
1988 	bus_size_t size;
1989 	int i, err;
1990 
1991 	ring->cur = 0;
1992 
1993 	/* Allocate RX descriptors (256-byte aligned). */
1994 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
1995 		size = sizeof(struct iwx_rx_transfer_desc);
1996 	else
1997 		size = sizeof(uint64_t);
1998 	err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->free_desc_dma,
1999 	    size * IWX_RX_MQ_RING_COUNT, 256);
2000 	if (err) {
2001 		device_printf(sc->sc_dev,
2002 		    "could not allocate RX ring DMA memory\n");
2003 		goto fail;
2004 	}
2005 	ring->desc = ring->free_desc_dma.vaddr;
2006 
2007 	/* Allocate RX status area (16-byte aligned). */
2008 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
2009 		size = sizeof(uint16_t);
2010 	else
2011 		size = sizeof(*ring->stat);
2012 	err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma, size, 16);
2013 	if (err) {
2014 		device_printf(sc->sc_dev,
2015 		    "could not allocate RX status DMA memory\n");
2016 		goto fail;
2017 	}
2018 	ring->stat = ring->stat_dma.vaddr;
2019 
2020 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
2021 		size = sizeof(struct iwx_rx_completion_desc);
2022 	else
2023 		size = sizeof(uint32_t);
2024 	err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->used_desc_dma,
2025 	    size * IWX_RX_MQ_RING_COUNT, 256);
2026 	if (err) {
2027 		device_printf(sc->sc_dev,
2028 		    "could not allocate RX ring DMA memory\n");
2029 		goto fail;
2030 	}
2031 
2032 	err = bus_dma_tag_create(sc->sc_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT,
2033 	    BUS_SPACE_MAXADDR, NULL, NULL, IWX_RBUF_SIZE, 1, IWX_RBUF_SIZE,
2034 	    0, NULL, NULL, &ring->data_dmat);
2035 
2036 	for (i = 0; i < IWX_RX_MQ_RING_COUNT; i++) {
2037 		struct iwx_rx_data *data = &ring->data[i];
2038 
2039 		memset(data, 0, sizeof(*data));
2040 		err = bus_dmamap_create(ring->data_dmat, 0, &data->map);
2041 		if (err) {
2042 			device_printf(sc->sc_dev,
2043 			    "could not create RX buf DMA map\n");
2044 			goto fail;
2045 		}
2046 
2047 		err = iwx_rx_addbuf(sc, IWX_RBUF_SIZE, i);
2048 		if (err)
2049 			goto fail;
2050 	}
2051 	return 0;
2052 
2053 fail:	iwx_free_rx_ring(sc, ring);
2054 	return err;
2055 }
2056 
2057 static void
2058 iwx_disable_rx_dma(struct iwx_softc *sc)
2059 {
2060 	int ntries;
2061 
2062 	if (iwx_nic_lock(sc)) {
2063 		if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
2064 			iwx_write_umac_prph(sc, IWX_RFH_RXF_DMA_CFG_GEN3, 0);
2065 		else
2066 			iwx_write_prph(sc, IWX_RFH_RXF_DMA_CFG, 0);
2067 		for (ntries = 0; ntries < 1000; ntries++) {
2068 			if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
2069 				if (iwx_read_umac_prph(sc,
2070 				    IWX_RFH_GEN_STATUS_GEN3) & IWX_RXF_DMA_IDLE)
2071 					break;
2072 			} else {
2073 				if (iwx_read_prph(sc, IWX_RFH_GEN_STATUS) &
2074 				    IWX_RXF_DMA_IDLE)
2075 					break;
2076 			}
2077 			DELAY(10);
2078 		}
2079 		iwx_nic_unlock(sc);
2080 	}
2081 }
2082 
2083 static void
2084 iwx_reset_rx_ring(struct iwx_softc *sc, struct iwx_rx_ring *ring)
2085 {
2086 	ring->cur = 0;
2087 	bus_dmamap_sync(sc->sc_dmat, ring->stat_dma.map,
2088 	    BUS_DMASYNC_PREWRITE);
2089 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
2090 		uint16_t *status = sc->rxq.stat_dma.vaddr;
2091 		*status = 0;
2092 	} else
2093 		memset(ring->stat, 0, sizeof(*ring->stat));
2094 	bus_dmamap_sync(sc->sc_dmat, ring->stat_dma.map,
2095 	    BUS_DMASYNC_POSTWRITE);
2096 
2097 }
2098 
2099 static void
2100 iwx_free_rx_ring(struct iwx_softc *sc, struct iwx_rx_ring *ring)
2101 {
2102 	int i;
2103 
2104 	iwx_dma_contig_free(&ring->free_desc_dma);
2105 	iwx_dma_contig_free(&ring->stat_dma);
2106 	iwx_dma_contig_free(&ring->used_desc_dma);
2107 
2108 	for (i = 0; i < IWX_RX_MQ_RING_COUNT; i++) {
2109 		struct iwx_rx_data *data = &ring->data[i];
2110 		if (data->m != NULL) {
2111 			bus_dmamap_sync(ring->data_dmat, data->map,
2112 			    BUS_DMASYNC_POSTREAD);
2113 			bus_dmamap_unload(ring->data_dmat, data->map);
2114 			m_freem(data->m);
2115 			data->m = NULL;
2116 		}
2117 		if (data->map != NULL) {
2118 			bus_dmamap_destroy(ring->data_dmat, data->map);
2119 			data->map = NULL;
2120 		}
2121 	}
2122 	if (ring->data_dmat != NULL) {
2123 		bus_dma_tag_destroy(ring->data_dmat);
2124 		ring->data_dmat = NULL;
2125 	}
2126 }
2127 
2128 static int
2129 iwx_alloc_tx_ring(struct iwx_softc *sc, struct iwx_tx_ring *ring, int qid)
2130 {
2131 	bus_addr_t paddr;
2132 	bus_size_t size;
2133 	int i, err;
2134 	size_t bc_tbl_size;
2135 	bus_size_t bc_align;
2136 	size_t mapsize;
2137 
2138 	ring->qid = qid;
2139 	ring->queued = 0;
2140 	ring->cur = 0;
2141 	ring->cur_hw = 0;
2142 	ring->tail = 0;
2143 	ring->tail_hw = 0;
2144 
2145 	/* Allocate TX descriptors (256-byte aligned). */
2146 	size = IWX_TX_RING_COUNT * sizeof(struct iwx_tfh_tfd);
2147 	err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256);
2148 	if (err) {
2149 		device_printf(sc->sc_dev,
2150 		    "could not allocate TX ring DMA memory\n");
2151 		goto fail;
2152 	}
2153 	ring->desc = ring->desc_dma.vaddr;
2154 
2155 	/*
2156 	 * The hardware supports up to 512 Tx rings which is more
2157 	 * than we currently need.
2158 	 *
2159 	 * In DQA mode we use 1 command queue + 1 default queue for
2160 	 * management, control, and non-QoS data frames.
2161 	 * The command is queue sc->txq[0], our default queue is sc->txq[1].
2162 	 *
2163 	 * Tx aggregation requires additional queues, one queue per TID for
2164 	 * which aggregation is enabled. We map TID 0-7 to sc->txq[2:9].
2165 	 * Firmware may assign its own internal IDs for these queues
2166 	 * depending on which TID gets aggregation enabled first.
2167 	 * The driver maintains a table mapping driver-side queue IDs
2168 	 * to firmware-side queue IDs.
2169 	 */
2170 
2171 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
2172 		bc_tbl_size = sizeof(struct iwx_gen3_bc_tbl_entry) *
2173 		    IWX_TFD_QUEUE_BC_SIZE_GEN3_AX210;
2174 		bc_align = 128;
2175 	} else {
2176 		bc_tbl_size = sizeof(struct iwx_agn_scd_bc_tbl);
2177 		bc_align = 64;
2178 	}
2179 	err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->bc_tbl, bc_tbl_size,
2180 	    bc_align);
2181 	if (err) {
2182 		device_printf(sc->sc_dev,
2183 		    "could not allocate byte count table DMA memory\n");
2184 		goto fail;
2185 	}
2186 
2187 	size = IWX_TX_RING_COUNT * sizeof(struct iwx_device_cmd);
2188 	err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma, size,
2189 	    IWX_FIRST_TB_SIZE_ALIGN);
2190 	if (err) {
2191 		device_printf(sc->sc_dev,
2192 		    "could not allocate cmd DMA memory\n");
2193 		goto fail;
2194 	}
2195 	ring->cmd = ring->cmd_dma.vaddr;
2196 
2197 	/* FW commands may require more mapped space than packets. */
2198 	if (qid == IWX_DQA_CMD_QUEUE)
2199 		mapsize = (sizeof(struct iwx_cmd_header) +
2200 		    IWX_MAX_CMD_PAYLOAD_SIZE);
2201 	else
2202 		mapsize = MCLBYTES;
2203 	err = bus_dma_tag_create(sc->sc_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT,
2204 	    BUS_SPACE_MAXADDR, NULL, NULL, mapsize, IWX_TFH_NUM_TBS - 2,
2205 	    mapsize, 0, NULL, NULL, &ring->data_dmat);
2206 
2207 	paddr = ring->cmd_dma.paddr;
2208 	for (i = 0; i < IWX_TX_RING_COUNT; i++) {
2209 		struct iwx_tx_data *data = &ring->data[i];
2210 
2211 		data->cmd_paddr = paddr;
2212 		paddr += sizeof(struct iwx_device_cmd);
2213 
2214 		err = bus_dmamap_create(ring->data_dmat, 0, &data->map);
2215 		if (err) {
2216 			device_printf(sc->sc_dev,
2217 			    "could not create TX buf DMA map\n");
2218 			goto fail;
2219 		}
2220 	}
2221 	KASSERT(paddr == ring->cmd_dma.paddr + size, ("bad paddr in txr alloc"));
2222 	return 0;
2223 
2224 fail:
2225 	return err;
2226 }
2227 
2228 static void
2229 iwx_reset_tx_ring(struct iwx_softc *sc, struct iwx_tx_ring *ring)
2230 {
2231 	int i;
2232 
2233 	for (i = 0; i < IWX_TX_RING_COUNT; i++) {
2234 		struct iwx_tx_data *data = &ring->data[i];
2235 
2236 		if (data->m != NULL) {
2237 			bus_dmamap_sync(ring->data_dmat, data->map,
2238 			    BUS_DMASYNC_POSTWRITE);
2239 			bus_dmamap_unload(ring->data_dmat, data->map);
2240 			m_freem(data->m);
2241 			data->m = NULL;
2242 		}
2243 	}
2244 
2245 	/* Clear byte count table. */
2246 	memset(ring->bc_tbl.vaddr, 0, ring->bc_tbl.size);
2247 
2248 	/* Clear TX descriptors. */
2249 	memset(ring->desc, 0, ring->desc_dma.size);
2250 	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
2251 	    BUS_DMASYNC_PREWRITE);
2252 	sc->qfullmsk &= ~(1 << ring->qid);
2253 	sc->qenablemsk &= ~(1 << ring->qid);
2254 	for (i = 0; i < nitems(sc->aggqid); i++) {
2255 		if (sc->aggqid[i] == ring->qid) {
2256 			sc->aggqid[i] = 0;
2257 			break;
2258 		}
2259 	}
2260 	ring->queued = 0;
2261 	ring->cur = 0;
2262 	ring->cur_hw = 0;
2263 	ring->tail = 0;
2264 	ring->tail_hw = 0;
2265 	ring->tid = 0;
2266 }
2267 
2268 static void
2269 iwx_free_tx_ring(struct iwx_softc *sc, struct iwx_tx_ring *ring)
2270 {
2271 	int i;
2272 
2273 	iwx_dma_contig_free(&ring->desc_dma);
2274 	iwx_dma_contig_free(&ring->cmd_dma);
2275 	iwx_dma_contig_free(&ring->bc_tbl);
2276 
2277 	for (i = 0; i < IWX_TX_RING_COUNT; i++) {
2278 		struct iwx_tx_data *data = &ring->data[i];
2279 
2280 		if (data->m != NULL) {
2281 			bus_dmamap_sync(ring->data_dmat, data->map,
2282 			    BUS_DMASYNC_POSTWRITE);
2283 			bus_dmamap_unload(ring->data_dmat, data->map);
2284 			m_freem(data->m);
2285 			data->m = NULL;
2286 		}
2287 		if (data->map != NULL) {
2288 			bus_dmamap_destroy(ring->data_dmat, data->map);
2289 			data->map = NULL;
2290 		}
2291 	}
2292 	if (ring->data_dmat != NULL) {
2293 		bus_dma_tag_destroy(ring->data_dmat);
2294 		ring->data_dmat = NULL;
2295 	}
2296 }
2297 
2298 static void
2299 iwx_enable_rfkill_int(struct iwx_softc *sc)
2300 {
2301 	if (!sc->sc_msix) {
2302 		sc->sc_intmask = IWX_CSR_INT_BIT_RF_KILL;
2303 		IWX_WRITE(sc, IWX_CSR_INT_MASK, sc->sc_intmask);
2304 	} else {
2305 		IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_MASK_AD,
2306 		    sc->sc_fh_init_mask);
2307 		IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_MASK_AD,
2308 		    ~IWX_MSIX_HW_INT_CAUSES_REG_RF_KILL);
2309 		sc->sc_hw_mask = IWX_MSIX_HW_INT_CAUSES_REG_RF_KILL;
2310 	}
2311 
2312 	IWX_SETBITS(sc, IWX_CSR_GP_CNTRL,
2313 	    IWX_CSR_GP_CNTRL_REG_FLAG_RFKILL_WAKE_L1A_EN);
2314 }
2315 
2316 static int
2317 iwx_check_rfkill(struct iwx_softc *sc)
2318 {
2319 	uint32_t v;
2320 	int rv;
2321 
2322 	/*
2323 	 * "documentation" is not really helpful here:
2324 	 *  27:	HW_RF_KILL_SW
2325 	 *	Indicates state of (platform's) hardware RF-Kill switch
2326 	 *
2327 	 * But apparently when it's off, it's on ...
2328 	 */
2329 	v = IWX_READ(sc, IWX_CSR_GP_CNTRL);
2330 	rv = (v & IWX_CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) == 0;
2331 	if (rv) {
2332 		sc->sc_flags |= IWX_FLAG_RFKILL;
2333 	} else {
2334 		sc->sc_flags &= ~IWX_FLAG_RFKILL;
2335 	}
2336 
2337 	return rv;
2338 }
2339 
2340 static void
2341 iwx_enable_interrupts(struct iwx_softc *sc)
2342 {
2343 	if (!sc->sc_msix) {
2344 		sc->sc_intmask = IWX_CSR_INI_SET_MASK;
2345 		IWX_WRITE(sc, IWX_CSR_INT_MASK, sc->sc_intmask);
2346 	} else {
2347 		/*
2348 		 * fh/hw_mask keeps all the unmasked causes.
2349 		 * Unlike msi, in msix cause is enabled when it is unset.
2350 		 */
2351 		sc->sc_hw_mask = sc->sc_hw_init_mask;
2352 		sc->sc_fh_mask = sc->sc_fh_init_mask;
2353 		IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_MASK_AD,
2354 		    ~sc->sc_fh_mask);
2355 		IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_MASK_AD,
2356 		    ~sc->sc_hw_mask);
2357 	}
2358 }
2359 
2360 static void
2361 iwx_enable_fwload_interrupt(struct iwx_softc *sc)
2362 {
2363 	if (!sc->sc_msix) {
2364 		sc->sc_intmask = IWX_CSR_INT_BIT_ALIVE | IWX_CSR_INT_BIT_FH_RX;
2365 		IWX_WRITE(sc, IWX_CSR_INT_MASK, sc->sc_intmask);
2366 	} else {
2367 		IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_MASK_AD,
2368 		    ~IWX_MSIX_HW_INT_CAUSES_REG_ALIVE);
2369 		sc->sc_hw_mask = IWX_MSIX_HW_INT_CAUSES_REG_ALIVE;
2370 		/*
2371 		 * Leave all the FH causes enabled to get the ALIVE
2372 		 * notification.
2373 		 */
2374 		IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_MASK_AD,
2375 		    ~sc->sc_fh_init_mask);
2376 		sc->sc_fh_mask = sc->sc_fh_init_mask;
2377 	}
2378 }
2379 
2380 #if 0
2381 static void
2382 iwx_restore_interrupts(struct iwx_softc *sc)
2383 {
2384 	IWX_WRITE(sc, IWX_CSR_INT_MASK, sc->sc_intmask);
2385 }
2386 #endif
2387 
2388 static void
2389 iwx_disable_interrupts(struct iwx_softc *sc)
2390 {
2391 	if (!sc->sc_msix) {
2392 		IWX_WRITE(sc, IWX_CSR_INT_MASK, 0);
2393 
2394 		/* acknowledge all interrupts */
2395 		IWX_WRITE(sc, IWX_CSR_INT, ~0);
2396 		IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, ~0);
2397 	} else {
2398 		IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_MASK_AD,
2399 		    sc->sc_fh_init_mask);
2400 		IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_MASK_AD,
2401 		    sc->sc_hw_init_mask);
2402 	}
2403 }
2404 
2405 static void
2406 iwx_ict_reset(struct iwx_softc *sc)
2407 {
2408 	iwx_disable_interrupts(sc);
2409 
2410 	memset(sc->ict_dma.vaddr, 0, IWX_ICT_SIZE);
2411 	sc->ict_cur = 0;
2412 
2413 	/* Set physical address of ICT (4KB aligned). */
2414 	IWX_WRITE(sc, IWX_CSR_DRAM_INT_TBL_REG,
2415 	    IWX_CSR_DRAM_INT_TBL_ENABLE
2416 	    | IWX_CSR_DRAM_INIT_TBL_WRAP_CHECK
2417 	    | IWX_CSR_DRAM_INIT_TBL_WRITE_POINTER
2418 	    | sc->ict_dma.paddr >> IWX_ICT_PADDR_SHIFT);
2419 
2420 	/* Switch to ICT interrupt mode in driver. */
2421 	sc->sc_flags |= IWX_FLAG_USE_ICT;
2422 
2423 	IWX_WRITE(sc, IWX_CSR_INT, ~0);
2424 	iwx_enable_interrupts(sc);
2425 }
2426 
2427 #define IWX_HW_READY_TIMEOUT 50
2428 static int
2429 iwx_set_hw_ready(struct iwx_softc *sc)
2430 {
2431 	int ready;
2432 
2433 	IWX_SETBITS(sc, IWX_CSR_HW_IF_CONFIG_REG,
2434 	    IWX_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
2435 
2436 	ready = iwx_poll_bit(sc, IWX_CSR_HW_IF_CONFIG_REG,
2437 	    IWX_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
2438 	    IWX_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
2439 	    IWX_HW_READY_TIMEOUT);
2440 	if (ready)
2441 		IWX_SETBITS(sc, IWX_CSR_MBOX_SET_REG,
2442 		    IWX_CSR_MBOX_SET_REG_OS_ALIVE);
2443 
2444 	DPRINTF(("%s: ready=%d\n", __func__, ready));
2445 	return ready;
2446 }
2447 #undef IWX_HW_READY_TIMEOUT
2448 
2449 static int
2450 iwx_prepare_card_hw(struct iwx_softc *sc)
2451 {
2452 	int t = 0;
2453 	int ntries;
2454 
2455 	if (iwx_set_hw_ready(sc))
2456 		return 0;
2457 
2458 	IWX_SETBITS(sc, IWX_CSR_DBG_LINK_PWR_MGMT_REG,
2459 	    IWX_CSR_RESET_LINK_PWR_MGMT_DISABLED);
2460 	DELAY(1000);
2461 
2462 	for (ntries = 0; ntries < 10; ntries++) {
2463 		/* If HW is not ready, prepare the conditions to check again */
2464 		IWX_SETBITS(sc, IWX_CSR_HW_IF_CONFIG_REG,
2465 		    IWX_CSR_HW_IF_CONFIG_REG_PREPARE);
2466 
2467 		do {
2468 			if (iwx_set_hw_ready(sc))
2469 				return 0;
2470 			DELAY(200);
2471 			t += 200;
2472 		} while (t < 150000);
2473 		DELAY(25000);
2474 	}
2475 
2476 	return ETIMEDOUT;
2477 }
2478 
2479 static int
2480 iwx_force_power_gating(struct iwx_softc *sc)
2481 {
2482 	int err;
2483 
2484 	err = iwx_set_bits_prph(sc, IWX_HPM_HIPM_GEN_CFG,
2485 	    IWX_HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE);
2486 	if (err)
2487 		return err;
2488 	DELAY(20);
2489 	err = iwx_set_bits_prph(sc, IWX_HPM_HIPM_GEN_CFG,
2490 	    IWX_HPM_HIPM_GEN_CFG_CR_PG_EN |
2491 	    IWX_HPM_HIPM_GEN_CFG_CR_SLP_EN);
2492 	if (err)
2493 		return err;
2494 	DELAY(20);
2495 	err = iwx_clear_bits_prph(sc, IWX_HPM_HIPM_GEN_CFG,
2496 	    IWX_HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE);
2497 	return err;
2498 }
2499 
2500 static void
2501 iwx_apm_config(struct iwx_softc *sc)
2502 {
2503 	uint16_t lctl, cap;
2504 	int pcie_ptr;
2505 	int error;
2506 
2507 	/*
2508 	 * L0S states have been found to be unstable with our devices
2509 	 * and in newer hardware they are not officially supported at
2510 	 * all, so we must always set the L0S_DISABLED bit.
2511 	 */
2512 	IWX_SETBITS(sc, IWX_CSR_GIO_REG, IWX_CSR_GIO_REG_VAL_L0S_DISABLED);
2513 
2514 	error = pci_find_cap(sc->sc_dev, PCIY_EXPRESS, &pcie_ptr);
2515 	if (error != 0) {
2516 		printf("can't fill pcie_ptr\n");
2517 		return;
2518 	}
2519 
2520 	lctl = pci_read_config(sc->sc_dev, pcie_ptr + PCIER_LINK_CTL,
2521 	    sizeof(lctl));
2522 #define PCI_PCIE_LCSR_ASPM_L0S 0x00000001
2523 	sc->sc_pm_support = !(lctl & PCI_PCIE_LCSR_ASPM_L0S);
2524 #define PCI_PCIE_DCSR2 0x28
2525 	cap = pci_read_config(sc->sc_dev, pcie_ptr + PCI_PCIE_DCSR2,
2526 	    sizeof(lctl));
2527 #define PCI_PCIE_DCSR2_LTREN 0x00000400
2528 	sc->sc_ltr_enabled = (cap & PCI_PCIE_DCSR2_LTREN) ? 1 : 0;
2529 #define PCI_PCIE_LCSR_ASPM_L1 0x00000002
2530 	DPRINTF(("%s: L1 %sabled - LTR %sabled\n",
2531 	    DEVNAME(sc),
2532 	    (lctl & PCI_PCIE_LCSR_ASPM_L1) ? "En" : "Dis",
2533 	    sc->sc_ltr_enabled ? "En" : "Dis"));
2534 #undef PCI_PCIE_LCSR_ASPM_L0S
2535 #undef PCI_PCIE_DCSR2
2536 #undef PCI_PCIE_DCSR2_LTREN
2537 #undef PCI_PCIE_LCSR_ASPM_L1
2538 }
2539 
2540 /*
2541  * Start up NIC's basic functionality after it has been reset
2542  * e.g. after platform boot or shutdown.
2543  * NOTE:  This does not load uCode nor start the embedded processor
2544  */
2545 static int
2546 iwx_apm_init(struct iwx_softc *sc)
2547 {
2548 	int err = 0;
2549 
2550 	/*
2551 	 * Disable L0s without affecting L1;
2552 	 *  don't wait for ICH L0s (ICH bug W/A)
2553 	 */
2554 	IWX_SETBITS(sc, IWX_CSR_GIO_CHICKEN_BITS,
2555 	    IWX_CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
2556 
2557 	/* Set FH wait threshold to maximum (HW error during stress W/A) */
2558 	IWX_SETBITS(sc, IWX_CSR_DBG_HPET_MEM_REG, IWX_CSR_DBG_HPET_MEM_REG_VAL);
2559 
2560 	/*
2561 	 * Enable HAP INTA (interrupt from management bus) to
2562 	 * wake device's PCI Express link L1a -> L0s
2563 	 */
2564 	IWX_SETBITS(sc, IWX_CSR_HW_IF_CONFIG_REG,
2565 	    IWX_CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
2566 
2567 	iwx_apm_config(sc);
2568 
2569 	/*
2570 	 * Set "initialization complete" bit to move adapter from
2571 	 * D0U* --> D0A* (powered-up active) state.
2572 	 */
2573 	IWX_SETBITS(sc, IWX_CSR_GP_CNTRL, IWX_CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
2574 
2575 	/*
2576 	 * Wait for clock stabilization; once stabilized, access to
2577 	 * device-internal resources is supported, e.g. iwx_write_prph()
2578 	 * and accesses to uCode SRAM.
2579 	 */
2580 	if (!iwx_poll_bit(sc, IWX_CSR_GP_CNTRL,
2581 	    IWX_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
2582 	    IWX_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000)) {
2583 		printf("%s: timeout waiting for clock stabilization\n",
2584 		    DEVNAME(sc));
2585 		err = ETIMEDOUT;
2586 		goto out;
2587 	}
2588  out:
2589 	if (err)
2590 		printf("%s: apm init error %d\n", DEVNAME(sc), err);
2591 	return err;
2592 }
2593 
2594 static void
2595 iwx_apm_stop(struct iwx_softc *sc)
2596 {
2597 	IWX_SETBITS(sc, IWX_CSR_DBG_LINK_PWR_MGMT_REG,
2598 	    IWX_CSR_RESET_LINK_PWR_MGMT_DISABLED);
2599 	IWX_SETBITS(sc, IWX_CSR_HW_IF_CONFIG_REG,
2600 	    IWX_CSR_HW_IF_CONFIG_REG_PREPARE |
2601 	    IWX_CSR_HW_IF_CONFIG_REG_ENABLE_PME);
2602 	DELAY(1000);
2603 	IWX_CLRBITS(sc, IWX_CSR_DBG_LINK_PWR_MGMT_REG,
2604 	    IWX_CSR_RESET_LINK_PWR_MGMT_DISABLED);
2605 	DELAY(5000);
2606 
2607 	/* stop device's busmaster DMA activity */
2608 	IWX_SETBITS(sc, IWX_CSR_RESET, IWX_CSR_RESET_REG_FLAG_STOP_MASTER);
2609 
2610 	if (!iwx_poll_bit(sc, IWX_CSR_RESET,
2611 	    IWX_CSR_RESET_REG_FLAG_MASTER_DISABLED,
2612 	    IWX_CSR_RESET_REG_FLAG_MASTER_DISABLED, 100))
2613 		printf("%s: timeout waiting for bus master\n", DEVNAME(sc));
2614 
2615 	/*
2616 	 * Clear "initialization complete" bit to move adapter from
2617 	 * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
2618 	 */
2619 	IWX_CLRBITS(sc, IWX_CSR_GP_CNTRL,
2620 	    IWX_CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
2621 }
2622 
2623 static void
2624 iwx_init_msix_hw(struct iwx_softc *sc)
2625 {
2626 	iwx_conf_msix_hw(sc, 0);
2627 
2628 	if (!sc->sc_msix)
2629 		return;
2630 
2631 	sc->sc_fh_init_mask = ~IWX_READ(sc, IWX_CSR_MSIX_FH_INT_MASK_AD);
2632 	sc->sc_fh_mask = sc->sc_fh_init_mask;
2633 	sc->sc_hw_init_mask = ~IWX_READ(sc, IWX_CSR_MSIX_HW_INT_MASK_AD);
2634 	sc->sc_hw_mask = sc->sc_hw_init_mask;
2635 }
2636 
2637 static void
2638 iwx_conf_msix_hw(struct iwx_softc *sc, int stopped)
2639 {
2640 	int vector = 0;
2641 
2642 	if (!sc->sc_msix) {
2643 		/* Newer chips default to MSIX. */
2644 		if (!stopped && iwx_nic_lock(sc)) {
2645 			iwx_write_umac_prph(sc, IWX_UREG_CHICK,
2646 			    IWX_UREG_CHICK_MSI_ENABLE);
2647 			iwx_nic_unlock(sc);
2648 		}
2649 		return;
2650 	}
2651 
2652 	if (!stopped && iwx_nic_lock(sc)) {
2653 		iwx_write_umac_prph(sc, IWX_UREG_CHICK,
2654 		    IWX_UREG_CHICK_MSIX_ENABLE);
2655 		iwx_nic_unlock(sc);
2656 	}
2657 
2658 	/* Disable all interrupts */
2659 	IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_MASK_AD, ~0);
2660 	IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_MASK_AD, ~0);
2661 
2662 	/* Map fallback-queue (command/mgmt) to a single vector */
2663 	IWX_WRITE_1(sc, IWX_CSR_MSIX_RX_IVAR(0),
2664 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2665 	/* Map RSS queue (data) to the same vector */
2666 	IWX_WRITE_1(sc, IWX_CSR_MSIX_RX_IVAR(1),
2667 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2668 
2669 	/* Enable the RX queues cause interrupts */
2670 	IWX_CLRBITS(sc, IWX_CSR_MSIX_FH_INT_MASK_AD,
2671 	    IWX_MSIX_FH_INT_CAUSES_Q0 | IWX_MSIX_FH_INT_CAUSES_Q1);
2672 
2673 	/* Map non-RX causes to the same vector */
2674 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_D2S_CH0_NUM),
2675 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2676 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_D2S_CH1_NUM),
2677 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2678 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_S2D),
2679 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2680 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_FH_ERR),
2681 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2682 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_ALIVE),
2683 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2684 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_WAKEUP),
2685 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2686 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_RESET_DONE),
2687 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2688 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_CT_KILL),
2689 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2690 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_RF_KILL),
2691 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2692 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_PERIODIC),
2693 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2694 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_SW_ERR),
2695 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2696 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_SCD),
2697 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2698 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_FH_TX),
2699 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2700 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_HW_ERR),
2701 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2702 	IWX_WRITE_1(sc, IWX_CSR_MSIX_IVAR(IWX_MSIX_IVAR_CAUSE_REG_HAP),
2703 	    vector | IWX_MSIX_NON_AUTO_CLEAR_CAUSE);
2704 
2705 	/* Enable non-RX causes interrupts */
2706 	IWX_CLRBITS(sc, IWX_CSR_MSIX_FH_INT_MASK_AD,
2707 	    IWX_MSIX_FH_INT_CAUSES_D2S_CH0_NUM |
2708 	    IWX_MSIX_FH_INT_CAUSES_D2S_CH1_NUM |
2709 	    IWX_MSIX_FH_INT_CAUSES_S2D |
2710 	    IWX_MSIX_FH_INT_CAUSES_FH_ERR);
2711 	IWX_CLRBITS(sc, IWX_CSR_MSIX_HW_INT_MASK_AD,
2712 	    IWX_MSIX_HW_INT_CAUSES_REG_ALIVE |
2713 	    IWX_MSIX_HW_INT_CAUSES_REG_WAKEUP |
2714 	    IWX_MSIX_HW_INT_CAUSES_REG_RESET_DONE |
2715 	    IWX_MSIX_HW_INT_CAUSES_REG_CT_KILL |
2716 	    IWX_MSIX_HW_INT_CAUSES_REG_RF_KILL |
2717 	    IWX_MSIX_HW_INT_CAUSES_REG_PERIODIC |
2718 	    IWX_MSIX_HW_INT_CAUSES_REG_SW_ERR |
2719 	    IWX_MSIX_HW_INT_CAUSES_REG_SCD |
2720 	    IWX_MSIX_HW_INT_CAUSES_REG_FH_TX |
2721 	    IWX_MSIX_HW_INT_CAUSES_REG_HW_ERR |
2722 	    IWX_MSIX_HW_INT_CAUSES_REG_HAP);
2723 }
2724 
2725 static int
2726 iwx_clear_persistence_bit(struct iwx_softc *sc)
2727 {
2728 	uint32_t hpm, wprot;
2729 
2730 	hpm = iwx_read_prph_unlocked(sc, IWX_HPM_DEBUG);
2731 	if (hpm != 0xa5a5a5a0 && (hpm & IWX_PERSISTENCE_BIT)) {
2732 		wprot = iwx_read_prph_unlocked(sc, IWX_PREG_PRPH_WPROT_22000);
2733 		if (wprot & IWX_PREG_WFPM_ACCESS) {
2734 			printf("%s: cannot clear persistence bit\n",
2735 			    DEVNAME(sc));
2736 			return EPERM;
2737 		}
2738 		iwx_write_prph_unlocked(sc, IWX_HPM_DEBUG,
2739 		    hpm & ~IWX_PERSISTENCE_BIT);
2740 	}
2741 
2742 	return 0;
2743 }
2744 
2745 static int
2746 iwx_start_hw(struct iwx_softc *sc)
2747 {
2748 	int err;
2749 
2750 	err = iwx_prepare_card_hw(sc);
2751 	if (err)
2752 		return err;
2753 
2754 	if (sc->sc_device_family == IWX_DEVICE_FAMILY_22000) {
2755 		err = iwx_clear_persistence_bit(sc);
2756 		if (err)
2757 			return err;
2758 	}
2759 
2760 	/* Reset the entire device */
2761 	IWX_SETBITS(sc, IWX_CSR_RESET, IWX_CSR_RESET_REG_FLAG_SW_RESET);
2762 	DELAY(5000);
2763 
2764 	if (sc->sc_device_family == IWX_DEVICE_FAMILY_22000 &&
2765 	    sc->sc_integrated) {
2766 		IWX_SETBITS(sc, IWX_CSR_GP_CNTRL,
2767 		    IWX_CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
2768 		DELAY(20);
2769 		if (!iwx_poll_bit(sc, IWX_CSR_GP_CNTRL,
2770 		    IWX_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
2771 		    IWX_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000)) {
2772 			printf("%s: timeout waiting for clock stabilization\n",
2773 			    DEVNAME(sc));
2774 			return ETIMEDOUT;
2775 		}
2776 
2777 		err = iwx_force_power_gating(sc);
2778 		if (err)
2779 			return err;
2780 
2781 		/* Reset the entire device */
2782 		IWX_SETBITS(sc, IWX_CSR_RESET, IWX_CSR_RESET_REG_FLAG_SW_RESET);
2783 		DELAY(5000);
2784 	}
2785 
2786 	err = iwx_apm_init(sc);
2787 	if (err)
2788 		return err;
2789 
2790 	iwx_init_msix_hw(sc);
2791 
2792 	iwx_enable_rfkill_int(sc);
2793 	iwx_check_rfkill(sc);
2794 
2795 	return 0;
2796 }
2797 
2798 static void
2799 iwx_stop_device(struct iwx_softc *sc)
2800 {
2801 	int i;
2802 
2803 	iwx_disable_interrupts(sc);
2804 	sc->sc_flags &= ~IWX_FLAG_USE_ICT;
2805 
2806 	iwx_disable_rx_dma(sc);
2807 	iwx_reset_rx_ring(sc, &sc->rxq);
2808 	for (i = 0; i < nitems(sc->txq); i++)
2809 		iwx_reset_tx_ring(sc, &sc->txq[i]);
2810 #if 0
2811 	/* XXX-THJ: Tidy up BA state on stop */
2812 	for (i = 0; i < IEEE80211_NUM_TID; i++) {
2813 		struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[i];
2814 		if (ba->ba_state != IEEE80211_BA_AGREED)
2815 			continue;
2816 		ieee80211_delba_request(ic, ni, 0, 1, i);
2817 	}
2818 #endif
2819 	/* Make sure (redundant) we've released our request to stay awake */
2820 	IWX_CLRBITS(sc, IWX_CSR_GP_CNTRL,
2821 	    IWX_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
2822 	if (sc->sc_nic_locks > 0)
2823 		printf("%s: %d active NIC locks forcefully cleared\n",
2824 		    DEVNAME(sc), sc->sc_nic_locks);
2825 	sc->sc_nic_locks = 0;
2826 
2827 	/* Stop the device, and put it in low power state */
2828 	iwx_apm_stop(sc);
2829 
2830 	/* Reset the on-board processor. */
2831 	IWX_SETBITS(sc, IWX_CSR_RESET, IWX_CSR_RESET_REG_FLAG_SW_RESET);
2832 	DELAY(5000);
2833 
2834 	/*
2835 	 * Upon stop, the IVAR table gets erased, so msi-x won't
2836 	 * work. This causes a bug in RF-KILL flows, since the interrupt
2837 	 * that enables radio won't fire on the correct irq, and the
2838 	 * driver won't be able to handle the interrupt.
2839 	 * Configure the IVAR table again after reset.
2840 	 */
2841 	iwx_conf_msix_hw(sc, 1);
2842 
2843 	/*
2844 	 * Upon stop, the APM issues an interrupt if HW RF kill is set.
2845 	 * Clear the interrupt again.
2846 	 */
2847 	iwx_disable_interrupts(sc);
2848 
2849 	/* Even though we stop the HW we still want the RF kill interrupt. */
2850 	iwx_enable_rfkill_int(sc);
2851 	iwx_check_rfkill(sc);
2852 
2853 	iwx_prepare_card_hw(sc);
2854 
2855 	iwx_ctxt_info_free_paging(sc);
2856 	iwx_dma_contig_free(&sc->pnvm_dma);
2857 }
2858 
2859 static void
2860 iwx_nic_config(struct iwx_softc *sc)
2861 {
2862 	uint8_t radio_cfg_type, radio_cfg_step, radio_cfg_dash;
2863 	uint32_t mask, val, reg_val = 0;
2864 
2865 	radio_cfg_type = (sc->sc_fw_phy_config & IWX_FW_PHY_CFG_RADIO_TYPE) >>
2866 	    IWX_FW_PHY_CFG_RADIO_TYPE_POS;
2867 	radio_cfg_step = (sc->sc_fw_phy_config & IWX_FW_PHY_CFG_RADIO_STEP) >>
2868 	    IWX_FW_PHY_CFG_RADIO_STEP_POS;
2869 	radio_cfg_dash = (sc->sc_fw_phy_config & IWX_FW_PHY_CFG_RADIO_DASH) >>
2870 	    IWX_FW_PHY_CFG_RADIO_DASH_POS;
2871 
2872 	reg_val |= IWX_CSR_HW_REV_STEP(sc->sc_hw_rev) <<
2873 	    IWX_CSR_HW_IF_CONFIG_REG_POS_MAC_STEP;
2874 	reg_val |= IWX_CSR_HW_REV_DASH(sc->sc_hw_rev) <<
2875 	    IWX_CSR_HW_IF_CONFIG_REG_POS_MAC_DASH;
2876 
2877 	/* radio configuration */
2878 	reg_val |= radio_cfg_type << IWX_CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE;
2879 	reg_val |= radio_cfg_step << IWX_CSR_HW_IF_CONFIG_REG_POS_PHY_STEP;
2880 	reg_val |= radio_cfg_dash << IWX_CSR_HW_IF_CONFIG_REG_POS_PHY_DASH;
2881 
2882 	mask = IWX_CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
2883 	    IWX_CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP |
2884 	    IWX_CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP |
2885 	    IWX_CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH |
2886 	    IWX_CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE |
2887 	    IWX_CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
2888 	    IWX_CSR_HW_IF_CONFIG_REG_BIT_MAC_SI;
2889 
2890 	val = IWX_READ(sc, IWX_CSR_HW_IF_CONFIG_REG);
2891 	val &= ~mask;
2892 	val |= reg_val;
2893 	IWX_WRITE(sc, IWX_CSR_HW_IF_CONFIG_REG, val);
2894 }
2895 
2896 static int
2897 iwx_nic_rx_init(struct iwx_softc *sc)
2898 {
2899 	IWX_WRITE_1(sc, IWX_CSR_INT_COALESCING, IWX_HOST_INT_TIMEOUT_DEF);
2900 
2901 	/*
2902 	 * We don't configure the RFH; the firmware will do that.
2903 	 * Rx descriptors are set when firmware sends an ALIVE interrupt.
2904 	 */
2905 	return 0;
2906 }
2907 
2908 static int
2909 iwx_nic_init(struct iwx_softc *sc)
2910 {
2911 	int err;
2912 
2913 	iwx_apm_init(sc);
2914 	if (sc->sc_device_family < IWX_DEVICE_FAMILY_AX210)
2915 		iwx_nic_config(sc);
2916 
2917 	err = iwx_nic_rx_init(sc);
2918 	if (err)
2919 		return err;
2920 
2921 	IWX_SETBITS(sc, IWX_CSR_MAC_SHADOW_REG_CTRL, 0x800fffff);
2922 
2923 	return 0;
2924 }
2925 
2926 /* Map ieee80211_edca_ac categories to firmware Tx FIFO. */
2927 const uint8_t iwx_ac_to_tx_fifo[] = {
2928 	IWX_GEN2_EDCA_TX_FIFO_BE,
2929 	IWX_GEN2_EDCA_TX_FIFO_BK,
2930 	IWX_GEN2_EDCA_TX_FIFO_VI,
2931 	IWX_GEN2_EDCA_TX_FIFO_VO,
2932 };
2933 
2934 static int
2935 iwx_enable_txq(struct iwx_softc *sc, int sta_id, int qid, int tid,
2936     int num_slots)
2937 {
2938 	struct iwx_rx_packet *pkt;
2939 	struct iwx_tx_queue_cfg_rsp *resp;
2940 	struct iwx_tx_queue_cfg_cmd cmd_v0;
2941 	struct iwx_scd_queue_cfg_cmd cmd_v3;
2942 	struct iwx_host_cmd hcmd = {
2943 		.flags = IWX_CMD_WANT_RESP,
2944 		.resp_pkt_len = sizeof(*pkt) + sizeof(*resp),
2945 	};
2946 	struct iwx_tx_ring *ring = &sc->txq[qid];
2947 	int err, fwqid, cmd_ver;
2948 	uint32_t wr_idx;
2949 	size_t resp_len;
2950 
2951 	DPRINTF(("%s: tid=%i\n", __func__, tid));
2952 	DPRINTF(("%s: qid=%i\n", __func__, qid));
2953 	iwx_reset_tx_ring(sc, ring);
2954 
2955 	cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
2956 	    IWX_SCD_QUEUE_CONFIG_CMD);
2957 	if (cmd_ver == 0 || cmd_ver == IWX_FW_CMD_VER_UNKNOWN) {
2958 		memset(&cmd_v0, 0, sizeof(cmd_v0));
2959 		cmd_v0.sta_id = sta_id;
2960 		cmd_v0.tid = tid;
2961 		cmd_v0.flags = htole16(IWX_TX_QUEUE_CFG_ENABLE_QUEUE);
2962 		cmd_v0.cb_size = htole32(IWX_TFD_QUEUE_CB_SIZE(num_slots));
2963 		cmd_v0.byte_cnt_addr = htole64(ring->bc_tbl.paddr);
2964 		cmd_v0.tfdq_addr = htole64(ring->desc_dma.paddr);
2965 		hcmd.id = IWX_SCD_QUEUE_CFG;
2966 		hcmd.data[0] = &cmd_v0;
2967 		hcmd.len[0] = sizeof(cmd_v0);
2968 	} else if (cmd_ver == 3) {
2969 		memset(&cmd_v3, 0, sizeof(cmd_v3));
2970 		cmd_v3.operation = htole32(IWX_SCD_QUEUE_ADD);
2971 		cmd_v3.u.add.tfdq_dram_addr = htole64(ring->desc_dma.paddr);
2972 		cmd_v3.u.add.bc_dram_addr = htole64(ring->bc_tbl.paddr);
2973 		cmd_v3.u.add.cb_size = htole32(IWX_TFD_QUEUE_CB_SIZE(num_slots));
2974 		cmd_v3.u.add.flags = htole32(0);
2975 		cmd_v3.u.add.sta_mask = htole32(1 << sta_id);
2976 		cmd_v3.u.add.tid = tid;
2977 		hcmd.id = IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
2978 		    IWX_SCD_QUEUE_CONFIG_CMD);
2979 		hcmd.data[0] = &cmd_v3;
2980 		hcmd.len[0] = sizeof(cmd_v3);
2981 	} else {
2982 		printf("%s: unsupported SCD_QUEUE_CFG command version %d\n",
2983 		    DEVNAME(sc), cmd_ver);
2984 		return ENOTSUP;
2985 	}
2986 
2987 	err = iwx_send_cmd(sc, &hcmd);
2988 	if (err)
2989 		return err;
2990 
2991 	pkt = hcmd.resp_pkt;
2992 	if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) {
2993 		err = EIO;
2994 		goto out;
2995 	}
2996 
2997 	resp_len = iwx_rx_packet_payload_len(pkt);
2998 	if (resp_len != sizeof(*resp)) {
2999 		err = EIO;
3000 		goto out;
3001 	}
3002 
3003 	resp = (void *)pkt->data;
3004 	fwqid = le16toh(resp->queue_number);
3005 	wr_idx = le16toh(resp->write_pointer);
3006 
3007 	/* Unlike iwlwifi, we do not support dynamic queue ID assignment. */
3008 	if (fwqid != qid) {
3009 		DPRINTF(("%s: === fwqid != qid\n", __func__));
3010 		err = EIO;
3011 		goto out;
3012 	}
3013 
3014 	if (wr_idx != ring->cur_hw) {
3015 		DPRINTF(("%s: === (wr_idx != ring->cur_hw)\n", __func__));
3016 		err = EIO;
3017 		goto out;
3018 	}
3019 
3020 	sc->qenablemsk |= (1 << qid);
3021 	ring->tid = tid;
3022 out:
3023 	iwx_free_resp(sc, &hcmd);
3024 	return err;
3025 }
3026 
3027 static int
3028 iwx_disable_txq(struct iwx_softc *sc, int sta_id, int qid, uint8_t tid)
3029 {
3030 	struct iwx_rx_packet *pkt;
3031 	struct iwx_tx_queue_cfg_rsp *resp;
3032 	struct iwx_tx_queue_cfg_cmd cmd_v0;
3033 	struct iwx_scd_queue_cfg_cmd cmd_v3;
3034 	struct iwx_host_cmd hcmd = {
3035 		.flags = IWX_CMD_WANT_RESP,
3036 		.resp_pkt_len = sizeof(*pkt) + sizeof(*resp),
3037 	};
3038 	struct iwx_tx_ring *ring = &sc->txq[qid];
3039 	int err, cmd_ver;
3040 
3041 	cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
3042 	    IWX_SCD_QUEUE_CONFIG_CMD);
3043 	if (cmd_ver == 0 || cmd_ver == IWX_FW_CMD_VER_UNKNOWN) {
3044 		memset(&cmd_v0, 0, sizeof(cmd_v0));
3045 		cmd_v0.sta_id = sta_id;
3046 		cmd_v0.tid = tid;
3047 		cmd_v0.flags = htole16(0); /* clear "queue enabled" flag */
3048 		cmd_v0.cb_size = htole32(0);
3049 		cmd_v0.byte_cnt_addr = htole64(0);
3050 		cmd_v0.tfdq_addr = htole64(0);
3051 		hcmd.id = IWX_SCD_QUEUE_CFG;
3052 		hcmd.data[0] = &cmd_v0;
3053 		hcmd.len[0] = sizeof(cmd_v0);
3054 	} else if (cmd_ver == 3) {
3055 		memset(&cmd_v3, 0, sizeof(cmd_v3));
3056 		cmd_v3.operation = htole32(IWX_SCD_QUEUE_REMOVE);
3057 		cmd_v3.u.remove.sta_mask = htole32(1 << sta_id);
3058 		cmd_v3.u.remove.tid = tid;
3059 		hcmd.id = IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
3060 		    IWX_SCD_QUEUE_CONFIG_CMD);
3061 		hcmd.data[0] = &cmd_v3;
3062 		hcmd.len[0] = sizeof(cmd_v3);
3063 	} else {
3064 		printf("%s: unsupported SCD_QUEUE_CFG command version %d\n",
3065 		    DEVNAME(sc), cmd_ver);
3066 		return ENOTSUP;
3067 	}
3068 
3069 	err = iwx_send_cmd(sc, &hcmd);
3070 	if (err)
3071 		return err;
3072 
3073 	pkt = hcmd.resp_pkt;
3074 	if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) {
3075 		err = EIO;
3076 		goto out;
3077 	}
3078 
3079 	sc->qenablemsk &= ~(1 << qid);
3080 	iwx_reset_tx_ring(sc, ring);
3081 out:
3082 	iwx_free_resp(sc, &hcmd);
3083 	return err;
3084 }
3085 
3086 static void
3087 iwx_post_alive(struct iwx_softc *sc)
3088 {
3089 	int txcmd_ver;
3090 
3091 	iwx_ict_reset(sc);
3092 
3093 	txcmd_ver = iwx_lookup_notif_ver(sc, IWX_LONG_GROUP, IWX_TX_CMD) ;
3094 	if (txcmd_ver != IWX_FW_CMD_VER_UNKNOWN && txcmd_ver > 6)
3095 		sc->sc_rate_n_flags_version = 2;
3096 	else
3097 		sc->sc_rate_n_flags_version = 1;
3098 
3099 	txcmd_ver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_TX_CMD);
3100 }
3101 
3102 static int
3103 iwx_schedule_session_protection(struct iwx_softc *sc, struct iwx_node *in,
3104     uint32_t duration_tu)
3105 {
3106 
3107 	struct iwx_session_prot_cmd cmd = {
3108 		.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id,
3109 		    in->in_color)),
3110 		.action = htole32(IWX_FW_CTXT_ACTION_ADD),
3111 		.conf_id = htole32(IWX_SESSION_PROTECT_CONF_ASSOC),
3112 		.duration_tu = htole32(duration_tu),
3113 	};
3114 	uint32_t cmd_id;
3115 	int err;
3116 
3117 	cmd_id = iwx_cmd_id(IWX_SESSION_PROTECTION_CMD, IWX_MAC_CONF_GROUP, 0);
3118 	err = iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd);
3119 	if (!err)
3120 		sc->sc_flags |= IWX_FLAG_TE_ACTIVE;
3121 	return err;
3122 }
3123 
3124 static void
3125 iwx_unprotect_session(struct iwx_softc *sc, struct iwx_node *in)
3126 {
3127 	struct iwx_session_prot_cmd cmd = {
3128 		.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id,
3129 		    in->in_color)),
3130 		.action = htole32(IWX_FW_CTXT_ACTION_REMOVE),
3131 		.conf_id = htole32(IWX_SESSION_PROTECT_CONF_ASSOC),
3132 		.duration_tu = 0,
3133 	};
3134 	uint32_t cmd_id;
3135 
3136 	/* Do nothing if the time event has already ended. */
3137 	if ((sc->sc_flags & IWX_FLAG_TE_ACTIVE) == 0)
3138 		return;
3139 
3140 	cmd_id = iwx_cmd_id(IWX_SESSION_PROTECTION_CMD, IWX_MAC_CONF_GROUP, 0);
3141 	if (iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd) == 0)
3142 		sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE;
3143 }
3144 
3145 /*
3146  * NVM read access and content parsing.  We do not support
3147  * external NVM or writing NVM.
3148  */
3149 
3150 static uint8_t
3151 iwx_fw_valid_tx_ant(struct iwx_softc *sc)
3152 {
3153 	uint8_t tx_ant;
3154 
3155 	tx_ant = ((sc->sc_fw_phy_config & IWX_FW_PHY_CFG_TX_CHAIN)
3156 	    >> IWX_FW_PHY_CFG_TX_CHAIN_POS);
3157 
3158 	if (sc->sc_nvm.valid_tx_ant)
3159 		tx_ant &= sc->sc_nvm.valid_tx_ant;
3160 
3161 	return tx_ant;
3162 }
3163 
3164 static uint8_t
3165 iwx_fw_valid_rx_ant(struct iwx_softc *sc)
3166 {
3167 	uint8_t rx_ant;
3168 
3169 	rx_ant = ((sc->sc_fw_phy_config & IWX_FW_PHY_CFG_RX_CHAIN)
3170 	    >> IWX_FW_PHY_CFG_RX_CHAIN_POS);
3171 
3172 	if (sc->sc_nvm.valid_rx_ant)
3173 		rx_ant &= sc->sc_nvm.valid_rx_ant;
3174 
3175 	return rx_ant;
3176 }
3177 
3178 static void
3179 iwx_init_channel_map(struct ieee80211com *ic, int maxchans, int *nchans,
3180     struct ieee80211_channel chans[])
3181 {
3182 	struct iwx_softc *sc = ic->ic_softc;
3183 	struct iwx_nvm_data *data = &sc->sc_nvm;
3184 	uint8_t bands[IEEE80211_MODE_BYTES];
3185 	const uint8_t *nvm_channels;
3186 	uint32_t ch_flags;
3187 	int ch_idx, nchan;
3188 
3189 	if (sc->sc_uhb_supported) {
3190 		nchan = nitems(iwx_nvm_channels_uhb);
3191 		nvm_channels = iwx_nvm_channels_uhb;
3192 	} else {
3193 		nchan = nitems(iwx_nvm_channels_8000);
3194 		nvm_channels = iwx_nvm_channels_8000;
3195 	}
3196 
3197 	/* 2.4Ghz; 1-13: 11b/g channels. */
3198 	if (!data->sku_cap_band_24GHz_enable)
3199 		goto band_5;
3200 
3201 	memset(bands, 0, sizeof(bands));
3202 	setbit(bands, IEEE80211_MODE_11B);
3203 	setbit(bands, IEEE80211_MODE_11G);
3204 	setbit(bands, IEEE80211_MODE_11NG);
3205 	for (ch_idx = 0;
3206 	    ch_idx < IWX_NUM_2GHZ_CHANNELS && ch_idx < nchan;
3207 	    ch_idx++) {
3208 
3209 		uint32_t nflags = 0;
3210 		int cflags = 0;
3211 
3212 		if (sc->sc_rsp_vers == IWX_FBSD_RSP_V4) {
3213 			ch_flags = le32_to_cpup(
3214 			    sc->sc_rsp_info.rsp_v4.regulatory.channel_profile + ch_idx);
3215 		} else {
3216 			ch_flags = le16_to_cpup(
3217 			    sc->sc_rsp_info.rsp_v3.regulatory.channel_profile + ch_idx);
3218 		}
3219 		if ((ch_flags & IWX_NVM_CHANNEL_VALID) == 0)
3220 			continue;
3221 
3222 	          if ((ch_flags & IWX_NVM_CHANNEL_40MHZ) != 0)
3223                   cflags |= NET80211_CBW_FLAG_HT40;
3224 
3225 		/* XXX-BZ nflags RADAR/DFS/INDOOR */
3226 
3227 		/* error = */ ieee80211_add_channel_cbw(chans, maxchans, nchans,
3228 		nvm_channels[ch_idx],
3229 		ieee80211_ieee2mhz(nvm_channels[ch_idx], IEEE80211_CHAN_B),
3230 		/* max_power IWL_DEFAULT_MAX_TX_POWER */ 22,
3231 		nflags, bands, cflags);
3232 	}
3233 
3234 band_5:
3235 	/* 5Ghz */
3236 	if (!data->sku_cap_band_52GHz_enable)
3237 		goto band_6;
3238 
3239 
3240 	memset(bands, 0, sizeof(bands));
3241 	setbit(bands, IEEE80211_MODE_11A);
3242 	setbit(bands, IEEE80211_MODE_11NA);
3243 	setbit(bands, IEEE80211_MODE_VHT_5GHZ);
3244 
3245 	for (ch_idx = IWX_NUM_2GHZ_CHANNELS;
3246 	    ch_idx < (IWX_NUM_2GHZ_CHANNELS + IWX_NUM_5GHZ_CHANNELS) && ch_idx < nchan;
3247 	    ch_idx++) {
3248 		uint32_t nflags = 0;
3249 		int cflags = 0;
3250 
3251 		if (sc->sc_rsp_vers == IWX_FBSD_RSP_V4)
3252 			ch_flags = le32_to_cpup(
3253 			    sc->sc_rsp_info.rsp_v4.regulatory.channel_profile + ch_idx);
3254 		else
3255 			ch_flags = le16_to_cpup(
3256 			    sc->sc_rsp_info.rsp_v3.regulatory.channel_profile + ch_idx);
3257 
3258 		if ((ch_flags & IWX_NVM_CHANNEL_VALID) == 0)
3259 		continue;
3260 
3261 		if ((ch_flags & IWX_NVM_CHANNEL_40MHZ) != 0)
3262 			cflags |= NET80211_CBW_FLAG_HT40;
3263 		if ((ch_flags & IWX_NVM_CHANNEL_80MHZ) != 0)
3264 			cflags |= NET80211_CBW_FLAG_VHT80;
3265 		if ((ch_flags & IWX_NVM_CHANNEL_160MHZ) != 0)
3266 			cflags |= NET80211_CBW_FLAG_VHT160;
3267 
3268 		/* XXX-BZ nflags RADAR/DFS/INDOOR */
3269 
3270 		/* error = */ ieee80211_add_channel_cbw(chans, maxchans, nchans,
3271 		nvm_channels[ch_idx],
3272 		ieee80211_ieee2mhz(nvm_channels[ch_idx], IEEE80211_CHAN_A),
3273 		/* max_power IWL_DEFAULT_MAX_TX_POWER */ 22,
3274 		nflags, bands, cflags);
3275 	}
3276 band_6:
3277 	/* 6GHz one day ... */
3278 	return;
3279 }
3280 
3281 static int
3282 iwx_mimo_enabled(struct iwx_softc *sc)
3283 {
3284 
3285 	return !sc->sc_nvm.sku_cap_mimo_disable;
3286 }
3287 
3288 static void
3289 iwx_init_reorder_buffer(struct iwx_reorder_buffer *reorder_buf,
3290     uint16_t ssn, uint16_t buf_size)
3291 {
3292 	reorder_buf->head_sn = ssn;
3293 	reorder_buf->num_stored = 0;
3294 	reorder_buf->buf_size = buf_size;
3295 	reorder_buf->last_amsdu = 0;
3296 	reorder_buf->last_sub_index = 0;
3297 	reorder_buf->removed = 0;
3298 	reorder_buf->valid = 0;
3299 	reorder_buf->consec_oldsn_drops = 0;
3300 	reorder_buf->consec_oldsn_ampdu_gp2 = 0;
3301 	reorder_buf->consec_oldsn_prev_drop = 0;
3302 }
3303 
3304 static void
3305 iwx_clear_reorder_buffer(struct iwx_softc *sc, struct iwx_rxba_data *rxba)
3306 {
3307 	struct iwx_reorder_buffer *reorder_buf = &rxba->reorder_buf;
3308 
3309 	reorder_buf->removed = 1;
3310 	rxba->baid = IWX_RX_REORDER_DATA_INVALID_BAID;
3311 }
3312 
3313 #define IWX_MAX_RX_BA_SESSIONS 16
3314 
3315 static struct iwx_rxba_data *
3316 iwx_find_rxba_data(struct iwx_softc *sc, uint8_t tid)
3317 {
3318 	int i;
3319 
3320 	for (i = 0; i < nitems(sc->sc_rxba_data); i++) {
3321 		if (sc->sc_rxba_data[i].baid ==
3322 		    IWX_RX_REORDER_DATA_INVALID_BAID)
3323 			continue;
3324 		if (sc->sc_rxba_data[i].tid == tid)
3325 			return &sc->sc_rxba_data[i];
3326 	}
3327 
3328 	return NULL;
3329 }
3330 
3331 static int
3332 iwx_sta_rx_agg_baid_cfg_cmd(struct iwx_softc *sc, struct ieee80211_node *ni,
3333     uint8_t tid, uint16_t ssn, uint16_t winsize, int timeout_val, int start,
3334     uint8_t *baid)
3335 {
3336 	struct iwx_rx_baid_cfg_cmd cmd;
3337 	uint32_t new_baid = 0;
3338 	int err;
3339 
3340 	IWX_ASSERT_LOCKED(sc);
3341 
3342 	memset(&cmd, 0, sizeof(cmd));
3343 
3344 	if (start) {
3345 		cmd.action = IWX_RX_BAID_ACTION_ADD;
3346 		cmd.alloc.sta_id_mask = htole32(1 << IWX_STATION_ID);
3347 		cmd.alloc.tid = tid;
3348 		cmd.alloc.ssn = htole16(ssn);
3349 		cmd.alloc.win_size = htole16(winsize);
3350 	} else {
3351 		struct iwx_rxba_data *rxba;
3352 
3353 		rxba = iwx_find_rxba_data(sc, tid);
3354 		if (rxba == NULL)
3355 			return ENOENT;
3356 		*baid = rxba->baid;
3357 
3358 		cmd.action = IWX_RX_BAID_ACTION_REMOVE;
3359 		if (iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
3360 		    IWX_RX_BAID_ALLOCATION_CONFIG_CMD) == 1) {
3361 			cmd.remove_v1.baid = rxba->baid;
3362 		} else {
3363 			cmd.remove.sta_id_mask = htole32(1 << IWX_STATION_ID);
3364 			cmd.remove.tid = tid;
3365 		}
3366 	}
3367 
3368 	err = iwx_send_cmd_pdu_status(sc, IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
3369 	    IWX_RX_BAID_ALLOCATION_CONFIG_CMD), sizeof(cmd), &cmd, &new_baid);
3370 	if (err)
3371 		return err;
3372 
3373 	if (start) {
3374 		if (new_baid >= nitems(sc->sc_rxba_data))
3375 			return ERANGE;
3376 		*baid = new_baid;
3377 	}
3378 
3379 	return 0;
3380 }
3381 
3382 static void
3383 iwx_sta_rx_agg(struct iwx_softc *sc, struct ieee80211_node *ni, uint8_t tid,
3384     uint16_t ssn, uint16_t winsize, int timeout_val, int start)
3385 {
3386 	int err;
3387 	struct iwx_rxba_data *rxba = NULL;
3388 	uint8_t baid = 0;
3389 
3390 	if (start && sc->sc_rx_ba_sessions >= IWX_MAX_RX_BA_SESSIONS) {
3391 		return;
3392 	}
3393 
3394 	if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_BAID_ML_SUPPORT)) {
3395 		err = iwx_sta_rx_agg_baid_cfg_cmd(sc, ni, tid, ssn, winsize,
3396 		    timeout_val, start, &baid);
3397 	} else {
3398 		panic("sta_rx_agg unsupported hw");
3399 	}
3400 	if (err) {
3401 		DPRINTF(("%s: iwx_sta_rx_agg_sta err=%i\n", __func__, err));
3402 		return;
3403 	} else
3404 		DPRINTF(("%s: iwx_sta_rx_agg_sta success\n", __func__));
3405 
3406 	rxba = &sc->sc_rxba_data[baid];
3407 
3408 	/* Deaggregation is done in hardware. */
3409 	if (start) {
3410 		if (rxba->baid != IWX_RX_REORDER_DATA_INVALID_BAID) {
3411 			return;
3412 		}
3413 		rxba->sta_id = IWX_STATION_ID;
3414 		rxba->tid = tid;
3415 		rxba->baid = baid;
3416 		rxba->timeout = timeout_val;
3417 		getmicrouptime(&rxba->last_rx);
3418 		iwx_init_reorder_buffer(&rxba->reorder_buf, ssn,
3419 		    winsize);
3420 		if (timeout_val != 0) {
3421 			DPRINTF(("%s: timeout_val != 0\n", __func__));
3422 			return;
3423 		}
3424 	} else
3425 		iwx_clear_reorder_buffer(sc, rxba);
3426 
3427 	if (start) {
3428 		sc->sc_rx_ba_sessions++;
3429 	} else if (sc->sc_rx_ba_sessions > 0)
3430 		sc->sc_rx_ba_sessions--;
3431 }
3432 
3433 /**
3434  * @brief Allocate an A-MPDU / aggregation session for the given node and TID.
3435  *
3436  * This allocates a TX queue specifically for that TID.
3437  *
3438  * Note that this routine currently doesn't return any status/errors,
3439  * so the caller can't know if the aggregation session was setup or not.
3440  */
3441 static void
3442 iwx_sta_tx_agg_start(struct iwx_softc *sc, struct ieee80211_node *ni,
3443     uint8_t tid)
3444 {
3445 	int err, qid;
3446 
3447 	qid = sc->aggqid[tid];
3448 	if (qid == 0) {
3449 		/* Firmware should pick the next unused Tx queue. */
3450 		qid = fls(sc->qenablemsk);
3451 	}
3452 
3453 	DPRINTF(("%s: qid=%i\n", __func__, qid));
3454 
3455 	/*
3456 	 * Simply enable the queue.
3457 	 * Firmware handles Tx Ba session setup and teardown.
3458 	 */
3459 	if ((sc->qenablemsk & (1 << qid)) == 0) {
3460 		if (!iwx_nic_lock(sc)) {
3461 			return;
3462 		}
3463 		err = iwx_enable_txq(sc, IWX_STATION_ID, qid, tid,
3464 		    IWX_TX_RING_COUNT);
3465 		iwx_nic_unlock(sc);
3466 		if (err) {
3467 			printf("%s: could not enable Tx queue %d "
3468 			    "(error %d)\n", DEVNAME(sc), qid, err);
3469 			return;
3470 		}
3471 	}
3472 	ni->ni_tx_ampdu[tid].txa_flags = IEEE80211_AGGR_RUNNING;
3473 	DPRINTF(("%s: will set sc->aggqid[%i]=%i\n", __func__, tid, qid));
3474 	sc->aggqid[tid] = qid;
3475 }
3476 
3477 static void
3478 iwx_ba_rx_task(void *arg, int npending __unused)
3479 {
3480 	struct iwx_softc *sc = arg;
3481 	struct ieee80211com *ic = &sc->sc_ic;
3482 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
3483 	struct ieee80211_node *ni = vap->iv_bss;
3484 	int tid;
3485 
3486 	IWX_LOCK(sc);
3487 	for (tid = 0; tid < IWX_MAX_TID_COUNT; tid++) {
3488 		if (sc->sc_flags & IWX_FLAG_SHUTDOWN)
3489 			break;
3490 		if (sc->ba_rx.start_tidmask & (1 << tid)) {
3491 			struct iwx_rx_ba *ba = &sc->ni_rx_ba[tid];
3492 			DPRINTF(("%s: ba->ba_flags=%x\n", __func__,
3493 			    ba->ba_flags));
3494 			if (ba->ba_flags == IWX_BA_DONE) {
3495 				DPRINTF(("%s: ampdu for tid %i already added\n",
3496 				    __func__, tid));
3497 				break;
3498 			}
3499 
3500 			DPRINTF(("%s: ampdu rx start for tid %i\n", __func__,
3501 			    tid));
3502 			iwx_sta_rx_agg(sc, ni, tid, ba->ba_winstart,
3503 			    ba->ba_winsize, ba->ba_timeout_val, 1);
3504 			sc->ba_rx.start_tidmask &= ~(1 << tid);
3505 			ba->ba_flags = IWX_BA_DONE;
3506 		} else if (sc->ba_rx.stop_tidmask & (1 << tid)) {
3507 			iwx_sta_rx_agg(sc, ni, tid, 0, 0, 0, 0);
3508 			sc->ba_rx.stop_tidmask &= ~(1 << tid);
3509 		}
3510 	}
3511 	IWX_UNLOCK(sc);
3512 }
3513 
3514 /**
3515  * @brief Task called to setup a deferred block-ack session.
3516  *
3517  * This sets up any/all pending blockack sessions as defined
3518  * in sc->ba_tx.start_tidmask.
3519  *
3520  * Note: the call to iwx_sta_tx_agg_start() isn't being error checked.
3521  */
3522 static void
3523 iwx_ba_tx_task(void *arg, int npending __unused)
3524 {
3525 	struct iwx_softc *sc = arg;
3526 	struct ieee80211com *ic = &sc->sc_ic;
3527 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
3528 	struct ieee80211_node *ni = vap->iv_bss;
3529 	uint32_t started_mask = 0;
3530 	int tid;
3531 
3532 	IWX_LOCK(sc);
3533 	for (tid = 0; tid < IWX_MAX_TID_COUNT; tid++) {
3534 		const struct ieee80211_tx_ampdu *tap;
3535 
3536 		if (sc->sc_flags & IWX_FLAG_SHUTDOWN)
3537 			break;
3538 		tap = &ni->ni_tx_ampdu[tid];
3539 		if (IEEE80211_AMPDU_RUNNING(tap))
3540 			break;
3541 		if (sc->ba_tx.start_tidmask & (1 << tid)) {
3542 			IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT,
3543 			    "%s: ampdu tx start for tid %i\n", __func__, tid);
3544 			iwx_sta_tx_agg_start(sc, ni, tid);
3545 			sc->ba_tx.start_tidmask &= ~(1 << tid);
3546 			started_mask |= (1 << tid);
3547 		}
3548 	}
3549 
3550 	IWX_UNLOCK(sc);
3551 
3552 	/* Iterate over the sessions we started; mark them as active */
3553 	for (tid = 0; tid < IWX_MAX_TID_COUNT; tid++) {
3554 		if (started_mask & (1 << tid)) {
3555 			IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT,
3556 			    "%s: informing net80211 to start ampdu on tid %i\n",
3557 			    __func__, tid);
3558 			ieee80211_ampdu_tx_request_active_ext(ni, tid, 1);
3559 		}
3560 	}
3561 }
3562 
3563 static void
3564 iwx_set_mac_addr_from_csr(struct iwx_softc *sc, struct iwx_nvm_data *data)
3565 {
3566 	uint32_t mac_addr0, mac_addr1;
3567 
3568 	memset(data->hw_addr, 0, sizeof(data->hw_addr));
3569 
3570 	if (!iwx_nic_lock(sc))
3571 		return;
3572 
3573 	mac_addr0 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR0_STRAP(sc)));
3574 	mac_addr1 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR1_STRAP(sc)));
3575 
3576 	iwx_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
3577 
3578 	/* If OEM fused a valid address, use it instead of the one in OTP. */
3579 	if (iwx_is_valid_mac_addr(data->hw_addr)) {
3580 		iwx_nic_unlock(sc);
3581 		return;
3582 	}
3583 
3584 	mac_addr0 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR0_OTP(sc)));
3585 	mac_addr1 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR1_OTP(sc)));
3586 
3587 	iwx_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
3588 
3589 	iwx_nic_unlock(sc);
3590 }
3591 
3592 static int
3593 iwx_is_valid_mac_addr(const uint8_t *addr)
3594 {
3595 	static const uint8_t reserved_mac[] = {
3596 		0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00
3597 	};
3598 
3599 	return (memcmp(reserved_mac, addr, ETHER_ADDR_LEN) != 0 &&
3600 	    memcmp(etherbroadcastaddr, addr, sizeof(etherbroadcastaddr)) != 0 &&
3601 	    memcmp(etheranyaddr, addr, sizeof(etheranyaddr)) != 0 &&
3602 	    !ETHER_IS_MULTICAST(addr));
3603 }
3604 
3605 static void
3606 iwx_flip_hw_address(uint32_t mac_addr0, uint32_t mac_addr1, uint8_t *dest)
3607 {
3608 	const uint8_t *hw_addr;
3609 
3610 	hw_addr = (const uint8_t *)&mac_addr0;
3611 	dest[0] = hw_addr[3];
3612 	dest[1] = hw_addr[2];
3613 	dest[2] = hw_addr[1];
3614 	dest[3] = hw_addr[0];
3615 
3616 	hw_addr = (const uint8_t *)&mac_addr1;
3617 	dest[4] = hw_addr[1];
3618 	dest[5] = hw_addr[0];
3619 }
3620 
3621 static int
3622 iwx_nvm_get(struct iwx_softc *sc)
3623 {
3624 	struct iwx_nvm_get_info cmd = {};
3625 	struct iwx_nvm_data *nvm = &sc->sc_nvm;
3626 	struct iwx_host_cmd hcmd = {
3627 		.flags = IWX_CMD_WANT_RESP | IWX_CMD_SEND_IN_RFKILL,
3628 		.data = { &cmd, },
3629 		.len = { sizeof(cmd) },
3630 		.id = IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
3631 		    IWX_NVM_GET_INFO)
3632 	};
3633 	int err = 0;
3634 	uint32_t mac_flags;
3635 	/*
3636 	 * All the values in iwx_nvm_get_info_rsp v4 are the same as
3637 	 * in v3, except for the channel profile part of the
3638 	 * regulatory.  So we can just access the new struct, with the
3639 	 * exception of the latter.
3640 	 */
3641 	struct iwx_nvm_get_info_rsp *rsp;
3642 	struct iwx_nvm_get_info_rsp_v3 *rsp_v3;
3643 	int v4 = isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_REGULATORY_NVM_INFO);
3644 	size_t resp_len = v4 ? sizeof(*rsp) : sizeof(*rsp_v3);
3645 
3646 	hcmd.resp_pkt_len = sizeof(struct iwx_rx_packet) + resp_len;
3647 	err = iwx_send_cmd(sc, &hcmd);
3648 	if (err) {
3649 		printf("%s: failed to send cmd (error %d)", __func__, err);
3650 		return err;
3651 	}
3652 
3653 	if (iwx_rx_packet_payload_len(hcmd.resp_pkt) != resp_len) {
3654 		printf("%s: iwx_rx_packet_payload_len=%d\n", __func__,
3655 		    iwx_rx_packet_payload_len(hcmd.resp_pkt));
3656 		printf("%s: resp_len=%zu\n", __func__, resp_len);
3657 		err = EIO;
3658 		goto out;
3659 	}
3660 
3661 	memset(nvm, 0, sizeof(*nvm));
3662 
3663 	iwx_set_mac_addr_from_csr(sc, nvm);
3664 	if (!iwx_is_valid_mac_addr(nvm->hw_addr)) {
3665 		printf("%s: no valid mac address was found\n", DEVNAME(sc));
3666 		err = EINVAL;
3667 		goto out;
3668 	}
3669 
3670 	rsp = (void *)hcmd.resp_pkt->data;
3671 
3672 	/* Initialize general data */
3673 	nvm->nvm_version = le16toh(rsp->general.nvm_version);
3674 	nvm->n_hw_addrs = rsp->general.n_hw_addrs;
3675 
3676 	/* Initialize MAC sku data */
3677 	mac_flags = le32toh(rsp->mac_sku.mac_sku_flags);
3678 	nvm->sku_cap_11ac_enable =
3679 		!!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_802_11AC_ENABLED);
3680 	nvm->sku_cap_11n_enable =
3681 		!!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_802_11N_ENABLED);
3682 	nvm->sku_cap_11ax_enable =
3683 		!!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_802_11AX_ENABLED);
3684 	nvm->sku_cap_band_24GHz_enable =
3685 		!!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_BAND_2_4_ENABLED);
3686 	nvm->sku_cap_band_52GHz_enable =
3687 		!!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_BAND_5_2_ENABLED);
3688 	nvm->sku_cap_mimo_disable =
3689 		!!(mac_flags & IWX_NVM_MAC_SKU_FLAGS_MIMO_DISABLED);
3690 
3691 	/* Initialize PHY sku data */
3692 	nvm->valid_tx_ant = (uint8_t)le32toh(rsp->phy_sku.tx_chains);
3693 	nvm->valid_rx_ant = (uint8_t)le32toh(rsp->phy_sku.rx_chains);
3694 
3695 	if (le32toh(rsp->regulatory.lar_enabled) &&
3696 	    isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_LAR_SUPPORT)) {
3697 		nvm->lar_enabled = 1;
3698 	}
3699 
3700 	memcpy(&sc->sc_rsp_info, rsp, resp_len);
3701 	if (v4) {
3702 		sc->sc_rsp_vers = IWX_FBSD_RSP_V4;
3703 	} else {
3704 		sc->sc_rsp_vers = IWX_FBSD_RSP_V3;
3705 	}
3706 out:
3707 	iwx_free_resp(sc, &hcmd);
3708 	return err;
3709 }
3710 
3711 static int
3712 iwx_load_firmware(struct iwx_softc *sc)
3713 {
3714 	struct iwx_fw_sects *fws;
3715 	int err;
3716 
3717 	IWX_ASSERT_LOCKED(sc)
3718 
3719 	sc->sc_uc.uc_intr = 0;
3720 	sc->sc_uc.uc_ok = 0;
3721 
3722 	fws = &sc->sc_fw.fw_sects[IWX_UCODE_TYPE_REGULAR];
3723 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
3724 		err = iwx_ctxt_info_gen3_init(sc, fws);
3725 	else
3726 		err = iwx_ctxt_info_init(sc, fws);
3727 	if (err) {
3728 		printf("%s: could not init context info\n", DEVNAME(sc));
3729 		return err;
3730 	}
3731 
3732 	/* wait for the firmware to load */
3733 	err = msleep(&sc->sc_uc, &sc->sc_mtx, 0, "iwxuc", hz);
3734 	if (err || !sc->sc_uc.uc_ok) {
3735 		printf("%s: firmware upload failed, %d\n", DEVNAME(sc), err);
3736 		iwx_ctxt_info_free_paging(sc);
3737 	}
3738 
3739 	iwx_dma_contig_free(&sc->iml_dma);
3740 	iwx_ctxt_info_free_fw_img(sc);
3741 
3742 	if (!sc->sc_uc.uc_ok)
3743 		return EINVAL;
3744 
3745 	return err;
3746 }
3747 
3748 static int
3749 iwx_start_fw(struct iwx_softc *sc)
3750 {
3751 	int err;
3752 
3753 	IWX_WRITE(sc, IWX_CSR_INT, ~0);
3754 
3755 	iwx_disable_interrupts(sc);
3756 
3757 	/* make sure rfkill handshake bits are cleared */
3758 	IWX_WRITE(sc, IWX_CSR_UCODE_DRV_GP1_CLR, IWX_CSR_UCODE_SW_BIT_RFKILL);
3759 	IWX_WRITE(sc, IWX_CSR_UCODE_DRV_GP1_CLR,
3760 	    IWX_CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
3761 
3762 	/* clear (again), then enable firmware load interrupt */
3763 	IWX_WRITE(sc, IWX_CSR_INT, ~0);
3764 
3765 	err = iwx_nic_init(sc);
3766 	if (err) {
3767 		printf("%s: unable to init nic\n", DEVNAME(sc));
3768 		return err;
3769 	}
3770 
3771 	iwx_enable_fwload_interrupt(sc);
3772 
3773 	return iwx_load_firmware(sc);
3774 }
3775 
3776 static int
3777 iwx_pnvm_handle_section(struct iwx_softc *sc, const uint8_t *data,
3778     size_t len)
3779 {
3780 	const struct iwx_ucode_tlv *tlv;
3781 	uint32_t sha1 = 0;
3782 	uint16_t mac_type = 0, rf_id = 0;
3783 	uint8_t *pnvm_data = NULL, *tmp;
3784 	int hw_match = 0;
3785 	uint32_t size = 0;
3786 	int err;
3787 
3788 	while (len >= sizeof(*tlv)) {
3789 		uint32_t tlv_len, tlv_type;
3790 
3791 		len -= sizeof(*tlv);
3792 		tlv = (const void *)data;
3793 
3794 		tlv_len = le32toh(tlv->length);
3795 		tlv_type = le32toh(tlv->type);
3796 
3797 		if (len < tlv_len) {
3798 			printf("%s: invalid TLV len: %zd/%u\n",
3799 			    DEVNAME(sc), len, tlv_len);
3800 			err = EINVAL;
3801 			goto out;
3802 		}
3803 
3804 		data += sizeof(*tlv);
3805 
3806 		switch (tlv_type) {
3807 		case IWX_UCODE_TLV_PNVM_VERSION:
3808 			if (tlv_len < sizeof(uint32_t))
3809 				break;
3810 
3811 			sha1 = le32_to_cpup((const uint32_t *)data);
3812 			break;
3813 		case IWX_UCODE_TLV_HW_TYPE:
3814 			if (tlv_len < 2 * sizeof(uint16_t))
3815 				break;
3816 
3817 			if (hw_match)
3818 				break;
3819 
3820 			mac_type = le16_to_cpup((const uint16_t *)data);
3821 			rf_id = le16_to_cpup((const uint16_t *)(data +
3822 			    sizeof(uint16_t)));
3823 
3824 			if (mac_type == IWX_CSR_HW_REV_TYPE(sc->sc_hw_rev) &&
3825 			    rf_id == IWX_CSR_HW_RFID_TYPE(sc->sc_hw_rf_id))
3826 				hw_match = 1;
3827 			break;
3828 		case IWX_UCODE_TLV_SEC_RT: {
3829 			const struct iwx_pnvm_section *section;
3830 			uint32_t data_len;
3831 
3832 			section = (const void *)data;
3833 			data_len = tlv_len - sizeof(*section);
3834 
3835 			/* TODO: remove, this is a deprecated separator */
3836 			if (le32_to_cpup((const uint32_t *)data) == 0xddddeeee)
3837 				break;
3838 
3839 			tmp = malloc(size + data_len, M_DEVBUF,
3840 			    M_WAITOK | M_ZERO);
3841 			if (tmp == NULL) {
3842 				err = ENOMEM;
3843 				goto out;
3844 			}
3845 			// XXX:misha pnvm_data is NULL and size is 0 at first pass
3846 			memcpy(tmp, pnvm_data, size);
3847 			memcpy(tmp + size, section->data, data_len);
3848 			free(pnvm_data, M_DEVBUF);
3849 			pnvm_data = tmp;
3850 			size += data_len;
3851 			break;
3852 		}
3853 		case IWX_UCODE_TLV_PNVM_SKU:
3854 			/* New PNVM section started, stop parsing. */
3855 			goto done;
3856 		default:
3857 			break;
3858 		}
3859 
3860 		if (roundup(tlv_len, 4) > len)
3861 			break;
3862 		len -= roundup(tlv_len, 4);
3863 		data += roundup(tlv_len, 4);
3864 	}
3865 done:
3866 	if (!hw_match || size == 0) {
3867 		err = ENOENT;
3868 		goto out;
3869 	}
3870 
3871 	err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->pnvm_dma, size, 1);
3872 	if (err) {
3873 		printf("%s: could not allocate DMA memory for PNVM\n",
3874 		    DEVNAME(sc));
3875 		err = ENOMEM;
3876 		goto out;
3877 	}
3878 	memcpy(sc->pnvm_dma.vaddr, pnvm_data, size);
3879 	iwx_ctxt_info_gen3_set_pnvm(sc);
3880 	sc->sc_pnvm_ver = sha1;
3881 out:
3882 	free(pnvm_data, M_DEVBUF);
3883 	return err;
3884 }
3885 
3886 static int
3887 iwx_pnvm_parse(struct iwx_softc *sc, const uint8_t *data, size_t len)
3888 {
3889 	const struct iwx_ucode_tlv *tlv;
3890 
3891 	while (len >= sizeof(*tlv)) {
3892 		uint32_t tlv_len, tlv_type;
3893 
3894 		len -= sizeof(*tlv);
3895 		tlv = (const void *)data;
3896 
3897 		tlv_len = le32toh(tlv->length);
3898 		tlv_type = le32toh(tlv->type);
3899 
3900 		if (len < tlv_len || roundup(tlv_len, 4) > len)
3901 			return EINVAL;
3902 
3903 		if (tlv_type == IWX_UCODE_TLV_PNVM_SKU) {
3904 			const struct iwx_sku_id *sku_id =
3905 				(const void *)(data + sizeof(*tlv));
3906 
3907 			data += sizeof(*tlv) + roundup(tlv_len, 4);
3908 			len -= roundup(tlv_len, 4);
3909 
3910 			if (sc->sc_sku_id[0] == le32toh(sku_id->data[0]) &&
3911 			    sc->sc_sku_id[1] == le32toh(sku_id->data[1]) &&
3912 			    sc->sc_sku_id[2] == le32toh(sku_id->data[2]) &&
3913 			    iwx_pnvm_handle_section(sc, data, len) == 0)
3914 				return 0;
3915 		} else {
3916 			data += sizeof(*tlv) + roundup(tlv_len, 4);
3917 			len -= roundup(tlv_len, 4);
3918 		}
3919 	}
3920 
3921 	return ENOENT;
3922 }
3923 
3924 /* Make AX210 firmware loading context point at PNVM image in DMA memory. */
3925 static void
3926 iwx_ctxt_info_gen3_set_pnvm(struct iwx_softc *sc)
3927 {
3928 	struct iwx_prph_scratch *prph_scratch;
3929 	struct iwx_prph_scratch_ctrl_cfg *prph_sc_ctrl;
3930 
3931 	prph_scratch = sc->prph_scratch_dma.vaddr;
3932 	prph_sc_ctrl = &prph_scratch->ctrl_cfg;
3933 
3934 	prph_sc_ctrl->pnvm_cfg.pnvm_base_addr = htole64(sc->pnvm_dma.paddr);
3935 	prph_sc_ctrl->pnvm_cfg.pnvm_size = htole32(sc->pnvm_dma.size);
3936 
3937 	bus_dmamap_sync(sc->sc_dmat, sc->pnvm_dma.map, BUS_DMASYNC_PREWRITE);
3938 }
3939 
3940 /*
3941  * Load platform-NVM (non-volatile-memory) data from the filesystem.
3942  * This data apparently contains regulatory information and affects device
3943  * channel configuration.
3944  * The SKU of AX210 devices tells us which PNVM file section is needed.
3945  * Pre-AX210 devices store NVM data onboard.
3946  */
3947 static int
3948 iwx_load_pnvm(struct iwx_softc *sc)
3949 {
3950 	const int wait_flags = IWX_PNVM_COMPLETE;
3951 	int err = 0;
3952 	const struct firmware *pnvm;
3953 
3954 	if (sc->sc_sku_id[0] == 0 &&
3955 	    sc->sc_sku_id[1] == 0 &&
3956 	    sc->sc_sku_id[2] == 0)
3957 		return 0;
3958 
3959 	if (sc->sc_pnvm_name) {
3960 		if (sc->pnvm_dma.vaddr == NULL) {
3961 			IWX_UNLOCK(sc);
3962 			pnvm = firmware_get(sc->sc_pnvm_name);
3963 			if (pnvm == NULL) {
3964 				printf("%s: could not read %s (error %d)\n",
3965 				    DEVNAME(sc), sc->sc_pnvm_name, err);
3966 				IWX_LOCK(sc);
3967 				return EINVAL;
3968 			}
3969 			sc->sc_pnvm = pnvm;
3970 
3971 			err = iwx_pnvm_parse(sc, pnvm->data, pnvm->datasize);
3972 			IWX_LOCK(sc);
3973 			if (err && err != ENOENT) {
3974 				return EINVAL;
3975 			}
3976 		} else
3977 			iwx_ctxt_info_gen3_set_pnvm(sc);
3978 	}
3979 
3980 	if (!iwx_nic_lock(sc)) {
3981 		return EBUSY;
3982 	}
3983 
3984 	/*
3985 	 * If we don't have a platform NVM file simply ask firmware
3986 	 * to proceed without it.
3987 	 */
3988 
3989 	iwx_write_umac_prph(sc, IWX_UREG_DOORBELL_TO_ISR6,
3990 	    IWX_UREG_DOORBELL_TO_ISR6_PNVM);
3991 
3992 	/* Wait for the pnvm complete notification from firmware. */
3993 	while ((sc->sc_init_complete & wait_flags) != wait_flags) {
3994 		err = msleep(&sc->sc_init_complete, &sc->sc_mtx, 0, "iwxinit", 2 * hz);
3995 		if (err)
3996 			break;
3997 	}
3998 
3999 	iwx_nic_unlock(sc);
4000 
4001 	return err;
4002 }
4003 
4004 static int
4005 iwx_send_tx_ant_cfg(struct iwx_softc *sc, uint8_t valid_tx_ant)
4006 {
4007 	struct iwx_tx_ant_cfg_cmd tx_ant_cmd = {
4008 		.valid = htole32(valid_tx_ant),
4009 	};
4010 
4011 	return iwx_send_cmd_pdu(sc, IWX_TX_ANT_CONFIGURATION_CMD,
4012 	    0, sizeof(tx_ant_cmd), &tx_ant_cmd);
4013 }
4014 
4015 static int
4016 iwx_send_phy_cfg_cmd(struct iwx_softc *sc)
4017 {
4018 	struct iwx_phy_cfg_cmd phy_cfg_cmd;
4019 
4020 	phy_cfg_cmd.phy_cfg = htole32(sc->sc_fw_phy_config);
4021 	phy_cfg_cmd.calib_control.event_trigger =
4022 	    sc->sc_default_calib[IWX_UCODE_TYPE_REGULAR].event_trigger;
4023 	phy_cfg_cmd.calib_control.flow_trigger =
4024 	    sc->sc_default_calib[IWX_UCODE_TYPE_REGULAR].flow_trigger;
4025 
4026 	return iwx_send_cmd_pdu(sc, IWX_PHY_CONFIGURATION_CMD, 0,
4027 	    sizeof(phy_cfg_cmd), &phy_cfg_cmd);
4028 }
4029 
4030 static int
4031 iwx_send_dqa_cmd(struct iwx_softc *sc)
4032 {
4033 	struct iwx_dqa_enable_cmd dqa_cmd = {
4034 		.cmd_queue = htole32(IWX_DQA_CMD_QUEUE),
4035 	};
4036 	uint32_t cmd_id;
4037 
4038 	cmd_id = iwx_cmd_id(IWX_DQA_ENABLE_CMD, IWX_DATA_PATH_GROUP, 0);
4039 	return iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(dqa_cmd), &dqa_cmd);
4040 }
4041 
4042 static int
4043 iwx_load_ucode_wait_alive(struct iwx_softc *sc)
4044 {
4045 	int err;
4046 
4047 	IWX_UNLOCK(sc);
4048 	err = iwx_read_firmware(sc);
4049 	IWX_LOCK(sc);
4050 	if (err)
4051 		return err;
4052 
4053 	err = iwx_start_fw(sc);
4054 	if (err)
4055 		return err;
4056 
4057 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
4058 		err = iwx_load_pnvm(sc);
4059 		if (err)
4060 			return err;
4061 	}
4062 
4063 	iwx_post_alive(sc);
4064 
4065 	return 0;
4066 }
4067 
4068 static int
4069 iwx_run_init_mvm_ucode(struct iwx_softc *sc, int readnvm)
4070 {
4071 	const int wait_flags = IWX_INIT_COMPLETE;
4072 	struct iwx_nvm_access_complete_cmd nvm_complete = {};
4073 	struct iwx_init_extended_cfg_cmd init_cfg = {
4074 		.init_flags = htole32(IWX_INIT_NVM),
4075 	};
4076 
4077 	int err;
4078 
4079 	if ((sc->sc_flags & IWX_FLAG_RFKILL) && !readnvm) {
4080 		printf("%s: radio is disabled by hardware switch\n",
4081 		    DEVNAME(sc));
4082 		return EPERM;
4083 	}
4084 
4085 	sc->sc_init_complete = 0;
4086 	err = iwx_load_ucode_wait_alive(sc);
4087 	if (err) {
4088 		IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV,
4089 		    "%s: failed to load init firmware\n", DEVNAME(sc));
4090 		return err;
4091 	} else {
4092 		IWX_DPRINTF(sc, IWX_DEBUG_FIRMWARE_TLV,
4093 		    "%s: successfully loaded init firmware\n", __func__);
4094 	}
4095 
4096 	/*
4097 	 * Send init config command to mark that we are sending NVM
4098 	 * access commands
4099 	 */
4100 	err = iwx_send_cmd_pdu(sc, IWX_WIDE_ID(IWX_SYSTEM_GROUP,
4101 	    IWX_INIT_EXTENDED_CFG_CMD), 0, sizeof(init_cfg), &init_cfg);
4102 	if (err) {
4103 		printf("%s: IWX_INIT_EXTENDED_CFG_CMD error=%d\n", __func__,
4104 		    err);
4105 		return err;
4106 	}
4107 
4108 	err = iwx_send_cmd_pdu(sc, IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
4109 	    IWX_NVM_ACCESS_COMPLETE), 0, sizeof(nvm_complete), &nvm_complete);
4110 	if (err) {
4111 		return err;
4112 	}
4113 
4114 	/* Wait for the init complete notification from the firmware. */
4115 	while ((sc->sc_init_complete & wait_flags) != wait_flags) {
4116 		err = msleep(&sc->sc_init_complete, &sc->sc_mtx, 0, "iwxinit", 2 * hz);
4117 		if (err) {
4118 			DPRINTF(("%s: will return err=%d\n", __func__, err));
4119 			return err;
4120 		} else {
4121 			DPRINTF(("%s: sc_init_complete == IWX_INIT_COMPLETE\n",
4122 			    __func__));
4123 		}
4124 	}
4125 
4126 	if (readnvm) {
4127 		err = iwx_nvm_get(sc);
4128 		DPRINTF(("%s: err=%d\n", __func__, err));
4129 		if (err) {
4130 			printf("%s: failed to read nvm (error %d)\n",
4131 			    DEVNAME(sc), err);
4132 			return err;
4133 		} else {
4134 			DPRINTF(("%s: successfully read nvm\n", DEVNAME(sc)));
4135 		}
4136 		IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, sc->sc_nvm.hw_addr);
4137 	}
4138 	return 0;
4139 }
4140 
4141 static int
4142 iwx_config_ltr(struct iwx_softc *sc)
4143 {
4144 	struct iwx_ltr_config_cmd cmd = {
4145 		.flags = htole32(IWX_LTR_CFG_FLAG_FEATURE_ENABLE),
4146 	};
4147 
4148 	if (!sc->sc_ltr_enabled)
4149 		return 0;
4150 
4151 	return iwx_send_cmd_pdu(sc, IWX_LTR_CONFIG, 0, sizeof(cmd), &cmd);
4152 }
4153 
4154 static void
4155 iwx_update_rx_desc(struct iwx_softc *sc, struct iwx_rx_ring *ring, int idx,
4156     bus_dma_segment_t *seg)
4157 {
4158 	struct iwx_rx_data *data = &ring->data[idx];
4159 
4160 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
4161 		struct iwx_rx_transfer_desc *desc = ring->desc;
4162 		desc[idx].rbid = htole16(idx & 0xffff);
4163 		desc[idx].addr = htole64((*seg).ds_addr);
4164 		bus_dmamap_sync(ring->data_dmat, data->map,
4165 		    BUS_DMASYNC_PREWRITE);
4166 	} else {
4167 		((uint64_t *)ring->desc)[idx] =
4168 		    htole64((*seg).ds_addr);
4169 		bus_dmamap_sync(ring->data_dmat, data->map,
4170 		    BUS_DMASYNC_PREWRITE);
4171 	}
4172 }
4173 
4174 static int
4175 iwx_rx_addbuf(struct iwx_softc *sc, int size, int idx)
4176 {
4177 	struct iwx_rx_ring *ring = &sc->rxq;
4178 	struct iwx_rx_data *data = &ring->data[idx];
4179 	struct mbuf *m;
4180 	int err;
4181 	int fatal = 0;
4182 	bus_dma_segment_t seg;
4183 	int nsegs;
4184 
4185 	m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, IWX_RBUF_SIZE);
4186 	if (m == NULL)
4187 		return ENOBUFS;
4188 
4189 	if (data->m != NULL) {
4190 		bus_dmamap_unload(ring->data_dmat, data->map);
4191 		fatal = 1;
4192 	}
4193 
4194 	m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
4195 	err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, &seg,
4196 	    &nsegs, BUS_DMA_NOWAIT);
4197 	if (err) {
4198 		/* XXX */
4199 		if (fatal)
4200 			panic("could not load RX mbuf");
4201 		m_freem(m);
4202 		return err;
4203 	}
4204 	data->m = m;
4205 	bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREREAD);
4206 
4207 	/* Update RX descriptor. */
4208 	iwx_update_rx_desc(sc, ring, idx, &seg);
4209 	return 0;
4210 }
4211 
4212 /*
4213  * @brief Return a single signal strength for the given frame.
4214  *
4215  * The firmware communicates up an energy field which is the negative of
4216  * the dBm value.  Ie, the number is positive and it increases as the
4217  * signal level decreases.
4218  *
4219  * Fetch the two values, map 0 (inactive antenna) to -256 dBm which is a
4220  * very small number, negate a non-zero value so it's mapped into a dBm
4221  * value, then choose the maximum value to return.
4222  */
4223 static int
4224 iwx_rxmq_get_signal_strength(struct iwx_softc *sc,
4225     struct iwx_rx_mpdu_desc *desc)
4226 {
4227 	int energy_a, energy_b;
4228 
4229 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
4230 		energy_a = desc->v3.energy_a;
4231 		energy_b = desc->v3.energy_b;
4232 	} else {
4233 		energy_a = desc->v1.energy_a;
4234 		energy_b = desc->v1.energy_b;
4235 	}
4236 	energy_a = energy_a ? -energy_a : -256;
4237 	energy_b = energy_b ? -energy_b : -256;
4238 	return MAX(energy_a, energy_b);
4239 }
4240 
4241 /**
4242  * @brief Calculate an RSSI from the given signal level and noise floor.
4243  *
4244  * This calculates an RSSI and clamps it at IWX_RSSI_MINIMUM at the lower level
4245  * and IWX_RSSI_MAXIMUM at the upper level.
4246  *
4247  * All units are in dBm.
4248  */
4249 static int
4250 iwx_calculate_rssi(struct iwx_softc *sc, int ss, int nf)
4251 {
4252 	int rssi = (ss - nf);
4253 	if (rssi < IWX_RSSI_MINIMUM)
4254 		rssi = IWX_RSSI_MINIMUM;
4255 	else if (rssi > IWX_RSSI_MAXIMUM)
4256 		rssi = IWX_RSSI_MAXIMUM;
4257 
4258 	return (rssi);
4259 }
4260 
4261 static int
4262 iwx_rxmq_get_chains(struct iwx_softc *sc,
4263     struct iwx_rx_mpdu_desc *desc)
4264 {
4265 
4266 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
4267 		return ((desc->v3.rate_n_flags & IWX_RATE_MCS_ANT_AB_MSK) >>
4268 		    IWX_RATE_MCS_ANT_POS);
4269 	else
4270 		return ((desc->v1.rate_n_flags & IWX_RATE_MCS_ANT_AB_MSK) >>
4271 		    IWX_RATE_MCS_ANT_POS);
4272 }
4273 
4274 static void
4275 iwx_rx_rx_phy_cmd(struct iwx_softc *sc, struct iwx_rx_packet *pkt,
4276     struct iwx_rx_data *data)
4277 {
4278 	struct iwx_rx_phy_info *phy_info = (void *)pkt->data;
4279 	struct iwx_cmd_header *cmd_hdr = &pkt->hdr;
4280 	int qid = cmd_hdr->qid;
4281 	struct iwx_tx_ring *ring = &sc->txq[qid];
4282 
4283 	bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREREAD);
4284 	memcpy(&sc->sc_last_phy_info, phy_info, sizeof(sc->sc_last_phy_info));
4285 }
4286 
4287 /*
4288  * @brief Retrieve the average noise (in dBm) among receivers.
4289  *
4290  * Note: This routine calculates the noise floor sum incorrectly, as
4291  * you can't just linearly add the logarithm based dB units together.
4292  *
4293  * If no noise floor is available then this routine will return -127.
4294  */
4295 static int
4296 iwx_get_noise(struct iwx_softc *sc,
4297     const struct iwx_statistics_rx_non_phy *stats)
4298 {
4299 	int i, total, nbant, noise, ret;
4300 
4301 	total = nbant = noise = 0;
4302 	for (i = 0; i < 3; i++) {
4303 		noise = le32toh(stats->beacon_silence_rssi[i]) & 0xff;
4304 		if (noise) {
4305 			total += noise;
4306 			nbant++;
4307 		}
4308 	}
4309 
4310 	/* There should be at least one antenna but check anyway. */
4311 	if (nbant == 0)
4312 		ret = -127;
4313 	else if (total == 0)
4314 		ret = -127;
4315 	else
4316 		ret = (total / nbant) - 127;
4317 
4318 	return (ret);
4319 }
4320 
4321 #if 0
4322 int
4323 iwx_ccmp_decap(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
4324     struct ieee80211_rxinfo *rxi)
4325 {
4326 	struct ieee80211com *ic = &sc->sc_ic;
4327 	struct ieee80211_key *k;
4328 	struct ieee80211_frame *wh;
4329 	uint64_t pn, *prsc;
4330 	uint8_t *ivp;
4331 	uint8_t tid;
4332 	int hdrlen, hasqos;
4333 
4334 	wh = mtod(m, struct ieee80211_frame *);
4335 	hdrlen = ieee80211_get_hdrlen(wh);
4336 	ivp = (uint8_t *)wh + hdrlen;
4337 
4338 	/* find key for decryption */
4339 	k = ieee80211_get_rxkey(ic, m, ni);
4340 	if (k == NULL || k->k_cipher != IEEE80211_CIPHER_CCMP)
4341 		return 1;
4342 
4343 	/* Check that ExtIV bit is be set. */
4344 	if (!(ivp[3] & IEEE80211_WEP_EXTIV))
4345 		return 1;
4346 
4347 	hasqos = ieee80211_has_qos(wh);
4348 	tid = hasqos ? ieee80211_get_qos(wh) & IEEE80211_QOS_TID : 0;
4349 	prsc = &k->k_rsc[tid];
4350 
4351 	/* Extract the 48-bit PN from the CCMP header. */
4352 	pn = (uint64_t)ivp[0]       |
4353 	     (uint64_t)ivp[1] <<  8 |
4354 	     (uint64_t)ivp[4] << 16 |
4355 	     (uint64_t)ivp[5] << 24 |
4356 	     (uint64_t)ivp[6] << 32 |
4357 	     (uint64_t)ivp[7] << 40;
4358 	if (rxi->rxi_flags & IEEE80211_RXI_HWDEC_SAME_PN) {
4359 		if (pn < *prsc) {
4360 			ic->ic_stats.is_ccmp_replays++;
4361 			return 1;
4362 		}
4363 	} else if (pn <= *prsc) {
4364 		ic->ic_stats.is_ccmp_replays++;
4365 		return 1;
4366 	}
4367 	/* Last seen packet number is updated in ieee80211_inputm(). */
4368 
4369 	/*
4370 	 * Some firmware versions strip the MIC, and some don't. It is not
4371 	 * clear which of the capability flags could tell us what to expect.
4372 	 * For now, keep things simple and just leave the MIC in place if
4373 	 * it is present.
4374 	 *
4375 	 * The IV will be stripped by ieee80211_inputm().
4376 	 */
4377 	return 0;
4378 }
4379 #endif
4380 
4381 static int
4382 iwx_rx_hwdecrypt(struct iwx_softc *sc, struct mbuf *m, uint32_t rx_pkt_status)
4383 {
4384 	struct ieee80211_frame *wh;
4385 	int ret = 0;
4386 	uint8_t type, subtype;
4387 
4388 	wh = mtod(m, struct ieee80211_frame *);
4389 
4390 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
4391 	if (type == IEEE80211_FC0_TYPE_CTL) {
4392 		return 0;
4393 	}
4394 
4395 	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
4396 	if (IEEE80211_QOS_HAS_SEQ(wh) && (subtype & IEEE80211_FC0_SUBTYPE_NODATA)) {
4397 		return 0;
4398 	}
4399 
4400 
4401 	if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
4402 	    IEEE80211_FC0_TYPE_CTL)
4403 	    && (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
4404 		if ((rx_pkt_status & IWX_RX_MPDU_RES_STATUS_SEC_ENC_MSK) !=
4405 		    IWX_RX_MPDU_RES_STATUS_SEC_CCM_ENC) {
4406 			DPRINTF(("%s: not IWX_RX_MPDU_RES_STATUS_SEC_CCM_ENC\n", __func__));
4407 			ret = 1;
4408 			goto out;
4409 		}
4410 		/* Check whether decryption was successful or not. */
4411 		if ((rx_pkt_status &
4412 		    (IWX_RX_MPDU_RES_STATUS_DEC_DONE |
4413 		    IWX_RX_MPDU_RES_STATUS_MIC_OK)) !=
4414 		    (IWX_RX_MPDU_RES_STATUS_DEC_DONE |
4415 		    IWX_RX_MPDU_RES_STATUS_MIC_OK)) {
4416 			DPRINTF(("%s: not IWX_RX_MPDU_RES_STATUS_MIC_OK\n", __func__));
4417 			ret = 1;
4418 			goto out;
4419 		}
4420 	}
4421 	out:
4422 	return ret;
4423 }
4424 
4425 static void
4426 iwx_rx_frame(struct iwx_softc *sc, struct mbuf *m, int chanidx,
4427     uint32_t rx_pkt_status, int is_shortpre, int rate_n_flags,
4428     uint32_t device_timestamp, uint8_t rssi)
4429 {
4430 	struct ieee80211com *ic = &sc->sc_ic;
4431 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
4432 	struct ieee80211_frame *wh;
4433 	struct ieee80211_node *ni;
4434 
4435 	/*
4436 	 * We need to turn the hardware provided channel index into a channel
4437 	 * and then find it in our ic_channels array
4438 	 */
4439 	if (chanidx < 0 || chanidx >= nitems(ic->ic_channels)) {
4440 		/*
4441 		 * OpenBSD points this at the ibss chan, which it defaults to
4442 		 * channel 1 and then never touches again. Skip a step.
4443 		 */
4444 		printf("iwx: %s:%d controlling chanidx to 1 (%d)\n", __func__, __LINE__, chanidx);
4445 		chanidx = 1;
4446 	}
4447 
4448 	int channel = chanidx;
4449 	for (int i = 0; i < ic->ic_nchans; i++) {
4450 		if (ic->ic_channels[i].ic_ieee == channel) {
4451 			chanidx = i;
4452 		}
4453 	}
4454 	ic->ic_curchan = &ic->ic_channels[chanidx];
4455 
4456 	wh = mtod(m, struct ieee80211_frame *);
4457 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
4458 
4459 #if 0	/* XXX hw decrypt */
4460 	if ((rxi->rxi_flags & IEEE80211_RXI_HWDEC) &&
4461 	    iwx_ccmp_decap(sc, m, ni, rxi) != 0) {
4462 		m_freem(m);
4463 		ieee80211_release_node(ic, ni);
4464 		return;
4465 	}
4466 #endif
4467 	if (ieee80211_radiotap_active_vap(vap)) {
4468 		struct iwx_rx_radiotap_header *tap = &sc->sc_rxtap;
4469 		uint16_t chan_flags;
4470 		int have_legacy_rate = 1;
4471 		uint8_t mcs, rate;
4472 
4473 		tap->wr_flags = 0;
4474 		if (is_shortpre)
4475 			tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4476 		tap->wr_chan_freq =
4477 		    htole16(ic->ic_channels[chanidx].ic_freq);
4478 		chan_flags = ic->ic_channels[chanidx].ic_flags;
4479 #if 0
4480 		if (ic->ic_curmode != IEEE80211_MODE_11N &&
4481 		    ic->ic_curmode != IEEE80211_MODE_11AC) {
4482 			chan_flags &= ~IEEE80211_CHAN_HT;
4483 			chan_flags &= ~IEEE80211_CHAN_40MHZ;
4484 		}
4485 		if (ic->ic_curmode != IEEE80211_MODE_11AC)
4486 			chan_flags &= ~IEEE80211_CHAN_VHT;
4487 #else
4488 		chan_flags &= ~IEEE80211_CHAN_HT;
4489 #endif
4490 		tap->wr_chan_flags = htole16(chan_flags);
4491 		tap->wr_dbm_antsignal = rssi;
4492 		tap->wr_dbm_antnoise = (int8_t)sc->sc_noise;
4493 		tap->wr_tsft = device_timestamp;
4494 
4495 		if (sc->sc_rate_n_flags_version >= 2) {
4496 			uint32_t mod_type = (rate_n_flags &
4497 			    IWX_RATE_MCS_MOD_TYPE_MSK);
4498 			const struct ieee80211_rateset *rs = NULL;
4499 			uint32_t ridx;
4500 			have_legacy_rate = (mod_type == IWX_RATE_MCS_CCK_MSK ||
4501 			    mod_type == IWX_RATE_MCS_LEGACY_OFDM_MSK);
4502 			mcs = (rate_n_flags & IWX_RATE_HT_MCS_CODE_MSK);
4503 			ridx = (rate_n_flags & IWX_RATE_LEGACY_RATE_MSK);
4504 			if (mod_type == IWX_RATE_MCS_CCK_MSK)
4505 				rs = &ieee80211_std_rateset_11b;
4506 			else if (mod_type == IWX_RATE_MCS_LEGACY_OFDM_MSK)
4507 				rs = &ieee80211_std_rateset_11a;
4508 			if (rs && ridx < rs->rs_nrates) {
4509 				rate = (rs->rs_rates[ridx] &
4510 				    IEEE80211_RATE_VAL);
4511 			} else
4512 				rate = 0;
4513 		} else {
4514 			have_legacy_rate = ((rate_n_flags &
4515 			    (IWX_RATE_MCS_HT_MSK_V1 |
4516 			    IWX_RATE_MCS_VHT_MSK_V1)) == 0);
4517 			mcs = (rate_n_flags &
4518 			    (IWX_RATE_HT_MCS_RATE_CODE_MSK_V1 |
4519 			    IWX_RATE_HT_MCS_NSS_MSK_V1));
4520 			rate = (rate_n_flags & IWX_RATE_LEGACY_RATE_MSK_V1);
4521 		}
4522 		if (!have_legacy_rate) {
4523 			tap->wr_rate = (0x80 | mcs);
4524 		} else {
4525 			switch (rate) {
4526 			/* CCK rates. */
4527 			case  10: tap->wr_rate =   2; break;
4528 			case  20: tap->wr_rate =   4; break;
4529 			case  55: tap->wr_rate =  11; break;
4530 			case 110: tap->wr_rate =  22; break;
4531 			/* OFDM rates. */
4532 			case 0xd: tap->wr_rate =  12; break;
4533 			case 0xf: tap->wr_rate =  18; break;
4534 			case 0x5: tap->wr_rate =  24; break;
4535 			case 0x7: tap->wr_rate =  36; break;
4536 			case 0x9: tap->wr_rate =  48; break;
4537 			case 0xb: tap->wr_rate =  72; break;
4538 			case 0x1: tap->wr_rate =  96; break;
4539 			case 0x3: tap->wr_rate = 108; break;
4540 			/* Unknown rate: should not happen. */
4541 			default:  tap->wr_rate =   0;
4542 			}
4543 			// XXX hack - this needs rebased with the new rate stuff anyway
4544 			tap->wr_rate = rate;
4545 		}
4546 	}
4547 
4548 	IWX_UNLOCK(sc);
4549 	if (ni == NULL) {
4550 		if (ieee80211_input_mimo_all(ic, m) == -1)
4551 			printf("%s:%d input_all returned -1\n", __func__, __LINE__);
4552 	} else {
4553 
4554 		if (ieee80211_input_mimo(ni, m) == -1)
4555 			printf("%s:%d input_all returned -1\n", __func__, __LINE__);
4556 		ieee80211_free_node(ni);
4557 	}
4558 	IWX_LOCK(sc);
4559 }
4560 
4561 static void
4562 iwx_rx_mpdu_mq(struct iwx_softc *sc, struct mbuf *m, void *pktdata,
4563     size_t maxlen)
4564 {
4565 	struct ieee80211com *ic = &sc->sc_ic;
4566 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
4567 	struct ieee80211_node *ni = vap->iv_bss;
4568 	struct ieee80211_key *k;
4569 	struct ieee80211_rx_stats rxs;
4570 	struct iwx_rx_mpdu_desc *desc;
4571 	uint32_t len, hdrlen, rate_n_flags, device_timestamp;
4572 	int rssi;
4573 	uint8_t chanidx;
4574 	uint16_t phy_info;
4575 	size_t desc_size;
4576 	int pad = 0;
4577 
4578 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
4579 		desc_size = sizeof(*desc);
4580 	else
4581 		desc_size = IWX_RX_DESC_SIZE_V1;
4582 
4583 	if (maxlen < desc_size) {
4584 		m_freem(m);
4585 		return; /* drop */
4586 	}
4587 
4588 	desc = (struct iwx_rx_mpdu_desc *)pktdata;
4589 
4590 	if (!(desc->status & htole16(IWX_RX_MPDU_RES_STATUS_CRC_OK)) ||
4591 	    !(desc->status & htole16(IWX_RX_MPDU_RES_STATUS_OVERRUN_OK))) {
4592 		printf("%s: Bad CRC or FIFO: 0x%08X\n", __func__, desc->status);
4593 		m_freem(m);
4594 		return; /* drop */
4595 	}
4596 
4597 	len = le16toh(desc->mpdu_len);
4598 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
4599 		/* Allow control frames in monitor mode. */
4600 		if (len < sizeof(struct ieee80211_frame_cts)) {
4601 			m_freem(m);
4602 			return;
4603 		}
4604 
4605 	} else if (len < sizeof(struct ieee80211_frame)) {
4606 		m_freem(m);
4607 		return;
4608 	}
4609 	if (len > maxlen - desc_size) {
4610 		m_freem(m);
4611 		return;
4612 	}
4613 
4614 	// TODO: arithmetic on a pointer to void is a GNU extension
4615 	m->m_data = (char *)pktdata + desc_size;
4616 	m->m_pkthdr.len = m->m_len = len;
4617 
4618 	/* Account for padding following the frame header. */
4619 	if (desc->mac_flags2 & IWX_RX_MPDU_MFLG2_PAD) {
4620 		struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
4621 		int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
4622 		if (type == IEEE80211_FC0_TYPE_CTL) {
4623 			switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
4624 			case IEEE80211_FC0_SUBTYPE_CTS:
4625 				hdrlen = sizeof(struct ieee80211_frame_cts);
4626 				break;
4627 			case IEEE80211_FC0_SUBTYPE_ACK:
4628 				hdrlen = sizeof(struct ieee80211_frame_ack);
4629 				break;
4630 			default:
4631 				hdrlen = sizeof(struct ieee80211_frame_min);
4632 				break;
4633 			}
4634 		} else
4635 			hdrlen = ieee80211_hdrsize(wh);
4636 
4637 		if ((le16toh(desc->status) &
4638 		    IWX_RX_MPDU_RES_STATUS_SEC_ENC_MSK) ==
4639 		    IWX_RX_MPDU_RES_STATUS_SEC_CCM_ENC) {
4640 			// CCMP header length
4641 			hdrlen += 8;
4642 		}
4643 
4644 		memmove(m->m_data + 2, m->m_data, hdrlen);
4645 		m_adj(m, 2);
4646 
4647 	}
4648 
4649 	if ((le16toh(desc->status) &
4650 	    IWX_RX_MPDU_RES_STATUS_SEC_ENC_MSK) ==
4651 	    IWX_RX_MPDU_RES_STATUS_SEC_CCM_ENC) {
4652 		pad = 1;
4653 	}
4654 
4655 	/* If it's a HT node then perform re-order processing */
4656 	if (ni->ni_flags & IEEE80211_NODE_HT)
4657 		m->m_flags |= M_AMPDU;
4658 
4659 	/*
4660 	 * Hardware de-aggregates A-MSDUs and copies the same MAC header
4661 	 * in place for each subframe. But it leaves the 'A-MSDU present'
4662 	 * bit set in the frame header. We need to clear this bit ourselves.
4663 	 * (XXX This workaround is not required on AX200/AX201 devices that
4664 	 * have been tested by me, but it's unclear when this problem was
4665 	 * fixed in the hardware. It definitely affects the 9k generation.
4666 	 * Leaving this in place for now since some 9k/AX200 hybrids seem
4667 	 * to exist that we may eventually add support for.)
4668 	 *
4669 	 * And we must allow the same CCMP PN for subframes following the
4670 	 * first subframe. Otherwise they would be discarded as replays.
4671 	 */
4672 	if (desc->mac_flags2 & IWX_RX_MPDU_MFLG2_AMSDU) {
4673 		struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
4674 		uint8_t subframe_idx = (desc->amsdu_info &
4675 		    IWX_RX_MPDU_AMSDU_SUBFRAME_IDX_MASK);
4676 		uint8_t *qos;
4677 
4678 		rxs.c_pktflags |= IEEE80211_RX_F_AMSDU;
4679 		if (subframe_idx > 0)
4680 			rxs.c_pktflags |= IEEE80211_RX_F_AMSDU_MORE;
4681 
4682 		/* XXX should keep driver statistics about this */
4683 		IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT,
4684 		    "%s: === IWX_RX_MPDU_MFLG2_AMSDU\n", __func__);
4685 
4686 		qos = ieee80211_getqos(wh);
4687 		qos[0] &= ~IEEE80211_QOS_AMSDU;
4688 	}
4689 
4690 	/*
4691 	 * Verify decryption before duplicate detection. The latter uses
4692 	 * the TID supplied in QoS frame headers and this TID is implicitly
4693 	 * verified as part of the CCMP nonce.
4694 	 */
4695 	k = ieee80211_crypto_get_txkey(ni, m);
4696 	if (k != NULL &&
4697 	    (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) &&
4698 	    iwx_rx_hwdecrypt(sc, m, le16toh(desc->status)/*, &rxi*/)) {
4699 		DPRINTF(("%s: iwx_rx_hwdecrypt failed\n", __func__));
4700 		m_freem(m);
4701 		return;
4702 	}
4703 
4704 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
4705 		rate_n_flags = le32toh(desc->v3.rate_n_flags);
4706 		chanidx = desc->v3.channel;
4707 		device_timestamp = le32toh(desc->v3.gp2_on_air_rise);
4708 	} else {
4709 		rate_n_flags = le32toh(desc->v1.rate_n_flags);
4710 		chanidx = desc->v1.channel;
4711 		device_timestamp = le32toh(desc->v1.gp2_on_air_rise);
4712 	}
4713 
4714 	phy_info = le16toh(desc->phy_info);
4715 
4716 	/* note: RSSI here is absolute signal strength, not relative */
4717 	rssi = iwx_rxmq_get_signal_strength(sc, desc);
4718 
4719 	memset(&rxs, 0, sizeof(rxs));
4720 	rxs.r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
4721 	rxs.r_flags |= IEEE80211_R_BAND;
4722 	rxs.r_flags |= IEEE80211_R_NF | IEEE80211_R_RSSI;
4723 	rxs.r_flags |= IEEE80211_R_TSF32 | IEEE80211_R_TSF_START;
4724 
4725 	rxs.c_ieee = chanidx;
4726 	rxs.c_freq = ieee80211_ieee2mhz(rxs.c_ieee,
4727 	    chanidx <= 14 ? IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ);
4728 	rxs.c_band = chanidx <= 14 ? IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ;
4729 	rxs.c_rx_tsf = device_timestamp;
4730 	rxs.c_chain = iwx_rxmq_get_chains(sc, desc);
4731 	if (rxs.c_chain != 0)
4732 		rxs.r_flags |= IEEE80211_R_C_CHAIN;
4733 
4734 	/* noise floor is in 1dB units */
4735 	if (sc->sc_noise < IWX_DEFAULT_NF)
4736 		/*
4737 		 * For now choose /a/ default, net80211 expects nf to be passed
4738 		 * in various places and older drivers fake NF values where
4739 		 * needed.
4740 		 */
4741 		rxs.c_nf = IWX_DEFAULT_NF;
4742 	else
4743 		rxs.c_nf = sc->sc_noise;
4744 
4745 	/* rssi is in 1/2db units relative to the noise floor */
4746 	rxs.c_rssi = iwx_calculate_rssi(sc, rssi, rxs.c_nf) * 2;
4747 
4748 	if (pad) {
4749 		rxs.c_pktflags |= IEEE80211_RX_F_DECRYPTED;
4750 		rxs.c_pktflags |= IEEE80211_RX_F_IV_STRIP;
4751 	}
4752 
4753 	if (ieee80211_add_rx_params(m, &rxs) == 0) {
4754 		printf("%s: ieee80211_add_rx_params failed\n", __func__);
4755 		return;
4756 	}
4757 
4758 	ieee80211_add_rx_params(m, &rxs);
4759 
4760 #if 0
4761 	if (iwx_rx_reorder(sc, m, chanidx, desc,
4762 	    (phy_info & IWX_RX_MPDU_PHY_SHORT_PREAMBLE),
4763 	    rate_n_flags, device_timestamp, &rxi, ml))
4764 		return;
4765 #endif
4766 
4767 	if (pad) {
4768 #define TRIM 8
4769 		struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
4770 		hdrlen = ieee80211_hdrsize(wh);
4771 		memmove(m->m_data + TRIM, m->m_data, hdrlen);
4772 		m_adj(m, TRIM);
4773 #undef TRIM
4774 	}
4775 
4776 	iwx_rx_frame(sc, m, chanidx, le16toh(desc->status),
4777 	    (phy_info & IWX_RX_MPDU_PHY_SHORT_PREAMBLE),
4778 	    rate_n_flags, device_timestamp, rssi);
4779 }
4780 
4781 static void
4782 iwx_clear_tx_desc(struct iwx_softc *sc, struct iwx_tx_ring *ring, int idx)
4783 {
4784 	struct iwx_tfh_tfd *desc = &ring->desc[idx];
4785 	uint8_t num_tbs = le16toh(desc->num_tbs) & 0x1f;
4786 	int i;
4787 
4788 	/* First TB is never cleared - it is bidirectional DMA data. */
4789 	for (i = 1; i < num_tbs; i++) {
4790 		struct iwx_tfh_tb *tb = &desc->tbs[i];
4791 		memset(tb, 0, sizeof(*tb));
4792 	}
4793 	desc->num_tbs = htole16(1);
4794 
4795 	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
4796 	    BUS_DMASYNC_PREWRITE);
4797 }
4798 
4799 static void
4800 iwx_txd_done(struct iwx_softc *sc, struct iwx_tx_ring *ring,
4801     struct iwx_tx_data *txd)
4802 {
4803 	bus_dmamap_sync(ring->data_dmat, txd->map, BUS_DMASYNC_POSTWRITE);
4804 	bus_dmamap_unload(ring->data_dmat, txd->map);
4805 
4806 	ieee80211_tx_complete(&txd->in->in_ni, txd->m, 0);
4807 	txd->m = NULL;
4808 	txd->in = NULL;
4809 }
4810 
4811 static void
4812 iwx_txq_advance(struct iwx_softc *sc, struct iwx_tx_ring *ring, uint16_t idx)
4813 {
4814 	struct iwx_tx_data *txd;
4815 
4816 	while (ring->tail_hw != idx) {
4817 		txd = &ring->data[ring->tail];
4818 		if (txd->m != NULL) {
4819 			iwx_clear_tx_desc(sc, ring, ring->tail);
4820 			iwx_tx_update_byte_tbl(sc, ring, ring->tail, 0, 0);
4821 			iwx_txd_done(sc, ring, txd);
4822 			ring->queued--;
4823 			if (ring->queued < 0)
4824 				panic("caught negative queue count");
4825 		}
4826 		ring->tail = (ring->tail + 1) % IWX_TX_RING_COUNT;
4827 		ring->tail_hw = (ring->tail_hw + 1) % sc->max_tfd_queue_size;
4828 	}
4829 }
4830 
4831 static void
4832 iwx_rx_tx_cmd(struct iwx_softc *sc, struct iwx_rx_packet *pkt,
4833     struct iwx_rx_data *data)
4834 {
4835 	struct ieee80211com *ic = &sc->sc_ic;
4836 	struct ifnet *ifp = IC2IFP(ic);
4837 	struct iwx_cmd_header *cmd_hdr = &pkt->hdr;
4838 	int qid = cmd_hdr->qid, status, txfail;
4839 	struct iwx_tx_ring *ring = &sc->txq[qid];
4840 	struct iwx_tx_resp *tx_resp = (void *)pkt->data;
4841 	uint32_t ssn;
4842 	uint32_t len = iwx_rx_packet_len(pkt);
4843 	int idx = cmd_hdr->idx;
4844 	struct iwx_tx_data *txd = &ring->data[idx];
4845 	struct mbuf *m = txd->m;
4846 
4847 	bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);
4848 
4849 	/* Sanity checks. */
4850 	if (sizeof(*tx_resp) > len)
4851 		return;
4852 	if (qid < IWX_FIRST_AGG_TX_QUEUE && tx_resp->frame_count > 1)
4853 		return;
4854 	if (qid >= IWX_FIRST_AGG_TX_QUEUE && sizeof(*tx_resp) + sizeof(ssn) +
4855 	    tx_resp->frame_count * sizeof(tx_resp->status) > len)
4856 		return;
4857 
4858 	sc->sc_tx_timer[qid] = 0;
4859 
4860 	if (tx_resp->frame_count > 1) /* A-MPDU */
4861 		return;
4862 
4863 	status = le16toh(tx_resp->status.status) & IWX_TX_STATUS_MSK;
4864 	txfail = (status != IWX_TX_STATUS_SUCCESS &&
4865 	    status != IWX_TX_STATUS_DIRECT_DONE);
4866 
4867 #ifdef __not_yet__
4868 	/* TODO: Replace accounting below with ieee80211_tx_complete() */
4869 	ieee80211_tx_complete(&in->in_ni, m, txfail);
4870 #else
4871 	if (txfail)
4872 		if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
4873 	else {
4874 		if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);
4875 		if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
4876 		if (m->m_flags & M_MCAST)
4877 			if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
4878 	}
4879 #endif
4880 	/*
4881 	 * On hardware supported by iwx(4) the SSN counter corresponds
4882 	 * to a Tx ring index rather than a sequence number.
4883 	 * Frames up to this index (non-inclusive) can now be freed.
4884 	 */
4885 	memcpy(&ssn, &tx_resp->status + tx_resp->frame_count, sizeof(ssn));
4886 	ssn = le32toh(ssn);
4887 	if (ssn < sc->max_tfd_queue_size) {
4888 		iwx_txq_advance(sc, ring, ssn);
4889 		iwx_clear_oactive(sc, ring);
4890 	}
4891 }
4892 
4893 static void
4894 iwx_clear_oactive(struct iwx_softc *sc, struct iwx_tx_ring *ring)
4895 {
4896 	IWX_ASSERT_LOCKED(sc);
4897 
4898 	if (ring->queued < iwx_lomark) {
4899 		sc->qfullmsk &= ~(1 << ring->qid);
4900 		if (sc->qfullmsk == 0 /* && ifq_is_oactive(&ifp->if_snd) */) {
4901 			/*
4902 			 * Well, we're in interrupt context, but then again
4903 			 * I guess net80211 does all sorts of stunts in
4904 			 * interrupt context, so maybe this is no biggie.
4905 			 */
4906 			iwx_start(sc);
4907 		}
4908 	}
4909 }
4910 
4911 static void
4912 iwx_rx_compressed_ba(struct iwx_softc *sc, struct iwx_rx_packet *pkt)
4913 {
4914 	struct iwx_compressed_ba_notif *ba_res = (void *)pkt->data;
4915 	struct ieee80211com *ic = &sc->sc_ic;
4916 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
4917 	struct iwx_node *in = IWX_NODE(vap->iv_bss);
4918 	struct ieee80211_node *ni = &in->in_ni;
4919 	struct iwx_tx_ring *ring;
4920 	uint16_t i, tfd_cnt, ra_tid_cnt, idx;
4921 	int qid;
4922 
4923 //	if (ic->ic_state != IEEE80211_S_RUN)
4924 //		return;
4925 
4926 	if (iwx_rx_packet_payload_len(pkt) < sizeof(*ba_res))
4927 		return;
4928 
4929 	if (ba_res->sta_id != IWX_STATION_ID)
4930 		return;
4931 
4932 	in = (void *)ni;
4933 
4934 	tfd_cnt = le16toh(ba_res->tfd_cnt);
4935 	ra_tid_cnt = le16toh(ba_res->ra_tid_cnt);
4936 	if (!tfd_cnt || iwx_rx_packet_payload_len(pkt) < (sizeof(*ba_res) +
4937 	    sizeof(ba_res->ra_tid[0]) * ra_tid_cnt +
4938 	    sizeof(ba_res->tfd[0]) * tfd_cnt))
4939 		return;
4940 
4941 	for (i = 0; i < tfd_cnt; i++) {
4942 		struct iwx_compressed_ba_tfd *ba_tfd = &ba_res->tfd[i];
4943 		uint8_t tid;
4944 
4945 		tid = ba_tfd->tid;
4946 		if (tid >= nitems(sc->aggqid))
4947 			continue;
4948 
4949 		qid = sc->aggqid[tid];
4950 		if (qid != htole16(ba_tfd->q_num))
4951 			continue;
4952 
4953 		ring = &sc->txq[qid];
4954 
4955 #if 0
4956 		ba = &ni->ni_tx_ba[tid];
4957 		if (ba->ba_state != IEEE80211_BA_AGREED)
4958 			continue;
4959 #endif
4960 		idx = le16toh(ba_tfd->tfd_index);
4961 		sc->sc_tx_timer[qid] = 0;
4962 		iwx_txq_advance(sc, ring, idx);
4963 		iwx_clear_oactive(sc, ring);
4964 	}
4965 }
4966 
4967 static void
4968 iwx_rx_bmiss(struct iwx_softc *sc, struct iwx_rx_packet *pkt,
4969     struct iwx_rx_data *data)
4970 {
4971 	struct ieee80211com *ic = &sc->sc_ic;
4972 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
4973 	struct iwx_missed_beacons_notif *mbn = (void *)pkt->data;
4974 	uint32_t missed;
4975 
4976 	if ((ic->ic_opmode != IEEE80211_M_STA) ||
4977 	    (vap->iv_state != IEEE80211_S_RUN))
4978 		return;
4979 
4980 	bus_dmamap_sync(sc->rxq.data_dmat, data->map,
4981 	    BUS_DMASYNC_POSTREAD);
4982 
4983 	IWX_DPRINTF(sc, IWX_DEBUG_BEACON,
4984 	    "%s: mac_id=%u, cmslrx=%u, cmb=%u, neb=%d, nrb=%u\n",
4985 	    __func__,
4986 	    le32toh(mbn->mac_id),
4987 	    le32toh(mbn->consec_missed_beacons_since_last_rx),
4988 	    le32toh(mbn->consec_missed_beacons),
4989 	    le32toh(mbn->num_expected_beacons),
4990 	    le32toh(mbn->num_recvd_beacons));
4991 
4992 	missed = le32toh(mbn->consec_missed_beacons_since_last_rx);
4993 	if (missed > vap->iv_bmissthreshold) {
4994 		ieee80211_beacon_miss(ic);
4995 	}
4996 }
4997 
4998 static int
4999 iwx_binding_cmd(struct iwx_softc *sc, struct iwx_node *in, uint32_t action)
5000 {
5001 	struct iwx_binding_cmd cmd;
5002 	struct ieee80211com *ic = &sc->sc_ic;
5003 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
5004 	struct iwx_vap *ivp = IWX_VAP(vap);
5005 	struct iwx_phy_ctxt *phyctxt = ivp->phy_ctxt;
5006 	uint32_t mac_id = IWX_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color);
5007 	int i, err, active = (sc->sc_flags & IWX_FLAG_BINDING_ACTIVE);
5008 	uint32_t status;
5009 
5010 	if (action == IWX_FW_CTXT_ACTION_ADD && active)
5011 		panic("binding already added");
5012 	if (action == IWX_FW_CTXT_ACTION_REMOVE && !active)
5013 		panic("binding already removed");
5014 
5015 	if (phyctxt == NULL) /* XXX race with iwx_stop() */
5016 		return EINVAL;
5017 
5018 	memset(&cmd, 0, sizeof(cmd));
5019 
5020 	cmd.id_and_color
5021 	    = htole32(IWX_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
5022 	cmd.action = htole32(action);
5023 	cmd.phy = htole32(IWX_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
5024 
5025 	cmd.macs[0] = htole32(mac_id);
5026 	for (i = 1; i < IWX_MAX_MACS_IN_BINDING; i++)
5027 		cmd.macs[i] = htole32(IWX_FW_CTXT_INVALID);
5028 
5029 	if (IEEE80211_IS_CHAN_2GHZ(phyctxt->channel) ||
5030 	    !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT))
5031 		cmd.lmac_id = htole32(IWX_LMAC_24G_INDEX);
5032 	else
5033 		cmd.lmac_id = htole32(IWX_LMAC_5G_INDEX);
5034 
5035 	status = 0;
5036 	err = iwx_send_cmd_pdu_status(sc, IWX_BINDING_CONTEXT_CMD, sizeof(cmd),
5037 	    &cmd, &status);
5038 	if (err == 0 && status != 0)
5039 		err = EIO;
5040 
5041 	return err;
5042 }
5043 
5044 static uint8_t
5045 iwx_get_vht_ctrl_pos(struct ieee80211com *ic, struct ieee80211_channel *chan)
5046 {
5047 	int ctlchan = ieee80211_chan2ieee(ic, chan);
5048 	int midpoint = chan->ic_vht_ch_freq1;
5049 
5050 	/*
5051 	 * The FW is expected to check the control channel position only
5052 	 * when in HT/VHT and the channel width is not 20MHz. Return
5053 	 * this value as the default one:
5054 	 */
5055 	uint8_t pos = IWX_PHY_VHT_CTRL_POS_1_BELOW;
5056 
5057 	switch (ctlchan - midpoint) {
5058 	case -6:
5059 		pos = IWX_PHY_VHT_CTRL_POS_2_BELOW;
5060 		break;
5061 	case -2:
5062 		pos = IWX_PHY_VHT_CTRL_POS_1_BELOW;
5063 		break;
5064 	case 2:
5065 		pos = IWX_PHY_VHT_CTRL_POS_1_ABOVE;
5066 		break;
5067 	case 6:
5068 		pos = IWX_PHY_VHT_CTRL_POS_2_ABOVE;
5069 		break;
5070 	default:
5071 		break;
5072 	}
5073 
5074 	return pos;
5075 }
5076 
5077 static int
5078 iwx_phy_ctxt_cmd_uhb_v3_v4(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
5079     uint8_t chains_static, uint8_t chains_dynamic, uint32_t action, uint8_t sco,
5080     uint8_t vht_chan_width, int cmdver)
5081 {
5082 	struct ieee80211com *ic = &sc->sc_ic;
5083 	struct iwx_phy_context_cmd_uhb cmd;
5084 	uint8_t active_cnt, idle_cnt;
5085 	struct ieee80211_channel *chan = ctxt->channel;
5086 
5087 	memset(&cmd, 0, sizeof(cmd));
5088 	cmd.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(ctxt->id,
5089 	    ctxt->color));
5090 	cmd.action = htole32(action);
5091 
5092 	if (IEEE80211_IS_CHAN_2GHZ(chan) ||
5093 	    !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT))
5094 		cmd.lmac_id = htole32(IWX_LMAC_24G_INDEX);
5095 	else
5096 		cmd.lmac_id = htole32(IWX_LMAC_5G_INDEX);
5097 
5098 	cmd.ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
5099 	    IWX_PHY_BAND_24 : IWX_PHY_BAND_5;
5100 	cmd.ci.channel = htole32(ieee80211_chan2ieee(ic, chan));
5101 
5102 	if (IEEE80211_IS_CHAN_VHT80(chan)) {
5103 		cmd.ci.ctrl_pos = iwx_get_vht_ctrl_pos(ic, chan);
5104 		cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE80;
5105 	} else if (IEEE80211_IS_CHAN_HT40(chan)) {
5106 		cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE40;
5107 		if (IEEE80211_IS_CHAN_HT40D(chan))
5108 			cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_ABOVE;
5109 		else
5110 			cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW;
5111 	} else {
5112 		cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE20;
5113 		cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW;
5114 	}
5115 
5116 	if (cmdver < 4 && iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
5117 	    IWX_RLC_CONFIG_CMD) != 2) {
5118 		idle_cnt = chains_static;
5119 		active_cnt = chains_dynamic;
5120 		cmd.rxchain_info = htole32(iwx_fw_valid_rx_ant(sc) <<
5121 		    IWX_PHY_RX_CHAIN_VALID_POS);
5122 		cmd.rxchain_info |= htole32(idle_cnt <<
5123 		    IWX_PHY_RX_CHAIN_CNT_POS);
5124 		cmd.rxchain_info |= htole32(active_cnt <<
5125 		    IWX_PHY_RX_CHAIN_MIMO_CNT_POS);
5126 	}
5127 
5128 	return iwx_send_cmd_pdu(sc, IWX_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
5129 }
5130 
5131 #if 0
5132 int
5133 iwx_phy_ctxt_cmd_v3_v4(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
5134     uint8_t chains_static, uint8_t chains_dynamic, uint32_t action, uint8_t sco,
5135     uint8_t vht_chan_width, int cmdver)
5136 {
5137 	struct ieee80211com *ic = &sc->sc_ic;
5138 	struct iwx_phy_context_cmd cmd;
5139 	uint8_t active_cnt, idle_cnt;
5140 	struct ieee80211_channel *chan = ctxt->channel;
5141 
5142 	memset(&cmd, 0, sizeof(cmd));
5143 	cmd.id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(ctxt->id,
5144 	    ctxt->color));
5145 	cmd.action = htole32(action);
5146 
5147 	if (IEEE80211_IS_CHAN_2GHZ(ctxt->channel) ||
5148 	    !isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CDB_SUPPORT))
5149 		cmd.lmac_id = htole32(IWX_LMAC_24G_INDEX);
5150 	else
5151 		cmd.lmac_id = htole32(IWX_LMAC_5G_INDEX);
5152 
5153 	cmd.ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
5154 	    IWX_PHY_BAND_24 : IWX_PHY_BAND_5;
5155 	cmd.ci.channel = ieee80211_chan2ieee(ic, chan);
5156 	if (vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80) {
5157 		cmd.ci.ctrl_pos = iwx_get_vht_ctrl_pos(ic, chan);
5158 		cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE80;
5159 	} else if (chan->ic_flags & IEEE80211_CHAN_40MHZ) {
5160 		if (sco == IEEE80211_HTOP0_SCO_SCA) {
5161 			/* secondary chan above -> control chan below */
5162 			cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW;
5163 			cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE40;
5164 		} else if (sco == IEEE80211_HTOP0_SCO_SCB) {
5165 			/* secondary chan below -> control chan above */
5166 			cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_ABOVE;
5167 			cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE40;
5168 		} else {
5169 			cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE20;
5170 			cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW;
5171 		}
5172 	} else {
5173 		cmd.ci.width = IWX_PHY_VHT_CHANNEL_MODE20;
5174 		cmd.ci.ctrl_pos = IWX_PHY_VHT_CTRL_POS_1_BELOW;
5175 	}
5176 
5177 	if (cmdver < 4 && iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
5178 	    IWX_RLC_CONFIG_CMD) != 2) {
5179 		idle_cnt = chains_static;
5180 		active_cnt = chains_dynamic;
5181 		cmd.rxchain_info = htole32(iwx_fw_valid_rx_ant(sc) <<
5182 		    IWX_PHY_RX_CHAIN_VALID_POS);
5183 		cmd.rxchain_info |= htole32(idle_cnt <<
5184 		    IWX_PHY_RX_CHAIN_CNT_POS);
5185 		cmd.rxchain_info |= htole32(active_cnt <<
5186 		    IWX_PHY_RX_CHAIN_MIMO_CNT_POS);
5187 	}
5188 
5189 	return iwx_send_cmd_pdu(sc, IWX_PHY_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
5190 }
5191 #endif
5192 
5193 static int
5194 iwx_phy_ctxt_cmd(struct iwx_softc *sc, struct iwx_phy_ctxt *ctxt,
5195     uint8_t chains_static, uint8_t chains_dynamic, uint32_t action,
5196     uint32_t apply_time, uint8_t sco, uint8_t vht_chan_width)
5197 {
5198 	int cmdver;
5199 
5200 	cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_PHY_CONTEXT_CMD);
5201 	if (cmdver != 3 && cmdver != 4) {
5202 		printf("%s: firmware does not support phy-context-cmd v3/v4\n",
5203 		    DEVNAME(sc));
5204 		return ENOTSUP;
5205 	}
5206 
5207 	/*
5208 	 * Intel increased the size of the fw_channel_info struct and neglected
5209 	 * to bump the phy_context_cmd struct, which contains an fw_channel_info
5210 	 * member in the middle.
5211 	 * To keep things simple we use a separate function to handle the larger
5212 	 * variant of the phy context command.
5213 	 */
5214 	if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS)) {
5215 		return iwx_phy_ctxt_cmd_uhb_v3_v4(sc, ctxt, chains_static,
5216 		    chains_dynamic, action, sco, vht_chan_width, cmdver);
5217 	} else
5218 		panic("Unsupported old hardware contact thj@");
5219 
5220 #if 0
5221 	return iwx_phy_ctxt_cmd_v3_v4(sc, ctxt, chains_static, chains_dynamic,
5222 	    action, sco, vht_chan_width, cmdver);
5223 #endif
5224 }
5225 
5226 static int
5227 iwx_send_cmd(struct iwx_softc *sc, struct iwx_host_cmd *hcmd)
5228 {
5229 	struct iwx_tx_ring *ring = &sc->txq[IWX_DQA_CMD_QUEUE];
5230 	struct iwx_tfh_tfd *desc;
5231 	struct iwx_tx_data *txdata;
5232 	struct iwx_device_cmd *cmd;
5233 	struct mbuf *m;
5234 	bus_addr_t paddr;
5235 	uint64_t addr;
5236 	int err = 0, i, paylen, off/*, s*/;
5237 	int idx, code, async, group_id;
5238 	size_t hdrlen, datasz;
5239 	uint8_t *data;
5240 	int generation = sc->sc_generation;
5241 	bus_dma_segment_t seg[10];
5242 	int nsegs;
5243 
5244 	code = hcmd->id;
5245 	async = hcmd->flags & IWX_CMD_ASYNC;
5246 	idx = ring->cur;
5247 
5248 	for (i = 0, paylen = 0; i < nitems(hcmd->len); i++) {
5249 		paylen += hcmd->len[i];
5250 	}
5251 
5252 	/* If this command waits for a response, allocate response buffer. */
5253 	hcmd->resp_pkt = NULL;
5254 	if (hcmd->flags & IWX_CMD_WANT_RESP) {
5255 		uint8_t *resp_buf;
5256 		KASSERT(!async, ("async command want response"));
5257 		KASSERT(hcmd->resp_pkt_len >= sizeof(struct iwx_rx_packet),
5258 		    ("wrong pkt len 1"));
5259 		KASSERT(hcmd->resp_pkt_len <= IWX_CMD_RESP_MAX,
5260 		    ("wrong pkt len 2"));
5261 		if (sc->sc_cmd_resp_pkt[idx] != NULL)
5262 			return ENOSPC;
5263 		resp_buf = malloc(hcmd->resp_pkt_len, M_DEVBUF,
5264 		    M_NOWAIT | M_ZERO);
5265 		if (resp_buf == NULL)
5266 			return ENOMEM;
5267 		sc->sc_cmd_resp_pkt[idx] = resp_buf;
5268 		sc->sc_cmd_resp_len[idx] = hcmd->resp_pkt_len;
5269 	} else {
5270 		sc->sc_cmd_resp_pkt[idx] = NULL;
5271 	}
5272 
5273 	desc = &ring->desc[idx];
5274 	txdata = &ring->data[idx];
5275 
5276 	/*
5277 	 * XXX Intel inside (tm)
5278 	 * Firmware API versions >= 50 reject old-style commands in
5279 	 * group 0 with a "BAD_COMMAND" firmware error. We must pretend
5280 	 * that such commands were in the LONG_GROUP instead in order
5281 	 * for firmware to accept them.
5282 	 */
5283 	if (iwx_cmd_groupid(code) == 0) {
5284 		code = IWX_WIDE_ID(IWX_LONG_GROUP, code);
5285 		txdata->flags |= IWX_TXDATA_FLAG_CMD_IS_NARROW;
5286 	} else
5287 		txdata->flags &= ~IWX_TXDATA_FLAG_CMD_IS_NARROW;
5288 
5289 	group_id = iwx_cmd_groupid(code);
5290 
5291 	hdrlen = sizeof(cmd->hdr_wide);
5292 	datasz = sizeof(cmd->data_wide);
5293 
5294 	if (paylen > datasz) {
5295 		/* Command is too large to fit in pre-allocated space. */
5296 		size_t totlen = hdrlen + paylen;
5297 		if (paylen > IWX_MAX_CMD_PAYLOAD_SIZE) {
5298 			printf("%s: firmware command too long (%zd bytes)\n",
5299 			    DEVNAME(sc), totlen);
5300 			err = EINVAL;
5301 			goto out;
5302 		}
5303 		if (totlen > IWX_RBUF_SIZE)
5304 			panic("totlen > IWX_RBUF_SIZE");
5305 		m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, IWX_RBUF_SIZE);
5306 		if (m == NULL) {
5307 			printf("%s: could not get fw cmd mbuf (%i bytes)\n",
5308 			    DEVNAME(sc), IWX_RBUF_SIZE);
5309 			err = ENOMEM;
5310 			goto out;
5311 		}
5312 		m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
5313 		err = bus_dmamap_load_mbuf_sg(ring->data_dmat, txdata->map, m,
5314 		    seg, &nsegs, BUS_DMA_NOWAIT);
5315 		if (nsegs > 20)
5316 			panic("nsegs > 20");
5317 		DPRINTF(("%s: nsegs=%i\n", __func__, nsegs));
5318 		if (err) {
5319 			printf("%s: could not load fw cmd mbuf (%zd bytes)\n",
5320 			    DEVNAME(sc), totlen);
5321 			m_freem(m);
5322 			goto out;
5323 		}
5324 		txdata->m = m; /* mbuf will be freed in iwx_cmd_done() */
5325 		cmd = mtod(m, struct iwx_device_cmd *);
5326 		paddr = seg[0].ds_addr;
5327 	} else {
5328 		cmd = &ring->cmd[idx];
5329 		paddr = txdata->cmd_paddr;
5330 	}
5331 
5332 	memset(cmd, 0, sizeof(*cmd));
5333 	cmd->hdr_wide.opcode = iwx_cmd_opcode(code);
5334 	cmd->hdr_wide.group_id = group_id;
5335 	cmd->hdr_wide.qid = ring->qid;
5336 	cmd->hdr_wide.idx = idx;
5337 	cmd->hdr_wide.length = htole16(paylen);
5338 	cmd->hdr_wide.version = iwx_cmd_version(code);
5339 	data = cmd->data_wide;
5340 
5341 	for (i = 0, off = 0; i < nitems(hcmd->data); i++) {
5342 		if (hcmd->len[i] == 0)
5343 			continue;
5344 		memcpy(data + off, hcmd->data[i], hcmd->len[i]);
5345 		off += hcmd->len[i];
5346 	}
5347 	KASSERT(off == paylen, ("off %d != paylen %d", off, paylen));
5348 
5349 	desc->tbs[0].tb_len = htole16(MIN(hdrlen + paylen, IWX_FIRST_TB_SIZE));
5350 	addr = htole64(paddr);
5351 	memcpy(&desc->tbs[0].addr, &addr, sizeof(addr));
5352 	if (hdrlen + paylen > IWX_FIRST_TB_SIZE) {
5353 		DPRINTF(("%s: hdrlen=%zu paylen=%d\n", __func__, hdrlen,
5354 		    paylen));
5355 		desc->tbs[1].tb_len = htole16(hdrlen + paylen -
5356 		    IWX_FIRST_TB_SIZE);
5357 		addr = htole64(paddr + IWX_FIRST_TB_SIZE);
5358 		memcpy(&desc->tbs[1].addr, &addr, sizeof(addr));
5359 		desc->num_tbs = htole16(2);
5360 	} else
5361 		desc->num_tbs = htole16(1);
5362 
5363 	if (paylen > datasz) {
5364 		bus_dmamap_sync(ring->data_dmat, txdata->map,
5365 		    BUS_DMASYNC_PREWRITE);
5366 	} else {
5367 		bus_dmamap_sync(ring->cmd_dma.tag, ring->cmd_dma.map,
5368 		    BUS_DMASYNC_PREWRITE);
5369 	}
5370 	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
5371 	    BUS_DMASYNC_PREWRITE);
5372 
5373 	/* Kick command ring. */
5374 	ring->queued++;
5375 	ring->cur = (ring->cur + 1) % IWX_TX_RING_COUNT;
5376 	ring->cur_hw = (ring->cur_hw + 1) % sc->max_tfd_queue_size;
5377 	DPRINTF(("%s: ring->cur_hw=%i\n", __func__, ring->cur_hw));
5378 	IWX_WRITE(sc, IWX_HBUS_TARG_WRPTR, ring->qid << 16 | ring->cur_hw);
5379 
5380 	if (!async) {
5381 		err = msleep(desc, &sc->sc_mtx, PCATCH, "iwxcmd", hz);
5382 		if (err == 0) {
5383 			/* if hardware is no longer up, return error */
5384 			if (generation != sc->sc_generation) {
5385 				err = ENXIO;
5386 				goto out;
5387 			}
5388 
5389 			/* Response buffer will be freed in iwx_free_resp(). */
5390 			hcmd->resp_pkt = (void *)sc->sc_cmd_resp_pkt[idx];
5391 			sc->sc_cmd_resp_pkt[idx] = NULL;
5392 		} else if (generation == sc->sc_generation) {
5393 			free(sc->sc_cmd_resp_pkt[idx], M_DEVBUF);
5394 			sc->sc_cmd_resp_pkt[idx] = NULL;
5395 		}
5396 	}
5397 out:
5398 	return err;
5399 }
5400 
5401 static int
5402 iwx_send_cmd_pdu(struct iwx_softc *sc, uint32_t id, uint32_t flags,
5403     uint16_t len, const void *data)
5404 {
5405 	struct iwx_host_cmd cmd = {
5406 		.id = id,
5407 		.len = { len, },
5408 		.data = { data, },
5409 		.flags = flags,
5410 	};
5411 
5412 	return iwx_send_cmd(sc, &cmd);
5413 }
5414 
5415 static int
5416 iwx_send_cmd_status(struct iwx_softc *sc, struct iwx_host_cmd *cmd,
5417     uint32_t *status)
5418 {
5419 	struct iwx_rx_packet *pkt;
5420 	struct iwx_cmd_response *resp;
5421 	int err, resp_len;
5422 
5423 	KASSERT(((cmd->flags & IWX_CMD_WANT_RESP) == 0), ("IWX_CMD_WANT_RESP"));
5424 	cmd->flags |= IWX_CMD_WANT_RESP;
5425 	cmd->resp_pkt_len = sizeof(*pkt) + sizeof(*resp);
5426 
5427 	err = iwx_send_cmd(sc, cmd);
5428 	if (err)
5429 		return err;
5430 
5431 	pkt = cmd->resp_pkt;
5432 	if (pkt == NULL || (pkt->hdr.flags & IWX_CMD_FAILED_MSK))
5433 		return EIO;
5434 
5435 	resp_len = iwx_rx_packet_payload_len(pkt);
5436 	if (resp_len != sizeof(*resp)) {
5437 		iwx_free_resp(sc, cmd);
5438 		return EIO;
5439 	}
5440 
5441 	resp = (void *)pkt->data;
5442 	*status = le32toh(resp->status);
5443 	iwx_free_resp(sc, cmd);
5444 	return err;
5445 }
5446 
5447 static int
5448 iwx_send_cmd_pdu_status(struct iwx_softc *sc, uint32_t id, uint16_t len,
5449     const void *data, uint32_t *status)
5450 {
5451 	struct iwx_host_cmd cmd = {
5452 		.id = id,
5453 		.len = { len, },
5454 		.data = { data, },
5455 	};
5456 
5457 	return iwx_send_cmd_status(sc, &cmd, status);
5458 }
5459 
5460 static void
5461 iwx_free_resp(struct iwx_softc *sc, struct iwx_host_cmd *hcmd)
5462 {
5463 	KASSERT((hcmd->flags & (IWX_CMD_WANT_RESP)) == IWX_CMD_WANT_RESP,
5464 	    ("hcmd flags !IWX_CMD_WANT_RESP"));
5465 	free(hcmd->resp_pkt, M_DEVBUF);
5466 	hcmd->resp_pkt = NULL;
5467 }
5468 
5469 static void
5470 iwx_cmd_done(struct iwx_softc *sc, int qid, int idx, int code)
5471 {
5472 	struct iwx_tx_ring *ring = &sc->txq[IWX_DQA_CMD_QUEUE];
5473 	struct iwx_tx_data *data;
5474 
5475 	if (qid != IWX_DQA_CMD_QUEUE) {
5476 		return;	/* Not a command ack. */
5477 	}
5478 
5479 	data = &ring->data[idx];
5480 
5481 	if (data->m != NULL) {
5482 		bus_dmamap_sync(ring->data_dmat, data->map,
5483 		    BUS_DMASYNC_POSTWRITE);
5484 		bus_dmamap_unload(ring->data_dmat, data->map);
5485 		m_freem(data->m);
5486 		data->m = NULL;
5487 	}
5488 	wakeup(&ring->desc[idx]);
5489 
5490 	DPRINTF(("%s: command 0x%x done\n", __func__, code));
5491 	if (ring->queued == 0) {
5492 		DPRINTF(("%s: unexpected firmware response to command 0x%x\n",
5493 			DEVNAME(sc), code));
5494 	} else if (ring->queued > 0)
5495 		ring->queued--;
5496 }
5497 
5498 static uint32_t
5499 iwx_fw_rateidx_ofdm(uint8_t rval)
5500 {
5501 	/* Firmware expects indices which match our 11a rate set. */
5502 	const struct ieee80211_rateset *rs = &ieee80211_std_rateset_11a;
5503 	int i;
5504 
5505 	for (i = 0; i < rs->rs_nrates; i++) {
5506 		if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rval)
5507 			return i;
5508 	}
5509 
5510 	return 0;
5511 }
5512 
5513 static uint32_t
5514 iwx_fw_rateidx_cck(uint8_t rval)
5515 {
5516 	/* Firmware expects indices which match our 11b rate set. */
5517 	const struct ieee80211_rateset *rs = &ieee80211_std_rateset_11b;
5518 	int i;
5519 
5520 	for (i = 0; i < rs->rs_nrates; i++) {
5521 		if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rval)
5522 			return i;
5523 	}
5524 
5525 	return 0;
5526 }
5527 
5528 static int
5529 iwx_min_basic_rate(struct ieee80211com *ic)
5530 {
5531 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
5532 	struct ieee80211_node *ni = vap->iv_bss;
5533 	struct ieee80211_rateset *rs = &ni->ni_rates;
5534 	struct ieee80211_channel *c = ni->ni_chan;
5535 	int i, min, rval;
5536 
5537 	min = -1;
5538 
5539 	if (c == IEEE80211_CHAN_ANYC) {
5540 		printf("%s: channel is IEEE80211_CHAN_ANYC\n", __func__);
5541 		return -1;
5542 	}
5543 
5544 	for (i = 0; i < rs->rs_nrates; i++) {
5545 		if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0)
5546 			continue;
5547 		rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL);
5548 		if (min == -1)
5549 			min = rval;
5550 		else if (rval < min)
5551 			min = rval;
5552 	}
5553 
5554 	/* Default to 1 Mbit/s on 2GHz and 6 Mbit/s on 5GHz. */
5555 	if (min == -1)
5556 		min = IEEE80211_IS_CHAN_2GHZ(c) ? 2 : 12;
5557 
5558 	return min;
5559 }
5560 
5561 /*
5562  * Determine the Tx command flags and Tx rate+flags to use.
5563  * Return the selected Tx rate.
5564  */
5565 static const struct iwx_rate *
5566 iwx_tx_fill_cmd(struct iwx_softc *sc, struct iwx_node *in,
5567     struct ieee80211_frame *wh, uint16_t *flags, uint32_t *rate_n_flags,
5568     struct mbuf *m)
5569 {
5570 	struct ieee80211com *ic = &sc->sc_ic;
5571 	struct ieee80211_node *ni = &in->in_ni;
5572 	struct ieee80211_rateset *rs = &ni->ni_rates;
5573 	const struct iwx_rate *rinfo = NULL;
5574 	int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
5575 	int ridx = iwx_min_basic_rate(ic);
5576 	int min_ridx, rate_flags;
5577 	uint8_t rval;
5578 
5579 	/* We're in the process of clearing the node, no channel already */
5580 	if (ridx == -1)
5581 		return NULL;
5582 
5583 	min_ridx = iwx_rval2ridx(ridx);
5584 
5585 	*flags = 0;
5586 
5587 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
5588 	    type != IEEE80211_FC0_TYPE_DATA) {
5589 		/* for non-data, use the lowest supported rate */
5590 		ridx = min_ridx;
5591 		*flags |= IWX_TX_FLAGS_CMD_RATE;
5592 	} else if (ni->ni_flags & IEEE80211_NODE_VHT) {
5593 		/* TODO: VHT - the ridx / rate array doesn't have VHT rates yet */
5594 		ridx = iwx_min_basic_rate(ic);
5595 	} else if (ni->ni_flags & IEEE80211_NODE_HT) {
5596 		ridx = iwx_mcs2ridx[ieee80211_node_get_txrate_dot11rate(ni)
5597 		    & ~IEEE80211_RATE_MCS];
5598 	} else {
5599 		rval = (rs->rs_rates[ieee80211_node_get_txrate_dot11rate(ni)]
5600 		    & IEEE80211_RATE_VAL);
5601 		ridx = iwx_rval2ridx(rval);
5602 		if (ridx < min_ridx)
5603 			ridx = min_ridx;
5604 	}
5605 
5606 	if (m->m_flags & M_EAPOL)
5607 		*flags |= IWX_TX_FLAGS_HIGH_PRI;
5608 
5609 	rinfo = &iwx_rates[ridx];
5610 
5611 	/*
5612 	 * Do not fill rate_n_flags if firmware controls the Tx rate.
5613 	 * For data frames we rely on Tx rate scaling in firmware by default.
5614 	 */
5615 	if ((*flags & IWX_TX_FLAGS_CMD_RATE) == 0) {
5616 		*rate_n_flags = 0;
5617 		return rinfo;
5618 	}
5619 
5620 	/*
5621 	 * Forcing a CCK/OFDM legacy rate is important for management frames.
5622 	 * Association will only succeed if we do this correctly.
5623 	 */
5624 
5625 	IWX_DPRINTF(sc, IWX_DEBUG_TXRATE,"%s%d:: min_ridx=%i\n", __func__, __LINE__, min_ridx);
5626 	IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d: ridx=%i\n", __func__, __LINE__, ridx);
5627 	rate_flags = IWX_RATE_MCS_ANT_A_MSK;
5628 	if (IWX_RIDX_IS_CCK(ridx)) {
5629 		if (sc->sc_rate_n_flags_version >= 2)
5630 			rate_flags |= IWX_RATE_MCS_CCK_MSK;
5631 		else
5632 			rate_flags |= IWX_RATE_MCS_CCK_MSK_V1;
5633 	} else if (sc->sc_rate_n_flags_version >= 2)
5634 		rate_flags |= IWX_RATE_MCS_LEGACY_OFDM_MSK;
5635 
5636 	IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d: rinfo->rate=%i dot11 %d\n", __func__, __LINE__,
5637 	    rinfo->rate, rs->rs_rates[ieee80211_node_get_txrate_dot11rate(ni)]);
5638 
5639 	if (sc->sc_rate_n_flags_version >= 2) {
5640 		if (rate_flags & IWX_RATE_MCS_LEGACY_OFDM_MSK) {
5641 			rate_flags |= (iwx_fw_rateidx_ofdm(rinfo->rate) &
5642 			    IWX_RATE_LEGACY_RATE_MSK);
5643 		} else {
5644 			rate_flags |= (iwx_fw_rateidx_cck(rinfo->rate) &
5645 			    IWX_RATE_LEGACY_RATE_MSK);
5646 		}
5647 	} else
5648 		rate_flags |= rinfo->plcp;
5649 
5650 	*rate_n_flags = rate_flags;
5651 	IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d flags=0x%x\n",
5652 	    __func__, __LINE__,*flags);
5653 	IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d rate_n_flags=0x%x\n",
5654 	    __func__, __LINE__, *rate_n_flags);
5655 
5656 	if (sc->sc_debug & IWX_DEBUG_TXRATE)
5657 		print_ratenflags(__func__, __LINE__,
5658 		    *rate_n_flags, sc->sc_rate_n_flags_version);
5659 
5660 	return rinfo;
5661 }
5662 
5663 static void
5664 iwx_tx_update_byte_tbl(struct iwx_softc *sc, struct iwx_tx_ring *txq,
5665     int idx, uint16_t byte_cnt, uint16_t num_tbs)
5666 {
5667 	uint8_t filled_tfd_size, num_fetch_chunks;
5668 	uint16_t len = byte_cnt;
5669 	uint16_t bc_ent;
5670 
5671 	filled_tfd_size = offsetof(struct iwx_tfh_tfd, tbs) +
5672 			  num_tbs * sizeof(struct iwx_tfh_tb);
5673 	/*
5674 	 * filled_tfd_size contains the number of filled bytes in the TFD.
5675 	 * Dividing it by 64 will give the number of chunks to fetch
5676 	 * to SRAM- 0 for one chunk, 1 for 2 and so on.
5677 	 * If, for example, TFD contains only 3 TBs then 32 bytes
5678 	 * of the TFD are used, and only one chunk of 64 bytes should
5679 	 * be fetched
5680 	 */
5681 	num_fetch_chunks = howmany(filled_tfd_size, 64) - 1;
5682 
5683 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
5684 		struct iwx_gen3_bc_tbl_entry *scd_bc_tbl = txq->bc_tbl.vaddr;
5685 		/* Starting from AX210, the HW expects bytes */
5686 		bc_ent = htole16(len | (num_fetch_chunks << 14));
5687 		scd_bc_tbl[idx].tfd_offset = bc_ent;
5688 	} else {
5689 		struct iwx_agn_scd_bc_tbl *scd_bc_tbl = txq->bc_tbl.vaddr;
5690 		/* Before AX210, the HW expects DW */
5691 		len = howmany(len, 4);
5692 		bc_ent = htole16(len | (num_fetch_chunks << 12));
5693 		scd_bc_tbl->tfd_offset[idx] = bc_ent;
5694 	}
5695 
5696 	bus_dmamap_sync(sc->sc_dmat, txq->bc_tbl.map, BUS_DMASYNC_PREWRITE);
5697 }
5698 
5699 static int
5700 iwx_tx(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
5701 {
5702 	struct ieee80211com *ic = &sc->sc_ic;
5703 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
5704 	struct iwx_node *in = (void *)ni;
5705 	struct iwx_tx_ring *ring;
5706 	struct iwx_tx_data *data;
5707 	struct iwx_tfh_tfd *desc;
5708 	struct iwx_device_cmd *cmd;
5709 	struct ieee80211_frame *wh;
5710 	struct ieee80211_key *k = NULL;
5711 	const struct iwx_rate *rinfo;
5712 	uint64_t paddr;
5713 	u_int hdrlen;
5714 	uint32_t rate_n_flags;
5715 	uint16_t num_tbs, flags, offload_assist = 0;
5716 	int i, totlen, err, pad, qid;
5717 #define IWM_MAX_SCATTER 20
5718 	bus_dma_segment_t *seg, segs[IWM_MAX_SCATTER];
5719 	int nsegs;
5720 	struct mbuf *m1;
5721 	size_t txcmd_size;
5722 
5723 	IWX_ASSERT_LOCKED(sc);
5724 
5725 	wh = mtod(m, struct ieee80211_frame *);
5726 	hdrlen = ieee80211_anyhdrsize(wh);
5727 
5728 	qid = sc->first_data_qid;
5729 
5730 	/* Put QoS frames on the data queue which maps to their TID. */
5731 	if (IEEE80211_QOS_HAS_SEQ(wh)) {
5732 		uint16_t qos = ieee80211_gettid(wh);
5733 		uint8_t tid = qos & IEEE80211_QOS_TID;
5734 		struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid];
5735 
5736 		/*
5737 		 * Note: we're currently putting all frames into one queue
5738 		 * except for A-MPDU queues.  We should be able to choose
5739 		 * other WME queues but first we need to verify they've been
5740 		 * correctly setup for data.
5741 		 */
5742 
5743 		/*
5744 		 * Only QoS data goes into an A-MPDU queue;
5745 		 * don't add QoS null, the other data types, etc.
5746 		 */
5747 		if (IEEE80211_AMPDU_RUNNING(tap) &&
5748 		    IEEE80211_IS_QOSDATA(wh) &&
5749 		    !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
5750 		    sc->aggqid[tid] != 0) {
5751 			qid = sc->aggqid[tid];
5752 		}
5753 	}
5754 
5755 	ring = &sc->txq[qid];
5756 	desc = &ring->desc[ring->cur];
5757 	memset(desc, 0, sizeof(*desc));
5758 	data = &ring->data[ring->cur];
5759 
5760 	cmd = &ring->cmd[ring->cur];
5761 	cmd->hdr.code = IWX_TX_CMD;
5762 	cmd->hdr.flags = 0;
5763 	cmd->hdr.qid = ring->qid;
5764 	cmd->hdr.idx = ring->cur;
5765 
5766 	rinfo = iwx_tx_fill_cmd(sc, in, wh, &flags, &rate_n_flags, m);
5767 	if (rinfo == NULL)
5768 		return EINVAL;
5769 
5770 	/* Offloaded sequence number assignment; non-AMPDU case */
5771 	if ((m->m_flags & M_AMPDU_MPDU) == 0)
5772 		ieee80211_output_seqno_assign(ni, -1, m);
5773 
5774 	/* Radiotap */
5775 	if (ieee80211_radiotap_active_vap(vap)) {
5776 		struct iwx_tx_radiotap_header *tap = &sc->sc_txtap;
5777 
5778 		tap->wt_flags = 0;
5779 		tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
5780 		tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
5781 		tap->wt_rate = rinfo->rate;
5782 		if (k != NULL)
5783 			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
5784 		ieee80211_radiotap_tx(vap, m);
5785 	}
5786 
5787 	/* Encrypt - CCMP via direct HW path, TKIP/WEP indirected openbsd-style for now */
5788 	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
5789 		k = ieee80211_crypto_get_txkey(ni, m);
5790 		if (k == NULL) {
5791 			printf("%s: k is NULL!\n", __func__);
5792 			m_freem(m);
5793 			return (ENOBUFS);
5794 		} else if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) {
5795 			k->wk_keytsc++;
5796 		} else {
5797 			k->wk_cipher->ic_encap(k, m);
5798 
5799 			/* 802.11 headers may have moved */
5800 			wh = mtod(m, struct ieee80211_frame *);
5801 			flags |= IWX_TX_FLAGS_ENCRYPT_DIS;
5802 		}
5803 	} else
5804 		flags |= IWX_TX_FLAGS_ENCRYPT_DIS;
5805 
5806 	totlen = m->m_pkthdr.len;
5807 
5808 	if (hdrlen & 3) {
5809 		/* First segment length must be a multiple of 4. */
5810 		pad = 4 - (hdrlen & 3);
5811 		offload_assist |= IWX_TX_CMD_OFFLD_PAD;
5812 	} else
5813 		pad = 0;
5814 
5815 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
5816 		struct iwx_tx_cmd_gen3 *tx = (void *)cmd->data;
5817 		memset(tx, 0, sizeof(*tx));
5818 		tx->len = htole16(totlen);
5819 		tx->offload_assist = htole32(offload_assist);
5820 		tx->flags = htole16(flags);
5821 		tx->rate_n_flags = htole32(rate_n_flags);
5822 		memcpy(tx->hdr, wh, hdrlen);
5823 		txcmd_size = sizeof(*tx);
5824 	} else {
5825 		struct iwx_tx_cmd_gen2 *tx = (void *)cmd->data;
5826 		memset(tx, 0, sizeof(*tx));
5827 		tx->len = htole16(totlen);
5828 		tx->offload_assist = htole16(offload_assist);
5829 		tx->flags = htole32(flags);
5830 		tx->rate_n_flags = htole32(rate_n_flags);
5831 		memcpy(tx->hdr, wh, hdrlen);
5832 		txcmd_size = sizeof(*tx);
5833 	}
5834 
5835 	/* Trim 802.11 header. */
5836 	m_adj(m, hdrlen);
5837 
5838 	err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, segs,
5839 	    &nsegs, BUS_DMA_NOWAIT);
5840 	if (err && err != EFBIG) {
5841 		printf("%s: can't map mbuf (error %d)\n", DEVNAME(sc), err);
5842 		m_freem(m);
5843 		return err;
5844 	}
5845 	if (err) {
5846 		/* Too many DMA segments, linearize mbuf. */
5847 		m1 = m_collapse(m, M_NOWAIT, IWM_MAX_SCATTER - 2);
5848 		if (m1 == NULL) {
5849 			printf("%s: could not defrag mbufs\n", __func__);
5850 			m_freem(m);
5851 			return (ENOBUFS);
5852 		}
5853 		m = m1;
5854 		err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m,
5855 		    segs, &nsegs, BUS_DMA_NOWAIT);
5856 		if (err) {
5857 			printf("%s: can't map mbuf (error %d)\n", __func__,
5858 			    err);
5859 			m_freem(m);
5860 			return (err);
5861 		}
5862 	}
5863 	data->m = m;
5864 	data->in = in;
5865 
5866 	/* Fill TX descriptor. */
5867 	num_tbs = 2 + nsegs;
5868 	desc->num_tbs = htole16(num_tbs);
5869 
5870 	desc->tbs[0].tb_len = htole16(IWX_FIRST_TB_SIZE);
5871 	paddr = htole64(data->cmd_paddr);
5872 	memcpy(&desc->tbs[0].addr, &paddr, sizeof(paddr));
5873 #if __SIZEOF_SIZE_T__ > 4
5874 	if (data->cmd_paddr >> 32 != (data->cmd_paddr +
5875 	    le32toh(desc->tbs[0].tb_len)) >> 32)
5876 		DPRINTF(("%s: TB0 crosses 32bit boundary\n", __func__));
5877 #endif
5878 	desc->tbs[1].tb_len = htole16(sizeof(struct iwx_cmd_header) +
5879 	    txcmd_size + hdrlen + pad - IWX_FIRST_TB_SIZE);
5880 	paddr = htole64(data->cmd_paddr + IWX_FIRST_TB_SIZE);
5881 	memcpy(&desc->tbs[1].addr, &paddr, sizeof(paddr));
5882 
5883 #if __SIZEOF_SIZE_T__ > 4
5884 	if (data->cmd_paddr >> 32 != (data->cmd_paddr +
5885 	    le32toh(desc->tbs[1].tb_len)) >> 32)
5886 		DPRINTF(("%s: TB1 crosses 32bit boundary\n", __func__));
5887 #endif
5888 
5889 	/* Other DMA segments are for data payload. */
5890 	for (i = 0; i < nsegs; i++) {
5891 		seg = &segs[i];
5892 		desc->tbs[i + 2].tb_len = htole16(seg->ds_len);
5893 		paddr = htole64(seg->ds_addr);
5894 		memcpy(&desc->tbs[i + 2].addr, &paddr, sizeof(paddr));
5895 #if __SIZEOF_SIZE_T__ > 4
5896 		if (data->cmd_paddr >> 32 != (data->cmd_paddr +
5897 		    le32toh(desc->tbs[i + 2].tb_len)) >> 32)
5898 			DPRINTF(("%s: TB%d crosses 32bit boundary\n", __func__,
5899 			    i + 2));
5900 #endif
5901 	}
5902 
5903 	bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
5904 	bus_dmamap_sync(ring->cmd_dma.tag, ring->cmd_dma.map,
5905 	    BUS_DMASYNC_PREWRITE);
5906 	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
5907 	    BUS_DMASYNC_PREWRITE);
5908 
5909 	iwx_tx_update_byte_tbl(sc, ring, ring->cur, totlen, num_tbs);
5910 
5911 	/* Kick TX ring. */
5912 	ring->cur = (ring->cur + 1) % IWX_TX_RING_COUNT;
5913 	ring->cur_hw = (ring->cur_hw + 1) % sc->max_tfd_queue_size;
5914 	IWX_WRITE(sc, IWX_HBUS_TARG_WRPTR, ring->qid << 16 | ring->cur_hw);
5915 
5916 	/* Mark TX ring as full if we reach a certain threshold. */
5917 	if (++ring->queued > iwx_himark) {
5918 		sc->qfullmsk |= 1 << ring->qid;
5919 	}
5920 
5921 	sc->sc_tx_timer[ring->qid] = 15;
5922 
5923 	return 0;
5924 }
5925 
5926 static int
5927 iwx_flush_sta_tids(struct iwx_softc *sc, int sta_id, uint16_t tids)
5928 {
5929 	struct iwx_rx_packet *pkt;
5930 	struct iwx_tx_path_flush_cmd_rsp *resp;
5931 	struct iwx_tx_path_flush_cmd flush_cmd = {
5932 		.sta_id = htole32(sta_id),
5933 		.tid_mask = htole16(tids),
5934 	};
5935 	struct iwx_host_cmd hcmd = {
5936 		.id = IWX_TXPATH_FLUSH,
5937 		.len = { sizeof(flush_cmd), },
5938 		.data = { &flush_cmd, },
5939 		.flags = IWX_CMD_WANT_RESP,
5940 		.resp_pkt_len = sizeof(*pkt) + sizeof(*resp),
5941 	};
5942 	int err, resp_len, i, num_flushed_queues;
5943 
5944 	err = iwx_send_cmd(sc, &hcmd);
5945 	if (err)
5946 		return err;
5947 
5948 	pkt = hcmd.resp_pkt;
5949 	if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) {
5950 		err = EIO;
5951 		goto out;
5952 	}
5953 
5954 	resp_len = iwx_rx_packet_payload_len(pkt);
5955 	/* Some firmware versions don't provide a response. */
5956 	if (resp_len != sizeof(*resp)) {
5957 		err = EIO;
5958 		goto out;
5959 	}
5960 
5961 	resp = (void *)pkt->data;
5962 
5963 	if (le16toh(resp->sta_id) != sta_id) {
5964 		err = EIO;
5965 		goto out;
5966 	}
5967 
5968 	num_flushed_queues = le16toh(resp->num_flushed_queues);
5969 	if (num_flushed_queues > IWX_TX_FLUSH_QUEUE_RSP) {
5970 		err = EIO;
5971 		goto out;
5972 	}
5973 
5974 	for (i = 0; i < num_flushed_queues; i++) {
5975 		struct iwx_flush_queue_info *queue_info = &resp->queues[i];
5976 		uint16_t tid = le16toh(queue_info->tid);
5977 		uint16_t read_after = le16toh(queue_info->read_after_flush);
5978 		uint16_t qid = le16toh(queue_info->queue_num);
5979 		struct iwx_tx_ring *txq;
5980 
5981 		if (qid >= nitems(sc->txq))
5982 			continue;
5983 
5984 		txq = &sc->txq[qid];
5985 		if (tid != txq->tid)
5986 			continue;
5987 
5988 		iwx_txq_advance(sc, txq, read_after);
5989 	}
5990 out:
5991 	iwx_free_resp(sc, &hcmd);
5992 	return err;
5993 }
5994 
5995 #define IWX_FLUSH_WAIT_MS	2000
5996 
5997 static int
5998 iwx_drain_sta(struct iwx_softc *sc, struct iwx_node* in, int drain)
5999 {
6000 	struct iwx_add_sta_cmd cmd;
6001 	int err;
6002 	uint32_t status;
6003 
6004 	memset(&cmd, 0, sizeof(cmd));
6005 	cmd.mac_id_n_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id,
6006 	    in->in_color));
6007 	cmd.sta_id = IWX_STATION_ID;
6008 	cmd.add_modify = IWX_STA_MODE_MODIFY;
6009 	cmd.station_flags = drain ? htole32(IWX_STA_FLG_DRAIN_FLOW) : 0;
6010 	cmd.station_flags_msk = htole32(IWX_STA_FLG_DRAIN_FLOW);
6011 
6012 	status = IWX_ADD_STA_SUCCESS;
6013 	err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA,
6014 	    sizeof(cmd), &cmd, &status);
6015 	if (err) {
6016 		printf("%s: could not update sta (error %d)\n",
6017 		    DEVNAME(sc), err);
6018 		return err;
6019 	}
6020 
6021 	switch (status & IWX_ADD_STA_STATUS_MASK) {
6022 	case IWX_ADD_STA_SUCCESS:
6023 		break;
6024 	default:
6025 		err = EIO;
6026 		printf("%s: Couldn't %s draining for station\n",
6027 		    DEVNAME(sc), drain ? "enable" : "disable");
6028 		break;
6029 	}
6030 
6031 	return err;
6032 }
6033 
6034 static int
6035 iwx_flush_sta(struct iwx_softc *sc, struct iwx_node *in)
6036 {
6037 	int err;
6038 
6039 	IWX_ASSERT_LOCKED(sc);
6040 
6041 	sc->sc_flags |= IWX_FLAG_TXFLUSH;
6042 
6043 	err = iwx_drain_sta(sc, in, 1);
6044 	if (err)
6045 		goto done;
6046 
6047 	err = iwx_flush_sta_tids(sc, IWX_STATION_ID, 0xffff);
6048 	if (err) {
6049 		printf("%s: could not flush Tx path (error %d)\n",
6050 		    DEVNAME(sc), err);
6051 		goto done;
6052 	}
6053 
6054 	err = iwx_drain_sta(sc, in, 0);
6055 done:
6056 	sc->sc_flags &= ~IWX_FLAG_TXFLUSH;
6057 	return err;
6058 }
6059 
6060 #define IWX_POWER_KEEP_ALIVE_PERIOD_SEC    25
6061 
6062 static int
6063 iwx_beacon_filter_send_cmd(struct iwx_softc *sc,
6064     struct iwx_beacon_filter_cmd *cmd)
6065 {
6066 	return iwx_send_cmd_pdu(sc, IWX_REPLY_BEACON_FILTERING_CMD,
6067 	    0, sizeof(struct iwx_beacon_filter_cmd), cmd);
6068 }
6069 
6070 static int
6071 iwx_update_beacon_abort(struct iwx_softc *sc, struct iwx_node *in, int enable)
6072 {
6073 	struct iwx_beacon_filter_cmd cmd = {
6074 		IWX_BF_CMD_CONFIG_DEFAULTS,
6075 		.bf_enable_beacon_filter = htole32(1),
6076 		.ba_enable_beacon_abort = htole32(enable),
6077 	};
6078 
6079 	if (!sc->sc_bf.bf_enabled)
6080 		return 0;
6081 
6082 	sc->sc_bf.ba_enabled = enable;
6083 	return iwx_beacon_filter_send_cmd(sc, &cmd);
6084 }
6085 
6086 static void
6087 iwx_power_build_cmd(struct iwx_softc *sc, struct iwx_node *in,
6088     struct iwx_mac_power_cmd *cmd)
6089 {
6090 	struct ieee80211com *ic = &sc->sc_ic;
6091 	struct ieee80211_node *ni = &in->in_ni;
6092 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
6093 	int dtim_period, dtim_msec, keep_alive;
6094 
6095 	cmd->id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id,
6096 	    in->in_color));
6097 	if (vap->iv_dtim_period)
6098 		dtim_period = vap->iv_dtim_period;
6099 	else
6100 		dtim_period = 1;
6101 
6102 	/*
6103 	 * Regardless of power management state the driver must set
6104 	 * keep alive period. FW will use it for sending keep alive NDPs
6105 	 * immediately after association. Check that keep alive period
6106 	 * is at least 3 * DTIM.
6107 	 */
6108 	dtim_msec = dtim_period * ni->ni_intval;
6109 	keep_alive = MAX(3 * dtim_msec, 1000 * IWX_POWER_KEEP_ALIVE_PERIOD_SEC);
6110 	keep_alive = roundup(keep_alive, 1000) / 1000;
6111 	cmd->keep_alive_seconds = htole16(keep_alive);
6112 
6113 	if (ic->ic_opmode != IEEE80211_M_MONITOR)
6114 		cmd->flags = htole16(IWX_POWER_FLAGS_POWER_SAVE_ENA_MSK);
6115 }
6116 
6117 static int
6118 iwx_power_mac_update_mode(struct iwx_softc *sc, struct iwx_node *in)
6119 {
6120 	int err;
6121 	int ba_enable;
6122 	struct iwx_mac_power_cmd cmd;
6123 
6124 	memset(&cmd, 0, sizeof(cmd));
6125 
6126 	iwx_power_build_cmd(sc, in, &cmd);
6127 
6128 	err = iwx_send_cmd_pdu(sc, IWX_MAC_PM_POWER_TABLE, 0,
6129 	    sizeof(cmd), &cmd);
6130 	if (err != 0)
6131 		return err;
6132 
6133 	ba_enable = !!(cmd.flags &
6134 	    htole16(IWX_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
6135 	return iwx_update_beacon_abort(sc, in, ba_enable);
6136 }
6137 
6138 static int
6139 iwx_power_update_device(struct iwx_softc *sc)
6140 {
6141 	struct iwx_device_power_cmd cmd = { };
6142 	struct ieee80211com *ic = &sc->sc_ic;
6143 
6144 	if (ic->ic_opmode != IEEE80211_M_MONITOR)
6145 		cmd.flags = htole16(IWX_DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK);
6146 
6147 	return iwx_send_cmd_pdu(sc,
6148 	    IWX_POWER_TABLE_CMD, 0, sizeof(cmd), &cmd);
6149 }
6150 #if 0
6151 static int
6152 iwx_enable_beacon_filter(struct iwx_softc *sc, struct iwx_node *in)
6153 {
6154 	struct iwx_beacon_filter_cmd cmd = {
6155 		IWX_BF_CMD_CONFIG_DEFAULTS,
6156 		.bf_enable_beacon_filter = htole32(1),
6157 		.ba_enable_beacon_abort = htole32(sc->sc_bf.ba_enabled),
6158 	};
6159 	int err;
6160 
6161 	err = iwx_beacon_filter_send_cmd(sc, &cmd);
6162 	if (err == 0)
6163 		sc->sc_bf.bf_enabled = 1;
6164 
6165 	return err;
6166 }
6167 #endif
6168 static int
6169 iwx_disable_beacon_filter(struct iwx_softc *sc)
6170 {
6171 	struct iwx_beacon_filter_cmd cmd;
6172 	int err;
6173 
6174 	memset(&cmd, 0, sizeof(cmd));
6175 
6176 	err = iwx_beacon_filter_send_cmd(sc, &cmd);
6177 	if (err == 0)
6178 		sc->sc_bf.bf_enabled = 0;
6179 
6180 	return err;
6181 }
6182 
6183 static int
6184 iwx_add_sta_cmd(struct iwx_softc *sc, struct iwx_node *in, int update)
6185 {
6186 	struct iwx_add_sta_cmd add_sta_cmd;
6187 	int err, i;
6188 	uint32_t status, aggsize;
6189 	const uint32_t max_aggsize = (IWX_STA_FLG_MAX_AGG_SIZE_64K >>
6190 		    IWX_STA_FLG_MAX_AGG_SIZE_SHIFT);
6191 	struct ieee80211com *ic = &sc->sc_ic;
6192 	struct ieee80211_node *ni = &in->in_ni;
6193 	struct ieee80211_htrateset *htrs = &ni->ni_htrates;
6194 
6195 	if (!update && (sc->sc_flags & IWX_FLAG_STA_ACTIVE))
6196 		panic("STA already added");
6197 
6198 	memset(&add_sta_cmd, 0, sizeof(add_sta_cmd));
6199 
6200 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
6201 		add_sta_cmd.sta_id = IWX_MONITOR_STA_ID;
6202 		add_sta_cmd.station_type = IWX_STA_GENERAL_PURPOSE;
6203 	} else {
6204 		add_sta_cmd.sta_id = IWX_STATION_ID;
6205 		add_sta_cmd.station_type = IWX_STA_LINK;
6206 	}
6207 	add_sta_cmd.mac_id_n_color
6208 	    = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
6209 	if (!update) {
6210 		if (ic->ic_opmode == IEEE80211_M_MONITOR)
6211 			IEEE80211_ADDR_COPY(&add_sta_cmd.addr,
6212 			    etheranyaddr);
6213 		else
6214 			IEEE80211_ADDR_COPY(&add_sta_cmd.addr,
6215 			    in->in_macaddr);
6216 	}
6217 	DPRINTF(("%s: add_sta_cmd.addr=%s\n", __func__,
6218 	    ether_sprintf(add_sta_cmd.addr)));
6219 	add_sta_cmd.add_modify = update ? 1 : 0;
6220 	add_sta_cmd.station_flags_msk
6221 	    |= htole32(IWX_STA_FLG_FAT_EN_MSK | IWX_STA_FLG_MIMO_EN_MSK);
6222 
6223 	if (in->in_ni.ni_flags & IEEE80211_NODE_HT) {
6224 		add_sta_cmd.station_flags_msk
6225 		    |= htole32(IWX_STA_FLG_MAX_AGG_SIZE_MSK |
6226 		    IWX_STA_FLG_AGG_MPDU_DENS_MSK);
6227 
6228 		if (iwx_mimo_enabled(sc)) {
6229 			if (ni->ni_flags & IEEE80211_NODE_VHT) {
6230 				add_sta_cmd.station_flags |=
6231 				    htole32(IWX_STA_FLG_MIMO_EN_MIMO2);
6232 			} else {
6233 				int hasmimo = 0;
6234 				for (i = 0; i < htrs->rs_nrates; i++) {
6235 					if (htrs->rs_rates[i] > 7) {
6236 						hasmimo = 1;
6237 						break;
6238 					}
6239 				}
6240 				if (hasmimo) {
6241 					add_sta_cmd.station_flags |=
6242 					    htole32(IWX_STA_FLG_MIMO_EN_MIMO2);
6243 				}
6244 			}
6245 		}
6246 
6247 		if (ni->ni_flags & IEEE80211_NODE_HT &&
6248 		    IEEE80211_IS_CHAN_HT40(ni->ni_chan)) {
6249 			add_sta_cmd.station_flags |= htole32(
6250 			    IWX_STA_FLG_FAT_EN_40MHZ);
6251 		}
6252 
6253 
6254 		if (ni->ni_flags & IEEE80211_NODE_VHT) {
6255 			if (IEEE80211_IS_CHAN_VHT80(ni->ni_chan)) {
6256 				add_sta_cmd.station_flags |= htole32(
6257 				    IWX_STA_FLG_FAT_EN_80MHZ);
6258 			}
6259 			// XXX-misha: TODO get real ampdu size
6260 			aggsize = max_aggsize;
6261 		} else {
6262 			aggsize = _IEEE80211_MASKSHIFT(le16toh(ni->ni_htparam),
6263 			    IEEE80211_HTCAP_MAXRXAMPDU);
6264 		}
6265 
6266 		if (aggsize > max_aggsize)
6267 			aggsize = max_aggsize;
6268 		add_sta_cmd.station_flags |= htole32((aggsize <<
6269 		    IWX_STA_FLG_MAX_AGG_SIZE_SHIFT) &
6270 		    IWX_STA_FLG_MAX_AGG_SIZE_MSK);
6271 
6272 		switch (_IEEE80211_MASKSHIFT(le16toh(ni->ni_htparam),
6273 		    IEEE80211_HTCAP_MPDUDENSITY)) {
6274 		case IEEE80211_HTCAP_MPDUDENSITY_2:
6275 			add_sta_cmd.station_flags
6276 			    |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_2US);
6277 			break;
6278 		case IEEE80211_HTCAP_MPDUDENSITY_4:
6279 			add_sta_cmd.station_flags
6280 			    |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_4US);
6281 			break;
6282 		case IEEE80211_HTCAP_MPDUDENSITY_8:
6283 			add_sta_cmd.station_flags
6284 			    |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_8US);
6285 			break;
6286 		case IEEE80211_HTCAP_MPDUDENSITY_16:
6287 			add_sta_cmd.station_flags
6288 			    |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_16US);
6289 			break;
6290 		default:
6291 			break;
6292 		}
6293 	}
6294 
6295 	status = IWX_ADD_STA_SUCCESS;
6296 	err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA, sizeof(add_sta_cmd),
6297 	    &add_sta_cmd, &status);
6298 	if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS)
6299 		err = EIO;
6300 
6301 	return err;
6302 }
6303 
6304 static int
6305 iwx_rm_sta_cmd(struct iwx_softc *sc, struct iwx_node *in)
6306 {
6307 	struct ieee80211com *ic = &sc->sc_ic;
6308 	struct iwx_rm_sta_cmd rm_sta_cmd;
6309 	int err;
6310 
6311 	if ((sc->sc_flags & IWX_FLAG_STA_ACTIVE) == 0)
6312 		panic("sta already removed");
6313 
6314 	memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
6315 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
6316 		rm_sta_cmd.sta_id = IWX_MONITOR_STA_ID;
6317 	else
6318 		rm_sta_cmd.sta_id = IWX_STATION_ID;
6319 
6320 	err = iwx_send_cmd_pdu(sc, IWX_REMOVE_STA, 0, sizeof(rm_sta_cmd),
6321 	    &rm_sta_cmd);
6322 
6323 	return err;
6324 }
6325 
6326 static int
6327 iwx_rm_sta(struct iwx_softc *sc, struct iwx_node *in)
6328 {
6329 	int err, i, cmd_ver;
6330 
6331 	err = iwx_flush_sta(sc, in);
6332 	if (err) {
6333 		printf("%s: could not flush Tx path (error %d)\n",
6334 		    DEVNAME(sc), err);
6335 		return err;
6336 	}
6337 
6338 	/*
6339 	 * New SCD_QUEUE_CONFIG API requires explicit queue removal
6340 	 * before a station gets removed.
6341 	 */
6342 	cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
6343 	    IWX_SCD_QUEUE_CONFIG_CMD);
6344 	if (cmd_ver != 0 && cmd_ver != IWX_FW_CMD_VER_UNKNOWN) {
6345 		err = iwx_disable_mgmt_queue(sc);
6346 		if (err)
6347 			return err;
6348 		for (i = IWX_FIRST_AGG_TX_QUEUE;
6349 		    i < IWX_LAST_AGG_TX_QUEUE; i++) {
6350 			struct iwx_tx_ring *ring = &sc->txq[i];
6351 			if ((sc->qenablemsk & (1 << i)) == 0)
6352 				continue;
6353 			err = iwx_disable_txq(sc, IWX_STATION_ID,
6354 			    ring->qid, ring->tid);
6355 			if (err) {
6356 				printf("%s: could not disable Tx queue %d "
6357 				    "(error %d)\n", DEVNAME(sc), ring->qid,
6358 				    err);
6359 				return err;
6360 			}
6361 		}
6362 	}
6363 
6364 	err = iwx_rm_sta_cmd(sc, in);
6365 	if (err) {
6366 		printf("%s: could not remove STA (error %d)\n",
6367 		    DEVNAME(sc), err);
6368 		return err;
6369 	}
6370 
6371 	in->in_flags = 0;
6372 
6373 	sc->sc_rx_ba_sessions = 0;
6374 	sc->ba_rx.start_tidmask = 0;
6375 	sc->ba_rx.stop_tidmask = 0;
6376 	memset(sc->aggqid, 0, sizeof(sc->aggqid));
6377 	sc->ba_tx.start_tidmask = 0;
6378 	sc->ba_tx.stop_tidmask = 0;
6379 	for (i = IWX_FIRST_AGG_TX_QUEUE; i < IWX_LAST_AGG_TX_QUEUE; i++)
6380 		sc->qenablemsk &= ~(1 << i);
6381 
6382 #if 0
6383 	for (i = 0; i < IEEE80211_NUM_TID; i++) {
6384 		struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[i];
6385 		if (ba->ba_state != IEEE80211_BA_AGREED)
6386 			continue;
6387 		ieee80211_delba_request(ic, ni, 0, 1, i);
6388 	}
6389 #endif
6390 	/* Clear ampdu rx state (GOS-1525) */
6391 	for (i = 0; i < IWX_MAX_TID_COUNT; i++) {
6392 		struct iwx_rx_ba *ba = &sc->ni_rx_ba[i];
6393 		ba->ba_flags = 0;
6394 	}
6395 
6396 	return 0;
6397 }
6398 
6399 static uint8_t
6400 iwx_umac_scan_fill_channels(struct iwx_softc *sc,
6401     struct iwx_scan_channel_cfg_umac *chan, size_t chan_nitems,
6402     int n_ssids, uint32_t channel_cfg_flags)
6403 {
6404 	struct ieee80211com *ic = &sc->sc_ic;
6405 	struct ieee80211_scan_state *ss = ic->ic_scan;
6406 	struct ieee80211_channel *c;
6407 	uint8_t nchan;
6408 	int j;
6409 
6410 	for (nchan = j = 0;
6411 	    j < ss->ss_last &&
6412 	    nchan < sc->sc_capa_n_scan_channels;
6413 	    j++) {
6414 		uint8_t channel_num;
6415 
6416 		c = ss->ss_chans[j];
6417 		channel_num = ieee80211_mhz2ieee(c->ic_freq, 0);
6418 		if (isset(sc->sc_ucode_api,
6419 		    IWX_UCODE_TLV_API_SCAN_EXT_CHAN_VER)) {
6420 			chan->v2.channel_num = channel_num;
6421 			if (IEEE80211_IS_CHAN_2GHZ(c))
6422 				chan->v2.band = IWX_PHY_BAND_24;
6423 			else
6424 				chan->v2.band = IWX_PHY_BAND_5;
6425 			chan->v2.iter_count = 1;
6426 			chan->v2.iter_interval = 0;
6427 		} else {
6428 			chan->v1.channel_num = channel_num;
6429 			chan->v1.iter_count = 1;
6430 			chan->v1.iter_interval = htole16(0);
6431 		}
6432 		chan->flags |= htole32(channel_cfg_flags);
6433 		chan++;
6434 		nchan++;
6435 	}
6436 
6437 	return nchan;
6438 }
6439 
6440 static int
6441 iwx_fill_probe_req(struct iwx_softc *sc, struct iwx_scan_probe_req *preq)
6442 {
6443 	struct ieee80211com *ic = &sc->sc_ic;
6444 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
6445 	struct ieee80211_frame *wh = (struct ieee80211_frame *)preq->buf;
6446 	struct ieee80211_rateset *rs;
6447 	size_t remain = sizeof(preq->buf);
6448 	uint8_t *frm, *pos;
6449 
6450 	memset(preq, 0, sizeof(*preq));
6451 
6452 	if (remain < sizeof(*wh) + 2)
6453 		return ENOBUFS;
6454 
6455 	/*
6456 	 * Build a probe request frame.  Most of the following code is a
6457 	 * copy & paste of what is done in net80211.
6458 	 */
6459 	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
6460 	    IEEE80211_FC0_SUBTYPE_PROBE_REQ;
6461 	wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
6462 	IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr);
6463 	IEEE80211_ADDR_COPY(wh->i_addr2, vap ? vap->iv_myaddr : ic->ic_macaddr);
6464 	IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr);
6465 	*(uint16_t *)&wh->i_dur[0] = 0;	/* filled by HW */
6466 	*(uint16_t *)&wh->i_seq[0] = 0;	/* filled by HW */
6467 
6468 	frm = (uint8_t *)(wh + 1);
6469 	*frm++ = IEEE80211_ELEMID_SSID;
6470 	*frm++ = 0;
6471 	/* hardware inserts SSID */
6472 
6473 	/* Tell the firmware where the MAC header is. */
6474 	preq->mac_header.offset = 0;
6475 	preq->mac_header.len = htole16(frm - (uint8_t *)wh);
6476 	remain -= frm - (uint8_t *)wh;
6477 
6478 	/* Fill in 2GHz IEs and tell firmware where they are. */
6479 	rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
6480 	if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
6481 		if (remain < 4 + rs->rs_nrates)
6482 			return ENOBUFS;
6483 	} else if (remain < 2 + rs->rs_nrates)
6484 		return ENOBUFS;
6485 	preq->band_data[0].offset = htole16(frm - (uint8_t *)wh);
6486 	pos = frm;
6487 	frm = ieee80211_add_rates(frm, rs);
6488 	if (rs->rs_nrates > IEEE80211_RATE_SIZE)
6489 		frm = ieee80211_add_xrates(frm, rs);
6490 	remain -= frm - pos;
6491 
6492 	if (isset(sc->sc_enabled_capa,
6493 	    IWX_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT)) {
6494 		if (remain < 3)
6495 			return ENOBUFS;
6496 		*frm++ = IEEE80211_ELEMID_DSPARMS;
6497 		*frm++ = 1;
6498 		*frm++ = 0;
6499 		remain -= 3;
6500 	}
6501 	preq->band_data[0].len = htole16(frm - pos);
6502 
6503 	if (sc->sc_nvm.sku_cap_band_52GHz_enable) {
6504 		/* Fill in 5GHz IEs. */
6505 		rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
6506 		if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
6507 			if (remain < 4 + rs->rs_nrates)
6508 				return ENOBUFS;
6509 		} else if (remain < 2 + rs->rs_nrates)
6510 			return ENOBUFS;
6511 		preq->band_data[1].offset = htole16(frm - (uint8_t *)wh);
6512 		pos = frm;
6513 		frm = ieee80211_add_rates(frm, rs);
6514 		if (rs->rs_nrates > IEEE80211_RATE_SIZE)
6515 			frm = ieee80211_add_xrates(frm, rs);
6516 		preq->band_data[1].len = htole16(frm - pos);
6517 		remain -= frm - pos;
6518 		if (vap->iv_vht_flags & IEEE80211_FVHT_VHT) {
6519 			if (remain < 14)
6520 				return ENOBUFS;
6521 			frm = ieee80211_add_vhtcap(frm, vap->iv_bss);
6522 			remain -= frm - pos;
6523 			preq->band_data[1].len = htole16(frm - pos);
6524 		}
6525 	}
6526 
6527 	/* Send 11n IEs on both 2GHz and 5GHz bands. */
6528 	preq->common_data.offset = htole16(frm - (uint8_t *)wh);
6529 	pos = frm;
6530 	if (vap->iv_flags_ht & IEEE80211_FHT_HT) {
6531 		if (remain < 28)
6532 			return ENOBUFS;
6533 		frm = ieee80211_add_htcap(frm, vap->iv_bss);
6534 		/* XXX add WME info? */
6535 		remain -= frm - pos;
6536 	}
6537 
6538 	preq->common_data.len = htole16(frm - pos);
6539 
6540 	return 0;
6541 }
6542 
6543 static int
6544 iwx_config_umac_scan_reduced(struct iwx_softc *sc)
6545 {
6546 	struct iwx_scan_config scan_cfg;
6547 	struct iwx_host_cmd hcmd = {
6548 		.id = iwx_cmd_id(IWX_SCAN_CFG_CMD, IWX_LONG_GROUP, 0),
6549 		.len[0] = sizeof(scan_cfg),
6550 		.data[0] = &scan_cfg,
6551 		.flags = 0,
6552 	};
6553 	int cmdver;
6554 
6555 	if (!isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG)) {
6556 		printf("%s: firmware does not support reduced scan config\n",
6557 		    DEVNAME(sc));
6558 		return ENOTSUP;
6559 	}
6560 
6561 	memset(&scan_cfg, 0, sizeof(scan_cfg));
6562 
6563 	/*
6564 	 * SCAN_CFG version >= 5 implies that the broadcast
6565 	 * STA ID field is deprecated.
6566 	 */
6567 	cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_SCAN_CFG_CMD);
6568 	if (cmdver == IWX_FW_CMD_VER_UNKNOWN || cmdver < 5)
6569 		scan_cfg.bcast_sta_id = 0xff;
6570 
6571 	scan_cfg.tx_chains = htole32(iwx_fw_valid_tx_ant(sc));
6572 	scan_cfg.rx_chains = htole32(iwx_fw_valid_rx_ant(sc));
6573 
6574 	return iwx_send_cmd(sc, &hcmd);
6575 }
6576 
6577 static uint16_t
6578 iwx_scan_umac_flags_v2(struct iwx_softc *sc, int bgscan)
6579 {
6580 	struct ieee80211com *ic = &sc->sc_ic;
6581 	struct ieee80211_scan_state *ss = ic->ic_scan;
6582 	uint16_t flags = 0;
6583 
6584 	if (ss->ss_nssid == 0) {
6585 		DPRINTF(("%s: Passive scan started\n", __func__));
6586 		flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE;
6587 	}
6588 
6589 	flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_PASS_ALL;
6590 	flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_NTFY_ITER_COMPLETE;
6591 	flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_ADAPTIVE_DWELL;
6592 
6593 	return flags;
6594 }
6595 
6596 #define IWX_SCAN_DWELL_ACTIVE		10
6597 #define IWX_SCAN_DWELL_PASSIVE		110
6598 
6599 /* adaptive dwell max budget time [TU] for full scan */
6600 #define IWX_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
6601 /* adaptive dwell max budget time [TU] for directed scan */
6602 #define IWX_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN 100
6603 /* adaptive dwell default high band APs number */
6604 #define IWX_SCAN_ADWELL_DEFAULT_HB_N_APS 8
6605 /* adaptive dwell default low band APs number */
6606 #define IWX_SCAN_ADWELL_DEFAULT_LB_N_APS 2
6607 /* adaptive dwell default APs number in social channels (1, 6, 11) */
6608 #define IWX_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10
6609 /* adaptive dwell number of APs override for p2p friendly GO channels */
6610 #define IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY 10
6611 /* adaptive dwell number of APs override for social channels */
6612 #define IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS 2
6613 
6614 static void
6615 iwx_scan_umac_dwell_v10(struct iwx_softc *sc,
6616     struct iwx_scan_general_params_v10 *general_params, int bgscan)
6617 {
6618 	uint32_t suspend_time, max_out_time;
6619 	uint8_t active_dwell, passive_dwell;
6620 
6621 	active_dwell = IWX_SCAN_DWELL_ACTIVE;
6622 	passive_dwell = IWX_SCAN_DWELL_PASSIVE;
6623 
6624 	general_params->adwell_default_social_chn =
6625 		IWX_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL;
6626 	general_params->adwell_default_2g = IWX_SCAN_ADWELL_DEFAULT_LB_N_APS;
6627 	general_params->adwell_default_5g = IWX_SCAN_ADWELL_DEFAULT_HB_N_APS;
6628 
6629 	if (bgscan)
6630 		general_params->adwell_max_budget =
6631 			htole16(IWX_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN);
6632 	else
6633 		general_params->adwell_max_budget =
6634 			htole16(IWX_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN);
6635 
6636 	general_params->scan_priority = htole32(IWX_SCAN_PRIORITY_EXT_6);
6637 	if (bgscan) {
6638 		max_out_time = htole32(120);
6639 		suspend_time = htole32(120);
6640 	} else {
6641 		max_out_time = htole32(0);
6642 		suspend_time = htole32(0);
6643 	}
6644 	general_params->max_out_of_time[IWX_SCAN_LB_LMAC_IDX] =
6645 		htole32(max_out_time);
6646 	general_params->suspend_time[IWX_SCAN_LB_LMAC_IDX] =
6647 		htole32(suspend_time);
6648 	general_params->max_out_of_time[IWX_SCAN_HB_LMAC_IDX] =
6649 		htole32(max_out_time);
6650 	general_params->suspend_time[IWX_SCAN_HB_LMAC_IDX] =
6651 		htole32(suspend_time);
6652 
6653 	general_params->active_dwell[IWX_SCAN_LB_LMAC_IDX] = active_dwell;
6654 	general_params->passive_dwell[IWX_SCAN_LB_LMAC_IDX] = passive_dwell;
6655 	general_params->active_dwell[IWX_SCAN_HB_LMAC_IDX] = active_dwell;
6656 	general_params->passive_dwell[IWX_SCAN_HB_LMAC_IDX] = passive_dwell;
6657 }
6658 
6659 static void
6660 iwx_scan_umac_fill_general_p_v10(struct iwx_softc *sc,
6661     struct iwx_scan_general_params_v10 *gp, uint16_t gen_flags, int bgscan)
6662 {
6663 	iwx_scan_umac_dwell_v10(sc, gp, bgscan);
6664 
6665 	gp->flags = htole16(gen_flags);
6666 
6667 	if (gen_flags & IWX_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1)
6668 		gp->num_of_fragments[IWX_SCAN_LB_LMAC_IDX] = 3;
6669 	if (gen_flags & IWX_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2)
6670 		gp->num_of_fragments[IWX_SCAN_HB_LMAC_IDX] = 3;
6671 
6672 	gp->scan_start_mac_id = 0;
6673 }
6674 
6675 static void
6676 iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *sc,
6677     struct iwx_scan_channel_params_v6 *cp, uint32_t channel_cfg_flags,
6678     int n_ssid)
6679 {
6680 	cp->flags = IWX_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER;
6681 
6682 	cp->count = iwx_umac_scan_fill_channels(sc, cp->channel_config,
6683 	    nitems(cp->channel_config), n_ssid, channel_cfg_flags);
6684 
6685 	cp->n_aps_override[0] = IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY;
6686 	cp->n_aps_override[1] = IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS;
6687 }
6688 
6689 static int
6690 iwx_umac_scan_v14(struct iwx_softc *sc, int bgscan)
6691 {
6692 	struct ieee80211com *ic = &sc->sc_ic;
6693 	struct ieee80211_scan_state *ss = ic->ic_scan;
6694 	struct iwx_host_cmd hcmd = {
6695 		.id = iwx_cmd_id(IWX_SCAN_REQ_UMAC, IWX_LONG_GROUP, 0),
6696 		.len = { 0, },
6697 		.data = { NULL, },
6698 		.flags = 0,
6699 	};
6700 	struct iwx_scan_req_umac_v14 *cmd = &sc->sc_umac_v14_cmd;
6701 	struct iwx_scan_req_params_v14 *scan_p;
6702 	int err, async = bgscan, n_ssid = 0;
6703 	uint16_t gen_flags;
6704 	uint32_t bitmap_ssid = 0;
6705 
6706 	IWX_ASSERT_LOCKED(sc);
6707 
6708 	bzero(cmd, sizeof(struct iwx_scan_req_umac_v14));
6709 
6710 	scan_p = &cmd->scan_params;
6711 
6712 	cmd->ooc_priority = htole32(IWX_SCAN_PRIORITY_EXT_6);
6713 	cmd->uid = htole32(0);
6714 
6715 	gen_flags = iwx_scan_umac_flags_v2(sc, bgscan);
6716 	iwx_scan_umac_fill_general_p_v10(sc, &scan_p->general_params,
6717 	    gen_flags, bgscan);
6718 
6719 	scan_p->periodic_params.schedule[0].interval = htole16(0);
6720 	scan_p->periodic_params.schedule[0].iter_count = 1;
6721 
6722 	err = iwx_fill_probe_req(sc, &scan_p->probe_params.preq);
6723 	if (err) {
6724 		printf("%s: iwx_fill_probe_req failed (error %d)\n", __func__,
6725 		    err);
6726 		return err;
6727 	}
6728 
6729 	for (int i=0; i < ss->ss_nssid; i++) {
6730 		scan_p->probe_params.direct_scan[i].id = IEEE80211_ELEMID_SSID;
6731 		scan_p->probe_params.direct_scan[i].len =
6732 		    MIN(ss->ss_ssid[i].len, IEEE80211_NWID_LEN);
6733 		DPRINTF(("%s: Active scan started for ssid ", __func__));
6734 		memcpy(scan_p->probe_params.direct_scan[i].ssid,
6735 		    ss->ss_ssid[i].ssid, ss->ss_ssid[i].len);
6736 		n_ssid++;
6737 		bitmap_ssid |= (1 << i);
6738 	}
6739 	DPRINTF(("%s: bitmap_ssid=0x%x\n", __func__, bitmap_ssid));
6740 
6741 	iwx_scan_umac_fill_ch_p_v6(sc, &scan_p->channel_params, bitmap_ssid,
6742 	    n_ssid);
6743 
6744 	hcmd.len[0] = sizeof(*cmd);
6745 	hcmd.data[0] = (void *)cmd;
6746 	hcmd.flags |= async ? IWX_CMD_ASYNC : 0;
6747 
6748 	err = iwx_send_cmd(sc, &hcmd);
6749 	return err;
6750 }
6751 
6752 static void
6753 iwx_mcc_update(struct iwx_softc *sc, struct iwx_mcc_chub_notif *notif)
6754 {
6755 	char alpha2[3];
6756 
6757 	snprintf(alpha2, sizeof(alpha2), "%c%c",
6758 	    (le16toh(notif->mcc) & 0xff00) >> 8, le16toh(notif->mcc) & 0xff);
6759 
6760 	IWX_DPRINTF(sc, IWX_DEBUG_FW, "%s: firmware has detected regulatory domain '%s' "
6761 		    "(0x%x)\n", DEVNAME(sc), alpha2, le16toh(notif->mcc));
6762 
6763 	/* TODO: Schedule a task to send MCC_UPDATE_CMD? */
6764 }
6765 
6766 uint8_t
6767 iwx_ridx2rate(struct ieee80211_rateset *rs, int ridx)
6768 {
6769 	int i;
6770 	uint8_t rval;
6771 
6772 	for (i = 0; i < rs->rs_nrates; i++) {
6773 		rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL);
6774 		if (rval == iwx_rates[ridx].rate)
6775 			return rs->rs_rates[i];
6776 	}
6777 
6778 	return 0;
6779 }
6780 
6781 static int
6782 iwx_rval2ridx(int rval)
6783 {
6784 	int ridx;
6785 
6786 	for (ridx = 0; ridx < nitems(iwx_rates); ridx++) {
6787 		if (iwx_rates[ridx].plcp == IWX_RATE_INVM_PLCP)
6788 			continue;
6789 		if (rval == iwx_rates[ridx].rate)
6790 			break;
6791 	}
6792 
6793 	return ridx;
6794 }
6795 
6796 static void
6797 iwx_ack_rates(struct iwx_softc *sc, struct iwx_node *in, int *cck_rates,
6798     int *ofdm_rates)
6799 {
6800 	struct ieee80211_node *ni = &in->in_ni;
6801 	struct ieee80211_rateset *rs = &ni->ni_rates;
6802 	int lowest_present_ofdm = -1;
6803 	int lowest_present_cck = -1;
6804 	uint8_t cck = 0;
6805 	uint8_t ofdm = 0;
6806 	int i;
6807 
6808 	if (ni->ni_chan == IEEE80211_CHAN_ANYC ||
6809 	    IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) {
6810 		for (i = IWX_FIRST_CCK_RATE; i < IWX_FIRST_OFDM_RATE; i++) {
6811 			if ((iwx_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0)
6812 				continue;
6813 			cck |= (1 << i);
6814 			if (lowest_present_cck == -1 || lowest_present_cck > i)
6815 				lowest_present_cck = i;
6816 		}
6817 	}
6818 	for (i = IWX_FIRST_OFDM_RATE; i <= IWX_LAST_NON_HT_RATE; i++) {
6819 		if ((iwx_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0)
6820 			continue;
6821 		ofdm |= (1 << (i - IWX_FIRST_OFDM_RATE));
6822 		if (lowest_present_ofdm == -1 || lowest_present_ofdm > i)
6823 			lowest_present_ofdm = i;
6824 	}
6825 
6826 	/*
6827 	 * Now we've got the basic rates as bitmaps in the ofdm and cck
6828 	 * variables. This isn't sufficient though, as there might not
6829 	 * be all the right rates in the bitmap. E.g. if the only basic
6830 	 * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps
6831 	 * and 6 Mbps because the 802.11-2007 standard says in 9.6:
6832 	 *
6833 	 *    [...] a STA responding to a received frame shall transmit
6834 	 *    its Control Response frame [...] at the highest rate in the
6835 	 *    BSSBasicRateSet parameter that is less than or equal to the
6836 	 *    rate of the immediately previous frame in the frame exchange
6837 	 *    sequence ([...]) and that is of the same modulation class
6838 	 *    ([...]) as the received frame. If no rate contained in the
6839 	 *    BSSBasicRateSet parameter meets these conditions, then the
6840 	 *    control frame sent in response to a received frame shall be
6841 	 *    transmitted at the highest mandatory rate of the PHY that is
6842 	 *    less than or equal to the rate of the received frame, and
6843 	 *    that is of the same modulation class as the received frame.
6844 	 *
6845 	 * As a consequence, we need to add all mandatory rates that are
6846 	 * lower than all of the basic rates to these bitmaps.
6847 	 */
6848 
6849 	if (IWX_RATE_24M_INDEX < lowest_present_ofdm)
6850 		ofdm |= IWX_RATE_BIT_MSK(24) >> IWX_FIRST_OFDM_RATE;
6851 	if (IWX_RATE_12M_INDEX < lowest_present_ofdm)
6852 		ofdm |= IWX_RATE_BIT_MSK(12) >> IWX_FIRST_OFDM_RATE;
6853 	/* 6M already there or needed so always add */
6854 	ofdm |= IWX_RATE_BIT_MSK(6) >> IWX_FIRST_OFDM_RATE;
6855 
6856 	/*
6857 	 * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP.
6858 	 * Note, however:
6859 	 *  - if no CCK rates are basic, it must be ERP since there must
6860 	 *    be some basic rates at all, so they're OFDM => ERP PHY
6861 	 *    (or we're in 5 GHz, and the cck bitmap will never be used)
6862 	 *  - if 11M is a basic rate, it must be ERP as well, so add 5.5M
6863 	 *  - if 5.5M is basic, 1M and 2M are mandatory
6864 	 *  - if 2M is basic, 1M is mandatory
6865 	 *  - if 1M is basic, that's the only valid ACK rate.
6866 	 * As a consequence, it's not as complicated as it sounds, just add
6867 	 * any lower rates to the ACK rate bitmap.
6868 	 */
6869 	if (IWX_RATE_11M_INDEX < lowest_present_cck)
6870 		cck |= IWX_RATE_BIT_MSK(11) >> IWX_FIRST_CCK_RATE;
6871 	if (IWX_RATE_5M_INDEX < lowest_present_cck)
6872 		cck |= IWX_RATE_BIT_MSK(5) >> IWX_FIRST_CCK_RATE;
6873 	if (IWX_RATE_2M_INDEX < lowest_present_cck)
6874 		cck |= IWX_RATE_BIT_MSK(2) >> IWX_FIRST_CCK_RATE;
6875 	/* 1M already there or needed so always add */
6876 	cck |= IWX_RATE_BIT_MSK(1) >> IWX_FIRST_CCK_RATE;
6877 
6878 	*cck_rates = cck;
6879 	*ofdm_rates = ofdm;
6880 }
6881 
6882 static void
6883 iwx_mac_ctxt_cmd_common(struct iwx_softc *sc, struct iwx_node *in,
6884     struct iwx_mac_ctx_cmd *cmd, uint32_t action)
6885 {
6886 #define IWX_EXP2(x)	((1 << (x)) - 1)	/* CWmin = 2^ECWmin - 1 */
6887 	struct ieee80211com *ic = &sc->sc_ic;
6888 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
6889 	struct ieee80211_node *ni = vap->iv_bss;
6890 	int cck_ack_rates, ofdm_ack_rates;
6891 
6892 	cmd->id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id,
6893 	    in->in_color));
6894 	cmd->action = htole32(action);
6895 
6896 	if (action == IWX_FW_CTXT_ACTION_REMOVE)
6897 		return;
6898 
6899 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
6900 		cmd->mac_type = htole32(IWX_FW_MAC_TYPE_LISTENER);
6901 	else if (ic->ic_opmode == IEEE80211_M_STA)
6902 		cmd->mac_type = htole32(IWX_FW_MAC_TYPE_BSS_STA);
6903 	else
6904 		panic("unsupported operating mode %d", ic->ic_opmode);
6905 	cmd->tsf_id = htole32(IWX_TSF_ID_A);
6906 
6907 	IEEE80211_ADDR_COPY(cmd->node_addr, vap->iv_myaddr);
6908 	DPRINTF(("%s: cmd->node_addr=%s\n", __func__,
6909 	    ether_sprintf(cmd->node_addr)));
6910 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
6911 		IEEE80211_ADDR_COPY(cmd->bssid_addr, etherbroadcastaddr);
6912 		return;
6913 	}
6914 
6915 	IEEE80211_ADDR_COPY(cmd->bssid_addr, in->in_macaddr);
6916 	DPRINTF(("%s: cmd->bssid_addr=%s\n", __func__,
6917 	    ether_sprintf(cmd->bssid_addr)));
6918 	iwx_ack_rates(sc, in, &cck_ack_rates, &ofdm_ack_rates);
6919 	cmd->cck_rates = htole32(cck_ack_rates);
6920 	cmd->ofdm_rates = htole32(ofdm_ack_rates);
6921 
6922 	cmd->cck_short_preamble
6923 	    = htole32((ic->ic_flags & IEEE80211_F_SHPREAMBLE)
6924 	      ? IWX_MAC_FLG_SHORT_PREAMBLE : 0);
6925 	cmd->short_slot
6926 	    = htole32((ic->ic_flags & IEEE80211_F_SHSLOT)
6927 	      ? IWX_MAC_FLG_SHORT_SLOT : 0);
6928 
6929 	struct chanAccParams chp;
6930 	ieee80211_wme_vap_getparams(vap, &chp);
6931 
6932 	for (int i = 0; i < WME_NUM_AC; i++) {
6933 		int txf = iwx_ac_to_tx_fifo[i];
6934 		cmd->ac[txf].cw_min = IWX_EXP2(chp.cap_wmeParams[i].wmep_logcwmin);
6935 		cmd->ac[txf].cw_max = IWX_EXP2(chp.cap_wmeParams[i].wmep_logcwmax);
6936 		cmd->ac[txf].aifsn = chp.cap_wmeParams[i].wmep_aifsn;
6937 		cmd->ac[txf].fifos_mask = (1 << txf);
6938 		cmd->ac[txf].edca_txop = chp.cap_wmeParams[i].wmep_txopLimit;
6939 
6940 		cmd->ac[txf].edca_txop = htole16(chp.cap_wmeParams[i].wmep_txopLimit * 32);
6941 	}
6942 
6943 	if (ni->ni_flags & IEEE80211_NODE_QOS) {
6944 		DPRINTF(("%s: === IEEE80211_NODE_QOS\n", __func__));
6945 		cmd->qos_flags |= htole32(IWX_MAC_QOS_FLG_UPDATE_EDCA);
6946 	}
6947 
6948 	if (ni->ni_flags & IEEE80211_NODE_HT) {
6949 		switch (vap->iv_curhtprotmode) {
6950 		case IEEE80211_HTINFO_OPMODE_PURE:
6951 			break;
6952 		case IEEE80211_HTINFO_OPMODE_PROTOPT:
6953 		case IEEE80211_HTINFO_OPMODE_MIXED:
6954 			cmd->protection_flags |=
6955 			    htole32(IWX_MAC_PROT_FLG_HT_PROT |
6956 			    IWX_MAC_PROT_FLG_FAT_PROT);
6957 			break;
6958 		case IEEE80211_HTINFO_OPMODE_HT20PR:
6959 			if (in->in_phyctxt &&
6960 			    (in->in_phyctxt->sco == IEEE80211_HTINFO_2NDCHAN_ABOVE ||
6961 			    in->in_phyctxt->sco == IEEE80211_HTINFO_2NDCHAN_BELOW)) {
6962 				cmd->protection_flags |=
6963 				    htole32(IWX_MAC_PROT_FLG_HT_PROT |
6964 				    IWX_MAC_PROT_FLG_FAT_PROT);
6965 			}
6966 			break;
6967 		default:
6968 			break;
6969 		}
6970 		cmd->qos_flags |= htole32(IWX_MAC_QOS_FLG_TGN);
6971 		DPRINTF(("%s: === IWX_MAC_QOS_FLG_TGN\n", __func__));
6972 	}
6973 
6974 	if (ic->ic_flags & IEEE80211_F_USEPROT)
6975 		cmd->protection_flags |= htole32(IWX_MAC_PROT_FLG_TGG_PROTECT);
6976 	cmd->filter_flags = htole32(IWX_MAC_FILTER_ACCEPT_GRP);
6977 #undef IWX_EXP2
6978 }
6979 
6980 static void
6981 iwx_mac_ctxt_cmd_fill_sta(struct iwx_softc *sc, struct iwx_node *in,
6982     struct iwx_mac_data_sta *sta, int assoc)
6983 {
6984 	struct ieee80211_node *ni = &in->in_ni;
6985 	struct ieee80211com *ic = &sc->sc_ic;
6986 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
6987 	uint32_t dtim_off;
6988 	uint64_t tsf;
6989 	int dtim_period;
6990 
6991 	dtim_off = ni->ni_dtim_count * ni->ni_intval * IEEE80211_DUR_TU;
6992 	tsf = le64toh(ni->ni_tstamp.tsf);
6993 	dtim_period = vap->iv_dtim_period;
6994 
6995 	sta->is_assoc = htole32(assoc);
6996 
6997 	if (assoc) {
6998 		sta->dtim_time = htole32(tsf + dtim_off);
6999 		sta->dtim_tsf = htole64(tsf + dtim_off);
7000 		// XXX: unset in iwm
7001 		sta->assoc_beacon_arrive_time = 0;
7002 	}
7003 	sta->bi = htole32(ni->ni_intval);
7004 	sta->dtim_interval = htole32(ni->ni_intval * dtim_period);
7005 	sta->data_policy = htole32(0);
7006 	sta->listen_interval = htole32(10);
7007 	sta->assoc_id = htole32(ni->ni_associd);
7008 }
7009 
7010 static int
7011 iwx_mac_ctxt_cmd(struct iwx_softc *sc, struct iwx_node *in, uint32_t action,
7012     int assoc)
7013 {
7014 	struct ieee80211com *ic = &sc->sc_ic;
7015 	struct ieee80211_node *ni = &in->in_ni;
7016 	struct iwx_mac_ctx_cmd cmd;
7017 	int active = (sc->sc_flags & IWX_FLAG_MAC_ACTIVE);
7018 
7019 	if (action == IWX_FW_CTXT_ACTION_ADD && active)
7020 		panic("MAC already added");
7021 	if (action == IWX_FW_CTXT_ACTION_REMOVE && !active)
7022 		panic("MAC already removed");
7023 
7024 	memset(&cmd, 0, sizeof(cmd));
7025 
7026 	iwx_mac_ctxt_cmd_common(sc, in, &cmd, action);
7027 
7028 	if (action == IWX_FW_CTXT_ACTION_REMOVE) {
7029 		return iwx_send_cmd_pdu(sc, IWX_MAC_CONTEXT_CMD, 0,
7030 		    sizeof(cmd), &cmd);
7031 	}
7032 
7033 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
7034 		cmd.filter_flags |= htole32(IWX_MAC_FILTER_IN_PROMISC |
7035 		    IWX_MAC_FILTER_IN_CONTROL_AND_MGMT |
7036 		    IWX_MAC_FILTER_ACCEPT_GRP |
7037 		    IWX_MAC_FILTER_IN_BEACON |
7038 		    IWX_MAC_FILTER_IN_PROBE_REQUEST |
7039 		    IWX_MAC_FILTER_IN_CRC32);
7040 	// XXX: dtim period is in vap
7041 	} else if (!assoc || !ni->ni_associd /*|| !ni->ni_dtimperiod*/) {
7042 		/*
7043 		 * Allow beacons to pass through as long as we are not
7044 		 * associated or we do not have dtim period information.
7045 		 */
7046 		cmd.filter_flags |= htole32(IWX_MAC_FILTER_IN_BEACON);
7047 	}
7048 	iwx_mac_ctxt_cmd_fill_sta(sc, in, &cmd.sta, assoc);
7049 	return iwx_send_cmd_pdu(sc, IWX_MAC_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
7050 }
7051 
7052 static int
7053 iwx_clear_statistics(struct iwx_softc *sc)
7054 {
7055 	struct iwx_statistics_cmd scmd = {
7056 		.flags = htole32(IWX_STATISTICS_FLG_CLEAR)
7057 	};
7058 	struct iwx_host_cmd cmd = {
7059 		.id = IWX_STATISTICS_CMD,
7060 		.len[0] = sizeof(scmd),
7061 		.data[0] = &scmd,
7062 		.flags = IWX_CMD_WANT_RESP,
7063 		.resp_pkt_len = sizeof(struct iwx_notif_statistics),
7064 	};
7065 	int err;
7066 
7067 	err = iwx_send_cmd(sc, &cmd);
7068 	if (err)
7069 		return err;
7070 
7071 	iwx_free_resp(sc, &cmd);
7072 	return 0;
7073 }
7074 
7075 static int
7076 iwx_scan(struct iwx_softc *sc)
7077 {
7078 	int err;
7079 	err = iwx_umac_scan_v14(sc, 0);
7080 
7081 	if (err) {
7082 		printf("%s: could not initiate scan\n", DEVNAME(sc));
7083 		return err;
7084 	}
7085 	return 0;
7086 }
7087 
7088 static int
7089 iwx_bgscan(struct ieee80211com *ic)
7090 {
7091 	struct iwx_softc *sc = ic->ic_softc;
7092 	int err;
7093 
7094 	err = iwx_umac_scan_v14(sc, 1);
7095 	if (err) {
7096 		printf("%s: could not initiate scan\n", DEVNAME(sc));
7097 		return err;
7098 	}
7099 	return 0;
7100 }
7101 
7102 static int
7103 iwx_enable_mgmt_queue(struct iwx_softc *sc)
7104 {
7105 	int err;
7106 
7107 	sc->first_data_qid = IWX_DQA_CMD_QUEUE + 1;
7108 
7109 	/*
7110 	 * Non-QoS frames use the "MGMT" TID and queue.
7111 	 * Other TIDs and data queues are reserved for QoS data frames.
7112 	 */
7113 	err = iwx_enable_txq(sc, IWX_STATION_ID, sc->first_data_qid,
7114 	    IWX_MGMT_TID, IWX_TX_RING_COUNT);
7115 	if (err) {
7116 		printf("%s: could not enable Tx queue %d (error %d)\n",
7117 		    DEVNAME(sc), sc->first_data_qid, err);
7118 		return err;
7119 	}
7120 
7121 	return 0;
7122 }
7123 
7124 static int
7125 iwx_disable_mgmt_queue(struct iwx_softc *sc)
7126 {
7127 	int err, cmd_ver;
7128 
7129 	/* Explicit removal is only required with old SCD_QUEUE_CFG command. */
7130 	cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
7131 	    IWX_SCD_QUEUE_CONFIG_CMD);
7132 	if (cmd_ver == 0 || cmd_ver == IWX_FW_CMD_VER_UNKNOWN)
7133 		return 0;
7134 
7135 	sc->first_data_qid = IWX_DQA_CMD_QUEUE + 1;
7136 
7137 	err = iwx_disable_txq(sc, IWX_STATION_ID, sc->first_data_qid,
7138 	    IWX_MGMT_TID);
7139 	if (err) {
7140 		printf("%s: could not disable Tx queue %d (error %d)\n",
7141 		    DEVNAME(sc), sc->first_data_qid, err);
7142 		return err;
7143 	}
7144 
7145 	return 0;
7146 }
7147 
7148 static int
7149 iwx_rs_rval2idx(uint8_t rval)
7150 {
7151 	/* Firmware expects indices which match our 11g rate set. */
7152 	const struct ieee80211_rateset *rs = &ieee80211_std_rateset_11g;
7153 	int i;
7154 
7155 	for (i = 0; i < rs->rs_nrates; i++) {
7156 		if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rval)
7157 			return i;
7158 	}
7159 
7160 	return -1;
7161 }
7162 
7163 static uint16_t
7164 iwx_rs_ht_rates(struct iwx_softc *sc, struct ieee80211_node *ni, int rsidx)
7165 {
7166 	uint16_t htrates = 0;
7167 	struct ieee80211_htrateset *htrs = &ni->ni_htrates;
7168 	int i;
7169 
7170 	if (rsidx == IEEE80211_HT_RATESET_SISO) {
7171 		for (i = 0; i < htrs->rs_nrates; i++) {
7172 			if (htrs->rs_rates[i] <= 7)
7173 				htrates |= (1 << htrs->rs_rates[i]);
7174 		}
7175 	} else if (rsidx == IEEE80211_HT_RATESET_MIMO2) {
7176 		for (i = 0; i < htrs->rs_nrates; i++) {
7177 			if (htrs->rs_rates[i] > 7 && htrs->rs_rates[i] <= 15)
7178 				htrates |= (1 << (htrs->rs_rates[i] - 8));
7179 		}
7180 	} else
7181 		panic(("iwx_rs_ht_rates"));
7182 
7183 	IWX_DPRINTF(sc, IWX_DEBUG_TXRATE,
7184 	    "%s:%d rsidx=%i htrates=0x%x\n", __func__, __LINE__, rsidx, htrates);
7185 
7186 	return htrates;
7187 }
7188 
7189 uint16_t
7190 iwx_rs_vht_rates(struct iwx_softc *sc, struct ieee80211_node *ni, int num_ss)
7191 {
7192 	uint16_t rx_mcs;
7193 	int max_mcs = -1;
7194 #define IEEE80211_VHT_MCS_FOR_SS_MASK(n)        (0x3 << (2*((n)-1)))
7195 #define IEEE80211_VHT_MCS_FOR_SS_SHIFT(n)       (2*((n)-1))
7196 	rx_mcs = (ni->ni_vht_mcsinfo.tx_mcs_map &
7197 	    IEEE80211_VHT_MCS_FOR_SS_MASK(num_ss)) >>
7198 	    IEEE80211_VHT_MCS_FOR_SS_SHIFT(num_ss);
7199 
7200 	switch (rx_mcs) {
7201 	case IEEE80211_VHT_MCS_NOT_SUPPORTED:
7202 		break;
7203 	case IEEE80211_VHT_MCS_SUPPORT_0_7:
7204 		max_mcs = 7;
7205 		break;
7206 	case IEEE80211_VHT_MCS_SUPPORT_0_8:
7207 		max_mcs = 8;
7208 		break;
7209 	case IEEE80211_VHT_MCS_SUPPORT_0_9:
7210 		/* Disable VHT MCS 9 for 20MHz-only stations. */
7211 		if ((ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) == 0)
7212 			max_mcs = 8;
7213 		else
7214 			max_mcs = 9;
7215 		break;
7216 	default:
7217 		/* Should not happen; Values above cover the possible range. */
7218 		panic("invalid VHT Rx MCS value %u", rx_mcs);
7219 	}
7220 
7221 	return ((1 << (max_mcs + 1)) - 1);
7222 }
7223 
7224 static int
7225 iwx_rs_init_v3(struct iwx_softc *sc, struct iwx_node *in)
7226 {
7227 #if 1
7228 	panic("iwx: Trying to init rate set on untested version");
7229 #else
7230 	struct ieee80211_node *ni = &in->in_ni;
7231 	struct ieee80211_rateset *rs = &ni->ni_rates;
7232 	struct iwx_tlc_config_cmd_v3 cfg_cmd;
7233 	uint32_t cmd_id;
7234 	int i;
7235 	size_t cmd_size = sizeof(cfg_cmd);
7236 
7237 	memset(&cfg_cmd, 0, sizeof(cfg_cmd));
7238 
7239 	for (i = 0; i < rs->rs_nrates; i++) {
7240 		uint8_t rval = rs->rs_rates[i] & IEEE80211_RATE_VAL;
7241 		int idx = iwx_rs_rval2idx(rval);
7242 		if (idx == -1)
7243 			return EINVAL;
7244 		cfg_cmd.non_ht_rates |= (1 << idx);
7245 	}
7246 
7247 	if (ni->ni_flags & IEEE80211_NODE_VHT) {
7248 		cfg_cmd.mode = IWX_TLC_MNG_MODE_VHT;
7249 		cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] =
7250 		    htole16(iwx_rs_vht_rates(sc, ni, 1));
7251 		cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] =
7252 		    htole16(iwx_rs_vht_rates(sc, ni, 2));
7253 	} else if (ni->ni_flags & IEEE80211_NODE_HT) {
7254 		cfg_cmd.mode = IWX_TLC_MNG_MODE_HT;
7255 		cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] =
7256 		    htole16(iwx_rs_ht_rates(sc, ni,
7257 		    IEEE80211_HT_RATESET_SISO));
7258 		cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] =
7259 		    htole16(iwx_rs_ht_rates(sc, ni,
7260 		    IEEE80211_HT_RATESET_MIMO2));
7261 	} else
7262 		cfg_cmd.mode = IWX_TLC_MNG_MODE_NON_HT;
7263 
7264 	cfg_cmd.sta_id = IWX_STATION_ID;
7265 	if (in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80)
7266 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ;
7267 	else if (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA ||
7268 	    in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB)
7269 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ;
7270 	else
7271 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ;
7272 	cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK | IWX_TLC_MNG_CHAIN_B_MSK;
7273 	if (ni->ni_flags & IEEE80211_NODE_VHT)
7274 		cfg_cmd.max_mpdu_len = htole16(3895);
7275 	else
7276 		cfg_cmd.max_mpdu_len = htole16(3839);
7277 	if (ni->ni_flags & IEEE80211_NODE_HT) {
7278 		if (ieee80211_node_supports_ht_sgi20(ni)) {
7279 			cfg_cmd.sgi_ch_width_supp |= (1 <<
7280 			    IWX_TLC_MNG_CH_WIDTH_20MHZ);
7281 		}
7282 		if (ieee80211_node_supports_ht_sgi40(ni)) {
7283 			cfg_cmd.sgi_ch_width_supp |= (1 <<
7284 			    IWX_TLC_MNG_CH_WIDTH_40MHZ);
7285 		}
7286 	}
7287 	if ((ni->ni_flags & IEEE80211_NODE_VHT) &&
7288 	    ieee80211_node_supports_vht_sgi80(ni))
7289 		cfg_cmd.sgi_ch_width_supp |= (1 << IWX_TLC_MNG_CH_WIDTH_80MHZ);
7290 
7291 	cmd_id = iwx_cmd_id(IWX_TLC_MNG_CONFIG_CMD, IWX_DATA_PATH_GROUP, 0);
7292 	return iwx_send_cmd_pdu(sc, cmd_id, IWX_CMD_ASYNC, cmd_size, &cfg_cmd);
7293 #endif
7294 }
7295 
7296 static int
7297 iwx_rs_init_v4(struct iwx_softc *sc, struct iwx_node *in)
7298 {
7299 	struct ieee80211_node *ni = &in->in_ni;
7300 	struct ieee80211_rateset *rs = &ni->ni_rates;
7301 	struct ieee80211_htrateset *htrs = &ni->ni_htrates;
7302 	struct iwx_tlc_config_cmd_v4 cfg_cmd;
7303 	uint32_t cmd_id;
7304 	int i;
7305 	int sgi80 = 0;
7306 	size_t cmd_size = sizeof(cfg_cmd);
7307 
7308 	memset(&cfg_cmd, 0, sizeof(cfg_cmd));
7309 
7310 	for (i = 0; i < rs->rs_nrates; i++) {
7311 		uint8_t rval = rs->rs_rates[i] & IEEE80211_RATE_VAL;
7312 		int idx = iwx_rs_rval2idx(rval);
7313 		if (idx == -1)
7314 			return EINVAL;
7315 		cfg_cmd.non_ht_rates |= (1 << idx);
7316 	}
7317 	for (i = 0; i < htrs->rs_nrates; i++) {
7318 		DPRINTF(("%s: htrate=%i\n", __func__, htrs->rs_rates[i]));
7319 	}
7320 
7321 	if (ni->ni_flags & IEEE80211_NODE_VHT) {
7322 		cfg_cmd.mode = IWX_TLC_MNG_MODE_VHT;
7323 		cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] =
7324 		    htole16(iwx_rs_vht_rates(sc, ni, 1));
7325 		cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] =
7326 		    htole16(iwx_rs_vht_rates(sc, ni, 2));
7327 
7328 		IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d SISO=0x%x\n",
7329 		    __func__, __LINE__,
7330 		    cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80]);
7331 		IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d MIMO2=0x%x\n",
7332 		    __func__, __LINE__,
7333 		    cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80]);
7334 	} else if (ni->ni_flags & IEEE80211_NODE_HT) {
7335 		cfg_cmd.mode = IWX_TLC_MNG_MODE_HT;
7336 		cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] =
7337 		    htole16(iwx_rs_ht_rates(sc, ni,
7338 		    IEEE80211_HT_RATESET_SISO));
7339 		cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] =
7340 		    htole16(iwx_rs_ht_rates(sc, ni,
7341 		    IEEE80211_HT_RATESET_MIMO2));
7342 
7343 		IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d SISO=0x%x\n",
7344 		    __func__, __LINE__,
7345 		    cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80]);
7346 		IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d MIMO2=0x%x\n",
7347 		    __func__, __LINE__,
7348 		    cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80]);
7349 	} else
7350 		cfg_cmd.mode = IWX_TLC_MNG_MODE_NON_HT;
7351 
7352 	cfg_cmd.sta_id = IWX_STATION_ID;
7353 #if 0
7354 	if (in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80)
7355 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ;
7356 	else if (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA ||
7357 	    in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB)
7358 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ;
7359 	else
7360 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ;
7361 #endif
7362 	if (IEEE80211_IS_CHAN_VHT80(in->in_ni.ni_chan)) {
7363 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ;
7364 	} else if (IEEE80211_IS_CHAN_HT40(in->in_ni.ni_chan)) {
7365 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ;
7366 	} else {
7367 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ;
7368 	}
7369 
7370 	cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK | IWX_TLC_MNG_CHAIN_B_MSK;
7371 	if (ni->ni_flags & IEEE80211_NODE_VHT)
7372 		cfg_cmd.max_mpdu_len = htole16(3895);
7373 	else
7374 		cfg_cmd.max_mpdu_len = htole16(3839);
7375 	if (ni->ni_flags & IEEE80211_NODE_HT) {
7376 		if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) {
7377 			cfg_cmd.sgi_ch_width_supp |= (1 <<
7378 			    IWX_TLC_MNG_CH_WIDTH_20MHZ);
7379 		}
7380 		if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) {
7381 			cfg_cmd.sgi_ch_width_supp |= (1 <<
7382 			    IWX_TLC_MNG_CH_WIDTH_40MHZ);
7383 		}
7384 	}
7385 	sgi80 = _IEEE80211_MASKSHIFT(ni->ni_vhtcap,
7386 	    IEEE80211_VHTCAP_SHORT_GI_80);
7387 	if ((ni->ni_flags & IEEE80211_NODE_VHT) && sgi80) {
7388 		cfg_cmd.sgi_ch_width_supp |= (1 << IWX_TLC_MNG_CH_WIDTH_80MHZ);
7389 	}
7390 
7391 	cmd_id = iwx_cmd_id(IWX_TLC_MNG_CONFIG_CMD, IWX_DATA_PATH_GROUP, 0);
7392 	return iwx_send_cmd_pdu(sc, cmd_id, IWX_CMD_ASYNC, cmd_size, &cfg_cmd);
7393 }
7394 
7395 static int
7396 iwx_rs_init(struct iwx_softc *sc, struct iwx_node *in)
7397 {
7398 	int cmd_ver;
7399 
7400 	cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
7401 	    IWX_TLC_MNG_CONFIG_CMD);
7402 	if (cmd_ver == 4)
7403 		return iwx_rs_init_v4(sc, in);
7404 	else
7405 		return iwx_rs_init_v3(sc, in);
7406 }
7407 
7408 
7409 /**
7410  * @brief Turn the given TX rate control notification into an ieee80211_node_txrate
7411  *
7412  * This populates the given txrate node with the TX rate control notification.
7413  *
7414  * @param sc driver softc
7415  * @param notif firmware notification
7416  * @param ni ieee80211_node update
7417  * @returns true if updated, false if not
7418  */
7419 static bool
7420 iwx_rs_update_node_txrate(struct iwx_softc *sc,
7421     const struct iwx_tlc_update_notif *notif, struct ieee80211_node *ni)
7422 {
7423 	struct ieee80211com *ic = &sc->sc_ic;
7424 	/* XXX TODO: create an inline function in if_iwxreg.h? */
7425 	static int cck_idx_to_rate[] = { 2, 4, 11, 22, 2, 2, 2, 2 };
7426 	static int ofdm_idx_to_rate[] = { 12, 18, 24, 36, 48, 72, 96, 108 };
7427 
7428 	uint32_t rate_n_flags;
7429 	uint32_t type;
7430 
7431 	/* Extract the rate and command version */
7432 	rate_n_flags = le32toh(notif->rate);
7433 
7434 	if (sc->sc_rate_n_flags_version != 2) {
7435 		net80211_ic_printf(ic,
7436 		    "%s: unsupported rate_n_flags version (%d)\n",
7437 		    __func__,
7438 		    sc->sc_rate_n_flags_version);
7439 		return (false);
7440 	}
7441 
7442 	if (sc->sc_debug & IWX_DEBUG_TXRATE)
7443 		print_ratenflags(__func__, __LINE__,
7444 		    rate_n_flags, sc->sc_rate_n_flags_version);
7445 
7446 	type = (rate_n_flags & IWX_RATE_MCS_MOD_TYPE_MSK);
7447 	switch (type) {
7448 	case IWX_RATE_MCS_CCK_MSK:
7449 		ieee80211_node_set_txrate_dot11rate(ni,
7450 		    cck_idx_to_rate[rate_n_flags & IWX_RATE_LEGACY_RATE_MSK]);
7451 		return (true);
7452 	case IWX_RATE_MCS_LEGACY_OFDM_MSK:
7453 		ieee80211_node_set_txrate_dot11rate(ni,
7454 		    ofdm_idx_to_rate[rate_n_flags & IWX_RATE_LEGACY_RATE_MSK]);
7455 		return (true);
7456 	case IWX_RATE_MCS_HT_MSK:
7457 		/*
7458 		 * TODO: the current API doesn't include channel width
7459 		 * and other flags, so we can't accurately store them yet!
7460 		 *
7461 		 * channel width: (flags & IWX_RATE_MCS_CHAN_WIDTH_MSK)
7462 		 *    >> IWX_RATE_MCS_CHAN_WIDTH_POS)
7463 		 * LDPC: (flags & (1 << 16))
7464 		 */
7465 		ieee80211_node_set_txrate_ht_mcsrate(ni,
7466 		    IWX_RATE_HT_MCS_INDEX(rate_n_flags));
7467 		return (true);
7468 	case IWX_RATE_MCS_VHT_MSK:
7469 		/* TODO: same comment on channel width, etc above */
7470 		ieee80211_node_set_txrate_vht_rate(ni,
7471 		    IWX_RATE_VHT_MCS_CODE(rate_n_flags),
7472 		    IWX_RATE_VHT_MCS_NSS(rate_n_flags));
7473 		return (true);
7474 	default:
7475 		net80211_ic_printf(ic,
7476 		    "%s: unsupported chosen rate type in "
7477 		    "IWX_RATE_MCS_MOD_TYPE (%d)\n", __func__,
7478 		    type >> IWX_RATE_MCS_MOD_TYPE_POS);
7479 		return (false);
7480 	}
7481 
7482 	/* Default: if we get here, we didn't successfully update anything */
7483 	return (false);
7484 }
7485 
7486 /**
7487  * @brief Process a firmware rate control update and update net80211.
7488  *
7489  * Since firmware is doing rate control, this just needs to update
7490  * the txrate in the ieee80211_node entry.
7491  */
7492 static void
7493 iwx_rs_update(struct iwx_softc *sc, struct iwx_tlc_update_notif *notif)
7494 {
7495 	struct ieee80211com *ic = &sc->sc_ic;
7496 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
7497 	/* XXX TODO: get a node ref! */
7498 	struct ieee80211_node *ni = (void *)vap->iv_bss;
7499 
7500 	/*
7501 	 * For now the iwx driver only supports a single vdev with a single
7502 	 * node; it doesn't yet support ibss/hostap/multiple vdevs.
7503 	 */
7504 	if (notif->sta_id != IWX_STATION_ID ||
7505 	    (le32toh(notif->flags) & IWX_TLC_NOTIF_FLAG_RATE) == 0)
7506 		return;
7507 
7508 	iwx_rs_update_node_txrate(sc, notif, ni);
7509 }
7510 
7511 static int
7512 iwx_phy_send_rlc(struct iwx_softc *sc, struct iwx_phy_ctxt *phyctxt,
7513     uint8_t chains_static, uint8_t chains_dynamic)
7514 {
7515 	struct iwx_rlc_config_cmd cmd;
7516 	uint32_t cmd_id;
7517 	uint8_t active_cnt, idle_cnt;
7518 
7519 	memset(&cmd, 0, sizeof(cmd));
7520 
7521 	idle_cnt = chains_static;
7522 	active_cnt = chains_dynamic;
7523 
7524 	cmd.phy_id = htole32(phyctxt->id);
7525 	cmd.rlc.rx_chain_info = htole32(iwx_fw_valid_rx_ant(sc) <<
7526 	    IWX_PHY_RX_CHAIN_VALID_POS);
7527 	cmd.rlc.rx_chain_info |= htole32(idle_cnt << IWX_PHY_RX_CHAIN_CNT_POS);
7528 	cmd.rlc.rx_chain_info |= htole32(active_cnt <<
7529 	    IWX_PHY_RX_CHAIN_MIMO_CNT_POS);
7530 
7531 	cmd_id = iwx_cmd_id(IWX_RLC_CONFIG_CMD, IWX_DATA_PATH_GROUP, 2);
7532 	return iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd);
7533 }
7534 
7535 static int
7536 iwx_phy_ctxt_update(struct iwx_softc *sc, struct iwx_phy_ctxt *phyctxt,
7537     struct ieee80211_channel *chan, uint8_t chains_static,
7538     uint8_t chains_dynamic, uint32_t apply_time, uint8_t sco,
7539     uint8_t vht_chan_width)
7540 {
7541 	uint16_t band_flags = (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ);
7542 	int err;
7543 
7544 	if (chan == IEEE80211_CHAN_ANYC) {
7545 		printf("%s: GOS-3833: IEEE80211_CHAN_ANYC triggered\n",
7546 		    DEVNAME(sc));
7547 		    return EIO;
7548 	}
7549 
7550 	if (isset(sc->sc_enabled_capa,
7551 	    IWX_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) &&
7552 	    (phyctxt->channel->ic_flags & band_flags) !=
7553 	    (chan->ic_flags & band_flags)) {
7554 		err = iwx_phy_ctxt_cmd(sc, phyctxt, chains_static,
7555 		    chains_dynamic, IWX_FW_CTXT_ACTION_REMOVE, apply_time, sco,
7556 		    vht_chan_width);
7557 		if (err) {
7558 			printf("%s: could not remove PHY context "
7559 			    "(error %d)\n", DEVNAME(sc), err);
7560 			return err;
7561 		}
7562 		phyctxt->channel = chan;
7563 		err = iwx_phy_ctxt_cmd(sc, phyctxt, chains_static,
7564 		    chains_dynamic, IWX_FW_CTXT_ACTION_ADD, apply_time, sco,
7565 		    vht_chan_width);
7566 		if (err) {
7567 			printf("%s: could not add PHY context "
7568 			    "(error %d)\n", DEVNAME(sc), err);
7569 			return err;
7570 		}
7571 	} else {
7572 		phyctxt->channel = chan;
7573 		err = iwx_phy_ctxt_cmd(sc, phyctxt, chains_static,
7574 		    chains_dynamic, IWX_FW_CTXT_ACTION_MODIFY, apply_time, sco,
7575 		    vht_chan_width);
7576 		if (err) {
7577 			printf("%s: could not update PHY context (error %d)\n",
7578 			    DEVNAME(sc), err);
7579 			return err;
7580 		}
7581 	}
7582 
7583 	phyctxt->sco = sco;
7584 	phyctxt->vht_chan_width = vht_chan_width;
7585 
7586 	DPRINTF(("%s: phyctxt->channel->ic_ieee=%d\n", __func__,
7587 	    phyctxt->channel->ic_ieee));
7588 	DPRINTF(("%s: phyctxt->sco=%d\n", __func__, phyctxt->sco));
7589 	DPRINTF(("%s: phyctxt->vht_chan_width=%d\n", __func__,
7590 	    phyctxt->vht_chan_width));
7591 
7592 	if (iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
7593 	    IWX_RLC_CONFIG_CMD) == 2)
7594 		return iwx_phy_send_rlc(sc, phyctxt,
7595 		    chains_static, chains_dynamic);
7596 
7597 	return 0;
7598 }
7599 
7600 static int
7601 iwx_auth(struct ieee80211vap *vap, struct iwx_softc *sc)
7602 {
7603 	struct ieee80211com *ic = &sc->sc_ic;
7604 	struct iwx_node *in;
7605 	struct iwx_vap *ivp = IWX_VAP(vap);
7606 	struct ieee80211_node *ni;
7607 	uint32_t duration;
7608 	int generation = sc->sc_generation, err;
7609 
7610 	IWX_ASSERT_LOCKED(sc);
7611 
7612 	ni = ieee80211_ref_node(vap->iv_bss);
7613 	in = IWX_NODE(ni);
7614 
7615 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
7616 		err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0],
7617 		    ic->ic_bsschan, 1, 1, 0, IEEE80211_HTOP0_SCO_SCN,
7618 		    IEEE80211_VHTOP0_CHAN_WIDTH_HT);
7619 		if (err)
7620 			return err;
7621 	} else {
7622 		err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0],
7623 		    in->in_ni.ni_chan, 1, 1, 0, IEEE80211_HTOP0_SCO_SCN,
7624 		    IEEE80211_VHTOP0_CHAN_WIDTH_HT);
7625 		if (err)
7626 			return err;
7627 	}
7628 	ivp->phy_ctxt = &sc->sc_phyctxt[0];
7629 	IEEE80211_ADDR_COPY(in->in_macaddr, in->in_ni.ni_macaddr);
7630 	DPRINTF(("%s: in-in_macaddr=%s\n", __func__,
7631 	    ether_sprintf(in->in_macaddr)));
7632 
7633 	err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_ADD, 0);
7634 	if (err) {
7635 		printf("%s: could not add MAC context (error %d)\n",
7636 		    DEVNAME(sc), err);
7637 		return err;
7638  	}
7639 	sc->sc_flags |= IWX_FLAG_MAC_ACTIVE;
7640 
7641 	err = iwx_binding_cmd(sc, in, IWX_FW_CTXT_ACTION_ADD);
7642 	if (err) {
7643 		printf("%s: could not add binding (error %d)\n",
7644 		    DEVNAME(sc), err);
7645 		goto rm_mac_ctxt;
7646 	}
7647 	sc->sc_flags |= IWX_FLAG_BINDING_ACTIVE;
7648 
7649 	err = iwx_add_sta_cmd(sc, in, 0);
7650 	if (err) {
7651 		printf("%s: could not add sta (error %d)\n",
7652 		    DEVNAME(sc), err);
7653 		goto rm_binding;
7654 	}
7655 	sc->sc_flags |= IWX_FLAG_STA_ACTIVE;
7656 
7657 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
7658 		err = iwx_enable_txq(sc, IWX_MONITOR_STA_ID,
7659 		    IWX_DQA_INJECT_MONITOR_QUEUE, IWX_MGMT_TID,
7660 		    IWX_TX_RING_COUNT);
7661 		if (err)
7662 			goto rm_sta;
7663 		return 0;
7664 	}
7665 
7666 	err = iwx_enable_mgmt_queue(sc);
7667 	if (err)
7668 		goto rm_sta;
7669 
7670 	err = iwx_clear_statistics(sc);
7671 	if (err)
7672 		goto rm_mgmt_queue;
7673 
7674 	/*
7675 	 * Prevent the FW from wandering off channel during association
7676 	 * by "protecting" the session with a time event.
7677 	 */
7678 	if (in->in_ni.ni_intval)
7679 		duration = in->in_ni.ni_intval * 9;
7680 	else
7681 		duration = 900;
7682 	return iwx_schedule_session_protection(sc, in, duration);
7683 
7684 rm_mgmt_queue:
7685 	if (generation == sc->sc_generation)
7686 		iwx_disable_mgmt_queue(sc);
7687 rm_sta:
7688 	if (generation == sc->sc_generation) {
7689 		iwx_rm_sta_cmd(sc, in);
7690 		sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE;
7691 	}
7692 rm_binding:
7693 	if (generation == sc->sc_generation) {
7694 		iwx_binding_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE);
7695 		sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE;
7696 	}
7697 rm_mac_ctxt:
7698 	if (generation == sc->sc_generation) {
7699 		iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE, 0);
7700 		sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE;
7701 	}
7702 	return err;
7703 }
7704 
7705 static int
7706 iwx_deauth(struct iwx_softc *sc)
7707 {
7708 	struct ieee80211com *ic = &sc->sc_ic;
7709 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
7710 	struct iwx_node *in = IWX_NODE(vap->iv_bss);
7711 	int err;
7712 
7713 	IWX_ASSERT_LOCKED(sc);
7714 
7715 	iwx_unprotect_session(sc, in);
7716 
7717 	if (sc->sc_flags & IWX_FLAG_STA_ACTIVE) {
7718 		err = iwx_rm_sta(sc, in);
7719 		if (err)
7720 			return err;
7721 		sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE;
7722 	}
7723 
7724 	if (sc->sc_flags & IWX_FLAG_BINDING_ACTIVE) {
7725 		err = iwx_binding_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE);
7726 		if (err) {
7727 			printf("%s: could not remove binding (error %d)\n",
7728 			    DEVNAME(sc), err);
7729 			return err;
7730 		}
7731 		sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE;
7732 	}
7733 
7734 	DPRINTF(("%s:  IWX_FLAG_MAC_ACTIVE=%d\n", __func__, sc->sc_flags &
7735 	    IWX_FLAG_MAC_ACTIVE));
7736 	if (sc->sc_flags & IWX_FLAG_MAC_ACTIVE) {
7737 		err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE, 0);
7738 		if (err) {
7739 			printf("%s: could not remove MAC context (error %d)\n",
7740 			    DEVNAME(sc), err);
7741 			return err;
7742 		}
7743 		sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE;
7744 	}
7745 
7746 	/* Move unused PHY context to a default channel. */
7747 	//TODO uncommented in obsd, but stays on the way of auth->auth
7748 	err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0],
7749 	    &ic->ic_channels[1], 1, 1, 0, IEEE80211_HTOP0_SCO_SCN,
7750 	    IEEE80211_VHTOP0_CHAN_WIDTH_HT);
7751 	if (err)
7752 		return err;
7753 
7754 	return 0;
7755 }
7756 
7757 static int
7758 iwx_run(struct ieee80211vap *vap, struct iwx_softc *sc)
7759 {
7760 	struct ieee80211com *ic = &sc->sc_ic;
7761 	struct iwx_node *in = IWX_NODE(vap->iv_bss);
7762 	struct ieee80211_node *ni = &in->in_ni;
7763 	struct iwx_vap *ivp = IWX_VAP(vap);
7764 	int err;
7765 
7766 	IWX_ASSERT_LOCKED(sc);
7767 
7768 	if (ni->ni_flags & IEEE80211_NODE_HT) {
7769 		uint8_t chains = iwx_mimo_enabled(sc) ? 2 : 1;
7770 		uint8_t sco, vht_chan_width;
7771 			sco = IEEE80211_HTOP0_SCO_SCN;
7772 		if ((ni->ni_flags & IEEE80211_NODE_VHT) &&
7773 		    IEEE80211_IS_CHAN_VHT80(ni->ni_chan))
7774 			vht_chan_width = IEEE80211_VHTOP0_CHAN_WIDTH_80;
7775 		else
7776 			vht_chan_width = IEEE80211_VHTOP0_CHAN_WIDTH_HT;
7777 		err = iwx_phy_ctxt_update(sc, ivp->phy_ctxt,
7778 		    ivp->phy_ctxt->channel, chains, chains,
7779 		    0, sco, vht_chan_width);
7780 		if (err) {
7781 			printf("%s: failed to update PHY\n", DEVNAME(sc));
7782 			return err;
7783 		}
7784 	}
7785 
7786 	/* Update STA again to apply HT and VHT settings. */
7787 	err = iwx_add_sta_cmd(sc, in, 1);
7788 	if (err) {
7789 		printf("%s: could not update STA (error %d)\n",
7790 		    DEVNAME(sc), err);
7791 		return err;
7792 	}
7793 
7794 	/* We have now been assigned an associd by the AP. */
7795 	err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_MODIFY, 1);
7796 	if (err) {
7797 		printf("%s: failed to update MAC\n", DEVNAME(sc));
7798 		return err;
7799 	}
7800 
7801 	err = iwx_sf_config(sc, IWX_SF_FULL_ON);
7802 	if (err) {
7803 		printf("%s: could not set sf full on (error %d)\n",
7804 		    DEVNAME(sc), err);
7805 		return err;
7806 	}
7807 
7808 	err = iwx_allow_mcast(sc);
7809 	if (err) {
7810 		printf("%s: could not allow mcast (error %d)\n",
7811 		    DEVNAME(sc), err);
7812 		return err;
7813 	}
7814 
7815 	err = iwx_power_update_device(sc);
7816 	if (err) {
7817 		printf("%s: could not send power command (error %d)\n",
7818 		    DEVNAME(sc), err);
7819 		return err;
7820 	}
7821 #ifdef notyet
7822 	/*
7823 	 * Disabled for now. Default beacon filter settings
7824 	 * prevent net80211 from getting ERP and HT protection
7825 	 * updates from beacons.
7826 	 */
7827 	err = iwx_enable_beacon_filter(sc, in);
7828 	if (err) {
7829 		printf("%s: could not enable beacon filter\n",
7830 		    DEVNAME(sc));
7831 		return err;
7832 	}
7833 #endif
7834 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
7835 		return 0;
7836 
7837 	err = iwx_power_mac_update_mode(sc, in);
7838 	if (err) {
7839 		printf("%s: could not update MAC power (error %d)\n",
7840 		    DEVNAME(sc), err);
7841 		return err;
7842 	}
7843 
7844 	err = iwx_rs_init(sc, in);
7845 	if (err) {
7846 		printf("%s: could not init rate scaling (error %d)\n",
7847 		    DEVNAME(sc), err);
7848 		return err;
7849 	}
7850 
7851 	return 0;
7852 }
7853 
7854 static int
7855 iwx_run_stop(struct iwx_softc *sc)
7856 {
7857 	struct ieee80211com *ic = &sc->sc_ic;
7858 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
7859 	struct iwx_node *in = IWX_NODE(vap->iv_bss);
7860 	struct ieee80211_node *ni = &in->in_ni;
7861 	int err, i;
7862 
7863 	IWX_ASSERT_LOCKED(sc);
7864 
7865 	err = iwx_flush_sta(sc, in);
7866 	if (err) {
7867 		printf("%s: could not flush Tx path (error %d)\n",
7868 		    DEVNAME(sc), err);
7869 		return err;
7870 	}
7871 
7872 	/*
7873 	 * Stop Rx BA sessions now. We cannot rely on the BA task
7874 	 * for this when moving out of RUN state since it runs in a
7875 	 * separate thread.
7876 	 * Note that in->in_ni (struct ieee80211_node) already represents
7877 	 * our new access point in case we are roaming between APs.
7878 	 * This means we cannot rely on struct ieee802111_node to tell
7879 	 * us which BA sessions exist.
7880 	 */
7881 	// TODO agg
7882 	for (i = 0; i < nitems(sc->sc_rxba_data); i++) {
7883 		struct iwx_rxba_data *rxba = &sc->sc_rxba_data[i];
7884 		if (rxba->baid == IWX_RX_REORDER_DATA_INVALID_BAID)
7885 			continue;
7886 		iwx_sta_rx_agg(sc, ni, rxba->tid, 0, 0, 0, 0);
7887 	}
7888 
7889 	err = iwx_sf_config(sc, IWX_SF_INIT_OFF);
7890 	if (err)
7891 		return err;
7892 
7893 	err = iwx_disable_beacon_filter(sc);
7894 	if (err) {
7895 		printf("%s: could not disable beacon filter (error %d)\n",
7896 		    DEVNAME(sc), err);
7897 		return err;
7898 	}
7899 
7900 	/* Mark station as disassociated. */
7901 	err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_MODIFY, 0);
7902 	if (err) {
7903 		printf("%s: failed to update MAC\n", DEVNAME(sc));
7904 		return err;
7905 	}
7906 
7907 	return 0;
7908 }
7909 
7910 static struct ieee80211_node *
7911 iwx_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
7912 {
7913 	return malloc(sizeof (struct iwx_node), M_80211_NODE,
7914 	    M_NOWAIT | M_ZERO);
7915 }
7916 
7917 #if 0
7918 int
7919 iwx_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
7920     struct ieee80211_key *k)
7921 {
7922 	struct iwx_softc *sc = ic->ic_softc;
7923 	struct iwx_node *in = (void *)ni;
7924 	struct iwx_setkey_task_arg *a;
7925 	int err;
7926 
7927 	if (k->k_cipher != IEEE80211_CIPHER_CCMP) {
7928 		/* Fallback to software crypto for other ciphers. */
7929 		err = ieee80211_set_key(ic, ni, k);
7930 		if (!err && in != NULL && (k->k_flags & IEEE80211_KEY_GROUP))
7931 			in->in_flags |= IWX_NODE_FLAG_HAVE_GROUP_KEY;
7932 		return err;
7933 	}
7934 
7935 	if (sc->setkey_nkeys >= nitems(sc->setkey_arg))
7936 		return ENOSPC;
7937 
7938 	a = &sc->setkey_arg[sc->setkey_cur];
7939 	a->sta_id = IWX_STATION_ID;
7940 	a->ni = ni;
7941 	a->k = k;
7942 	sc->setkey_cur = (sc->setkey_cur + 1) % nitems(sc->setkey_arg);
7943 	sc->setkey_nkeys++;
7944 	iwx_add_task(sc, systq, &sc->setkey_task);
7945 	return EBUSY;
7946 }
7947 
7948 int
7949 iwx_add_sta_key(struct iwx_softc *sc, int sta_id, struct ieee80211_node *ni,
7950     struct ieee80211_key *k)
7951 {
7952 	struct ieee80211com *ic = &sc->sc_ic;
7953 	struct iwx_node *in = (void *)ni;
7954 	struct iwx_add_sta_key_cmd cmd;
7955 	uint32_t status;
7956 	const int want_keymask = (IWX_NODE_FLAG_HAVE_PAIRWISE_KEY |
7957 	    IWX_NODE_FLAG_HAVE_GROUP_KEY);
7958 	int err;
7959 
7960 	/*
7961 	 * Keys are stored in 'ni' so 'k' is valid if 'ni' is valid.
7962 	 * Currently we only implement station mode where 'ni' is always
7963 	 * ic->ic_bss so there is no need to validate arguments beyond this:
7964 	 */
7965 	KASSERT(ni == ic->ic_bss);
7966 
7967 	memset(&cmd, 0, sizeof(cmd));
7968 
7969 	cmd.common.key_flags = htole16(IWX_STA_KEY_FLG_CCM |
7970 	    IWX_STA_KEY_FLG_WEP_KEY_MAP |
7971 	    ((k->k_id << IWX_STA_KEY_FLG_KEYID_POS) &
7972 	    IWX_STA_KEY_FLG_KEYID_MSK));
7973 	if (k->k_flags & IEEE80211_KEY_GROUP) {
7974 		cmd.common.key_offset = 1;
7975 		cmd.common.key_flags |= htole16(IWX_STA_KEY_MULTICAST);
7976 	} else
7977 		cmd.common.key_offset = 0;
7978 
7979 	memcpy(cmd.common.key, k->k_key, MIN(sizeof(cmd.common.key), k->k_len));
7980 	cmd.common.sta_id = sta_id;
7981 
7982 	cmd.transmit_seq_cnt = htole64(k->k_tsc);
7983 
7984 	status = IWX_ADD_STA_SUCCESS;
7985 	err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA_KEY, sizeof(cmd), &cmd,
7986 	    &status);
7987 	if (sc->sc_flags & IWX_FLAG_SHUTDOWN)
7988 		return ECANCELED;
7989 	if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS)
7990 		err = EIO;
7991 	if (err) {
7992 		IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
7993 		    IEEE80211_REASON_AUTH_LEAVE);
7994 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
7995 		return err;
7996 	}
7997 
7998 	if (k->k_flags & IEEE80211_KEY_GROUP)
7999 		in->in_flags |= IWX_NODE_FLAG_HAVE_GROUP_KEY;
8000 	else
8001 		in->in_flags |= IWX_NODE_FLAG_HAVE_PAIRWISE_KEY;
8002 
8003 	if ((in->in_flags & want_keymask) == want_keymask) {
8004 		DPRINTF(("marking port %s valid\n",
8005 		    ether_sprintf(ni->ni_macaddr)));
8006 		ni->ni_port_valid = 1;
8007 		ieee80211_set_link_state(ic, LINK_STATE_UP);
8008 	}
8009 
8010 	return 0;
8011 }
8012 
8013 void
8014 iwx_setkey_task(void *arg)
8015 {
8016 	struct iwx_softc *sc = arg;
8017 	struct iwx_setkey_task_arg *a;
8018 	int err = 0, s = splnet();
8019 
8020 	while (sc->setkey_nkeys > 0) {
8021 		if (err || (sc->sc_flags & IWX_FLAG_SHUTDOWN))
8022 			break;
8023 		a = &sc->setkey_arg[sc->setkey_tail];
8024 		err = iwx_add_sta_key(sc, a->sta_id, a->ni, a->k);
8025 		a->sta_id = 0;
8026 		a->ni = NULL;
8027 		a->k = NULL;
8028 		sc->setkey_tail = (sc->setkey_tail + 1) %
8029 		    nitems(sc->setkey_arg);
8030 		sc->setkey_nkeys--;
8031 	}
8032 
8033 	refcnt_rele_wake(&sc->task_refs);
8034 	splx(s);
8035 }
8036 
8037 void
8038 iwx_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
8039     struct ieee80211_key *k)
8040 {
8041 	struct iwx_softc *sc = ic->ic_softc;
8042 	struct iwx_add_sta_key_cmd cmd;
8043 
8044 	if (k->k_cipher != IEEE80211_CIPHER_CCMP) {
8045 		/* Fallback to software crypto for other ciphers. */
8046                 ieee80211_delete_key(ic, ni, k);
8047 		return;
8048 	}
8049 
8050 	if ((sc->sc_flags & IWX_FLAG_STA_ACTIVE) == 0)
8051 		return;
8052 
8053 	memset(&cmd, 0, sizeof(cmd));
8054 
8055 	cmd.common.key_flags = htole16(IWX_STA_KEY_NOT_VALID |
8056 	    IWX_STA_KEY_FLG_NO_ENC | IWX_STA_KEY_FLG_WEP_KEY_MAP |
8057 	    ((k->k_id << IWX_STA_KEY_FLG_KEYID_POS) &
8058 	    IWX_STA_KEY_FLG_KEYID_MSK));
8059 	memcpy(cmd.common.key, k->k_key, MIN(sizeof(cmd.common.key), k->k_len));
8060 	if (k->k_flags & IEEE80211_KEY_GROUP)
8061 		cmd.common.key_offset = 1;
8062 	else
8063 		cmd.common.key_offset = 0;
8064 	cmd.common.sta_id = IWX_STATION_ID;
8065 
8066 	iwx_send_cmd_pdu(sc, IWX_ADD_STA_KEY, IWX_CMD_ASYNC, sizeof(cmd), &cmd);
8067 }
8068 #endif
8069 
8070 static int
8071 iwx_newstate_sub(struct ieee80211vap *vap, enum ieee80211_state nstate)
8072 {
8073 	struct ieee80211com *ic = vap->iv_ic;
8074 	struct iwx_softc *sc = ic->ic_softc;
8075 	enum ieee80211_state ostate = vap->iv_state;
8076 	int err = 0;
8077 
8078 	IWX_LOCK(sc);
8079 	if (sc->sc_flags & IWX_FLAG_SHUTDOWN) {
8080 		goto out;
8081 	}
8082 
8083 	if (nstate <= ostate || nstate > IEEE80211_S_RUN) {
8084 		switch (ostate) {
8085 		case IEEE80211_S_RUN:
8086 			err = iwx_run_stop(sc);
8087 			if (err)
8088 				goto out;
8089 			/* FALLTHROUGH */
8090 		case IEEE80211_S_ASSOC:
8091 		case IEEE80211_S_AUTH:
8092 			if (nstate <= IEEE80211_S_AUTH) {
8093 				err = iwx_deauth(sc);
8094 				if (err)
8095 					goto out;
8096 			}
8097 			/* FALLTHROUGH */
8098 		case IEEE80211_S_SCAN:
8099 		case IEEE80211_S_INIT:
8100 		default:
8101 			break;
8102 		}
8103 //
8104 //		/* Die now if iwx_stop() was called while we were sleeping. */
8105 //		if (sc->sc_flags & IWX_FLAG_SHUTDOWN) {
8106 //			refcnt_rele_wake(&sc->task_refs);
8107 //			splx(s);
8108 //			return;
8109 //		}
8110 	}
8111 
8112 	switch (nstate) {
8113 	case IEEE80211_S_INIT:
8114 		break;
8115 
8116 	case IEEE80211_S_SCAN:
8117 			break;
8118 
8119 	case IEEE80211_S_AUTH:
8120 		err = iwx_auth(vap, sc);
8121 		break;
8122 
8123 	case IEEE80211_S_ASSOC:
8124 		break;
8125 
8126 	case IEEE80211_S_RUN:
8127 		err = iwx_run(vap, sc);
8128 		break;
8129 	default:
8130 		break;
8131 	}
8132 
8133 out:
8134 	IWX_UNLOCK(sc);
8135 
8136 	return (err);
8137 }
8138 
8139 static int
8140 iwx_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8141 {
8142 	struct iwx_vap *ivp = IWX_VAP(vap);
8143 	struct ieee80211com *ic = vap->iv_ic;
8144 	enum ieee80211_state ostate = vap->iv_state;
8145 	int err;
8146 
8147 	/*
8148 	 * Prevent attempts to transition towards the same state, unless
8149 	 * we are scanning in which case a SCAN -> SCAN transition
8150 	 * triggers another scan iteration. And AUTH -> AUTH is needed
8151 	 * to support band-steering.
8152 	 */
8153 	if (ostate == nstate && nstate != IEEE80211_S_SCAN &&
8154 	    nstate != IEEE80211_S_AUTH)
8155 		return 0;
8156 	IEEE80211_UNLOCK(ic);
8157 	err = iwx_newstate_sub(vap, nstate);
8158 	IEEE80211_LOCK(ic);
8159 	if (err == 0)
8160 		err = ivp->iv_newstate(vap, nstate, arg);
8161 
8162 	return (err);
8163 }
8164 
8165 static void
8166 iwx_endscan(struct iwx_softc *sc)
8167 {
8168         struct ieee80211com *ic = &sc->sc_ic;
8169         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8170 
8171         if ((sc->sc_flags & (IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN)) == 0)
8172                 return;
8173 
8174         sc->sc_flags &= ~(IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN);
8175 
8176         ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps));
8177         wakeup(&vap->iv_state); /* wake up iwx_newstate */
8178 }
8179 
8180 /*
8181  * Aging and idle timeouts for the different possible scenarios
8182  * in default configuration
8183  */
8184 static const uint32_t
8185 iwx_sf_full_timeout_def[IWX_SF_NUM_SCENARIO][IWX_SF_NUM_TIMEOUT_TYPES] = {
8186 	{
8187 		htole32(IWX_SF_SINGLE_UNICAST_AGING_TIMER_DEF),
8188 		htole32(IWX_SF_SINGLE_UNICAST_IDLE_TIMER_DEF)
8189 	},
8190 	{
8191 		htole32(IWX_SF_AGG_UNICAST_AGING_TIMER_DEF),
8192 		htole32(IWX_SF_AGG_UNICAST_IDLE_TIMER_DEF)
8193 	},
8194 	{
8195 		htole32(IWX_SF_MCAST_AGING_TIMER_DEF),
8196 		htole32(IWX_SF_MCAST_IDLE_TIMER_DEF)
8197 	},
8198 	{
8199 		htole32(IWX_SF_BA_AGING_TIMER_DEF),
8200 		htole32(IWX_SF_BA_IDLE_TIMER_DEF)
8201 	},
8202 	{
8203 		htole32(IWX_SF_TX_RE_AGING_TIMER_DEF),
8204 		htole32(IWX_SF_TX_RE_IDLE_TIMER_DEF)
8205 	},
8206 };
8207 
8208 /*
8209  * Aging and idle timeouts for the different possible scenarios
8210  * in single BSS MAC configuration.
8211  */
8212 static const uint32_t
8213 iwx_sf_full_timeout[IWX_SF_NUM_SCENARIO][IWX_SF_NUM_TIMEOUT_TYPES] = {
8214 	{
8215 		htole32(IWX_SF_SINGLE_UNICAST_AGING_TIMER),
8216 		htole32(IWX_SF_SINGLE_UNICAST_IDLE_TIMER)
8217 	},
8218 	{
8219 		htole32(IWX_SF_AGG_UNICAST_AGING_TIMER),
8220 		htole32(IWX_SF_AGG_UNICAST_IDLE_TIMER)
8221 	},
8222 	{
8223 		htole32(IWX_SF_MCAST_AGING_TIMER),
8224 		htole32(IWX_SF_MCAST_IDLE_TIMER)
8225 	},
8226 	{
8227 		htole32(IWX_SF_BA_AGING_TIMER),
8228 		htole32(IWX_SF_BA_IDLE_TIMER)
8229 	},
8230 	{
8231 		htole32(IWX_SF_TX_RE_AGING_TIMER),
8232 		htole32(IWX_SF_TX_RE_IDLE_TIMER)
8233 	},
8234 };
8235 
8236 static void
8237 iwx_fill_sf_command(struct iwx_softc *sc, struct iwx_sf_cfg_cmd *sf_cmd,
8238     struct ieee80211_node *ni)
8239 {
8240 	int i, j, watermark;
8241 
8242 	sf_cmd->watermark[IWX_SF_LONG_DELAY_ON] = htole32(IWX_SF_W_MARK_SCAN);
8243 
8244 	/*
8245 	 * If we are in association flow - check antenna configuration
8246 	 * capabilities of the AP station, and choose the watermark accordingly.
8247 	 */
8248 	if (ni) {
8249 		if (ni->ni_flags & IEEE80211_NODE_HT) {
8250 			struct ieee80211_htrateset *htrs = &ni->ni_htrates;
8251 			int hasmimo = 0;
8252 			for (i = 0; i < htrs->rs_nrates; i++) {
8253 				if (htrs->rs_rates[i] > 7) {
8254 					hasmimo = 1;
8255 					break;
8256 				}
8257 			}
8258 			if (hasmimo)
8259 				watermark = IWX_SF_W_MARK_MIMO2;
8260 			else
8261 				watermark = IWX_SF_W_MARK_SISO;
8262 		} else {
8263 			watermark = IWX_SF_W_MARK_LEGACY;
8264 		}
8265 	/* default watermark value for unassociated mode. */
8266 	} else {
8267 		watermark = IWX_SF_W_MARK_MIMO2;
8268 	}
8269 	sf_cmd->watermark[IWX_SF_FULL_ON] = htole32(watermark);
8270 
8271 	for (i = 0; i < IWX_SF_NUM_SCENARIO; i++) {
8272 		for (j = 0; j < IWX_SF_NUM_TIMEOUT_TYPES; j++) {
8273 			sf_cmd->long_delay_timeouts[i][j] =
8274 					htole32(IWX_SF_LONG_DELAY_AGING_TIMER);
8275 		}
8276 	}
8277 
8278 	if (ni) {
8279 		memcpy(sf_cmd->full_on_timeouts, iwx_sf_full_timeout,
8280 		       sizeof(iwx_sf_full_timeout));
8281 	} else {
8282 		memcpy(sf_cmd->full_on_timeouts, iwx_sf_full_timeout_def,
8283 		       sizeof(iwx_sf_full_timeout_def));
8284 	}
8285 
8286 }
8287 
8288 static int
8289 iwx_sf_config(struct iwx_softc *sc, int new_state)
8290 {
8291 	struct ieee80211com *ic = &sc->sc_ic;
8292 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8293 	struct ieee80211_node *ni = vap->iv_bss;
8294 	struct iwx_sf_cfg_cmd sf_cmd = {
8295 		.state = htole32(new_state),
8296 	};
8297 	int err = 0;
8298 
8299 	switch (new_state) {
8300 	case IWX_SF_UNINIT:
8301 	case IWX_SF_INIT_OFF:
8302 		iwx_fill_sf_command(sc, &sf_cmd, NULL);
8303 		break;
8304 	case IWX_SF_FULL_ON:
8305 		iwx_fill_sf_command(sc, &sf_cmd, ni);
8306 		break;
8307 	default:
8308 		return EINVAL;
8309 	}
8310 
8311 	err = iwx_send_cmd_pdu(sc, IWX_REPLY_SF_CFG_CMD, IWX_CMD_ASYNC,
8312 				   sizeof(sf_cmd), &sf_cmd);
8313 	return err;
8314 }
8315 
8316 static int
8317 iwx_send_bt_init_conf(struct iwx_softc *sc)
8318 {
8319 	struct iwx_bt_coex_cmd bt_cmd;
8320 
8321 	bzero(&bt_cmd, sizeof(struct iwx_bt_coex_cmd));
8322 
8323 	bt_cmd.mode = htole32(IWX_BT_COEX_NW);
8324 	bt_cmd.enabled_modules |= BT_COEX_SYNC2SCO_ENABLED;
8325 	bt_cmd.enabled_modules |= BT_COEX_HIGH_BAND_RET;
8326 
8327 
8328 	return iwx_send_cmd_pdu(sc, IWX_BT_CONFIG, 0, sizeof(bt_cmd),
8329 	    &bt_cmd);
8330 }
8331 
8332 static int
8333 iwx_send_soc_conf(struct iwx_softc *sc)
8334 {
8335 	struct iwx_soc_configuration_cmd cmd;
8336 	int err;
8337 	uint32_t cmd_id, flags = 0;
8338 
8339 	memset(&cmd, 0, sizeof(cmd));
8340 
8341 	/*
8342 	 * In VER_1 of this command, the discrete value is considered
8343 	 * an integer; In VER_2, it's a bitmask.  Since we have only 2
8344 	 * values in VER_1, this is backwards-compatible with VER_2,
8345 	 * as long as we don't set any other flag bits.
8346 	 */
8347 	if (!sc->sc_integrated) { /* VER_1 */
8348 		flags = IWX_SOC_CONFIG_CMD_FLAGS_DISCRETE;
8349 	} else { /* VER_2 */
8350 		uint8_t scan_cmd_ver;
8351 		if (sc->sc_ltr_delay != IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE)
8352 			flags |= (sc->sc_ltr_delay &
8353 			    IWX_SOC_FLAGS_LTR_APPLY_DELAY_MASK);
8354 		scan_cmd_ver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP,
8355 		    IWX_SCAN_REQ_UMAC);
8356 		if (scan_cmd_ver != IWX_FW_CMD_VER_UNKNOWN &&
8357 		    scan_cmd_ver >= 2 && sc->sc_low_latency_xtal)
8358 			flags |= IWX_SOC_CONFIG_CMD_FLAGS_LOW_LATENCY;
8359 	}
8360 	cmd.flags = htole32(flags);
8361 
8362 	cmd.latency = htole32(sc->sc_xtal_latency);
8363 
8364 	cmd_id = iwx_cmd_id(IWX_SOC_CONFIGURATION_CMD, IWX_SYSTEM_GROUP, 0);
8365 	err = iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd);
8366 	if (err)
8367 		printf("%s: failed to set soc latency: %d\n", DEVNAME(sc), err);
8368 	return err;
8369 }
8370 
8371 static int
8372 iwx_send_update_mcc_cmd(struct iwx_softc *sc, const char *alpha2)
8373 {
8374 	struct iwx_mcc_update_cmd mcc_cmd;
8375 	struct iwx_host_cmd hcmd = {
8376 		.id = IWX_MCC_UPDATE_CMD,
8377 		.flags = IWX_CMD_WANT_RESP,
8378 		.data = { &mcc_cmd },
8379 	};
8380 	struct iwx_rx_packet *pkt;
8381 	struct iwx_mcc_update_resp *resp;
8382 	size_t resp_len;
8383 	int err;
8384 
8385 	memset(&mcc_cmd, 0, sizeof(mcc_cmd));
8386 	mcc_cmd.mcc = htole16(alpha2[0] << 8 | alpha2[1]);
8387 	if (isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_WIFI_MCC_UPDATE) ||
8388 	    isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_LAR_MULTI_MCC))
8389 		mcc_cmd.source_id = IWX_MCC_SOURCE_GET_CURRENT;
8390 	else
8391 		mcc_cmd.source_id = IWX_MCC_SOURCE_OLD_FW;
8392 
8393 	hcmd.len[0] = sizeof(struct iwx_mcc_update_cmd);
8394 	hcmd.resp_pkt_len = IWX_CMD_RESP_MAX;
8395 
8396 	err = iwx_send_cmd(sc, &hcmd);
8397 	if (err)
8398 		return err;
8399 
8400 	pkt = hcmd.resp_pkt;
8401 	if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) {
8402 		err = EIO;
8403 		goto out;
8404 	}
8405 
8406 	resp_len = iwx_rx_packet_payload_len(pkt);
8407 	if (resp_len < sizeof(*resp)) {
8408 		err = EIO;
8409 		goto out;
8410 	}
8411 
8412 	resp = (void *)pkt->data;
8413 	if (resp_len != sizeof(*resp) +
8414 	    resp->n_channels * sizeof(resp->channels[0])) {
8415 		err = EIO;
8416 		goto out;
8417 	}
8418 
8419 	DPRINTF(("MCC status=0x%x mcc=0x%x cap=0x%x time=0x%x geo_info=0x%x source_id=0x%d n_channels=%u\n",
8420 	    resp->status, resp->mcc, resp->cap, resp->time, resp->geo_info, resp->source_id, resp->n_channels));
8421 
8422 out:
8423 	iwx_free_resp(sc, &hcmd);
8424 
8425 	return err;
8426 }
8427 
8428 static int
8429 iwx_send_temp_report_ths_cmd(struct iwx_softc *sc)
8430 {
8431 	struct iwx_temp_report_ths_cmd cmd;
8432 	int err;
8433 
8434 	/*
8435 	 * In order to give responsibility for critical-temperature-kill
8436 	 * and TX backoff to FW we need to send an empty temperature
8437 	 * reporting command at init time.
8438 	 */
8439 	memset(&cmd, 0, sizeof(cmd));
8440 
8441 	err = iwx_send_cmd_pdu(sc,
8442 	    IWX_WIDE_ID(IWX_PHY_OPS_GROUP, IWX_TEMP_REPORTING_THRESHOLDS_CMD),
8443 	    0, sizeof(cmd), &cmd);
8444 	if (err)
8445 		printf("%s: TEMP_REPORT_THS_CMD command failed (error %d)\n",
8446 		    DEVNAME(sc), err);
8447 
8448 	return err;
8449 }
8450 
8451 static int
8452 iwx_init_hw(struct iwx_softc *sc)
8453 {
8454 	struct ieee80211com *ic = &sc->sc_ic;
8455 	int err = 0, i;
8456 
8457 	err = iwx_run_init_mvm_ucode(sc, 0);
8458 	if (err)
8459 		return err;
8460 
8461 	if (!iwx_nic_lock(sc))
8462 		return EBUSY;
8463 
8464 	err = iwx_send_tx_ant_cfg(sc, iwx_fw_valid_tx_ant(sc));
8465 	if (err) {
8466 		printf("%s: could not init tx ant config (error %d)\n",
8467 		    DEVNAME(sc), err);
8468 		goto err;
8469 	}
8470 
8471 	if (sc->sc_tx_with_siso_diversity) {
8472 		err = iwx_send_phy_cfg_cmd(sc);
8473 		if (err) {
8474 			printf("%s: could not send phy config (error %d)\n",
8475 			    DEVNAME(sc), err);
8476 			goto err;
8477 		}
8478 	}
8479 
8480 	err = iwx_send_bt_init_conf(sc);
8481 	if (err) {
8482 		printf("%s: could not init bt coex (error %d)\n",
8483 		    DEVNAME(sc), err);
8484 		return err;
8485 	}
8486 
8487 	err = iwx_send_soc_conf(sc);
8488 	if (err) {
8489 		printf("%s: iwx_send_soc_conf failed\n", __func__);
8490 		return err;
8491 	}
8492 
8493 	if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_DQA_SUPPORT)) {
8494 		printf("%s: === IWX_UCODE_TLV_CAPA_DQA_SUPPORT\n", __func__);
8495 		err = iwx_send_dqa_cmd(sc);
8496 		if (err) {
8497 			printf("%s: IWX_UCODE_TLV_CAPA_DQA_SUPPORT "
8498 			    "failed (error %d)\n", __func__, err);
8499 			return err;
8500 		}
8501 	}
8502 	// TODO phyctxt
8503 	for (i = 0; i < IWX_NUM_PHY_CTX; i++) {
8504 		/*
8505 		 * The channel used here isn't relevant as it's
8506 		 * going to be overwritten in the other flows.
8507 		 * For now use the first channel we have.
8508 		 */
8509 		sc->sc_phyctxt[i].id = i;
8510 		sc->sc_phyctxt[i].channel = &ic->ic_channels[1];
8511 		err = iwx_phy_ctxt_cmd(sc, &sc->sc_phyctxt[i], 1, 1,
8512 		    IWX_FW_CTXT_ACTION_ADD, 0, 0, 0);
8513 		if (err) {
8514 			printf("%s: could not add phy context %d (error %d)\n",
8515 			    DEVNAME(sc), i, err);
8516 			goto err;
8517 		}
8518 		if (iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
8519 		    IWX_RLC_CONFIG_CMD) == 2) {
8520 			err = iwx_phy_send_rlc(sc, &sc->sc_phyctxt[i], 1, 1);
8521 			if (err) {
8522 				printf("%s: could not configure RLC for PHY "
8523 				    "%d (error %d)\n", DEVNAME(sc), i, err);
8524 				goto err;
8525 			}
8526 		}
8527 	}
8528 
8529 	err = iwx_config_ltr(sc);
8530 	if (err) {
8531 		printf("%s: PCIe LTR configuration failed (error %d)\n",
8532 		    DEVNAME(sc), err);
8533 	}
8534 
8535 	if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CT_KILL_BY_FW)) {
8536 		err = iwx_send_temp_report_ths_cmd(sc);
8537 		if (err) {
8538 			printf("%s: iwx_send_temp_report_ths_cmd failed\n",
8539 			    __func__);
8540 			goto err;
8541 		}
8542 	}
8543 
8544 	err = iwx_power_update_device(sc);
8545 	if (err) {
8546 		printf("%s: could not send power command (error %d)\n",
8547 		    DEVNAME(sc), err);
8548 		goto err;
8549 	}
8550 
8551 	if (sc->sc_nvm.lar_enabled) {
8552 		err = iwx_send_update_mcc_cmd(sc, "ZZ");
8553 		if (err) {
8554 			printf("%s: could not init LAR (error %d)\n",
8555 			    DEVNAME(sc), err);
8556 			goto err;
8557 		}
8558 	}
8559 
8560 	err = iwx_config_umac_scan_reduced(sc);
8561 	if (err) {
8562 		printf("%s: could not configure scan (error %d)\n",
8563 		    DEVNAME(sc), err);
8564 		goto err;
8565 	}
8566 
8567 	err = iwx_disable_beacon_filter(sc);
8568 	if (err) {
8569 		printf("%s: could not disable beacon filter (error %d)\n",
8570 		    DEVNAME(sc), err);
8571 		goto err;
8572 	}
8573 
8574 err:
8575 	iwx_nic_unlock(sc);
8576 	return err;
8577 }
8578 
8579 /* Allow multicast from our BSSID. */
8580 static int
8581 iwx_allow_mcast(struct iwx_softc *sc)
8582 {
8583 	struct ieee80211com *ic = &sc->sc_ic;
8584 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8585 	struct iwx_node *in = IWX_NODE(vap->iv_bss);
8586 	struct iwx_mcast_filter_cmd *cmd;
8587 	size_t size;
8588 	int err;
8589 
8590 	size = roundup(sizeof(*cmd), 4);
8591 	cmd = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
8592 	if (cmd == NULL)
8593 		return ENOMEM;
8594 	cmd->filter_own = 1;
8595 	cmd->port_id = 0;
8596 	cmd->count = 0;
8597 	cmd->pass_all = 1;
8598 	IEEE80211_ADDR_COPY(cmd->bssid, in->in_macaddr);
8599 
8600 	err = iwx_send_cmd_pdu(sc, IWX_MCAST_FILTER_CMD,
8601 	    0, size, cmd);
8602 	free(cmd, M_DEVBUF);
8603 	return err;
8604 }
8605 
8606 static int
8607 iwx_init(struct iwx_softc *sc)
8608 {
8609 	int err, generation;
8610 	generation = ++sc->sc_generation;
8611 	iwx_preinit(sc);
8612 
8613 	err = iwx_start_hw(sc);
8614 	if (err) {
8615 		printf("%s: iwx_start_hw failed\n", __func__);
8616 		return err;
8617 	}
8618 
8619 	err = iwx_init_hw(sc);
8620 	if (err) {
8621 		if (generation == sc->sc_generation)
8622 			iwx_stop_device(sc);
8623 		printf("%s: iwx_init_hw failed (error %d)\n", __func__, err);
8624 		return err;
8625 	}
8626 
8627 	sc->sc_flags |= IWX_FLAG_HW_INITED;
8628 	callout_reset(&sc->watchdog_to, hz, iwx_watchdog, sc);
8629 
8630 	return 0;
8631 }
8632 
8633 static void
8634 iwx_start(struct iwx_softc *sc)
8635 {
8636         struct ieee80211_node *ni;
8637         struct mbuf *m;
8638 
8639         IWX_ASSERT_LOCKED(sc);
8640 
8641         while (sc->qfullmsk == 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
8642                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
8643                 if (iwx_tx(sc, m, ni) != 0) {
8644                       if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
8645                         continue;
8646                 }
8647         }
8648 }
8649 
8650 static void
8651 iwx_stop(struct iwx_softc *sc)
8652 {
8653 	struct ieee80211com *ic = &sc->sc_ic;
8654 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8655 	struct iwx_vap *ivp = IWX_VAP(vap);
8656 
8657 	iwx_stop_device(sc);
8658 
8659 	/* Reset soft state. */
8660 	sc->sc_generation++;
8661 	ivp->phy_ctxt = NULL;
8662 
8663 	sc->sc_flags &= ~(IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN);
8664 	sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE;
8665 	sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE;
8666 	sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE;
8667 	sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE;
8668 	sc->sc_flags &= ~IWX_FLAG_HW_ERR;
8669 	sc->sc_flags &= ~IWX_FLAG_SHUTDOWN;
8670 	sc->sc_flags &= ~IWX_FLAG_TXFLUSH;
8671 
8672 	sc->sc_rx_ba_sessions = 0;
8673 	sc->ba_rx.start_tidmask = 0;
8674 	sc->ba_rx.stop_tidmask = 0;
8675 	memset(sc->aggqid, 0, sizeof(sc->aggqid));
8676 	sc->ba_tx.start_tidmask = 0;
8677 	sc->ba_tx.stop_tidmask = 0;
8678 }
8679 
8680 static void
8681 iwx_watchdog(void *arg)
8682 {
8683 	struct iwx_softc *sc = arg;
8684 	struct ieee80211com *ic = &sc->sc_ic;
8685 	int i;
8686 
8687 	/*
8688 	 * We maintain a separate timer for each Tx queue because
8689 	 * Tx aggregation queues can get "stuck" while other queues
8690 	 * keep working. The Linux driver uses a similar workaround.
8691 	 */
8692 	for (i = 0; i < nitems(sc->sc_tx_timer); i++) {
8693 		if (sc->sc_tx_timer[i] > 0) {
8694 			if (--sc->sc_tx_timer[i] == 0) {
8695 				printf("%s: device timeout\n", DEVNAME(sc));
8696 
8697 				iwx_nic_error(sc);
8698 				iwx_dump_driver_status(sc);
8699 				ieee80211_restart_all(ic);
8700 				return;
8701 			}
8702 		}
8703 	}
8704 	callout_reset(&sc->watchdog_to, hz, iwx_watchdog, sc);
8705 }
8706 
8707 /*
8708  * Note: This structure is read from the device with IO accesses,
8709  * and the reading already does the endian conversion. As it is
8710  * read with uint32_t-sized accesses, any members with a different size
8711  * need to be ordered correctly though!
8712  */
8713 struct iwx_error_event_table {
8714 	uint32_t valid;		/* (nonzero) valid, (0) log is empty */
8715 	uint32_t error_id;		/* type of error */
8716 	uint32_t trm_hw_status0;	/* TRM HW status */
8717 	uint32_t trm_hw_status1;	/* TRM HW status */
8718 	uint32_t blink2;		/* branch link */
8719 	uint32_t ilink1;		/* interrupt link */
8720 	uint32_t ilink2;		/* interrupt link */
8721 	uint32_t data1;		/* error-specific data */
8722 	uint32_t data2;		/* error-specific data */
8723 	uint32_t data3;		/* error-specific data */
8724 	uint32_t bcon_time;		/* beacon timer */
8725 	uint32_t tsf_low;		/* network timestamp function timer */
8726 	uint32_t tsf_hi;		/* network timestamp function timer */
8727 	uint32_t gp1;		/* GP1 timer register */
8728 	uint32_t gp2;		/* GP2 timer register */
8729 	uint32_t fw_rev_type;	/* firmware revision type */
8730 	uint32_t major;		/* uCode version major */
8731 	uint32_t minor;		/* uCode version minor */
8732 	uint32_t hw_ver;		/* HW Silicon version */
8733 	uint32_t brd_ver;		/* HW board version */
8734 	uint32_t log_pc;		/* log program counter */
8735 	uint32_t frame_ptr;		/* frame pointer */
8736 	uint32_t stack_ptr;		/* stack pointer */
8737 	uint32_t hcmd;		/* last host command header */
8738 	uint32_t isr0;		/* isr status register LMPM_NIC_ISR0:
8739 				 * rxtx_flag */
8740 	uint32_t isr1;		/* isr status register LMPM_NIC_ISR1:
8741 				 * host_flag */
8742 	uint32_t isr2;		/* isr status register LMPM_NIC_ISR2:
8743 				 * enc_flag */
8744 	uint32_t isr3;		/* isr status register LMPM_NIC_ISR3:
8745 				 * time_flag */
8746 	uint32_t isr4;		/* isr status register LMPM_NIC_ISR4:
8747 				 * wico interrupt */
8748 	uint32_t last_cmd_id;	/* last HCMD id handled by the firmware */
8749 	uint32_t wait_event;		/* wait event() caller address */
8750 	uint32_t l2p_control;	/* L2pControlField */
8751 	uint32_t l2p_duration;	/* L2pDurationField */
8752 	uint32_t l2p_mhvalid;	/* L2pMhValidBits */
8753 	uint32_t l2p_addr_match;	/* L2pAddrMatchStat */
8754 	uint32_t lmpm_pmg_sel;	/* indicate which clocks are turned on
8755 				 * (LMPM_PMG_SEL) */
8756 	uint32_t u_timestamp;	/* indicate when the date and time of the
8757 				 * compilation */
8758 	uint32_t flow_handler;	/* FH read/write pointers, RX credit */
8759 } __packed /* LOG_ERROR_TABLE_API_S_VER_3 */;
8760 
8761 /*
8762  * UMAC error struct - relevant starting from family 8000 chip.
8763  * Note: This structure is read from the device with IO accesses,
8764  * and the reading already does the endian conversion. As it is
8765  * read with u32-sized accesses, any members with a different size
8766  * need to be ordered correctly though!
8767  */
8768 struct iwx_umac_error_event_table {
8769 	uint32_t valid;		/* (nonzero) valid, (0) log is empty */
8770 	uint32_t error_id;	/* type of error */
8771 	uint32_t blink1;	/* branch link */
8772 	uint32_t blink2;	/* branch link */
8773 	uint32_t ilink1;	/* interrupt link */
8774 	uint32_t ilink2;	/* interrupt link */
8775 	uint32_t data1;		/* error-specific data */
8776 	uint32_t data2;		/* error-specific data */
8777 	uint32_t data3;		/* error-specific data */
8778 	uint32_t umac_major;
8779 	uint32_t umac_minor;
8780 	uint32_t frame_pointer;	/* core register 27*/
8781 	uint32_t stack_pointer;	/* core register 28 */
8782 	uint32_t cmd_header;	/* latest host cmd sent to UMAC */
8783 	uint32_t nic_isr_pref;	/* ISR status register */
8784 } __packed;
8785 
8786 #define ERROR_START_OFFSET  (1 * sizeof(uint32_t))
8787 #define ERROR_ELEM_SIZE     (7 * sizeof(uint32_t))
8788 
8789 static void
8790 iwx_nic_umac_error(struct iwx_softc *sc)
8791 {
8792 	struct iwx_umac_error_event_table table;
8793 	uint32_t base;
8794 
8795 	base = sc->sc_uc.uc_umac_error_event_table;
8796 
8797 	if (base < 0x400000) {
8798 		printf("%s: Invalid error log pointer 0x%08x\n",
8799 		    DEVNAME(sc), base);
8800 		return;
8801 	}
8802 
8803 	if (iwx_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t))) {
8804 		printf("%s: reading errlog failed\n", DEVNAME(sc));
8805 		return;
8806 	}
8807 
8808 	if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
8809 		printf("%s: Start UMAC Error Log Dump:\n", DEVNAME(sc));
8810 		printf("%s: Status: 0x%x, count: %d\n", DEVNAME(sc),
8811 			sc->sc_flags, table.valid);
8812 	}
8813 
8814 	printf("%s: 0x%08X | %s\n", DEVNAME(sc), table.error_id,
8815 		iwx_desc_lookup(table.error_id));
8816 	printf("%s: 0x%08X | umac branchlink1\n", DEVNAME(sc), table.blink1);
8817 	printf("%s: 0x%08X | umac branchlink2\n", DEVNAME(sc), table.blink2);
8818 	printf("%s: 0x%08X | umac interruptlink1\n", DEVNAME(sc), table.ilink1);
8819 	printf("%s: 0x%08X | umac interruptlink2\n", DEVNAME(sc), table.ilink2);
8820 	printf("%s: 0x%08X | umac data1\n", DEVNAME(sc), table.data1);
8821 	printf("%s: 0x%08X | umac data2\n", DEVNAME(sc), table.data2);
8822 	printf("%s: 0x%08X | umac data3\n", DEVNAME(sc), table.data3);
8823 	printf("%s: 0x%08X | umac major\n", DEVNAME(sc), table.umac_major);
8824 	printf("%s: 0x%08X | umac minor\n", DEVNAME(sc), table.umac_minor);
8825 	printf("%s: 0x%08X | frame pointer\n", DEVNAME(sc),
8826 	    table.frame_pointer);
8827 	printf("%s: 0x%08X | stack pointer\n", DEVNAME(sc),
8828 	    table.stack_pointer);
8829 	printf("%s: 0x%08X | last host cmd\n", DEVNAME(sc), table.cmd_header);
8830 	printf("%s: 0x%08X | isr status reg\n", DEVNAME(sc),
8831 	    table.nic_isr_pref);
8832 }
8833 
8834 #define IWX_FW_SYSASSERT_CPU_MASK 0xf0000000
8835 static struct {
8836 	const char *name;
8837 	uint8_t num;
8838 } advanced_lookup[] = {
8839 	{ "NMI_INTERRUPT_WDG", 0x34 },
8840 	{ "SYSASSERT", 0x35 },
8841 	{ "UCODE_VERSION_MISMATCH", 0x37 },
8842 	{ "BAD_COMMAND", 0x38 },
8843 	{ "BAD_COMMAND", 0x39 },
8844 	{ "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
8845 	{ "FATAL_ERROR", 0x3D },
8846 	{ "NMI_TRM_HW_ERR", 0x46 },
8847 	{ "NMI_INTERRUPT_TRM", 0x4C },
8848 	{ "NMI_INTERRUPT_BREAK_POINT", 0x54 },
8849 	{ "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
8850 	{ "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
8851 	{ "NMI_INTERRUPT_HOST", 0x66 },
8852 	{ "NMI_INTERRUPT_LMAC_FATAL", 0x70 },
8853 	{ "NMI_INTERRUPT_UMAC_FATAL", 0x71 },
8854 	{ "NMI_INTERRUPT_OTHER_LMAC_FATAL", 0x73 },
8855 	{ "NMI_INTERRUPT_ACTION_PT", 0x7C },
8856 	{ "NMI_INTERRUPT_UNKNOWN", 0x84 },
8857 	{ "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
8858 	{ "ADVANCED_SYSASSERT", 0 },
8859 };
8860 
8861 static const char *
8862 iwx_desc_lookup(uint32_t num)
8863 {
8864 	int i;
8865 
8866 	for (i = 0; i < nitems(advanced_lookup) - 1; i++)
8867 		if (advanced_lookup[i].num ==
8868 		    (num & ~IWX_FW_SYSASSERT_CPU_MASK))
8869 			return advanced_lookup[i].name;
8870 
8871 	/* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */
8872 	return advanced_lookup[i].name;
8873 }
8874 
8875 /*
8876  * Support for dumping the error log seemed like a good idea ...
8877  * but it's mostly hex junk and the only sensible thing is the
8878  * hw/ucode revision (which we know anyway).  Since it's here,
8879  * I'll just leave it in, just in case e.g. the Intel guys want to
8880  * help us decipher some "ADVANCED_SYSASSERT" later.
8881  */
8882 static void
8883 iwx_nic_error(struct iwx_softc *sc)
8884 {
8885 	struct iwx_error_event_table table;
8886 	uint32_t base;
8887 
8888 	printf("%s: dumping device error log\n", DEVNAME(sc));
8889 	printf("%s: GOS-3758: 1\n", __func__);
8890 	base = sc->sc_uc.uc_lmac_error_event_table[0];
8891 	printf("%s: GOS-3758: 2\n", __func__);
8892 	if (base < 0x400000) {
8893 		printf("%s: Invalid error log pointer 0x%08x\n",
8894 		    DEVNAME(sc), base);
8895 		return;
8896 	}
8897 
8898 	printf("%s: GOS-3758: 3\n", __func__);
8899 	if (iwx_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t))) {
8900 		printf("%s: reading errlog failed\n", DEVNAME(sc));
8901 		return;
8902 	}
8903 
8904 	printf("%s: GOS-3758: 4\n", __func__);
8905 	if (!table.valid) {
8906 		printf("%s: errlog not found, skipping\n", DEVNAME(sc));
8907 		return;
8908 	}
8909 
8910 	printf("%s: GOS-3758: 5\n", __func__);
8911 	if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
8912 		printf("%s: Start Error Log Dump:\n", DEVNAME(sc));
8913 		printf("%s: Status: 0x%x, count: %d\n", DEVNAME(sc),
8914 		    sc->sc_flags, table.valid);
8915 	}
8916 
8917 	printf("%s: GOS-3758: 6\n", __func__);
8918 	printf("%s: 0x%08X | %-28s\n", DEVNAME(sc), table.error_id,
8919 	    iwx_desc_lookup(table.error_id));
8920 	printf("%s: %08X | trm_hw_status0\n", DEVNAME(sc),
8921 	    table.trm_hw_status0);
8922 	printf("%s: %08X | trm_hw_status1\n", DEVNAME(sc),
8923 	    table.trm_hw_status1);
8924 	printf("%s: %08X | branchlink2\n", DEVNAME(sc), table.blink2);
8925 	printf("%s: %08X | interruptlink1\n", DEVNAME(sc), table.ilink1);
8926 	printf("%s: %08X | interruptlink2\n", DEVNAME(sc), table.ilink2);
8927 	printf("%s: %08X | data1\n", DEVNAME(sc), table.data1);
8928 	printf("%s: %08X | data2\n", DEVNAME(sc), table.data2);
8929 	printf("%s: %08X | data3\n", DEVNAME(sc), table.data3);
8930 	printf("%s: %08X | beacon time\n", DEVNAME(sc), table.bcon_time);
8931 	printf("%s: %08X | tsf low\n", DEVNAME(sc), table.tsf_low);
8932 	printf("%s: %08X | tsf hi\n", DEVNAME(sc), table.tsf_hi);
8933 	printf("%s: %08X | time gp1\n", DEVNAME(sc), table.gp1);
8934 	printf("%s: %08X | time gp2\n", DEVNAME(sc), table.gp2);
8935 	printf("%s: %08X | uCode revision type\n", DEVNAME(sc),
8936 	    table.fw_rev_type);
8937 	printf("%s: %08X | uCode version major\n", DEVNAME(sc),
8938 	    table.major);
8939 	printf("%s: %08X | uCode version minor\n", DEVNAME(sc),
8940 	    table.minor);
8941 	printf("%s: %08X | hw version\n", DEVNAME(sc), table.hw_ver);
8942 	printf("%s: %08X | board version\n", DEVNAME(sc), table.brd_ver);
8943 	printf("%s: %08X | hcmd\n", DEVNAME(sc), table.hcmd);
8944 	printf("%s: %08X | isr0\n", DEVNAME(sc), table.isr0);
8945 	printf("%s: %08X | isr1\n", DEVNAME(sc), table.isr1);
8946 	printf("%s: %08X | isr2\n", DEVNAME(sc), table.isr2);
8947 	printf("%s: %08X | isr3\n", DEVNAME(sc), table.isr3);
8948 	printf("%s: %08X | isr4\n", DEVNAME(sc), table.isr4);
8949 	printf("%s: %08X | last cmd Id\n", DEVNAME(sc), table.last_cmd_id);
8950 	printf("%s: %08X | wait_event\n", DEVNAME(sc), table.wait_event);
8951 	printf("%s: %08X | l2p_control\n", DEVNAME(sc), table.l2p_control);
8952 	printf("%s: %08X | l2p_duration\n", DEVNAME(sc), table.l2p_duration);
8953 	printf("%s: %08X | l2p_mhvalid\n", DEVNAME(sc), table.l2p_mhvalid);
8954 	printf("%s: %08X | l2p_addr_match\n", DEVNAME(sc), table.l2p_addr_match);
8955 	printf("%s: %08X | lmpm_pmg_sel\n", DEVNAME(sc), table.lmpm_pmg_sel);
8956 	printf("%s: %08X | timestamp\n", DEVNAME(sc), table.u_timestamp);
8957 	printf("%s: %08X | flow_handler\n", DEVNAME(sc), table.flow_handler);
8958 
8959 	if (sc->sc_uc.uc_umac_error_event_table)
8960 		iwx_nic_umac_error(sc);
8961 }
8962 
8963 static void
8964 iwx_dump_driver_status(struct iwx_softc *sc)
8965 {
8966 	struct ieee80211com *ic = &sc->sc_ic;
8967 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8968 	enum ieee80211_state state = vap->iv_state;
8969 	int i;
8970 
8971 	printf("driver status:\n");
8972 	for (i = 0; i < nitems(sc->txq); i++) {
8973 		struct iwx_tx_ring *ring = &sc->txq[i];
8974 		printf("  tx ring %2d: qid=%-2d cur=%-3d "
8975 		    "cur_hw=%-3d queued=%-3d\n",
8976 		    i, ring->qid, ring->cur, ring->cur_hw,
8977 		    ring->queued);
8978 	}
8979 	printf("  rx ring: cur=%d\n", sc->rxq.cur);
8980 	printf("  802.11 state %s\n", ieee80211_state_name[state]);
8981 }
8982 
8983 #define SYNC_RESP_STRUCT(_var_, _pkt_)					\
8984 do {									\
8985 	bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); \
8986 	_var_ = (void *)((_pkt_)+1);					\
8987 } while (/*CONSTCOND*/0)
8988 
8989 static int
8990 iwx_rx_pkt_valid(struct iwx_rx_packet *pkt)
8991 {
8992 	int qid, idx, code;
8993 
8994 	qid = pkt->hdr.qid & ~0x80;
8995 	idx = pkt->hdr.idx;
8996 	code = IWX_WIDE_ID(pkt->hdr.flags, pkt->hdr.code);
8997 
8998 	return (!(qid == 0 && idx == 0 && code == 0) &&
8999 	    pkt->len_n_flags != htole32(IWX_FH_RSCSR_FRAME_INVALID));
9000 }
9001 
9002 static void
9003 iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *data, struct mbuf *ml)
9004 {
9005 	struct ieee80211com *ic = &sc->sc_ic;
9006 	struct iwx_rx_packet *pkt, *nextpkt;
9007 	uint32_t offset = 0, nextoff = 0, nmpdu = 0, len;
9008 	struct mbuf *m0, *m;
9009 	const size_t minsz = sizeof(pkt->len_n_flags) + sizeof(pkt->hdr);
9010 	int qid, idx, code, handled = 1;
9011 
9012 	m0 = data->m;
9013 	while (m0 && offset + minsz < IWX_RBUF_SIZE) {
9014 		pkt = (struct iwx_rx_packet *)(m0->m_data + offset);
9015 		qid = pkt->hdr.qid;
9016 		idx = pkt->hdr.idx;
9017 		code = IWX_WIDE_ID(pkt->hdr.flags, pkt->hdr.code);
9018 
9019 		if (!iwx_rx_pkt_valid(pkt))
9020 			break;
9021 
9022 		/*
9023 		 * XXX Intel inside (tm)
9024 		 * Any commands in the LONG_GROUP could actually be in the
9025 		 * LEGACY group. Firmware API versions >= 50 reject commands
9026 		 * in group 0, forcing us to use this hack.
9027 		 */
9028 		if (iwx_cmd_groupid(code) == IWX_LONG_GROUP) {
9029 			struct iwx_tx_ring *ring = &sc->txq[qid];
9030 			struct iwx_tx_data *txdata = &ring->data[idx];
9031 			if (txdata->flags & IWX_TXDATA_FLAG_CMD_IS_NARROW)
9032 				code = iwx_cmd_opcode(code);
9033 		}
9034 
9035 		len = sizeof(pkt->len_n_flags) + iwx_rx_packet_len(pkt);
9036 		if (len < minsz || len > (IWX_RBUF_SIZE - offset))
9037 			break;
9038 
9039 		// TODO ???
9040 		if (code == IWX_REPLY_RX_MPDU_CMD && ++nmpdu == 1) {
9041 			/* Take mbuf m0 off the RX ring. */
9042 			if (iwx_rx_addbuf(sc, IWX_RBUF_SIZE, sc->rxq.cur)) {
9043 				break;
9044 			}
9045 			KASSERT((data->m != m0), ("%s: data->m != m0", __func__));
9046 		}
9047 
9048 		switch (code) {
9049 		case IWX_REPLY_RX_PHY_CMD:
9050 			/* XXX-THJ: I've not managed to hit this path in testing */
9051 			iwx_rx_rx_phy_cmd(sc, pkt, data);
9052 			break;
9053 
9054 		case IWX_REPLY_RX_MPDU_CMD: {
9055 			size_t maxlen = IWX_RBUF_SIZE - offset - minsz;
9056 			nextoff = offset +
9057 			    roundup(len, IWX_FH_RSCSR_FRAME_ALIGN);
9058 			nextpkt = (struct iwx_rx_packet *)
9059 			    (m0->m_data + nextoff);
9060 			/* AX210 devices ship only one packet per Rx buffer. */
9061 			if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210 ||
9062 			    nextoff + minsz >= IWX_RBUF_SIZE ||
9063 			    !iwx_rx_pkt_valid(nextpkt)) {
9064 				/* No need to copy last frame in buffer. */
9065 				if (offset > 0)
9066 					m_adj(m0, offset);
9067 				iwx_rx_mpdu_mq(sc, m0, pkt->data, maxlen);
9068 				m0 = NULL; /* stack owns m0 now; abort loop */
9069 			} else {
9070 				/*
9071 				 * Create an mbuf which points to the current
9072 				 * packet. Always copy from offset zero to
9073 				 * preserve m_pkthdr.
9074 				 */
9075 				m = m_copym(m0, 0, M_COPYALL, M_NOWAIT);
9076 				if (m == NULL) {
9077 					m_freem(m0);
9078 					m0 = NULL;
9079 					break;
9080 				}
9081 				m_adj(m, offset);
9082 				iwx_rx_mpdu_mq(sc, m, pkt->data, maxlen);
9083 			}
9084 			break;
9085 		}
9086 
9087 //		case IWX_BAR_FRAME_RELEASE:
9088 //			iwx_rx_bar_frame_release(sc, pkt, ml);
9089 //			break;
9090 //
9091 		case IWX_TX_CMD:
9092 			iwx_rx_tx_cmd(sc, pkt, data);
9093 			break;
9094 
9095 		case IWX_BA_NOTIF:
9096 			iwx_rx_compressed_ba(sc, pkt);
9097 			break;
9098 
9099 		case IWX_MISSED_BEACONS_NOTIFICATION:
9100 			IWX_DPRINTF(sc, IWX_DEBUG_BEACON,
9101 			    "%s: IWX_MISSED_BEACONS_NOTIFICATION\n",
9102 			    __func__);
9103 			iwx_rx_bmiss(sc, pkt, data);
9104 			break;
9105 
9106 		case IWX_MFUART_LOAD_NOTIFICATION:
9107 			break;
9108 
9109 		case IWX_ALIVE: {
9110 			struct iwx_alive_resp_v4 *resp4;
9111 			struct iwx_alive_resp_v5 *resp5;
9112 			struct iwx_alive_resp_v6 *resp6;
9113 
9114 			DPRINTF(("%s: firmware alive\n", __func__));
9115 			sc->sc_uc.uc_ok = 0;
9116 
9117 			/*
9118 			 * For v5 and above, we can check the version, for older
9119 			 * versions we need to check the size.
9120 			 */
9121 			if (iwx_lookup_notif_ver(sc, IWX_LEGACY_GROUP,
9122 			    IWX_ALIVE) == 6) {
9123 				SYNC_RESP_STRUCT(resp6, pkt);
9124 				if (iwx_rx_packet_payload_len(pkt) !=
9125 				    sizeof(*resp6)) {
9126 					sc->sc_uc.uc_intr = 1;
9127 					wakeup(&sc->sc_uc);
9128 					break;
9129 				}
9130 				sc->sc_uc.uc_lmac_error_event_table[0] = le32toh(
9131 				    resp6->lmac_data[0].dbg_ptrs.error_event_table_ptr);
9132 				sc->sc_uc.uc_lmac_error_event_table[1] = le32toh(
9133 				    resp6->lmac_data[1].dbg_ptrs.error_event_table_ptr);
9134 				sc->sc_uc.uc_log_event_table = le32toh(
9135 				    resp6->lmac_data[0].dbg_ptrs.log_event_table_ptr);
9136 				sc->sc_uc.uc_umac_error_event_table = le32toh(
9137 				    resp6->umac_data.dbg_ptrs.error_info_addr);
9138 				sc->sc_sku_id[0] =
9139 				    le32toh(resp6->sku_id.data[0]);
9140 				sc->sc_sku_id[1] =
9141 				    le32toh(resp6->sku_id.data[1]);
9142 				sc->sc_sku_id[2] =
9143 				    le32toh(resp6->sku_id.data[2]);
9144 				if (resp6->status == IWX_ALIVE_STATUS_OK) {
9145 					sc->sc_uc.uc_ok = 1;
9146 				}
9147 			 } else if (iwx_lookup_notif_ver(sc, IWX_LEGACY_GROUP,
9148 			    IWX_ALIVE) == 5) {
9149 				SYNC_RESP_STRUCT(resp5, pkt);
9150 				if (iwx_rx_packet_payload_len(pkt) !=
9151 				    sizeof(*resp5)) {
9152 					sc->sc_uc.uc_intr = 1;
9153 					wakeup(&sc->sc_uc);
9154 					break;
9155 				}
9156 				sc->sc_uc.uc_lmac_error_event_table[0] = le32toh(
9157 				    resp5->lmac_data[0].dbg_ptrs.error_event_table_ptr);
9158 				sc->sc_uc.uc_lmac_error_event_table[1] = le32toh(
9159 				    resp5->lmac_data[1].dbg_ptrs.error_event_table_ptr);
9160 				sc->sc_uc.uc_log_event_table = le32toh(
9161 				    resp5->lmac_data[0].dbg_ptrs.log_event_table_ptr);
9162 				sc->sc_uc.uc_umac_error_event_table = le32toh(
9163 				    resp5->umac_data.dbg_ptrs.error_info_addr);
9164 				sc->sc_sku_id[0] =
9165 				    le32toh(resp5->sku_id.data[0]);
9166 				sc->sc_sku_id[1] =
9167 				    le32toh(resp5->sku_id.data[1]);
9168 				sc->sc_sku_id[2] =
9169 				    le32toh(resp5->sku_id.data[2]);
9170 				if (resp5->status == IWX_ALIVE_STATUS_OK)
9171 					sc->sc_uc.uc_ok = 1;
9172 			} else if (iwx_rx_packet_payload_len(pkt) == sizeof(*resp4)) {
9173 				SYNC_RESP_STRUCT(resp4, pkt);
9174 				sc->sc_uc.uc_lmac_error_event_table[0] = le32toh(
9175 				    resp4->lmac_data[0].dbg_ptrs.error_event_table_ptr);
9176 				sc->sc_uc.uc_lmac_error_event_table[1] = le32toh(
9177 				    resp4->lmac_data[1].dbg_ptrs.error_event_table_ptr);
9178 				sc->sc_uc.uc_log_event_table = le32toh(
9179 				    resp4->lmac_data[0].dbg_ptrs.log_event_table_ptr);
9180 				sc->sc_uc.uc_umac_error_event_table = le32toh(
9181 				    resp4->umac_data.dbg_ptrs.error_info_addr);
9182 				if (resp4->status == IWX_ALIVE_STATUS_OK)
9183 					sc->sc_uc.uc_ok = 1;
9184 			} else
9185 				printf("unknown payload version");
9186 
9187 			sc->sc_uc.uc_intr = 1;
9188 			wakeup(&sc->sc_uc);
9189 			break;
9190 		}
9191 
9192 		/*
9193 		 * TODO: is this the right struct to use? Look at what
9194 		 * mvm is doing for statistics notification (eg
9195 		 * iwl_mvm_handle_rx_statistics() .
9196 		 */
9197 		case IWX_STATISTICS_NOTIFICATION: {
9198 			struct iwx_notif_statistics *stats;
9199 			SYNC_RESP_STRUCT(stats, pkt);
9200 			memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats));
9201 			sc->sc_noise = iwx_get_noise(sc, &stats->rx.general);
9202 			break;
9203 		}
9204 
9205 		case IWX_DTS_MEASUREMENT_NOTIFICATION:
9206 		case IWX_WIDE_ID(IWX_PHY_OPS_GROUP,
9207 				 IWX_DTS_MEASUREMENT_NOTIF_WIDE):
9208 		case IWX_WIDE_ID(IWX_PHY_OPS_GROUP,
9209 				 IWX_TEMP_REPORTING_THRESHOLDS_CMD):
9210 			break;
9211 
9212 		case IWX_WIDE_ID(IWX_PHY_OPS_GROUP,
9213 		    IWX_CT_KILL_NOTIFICATION): {
9214 			struct iwx_ct_kill_notif *notif;
9215 			SYNC_RESP_STRUCT(notif, pkt);
9216 			printf("%s: device at critical temperature (%u degC), "
9217 			    "stopping device\n",
9218 			    DEVNAME(sc), le16toh(notif->temperature));
9219 			sc->sc_flags |= IWX_FLAG_HW_ERR;
9220 			ieee80211_restart_all(ic);
9221 			break;
9222 		}
9223 
9224 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
9225 		    IWX_SCD_QUEUE_CONFIG_CMD):
9226 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
9227 		    IWX_RX_BAID_ALLOCATION_CONFIG_CMD):
9228 		case IWX_WIDE_ID(IWX_MAC_CONF_GROUP,
9229 		    IWX_SESSION_PROTECTION_CMD):
9230 		case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
9231 		    IWX_NVM_GET_INFO):
9232 		case IWX_ADD_STA_KEY:
9233 		case IWX_PHY_CONFIGURATION_CMD:
9234 		case IWX_TX_ANT_CONFIGURATION_CMD:
9235 		case IWX_ADD_STA:
9236 		case IWX_MAC_CONTEXT_CMD:
9237 		case IWX_REPLY_SF_CFG_CMD:
9238 		case IWX_POWER_TABLE_CMD:
9239 		case IWX_LTR_CONFIG:
9240 		case IWX_PHY_CONTEXT_CMD:
9241 		case IWX_BINDING_CONTEXT_CMD:
9242 		case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_CFG_CMD):
9243 		case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_REQ_UMAC):
9244 		case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_ABORT_UMAC):
9245 		case IWX_REPLY_BEACON_FILTERING_CMD:
9246 		case IWX_MAC_PM_POWER_TABLE:
9247 		case IWX_TIME_QUOTA_CMD:
9248 		case IWX_REMOVE_STA:
9249 		case IWX_TXPATH_FLUSH:
9250 		case IWX_BT_CONFIG:
9251 		case IWX_MCC_UPDATE_CMD:
9252 		case IWX_TIME_EVENT_CMD:
9253 		case IWX_STATISTICS_CMD:
9254 		case IWX_SCD_QUEUE_CFG: {
9255 			size_t pkt_len;
9256 
9257 			if (sc->sc_cmd_resp_pkt[idx] == NULL)
9258 				break;
9259 
9260 			bus_dmamap_sync(sc->rxq.data_dmat, data->map,
9261 			    BUS_DMASYNC_POSTREAD);
9262 
9263 			pkt_len = sizeof(pkt->len_n_flags) +
9264 			    iwx_rx_packet_len(pkt);
9265 
9266 			if ((pkt->hdr.flags & IWX_CMD_FAILED_MSK) ||
9267 			    pkt_len < sizeof(*pkt) ||
9268 			    pkt_len > sc->sc_cmd_resp_len[idx]) {
9269 				free(sc->sc_cmd_resp_pkt[idx], M_DEVBUF);
9270 				sc->sc_cmd_resp_pkt[idx] = NULL;
9271 				break;
9272 			}
9273 
9274 			bus_dmamap_sync(sc->rxq.data_dmat, data->map,
9275 			    BUS_DMASYNC_POSTREAD);
9276 			memcpy(sc->sc_cmd_resp_pkt[idx], pkt, pkt_len);
9277 			break;
9278 		}
9279 
9280 		case IWX_INIT_COMPLETE_NOTIF:
9281 			sc->sc_init_complete |= IWX_INIT_COMPLETE;
9282 			wakeup(&sc->sc_init_complete);
9283 			break;
9284 
9285 		case IWX_SCAN_COMPLETE_UMAC: {
9286 			DPRINTF(("%s: >>> IWX_SCAN_COMPLETE_UMAC\n", __func__));
9287 			struct iwx_umac_scan_complete *notif __attribute__((unused));
9288 			SYNC_RESP_STRUCT(notif, pkt);
9289 			DPRINTF(("%s: scan complete notif->status=%d\n", __func__,
9290 			    notif->status));
9291 			ieee80211_runtask(&sc->sc_ic, &sc->sc_es_task);
9292 			iwx_endscan(sc);
9293 			break;
9294 		}
9295 
9296 		case IWX_SCAN_ITERATION_COMPLETE_UMAC: {
9297 			DPRINTF(("%s: >>> IWX_SCAN_ITERATION_COMPLETE_UMAC\n",
9298 			    __func__));
9299 			struct iwx_umac_scan_iter_complete_notif *notif __attribute__((unused));
9300 			SYNC_RESP_STRUCT(notif, pkt);
9301 			DPRINTF(("%s: iter scan complete notif->status=%d\n", __func__,
9302 			    notif->status));
9303 			iwx_endscan(sc);
9304 			break;
9305 		}
9306 
9307 		case IWX_MCC_CHUB_UPDATE_CMD: {
9308 			struct iwx_mcc_chub_notif *notif;
9309 			SYNC_RESP_STRUCT(notif, pkt);
9310 			iwx_mcc_update(sc, notif);
9311 			break;
9312 		}
9313 
9314 		case IWX_REPLY_ERROR: {
9315 			struct iwx_error_resp *resp;
9316 			SYNC_RESP_STRUCT(resp, pkt);
9317 			printf("%s: firmware error 0x%x, cmd 0x%x\n",
9318 				DEVNAME(sc), le32toh(resp->error_type),
9319 				resp->cmd_id);
9320 			break;
9321 		}
9322 
9323 		case IWX_TIME_EVENT_NOTIFICATION: {
9324 			struct iwx_time_event_notif *notif;
9325 			uint32_t action;
9326 			SYNC_RESP_STRUCT(notif, pkt);
9327 
9328 			if (sc->sc_time_event_uid != le32toh(notif->unique_id))
9329 				break;
9330 			action = le32toh(notif->action);
9331 			if (action & IWX_TE_V2_NOTIF_HOST_EVENT_END)
9332 				sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE;
9333 			break;
9334 		}
9335 
9336 		case IWX_WIDE_ID(IWX_MAC_CONF_GROUP,
9337 		    IWX_SESSION_PROTECTION_NOTIF): {
9338 			struct iwx_session_prot_notif *notif;
9339 			uint32_t status, start, conf_id;
9340 
9341 			SYNC_RESP_STRUCT(notif, pkt);
9342 
9343 			status = le32toh(notif->status);
9344 			start = le32toh(notif->start);
9345 			conf_id = le32toh(notif->conf_id);
9346 			/* Check for end of successful PROTECT_CONF_ASSOC. */
9347 			if (status == 1 && start == 0 &&
9348 			    conf_id == IWX_SESSION_PROTECT_CONF_ASSOC)
9349 				sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE;
9350 			break;
9351 		}
9352 
9353 		case IWX_WIDE_ID(IWX_SYSTEM_GROUP,
9354 		    IWX_FSEQ_VER_MISMATCH_NOTIFICATION):
9355 		    break;
9356 
9357 		/*
9358 		 * Firmware versions 21 and 22 generate some DEBUG_LOG_MSG
9359 		 * messages. Just ignore them for now.
9360 		 */
9361 		case IWX_DEBUG_LOG_MSG:
9362 			break;
9363 
9364 		case IWX_MCAST_FILTER_CMD:
9365 			break;
9366 
9367 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_DQA_ENABLE_CMD):
9368 			break;
9369 
9370 		case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_SOC_CONFIGURATION_CMD):
9371 			break;
9372 
9373 		case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_INIT_EXTENDED_CFG_CMD):
9374 			break;
9375 
9376 		case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
9377 		    IWX_NVM_ACCESS_COMPLETE):
9378 			break;
9379 
9380 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_RX_NO_DATA_NOTIF):
9381 			break; /* happens in monitor mode; ignore for now */
9382 
9383 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_TLC_MNG_CONFIG_CMD):
9384 			break;
9385 
9386 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
9387 		    IWX_TLC_MNG_UPDATE_NOTIF): {
9388 			struct iwx_tlc_update_notif *notif;
9389 			SYNC_RESP_STRUCT(notif, pkt);
9390 			(void)notif;
9391 			if (iwx_rx_packet_payload_len(pkt) == sizeof(*notif))
9392 				iwx_rs_update(sc, notif);
9393 			break;
9394 		}
9395 
9396 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_RLC_CONFIG_CMD):
9397 			break;
9398 
9399 		/*
9400 		 * Ignore for now. The Linux driver only acts on this request
9401 		 * with 160Mhz channels in 11ax mode.
9402 		 */
9403 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
9404 		    IWX_THERMAL_DUAL_CHAIN_REQUEST):
9405 			DPRINTF(("%s: thermal dual-chain request received\n",
9406 			    DEVNAME(sc)));
9407 			break;
9408 
9409 		/* undocumented notification from iwx-ty-a0-gf-a0-77 image */
9410 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 0xf8):
9411 			break;
9412 
9413 		case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
9414 		    IWX_PNVM_INIT_COMPLETE):
9415 			DPRINTF(("%s: IWX_PNVM_INIT_COMPLETE\n", __func__));
9416 			sc->sc_init_complete |= IWX_PNVM_COMPLETE;
9417 			wakeup(&sc->sc_init_complete);
9418 			break;
9419 
9420 		default:
9421 			handled = 0;
9422 			/* XXX wulf: Get rid of bluetooth-related spam */
9423 			if ((code == 0xc2 && pkt->len_n_flags == 0x0000000c) ||
9424 			    (code == 0xce && pkt->len_n_flags == 0x2000002c))
9425 				break;
9426 			printf("%s: unhandled firmware response 0x%x/0x%x "
9427 			    "rx ring %d[%d]\n",
9428 			    DEVNAME(sc), code, pkt->len_n_flags,
9429 			    (qid & ~0x80), idx);
9430 			break;
9431 		}
9432 
9433 		/*
9434 		 * uCode sets bit 0x80 when it originates the notification,
9435 		 * i.e. when the notification is not a direct response to a
9436 		 * command sent by the driver.
9437 		 * For example, uCode issues IWX_REPLY_RX when it sends a
9438 		 * received frame to the driver.
9439 		 */
9440 		if (handled && !(qid & (1 << 7))) {
9441 			iwx_cmd_done(sc, qid, idx, code);
9442 		}
9443 
9444 		offset += roundup(len, IWX_FH_RSCSR_FRAME_ALIGN);
9445 
9446 		/* AX210 devices ship only one packet per Rx buffer. */
9447 		if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
9448 			break;
9449 	}
9450 
9451 	if (m0 && m0 != data->m)
9452 		m_freem(m0);
9453 }
9454 
9455 static void
9456 iwx_notif_intr(struct iwx_softc *sc)
9457 {
9458 	struct mbuf m;
9459 	uint16_t hw;
9460 
9461 	bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map,
9462 	    BUS_DMASYNC_POSTREAD);
9463 
9464 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
9465 		uint16_t *status = sc->rxq.stat_dma.vaddr;
9466 		hw = le16toh(*status) & 0xfff;
9467 	} else
9468 		hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff;
9469 	hw &= (IWX_RX_MQ_RING_COUNT - 1);
9470 	while (sc->rxq.cur != hw) {
9471 		struct iwx_rx_data *data = &sc->rxq.data[sc->rxq.cur];
9472 
9473 		bus_dmamap_sync(sc->rxq.data_dmat, data->map,
9474 		BUS_DMASYNC_POSTREAD);
9475 
9476 		iwx_rx_pkt(sc, data, &m);
9477 		sc->rxq.cur = (sc->rxq.cur + 1) % IWX_RX_MQ_RING_COUNT;
9478 	}
9479 
9480 	/*
9481 	 * Tell the firmware what we have processed.
9482 	 * Seems like the hardware gets upset unless we align the write by 8??
9483 	 */
9484 	hw = (hw == 0) ? IWX_RX_MQ_RING_COUNT - 1 : hw - 1;
9485 	IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, hw & ~7);
9486 }
9487 
9488 #if 0
9489 int
9490 iwx_intr(void *arg)
9491 {
9492 	struct iwx_softc *sc = arg;
9493 	struct ieee80211com *ic = &sc->sc_ic;
9494 	struct ifnet *ifp = IC2IFP(ic);
9495 	int r1, r2, rv = 0;
9496 
9497 	IWX_WRITE(sc, IWX_CSR_INT_MASK, 0);
9498 
9499 	if (sc->sc_flags & IWX_FLAG_USE_ICT) {
9500 		uint32_t *ict = sc->ict_dma.vaddr;
9501 		int tmp;
9502 
9503 		tmp = htole32(ict[sc->ict_cur]);
9504 		if (!tmp)
9505 			goto out_ena;
9506 
9507 		/*
9508 		 * ok, there was something.  keep plowing until we have all.
9509 		 */
9510 		r1 = r2 = 0;
9511 		while (tmp) {
9512 			r1 |= tmp;
9513 			ict[sc->ict_cur] = 0;
9514 			sc->ict_cur = (sc->ict_cur+1) % IWX_ICT_COUNT;
9515 			tmp = htole32(ict[sc->ict_cur]);
9516 		}
9517 
9518 		/* this is where the fun begins.  don't ask */
9519 		if (r1 == 0xffffffff)
9520 			r1 = 0;
9521 
9522 		/* i am not expected to understand this */
9523 		if (r1 & 0xc0000)
9524 			r1 |= 0x8000;
9525 		r1 = (0xff & r1) | ((0xff00 & r1) << 16);
9526 	} else {
9527 		r1 = IWX_READ(sc, IWX_CSR_INT);
9528 		if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
9529 			goto out;
9530 		r2 = IWX_READ(sc, IWX_CSR_FH_INT_STATUS);
9531 	}
9532 	if (r1 == 0 && r2 == 0) {
9533 		goto out_ena;
9534 	}
9535 
9536 	IWX_WRITE(sc, IWX_CSR_INT, r1 | ~sc->sc_intmask);
9537 
9538 	if (r1 & IWX_CSR_INT_BIT_ALIVE) {
9539 #if 0
9540 		int i;
9541 		/* Firmware has now configured the RFH. */
9542 		for (i = 0; i < IWX_RX_MQ_RING_COUNT; i++)
9543 			iwx_update_rx_desc(sc, &sc->rxq, i);
9544 #endif
9545 		IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, 8);
9546 	}
9547 
9548 
9549 	if (r1 & IWX_CSR_INT_BIT_RF_KILL) {
9550 		iwx_check_rfkill(sc);
9551 		rv = 1;
9552 		goto out_ena;
9553 	}
9554 
9555 	if (r1 & IWX_CSR_INT_BIT_SW_ERR) {
9556 		if (ifp->if_flags & IFF_DEBUG) {
9557 			iwx_nic_error(sc);
9558 			iwx_dump_driver_status(sc);
9559 		}
9560 		printf("%s: fatal firmware error\n", DEVNAME(sc));
9561 		ieee80211_restart_all(ic);
9562 		rv = 1;
9563 		goto out;
9564 
9565 	}
9566 
9567 	if (r1 & IWX_CSR_INT_BIT_HW_ERR) {
9568 		printf("%s: hardware error, stopping device \n", DEVNAME(sc));
9569 		iwx_stop(sc);
9570 		rv = 1;
9571 		goto out;
9572 	}
9573 
9574 	/* firmware chunk loaded */
9575 	if (r1 & IWX_CSR_INT_BIT_FH_TX) {
9576 		IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, IWX_CSR_FH_INT_TX_MASK);
9577 
9578 		sc->sc_fw_chunk_done = 1;
9579 		wakeup(&sc->sc_fw);
9580 	}
9581 
9582 	if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX |
9583 	    IWX_CSR_INT_BIT_RX_PERIODIC)) {
9584 		if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX)) {
9585 			IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, IWX_CSR_FH_INT_RX_MASK);
9586 		}
9587 		if (r1 & IWX_CSR_INT_BIT_RX_PERIODIC) {
9588 			IWX_WRITE(sc, IWX_CSR_INT, IWX_CSR_INT_BIT_RX_PERIODIC);
9589 		}
9590 
9591 		/* Disable periodic interrupt; we use it as just a one-shot. */
9592 		IWX_WRITE_1(sc, IWX_CSR_INT_PERIODIC_REG, IWX_CSR_INT_PERIODIC_DIS);
9593 
9594 		/*
9595 		 * Enable periodic interrupt in 8 msec only if we received
9596 		 * real RX interrupt (instead of just periodic int), to catch
9597 		 * any dangling Rx interrupt.  If it was just the periodic
9598 		 * interrupt, there was no dangling Rx activity, and no need
9599 		 * to extend the periodic interrupt; one-shot is enough.
9600 		 */
9601 		if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX))
9602 			IWX_WRITE_1(sc, IWX_CSR_INT_PERIODIC_REG,
9603 			    IWX_CSR_INT_PERIODIC_ENA);
9604 
9605 		iwx_notif_intr(sc);
9606 	}
9607 
9608 	rv = 1;
9609 
9610  out_ena:
9611 	iwx_restore_interrupts(sc);
9612  out:
9613 	return rv;
9614 }
9615 #endif
9616 
9617 static void
9618 iwx_intr_msix(void *arg)
9619 {
9620 	struct iwx_softc *sc = arg;
9621 	struct ieee80211com *ic = &sc->sc_ic;
9622 	uint32_t inta_fh, inta_hw;
9623 	int vector = 0;
9624 
9625 	IWX_LOCK(sc);
9626 
9627 	inta_fh = IWX_READ(sc, IWX_CSR_MSIX_FH_INT_CAUSES_AD);
9628 	inta_hw = IWX_READ(sc, IWX_CSR_MSIX_HW_INT_CAUSES_AD);
9629 	IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_CAUSES_AD, inta_fh);
9630 	IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_CAUSES_AD, inta_hw);
9631 	inta_fh &= sc->sc_fh_mask;
9632 	inta_hw &= sc->sc_hw_mask;
9633 
9634 	if (inta_fh & IWX_MSIX_FH_INT_CAUSES_Q0 ||
9635 	    inta_fh & IWX_MSIX_FH_INT_CAUSES_Q1) {
9636 		iwx_notif_intr(sc);
9637 	}
9638 
9639 	/* firmware chunk loaded */
9640 	if (inta_fh & IWX_MSIX_FH_INT_CAUSES_D2S_CH0_NUM) {
9641 		sc->sc_fw_chunk_done = 1;
9642 		wakeup(&sc->sc_fw);
9643 	}
9644 
9645 	if ((inta_fh & IWX_MSIX_FH_INT_CAUSES_FH_ERR) ||
9646 	    (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_SW_ERR) ||
9647 	    (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_SW_ERR_V2)) {
9648 		if (sc->sc_debug) {
9649 			iwx_nic_error(sc);
9650 			iwx_dump_driver_status(sc);
9651 		}
9652 		printf("%s: fatal firmware error\n", DEVNAME(sc));
9653 		ieee80211_restart_all(ic);
9654 		goto out;
9655 	}
9656 
9657 	if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_RF_KILL) {
9658 		iwx_check_rfkill(sc);
9659 	}
9660 
9661 	if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_HW_ERR) {
9662 		printf("%s: hardware error, stopping device \n", DEVNAME(sc));
9663 		sc->sc_flags |= IWX_FLAG_HW_ERR;
9664 		iwx_stop(sc);
9665 		goto out;
9666 	}
9667 
9668 	if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_ALIVE) {
9669 		IWX_DPRINTF(sc, IWX_DEBUG_TRACE,
9670 		    "%s:%d WARNING: Skipping rx desc update\n",
9671 		    __func__, __LINE__);
9672 #if 0
9673 		/*
9674 		 * XXX-THJ: we don't have the dma segment handy. This is hacked
9675 		 * out in the fc release, return to it if we ever get this
9676 		 * warning.
9677 		 */
9678 		/* Firmware has now configured the RFH. */
9679 		for (int i = 0; i < IWX_RX_MQ_RING_COUNT; i++)
9680 			iwx_update_rx_desc(sc, &sc->rxq, i);
9681 #endif
9682 		IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, 8);
9683 	}
9684 
9685 	/*
9686 	 * Before sending the interrupt the HW disables it to prevent
9687 	 * a nested interrupt. This is done by writing 1 to the corresponding
9688 	 * bit in the mask register. After handling the interrupt, it should be
9689 	 * re-enabled by clearing this bit. This register is defined as
9690 	 * write 1 clear (W1C) register, meaning that it's being clear
9691 	 * by writing 1 to the bit.
9692 	 */
9693 	IWX_WRITE(sc, IWX_CSR_MSIX_AUTOMASK_ST_AD, 1 << vector);
9694 out:
9695 	IWX_UNLOCK(sc);
9696 	return;
9697 }
9698 
9699 /*
9700  * The device info table below contains device-specific config overrides.
9701  * The most important parameter derived from this table is the name of the
9702  * firmware image to load.
9703  *
9704  * The Linux iwlwifi driver uses an "old" and a "new" device info table.
9705  * The "old" table matches devices based on PCI vendor/product IDs only.
9706  * The "new" table extends this with various device parameters derived
9707  * from MAC type, and RF type.
9708  *
9709  * In iwlwifi "old" and "new" tables share the same array, where "old"
9710  * entries contain dummy values for data defined only for "new" entries.
9711  * As of 2022, Linux developers are still in the process of moving entries
9712  * from "old" to "new" style and it looks like this effort has stalled in
9713  * in some work-in-progress state for quite a while. Linux commits moving
9714  * entries from "old" to "new" have at times been reverted due to regressions.
9715  * Part of this complexity comes from iwlwifi supporting both iwm(4) and iwx(4)
9716  * devices in the same driver.
9717  *
9718  * Our table below contains mostly "new" entries declared in iwlwifi
9719  * with the _IWL_DEV_INFO() macro (with a leading underscore).
9720  * Other devices are matched based on PCI vendor/product ID as usual,
9721  * unless matching specific PCI subsystem vendor/product IDs is required.
9722  *
9723  * Some "old"-style entries are required to identify the firmware image to use.
9724  * Others might be used to print a specific marketing name into Linux dmesg,
9725  * but we can't be sure whether the corresponding devices would be matched
9726  * correctly in the absence of their entries. So we include them just in case.
9727  */
9728 
9729 struct iwx_dev_info {
9730 	uint16_t device;
9731 	uint16_t subdevice;
9732 	uint16_t mac_type;
9733 	uint16_t rf_type;
9734 	uint8_t mac_step;
9735 	uint8_t rf_id;
9736 	uint8_t no_160;
9737 	uint8_t cores;
9738 	uint8_t cdb;
9739 	uint8_t jacket;
9740 	const struct iwx_device_cfg *cfg;
9741 };
9742 
9743 #define _IWX_DEV_INFO(_device, _subdevice, _mac_type, _mac_step, _rf_type, \
9744 		      _rf_id, _no_160, _cores, _cdb, _jacket, _cfg) \
9745 	{ .device = (_device), .subdevice = (_subdevice), .cfg = &(_cfg),  \
9746 	  .mac_type = _mac_type, .rf_type = _rf_type,	   \
9747 	  .no_160 = _no_160, .cores = _cores, .rf_id = _rf_id,		   \
9748 	  .mac_step = _mac_step, .cdb = _cdb, .jacket = _jacket }
9749 
9750 #define IWX_DEV_INFO(_device, _subdevice, _cfg) \
9751 	_IWX_DEV_INFO(_device, _subdevice, IWX_CFG_ANY, IWX_CFG_ANY,	   \
9752 		      IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_ANY,  \
9753 		      IWX_CFG_ANY, IWX_CFG_ANY, _cfg)
9754 
9755 /*
9756  * When adding entries to this table keep in mind that entries must
9757  * be listed in the same order as in the Linux driver. Code walks this
9758  * table backwards and uses the first matching entry it finds.
9759  * Device firmware must be available in fw_update(8).
9760  */
9761 static const struct iwx_dev_info iwx_dev_info_table[] = {
9762 	/* So with HR */
9763 	IWX_DEV_INFO(0x2725, 0x0090, iwx_2ax_cfg_so_gf_a0),
9764 	IWX_DEV_INFO(0x2725, 0x0020, iwx_2ax_cfg_ty_gf_a0),
9765 	IWX_DEV_INFO(0x2725, 0x2020, iwx_2ax_cfg_ty_gf_a0),
9766 	IWX_DEV_INFO(0x2725, 0x0024, iwx_2ax_cfg_ty_gf_a0),
9767 	IWX_DEV_INFO(0x2725, 0x0310, iwx_2ax_cfg_ty_gf_a0),
9768 	IWX_DEV_INFO(0x2725, 0x0510, iwx_2ax_cfg_ty_gf_a0),
9769 	IWX_DEV_INFO(0x2725, 0x0A10, iwx_2ax_cfg_ty_gf_a0),
9770 	IWX_DEV_INFO(0x2725, 0xE020, iwx_2ax_cfg_ty_gf_a0),
9771 	IWX_DEV_INFO(0x2725, 0xE024, iwx_2ax_cfg_ty_gf_a0),
9772 	IWX_DEV_INFO(0x2725, 0x4020, iwx_2ax_cfg_ty_gf_a0),
9773 	IWX_DEV_INFO(0x2725, 0x6020, iwx_2ax_cfg_ty_gf_a0),
9774 	IWX_DEV_INFO(0x2725, 0x6024, iwx_2ax_cfg_ty_gf_a0),
9775 	IWX_DEV_INFO(0x2725, 0x1673, iwx_2ax_cfg_ty_gf_a0), /* killer_1675w */
9776 	IWX_DEV_INFO(0x2725, 0x1674, iwx_2ax_cfg_ty_gf_a0), /* killer_1675x */
9777 	IWX_DEV_INFO(0x51f0, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */
9778 	IWX_DEV_INFO(0x51f0, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */
9779 	IWX_DEV_INFO(0x51f1, 0x1691, iwx_2ax_cfg_so_gf4_a0),
9780 	IWX_DEV_INFO(0x51f1, 0x1692, iwx_2ax_cfg_so_gf4_a0),
9781 	IWX_DEV_INFO(0x54f0, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */
9782 	IWX_DEV_INFO(0x54f0, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */
9783 	IWX_DEV_INFO(0x7a70, 0x0090, iwx_2ax_cfg_so_gf_a0_long),
9784 	IWX_DEV_INFO(0x7a70, 0x0098, iwx_2ax_cfg_so_gf_a0_long),
9785 	IWX_DEV_INFO(0x7a70, 0x00b0, iwx_2ax_cfg_so_gf4_a0_long),
9786 	IWX_DEV_INFO(0x7a70, 0x0310, iwx_2ax_cfg_so_gf_a0_long),
9787 	IWX_DEV_INFO(0x7a70, 0x0510, iwx_2ax_cfg_so_gf_a0_long),
9788 	IWX_DEV_INFO(0x7a70, 0x0a10, iwx_2ax_cfg_so_gf_a0_long),
9789 	IWX_DEV_INFO(0x7af0, 0x0090, iwx_2ax_cfg_so_gf_a0),
9790 	IWX_DEV_INFO(0x7af0, 0x0098, iwx_2ax_cfg_so_gf_a0),
9791 	IWX_DEV_INFO(0x7af0, 0x00b0, iwx_2ax_cfg_so_gf4_a0),
9792 	IWX_DEV_INFO(0x7a70, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */
9793 	IWX_DEV_INFO(0x7a70, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */
9794 	IWX_DEV_INFO(0x7af0, 0x0310, iwx_2ax_cfg_so_gf_a0),
9795 	IWX_DEV_INFO(0x7af0, 0x0510, iwx_2ax_cfg_so_gf_a0),
9796 	IWX_DEV_INFO(0x7af0, 0x0a10, iwx_2ax_cfg_so_gf_a0),
9797 	IWX_DEV_INFO(0x7f70, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */
9798 	IWX_DEV_INFO(0x7f70, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */
9799 
9800 	/* So with GF2 */
9801 	IWX_DEV_INFO(0x2726, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9802 	IWX_DEV_INFO(0x2726, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9803 	IWX_DEV_INFO(0x51f0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9804 	IWX_DEV_INFO(0x51f0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9805 	IWX_DEV_INFO(0x54f0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9806 	IWX_DEV_INFO(0x54f0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9807 	IWX_DEV_INFO(0x7a70, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9808 	IWX_DEV_INFO(0x7a70, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9809 	IWX_DEV_INFO(0x7af0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9810 	IWX_DEV_INFO(0x7af0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9811 	IWX_DEV_INFO(0x7f70, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9812 	IWX_DEV_INFO(0x7f70, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9813 
9814 	/* Qu with Jf, C step */
9815 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9816 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9817 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
9818 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9819 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9461_160 */
9820 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9821 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9822 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
9823 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9824 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* iwl9461 */
9825 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9826 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9827 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9828 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9829 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9462_160 */
9830 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9831 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9832 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9833 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9834 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9462 */
9835 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9836 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9837 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9838 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9839 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9560_160 */
9840 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9841 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9842 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9843 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9844 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9560 */
9845 	_IWX_DEV_INFO(IWX_CFG_ANY, 0x1551,
9846 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9847 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9848 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9849 		      IWX_CFG_ANY,
9850 		      iwx_9560_qu_c0_jf_b0_cfg), /* 9560_killer_1550s */
9851 	_IWX_DEV_INFO(IWX_CFG_ANY, 0x1552,
9852 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9853 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9854 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9855 		      IWX_CFG_ANY,
9856 		      iwx_9560_qu_c0_jf_b0_cfg), /* 9560_killer_1550i */
9857 
9858 	/* QuZ with Jf */
9859 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9860 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9861 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9862 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9863 		      IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9461_160 */
9864 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9865 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9866 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9867 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9868 		      IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9461 */
9869 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9870 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9871 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9872 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9873 		      IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9462_160 */
9874 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9875 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9876 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9877 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9878 		      IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9462 */
9879 	_IWX_DEV_INFO(IWX_CFG_ANY, 0x1551,
9880 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9881 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9882 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9883 		      IWX_CFG_ANY,
9884 		      iwx_9560_quz_a0_jf_b0_cfg), /* killer_1550s */
9885 	_IWX_DEV_INFO(IWX_CFG_ANY, 0x1552,
9886 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9887 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9888 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9889 		      IWX_CFG_ANY,
9890 		      iwx_9560_quz_a0_jf_b0_cfg), /* 9560_killer_1550i */
9891 
9892 	/* Qu with Hr, B step */
9893 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9894 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_B_STEP,
9895 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9896 		      IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9897 		      iwx_qu_b0_hr1_b0), /* AX101 */
9898 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9899 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_B_STEP,
9900 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9901 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9902 		      iwx_qu_b0_hr_b0), /* AX203 */
9903 
9904 	/* Qu with Hr, C step */
9905 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9906 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9907 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9908 		      IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9909 		      iwx_qu_c0_hr1_b0), /* AX101 */
9910 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9911 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9912 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9913 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9914 		      iwx_qu_c0_hr_b0), /* AX203 */
9915 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9916 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9917 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9918 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9919 		      iwx_qu_c0_hr_b0), /* AX201 */
9920 
9921 	/* QuZ with Hr */
9922 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9923 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9924 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9925 		      IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9926 		      iwx_quz_a0_hr1_b0), /* AX101 */
9927 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9928 		      IWX_CFG_MAC_TYPE_QUZ, IWX_SILICON_B_STEP,
9929 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9930 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9931 		      iwx_cfg_quz_a0_hr_b0), /* AX203 */
9932 
9933 	/* SoF with JF2 */
9934 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9935 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9936 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9937 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9938 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560_160 */
9939 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9940 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9941 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9942 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9943 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560 */
9944 
9945 	/* SoF with JF */
9946 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9947 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9948 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
9949 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9950 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_160 */
9951 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9952 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9953 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9954 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9955 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462_160 */
9956 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9957 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9958 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
9959 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9960 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_name */
9961 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9962 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9963 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9964 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9965 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462 */
9966 
9967 	/* So with Hr */
9968 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9969 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
9970 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9971 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9972 		      iwx_cfg_so_a0_hr_b0), /* AX203 */
9973 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9974 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
9975 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9976 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9977 		      iwx_cfg_so_a0_hr_b0), /* ax101 */
9978 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9979 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
9980 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9981 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9982 		      iwx_cfg_so_a0_hr_b0), /* ax201 */
9983 
9984 	/* So-F with Hr */
9985 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9986 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9987 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9988 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9989 		      iwx_cfg_so_a0_hr_b0), /* AX203 */
9990 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9991 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9992 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9993 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9994 		      iwx_cfg_so_a0_hr_b0), /* AX101 */
9995 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9996 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9997 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9998 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9999 		      iwx_cfg_so_a0_hr_b0), /* AX201 */
10000 
10001 	/* So-F with GF */
10002 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10003 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
10004 		      IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY,
10005 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
10006 		      iwx_2ax_cfg_so_gf_a0), /* AX211 */
10007 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10008 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
10009 		      IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY,
10010 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_CDB, IWX_CFG_ANY,
10011 		      iwx_2ax_cfg_so_gf4_a0), /* AX411 */
10012 
10013 	/* So with GF */
10014 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10015 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10016 		      IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY,
10017 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
10018 		      iwx_2ax_cfg_so_gf_a0), /* AX211 */
10019 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10020 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10021 		      IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY,
10022 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_CDB, IWX_CFG_ANY,
10023 		      iwx_2ax_cfg_so_gf4_a0), /* AX411 */
10024 
10025 	/* So with JF2 */
10026 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10027 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10028 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
10029 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10030 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560_160 */
10031 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10032 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10033 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
10034 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10035 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560 */
10036 
10037 	/* So with JF */
10038 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10039 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10040 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
10041 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10042 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_160 */
10043 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10044 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10045 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
10046 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10047 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462_160 */
10048 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10049 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10050 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
10051 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10052 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* iwl9461 */
10053 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10054 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10055 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
10056 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10057 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462 */
10058 };
10059 
10060 static int
10061 iwx_preinit(struct iwx_softc *sc)
10062 {
10063 	struct ieee80211com *ic = &sc->sc_ic;
10064 	int err;
10065 
10066 	err = iwx_prepare_card_hw(sc);
10067 	if (err) {
10068 		printf("%s: could not initialize hardware\n", DEVNAME(sc));
10069 		return err;
10070 	}
10071 
10072 	if (sc->attached) {
10073 		return 0;
10074 	}
10075 
10076 	err = iwx_start_hw(sc);
10077 	if (err) {
10078 		printf("%s: could not initialize hardware\n", DEVNAME(sc));
10079 		return err;
10080 	}
10081 
10082 	err = iwx_run_init_mvm_ucode(sc, 1);
10083 	iwx_stop_device(sc);
10084 	if (err) {
10085 		printf("%s: failed to stop device\n", DEVNAME(sc));
10086 		return err;
10087 	}
10088 
10089 	/* Print version info and MAC address on first successful fw load. */
10090 	sc->attached = 1;
10091 	if (sc->sc_pnvm_ver) {
10092 		printf("%s: hw rev 0x%x, fw %s, pnvm %08x, "
10093 		    "address %s\n",
10094 		    DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK,
10095 		    sc->sc_fwver, sc->sc_pnvm_ver,
10096 		    ether_sprintf(sc->sc_nvm.hw_addr));
10097 	} else {
10098 		printf("%s: hw rev 0x%x, fw %s, address %s\n",
10099 		    DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK,
10100 		    sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr));
10101 	}
10102 
10103 	/* not all hardware can do 5GHz band */
10104 	if (!sc->sc_nvm.sku_cap_band_52GHz_enable)
10105 		memset(&ic->ic_sup_rates[IEEE80211_MODE_11A], 0,
10106 		    sizeof(ic->ic_sup_rates[IEEE80211_MODE_11A]));
10107 
10108 	return 0;
10109 }
10110 
10111 static void
10112 iwx_attach_hook(void *self)
10113 {
10114 	struct iwx_softc *sc = (void *)self;
10115 	struct ieee80211com *ic = &sc->sc_ic;
10116 	int err;
10117 
10118 	IWX_LOCK(sc);
10119 	err = iwx_preinit(sc);
10120 	IWX_UNLOCK(sc);
10121 	if (err != 0)
10122 		goto out;
10123 
10124 	iwx_init_channel_map(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
10125 	    ic->ic_channels);
10126 
10127 	ieee80211_ifattach(ic);
10128 	ic->ic_vap_create = iwx_vap_create;
10129 	ic->ic_vap_delete = iwx_vap_delete;
10130 	ic->ic_raw_xmit = iwx_raw_xmit;
10131 	ic->ic_node_alloc = iwx_node_alloc;
10132 	ic->ic_scan_start = iwx_scan_start;
10133 	ic->ic_scan_end = iwx_scan_end;
10134 	ic->ic_update_mcast = iwx_update_mcast;
10135 	ic->ic_getradiocaps = iwx_init_channel_map;
10136 
10137 	ic->ic_set_channel = iwx_set_channel;
10138 	ic->ic_scan_curchan = iwx_scan_curchan;
10139 	ic->ic_scan_mindwell = iwx_scan_mindwell;
10140 	ic->ic_wme.wme_update = iwx_wme_update;
10141 	ic->ic_parent = iwx_parent;
10142 	ic->ic_transmit = iwx_transmit;
10143 
10144 	sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start;
10145 	ic->ic_ampdu_rx_start = iwx_ampdu_rx_start;
10146 	sc->sc_ampdu_rx_stop = ic->ic_ampdu_rx_stop;
10147 	ic->ic_ampdu_rx_stop = iwx_ampdu_rx_stop;
10148 
10149 	sc->sc_addba_request = ic->ic_addba_request;
10150 	ic->ic_addba_request = iwx_addba_request;
10151 	sc->sc_addba_response = ic->ic_addba_response;
10152 	ic->ic_addba_response = iwx_addba_response;
10153 
10154 	iwx_radiotap_attach(sc);
10155 	ieee80211_announce(ic);
10156 out:
10157 	config_intrhook_disestablish(&sc->sc_preinit_hook);
10158 }
10159 
10160 const struct iwx_device_cfg *
10161 iwx_find_device_cfg(struct iwx_softc *sc)
10162 {
10163 	uint16_t sdev_id, mac_type, rf_type;
10164 	uint8_t mac_step, cdb, jacket, rf_id, no_160, cores;
10165 	int i;
10166 
10167 	sdev_id = pci_get_subdevice(sc->sc_dev);
10168 	mac_type = IWX_CSR_HW_REV_TYPE(sc->sc_hw_rev);
10169 	mac_step = IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2);
10170 	rf_type = IWX_CSR_HW_RFID_TYPE(sc->sc_hw_rf_id);
10171 	cdb = IWX_CSR_HW_RFID_IS_CDB(sc->sc_hw_rf_id);
10172 	jacket = IWX_CSR_HW_RFID_IS_JACKET(sc->sc_hw_rf_id);
10173 
10174 	rf_id = IWX_SUBDEVICE_RF_ID(sdev_id);
10175 	no_160 = IWX_SUBDEVICE_NO_160(sdev_id);
10176 	cores = IWX_SUBDEVICE_CORES(sdev_id);
10177 
10178 	for (i = nitems(iwx_dev_info_table) - 1; i >= 0; i--) {
10179 		const struct iwx_dev_info *dev_info = &iwx_dev_info_table[i];
10180 
10181 		if (dev_info->device != (uint16_t)IWX_CFG_ANY &&
10182 		    dev_info->device != sc->sc_pid)
10183 			continue;
10184 
10185 		if (dev_info->subdevice != (uint16_t)IWX_CFG_ANY &&
10186 		    dev_info->subdevice != sdev_id)
10187 			continue;
10188 
10189 		if (dev_info->mac_type != (uint16_t)IWX_CFG_ANY &&
10190 		    dev_info->mac_type != mac_type)
10191 			continue;
10192 
10193 		if (dev_info->mac_step != (uint8_t)IWX_CFG_ANY &&
10194 		    dev_info->mac_step != mac_step)
10195 			continue;
10196 
10197 		if (dev_info->rf_type != (uint16_t)IWX_CFG_ANY &&
10198 		    dev_info->rf_type != rf_type)
10199 			continue;
10200 
10201 		if (dev_info->cdb != (uint8_t)IWX_CFG_ANY &&
10202 		    dev_info->cdb != cdb)
10203 			continue;
10204 
10205 		if (dev_info->jacket != (uint8_t)IWX_CFG_ANY &&
10206 		    dev_info->jacket != jacket)
10207 			continue;
10208 
10209 		if (dev_info->rf_id != (uint8_t)IWX_CFG_ANY &&
10210 		    dev_info->rf_id != rf_id)
10211 			continue;
10212 
10213 		if (dev_info->no_160 != (uint8_t)IWX_CFG_ANY &&
10214 		    dev_info->no_160 != no_160)
10215 			continue;
10216 
10217 		if (dev_info->cores != (uint8_t)IWX_CFG_ANY &&
10218 		    dev_info->cores != cores)
10219 			continue;
10220 
10221 		return dev_info->cfg;
10222 	}
10223 
10224 	return NULL;
10225 }
10226 
10227 static int
10228 iwx_probe(device_t dev)
10229 {
10230 	int i;
10231 
10232 	for (i = 0; i < nitems(iwx_devices); i++) {
10233 		if (pci_get_vendor(dev) == PCI_VENDOR_INTEL &&
10234 		    pci_get_device(dev) == iwx_devices[i].device) {
10235 			device_set_desc(dev, iwx_devices[i].name);
10236 
10237 			/*
10238 			 * Due to significant existing deployments using
10239 			 * iwlwifi lower the priority of iwx.
10240 			 *
10241 			 * This inverts the advice in bus.h where drivers
10242 			 * supporting newer hardware should return
10243 			 * BUS_PROBE_DEFAULT and drivers for older devices
10244 			 * return BUS_PROBE_LOW_PRIORITY.
10245 			 *
10246 			 */
10247 			return (BUS_PROBE_LOW_PRIORITY);
10248 		}
10249 	}
10250 
10251 	return (ENXIO);
10252 }
10253 
10254 static int
10255 iwx_attach(device_t dev)
10256 {
10257 	struct iwx_softc *sc = device_get_softc(dev);
10258 	struct ieee80211com *ic = &sc->sc_ic;
10259 	const struct iwx_device_cfg *cfg;
10260 	int err;
10261 	int txq_i, i, j;
10262 	size_t ctxt_info_size;
10263 	int rid;
10264 	int count;
10265 	int error;
10266 	sc->sc_dev = dev;
10267 	sc->sc_pid = pci_get_device(dev);
10268 	sc->sc_dmat = bus_get_dma_tag(sc->sc_dev);
10269 
10270 	TASK_INIT(&sc->sc_es_task, 0, iwx_endscan_cb, sc);
10271 	IWX_LOCK_INIT(sc);
10272 	mbufq_init(&sc->sc_snd, ifqmaxlen);
10273 	TASK_INIT(&sc->ba_rx_task, 0, iwx_ba_rx_task, sc);
10274 	TASK_INIT(&sc->ba_tx_task, 0, iwx_ba_tx_task, sc);
10275 	sc->sc_tq = taskqueue_create("iwm_taskq", M_WAITOK,
10276 	    taskqueue_thread_enqueue, &sc->sc_tq);
10277 	error = taskqueue_start_threads(&sc->sc_tq, 1, 0, "iwm_taskq");
10278 	if (error != 0) {
10279 		device_printf(dev, "can't start taskq thread, error %d\n",
10280 		    error);
10281 		return (ENXIO);
10282 	}
10283 
10284 	pci_find_cap(dev, PCIY_EXPRESS, &sc->sc_cap_off);
10285 	if (sc->sc_cap_off == 0) {
10286 		device_printf(dev, "PCIe capability structure not found!\n");
10287 		return (ENXIO);
10288 	}
10289 
10290 	/*
10291 	 * We disable the RETRY_TIMEOUT register (0x41) to keep
10292 	 * PCI Tx retries from interfering with C3 CPU state.
10293 	 */
10294 	pci_write_config(dev, PCI_CFG_RETRY_TIMEOUT, 0x00, 1);
10295 
10296 	if (pci_msix_count(dev)) {
10297 		sc->sc_msix = 1;
10298 	} else {
10299 		device_printf(dev, "no MSI-X found\n");
10300 		return (ENXIO);
10301 	}
10302 
10303 	pci_enable_busmaster(dev);
10304 	rid = PCIR_BAR(0);
10305 	sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
10306 	    RF_ACTIVE);
10307 	if (sc->sc_mem == NULL) {
10308 		device_printf(sc->sc_dev, "can't map mem space\n");
10309 		return (ENXIO);
10310 	}
10311 	sc->sc_st = rman_get_bustag(sc->sc_mem);
10312 	sc->sc_sh = rman_get_bushandle(sc->sc_mem);
10313 
10314 	count = 1;
10315 	rid = 0;
10316 	if (pci_alloc_msix(dev, &count) == 0)
10317 		rid = 1;
10318 	DPRINTF(("%s: count=%d\n", __func__, count));
10319 	sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE |
10320 	    (rid != 0 ? 0 : RF_SHAREABLE));
10321 	if (sc->sc_irq == NULL) {
10322 		device_printf(dev, "can't map interrupt\n");
10323 		return (ENXIO);
10324 	}
10325 	error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_NET | INTR_MPSAFE,
10326 	    NULL, iwx_intr_msix, sc, &sc->sc_ih);
10327 	if (error != 0) {
10328 		device_printf(dev, "can't establish interrupt\n");
10329 		return (ENXIO);
10330 	}
10331 
10332 	/* Clear pending interrupts. */
10333 	IWX_WRITE(sc, IWX_CSR_INT_MASK, 0);
10334 	IWX_WRITE(sc, IWX_CSR_INT, ~0);
10335 	IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, ~0);
10336 
10337 	sc->sc_hw_rev = IWX_READ(sc, IWX_CSR_HW_REV);
10338 	DPRINTF(("%s: sc->sc_hw_rev=%d\n", __func__, sc->sc_hw_rev));
10339 	sc->sc_hw_rf_id = IWX_READ(sc, IWX_CSR_HW_RF_ID);
10340 	DPRINTF(("%s: sc->sc_hw_rf_id =%d\n", __func__, sc->sc_hw_rf_id));
10341 
10342 	/*
10343 	 * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have
10344 	 * changed, and now the revision step also includes bit 0-1 (no more
10345 	 * "dash" value). To keep hw_rev backwards compatible - we'll store it
10346 	 * in the old format.
10347 	 */
10348 	sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) |
10349 			(IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2);
10350 
10351 	switch (sc->sc_pid) {
10352 	case PCI_PRODUCT_INTEL_WL_22500_1:
10353 		sc->sc_fwname = IWX_CC_A_FW;
10354 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10355 		sc->sc_integrated = 0;
10356 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE;
10357 		sc->sc_low_latency_xtal = 0;
10358 		sc->sc_xtal_latency = 0;
10359 		sc->sc_tx_with_siso_diversity = 0;
10360 		sc->sc_uhb_supported = 0;
10361 		break;
10362 	case PCI_PRODUCT_INTEL_WL_22500_2:
10363 	case PCI_PRODUCT_INTEL_WL_22500_5:
10364 		/* These devices should be QuZ only. */
10365 		if (sc->sc_hw_rev != IWX_CSR_HW_REV_TYPE_QUZ) {
10366 			device_printf(dev, "unsupported AX201 adapter\n");
10367 			return (ENXIO);
10368 		}
10369 		sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
10370 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10371 		sc->sc_integrated = 1;
10372 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200;
10373 		sc->sc_low_latency_xtal = 0;
10374 		sc->sc_xtal_latency = 500;
10375 		sc->sc_tx_with_siso_diversity = 0;
10376 		sc->sc_uhb_supported = 0;
10377 		break;
10378 	case PCI_PRODUCT_INTEL_WL_22500_3:
10379 		if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
10380 			sc->sc_fwname = IWX_QU_C_HR_B_FW;
10381 		else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
10382 			sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
10383 		else
10384 			sc->sc_fwname = IWX_QU_B_HR_B_FW;
10385 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10386 		sc->sc_integrated = 1;
10387 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200;
10388 		sc->sc_low_latency_xtal = 0;
10389 		sc->sc_xtal_latency = 500;
10390 		sc->sc_tx_with_siso_diversity = 0;
10391 		sc->sc_uhb_supported = 0;
10392 		break;
10393 	case PCI_PRODUCT_INTEL_WL_22500_4:
10394 	case PCI_PRODUCT_INTEL_WL_22500_7:
10395 	case PCI_PRODUCT_INTEL_WL_22500_8:
10396 		if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
10397 			sc->sc_fwname = IWX_QU_C_HR_B_FW;
10398 		else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
10399 			sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
10400 		else
10401 			sc->sc_fwname = IWX_QU_B_HR_B_FW;
10402 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10403 		sc->sc_integrated = 1;
10404 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_1820;
10405 		sc->sc_low_latency_xtal = 0;
10406 		sc->sc_xtal_latency = 1820;
10407 		sc->sc_tx_with_siso_diversity = 0;
10408 		sc->sc_uhb_supported = 0;
10409 		break;
10410 	case PCI_PRODUCT_INTEL_WL_22500_6:
10411 		if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
10412 			sc->sc_fwname = IWX_QU_C_HR_B_FW;
10413 		else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
10414 			sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
10415 		else
10416 			sc->sc_fwname = IWX_QU_B_HR_B_FW;
10417 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10418 		sc->sc_integrated = 1;
10419 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500;
10420 		sc->sc_low_latency_xtal = 1;
10421 		sc->sc_xtal_latency = 12000;
10422 		sc->sc_tx_with_siso_diversity = 0;
10423 		sc->sc_uhb_supported = 0;
10424 		break;
10425 	case PCI_PRODUCT_INTEL_WL_22500_9:
10426 	case PCI_PRODUCT_INTEL_WL_22500_10:
10427 	case PCI_PRODUCT_INTEL_WL_22500_11:
10428 	case PCI_PRODUCT_INTEL_WL_22500_13:
10429 	/* _14 is an MA device, not yet supported */
10430 	case PCI_PRODUCT_INTEL_WL_22500_15:
10431 	case PCI_PRODUCT_INTEL_WL_22500_16:
10432 		sc->sc_fwname = IWX_SO_A_GF_A_FW;
10433 		sc->sc_pnvm_name = IWX_SO_A_GF_A_PNVM;
10434 		sc->sc_device_family = IWX_DEVICE_FAMILY_AX210;
10435 		sc->sc_integrated = 0;
10436 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE;
10437 		sc->sc_low_latency_xtal = 0;
10438 		sc->sc_xtal_latency = 0;
10439 		sc->sc_tx_with_siso_diversity = 0;
10440 		sc->sc_uhb_supported = 1;
10441 		break;
10442 	case PCI_PRODUCT_INTEL_WL_22500_12:
10443 	case PCI_PRODUCT_INTEL_WL_22500_17:
10444 		sc->sc_fwname = IWX_SO_A_GF_A_FW;
10445 		sc->sc_pnvm_name = IWX_SO_A_GF_A_PNVM;
10446 		sc->sc_device_family = IWX_DEVICE_FAMILY_AX210;
10447 		sc->sc_integrated = 1;
10448 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500;
10449 		sc->sc_low_latency_xtal = 1;
10450 		sc->sc_xtal_latency = 12000;
10451 		sc->sc_tx_with_siso_diversity = 0;
10452 		sc->sc_uhb_supported = 0;
10453 		sc->sc_imr_enabled = 1;
10454 		break;
10455 	default:
10456 		device_printf(dev, "unknown adapter type\n");
10457 		return (ENXIO);
10458 	}
10459 
10460 	cfg = iwx_find_device_cfg(sc);
10461 	DPRINTF(("%s: cfg=%p\n", __func__, cfg));
10462 	if (cfg) {
10463 		sc->sc_fwname = cfg->fw_name;
10464 		sc->sc_pnvm_name = cfg->pnvm_name;
10465 		sc->sc_tx_with_siso_diversity = cfg->tx_with_siso_diversity;
10466 		sc->sc_uhb_supported = cfg->uhb_supported;
10467 		if (cfg->xtal_latency) {
10468 			sc->sc_xtal_latency = cfg->xtal_latency;
10469 			sc->sc_low_latency_xtal = cfg->low_latency_xtal;
10470 		}
10471 	}
10472 
10473 	sc->mac_addr_from_csr = 0x380; /* differs on BZ hw generation */
10474 
10475 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
10476 		sc->sc_umac_prph_offset = 0x300000;
10477 		sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX_GEN3;
10478 	} else
10479 		sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX;
10480 
10481 	/* Allocate DMA memory for loading firmware. */
10482 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
10483 		ctxt_info_size = sizeof(struct iwx_context_info_gen3);
10484 	else
10485 		ctxt_info_size = sizeof(struct iwx_context_info);
10486 	err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ctxt_info_dma,
10487 	    ctxt_info_size, 1);
10488 	if (err) {
10489 		device_printf(dev,
10490 		    "could not allocate memory for loading firmware\n");
10491 		return (ENXIO);
10492 	}
10493 
10494 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
10495 		err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->prph_scratch_dma,
10496 		    sizeof(struct iwx_prph_scratch), 1);
10497 		if (err) {
10498 			device_printf(dev,
10499 			    "could not allocate prph scratch memory\n");
10500 			goto fail1;
10501 		}
10502 
10503 		/*
10504 		 * Allocate prph information. The driver doesn't use this.
10505 		 * We use the second half of this page to give the device
10506 		 * some dummy TR/CR tail pointers - which shouldn't be
10507 		 * necessary as we don't use this, but the hardware still
10508 		 * reads/writes there and we can't let it go do that with
10509 		 * a NULL pointer.
10510 		 */
10511 		KASSERT((sizeof(struct iwx_prph_info) < PAGE_SIZE / 2),
10512 		    ("iwx_prph_info has wrong size"));
10513 		err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->prph_info_dma,
10514 		    PAGE_SIZE, 1);
10515 		if (err) {
10516 			device_printf(dev,
10517 			    "could not allocate prph info memory\n");
10518 			goto fail1;
10519 		}
10520 	}
10521 
10522 	/* Allocate interrupt cause table (ICT).*/
10523 	err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma,
10524 	    IWX_ICT_SIZE, 1<<IWX_ICT_PADDR_SHIFT);
10525 	if (err) {
10526 		device_printf(dev, "could not allocate ICT table\n");
10527 		goto fail1;
10528 	}
10529 
10530 	for (txq_i = 0; txq_i < nitems(sc->txq); txq_i++) {
10531 		err = iwx_alloc_tx_ring(sc, &sc->txq[txq_i], txq_i);
10532 		if (err) {
10533 			device_printf(dev, "could not allocate TX ring %d\n",
10534 			    txq_i);
10535 			goto fail4;
10536 		}
10537 	}
10538 
10539 	err = iwx_alloc_rx_ring(sc, &sc->rxq);
10540 	if (err) {
10541 		device_printf(sc->sc_dev, "could not allocate RX ring\n");
10542 		goto fail4;
10543 	}
10544 
10545 #ifdef IWX_DEBUG
10546 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10547 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "debug",
10548 	    CTLFLAG_RWTUN, &sc->sc_debug, 0, "bitmask to control debugging");
10549 
10550 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10551 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "himark",
10552 	    CTLFLAG_RW, &iwx_himark, 0, "queues high watermark");
10553 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10554 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "lomark",
10555 	    CTLFLAG_RW, &iwx_lomark, 0, "queues low watermark");
10556 
10557 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10558 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "qfullmsk",
10559 	    CTLFLAG_RD, &sc->qfullmsk, 0, "queue fullmask");
10560 
10561 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10562 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue0",
10563 	    CTLFLAG_RD, &sc->txq[0].queued, 0, "queue 0");
10564 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10565 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue1",
10566 	    CTLFLAG_RD, &sc->txq[1].queued, 0, "queue 1");
10567 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10568 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue2",
10569 	    CTLFLAG_RD, &sc->txq[2].queued, 0, "queue 2");
10570 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10571 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue3",
10572 	    CTLFLAG_RD, &sc->txq[3].queued, 0, "queue 3");
10573 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10574 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue4",
10575 	    CTLFLAG_RD, &sc->txq[4].queued, 0, "queue 4");
10576 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10577 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue5",
10578 	    CTLFLAG_RD, &sc->txq[5].queued, 0, "queue 5");
10579 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10580 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue6",
10581 	    CTLFLAG_RD, &sc->txq[6].queued, 0, "queue 6");
10582 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10583 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue7",
10584 	    CTLFLAG_RD, &sc->txq[7].queued, 0, "queue 7");
10585 #endif
10586 	ic->ic_softc = sc;
10587 	ic->ic_name = device_get_nameunit(sc->sc_dev);
10588 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
10589 	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
10590 
10591 	/* Set device capabilities. */
10592 	ic->ic_caps =
10593 	    IEEE80211_C_STA |
10594 	    IEEE80211_C_MONITOR |
10595 	    IEEE80211_C_WPA |		/* WPA/RSN */
10596 	    IEEE80211_C_WME |
10597 	    IEEE80211_C_PMGT |
10598 	    IEEE80211_C_SHSLOT |	/* short slot time supported */
10599 	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
10600 	    IEEE80211_C_BGSCAN		/* capable of bg scanning */
10601 	    ;
10602 	ic->ic_flags_ext = IEEE80211_FEXT_SCAN_OFFLOAD;
10603 	/* Enable seqno offload */
10604 	ic->ic_flags_ext |= IEEE80211_FEXT_SEQNO_OFFLOAD;
10605 	/* Don't send null data frames; let firmware do it */
10606 	ic->ic_flags_ext |= IEEE80211_FEXT_NO_NULLDATA;
10607 
10608 	ic->ic_txstream = 2;
10609 	ic->ic_rxstream = 2;
10610 	ic->ic_htcaps |= IEEE80211_HTC_HT
10611 			| IEEE80211_HTCAP_SMPS_OFF
10612 			| IEEE80211_HTCAP_SHORTGI20	/* short GI in 20MHz */
10613 			| IEEE80211_HTCAP_SHORTGI40	/* short GI in 40MHz */
10614 			| IEEE80211_HTCAP_CHWIDTH40	/* 40MHz channel width*/
10615 			| IEEE80211_HTC_AMPDU		/* tx A-MPDU */
10616 //			| IEEE80211_HTC_RX_AMSDU_AMPDU	/* TODO: hw reorder */
10617 			| IEEE80211_HTCAP_MAXAMSDU_3839;	/* max A-MSDU length */
10618 
10619 	ic->ic_cryptocaps |= IEEE80211_CRYPTO_AES_CCM;
10620 
10621 	/*
10622 	 * XXX: setupcurchan() expects vhtcaps to be non-zero
10623 	 * https://bugs.freebsd.org/274156
10624 	 */
10625 	ic->ic_vht_cap.vht_cap_info |= IEEE80211_VHTCAP_MAX_MPDU_LENGTH_3895
10626 			| IEEE80211_VHTCAP_SHORT_GI_80
10627 			| 3 << IEEE80211_VHTCAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_S
10628 			| IEEE80211_VHTCAP_RX_ANTENNA_PATTERN
10629 			| IEEE80211_VHTCAP_TX_ANTENNA_PATTERN;
10630 
10631 	ic->ic_flags_ext |= IEEE80211_FEXT_VHT;
10632 	int mcsmap = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
10633 		  IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
10634 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
10635 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
10636 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
10637 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
10638 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
10639 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 14;
10640 	ic->ic_vht_cap.supp_mcs.tx_mcs_map = htole16(mcsmap);
10641 	ic->ic_vht_cap.supp_mcs.rx_mcs_map = htole16(mcsmap);
10642 
10643 	callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0);
10644 	for (i = 0; i < nitems(sc->sc_rxba_data); i++) {
10645 		struct iwx_rxba_data *rxba = &sc->sc_rxba_data[i];
10646 		rxba->baid = IWX_RX_REORDER_DATA_INVALID_BAID;
10647 		rxba->sc = sc;
10648 		for (j = 0; j < nitems(rxba->entries); j++)
10649 			mbufq_init(&rxba->entries[j].frames, ifqmaxlen);
10650 	}
10651 
10652 	/* Initialize to something to have a chance to get S:N values. */
10653 	sc->sc_noise = IWX_DEFAULT_NF;
10654 
10655 	sc->sc_preinit_hook.ich_func = iwx_attach_hook;
10656 	sc->sc_preinit_hook.ich_arg = sc;
10657 	if (config_intrhook_establish(&sc->sc_preinit_hook) != 0) {
10658 		device_printf(dev,
10659 		    "config_intrhook_establish failed\n");
10660 		goto fail4;
10661 	}
10662 
10663 	return (0);
10664 
10665 fail4:
10666 	while (--txq_i >= 0)
10667 		iwx_free_tx_ring(sc, &sc->txq[txq_i]);
10668 	iwx_free_rx_ring(sc, &sc->rxq);
10669 	if (sc->ict_dma.vaddr != NULL)
10670 		iwx_dma_contig_free(&sc->ict_dma);
10671 
10672 fail1:
10673 	iwx_dma_contig_free(&sc->ctxt_info_dma);
10674 	iwx_dma_contig_free(&sc->prph_scratch_dma);
10675 	iwx_dma_contig_free(&sc->prph_info_dma);
10676 	return (ENXIO);
10677 }
10678 
10679 static int
10680 iwx_detach(device_t dev)
10681 {
10682 	struct iwx_softc *sc = device_get_softc(dev);
10683 	int txq_i;
10684 
10685 	iwx_stop_device(sc);
10686 	sc->sc_flags |= IWX_FLAG_SHUTDOWN;
10687 
10688 	taskqueue_drain_all(sc->sc_tq);
10689 	taskqueue_free(sc->sc_tq);
10690 
10691 	ieee80211_ifdetach(&sc->sc_ic);
10692 
10693 	callout_drain(&sc->watchdog_to);
10694 
10695 	for (txq_i = 0; txq_i < nitems(sc->txq); txq_i++)
10696 		iwx_free_tx_ring(sc, &sc->txq[txq_i]);
10697 	iwx_free_rx_ring(sc, &sc->rxq);
10698 
10699 	if (sc->sc_fwp != NULL) {
10700 		firmware_put(sc->sc_fwp, FIRMWARE_UNLOAD);
10701 		sc->sc_fwp = NULL;
10702 	}
10703 
10704 	if (sc->sc_pnvm != NULL) {
10705 		firmware_put(sc->sc_pnvm, FIRMWARE_UNLOAD);
10706 		sc->sc_pnvm = NULL;
10707 	}
10708 
10709 	if (sc->sc_irq != NULL) {
10710 		bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
10711 		bus_release_resource(dev, SYS_RES_IRQ,
10712 		    rman_get_rid(sc->sc_irq), sc->sc_irq);
10713 		pci_release_msi(dev);
10714         }
10715 	if (sc->sc_mem != NULL)
10716 		bus_release_resource(dev, SYS_RES_MEMORY,
10717 		    rman_get_rid(sc->sc_mem), sc->sc_mem);
10718 
10719 	IWX_LOCK_DESTROY(sc);
10720 
10721 	return (0);
10722 }
10723 
10724 static void
10725 iwx_radiotap_attach(struct iwx_softc *sc)
10726 {
10727 	struct ieee80211com *ic = &sc->sc_ic;
10728 
10729 	IWX_DPRINTF(sc, IWX_DEBUG_RESET | IWX_DEBUG_TRACE,
10730 	    "->%s begin\n", __func__);
10731 
10732 	ieee80211_radiotap_attach(ic,
10733 	    &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
10734 		IWX_TX_RADIOTAP_PRESENT,
10735 	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
10736 		IWX_RX_RADIOTAP_PRESENT);
10737 
10738 	IWX_DPRINTF(sc, IWX_DEBUG_RESET | IWX_DEBUG_TRACE,
10739 	    "->%s end\n", __func__);
10740 }
10741 
10742 struct ieee80211vap *
10743 iwx_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
10744     enum ieee80211_opmode opmode, int flags,
10745     const uint8_t bssid[IEEE80211_ADDR_LEN],
10746     const uint8_t mac[IEEE80211_ADDR_LEN])
10747 {
10748 	struct iwx_vap *ivp;
10749 	struct ieee80211vap *vap;
10750 
10751 	if (!TAILQ_EMPTY(&ic->ic_vaps))         /* only one at a time */
10752 		return NULL;
10753 	ivp = malloc(sizeof(struct iwx_vap), M_80211_VAP, M_WAITOK | M_ZERO);
10754 	vap = &ivp->iv_vap;
10755 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
10756 	vap->iv_bmissthreshold = 10;            /* override default */
10757 	/* Override with driver methods. */
10758 	ivp->iv_newstate = vap->iv_newstate;
10759 	vap->iv_newstate = iwx_newstate;
10760 
10761 	ivp->id = IWX_DEFAULT_MACID;
10762 	ivp->color = IWX_DEFAULT_COLOR;
10763 
10764 	ivp->have_wme = TRUE;
10765 	ivp->ps_disabled = FALSE;
10766 
10767 	vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K;
10768 	vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_4;
10769 
10770 	/* h/w crypto support */
10771 	vap->iv_key_alloc = iwx_key_alloc;
10772 	vap->iv_key_delete = iwx_key_delete;
10773 	vap->iv_key_set = iwx_key_set;
10774 	vap->iv_key_update_begin = iwx_key_update_begin;
10775 	vap->iv_key_update_end = iwx_key_update_end;
10776 
10777 	ieee80211_ratectl_init(vap);
10778 	/* Complete setup. */
10779 	ieee80211_vap_attach(vap, ieee80211_media_change,
10780 	    ieee80211_media_status, mac);
10781 	ic->ic_opmode = opmode;
10782 
10783 	return vap;
10784 }
10785 
10786 static void
10787 iwx_vap_delete(struct ieee80211vap *vap)
10788 {
10789 	struct iwx_vap *ivp = IWX_VAP(vap);
10790 
10791 	ieee80211_ratectl_deinit(vap);
10792 	ieee80211_vap_detach(vap);
10793 	free(ivp, M_80211_VAP);
10794 }
10795 
10796 static void
10797 iwx_parent(struct ieee80211com *ic)
10798 {
10799 	struct iwx_softc *sc = ic->ic_softc;
10800 	IWX_LOCK(sc);
10801 
10802 	if (sc->sc_flags & IWX_FLAG_HW_INITED) {
10803 		iwx_stop(sc);
10804 		sc->sc_flags &= ~IWX_FLAG_HW_INITED;
10805 	} else {
10806 		iwx_init(sc);
10807 		ieee80211_start_all(ic);
10808 	}
10809 	IWX_UNLOCK(sc);
10810 }
10811 
10812 static int
10813 iwx_suspend(device_t dev)
10814 {
10815 	struct iwx_softc *sc = device_get_softc(dev);
10816 	struct ieee80211com *ic = &sc->sc_ic;
10817 
10818 	/*
10819 	 * Suspend everything first, then shutdown hardware if it's
10820 	 * still up.
10821 	 */
10822 	ieee80211_suspend_all(ic);
10823 
10824 	if (sc->sc_flags & IWX_FLAG_HW_INITED) {
10825 		iwx_stop(sc);
10826 		sc->sc_flags &= ~IWX_FLAG_HW_INITED;
10827 	}
10828 	return (0);
10829 }
10830 
10831 static int
10832 iwx_resume(device_t dev)
10833 {
10834 	struct iwx_softc *sc = device_get_softc(dev);
10835 	struct ieee80211com *ic = &sc->sc_ic;
10836 
10837 	/*
10838 	 * We disable the RETRY_TIMEOUT register (0x41) to keep
10839 	 * PCI Tx retries from interfering with C3 CPU state.
10840 	 */
10841 	pci_write_config(dev, PCI_CFG_RETRY_TIMEOUT, 0x00, 1);
10842 
10843 	IWX_LOCK(sc);
10844 
10845 	/* Stop the hardware here if it's still thought of as "up" */
10846 	if (sc->sc_flags & IWX_FLAG_HW_INITED) {
10847 		iwx_stop(sc);
10848 		sc->sc_flags &= ~IWX_FLAG_HW_INITED;
10849 	}
10850 
10851 	IWX_UNLOCK(sc);
10852 
10853 	/* Start the VAPs, which will bring the hardware back up again */
10854 	ieee80211_resume_all(ic);
10855 	return (0);
10856 }
10857 
10858 static void
10859 iwx_scan_start(struct ieee80211com *ic)
10860 {
10861 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
10862 	struct iwx_softc *sc = ic->ic_softc;
10863 	int err;
10864 
10865 	IWX_LOCK(sc);
10866 	if ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) == 0)
10867 		err = iwx_scan(sc);
10868 	else
10869 		err = iwx_bgscan(ic);
10870 	IWX_UNLOCK(sc);
10871 	if (err)
10872 		ieee80211_cancel_scan(vap);
10873 
10874 	return;
10875 }
10876 
10877 static void
10878 iwx_update_mcast(struct ieee80211com *ic)
10879 {
10880 }
10881 
10882 static void
10883 iwx_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
10884 {
10885 }
10886 
10887 static void
10888 iwx_scan_mindwell(struct ieee80211_scan_state *ss)
10889 {
10890 }
10891 
10892 static void
10893 iwx_scan_end(struct ieee80211com *ic)
10894 {
10895 	iwx_endscan(ic->ic_softc);
10896 }
10897 
10898 static void
10899 iwx_set_channel(struct ieee80211com *ic)
10900 {
10901 #if 0
10902         struct iwx_softc *sc = ic->ic_softc;
10903         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
10904 
10905         IWX_DPRINTF(sc, IWX_DEBUG_NI , "%s:%d NOT IMPLEMENTED\n", __func__, __LINE__);
10906         iwx_phy_ctxt_task((void *)sc);
10907 #endif
10908 }
10909 
10910 static void
10911 iwx_endscan_cb(void *arg, int pending)
10912 {
10913 	struct iwx_softc *sc = arg;
10914 	struct ieee80211com *ic = &sc->sc_ic;
10915 
10916 	DPRINTF(("scan ended\n"));
10917 	ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps));
10918 }
10919 
10920 static int
10921 iwx_wme_update(struct ieee80211com *ic)
10922 {
10923 	return 0;
10924 }
10925 
10926 static int
10927 iwx_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
10928     const struct ieee80211_bpf_params *params)
10929 {
10930 	struct ieee80211com *ic = ni->ni_ic;
10931 	struct iwx_softc *sc = ic->ic_softc;
10932 	int err;
10933 
10934 	IWX_LOCK(sc);
10935 	if (sc->sc_flags & IWX_FLAG_STA_ACTIVE) {
10936 		err = iwx_tx(sc, m, ni);
10937 		IWX_UNLOCK(sc);
10938 		return err;
10939 	} else {
10940 		IWX_UNLOCK(sc);
10941 		return EIO;
10942 	}
10943 }
10944 
10945 static int
10946 iwx_transmit(struct ieee80211com *ic, struct mbuf *m)
10947 {
10948 	struct iwx_softc *sc = ic->ic_softc;
10949 	int error;
10950 
10951 	// TODO: mbufq_enqueue in iwm
10952 	// TODO dequeue in iwm_start, counters, locking
10953 	IWX_LOCK(sc);
10954 	error = mbufq_enqueue(&sc->sc_snd, m);
10955 	if (error) {
10956 		IWX_UNLOCK(sc);
10957 		return (error);
10958 	}
10959 
10960 	iwx_start(sc);
10961 	IWX_UNLOCK(sc);
10962 	return (0);
10963 }
10964 
10965 static int
10966 iwx_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
10967     int baparamset, int batimeout, int baseqctl)
10968 {
10969 	struct ieee80211com *ic = ni->ni_ic;
10970 	struct iwx_softc *sc = ic->ic_softc;
10971 	int tid;
10972 
10973 	tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID);
10974 	sc->ni_rx_ba[tid].ba_winstart =
10975 	    _IEEE80211_MASKSHIFT(le16toh(baseqctl), IEEE80211_BASEQ_START);
10976 	sc->ni_rx_ba[tid].ba_winsize =
10977 	    _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_BUFSIZ);
10978 	sc->ni_rx_ba[tid].ba_timeout_val = batimeout;
10979 
10980 	if (sc->sc_rx_ba_sessions >= IWX_MAX_RX_BA_SESSIONS ||
10981 	    tid >= IWX_MAX_TID_COUNT)
10982 		return ENOSPC;
10983 
10984 	if (sc->ba_rx.start_tidmask & (1 << tid)) {
10985 		DPRINTF(("%s: tid %d already added\n", __func__, tid));
10986 		return EBUSY;
10987 	}
10988 	DPRINTF(("%s: sc->ba_rx.start_tidmask=%x\n", __func__, sc->ba_rx.start_tidmask));
10989 
10990 	sc->ba_rx.start_tidmask |= (1 << tid);
10991 	DPRINTF(("%s: tid=%i\n", __func__, tid));
10992 	DPRINTF(("%s: ba_winstart=%i\n", __func__, sc->ni_rx_ba[tid].ba_winstart));
10993 	DPRINTF(("%s: ba_winsize=%i\n", __func__, sc->ni_rx_ba[tid].ba_winsize));
10994 	DPRINTF(("%s: ba_timeout_val=%i\n", __func__, sc->ni_rx_ba[tid].ba_timeout_val));
10995 
10996 	taskqueue_enqueue(sc->sc_tq, &sc->ba_rx_task);
10997 
10998 	// TODO:misha move to ba_task (serialize)
10999 	sc->sc_ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl);
11000 
11001 	return (0);
11002 }
11003 
11004 static void
11005 iwx_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
11006 {
11007 	return;
11008 }
11009 
11010 /**
11011  * @brief Called by net80211 to request an A-MPDU session be established.
11012  *
11013  * This is called by net80211 to see if an A-MPDU session can be established.
11014  * However, the iwx(4) firmware will take care of establishing the BA
11015  * session for us.  net80211 doesn't have to send any action frames here;
11016  * it just needs to plumb up the ampdu session once the BA has been sent.
11017  *
11018  * If we return 0 here then the firmware will set up the state but net80211
11019  * will not; so it's on us to actually complete it via a call to
11020  * ieee80211_ampdu_tx_request_active_ext() .
11021  *
11022  * @param ni	ieee80211_node to establish A-MPDU session for
11023  * @param tap	pointer to the per-TID state struct
11024  * @param dialogtoken	dialogtoken field from the BA request
11025  * @param baparamset	baparamset field from the BA request
11026  * @param batimeout	batimeout field from the BA request
11027  *
11028  * @returns 0 so net80211 doesn't send the BA action frame to establish A-MPDU.
11029  */
11030 static int
11031 iwx_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
11032     int dialogtoken, int baparamset, int batimeout)
11033 {
11034 	struct iwx_softc *sc = ni->ni_ic->ic_softc;
11035 	int tid;
11036 
11037 	tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID);
11038 	IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT,
11039 	    "%s: queuing AMPDU start on tid %i\n", __func__, tid);
11040 
11041 	/* There's no nice way right now to tell net80211 that we're in the
11042 	 * middle of an asynchronous ADDBA setup session.  So, bump the timeout
11043 	 * to hz ticks, hopefully we'll get a response by then.
11044 	 */
11045 	tap->txa_nextrequest = ticks + hz;
11046 
11047 	IWX_LOCK(sc);
11048 	sc->ba_tx.start_tidmask |= (1 << tid);
11049 	IWX_UNLOCK(sc);
11050 
11051 	taskqueue_enqueue(sc->sc_tq, &sc->ba_tx_task);
11052 
11053 	return (0);
11054 }
11055 
11056 
11057 static int
11058 iwx_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
11059     int code, int baparamset, int batimeout)
11060 {
11061 	return 0;
11062 }
11063 
11064 static void
11065 iwx_key_update_begin(struct ieee80211vap *vap)
11066 {
11067 	return;
11068 }
11069 
11070 static void
11071 iwx_key_update_end(struct ieee80211vap *vap)
11072 {
11073 	return;
11074 }
11075 
11076 static int
11077 iwx_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
11078 	ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
11079 {
11080 
11081 	if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) {
11082 		return (1);
11083 	}
11084 
11085 	if (ieee80211_is_key_unicast(vap, k)) {
11086 		*keyix = 0;	/* NB: use key index 0 for ucast key */
11087 	} else if (ieee80211_is_key_global(vap, k)) {
11088 		*keyix = ieee80211_crypto_get_key_wepidx(vap, k);
11089 	} else {
11090 		net80211_vap_printf(vap, "%s: invalid crypto key type\n",
11091 		    __func__);
11092 		return (0);
11093 	}
11094 	*rxkeyix = IEEE80211_KEYIX_NONE;	/* XXX maybe *keyix? */
11095 	return (1);
11096 }
11097 
11098 static int
11099 iwx_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
11100 {
11101 	struct ieee80211com *ic = vap->iv_ic;
11102 	struct iwx_softc *sc = ic->ic_softc;
11103 	struct iwx_add_sta_key_cmd cmd;
11104 	uint32_t status;
11105 	int err;
11106 	int id;
11107 
11108 	if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_AES_CCM) {
11109 		return 1;
11110 	}
11111 
11112 	/*
11113 	 * Keys are stored in 'ni' so 'k' is valid if 'ni' is valid.
11114 	 * Currently we only implement station mode where 'ni' is always
11115 	 * ic->ic_bss so there is no need to validate arguments beyond this:
11116 	 */
11117 
11118 	memset(&cmd, 0, sizeof(cmd));
11119 
11120 	if (ieee80211_is_key_global(vap, k)) {
11121 		id = ieee80211_crypto_get_key_wepidx(vap, k);
11122 		IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: adding group key\n",
11123 		    __func__);
11124 	} else if (ieee80211_is_key_unicast(vap, k)) {
11125 		IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: adding key\n",
11126 		    __func__);
11127 		id = 0; /* net80211 currently only supports unicast key 0 */
11128 	} else {
11129 		net80211_vap_printf(vap, "%s: unknown key type\n", __func__);
11130 		return (ENXIO);
11131 	}
11132 
11133 	IWX_LOCK(sc);
11134 
11135 	cmd.common.key_flags = htole16(IWX_STA_KEY_FLG_CCM |
11136 	    IWX_STA_KEY_FLG_WEP_KEY_MAP |
11137 	    ((id << IWX_STA_KEY_FLG_KEYID_POS) &
11138 	    IWX_STA_KEY_FLG_KEYID_MSK));
11139 	if (ieee80211_is_key_global(vap, k)) {
11140 		cmd.common.key_offset = 1;
11141 		cmd.common.key_flags |= htole16(IWX_STA_KEY_MULTICAST);
11142 	} else if (ieee80211_is_key_unicast(vap, k)) {
11143 		cmd.common.key_offset = 0;
11144 	} else {
11145 		net80211_vap_printf(vap, "%s: unknown key type\n", __func__);
11146 		IWX_UNLOCK(sc);
11147 		return (ENXIO);
11148 	}
11149 	memcpy(cmd.common.key, ieee80211_crypto_get_key_data(k),
11150 	    MIN(sizeof(cmd.common.key), ieee80211_crypto_get_key_len(k)));
11151 	IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: key: id=%d, len=%i, key=%*D\n",
11152 	    __func__, id,
11153 	    ieee80211_crypto_get_key_len(k),
11154 	    ieee80211_crypto_get_key_len(k),
11155 	    (const unsigned char *) ieee80211_crypto_get_key_data(k), "");
11156 	cmd.common.sta_id = IWX_STATION_ID;
11157 
11158 	cmd.transmit_seq_cnt = htole64(k->wk_keytsc);
11159 	IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: k->wk_keytsc=%" PRIu64 "\n",
11160 	    __func__, k->wk_keytsc);
11161 
11162 	status = IWX_ADD_STA_SUCCESS;
11163 	err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA_KEY, sizeof(cmd), &cmd,
11164 	    &status);
11165 	if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS)
11166 		err = EIO;
11167 	if (err) {
11168 		net80211_vap_printf(vap,
11169 		    "%s: can't set wpa2 keys (error %d)\n", __func__, err);
11170 		IWX_UNLOCK(sc);
11171 		return err;
11172 	} else
11173 		IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT,
11174 		    "%s: key added successfully\n", __func__);
11175 	IWX_UNLOCK(sc);
11176 	return (1);
11177 }
11178 
11179 static int
11180 iwx_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
11181 {
11182 	/*
11183 	 * Note: since there's no key allocations to track - it's either
11184 	 * the 4 static WEP keys or the single unicast key - there's nothing
11185 	 * else to do here.
11186 	 *
11187 	 * This would need some further work to support IBSS/mesh/AP modes.
11188 	 */
11189 	return (1);
11190 }
11191 
11192 static device_method_t iwx_pci_methods[] = {
11193 	/* Device interface */
11194 	DEVMETHOD(device_probe,		iwx_probe),
11195 	DEVMETHOD(device_attach,	iwx_attach),
11196 	DEVMETHOD(device_detach,	iwx_detach),
11197 	DEVMETHOD(device_suspend,	iwx_suspend),
11198 	DEVMETHOD(device_resume,	iwx_resume),
11199 
11200 	DEVMETHOD_END
11201 };
11202 
11203 static driver_t iwx_pci_driver = {
11204 	"iwx",
11205 	iwx_pci_methods,
11206 	sizeof (struct iwx_softc)
11207 };
11208 
11209 DRIVER_MODULE(iwx, pci, iwx_pci_driver, NULL, NULL);
11210 MODULE_PNP_INFO("U16:device;D:#;T:vendor=0x8086", pci, iwx_pci_driver,
11211     iwx_devices, nitems(iwx_devices));
11212 MODULE_DEPEND(iwx, firmware, 1, 1, 1);
11213 MODULE_DEPEND(iwx, pci, 1, 1, 1);
11214 MODULE_DEPEND(iwx, wlan, 1, 1, 1);
11215