xref: /freebsd/sys/dev/iwx/if_iwx.c (revision f616f8a83ba1bf8aa41003837c11a0f0955efed8)
1 /*-
2  * SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) AND ISC
3  */
4 
5 /*	$OpenBSD: if_iwx.c,v 1.175 2023/07/05 15:07:28 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
ieee80211_has_addr4(const struct ieee80211_frame * wh)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
iwx_lookup_cmd_ver(struct iwx_softc * sc,uint8_t grp,uint8_t cmd)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
iwx_lookup_notif_ver(struct iwx_softc * sc,uint8_t grp,uint8_t cmd)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
iwx_store_cscheme(struct iwx_softc * sc,const uint8_t * data,size_t dlen)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
iwx_ctxt_info_alloc_dma(struct iwx_softc * sc,const struct iwx_fw_onesect * sec,struct iwx_dma_info * dram)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
iwx_ctxt_info_free_paging(struct iwx_softc * sc)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
iwx_get_num_sections(const struct iwx_fw_sects * fws,int start)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
iwx_init_fw_sec(struct iwx_softc * sc,const struct iwx_fw_sects * fws,struct iwx_context_info_dram * ctxt_dram)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
iwx_fw_version_str(char * buf,size_t bufsize,uint32_t major,uint32_t minor,uint32_t api)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
iwx_apply_debug_destination(struct iwx_softc * sc)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
iwx_set_ltr(struct iwx_softc * sc)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
iwx_ctxt_info_init(struct iwx_softc * sc,const struct iwx_fw_sects * fws)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
iwx_ctxt_info_gen3_init(struct iwx_softc * sc,const struct iwx_fw_sects * fws)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
iwx_ctxt_info_free_fw_img(struct iwx_softc * sc)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
iwx_firmware_store_section(struct iwx_softc * sc,enum iwx_ucode_type type,const uint8_t * data,size_t dlen)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
iwx_set_default_calib(struct iwx_softc * sc,const void * data)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
iwx_fw_info_free(struct iwx_fw_info * fw)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
iwx_read_firmware(struct iwx_softc * sc)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
iwx_prph_addr_mask(struct iwx_softc * sc)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
iwx_read_prph_unlocked(struct iwx_softc * sc,uint32_t addr)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
iwx_read_prph(struct iwx_softc * sc,uint32_t addr)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
iwx_write_prph_unlocked(struct iwx_softc * sc,uint32_t addr,uint32_t val)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
iwx_write_prph(struct iwx_softc * sc,uint32_t addr,uint32_t val)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
iwx_read_umac_prph(struct iwx_softc * sc,uint32_t addr)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
iwx_write_umac_prph(struct iwx_softc * sc,uint32_t addr,uint32_t val)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
iwx_read_mem(struct iwx_softc * sc,uint32_t addr,void * buf,int dwords)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
iwx_poll_bit(struct iwx_softc * sc,int reg,uint32_t bits,uint32_t mask,int timo)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
iwx_nic_lock(struct iwx_softc * sc)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
iwx_nic_assert_locked(struct iwx_softc * sc)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
iwx_nic_unlock(struct iwx_softc * sc)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
iwx_set_bits_mask_prph(struct iwx_softc * sc,uint32_t reg,uint32_t bits,uint32_t mask)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
iwx_set_bits_prph(struct iwx_softc * sc,uint32_t reg,uint32_t bits)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
iwx_clear_bits_prph(struct iwx_softc * sc,uint32_t reg,uint32_t bits)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
iwx_dma_map_addr(void * arg,bus_dma_segment_t * segs,int nsegs,int error)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
iwx_dma_contig_alloc(bus_dma_tag_t tag,struct iwx_dma_info * dma,bus_size_t size,bus_size_t alignment)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
iwx_dma_contig_free(struct iwx_dma_info * dma)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
iwx_alloc_rx_ring(struct iwx_softc * sc,struct iwx_rx_ring * ring)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
iwx_disable_rx_dma(struct iwx_softc * sc)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
iwx_reset_rx_ring(struct iwx_softc * sc,struct iwx_rx_ring * ring)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
iwx_free_rx_ring(struct iwx_softc * sc,struct iwx_rx_ring * ring)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
iwx_alloc_tx_ring(struct iwx_softc * sc,struct iwx_tx_ring * ring,int qid)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
iwx_reset_tx_ring(struct iwx_softc * sc,struct iwx_tx_ring * ring)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
iwx_free_tx_ring(struct iwx_softc * sc,struct iwx_tx_ring * ring)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
iwx_enable_rfkill_int(struct iwx_softc * sc)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
iwx_check_rfkill(struct iwx_softc * sc)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
iwx_enable_interrupts(struct iwx_softc * sc)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
iwx_enable_fwload_interrupt(struct iwx_softc * sc)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
iwx_disable_interrupts(struct iwx_softc * sc)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
iwx_ict_reset(struct iwx_softc * sc)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
iwx_set_hw_ready(struct iwx_softc * sc)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
iwx_prepare_card_hw(struct iwx_softc * sc)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
iwx_force_power_gating(struct iwx_softc * sc)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
iwx_apm_config(struct iwx_softc * sc)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
iwx_apm_init(struct iwx_softc * sc)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
iwx_apm_stop(struct iwx_softc * sc)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
iwx_init_msix_hw(struct iwx_softc * sc)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
iwx_conf_msix_hw(struct iwx_softc * sc,int stopped)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
iwx_clear_persistence_bit(struct iwx_softc * sc)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
iwx_start_hw(struct iwx_softc * sc)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
iwx_stop_device(struct iwx_softc * sc)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
iwx_nic_config(struct iwx_softc * sc)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
iwx_nic_rx_init(struct iwx_softc * sc)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
iwx_nic_init(struct iwx_softc * sc)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
iwx_enable_txq(struct iwx_softc * sc,int sta_id,int qid,int tid,int num_slots)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
iwx_disable_txq(struct iwx_softc * sc,int sta_id,int qid,uint8_t tid)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
iwx_post_alive(struct iwx_softc * sc)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
iwx_schedule_session_protection(struct iwx_softc * sc,struct iwx_node * in,uint32_t duration_tu)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
iwx_unprotect_session(struct iwx_softc * sc,struct iwx_node * in)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
iwx_fw_valid_tx_ant(struct iwx_softc * sc)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
iwx_fw_valid_rx_ant(struct iwx_softc * sc)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
iwx_init_channel_map(struct ieee80211com * ic,int maxchans,int * nchans,struct ieee80211_channel chans[])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
iwx_mimo_enabled(struct iwx_softc * sc)3282 iwx_mimo_enabled(struct iwx_softc *sc)
3283 {
3284 
3285 	return !sc->sc_nvm.sku_cap_mimo_disable;
3286 }
3287 
3288 static void
iwx_init_reorder_buffer(struct iwx_reorder_buffer * reorder_buf,uint16_t ssn,uint16_t buf_size)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
iwx_clear_reorder_buffer(struct iwx_softc * sc,struct iwx_rxba_data * rxba)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 *
iwx_find_rxba_data(struct iwx_softc * sc,uint8_t tid)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
iwx_sta_rx_agg_baid_cfg_cmd(struct iwx_softc * sc,struct ieee80211_node * ni,uint8_t tid,uint16_t ssn,uint16_t winsize,int timeout_val,int start,uint8_t * baid)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
iwx_sta_rx_agg(struct iwx_softc * sc,struct ieee80211_node * ni,uint8_t tid,uint16_t ssn,uint16_t winsize,int timeout_val,int start)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
iwx_sta_tx_agg_start(struct iwx_softc * sc,struct ieee80211_node * ni,uint8_t tid)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
iwx_ba_rx_task(void * arg,int npending __unused)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
iwx_ba_tx_task(void * arg,int npending __unused)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
iwx_set_mac_addr_from_csr(struct iwx_softc * sc,struct iwx_nvm_data * data)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
iwx_is_valid_mac_addr(const uint8_t * addr)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
iwx_flip_hw_address(uint32_t mac_addr0,uint32_t mac_addr1,uint8_t * dest)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
iwx_nvm_get(struct iwx_softc * sc)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
iwx_load_firmware(struct iwx_softc * sc)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
iwx_start_fw(struct iwx_softc * sc)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
iwx_pnvm_handle_section(struct iwx_softc * sc,const uint8_t * data,size_t len)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
iwx_pnvm_parse(struct iwx_softc * sc,const uint8_t * data,size_t len)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
iwx_ctxt_info_gen3_set_pnvm(struct iwx_softc * sc)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
iwx_load_pnvm(struct iwx_softc * sc)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
iwx_send_tx_ant_cfg(struct iwx_softc * sc,uint8_t valid_tx_ant)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
iwx_send_phy_cfg_cmd(struct iwx_softc * sc)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
iwx_send_dqa_cmd(struct iwx_softc * sc)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
iwx_load_ucode_wait_alive(struct iwx_softc * sc)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
iwx_run_init_mvm_ucode(struct iwx_softc * sc,int readnvm)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
iwx_config_ltr(struct iwx_softc * sc)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
iwx_update_rx_desc(struct iwx_softc * sc,struct iwx_rx_ring * ring,int idx,bus_dma_segment_t * seg)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
iwx_rx_addbuf(struct iwx_softc * sc,int size,int idx)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
iwx_rxmq_get_signal_strength(struct iwx_softc * sc,struct iwx_rx_mpdu_desc * desc)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
iwx_calculate_rssi(struct iwx_softc * sc,int ss,int nf)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
iwx_rxmq_get_chains(struct iwx_softc * sc,struct iwx_rx_mpdu_desc * desc)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
iwx_rx_rx_phy_cmd(struct iwx_softc * sc,struct iwx_rx_packet * pkt,struct iwx_rx_data * data)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
iwx_get_noise(struct iwx_softc * sc,const struct iwx_statistics_rx_non_phy * stats)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
iwx_rx_hwdecrypt(struct iwx_softc * sc,struct mbuf * m,uint32_t rx_pkt_status)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
iwx_rx_frame(struct iwx_softc * sc,struct mbuf * m,int chanidx,uint32_t rx_pkt_status,int is_shortpre,int rate_n_flags,uint32_t device_timestamp,uint8_t rssi)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
iwx_rx_mpdu_mq(struct iwx_softc * sc,struct mbuf * m,void * pktdata,size_t maxlen)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
iwx_clear_tx_desc(struct iwx_softc * sc,struct iwx_tx_ring * ring,int idx)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
iwx_txd_done(struct iwx_softc * sc,struct iwx_tx_ring * ring,struct iwx_tx_data * txd)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
iwx_txq_advance(struct iwx_softc * sc,struct iwx_tx_ring * ring,uint16_t idx)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
iwx_rx_tx_cmd(struct iwx_softc * sc,struct iwx_rx_packet * pkt,struct iwx_rx_data * data)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
iwx_clear_oactive(struct iwx_softc * sc,struct iwx_tx_ring * ring)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
iwx_rx_compressed_ba(struct iwx_softc * sc,struct iwx_rx_packet * pkt)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
iwx_rx_bmiss(struct iwx_softc * sc,struct iwx_rx_packet * pkt,struct iwx_rx_data * data)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
iwx_binding_cmd(struct iwx_softc * sc,struct iwx_node * in,uint32_t action)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
iwx_get_vht_ctrl_pos(struct ieee80211com * ic,struct ieee80211_channel * chan)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
iwx_phy_ctxt_cmd_uhb_v3_v4(struct iwx_softc * sc,struct iwx_phy_ctxt * ctxt,uint8_t chains_static,uint8_t chains_dynamic,uint32_t action,uint8_t sco,uint8_t vht_chan_width,int cmdver)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
iwx_phy_ctxt_cmd(struct iwx_softc * sc,struct iwx_phy_ctxt * ctxt,uint8_t chains_static,uint8_t chains_dynamic,uint32_t action,uint32_t apply_time,uint8_t sco,uint8_t vht_chan_width)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
iwx_send_cmd(struct iwx_softc * sc,struct iwx_host_cmd * hcmd)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
iwx_send_cmd_pdu(struct iwx_softc * sc,uint32_t id,uint32_t flags,uint16_t len,const void * data)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
iwx_send_cmd_status(struct iwx_softc * sc,struct iwx_host_cmd * cmd,uint32_t * status)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
iwx_send_cmd_pdu_status(struct iwx_softc * sc,uint32_t id,uint16_t len,const void * data,uint32_t * status)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
iwx_free_resp(struct iwx_softc * sc,struct iwx_host_cmd * hcmd)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
iwx_cmd_done(struct iwx_softc * sc,int qid,int idx,int code)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
iwx_fw_rateidx_ofdm(uint8_t rval)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
iwx_fw_rateidx_cck(uint8_t rval)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
iwx_min_basic_rate(struct ieee80211com * ic)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 *
iwx_tx_fill_cmd(struct iwx_softc * sc,struct iwx_node * in,struct ieee80211_frame * wh,uint16_t * flags,uint32_t * rate_n_flags,struct mbuf * m)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 	rval = (rs->rs_rates[ieee80211_node_get_txrate_dot11rate(ni)]
5637 	    & IEEE80211_RATE_VAL);
5638 	IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d: rval=%i dot11 %d\n", __func__, __LINE__,
5639 	    rval, rs->rs_rates[ieee80211_node_get_txrate_dot11rate(ni)]);
5640 
5641 	if (sc->sc_rate_n_flags_version >= 2) {
5642 		if (rate_flags & IWX_RATE_MCS_LEGACY_OFDM_MSK) {
5643 			rate_flags |= (iwx_fw_rateidx_ofdm(rval) &
5644 			    IWX_RATE_LEGACY_RATE_MSK);
5645 		} else {
5646 			rate_flags |= (iwx_fw_rateidx_cck(rval) &
5647 			    IWX_RATE_LEGACY_RATE_MSK);
5648 		}
5649 	} else
5650 		rate_flags |= rinfo->plcp;
5651 
5652 	*rate_n_flags = rate_flags;
5653 	IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d flags=0x%x\n",
5654 	    __func__, __LINE__,*flags);
5655 	IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d rate_n_flags=0x%x\n",
5656 	    __func__, __LINE__, *rate_n_flags);
5657 
5658 	if (sc->sc_debug & IWX_DEBUG_TXRATE)
5659 		print_ratenflags(__func__, __LINE__,
5660 		    *rate_n_flags, sc->sc_rate_n_flags_version);
5661 
5662 	return rinfo;
5663 }
5664 
5665 static void
iwx_tx_update_byte_tbl(struct iwx_softc * sc,struct iwx_tx_ring * txq,int idx,uint16_t byte_cnt,uint16_t num_tbs)5666 iwx_tx_update_byte_tbl(struct iwx_softc *sc, struct iwx_tx_ring *txq,
5667     int idx, uint16_t byte_cnt, uint16_t num_tbs)
5668 {
5669 	uint8_t filled_tfd_size, num_fetch_chunks;
5670 	uint16_t len = byte_cnt;
5671 	uint16_t bc_ent;
5672 
5673 	filled_tfd_size = offsetof(struct iwx_tfh_tfd, tbs) +
5674 			  num_tbs * sizeof(struct iwx_tfh_tb);
5675 	/*
5676 	 * filled_tfd_size contains the number of filled bytes in the TFD.
5677 	 * Dividing it by 64 will give the number of chunks to fetch
5678 	 * to SRAM- 0 for one chunk, 1 for 2 and so on.
5679 	 * If, for example, TFD contains only 3 TBs then 32 bytes
5680 	 * of the TFD are used, and only one chunk of 64 bytes should
5681 	 * be fetched
5682 	 */
5683 	num_fetch_chunks = howmany(filled_tfd_size, 64) - 1;
5684 
5685 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
5686 		struct iwx_gen3_bc_tbl_entry *scd_bc_tbl = txq->bc_tbl.vaddr;
5687 		/* Starting from AX210, the HW expects bytes */
5688 		bc_ent = htole16(len | (num_fetch_chunks << 14));
5689 		scd_bc_tbl[idx].tfd_offset = bc_ent;
5690 	} else {
5691 		struct iwx_agn_scd_bc_tbl *scd_bc_tbl = txq->bc_tbl.vaddr;
5692 		/* Before AX210, the HW expects DW */
5693 		len = howmany(len, 4);
5694 		bc_ent = htole16(len | (num_fetch_chunks << 12));
5695 		scd_bc_tbl->tfd_offset[idx] = bc_ent;
5696 	}
5697 
5698 	bus_dmamap_sync(sc->sc_dmat, txq->bc_tbl.map, BUS_DMASYNC_PREWRITE);
5699 }
5700 
5701 static int
iwx_tx(struct iwx_softc * sc,struct mbuf * m,struct ieee80211_node * ni)5702 iwx_tx(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
5703 {
5704 	struct ieee80211com *ic = &sc->sc_ic;
5705 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
5706 	struct iwx_node *in = (void *)ni;
5707 	struct iwx_tx_ring *ring;
5708 	struct iwx_tx_data *data;
5709 	struct iwx_tfh_tfd *desc;
5710 	struct iwx_device_cmd *cmd;
5711 	struct ieee80211_frame *wh;
5712 	struct ieee80211_key *k = NULL;
5713 	const struct iwx_rate *rinfo;
5714 	uint64_t paddr;
5715 	u_int hdrlen;
5716 	uint32_t rate_n_flags;
5717 	uint16_t num_tbs, flags, offload_assist = 0;
5718 	int i, totlen, err, pad, qid;
5719 #define IWM_MAX_SCATTER 20
5720 	bus_dma_segment_t *seg, segs[IWM_MAX_SCATTER];
5721 	int nsegs;
5722 	struct mbuf *m1;
5723 	size_t txcmd_size;
5724 
5725 	IWX_ASSERT_LOCKED(sc);
5726 
5727 	wh = mtod(m, struct ieee80211_frame *);
5728 	hdrlen = ieee80211_anyhdrsize(wh);
5729 
5730 	qid = sc->first_data_qid;
5731 
5732 	/* Put QoS frames on the data queue which maps to their TID. */
5733 	if (IEEE80211_QOS_HAS_SEQ(wh)) {
5734 		uint16_t qos = ieee80211_gettid(wh);
5735 		uint8_t tid = qos & IEEE80211_QOS_TID;
5736 		struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid];
5737 
5738 		/*
5739 		 * Note: we're currently putting all frames into one queue
5740 		 * except for A-MPDU queues.  We should be able to choose
5741 		 * other WME queues but first we need to verify they've been
5742 		 * correctly setup for data.
5743 		 */
5744 
5745 		/*
5746 		 * Only QoS data goes into an A-MPDU queue;
5747 		 * don't add QoS null, the other data types, etc.
5748 		 */
5749 		if (IEEE80211_AMPDU_RUNNING(tap) &&
5750 		    IEEE80211_IS_QOSDATA(wh) &&
5751 		    !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
5752 		    sc->aggqid[tid] != 0) {
5753 			qid = sc->aggqid[tid];
5754 		}
5755 	}
5756 
5757 	ring = &sc->txq[qid];
5758 	desc = &ring->desc[ring->cur];
5759 	memset(desc, 0, sizeof(*desc));
5760 	data = &ring->data[ring->cur];
5761 
5762 	cmd = &ring->cmd[ring->cur];
5763 	cmd->hdr.code = IWX_TX_CMD;
5764 	cmd->hdr.flags = 0;
5765 	cmd->hdr.qid = ring->qid;
5766 	cmd->hdr.idx = ring->cur;
5767 
5768 	rinfo = iwx_tx_fill_cmd(sc, in, wh, &flags, &rate_n_flags, m);
5769 	if (rinfo == NULL)
5770 		return EINVAL;
5771 
5772 	/* Offloaded sequence number assignment; non-AMPDU case */
5773 	if ((m->m_flags & M_AMPDU_MPDU) == 0)
5774 		ieee80211_output_seqno_assign(ni, -1, m);
5775 
5776 	/* Radiotap */
5777 	if (ieee80211_radiotap_active_vap(vap)) {
5778 		struct iwx_tx_radiotap_header *tap = &sc->sc_txtap;
5779 
5780 		tap->wt_flags = 0;
5781 		tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
5782 		tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
5783 		tap->wt_rate = rinfo->rate;
5784 		if (k != NULL)
5785 			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
5786 		ieee80211_radiotap_tx(vap, m);
5787 	}
5788 
5789 	/* Encrypt - CCMP via direct HW path, TKIP/WEP indirected openbsd-style for now */
5790 	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
5791 		k = ieee80211_crypto_get_txkey(ni, m);
5792 		if (k == NULL) {
5793 			printf("%s: k is NULL!\n", __func__);
5794 			m_freem(m);
5795 			return (ENOBUFS);
5796 		} else if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) {
5797 			k->wk_keytsc++;
5798 		} else {
5799 			k->wk_cipher->ic_encap(k, m);
5800 
5801 			/* 802.11 headers may have moved */
5802 			wh = mtod(m, struct ieee80211_frame *);
5803 			flags |= IWX_TX_FLAGS_ENCRYPT_DIS;
5804 		}
5805 	} else
5806 		flags |= IWX_TX_FLAGS_ENCRYPT_DIS;
5807 
5808 	totlen = m->m_pkthdr.len;
5809 
5810 	if (hdrlen & 3) {
5811 		/* First segment length must be a multiple of 4. */
5812 		pad = 4 - (hdrlen & 3);
5813 		offload_assist |= IWX_TX_CMD_OFFLD_PAD;
5814 	} else
5815 		pad = 0;
5816 
5817 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
5818 		struct iwx_tx_cmd_gen3 *tx = (void *)cmd->data;
5819 		memset(tx, 0, sizeof(*tx));
5820 		tx->len = htole16(totlen);
5821 		tx->offload_assist = htole32(offload_assist);
5822 		tx->flags = htole16(flags);
5823 		tx->rate_n_flags = htole32(rate_n_flags);
5824 		memcpy(tx->hdr, wh, hdrlen);
5825 		txcmd_size = sizeof(*tx);
5826 	} else {
5827 		struct iwx_tx_cmd_gen2 *tx = (void *)cmd->data;
5828 		memset(tx, 0, sizeof(*tx));
5829 		tx->len = htole16(totlen);
5830 		tx->offload_assist = htole16(offload_assist);
5831 		tx->flags = htole32(flags);
5832 		tx->rate_n_flags = htole32(rate_n_flags);
5833 		memcpy(tx->hdr, wh, hdrlen);
5834 		txcmd_size = sizeof(*tx);
5835 	}
5836 
5837 	/* Trim 802.11 header. */
5838 	m_adj(m, hdrlen);
5839 
5840 	err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, segs,
5841 	    &nsegs, BUS_DMA_NOWAIT);
5842 	if (err && err != EFBIG) {
5843 		printf("%s: can't map mbuf (error %d)\n", DEVNAME(sc), err);
5844 		m_freem(m);
5845 		return err;
5846 	}
5847 	if (err) {
5848 		/* Too many DMA segments, linearize mbuf. */
5849 		m1 = m_collapse(m, M_NOWAIT, IWM_MAX_SCATTER - 2);
5850 		if (m1 == NULL) {
5851 			printf("%s: could not defrag mbufs\n", __func__);
5852 			m_freem(m);
5853 			return (ENOBUFS);
5854 		}
5855 		m = m1;
5856 		err = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m,
5857 		    segs, &nsegs, BUS_DMA_NOWAIT);
5858 		if (err) {
5859 			printf("%s: can't map mbuf (error %d)\n", __func__,
5860 			    err);
5861 			m_freem(m);
5862 			return (err);
5863 		}
5864 	}
5865 	data->m = m;
5866 	data->in = in;
5867 
5868 	/* Fill TX descriptor. */
5869 	num_tbs = 2 + nsegs;
5870 	desc->num_tbs = htole16(num_tbs);
5871 
5872 	desc->tbs[0].tb_len = htole16(IWX_FIRST_TB_SIZE);
5873 	paddr = htole64(data->cmd_paddr);
5874 	memcpy(&desc->tbs[0].addr, &paddr, sizeof(paddr));
5875 #if __SIZEOF_SIZE_T__ > 4
5876 	if (data->cmd_paddr >> 32 != (data->cmd_paddr +
5877 	    le32toh(desc->tbs[0].tb_len)) >> 32)
5878 		DPRINTF(("%s: TB0 crosses 32bit boundary\n", __func__));
5879 #endif
5880 	desc->tbs[1].tb_len = htole16(sizeof(struct iwx_cmd_header) +
5881 	    txcmd_size + hdrlen + pad - IWX_FIRST_TB_SIZE);
5882 	paddr = htole64(data->cmd_paddr + IWX_FIRST_TB_SIZE);
5883 	memcpy(&desc->tbs[1].addr, &paddr, sizeof(paddr));
5884 
5885 #if __SIZEOF_SIZE_T__ > 4
5886 	if (data->cmd_paddr >> 32 != (data->cmd_paddr +
5887 	    le32toh(desc->tbs[1].tb_len)) >> 32)
5888 		DPRINTF(("%s: TB1 crosses 32bit boundary\n", __func__));
5889 #endif
5890 
5891 	/* Other DMA segments are for data payload. */
5892 	for (i = 0; i < nsegs; i++) {
5893 		seg = &segs[i];
5894 		desc->tbs[i + 2].tb_len = htole16(seg->ds_len);
5895 		paddr = htole64(seg->ds_addr);
5896 		memcpy(&desc->tbs[i + 2].addr, &paddr, sizeof(paddr));
5897 #if __SIZEOF_SIZE_T__ > 4
5898 		if (data->cmd_paddr >> 32 != (data->cmd_paddr +
5899 		    le32toh(desc->tbs[i + 2].tb_len)) >> 32)
5900 			DPRINTF(("%s: TB%d crosses 32bit boundary\n", __func__,
5901 			    i + 2));
5902 #endif
5903 	}
5904 
5905 	bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
5906 	bus_dmamap_sync(ring->cmd_dma.tag, ring->cmd_dma.map,
5907 	    BUS_DMASYNC_PREWRITE);
5908 	bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
5909 	    BUS_DMASYNC_PREWRITE);
5910 
5911 	iwx_tx_update_byte_tbl(sc, ring, ring->cur, totlen, num_tbs);
5912 
5913 	/* Kick TX ring. */
5914 	ring->cur = (ring->cur + 1) % IWX_TX_RING_COUNT;
5915 	ring->cur_hw = (ring->cur_hw + 1) % sc->max_tfd_queue_size;
5916 	IWX_WRITE(sc, IWX_HBUS_TARG_WRPTR, ring->qid << 16 | ring->cur_hw);
5917 
5918 	/* Mark TX ring as full if we reach a certain threshold. */
5919 	if (++ring->queued > iwx_himark) {
5920 		sc->qfullmsk |= 1 << ring->qid;
5921 	}
5922 
5923 	sc->sc_tx_timer[ring->qid] = 15;
5924 
5925 	return 0;
5926 }
5927 
5928 static int
iwx_flush_sta_tids(struct iwx_softc * sc,int sta_id,uint16_t tids)5929 iwx_flush_sta_tids(struct iwx_softc *sc, int sta_id, uint16_t tids)
5930 {
5931 	struct iwx_rx_packet *pkt;
5932 	struct iwx_tx_path_flush_cmd_rsp *resp;
5933 	struct iwx_tx_path_flush_cmd flush_cmd = {
5934 		.sta_id = htole32(sta_id),
5935 		.tid_mask = htole16(tids),
5936 	};
5937 	struct iwx_host_cmd hcmd = {
5938 		.id = IWX_TXPATH_FLUSH,
5939 		.len = { sizeof(flush_cmd), },
5940 		.data = { &flush_cmd, },
5941 		.flags = IWX_CMD_WANT_RESP,
5942 		.resp_pkt_len = sizeof(*pkt) + sizeof(*resp),
5943 	};
5944 	int err, resp_len, i, num_flushed_queues;
5945 
5946 	err = iwx_send_cmd(sc, &hcmd);
5947 	if (err)
5948 		return err;
5949 
5950 	pkt = hcmd.resp_pkt;
5951 	if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) {
5952 		err = EIO;
5953 		goto out;
5954 	}
5955 
5956 	resp_len = iwx_rx_packet_payload_len(pkt);
5957 	/* Some firmware versions don't provide a response. */
5958 	if (resp_len == 0)
5959 		goto out;
5960 	else if (resp_len != sizeof(*resp)) {
5961 		err = EIO;
5962 		goto out;
5963 	}
5964 
5965 	resp = (void *)pkt->data;
5966 
5967 	if (le16toh(resp->sta_id) != sta_id) {
5968 		err = EIO;
5969 		goto out;
5970 	}
5971 
5972 	num_flushed_queues = le16toh(resp->num_flushed_queues);
5973 	if (num_flushed_queues > IWX_TX_FLUSH_QUEUE_RSP) {
5974 		err = EIO;
5975 		goto out;
5976 	}
5977 
5978 	for (i = 0; i < num_flushed_queues; i++) {
5979 		struct iwx_flush_queue_info *queue_info = &resp->queues[i];
5980 		uint16_t tid = le16toh(queue_info->tid);
5981 		uint16_t read_after = le16toh(queue_info->read_after_flush);
5982 		uint16_t qid = le16toh(queue_info->queue_num);
5983 		struct iwx_tx_ring *txq;
5984 
5985 		if (qid >= nitems(sc->txq))
5986 			continue;
5987 
5988 		txq = &sc->txq[qid];
5989 		if (tid != txq->tid)
5990 			continue;
5991 
5992 		iwx_txq_advance(sc, txq, read_after);
5993 	}
5994 out:
5995 	iwx_free_resp(sc, &hcmd);
5996 	return err;
5997 }
5998 
5999 #define IWX_FLUSH_WAIT_MS	2000
6000 
6001 static int
iwx_drain_sta(struct iwx_softc * sc,struct iwx_node * in,int drain)6002 iwx_drain_sta(struct iwx_softc *sc, struct iwx_node* in, int drain)
6003 {
6004 	struct iwx_add_sta_cmd cmd;
6005 	int err;
6006 	uint32_t status;
6007 
6008 	memset(&cmd, 0, sizeof(cmd));
6009 	cmd.mac_id_n_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id,
6010 	    in->in_color));
6011 	cmd.sta_id = IWX_STATION_ID;
6012 	cmd.add_modify = IWX_STA_MODE_MODIFY;
6013 	cmd.station_flags = drain ? htole32(IWX_STA_FLG_DRAIN_FLOW) : 0;
6014 	cmd.station_flags_msk = htole32(IWX_STA_FLG_DRAIN_FLOW);
6015 
6016 	status = IWX_ADD_STA_SUCCESS;
6017 	err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA,
6018 	    sizeof(cmd), &cmd, &status);
6019 	if (err) {
6020 		printf("%s: could not update sta (error %d)\n",
6021 		    DEVNAME(sc), err);
6022 		return err;
6023 	}
6024 
6025 	switch (status & IWX_ADD_STA_STATUS_MASK) {
6026 	case IWX_ADD_STA_SUCCESS:
6027 		break;
6028 	default:
6029 		err = EIO;
6030 		printf("%s: Couldn't %s draining for station\n",
6031 		    DEVNAME(sc), drain ? "enable" : "disable");
6032 		break;
6033 	}
6034 
6035 	return err;
6036 }
6037 
6038 static int
iwx_flush_sta(struct iwx_softc * sc,struct iwx_node * in)6039 iwx_flush_sta(struct iwx_softc *sc, struct iwx_node *in)
6040 {
6041 	int err;
6042 
6043 	IWX_ASSERT_LOCKED(sc);
6044 
6045 	sc->sc_flags |= IWX_FLAG_TXFLUSH;
6046 
6047 	err = iwx_drain_sta(sc, in, 1);
6048 	if (err)
6049 		goto done;
6050 
6051 	err = iwx_flush_sta_tids(sc, IWX_STATION_ID, 0xffff);
6052 	if (err) {
6053 		printf("%s: could not flush Tx path (error %d)\n",
6054 		    DEVNAME(sc), err);
6055 		goto done;
6056 	}
6057 
6058 	/*
6059 	 * XXX-THJ: iwx_wait_tx_queues_empty was here, but it was a nope in the
6060 	 * fc drive rand has has been replaced in OpenBSD.
6061 	 */
6062 
6063 	err = iwx_drain_sta(sc, in, 0);
6064 done:
6065 	sc->sc_flags &= ~IWX_FLAG_TXFLUSH;
6066 	return err;
6067 }
6068 
6069 #define IWX_POWER_KEEP_ALIVE_PERIOD_SEC    25
6070 
6071 static int
iwx_beacon_filter_send_cmd(struct iwx_softc * sc,struct iwx_beacon_filter_cmd * cmd)6072 iwx_beacon_filter_send_cmd(struct iwx_softc *sc,
6073     struct iwx_beacon_filter_cmd *cmd)
6074 {
6075 	return iwx_send_cmd_pdu(sc, IWX_REPLY_BEACON_FILTERING_CMD,
6076 	    0, sizeof(struct iwx_beacon_filter_cmd), cmd);
6077 }
6078 
6079 static int
iwx_update_beacon_abort(struct iwx_softc * sc,struct iwx_node * in,int enable)6080 iwx_update_beacon_abort(struct iwx_softc *sc, struct iwx_node *in, int enable)
6081 {
6082 	struct iwx_beacon_filter_cmd cmd = {
6083 		IWX_BF_CMD_CONFIG_DEFAULTS,
6084 		.bf_enable_beacon_filter = htole32(1),
6085 		.ba_enable_beacon_abort = htole32(enable),
6086 	};
6087 
6088 	if (!sc->sc_bf.bf_enabled)
6089 		return 0;
6090 
6091 	sc->sc_bf.ba_enabled = enable;
6092 	return iwx_beacon_filter_send_cmd(sc, &cmd);
6093 }
6094 
6095 static void
iwx_power_build_cmd(struct iwx_softc * sc,struct iwx_node * in,struct iwx_mac_power_cmd * cmd)6096 iwx_power_build_cmd(struct iwx_softc *sc, struct iwx_node *in,
6097     struct iwx_mac_power_cmd *cmd)
6098 {
6099 	struct ieee80211com *ic = &sc->sc_ic;
6100 	struct ieee80211_node *ni = &in->in_ni;
6101 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
6102 	int dtim_period, dtim_msec, keep_alive;
6103 
6104 	cmd->id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id,
6105 	    in->in_color));
6106 	if (vap->iv_dtim_period)
6107 		dtim_period = vap->iv_dtim_period;
6108 	else
6109 		dtim_period = 1;
6110 
6111 	/*
6112 	 * Regardless of power management state the driver must set
6113 	 * keep alive period. FW will use it for sending keep alive NDPs
6114 	 * immediately after association. Check that keep alive period
6115 	 * is at least 3 * DTIM.
6116 	 */
6117 	dtim_msec = dtim_period * ni->ni_intval;
6118 	keep_alive = MAX(3 * dtim_msec, 1000 * IWX_POWER_KEEP_ALIVE_PERIOD_SEC);
6119 	keep_alive = roundup(keep_alive, 1000) / 1000;
6120 	cmd->keep_alive_seconds = htole16(keep_alive);
6121 
6122 	if (ic->ic_opmode != IEEE80211_M_MONITOR)
6123 		cmd->flags = htole16(IWX_POWER_FLAGS_POWER_SAVE_ENA_MSK);
6124 }
6125 
6126 static int
iwx_power_mac_update_mode(struct iwx_softc * sc,struct iwx_node * in)6127 iwx_power_mac_update_mode(struct iwx_softc *sc, struct iwx_node *in)
6128 {
6129 	int err;
6130 	int ba_enable;
6131 	struct iwx_mac_power_cmd cmd;
6132 
6133 	memset(&cmd, 0, sizeof(cmd));
6134 
6135 	iwx_power_build_cmd(sc, in, &cmd);
6136 
6137 	err = iwx_send_cmd_pdu(sc, IWX_MAC_PM_POWER_TABLE, 0,
6138 	    sizeof(cmd), &cmd);
6139 	if (err != 0)
6140 		return err;
6141 
6142 	ba_enable = !!(cmd.flags &
6143 	    htole16(IWX_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
6144 	return iwx_update_beacon_abort(sc, in, ba_enable);
6145 }
6146 
6147 static int
iwx_power_update_device(struct iwx_softc * sc)6148 iwx_power_update_device(struct iwx_softc *sc)
6149 {
6150 	struct iwx_device_power_cmd cmd = { };
6151 	struct ieee80211com *ic = &sc->sc_ic;
6152 
6153 	if (ic->ic_opmode != IEEE80211_M_MONITOR)
6154 		cmd.flags = htole16(IWX_DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK);
6155 
6156 	return iwx_send_cmd_pdu(sc,
6157 	    IWX_POWER_TABLE_CMD, 0, sizeof(cmd), &cmd);
6158 }
6159 #if 0
6160 static int
6161 iwx_enable_beacon_filter(struct iwx_softc *sc, struct iwx_node *in)
6162 {
6163 	struct iwx_beacon_filter_cmd cmd = {
6164 		IWX_BF_CMD_CONFIG_DEFAULTS,
6165 		.bf_enable_beacon_filter = htole32(1),
6166 		.ba_enable_beacon_abort = htole32(sc->sc_bf.ba_enabled),
6167 	};
6168 	int err;
6169 
6170 	err = iwx_beacon_filter_send_cmd(sc, &cmd);
6171 	if (err == 0)
6172 		sc->sc_bf.bf_enabled = 1;
6173 
6174 	return err;
6175 }
6176 #endif
6177 static int
iwx_disable_beacon_filter(struct iwx_softc * sc)6178 iwx_disable_beacon_filter(struct iwx_softc *sc)
6179 {
6180 	struct iwx_beacon_filter_cmd cmd;
6181 	int err;
6182 
6183 	memset(&cmd, 0, sizeof(cmd));
6184 
6185 	err = iwx_beacon_filter_send_cmd(sc, &cmd);
6186 	if (err == 0)
6187 		sc->sc_bf.bf_enabled = 0;
6188 
6189 	return err;
6190 }
6191 
6192 static int
iwx_add_sta_cmd(struct iwx_softc * sc,struct iwx_node * in,int update)6193 iwx_add_sta_cmd(struct iwx_softc *sc, struct iwx_node *in, int update)
6194 {
6195 	struct iwx_add_sta_cmd add_sta_cmd;
6196 	int err, i;
6197 	uint32_t status, aggsize;
6198 	const uint32_t max_aggsize = (IWX_STA_FLG_MAX_AGG_SIZE_64K >>
6199 		    IWX_STA_FLG_MAX_AGG_SIZE_SHIFT);
6200 	struct ieee80211com *ic = &sc->sc_ic;
6201 	struct ieee80211_node *ni = &in->in_ni;
6202 	struct ieee80211_htrateset *htrs = &ni->ni_htrates;
6203 
6204 	if (!update && (sc->sc_flags & IWX_FLAG_STA_ACTIVE))
6205 		panic("STA already added");
6206 
6207 	memset(&add_sta_cmd, 0, sizeof(add_sta_cmd));
6208 
6209 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
6210 		add_sta_cmd.sta_id = IWX_MONITOR_STA_ID;
6211 		add_sta_cmd.station_type = IWX_STA_GENERAL_PURPOSE;
6212 	} else {
6213 		add_sta_cmd.sta_id = IWX_STATION_ID;
6214 		add_sta_cmd.station_type = IWX_STA_LINK;
6215 	}
6216 	add_sta_cmd.mac_id_n_color
6217 	    = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
6218 	if (!update) {
6219 		if (ic->ic_opmode == IEEE80211_M_MONITOR)
6220 			IEEE80211_ADDR_COPY(&add_sta_cmd.addr,
6221 			    etheranyaddr);
6222 		else
6223 			IEEE80211_ADDR_COPY(&add_sta_cmd.addr,
6224 			    in->in_macaddr);
6225 	}
6226 	DPRINTF(("%s: add_sta_cmd.addr=%s\n", __func__,
6227 	    ether_sprintf(add_sta_cmd.addr)));
6228 	add_sta_cmd.add_modify = update ? 1 : 0;
6229 	add_sta_cmd.station_flags_msk
6230 	    |= htole32(IWX_STA_FLG_FAT_EN_MSK | IWX_STA_FLG_MIMO_EN_MSK);
6231 
6232 	if (in->in_ni.ni_flags & IEEE80211_NODE_HT) {
6233 		add_sta_cmd.station_flags_msk
6234 		    |= htole32(IWX_STA_FLG_MAX_AGG_SIZE_MSK |
6235 		    IWX_STA_FLG_AGG_MPDU_DENS_MSK);
6236 
6237 		if (iwx_mimo_enabled(sc)) {
6238 			if (ni->ni_flags & IEEE80211_NODE_VHT) {
6239 				add_sta_cmd.station_flags |=
6240 				    htole32(IWX_STA_FLG_MIMO_EN_MIMO2);
6241 			} else {
6242 				int hasmimo = 0;
6243 				for (i = 0; i < htrs->rs_nrates; i++) {
6244 					if (htrs->rs_rates[i] > 7) {
6245 						hasmimo = 1;
6246 						break;
6247 					}
6248 				}
6249 				if (hasmimo) {
6250 					add_sta_cmd.station_flags |=
6251 					    htole32(IWX_STA_FLG_MIMO_EN_MIMO2);
6252 				}
6253 			}
6254 		}
6255 
6256 		if (ni->ni_flags & IEEE80211_NODE_HT &&
6257 		    IEEE80211_IS_CHAN_HT40(ni->ni_chan)) {
6258 			add_sta_cmd.station_flags |= htole32(
6259 			    IWX_STA_FLG_FAT_EN_40MHZ);
6260 		}
6261 
6262 
6263 		if (ni->ni_flags & IEEE80211_NODE_VHT) {
6264 			if (IEEE80211_IS_CHAN_VHT80(ni->ni_chan)) {
6265 				add_sta_cmd.station_flags |= htole32(
6266 				    IWX_STA_FLG_FAT_EN_80MHZ);
6267 			}
6268 			// XXX-misha: TODO get real ampdu size
6269 			aggsize = max_aggsize;
6270 		} else {
6271 			aggsize = _IEEE80211_MASKSHIFT(le16toh(ni->ni_htparam),
6272 			    IEEE80211_HTCAP_MAXRXAMPDU);
6273 		}
6274 
6275 		if (aggsize > max_aggsize)
6276 			aggsize = max_aggsize;
6277 		add_sta_cmd.station_flags |= htole32((aggsize <<
6278 		    IWX_STA_FLG_MAX_AGG_SIZE_SHIFT) &
6279 		    IWX_STA_FLG_MAX_AGG_SIZE_MSK);
6280 
6281 		switch (_IEEE80211_MASKSHIFT(le16toh(ni->ni_htparam),
6282 		    IEEE80211_HTCAP_MPDUDENSITY)) {
6283 		case IEEE80211_HTCAP_MPDUDENSITY_2:
6284 			add_sta_cmd.station_flags
6285 			    |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_2US);
6286 			break;
6287 		case IEEE80211_HTCAP_MPDUDENSITY_4:
6288 			add_sta_cmd.station_flags
6289 			    |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_4US);
6290 			break;
6291 		case IEEE80211_HTCAP_MPDUDENSITY_8:
6292 			add_sta_cmd.station_flags
6293 			    |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_8US);
6294 			break;
6295 		case IEEE80211_HTCAP_MPDUDENSITY_16:
6296 			add_sta_cmd.station_flags
6297 			    |= htole32(IWX_STA_FLG_AGG_MPDU_DENS_16US);
6298 			break;
6299 		default:
6300 			break;
6301 		}
6302 	}
6303 
6304 	status = IWX_ADD_STA_SUCCESS;
6305 	err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA, sizeof(add_sta_cmd),
6306 	    &add_sta_cmd, &status);
6307 	if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS)
6308 		err = EIO;
6309 
6310 	return err;
6311 }
6312 
6313 static int
iwx_rm_sta_cmd(struct iwx_softc * sc,struct iwx_node * in)6314 iwx_rm_sta_cmd(struct iwx_softc *sc, struct iwx_node *in)
6315 {
6316 	struct ieee80211com *ic = &sc->sc_ic;
6317 	struct iwx_rm_sta_cmd rm_sta_cmd;
6318 	int err;
6319 
6320 	if ((sc->sc_flags & IWX_FLAG_STA_ACTIVE) == 0)
6321 		panic("sta already removed");
6322 
6323 	memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
6324 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
6325 		rm_sta_cmd.sta_id = IWX_MONITOR_STA_ID;
6326 	else
6327 		rm_sta_cmd.sta_id = IWX_STATION_ID;
6328 
6329 	err = iwx_send_cmd_pdu(sc, IWX_REMOVE_STA, 0, sizeof(rm_sta_cmd),
6330 	    &rm_sta_cmd);
6331 
6332 	return err;
6333 }
6334 
6335 static int
iwx_rm_sta(struct iwx_softc * sc,struct iwx_node * in)6336 iwx_rm_sta(struct iwx_softc *sc, struct iwx_node *in)
6337 {
6338 	int err, i, cmd_ver;
6339 
6340 	err = iwx_flush_sta(sc, in);
6341 	if (err) {
6342 		printf("%s: could not flush Tx path (error %d)\n",
6343 		    DEVNAME(sc), err);
6344 		return err;
6345 	}
6346 
6347 	/*
6348 	 * New SCD_QUEUE_CONFIG API requires explicit queue removal
6349 	 * before a station gets removed.
6350 	 */
6351 	cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
6352 	    IWX_SCD_QUEUE_CONFIG_CMD);
6353 	if (cmd_ver != 0 && cmd_ver != IWX_FW_CMD_VER_UNKNOWN) {
6354 		err = iwx_disable_mgmt_queue(sc);
6355 		if (err)
6356 			return err;
6357 		for (i = IWX_FIRST_AGG_TX_QUEUE;
6358 		    i < IWX_LAST_AGG_TX_QUEUE; i++) {
6359 			struct iwx_tx_ring *ring = &sc->txq[i];
6360 			if ((sc->qenablemsk & (1 << i)) == 0)
6361 				continue;
6362 			err = iwx_disable_txq(sc, IWX_STATION_ID,
6363 			    ring->qid, ring->tid);
6364 			if (err) {
6365 				printf("%s: could not disable Tx queue %d "
6366 				    "(error %d)\n", DEVNAME(sc), ring->qid,
6367 				    err);
6368 				return err;
6369 			}
6370 		}
6371 	}
6372 
6373 	err = iwx_rm_sta_cmd(sc, in);
6374 	if (err) {
6375 		printf("%s: could not remove STA (error %d)\n",
6376 		    DEVNAME(sc), err);
6377 		return err;
6378 	}
6379 
6380 	in->in_flags = 0;
6381 
6382 	sc->sc_rx_ba_sessions = 0;
6383 	sc->ba_rx.start_tidmask = 0;
6384 	sc->ba_rx.stop_tidmask = 0;
6385 	memset(sc->aggqid, 0, sizeof(sc->aggqid));
6386 	sc->ba_tx.start_tidmask = 0;
6387 	sc->ba_tx.stop_tidmask = 0;
6388 	for (i = IWX_FIRST_AGG_TX_QUEUE; i < IWX_LAST_AGG_TX_QUEUE; i++)
6389 		sc->qenablemsk &= ~(1 << i);
6390 
6391 #if 0
6392 	for (i = 0; i < IEEE80211_NUM_TID; i++) {
6393 		struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[i];
6394 		if (ba->ba_state != IEEE80211_BA_AGREED)
6395 			continue;
6396 		ieee80211_delba_request(ic, ni, 0, 1, i);
6397 	}
6398 #endif
6399 	/* Clear ampdu rx state (GOS-1525) */
6400 	for (i = 0; i < IWX_MAX_TID_COUNT; i++) {
6401 		struct iwx_rx_ba *ba = &sc->ni_rx_ba[i];
6402 		ba->ba_flags = 0;
6403 	}
6404 
6405 	return 0;
6406 }
6407 
6408 static uint8_t
iwx_umac_scan_fill_channels(struct iwx_softc * sc,struct iwx_scan_channel_cfg_umac * chan,size_t chan_nitems,int n_ssids,uint32_t channel_cfg_flags)6409 iwx_umac_scan_fill_channels(struct iwx_softc *sc,
6410     struct iwx_scan_channel_cfg_umac *chan, size_t chan_nitems,
6411     int n_ssids, uint32_t channel_cfg_flags)
6412 {
6413 	struct ieee80211com *ic = &sc->sc_ic;
6414 	struct ieee80211_scan_state *ss = ic->ic_scan;
6415 	struct ieee80211_channel *c;
6416 	uint8_t nchan;
6417 	int j;
6418 
6419 	for (nchan = j = 0;
6420 	    j < ss->ss_last &&
6421 	    nchan < sc->sc_capa_n_scan_channels;
6422 	    j++) {
6423 		uint8_t channel_num;
6424 
6425 		c = ss->ss_chans[j];
6426 		channel_num = ieee80211_mhz2ieee(c->ic_freq, 0);
6427 		if (isset(sc->sc_ucode_api,
6428 		    IWX_UCODE_TLV_API_SCAN_EXT_CHAN_VER)) {
6429 			chan->v2.channel_num = channel_num;
6430 			if (IEEE80211_IS_CHAN_2GHZ(c))
6431 				chan->v2.band = IWX_PHY_BAND_24;
6432 			else
6433 				chan->v2.band = IWX_PHY_BAND_5;
6434 			chan->v2.iter_count = 1;
6435 			chan->v2.iter_interval = 0;
6436 		} else {
6437 			chan->v1.channel_num = channel_num;
6438 			chan->v1.iter_count = 1;
6439 			chan->v1.iter_interval = htole16(0);
6440 		}
6441 		chan->flags |= htole32(channel_cfg_flags);
6442 		chan++;
6443 		nchan++;
6444 	}
6445 
6446 	return nchan;
6447 }
6448 
6449 static int
iwx_fill_probe_req(struct iwx_softc * sc,struct iwx_scan_probe_req * preq)6450 iwx_fill_probe_req(struct iwx_softc *sc, struct iwx_scan_probe_req *preq)
6451 {
6452 	struct ieee80211com *ic = &sc->sc_ic;
6453 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
6454 	struct ieee80211_frame *wh = (struct ieee80211_frame *)preq->buf;
6455 	struct ieee80211_rateset *rs;
6456 	size_t remain = sizeof(preq->buf);
6457 	uint8_t *frm, *pos;
6458 
6459 	memset(preq, 0, sizeof(*preq));
6460 
6461 	if (remain < sizeof(*wh) + 2)
6462 		return ENOBUFS;
6463 
6464 	/*
6465 	 * Build a probe request frame.  Most of the following code is a
6466 	 * copy & paste of what is done in net80211.
6467 	 */
6468 	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
6469 	    IEEE80211_FC0_SUBTYPE_PROBE_REQ;
6470 	wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
6471 	IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr);
6472 	IEEE80211_ADDR_COPY(wh->i_addr2, vap ? vap->iv_myaddr : ic->ic_macaddr);
6473 	IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr);
6474 	*(uint16_t *)&wh->i_dur[0] = 0;	/* filled by HW */
6475 	*(uint16_t *)&wh->i_seq[0] = 0;	/* filled by HW */
6476 
6477 	frm = (uint8_t *)(wh + 1);
6478 	*frm++ = IEEE80211_ELEMID_SSID;
6479 	*frm++ = 0;
6480 	/* hardware inserts SSID */
6481 
6482 	/* Tell the firmware where the MAC header is. */
6483 	preq->mac_header.offset = 0;
6484 	preq->mac_header.len = htole16(frm - (uint8_t *)wh);
6485 	remain -= frm - (uint8_t *)wh;
6486 
6487 	/* Fill in 2GHz IEs and tell firmware where they are. */
6488 	rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
6489 	if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
6490 		if (remain < 4 + rs->rs_nrates)
6491 			return ENOBUFS;
6492 	} else if (remain < 2 + rs->rs_nrates)
6493 		return ENOBUFS;
6494 	preq->band_data[0].offset = htole16(frm - (uint8_t *)wh);
6495 	pos = frm;
6496 	frm = ieee80211_add_rates(frm, rs);
6497 	if (rs->rs_nrates > IEEE80211_RATE_SIZE)
6498 		frm = ieee80211_add_xrates(frm, rs);
6499 	remain -= frm - pos;
6500 
6501 	if (isset(sc->sc_enabled_capa,
6502 	    IWX_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT)) {
6503 		if (remain < 3)
6504 			return ENOBUFS;
6505 		*frm++ = IEEE80211_ELEMID_DSPARMS;
6506 		*frm++ = 1;
6507 		*frm++ = 0;
6508 		remain -= 3;
6509 	}
6510 	preq->band_data[0].len = htole16(frm - pos);
6511 
6512 	if (sc->sc_nvm.sku_cap_band_52GHz_enable) {
6513 		/* Fill in 5GHz IEs. */
6514 		rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
6515 		if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
6516 			if (remain < 4 + rs->rs_nrates)
6517 				return ENOBUFS;
6518 		} else if (remain < 2 + rs->rs_nrates)
6519 			return ENOBUFS;
6520 		preq->band_data[1].offset = htole16(frm - (uint8_t *)wh);
6521 		pos = frm;
6522 		frm = ieee80211_add_rates(frm, rs);
6523 		if (rs->rs_nrates > IEEE80211_RATE_SIZE)
6524 			frm = ieee80211_add_xrates(frm, rs);
6525 		preq->band_data[1].len = htole16(frm - pos);
6526 		remain -= frm - pos;
6527 		if (vap->iv_vht_flags & IEEE80211_FVHT_VHT) {
6528 			if (remain < 14)
6529 				return ENOBUFS;
6530 			frm = ieee80211_add_vhtcap(frm, vap->iv_bss);
6531 			remain -= frm - pos;
6532 			preq->band_data[1].len = htole16(frm - pos);
6533 		}
6534 	}
6535 
6536 	/* Send 11n IEs on both 2GHz and 5GHz bands. */
6537 	preq->common_data.offset = htole16(frm - (uint8_t *)wh);
6538 	pos = frm;
6539 	if (vap->iv_flags_ht & IEEE80211_FHT_HT) {
6540 		if (remain < 28)
6541 			return ENOBUFS;
6542 		frm = ieee80211_add_htcap(frm, vap->iv_bss);
6543 		/* XXX add WME info? */
6544 		remain -= frm - pos;
6545 	}
6546 
6547 	preq->common_data.len = htole16(frm - pos);
6548 
6549 	return 0;
6550 }
6551 
6552 static int
iwx_config_umac_scan_reduced(struct iwx_softc * sc)6553 iwx_config_umac_scan_reduced(struct iwx_softc *sc)
6554 {
6555 	struct iwx_scan_config scan_cfg;
6556 	struct iwx_host_cmd hcmd = {
6557 		.id = iwx_cmd_id(IWX_SCAN_CFG_CMD, IWX_LONG_GROUP, 0),
6558 		.len[0] = sizeof(scan_cfg),
6559 		.data[0] = &scan_cfg,
6560 		.flags = 0,
6561 	};
6562 	int cmdver;
6563 
6564 	if (!isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_REDUCED_SCAN_CONFIG)) {
6565 		printf("%s: firmware does not support reduced scan config\n",
6566 		    DEVNAME(sc));
6567 		return ENOTSUP;
6568 	}
6569 
6570 	memset(&scan_cfg, 0, sizeof(scan_cfg));
6571 
6572 	/*
6573 	 * SCAN_CFG version >= 5 implies that the broadcast
6574 	 * STA ID field is deprecated.
6575 	 */
6576 	cmdver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP, IWX_SCAN_CFG_CMD);
6577 	if (cmdver == IWX_FW_CMD_VER_UNKNOWN || cmdver < 5)
6578 		scan_cfg.bcast_sta_id = 0xff;
6579 
6580 	scan_cfg.tx_chains = htole32(iwx_fw_valid_tx_ant(sc));
6581 	scan_cfg.rx_chains = htole32(iwx_fw_valid_rx_ant(sc));
6582 
6583 	return iwx_send_cmd(sc, &hcmd);
6584 }
6585 
6586 static uint16_t
iwx_scan_umac_flags_v2(struct iwx_softc * sc,int bgscan)6587 iwx_scan_umac_flags_v2(struct iwx_softc *sc, int bgscan)
6588 {
6589 	struct ieee80211com *ic = &sc->sc_ic;
6590 	struct ieee80211_scan_state *ss = ic->ic_scan;
6591 	uint16_t flags = 0;
6592 
6593 	if (ss->ss_nssid == 0) {
6594 		DPRINTF(("%s: Passive scan started\n", __func__));
6595 		flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE;
6596 	}
6597 
6598 	flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_PASS_ALL;
6599 	flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_NTFY_ITER_COMPLETE;
6600 	flags |= IWX_UMAC_SCAN_GEN_FLAGS_V2_ADAPTIVE_DWELL;
6601 
6602 	return flags;
6603 }
6604 
6605 #define IWX_SCAN_DWELL_ACTIVE		10
6606 #define IWX_SCAN_DWELL_PASSIVE		110
6607 
6608 /* adaptive dwell max budget time [TU] for full scan */
6609 #define IWX_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
6610 /* adaptive dwell max budget time [TU] for directed scan */
6611 #define IWX_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN 100
6612 /* adaptive dwell default high band APs number */
6613 #define IWX_SCAN_ADWELL_DEFAULT_HB_N_APS 8
6614 /* adaptive dwell default low band APs number */
6615 #define IWX_SCAN_ADWELL_DEFAULT_LB_N_APS 2
6616 /* adaptive dwell default APs number in social channels (1, 6, 11) */
6617 #define IWX_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10
6618 /* adaptive dwell number of APs override for p2p friendly GO channels */
6619 #define IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY 10
6620 /* adaptive dwell number of APs override for social channels */
6621 #define IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS 2
6622 
6623 static void
iwx_scan_umac_dwell_v10(struct iwx_softc * sc,struct iwx_scan_general_params_v10 * general_params,int bgscan)6624 iwx_scan_umac_dwell_v10(struct iwx_softc *sc,
6625     struct iwx_scan_general_params_v10 *general_params, int bgscan)
6626 {
6627 	uint32_t suspend_time, max_out_time;
6628 	uint8_t active_dwell, passive_dwell;
6629 
6630 	active_dwell = IWX_SCAN_DWELL_ACTIVE;
6631 	passive_dwell = IWX_SCAN_DWELL_PASSIVE;
6632 
6633 	general_params->adwell_default_social_chn =
6634 		IWX_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL;
6635 	general_params->adwell_default_2g = IWX_SCAN_ADWELL_DEFAULT_LB_N_APS;
6636 	general_params->adwell_default_5g = IWX_SCAN_ADWELL_DEFAULT_HB_N_APS;
6637 
6638 	if (bgscan)
6639 		general_params->adwell_max_budget =
6640 			htole16(IWX_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN);
6641 	else
6642 		general_params->adwell_max_budget =
6643 			htole16(IWX_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN);
6644 
6645 	general_params->scan_priority = htole32(IWX_SCAN_PRIORITY_EXT_6);
6646 	if (bgscan) {
6647 		max_out_time = htole32(120);
6648 		suspend_time = htole32(120);
6649 	} else {
6650 		max_out_time = htole32(0);
6651 		suspend_time = htole32(0);
6652 	}
6653 	general_params->max_out_of_time[IWX_SCAN_LB_LMAC_IDX] =
6654 		htole32(max_out_time);
6655 	general_params->suspend_time[IWX_SCAN_LB_LMAC_IDX] =
6656 		htole32(suspend_time);
6657 	general_params->max_out_of_time[IWX_SCAN_HB_LMAC_IDX] =
6658 		htole32(max_out_time);
6659 	general_params->suspend_time[IWX_SCAN_HB_LMAC_IDX] =
6660 		htole32(suspend_time);
6661 
6662 	general_params->active_dwell[IWX_SCAN_LB_LMAC_IDX] = active_dwell;
6663 	general_params->passive_dwell[IWX_SCAN_LB_LMAC_IDX] = passive_dwell;
6664 	general_params->active_dwell[IWX_SCAN_HB_LMAC_IDX] = active_dwell;
6665 	general_params->passive_dwell[IWX_SCAN_HB_LMAC_IDX] = passive_dwell;
6666 }
6667 
6668 static void
iwx_scan_umac_fill_general_p_v10(struct iwx_softc * sc,struct iwx_scan_general_params_v10 * gp,uint16_t gen_flags,int bgscan)6669 iwx_scan_umac_fill_general_p_v10(struct iwx_softc *sc,
6670     struct iwx_scan_general_params_v10 *gp, uint16_t gen_flags, int bgscan)
6671 {
6672 	iwx_scan_umac_dwell_v10(sc, gp, bgscan);
6673 
6674 	gp->flags = htole16(gen_flags);
6675 
6676 	if (gen_flags & IWX_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1)
6677 		gp->num_of_fragments[IWX_SCAN_LB_LMAC_IDX] = 3;
6678 	if (gen_flags & IWX_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2)
6679 		gp->num_of_fragments[IWX_SCAN_HB_LMAC_IDX] = 3;
6680 
6681 	gp->scan_start_mac_id = 0;
6682 }
6683 
6684 static void
iwx_scan_umac_fill_ch_p_v6(struct iwx_softc * sc,struct iwx_scan_channel_params_v6 * cp,uint32_t channel_cfg_flags,int n_ssid)6685 iwx_scan_umac_fill_ch_p_v6(struct iwx_softc *sc,
6686     struct iwx_scan_channel_params_v6 *cp, uint32_t channel_cfg_flags,
6687     int n_ssid)
6688 {
6689 	cp->flags = IWX_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER;
6690 
6691 	cp->count = iwx_umac_scan_fill_channels(sc, cp->channel_config,
6692 	    nitems(cp->channel_config), n_ssid, channel_cfg_flags);
6693 
6694 	cp->n_aps_override[0] = IWX_SCAN_ADWELL_N_APS_GO_FRIENDLY;
6695 	cp->n_aps_override[1] = IWX_SCAN_ADWELL_N_APS_SOCIAL_CHS;
6696 }
6697 
6698 static int
iwx_umac_scan_v14(struct iwx_softc * sc,int bgscan)6699 iwx_umac_scan_v14(struct iwx_softc *sc, int bgscan)
6700 {
6701 	struct ieee80211com *ic = &sc->sc_ic;
6702 	struct ieee80211_scan_state *ss = ic->ic_scan;
6703 	struct iwx_host_cmd hcmd = {
6704 		.id = iwx_cmd_id(IWX_SCAN_REQ_UMAC, IWX_LONG_GROUP, 0),
6705 		.len = { 0, },
6706 		.data = { NULL, },
6707 		.flags = 0,
6708 	};
6709 	struct iwx_scan_req_umac_v14 *cmd = &sc->sc_umac_v14_cmd;
6710 	struct iwx_scan_req_params_v14 *scan_p;
6711 	int err, async = bgscan, n_ssid = 0;
6712 	uint16_t gen_flags;
6713 	uint32_t bitmap_ssid = 0;
6714 
6715 	IWX_ASSERT_LOCKED(sc);
6716 
6717 	bzero(cmd, sizeof(struct iwx_scan_req_umac_v14));
6718 
6719 	scan_p = &cmd->scan_params;
6720 
6721 	cmd->ooc_priority = htole32(IWX_SCAN_PRIORITY_EXT_6);
6722 	cmd->uid = htole32(0);
6723 
6724 	gen_flags = iwx_scan_umac_flags_v2(sc, bgscan);
6725 	iwx_scan_umac_fill_general_p_v10(sc, &scan_p->general_params,
6726 	    gen_flags, bgscan);
6727 
6728 	scan_p->periodic_params.schedule[0].interval = htole16(0);
6729 	scan_p->periodic_params.schedule[0].iter_count = 1;
6730 
6731 	err = iwx_fill_probe_req(sc, &scan_p->probe_params.preq);
6732 	if (err) {
6733 		printf("%s: iwx_fill_probe_req failed (error %d)\n", __func__,
6734 		    err);
6735 		return err;
6736 	}
6737 
6738 	for (int i=0; i < ss->ss_nssid; i++) {
6739 		scan_p->probe_params.direct_scan[i].id = IEEE80211_ELEMID_SSID;
6740 		scan_p->probe_params.direct_scan[i].len =
6741 		    MIN(ss->ss_ssid[i].len, IEEE80211_NWID_LEN);
6742 		DPRINTF(("%s: Active scan started for ssid ", __func__));
6743 		memcpy(scan_p->probe_params.direct_scan[i].ssid,
6744 		    ss->ss_ssid[i].ssid, ss->ss_ssid[i].len);
6745 		n_ssid++;
6746 		bitmap_ssid |= (1 << i);
6747 	}
6748 	DPRINTF(("%s: bitmap_ssid=0x%x\n", __func__, bitmap_ssid));
6749 
6750 	iwx_scan_umac_fill_ch_p_v6(sc, &scan_p->channel_params, bitmap_ssid,
6751 	    n_ssid);
6752 
6753 	hcmd.len[0] = sizeof(*cmd);
6754 	hcmd.data[0] = (void *)cmd;
6755 	hcmd.flags |= async ? IWX_CMD_ASYNC : 0;
6756 
6757 	err = iwx_send_cmd(sc, &hcmd);
6758 	return err;
6759 }
6760 
6761 static void
iwx_mcc_update(struct iwx_softc * sc,struct iwx_mcc_chub_notif * notif)6762 iwx_mcc_update(struct iwx_softc *sc, struct iwx_mcc_chub_notif *notif)
6763 {
6764 	char alpha2[3];
6765 
6766 	snprintf(alpha2, sizeof(alpha2), "%c%c",
6767 	    (le16toh(notif->mcc) & 0xff00) >> 8, le16toh(notif->mcc) & 0xff);
6768 
6769 	IWX_DPRINTF(sc, IWX_DEBUG_FW, "%s: firmware has detected regulatory domain '%s' "
6770 		    "(0x%x)\n", DEVNAME(sc), alpha2, le16toh(notif->mcc));
6771 
6772 	/* TODO: Schedule a task to send MCC_UPDATE_CMD? */
6773 }
6774 
6775 uint8_t
iwx_ridx2rate(struct ieee80211_rateset * rs,int ridx)6776 iwx_ridx2rate(struct ieee80211_rateset *rs, int ridx)
6777 {
6778 	int i;
6779 	uint8_t rval;
6780 
6781 	for (i = 0; i < rs->rs_nrates; i++) {
6782 		rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL);
6783 		if (rval == iwx_rates[ridx].rate)
6784 			return rs->rs_rates[i];
6785 	}
6786 
6787 	return 0;
6788 }
6789 
6790 static int
iwx_rval2ridx(int rval)6791 iwx_rval2ridx(int rval)
6792 {
6793 	int ridx;
6794 
6795 	for (ridx = 0; ridx < nitems(iwx_rates); ridx++) {
6796 		if (iwx_rates[ridx].plcp == IWX_RATE_INVM_PLCP)
6797 			continue;
6798 		if (rval == iwx_rates[ridx].rate)
6799 			break;
6800 	}
6801 
6802        return ridx;
6803 }
6804 
6805 static void
iwx_ack_rates(struct iwx_softc * sc,struct iwx_node * in,int * cck_rates,int * ofdm_rates)6806 iwx_ack_rates(struct iwx_softc *sc, struct iwx_node *in, int *cck_rates,
6807     int *ofdm_rates)
6808 {
6809 	struct ieee80211_node *ni = &in->in_ni;
6810 	struct ieee80211_rateset *rs = &ni->ni_rates;
6811 	int lowest_present_ofdm = -1;
6812 	int lowest_present_cck = -1;
6813 	uint8_t cck = 0;
6814 	uint8_t ofdm = 0;
6815 	int i;
6816 
6817 	if (ni->ni_chan == IEEE80211_CHAN_ANYC ||
6818 	    IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) {
6819 		for (i = IWX_FIRST_CCK_RATE; i < IWX_FIRST_OFDM_RATE; i++) {
6820 			if ((iwx_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0)
6821 				continue;
6822 			cck |= (1 << i);
6823 			if (lowest_present_cck == -1 || lowest_present_cck > i)
6824 				lowest_present_cck = i;
6825 		}
6826 	}
6827 	for (i = IWX_FIRST_OFDM_RATE; i <= IWX_LAST_NON_HT_RATE; i++) {
6828 		if ((iwx_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0)
6829 			continue;
6830 		ofdm |= (1 << (i - IWX_FIRST_OFDM_RATE));
6831 		if (lowest_present_ofdm == -1 || lowest_present_ofdm > i)
6832 			lowest_present_ofdm = i;
6833 	}
6834 
6835 	/*
6836 	 * Now we've got the basic rates as bitmaps in the ofdm and cck
6837 	 * variables. This isn't sufficient though, as there might not
6838 	 * be all the right rates in the bitmap. E.g. if the only basic
6839 	 * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps
6840 	 * and 6 Mbps because the 802.11-2007 standard says in 9.6:
6841 	 *
6842 	 *    [...] a STA responding to a received frame shall transmit
6843 	 *    its Control Response frame [...] at the highest rate in the
6844 	 *    BSSBasicRateSet parameter that is less than or equal to the
6845 	 *    rate of the immediately previous frame in the frame exchange
6846 	 *    sequence ([...]) and that is of the same modulation class
6847 	 *    ([...]) as the received frame. If no rate contained in the
6848 	 *    BSSBasicRateSet parameter meets these conditions, then the
6849 	 *    control frame sent in response to a received frame shall be
6850 	 *    transmitted at the highest mandatory rate of the PHY that is
6851 	 *    less than or equal to the rate of the received frame, and
6852 	 *    that is of the same modulation class as the received frame.
6853 	 *
6854 	 * As a consequence, we need to add all mandatory rates that are
6855 	 * lower than all of the basic rates to these bitmaps.
6856 	 */
6857 
6858 	if (IWX_RATE_24M_INDEX < lowest_present_ofdm)
6859 		ofdm |= IWX_RATE_BIT_MSK(24) >> IWX_FIRST_OFDM_RATE;
6860 	if (IWX_RATE_12M_INDEX < lowest_present_ofdm)
6861 		ofdm |= IWX_RATE_BIT_MSK(12) >> IWX_FIRST_OFDM_RATE;
6862 	/* 6M already there or needed so always add */
6863 	ofdm |= IWX_RATE_BIT_MSK(6) >> IWX_FIRST_OFDM_RATE;
6864 
6865 	/*
6866 	 * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP.
6867 	 * Note, however:
6868 	 *  - if no CCK rates are basic, it must be ERP since there must
6869 	 *    be some basic rates at all, so they're OFDM => ERP PHY
6870 	 *    (or we're in 5 GHz, and the cck bitmap will never be used)
6871 	 *  - if 11M is a basic rate, it must be ERP as well, so add 5.5M
6872 	 *  - if 5.5M is basic, 1M and 2M are mandatory
6873 	 *  - if 2M is basic, 1M is mandatory
6874 	 *  - if 1M is basic, that's the only valid ACK rate.
6875 	 * As a consequence, it's not as complicated as it sounds, just add
6876 	 * any lower rates to the ACK rate bitmap.
6877 	 */
6878 	if (IWX_RATE_11M_INDEX < lowest_present_cck)
6879 		cck |= IWX_RATE_BIT_MSK(11) >> IWX_FIRST_CCK_RATE;
6880 	if (IWX_RATE_5M_INDEX < lowest_present_cck)
6881 		cck |= IWX_RATE_BIT_MSK(5) >> IWX_FIRST_CCK_RATE;
6882 	if (IWX_RATE_2M_INDEX < lowest_present_cck)
6883 		cck |= IWX_RATE_BIT_MSK(2) >> IWX_FIRST_CCK_RATE;
6884 	/* 1M already there or needed so always add */
6885 	cck |= IWX_RATE_BIT_MSK(1) >> IWX_FIRST_CCK_RATE;
6886 
6887 	*cck_rates = cck;
6888 	*ofdm_rates = ofdm;
6889 }
6890 
6891 static void
iwx_mac_ctxt_cmd_common(struct iwx_softc * sc,struct iwx_node * in,struct iwx_mac_ctx_cmd * cmd,uint32_t action)6892 iwx_mac_ctxt_cmd_common(struct iwx_softc *sc, struct iwx_node *in,
6893     struct iwx_mac_ctx_cmd *cmd, uint32_t action)
6894 {
6895 #define IWX_EXP2(x)	((1 << (x)) - 1)	/* CWmin = 2^ECWmin - 1 */
6896 	struct ieee80211com *ic = &sc->sc_ic;
6897 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
6898 	struct ieee80211_node *ni = vap->iv_bss;
6899 	int cck_ack_rates, ofdm_ack_rates;
6900 
6901 	cmd->id_and_color = htole32(IWX_FW_CMD_ID_AND_COLOR(in->in_id,
6902 	    in->in_color));
6903 	cmd->action = htole32(action);
6904 
6905 	if (action == IWX_FW_CTXT_ACTION_REMOVE)
6906 		return;
6907 
6908 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
6909 		cmd->mac_type = htole32(IWX_FW_MAC_TYPE_LISTENER);
6910 	else if (ic->ic_opmode == IEEE80211_M_STA)
6911 		cmd->mac_type = htole32(IWX_FW_MAC_TYPE_BSS_STA);
6912 	else
6913 		panic("unsupported operating mode %d", ic->ic_opmode);
6914 	cmd->tsf_id = htole32(IWX_TSF_ID_A);
6915 
6916 	IEEE80211_ADDR_COPY(cmd->node_addr, vap->iv_myaddr);
6917 	DPRINTF(("%s: cmd->node_addr=%s\n", __func__,
6918 	    ether_sprintf(cmd->node_addr)));
6919 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
6920 		IEEE80211_ADDR_COPY(cmd->bssid_addr, etherbroadcastaddr);
6921 		return;
6922 	}
6923 
6924 	IEEE80211_ADDR_COPY(cmd->bssid_addr, in->in_macaddr);
6925 	DPRINTF(("%s: cmd->bssid_addr=%s\n", __func__,
6926 	    ether_sprintf(cmd->bssid_addr)));
6927 	iwx_ack_rates(sc, in, &cck_ack_rates, &ofdm_ack_rates);
6928 	cmd->cck_rates = htole32(cck_ack_rates);
6929 	cmd->ofdm_rates = htole32(ofdm_ack_rates);
6930 
6931 	cmd->cck_short_preamble
6932 	    = htole32((ic->ic_flags & IEEE80211_F_SHPREAMBLE)
6933 	      ? IWX_MAC_FLG_SHORT_PREAMBLE : 0);
6934 	cmd->short_slot
6935 	    = htole32((ic->ic_flags & IEEE80211_F_SHSLOT)
6936 	      ? IWX_MAC_FLG_SHORT_SLOT : 0);
6937 
6938 	struct chanAccParams chp;
6939 	ieee80211_wme_vap_getparams(vap, &chp);
6940 
6941 	for (int i = 0; i < WME_NUM_AC; i++) {
6942 		int txf = iwx_ac_to_tx_fifo[i];
6943 		cmd->ac[txf].cw_min = IWX_EXP2(chp.cap_wmeParams[i].wmep_logcwmin);
6944 		cmd->ac[txf].cw_max = IWX_EXP2(chp.cap_wmeParams[i].wmep_logcwmax);
6945 		cmd->ac[txf].aifsn = chp.cap_wmeParams[i].wmep_aifsn;
6946 		cmd->ac[txf].fifos_mask = (1 << txf);
6947 		cmd->ac[txf].edca_txop = chp.cap_wmeParams[i].wmep_txopLimit;
6948 
6949 		cmd->ac[txf].edca_txop = htole16(chp.cap_wmeParams[i].wmep_txopLimit * 32);
6950 	}
6951 
6952 	if (ni->ni_flags & IEEE80211_NODE_QOS) {
6953 		DPRINTF(("%s: === IEEE80211_NODE_QOS\n", __func__));
6954 		cmd->qos_flags |= htole32(IWX_MAC_QOS_FLG_UPDATE_EDCA);
6955 	}
6956 
6957 	if (ni->ni_flags & IEEE80211_NODE_HT) {
6958 		switch (vap->iv_curhtprotmode) {
6959 		case IEEE80211_HTINFO_OPMODE_PURE:
6960 			break;
6961 		case IEEE80211_HTINFO_OPMODE_PROTOPT:
6962 		case IEEE80211_HTINFO_OPMODE_MIXED:
6963 			cmd->protection_flags |=
6964 			    htole32(IWX_MAC_PROT_FLG_HT_PROT |
6965 			    IWX_MAC_PROT_FLG_FAT_PROT);
6966 			break;
6967 		case IEEE80211_HTINFO_OPMODE_HT20PR:
6968 			if (in->in_phyctxt &&
6969 			    (in->in_phyctxt->sco == IEEE80211_HTINFO_2NDCHAN_ABOVE ||
6970 			    in->in_phyctxt->sco == IEEE80211_HTINFO_2NDCHAN_BELOW)) {
6971 				cmd->protection_flags |=
6972 				    htole32(IWX_MAC_PROT_FLG_HT_PROT |
6973 				    IWX_MAC_PROT_FLG_FAT_PROT);
6974 			}
6975 			break;
6976 		default:
6977 			break;
6978 		}
6979 		cmd->qos_flags |= htole32(IWX_MAC_QOS_FLG_TGN);
6980 		DPRINTF(("%s: === IWX_MAC_QOS_FLG_TGN\n", __func__));
6981 	}
6982 
6983 	if (ic->ic_flags & IEEE80211_F_USEPROT)
6984 		cmd->protection_flags |= htole32(IWX_MAC_PROT_FLG_TGG_PROTECT);
6985 	cmd->filter_flags = htole32(IWX_MAC_FILTER_ACCEPT_GRP);
6986 #undef IWX_EXP2
6987 }
6988 
6989 static void
iwx_mac_ctxt_cmd_fill_sta(struct iwx_softc * sc,struct iwx_node * in,struct iwx_mac_data_sta * sta,int assoc)6990 iwx_mac_ctxt_cmd_fill_sta(struct iwx_softc *sc, struct iwx_node *in,
6991     struct iwx_mac_data_sta *sta, int assoc)
6992 {
6993 	struct ieee80211_node *ni = &in->in_ni;
6994 	struct ieee80211com *ic = &sc->sc_ic;
6995 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
6996 	uint32_t dtim_off;
6997 	uint64_t tsf;
6998 	int dtim_period;
6999 
7000 	dtim_off = ni->ni_dtim_count * ni->ni_intval * IEEE80211_DUR_TU;
7001 	tsf = le64toh(ni->ni_tstamp.tsf);
7002 	dtim_period = vap->iv_dtim_period;
7003 
7004 	sta->is_assoc = htole32(assoc);
7005 
7006 	if (assoc) {
7007 		sta->dtim_time = htole32(tsf + dtim_off);
7008 		sta->dtim_tsf = htole64(tsf + dtim_off);
7009 		// XXX: unset in iwm
7010 		sta->assoc_beacon_arrive_time = 0;
7011 	}
7012 	sta->bi = htole32(ni->ni_intval);
7013 	sta->dtim_interval = htole32(ni->ni_intval * dtim_period);
7014 	sta->data_policy = htole32(0);
7015 	sta->listen_interval = htole32(10);
7016 	sta->assoc_id = htole32(ni->ni_associd);
7017 }
7018 
7019 static int
iwx_mac_ctxt_cmd(struct iwx_softc * sc,struct iwx_node * in,uint32_t action,int assoc)7020 iwx_mac_ctxt_cmd(struct iwx_softc *sc, struct iwx_node *in, uint32_t action,
7021     int assoc)
7022 {
7023 	struct ieee80211com *ic = &sc->sc_ic;
7024 	struct ieee80211_node *ni = &in->in_ni;
7025 	struct iwx_mac_ctx_cmd cmd;
7026 	int active = (sc->sc_flags & IWX_FLAG_MAC_ACTIVE);
7027 
7028 	if (action == IWX_FW_CTXT_ACTION_ADD && active)
7029 		panic("MAC already added");
7030 	if (action == IWX_FW_CTXT_ACTION_REMOVE && !active)
7031 		panic("MAC already removed");
7032 
7033 	memset(&cmd, 0, sizeof(cmd));
7034 
7035 	iwx_mac_ctxt_cmd_common(sc, in, &cmd, action);
7036 
7037 	if (action == IWX_FW_CTXT_ACTION_REMOVE) {
7038 		return iwx_send_cmd_pdu(sc, IWX_MAC_CONTEXT_CMD, 0,
7039 		    sizeof(cmd), &cmd);
7040 	}
7041 
7042 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
7043 		cmd.filter_flags |= htole32(IWX_MAC_FILTER_IN_PROMISC |
7044 		    IWX_MAC_FILTER_IN_CONTROL_AND_MGMT |
7045 		    IWX_MAC_FILTER_ACCEPT_GRP |
7046 		    IWX_MAC_FILTER_IN_BEACON |
7047 		    IWX_MAC_FILTER_IN_PROBE_REQUEST |
7048 		    IWX_MAC_FILTER_IN_CRC32);
7049 	// XXX: dtim period is in vap
7050 	} else if (!assoc || !ni->ni_associd /*|| !ni->ni_dtimperiod*/) {
7051 		/*
7052 		 * Allow beacons to pass through as long as we are not
7053 		 * associated or we do not have dtim period information.
7054 		 */
7055 		cmd.filter_flags |= htole32(IWX_MAC_FILTER_IN_BEACON);
7056 	}
7057 	iwx_mac_ctxt_cmd_fill_sta(sc, in, &cmd.sta, assoc);
7058 	return iwx_send_cmd_pdu(sc, IWX_MAC_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
7059 }
7060 
7061 static int
iwx_clear_statistics(struct iwx_softc * sc)7062 iwx_clear_statistics(struct iwx_softc *sc)
7063 {
7064 	struct iwx_statistics_cmd scmd = {
7065 		.flags = htole32(IWX_STATISTICS_FLG_CLEAR)
7066 	};
7067 	struct iwx_host_cmd cmd = {
7068 		.id = IWX_STATISTICS_CMD,
7069 		.len[0] = sizeof(scmd),
7070 		.data[0] = &scmd,
7071 		.flags = IWX_CMD_WANT_RESP,
7072 		.resp_pkt_len = sizeof(struct iwx_notif_statistics),
7073 	};
7074 	int err;
7075 
7076 	err = iwx_send_cmd(sc, &cmd);
7077 	if (err)
7078 		return err;
7079 
7080 	iwx_free_resp(sc, &cmd);
7081 	return 0;
7082 }
7083 
7084 static int
iwx_scan(struct iwx_softc * sc)7085 iwx_scan(struct iwx_softc *sc)
7086 {
7087 	int err;
7088 	err = iwx_umac_scan_v14(sc, 0);
7089 
7090 	if (err) {
7091 		printf("%s: could not initiate scan\n", DEVNAME(sc));
7092 		return err;
7093 	}
7094 	return 0;
7095 }
7096 
7097 static int
iwx_bgscan(struct ieee80211com * ic)7098 iwx_bgscan(struct ieee80211com *ic)
7099 {
7100 	struct iwx_softc *sc = ic->ic_softc;
7101 	int err;
7102 
7103 	err = iwx_umac_scan_v14(sc, 1);
7104 	if (err) {
7105 		printf("%s: could not initiate scan\n", DEVNAME(sc));
7106 		return err;
7107 	}
7108 	return 0;
7109 }
7110 
7111 static int
iwx_enable_mgmt_queue(struct iwx_softc * sc)7112 iwx_enable_mgmt_queue(struct iwx_softc *sc)
7113 {
7114 	int err;
7115 
7116 	sc->first_data_qid = IWX_DQA_CMD_QUEUE + 1;
7117 
7118 	/*
7119 	 * Non-QoS frames use the "MGMT" TID and queue.
7120 	 * Other TIDs and data queues are reserved for QoS data frames.
7121 	 */
7122 	err = iwx_enable_txq(sc, IWX_STATION_ID, sc->first_data_qid,
7123 	    IWX_MGMT_TID, IWX_TX_RING_COUNT);
7124 	if (err) {
7125 		printf("%s: could not enable Tx queue %d (error %d)\n",
7126 		    DEVNAME(sc), sc->first_data_qid, err);
7127 		return err;
7128 	}
7129 
7130 	return 0;
7131 }
7132 
7133 static int
iwx_disable_mgmt_queue(struct iwx_softc * sc)7134 iwx_disable_mgmt_queue(struct iwx_softc *sc)
7135 {
7136 	int err, cmd_ver;
7137 
7138 	/* Explicit removal is only required with old SCD_QUEUE_CFG command. */
7139 	cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
7140 	    IWX_SCD_QUEUE_CONFIG_CMD);
7141 	if (cmd_ver == 0 || cmd_ver == IWX_FW_CMD_VER_UNKNOWN)
7142 		return 0;
7143 
7144 	sc->first_data_qid = IWX_DQA_CMD_QUEUE + 1;
7145 
7146 	err = iwx_disable_txq(sc, IWX_STATION_ID, sc->first_data_qid,
7147 	    IWX_MGMT_TID);
7148 	if (err) {
7149 		printf("%s: could not disable Tx queue %d (error %d)\n",
7150 		    DEVNAME(sc), sc->first_data_qid, err);
7151 		return err;
7152 	}
7153 
7154 	return 0;
7155 }
7156 
7157 static int
iwx_rs_rval2idx(uint8_t rval)7158 iwx_rs_rval2idx(uint8_t rval)
7159 {
7160 	/* Firmware expects indices which match our 11g rate set. */
7161 	const struct ieee80211_rateset *rs = &ieee80211_std_rateset_11g;
7162 	int i;
7163 
7164 	for (i = 0; i < rs->rs_nrates; i++) {
7165 		if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rval)
7166 			return i;
7167 	}
7168 
7169 	return -1;
7170 }
7171 
7172 static uint16_t
iwx_rs_ht_rates(struct iwx_softc * sc,struct ieee80211_node * ni,int rsidx)7173 iwx_rs_ht_rates(struct iwx_softc *sc, struct ieee80211_node *ni, int rsidx)
7174 {
7175 	uint16_t htrates = 0;
7176 	struct ieee80211_htrateset *htrs = &ni->ni_htrates;
7177 	int i;
7178 
7179 	if (rsidx == IEEE80211_HT_RATESET_SISO) {
7180 		for (i = 0; i < htrs->rs_nrates; i++) {
7181 			if (htrs->rs_rates[i] <= 7)
7182 				htrates |= (1 << htrs->rs_rates[i]);
7183 		}
7184 	} else if (rsidx == IEEE80211_HT_RATESET_MIMO2) {
7185 		for (i = 0; i < htrs->rs_nrates; i++) {
7186 			if (htrs->rs_rates[i] > 7 && htrs->rs_rates[i] <= 15)
7187 				htrates |= (1 << (htrs->rs_rates[i] - 8));
7188 		}
7189 	} else
7190 		panic(("iwx_rs_ht_rates"));
7191 
7192 	IWX_DPRINTF(sc, IWX_DEBUG_TXRATE,
7193 	    "%s:%d rsidx=%i htrates=0x%x\n", __func__, __LINE__, rsidx, htrates);
7194 
7195 	return htrates;
7196 }
7197 
7198 uint16_t
iwx_rs_vht_rates(struct iwx_softc * sc,struct ieee80211_node * ni,int num_ss)7199 iwx_rs_vht_rates(struct iwx_softc *sc, struct ieee80211_node *ni, int num_ss)
7200 {
7201 	uint16_t rx_mcs;
7202 	int max_mcs = -1;
7203 #define IEEE80211_VHT_MCS_FOR_SS_MASK(n)        (0x3 << (2*((n)-1)))
7204 #define IEEE80211_VHT_MCS_FOR_SS_SHIFT(n)       (2*((n)-1))
7205 	rx_mcs = (ni->ni_vht_mcsinfo.tx_mcs_map &
7206 	    IEEE80211_VHT_MCS_FOR_SS_MASK(num_ss)) >>
7207 	    IEEE80211_VHT_MCS_FOR_SS_SHIFT(num_ss);
7208 
7209 	switch (rx_mcs) {
7210 	case IEEE80211_VHT_MCS_NOT_SUPPORTED:
7211 		break;
7212 	case IEEE80211_VHT_MCS_SUPPORT_0_7:
7213 		max_mcs = 7;
7214 		break;
7215 	case IEEE80211_VHT_MCS_SUPPORT_0_8:
7216 		max_mcs = 8;
7217 		break;
7218 	case IEEE80211_VHT_MCS_SUPPORT_0_9:
7219 		/* Disable VHT MCS 9 for 20MHz-only stations. */
7220 		if ((ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) == 0)
7221 			max_mcs = 8;
7222 		else
7223 			max_mcs = 9;
7224 		break;
7225 	default:
7226 		/* Should not happen; Values above cover the possible range. */
7227 		panic("invalid VHT Rx MCS value %u", rx_mcs);
7228 	}
7229 
7230 	return ((1 << (max_mcs + 1)) - 1);
7231 }
7232 
7233 static int
iwx_rs_init_v3(struct iwx_softc * sc,struct iwx_node * in)7234 iwx_rs_init_v3(struct iwx_softc *sc, struct iwx_node *in)
7235 {
7236 #if 1
7237 	panic("iwx: Trying to init rate set on untested version");
7238 #else
7239 	struct ieee80211_node *ni = &in->in_ni;
7240 	struct ieee80211_rateset *rs = &ni->ni_rates;
7241 	struct iwx_tlc_config_cmd_v3 cfg_cmd;
7242 	uint32_t cmd_id;
7243 	int i;
7244 	size_t cmd_size = sizeof(cfg_cmd);
7245 
7246 	memset(&cfg_cmd, 0, sizeof(cfg_cmd));
7247 
7248 	for (i = 0; i < rs->rs_nrates; i++) {
7249 		uint8_t rval = rs->rs_rates[i] & IEEE80211_RATE_VAL;
7250 		int idx = iwx_rs_rval2idx(rval);
7251 		if (idx == -1)
7252 			return EINVAL;
7253 		cfg_cmd.non_ht_rates |= (1 << idx);
7254 	}
7255 
7256 	if (ni->ni_flags & IEEE80211_NODE_VHT) {
7257 		cfg_cmd.mode = IWX_TLC_MNG_MODE_VHT;
7258 		cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] =
7259 		    htole16(iwx_rs_vht_rates(sc, ni, 1));
7260 		cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] =
7261 		    htole16(iwx_rs_vht_rates(sc, ni, 2));
7262 	} else if (ni->ni_flags & IEEE80211_NODE_HT) {
7263 		cfg_cmd.mode = IWX_TLC_MNG_MODE_HT;
7264 		cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] =
7265 		    htole16(iwx_rs_ht_rates(sc, ni,
7266 		    IEEE80211_HT_RATESET_SISO));
7267 		cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] =
7268 		    htole16(iwx_rs_ht_rates(sc, ni,
7269 		    IEEE80211_HT_RATESET_MIMO2));
7270 	} else
7271 		cfg_cmd.mode = IWX_TLC_MNG_MODE_NON_HT;
7272 
7273 	cfg_cmd.sta_id = IWX_STATION_ID;
7274 	if (in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80)
7275 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ;
7276 	else if (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA ||
7277 	    in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB)
7278 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ;
7279 	else
7280 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ;
7281 	cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK | IWX_TLC_MNG_CHAIN_B_MSK;
7282 	if (ni->ni_flags & IEEE80211_NODE_VHT)
7283 		cfg_cmd.max_mpdu_len = htole16(3895);
7284 	else
7285 		cfg_cmd.max_mpdu_len = htole16(3839);
7286 	if (ni->ni_flags & IEEE80211_NODE_HT) {
7287 		if (ieee80211_node_supports_ht_sgi20(ni)) {
7288 			cfg_cmd.sgi_ch_width_supp |= (1 <<
7289 			    IWX_TLC_MNG_CH_WIDTH_20MHZ);
7290 		}
7291 		if (ieee80211_node_supports_ht_sgi40(ni)) {
7292 			cfg_cmd.sgi_ch_width_supp |= (1 <<
7293 			    IWX_TLC_MNG_CH_WIDTH_40MHZ);
7294 		}
7295 	}
7296 	if ((ni->ni_flags & IEEE80211_NODE_VHT) &&
7297 	    ieee80211_node_supports_vht_sgi80(ni))
7298 		cfg_cmd.sgi_ch_width_supp |= (1 << IWX_TLC_MNG_CH_WIDTH_80MHZ);
7299 
7300 	cmd_id = iwx_cmd_id(IWX_TLC_MNG_CONFIG_CMD, IWX_DATA_PATH_GROUP, 0);
7301 	return iwx_send_cmd_pdu(sc, cmd_id, IWX_CMD_ASYNC, cmd_size, &cfg_cmd);
7302 #endif
7303 }
7304 
7305 static int
iwx_rs_init_v4(struct iwx_softc * sc,struct iwx_node * in)7306 iwx_rs_init_v4(struct iwx_softc *sc, struct iwx_node *in)
7307 {
7308 	struct ieee80211_node *ni = &in->in_ni;
7309 	struct ieee80211_rateset *rs = &ni->ni_rates;
7310 	struct ieee80211_htrateset *htrs = &ni->ni_htrates;
7311 	struct iwx_tlc_config_cmd_v4 cfg_cmd;
7312 	uint32_t cmd_id;
7313 	int i;
7314 	int sgi80 = 0;
7315 	size_t cmd_size = sizeof(cfg_cmd);
7316 
7317 	memset(&cfg_cmd, 0, sizeof(cfg_cmd));
7318 
7319 	for (i = 0; i < rs->rs_nrates; i++) {
7320 		uint8_t rval = rs->rs_rates[i] & IEEE80211_RATE_VAL;
7321 		int idx = iwx_rs_rval2idx(rval);
7322 		if (idx == -1)
7323 			return EINVAL;
7324 		cfg_cmd.non_ht_rates |= (1 << idx);
7325 	}
7326 	for (i = 0; i < htrs->rs_nrates; i++) {
7327 		DPRINTF(("%s: htrate=%i\n", __func__, htrs->rs_rates[i]));
7328 	}
7329 
7330 	if (ni->ni_flags & IEEE80211_NODE_VHT) {
7331 		cfg_cmd.mode = IWX_TLC_MNG_MODE_VHT;
7332 		cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] =
7333 		    htole16(iwx_rs_vht_rates(sc, ni, 1));
7334 		cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] =
7335 		    htole16(iwx_rs_vht_rates(sc, ni, 2));
7336 
7337 		IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d SISO=0x%x\n",
7338 		    __func__, __LINE__,
7339 		    cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80]);
7340 		IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d MIMO2=0x%x\n",
7341 		    __func__, __LINE__,
7342 		    cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80]);
7343 	} else if (ni->ni_flags & IEEE80211_NODE_HT) {
7344 		cfg_cmd.mode = IWX_TLC_MNG_MODE_HT;
7345 		cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80] =
7346 		    htole16(iwx_rs_ht_rates(sc, ni,
7347 		    IEEE80211_HT_RATESET_SISO));
7348 		cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80] =
7349 		    htole16(iwx_rs_ht_rates(sc, ni,
7350 		    IEEE80211_HT_RATESET_MIMO2));
7351 
7352 		IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d SISO=0x%x\n",
7353 		    __func__, __LINE__,
7354 		    cfg_cmd.ht_rates[IWX_TLC_NSS_1][IWX_TLC_MCS_PER_BW_80]);
7355 		IWX_DPRINTF(sc, IWX_DEBUG_TXRATE, "%s:%d MIMO2=0x%x\n",
7356 		    __func__, __LINE__,
7357 		    cfg_cmd.ht_rates[IWX_TLC_NSS_2][IWX_TLC_MCS_PER_BW_80]);
7358 	} else
7359 		cfg_cmd.mode = IWX_TLC_MNG_MODE_NON_HT;
7360 
7361 	cfg_cmd.sta_id = IWX_STATION_ID;
7362 #if 0
7363 	if (in->in_phyctxt->vht_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80)
7364 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ;
7365 	else if (in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCA ||
7366 	    in->in_phyctxt->sco == IEEE80211_HTOP0_SCO_SCB)
7367 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ;
7368 	else
7369 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ;
7370 #endif
7371 	if (IEEE80211_IS_CHAN_VHT80(in->in_ni.ni_chan)) {
7372 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_80MHZ;
7373 	} else if (IEEE80211_IS_CHAN_HT40(in->in_ni.ni_chan)) {
7374 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_40MHZ;
7375 	} else {
7376 		cfg_cmd.max_ch_width = IWX_TLC_MNG_CH_WIDTH_20MHZ;
7377 	}
7378 
7379 	cfg_cmd.chains = IWX_TLC_MNG_CHAIN_A_MSK | IWX_TLC_MNG_CHAIN_B_MSK;
7380 	if (ni->ni_flags & IEEE80211_NODE_VHT)
7381 		cfg_cmd.max_mpdu_len = htole16(3895);
7382 	else
7383 		cfg_cmd.max_mpdu_len = htole16(3839);
7384 	if (ni->ni_flags & IEEE80211_NODE_HT) {
7385 		if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) {
7386 			cfg_cmd.sgi_ch_width_supp |= (1 <<
7387 			    IWX_TLC_MNG_CH_WIDTH_20MHZ);
7388 		}
7389 		if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) {
7390 			cfg_cmd.sgi_ch_width_supp |= (1 <<
7391 			    IWX_TLC_MNG_CH_WIDTH_40MHZ);
7392 		}
7393 	}
7394 	sgi80 = _IEEE80211_MASKSHIFT(ni->ni_vhtcap,
7395 	    IEEE80211_VHTCAP_SHORT_GI_80);
7396 	if ((ni->ni_flags & IEEE80211_NODE_VHT) && sgi80) {
7397 		cfg_cmd.sgi_ch_width_supp |= (1 << IWX_TLC_MNG_CH_WIDTH_80MHZ);
7398 	}
7399 
7400 	cmd_id = iwx_cmd_id(IWX_TLC_MNG_CONFIG_CMD, IWX_DATA_PATH_GROUP, 0);
7401 	return iwx_send_cmd_pdu(sc, cmd_id, IWX_CMD_ASYNC, cmd_size, &cfg_cmd);
7402 }
7403 
7404 static int
iwx_rs_init(struct iwx_softc * sc,struct iwx_node * in)7405 iwx_rs_init(struct iwx_softc *sc, struct iwx_node *in)
7406 {
7407 	int cmd_ver;
7408 
7409 	cmd_ver = iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
7410 	    IWX_TLC_MNG_CONFIG_CMD);
7411 	if (cmd_ver == 4)
7412 		return iwx_rs_init_v4(sc, in);
7413 	else
7414 		return iwx_rs_init_v3(sc, in);
7415 }
7416 
7417 
7418 /**
7419  * @brief Turn the given TX rate control notification into an ieee80211_node_txrate
7420  *
7421  * This populates the given txrate node with the TX rate control notification.
7422  *
7423  * @param sc driver softc
7424  * @param notif firmware notification
7425  * @param ni ieee80211_node update
7426  * @returns true if updated, false if not
7427  */
7428 static bool
iwx_rs_update_node_txrate(struct iwx_softc * sc,const struct iwx_tlc_update_notif * notif,struct ieee80211_node * ni)7429 iwx_rs_update_node_txrate(struct iwx_softc *sc,
7430     const struct iwx_tlc_update_notif *notif, struct ieee80211_node *ni)
7431 {
7432 	struct ieee80211com *ic = &sc->sc_ic;
7433 	/* XXX TODO: create an inline function in if_iwxreg.h? */
7434 	static int cck_idx_to_rate[] = { 2, 4, 11, 22, 2, 2, 2, 2 };
7435 	static int ofdm_idx_to_rate[] = { 12, 18, 24, 36, 48, 72, 96, 108 };
7436 
7437 	uint32_t rate_n_flags;
7438 	uint32_t type;
7439 
7440 	/* Extract the rate and command version */
7441 	rate_n_flags = le32toh(notif->rate);
7442 
7443 	if (sc->sc_rate_n_flags_version != 2) {
7444 		net80211_ic_printf(ic,
7445 		    "%s: unsupported rate_n_flags version (%d)\n",
7446 		    __func__,
7447 		    sc->sc_rate_n_flags_version);
7448 		return (false);
7449 	}
7450 
7451 	if (sc->sc_debug & IWX_DEBUG_TXRATE)
7452 		print_ratenflags(__func__, __LINE__,
7453 		    rate_n_flags, sc->sc_rate_n_flags_version);
7454 
7455 	type = (rate_n_flags & IWX_RATE_MCS_MOD_TYPE_MSK);
7456 	switch (type) {
7457 	case IWX_RATE_MCS_CCK_MSK:
7458 		ieee80211_node_set_txrate_dot11rate(ni,
7459 		    cck_idx_to_rate[rate_n_flags & IWX_RATE_LEGACY_RATE_MSK]);
7460 		return (true);
7461 	case IWX_RATE_MCS_LEGACY_OFDM_MSK:
7462 		ieee80211_node_set_txrate_dot11rate(ni,
7463 		    ofdm_idx_to_rate[rate_n_flags & IWX_RATE_LEGACY_RATE_MSK]);
7464 		return (true);
7465 	case IWX_RATE_MCS_HT_MSK:
7466 		/*
7467 		 * TODO: the current API doesn't include channel width
7468 		 * and other flags, so we can't accurately store them yet!
7469 		 *
7470 		 * channel width: (flags & IWX_RATE_MCS_CHAN_WIDTH_MSK)
7471 		 *    >> IWX_RATE_MCS_CHAN_WIDTH_POS)
7472 		 * LDPC: (flags & (1 << 16))
7473 		 */
7474 		ieee80211_node_set_txrate_ht_mcsrate(ni,
7475 		    IWX_RATE_HT_MCS_INDEX(rate_n_flags));
7476 		return (true);
7477 	case IWX_RATE_MCS_VHT_MSK:
7478 		/* TODO: same comment on channel width, etc above */
7479 		ieee80211_node_set_txrate_vht_rate(ni,
7480 		    IWX_RATE_VHT_MCS_CODE(rate_n_flags),
7481 		    IWX_RATE_VHT_MCS_NSS(rate_n_flags));
7482 		return (true);
7483 	default:
7484 		net80211_ic_printf(ic,
7485 		    "%s: unsupported chosen rate type in "
7486 		    "IWX_RATE_MCS_MOD_TYPE (%d)\n", __func__,
7487 		    type >> IWX_RATE_MCS_MOD_TYPE_POS);
7488 		return (false);
7489 	}
7490 
7491 	/* Default: if we get here, we didn't successfully update anything */
7492 	return (false);
7493 }
7494 
7495 /**
7496  * @brief Process a firmware rate control update and update net80211.
7497  *
7498  * Since firmware is doing rate control, this just needs to update
7499  * the txrate in the ieee80211_node entry.
7500  */
7501 static void
iwx_rs_update(struct iwx_softc * sc,struct iwx_tlc_update_notif * notif)7502 iwx_rs_update(struct iwx_softc *sc, struct iwx_tlc_update_notif *notif)
7503 {
7504 	struct ieee80211com *ic = &sc->sc_ic;
7505 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
7506 	/* XXX TODO: get a node ref! */
7507 	struct ieee80211_node *ni = (void *)vap->iv_bss;
7508 
7509 	/*
7510 	 * For now the iwx driver only supports a single vdev with a single
7511 	 * node; it doesn't yet support ibss/hostap/multiple vdevs.
7512 	 */
7513 	if (notif->sta_id != IWX_STATION_ID ||
7514 	    (le32toh(notif->flags) & IWX_TLC_NOTIF_FLAG_RATE) == 0)
7515 		return;
7516 
7517 	iwx_rs_update_node_txrate(sc, notif, ni);
7518 }
7519 
7520 static int
iwx_phy_send_rlc(struct iwx_softc * sc,struct iwx_phy_ctxt * phyctxt,uint8_t chains_static,uint8_t chains_dynamic)7521 iwx_phy_send_rlc(struct iwx_softc *sc, struct iwx_phy_ctxt *phyctxt,
7522     uint8_t chains_static, uint8_t chains_dynamic)
7523 {
7524 	struct iwx_rlc_config_cmd cmd;
7525 	uint32_t cmd_id;
7526 	uint8_t active_cnt, idle_cnt;
7527 
7528 	memset(&cmd, 0, sizeof(cmd));
7529 
7530 	idle_cnt = chains_static;
7531 	active_cnt = chains_dynamic;
7532 
7533 	cmd.phy_id = htole32(phyctxt->id);
7534 	cmd.rlc.rx_chain_info = htole32(iwx_fw_valid_rx_ant(sc) <<
7535 	    IWX_PHY_RX_CHAIN_VALID_POS);
7536 	cmd.rlc.rx_chain_info |= htole32(idle_cnt << IWX_PHY_RX_CHAIN_CNT_POS);
7537 	cmd.rlc.rx_chain_info |= htole32(active_cnt <<
7538 	    IWX_PHY_RX_CHAIN_MIMO_CNT_POS);
7539 
7540 	cmd_id = iwx_cmd_id(IWX_RLC_CONFIG_CMD, IWX_DATA_PATH_GROUP, 2);
7541 	return iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd);
7542 }
7543 
7544 static int
iwx_phy_ctxt_update(struct iwx_softc * sc,struct iwx_phy_ctxt * phyctxt,struct ieee80211_channel * chan,uint8_t chains_static,uint8_t chains_dynamic,uint32_t apply_time,uint8_t sco,uint8_t vht_chan_width)7545 iwx_phy_ctxt_update(struct iwx_softc *sc, struct iwx_phy_ctxt *phyctxt,
7546     struct ieee80211_channel *chan, uint8_t chains_static,
7547     uint8_t chains_dynamic, uint32_t apply_time, uint8_t sco,
7548     uint8_t vht_chan_width)
7549 {
7550 	uint16_t band_flags = (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ);
7551 	int err;
7552 
7553 	if (chan == IEEE80211_CHAN_ANYC) {
7554 		printf("%s: GOS-3833: IEEE80211_CHAN_ANYC triggered\n",
7555 		    DEVNAME(sc));
7556 		    return EIO;
7557 	}
7558 
7559 	if (isset(sc->sc_enabled_capa,
7560 	    IWX_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) &&
7561 	    (phyctxt->channel->ic_flags & band_flags) !=
7562 	    (chan->ic_flags & band_flags)) {
7563 		err = iwx_phy_ctxt_cmd(sc, phyctxt, chains_static,
7564 		    chains_dynamic, IWX_FW_CTXT_ACTION_REMOVE, apply_time, sco,
7565 		    vht_chan_width);
7566 		if (err) {
7567 			printf("%s: could not remove PHY context "
7568 			    "(error %d)\n", DEVNAME(sc), err);
7569 			return err;
7570 		}
7571 		phyctxt->channel = chan;
7572 		err = iwx_phy_ctxt_cmd(sc, phyctxt, chains_static,
7573 		    chains_dynamic, IWX_FW_CTXT_ACTION_ADD, apply_time, sco,
7574 		    vht_chan_width);
7575 		if (err) {
7576 			printf("%s: could not add PHY context "
7577 			    "(error %d)\n", DEVNAME(sc), err);
7578 			return err;
7579 		}
7580 	} else {
7581 		phyctxt->channel = chan;
7582 		err = iwx_phy_ctxt_cmd(sc, phyctxt, chains_static,
7583 		    chains_dynamic, IWX_FW_CTXT_ACTION_MODIFY, apply_time, sco,
7584 		    vht_chan_width);
7585 		if (err) {
7586 			printf("%s: could not update PHY context (error %d)\n",
7587 			    DEVNAME(sc), err);
7588 			return err;
7589 		}
7590 	}
7591 
7592 	phyctxt->sco = sco;
7593 	phyctxt->vht_chan_width = vht_chan_width;
7594 
7595 	DPRINTF(("%s: phyctxt->channel->ic_ieee=%d\n", __func__,
7596 	    phyctxt->channel->ic_ieee));
7597 	DPRINTF(("%s: phyctxt->sco=%d\n", __func__, phyctxt->sco));
7598 	DPRINTF(("%s: phyctxt->vht_chan_width=%d\n", __func__,
7599 	    phyctxt->vht_chan_width));
7600 
7601 	if (iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
7602 	    IWX_RLC_CONFIG_CMD) == 2)
7603 		return iwx_phy_send_rlc(sc, phyctxt,
7604 		    chains_static, chains_dynamic);
7605 
7606 	return 0;
7607 }
7608 
7609 static int
iwx_auth(struct ieee80211vap * vap,struct iwx_softc * sc)7610 iwx_auth(struct ieee80211vap *vap, struct iwx_softc *sc)
7611 {
7612 	struct ieee80211com *ic = &sc->sc_ic;
7613 	struct iwx_node *in;
7614 	struct iwx_vap *ivp = IWX_VAP(vap);
7615 	struct ieee80211_node *ni;
7616 	uint32_t duration;
7617 	int generation = sc->sc_generation, err;
7618 
7619 	IWX_ASSERT_LOCKED(sc);
7620 
7621 	ni = ieee80211_ref_node(vap->iv_bss);
7622 	in = IWX_NODE(ni);
7623 
7624 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
7625 		err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0],
7626 		    ic->ic_bsschan, 1, 1, 0, IEEE80211_HTOP0_SCO_SCN,
7627 		    IEEE80211_VHTOP0_CHAN_WIDTH_HT);
7628 		if (err)
7629 			return err;
7630 	} else {
7631 		err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0],
7632 		    in->in_ni.ni_chan, 1, 1, 0, IEEE80211_HTOP0_SCO_SCN,
7633 		    IEEE80211_VHTOP0_CHAN_WIDTH_HT);
7634 		if (err)
7635 			return err;
7636 	}
7637 	ivp->phy_ctxt = &sc->sc_phyctxt[0];
7638 	IEEE80211_ADDR_COPY(in->in_macaddr, in->in_ni.ni_macaddr);
7639 	DPRINTF(("%s: in-in_macaddr=%s\n", __func__,
7640 	    ether_sprintf(in->in_macaddr)));
7641 
7642 	err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_ADD, 0);
7643 	if (err) {
7644 		printf("%s: could not add MAC context (error %d)\n",
7645 		    DEVNAME(sc), err);
7646 		return err;
7647  	}
7648 	sc->sc_flags |= IWX_FLAG_MAC_ACTIVE;
7649 
7650 	err = iwx_binding_cmd(sc, in, IWX_FW_CTXT_ACTION_ADD);
7651 	if (err) {
7652 		printf("%s: could not add binding (error %d)\n",
7653 		    DEVNAME(sc), err);
7654 		goto rm_mac_ctxt;
7655 	}
7656 	sc->sc_flags |= IWX_FLAG_BINDING_ACTIVE;
7657 
7658 	err = iwx_add_sta_cmd(sc, in, 0);
7659 	if (err) {
7660 		printf("%s: could not add sta (error %d)\n",
7661 		    DEVNAME(sc), err);
7662 		goto rm_binding;
7663 	}
7664 	sc->sc_flags |= IWX_FLAG_STA_ACTIVE;
7665 
7666 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
7667 		err = iwx_enable_txq(sc, IWX_MONITOR_STA_ID,
7668 		    IWX_DQA_INJECT_MONITOR_QUEUE, IWX_MGMT_TID,
7669 		    IWX_TX_RING_COUNT);
7670 		if (err)
7671 			goto rm_sta;
7672 		return 0;
7673 	}
7674 
7675 	err = iwx_enable_mgmt_queue(sc);
7676 	if (err)
7677 		goto rm_sta;
7678 
7679 	err = iwx_clear_statistics(sc);
7680 	if (err)
7681 		goto rm_mgmt_queue;
7682 
7683 	/*
7684 	 * Prevent the FW from wandering off channel during association
7685 	 * by "protecting" the session with a time event.
7686 	 */
7687 	if (in->in_ni.ni_intval)
7688 		duration = in->in_ni.ni_intval * 9;
7689 	else
7690 		duration = 900;
7691 	return iwx_schedule_session_protection(sc, in, duration);
7692 
7693 rm_mgmt_queue:
7694 	if (generation == sc->sc_generation)
7695 		iwx_disable_mgmt_queue(sc);
7696 rm_sta:
7697 	if (generation == sc->sc_generation) {
7698 		iwx_rm_sta_cmd(sc, in);
7699 		sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE;
7700 	}
7701 rm_binding:
7702 	if (generation == sc->sc_generation) {
7703 		iwx_binding_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE);
7704 		sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE;
7705 	}
7706 rm_mac_ctxt:
7707 	if (generation == sc->sc_generation) {
7708 		iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE, 0);
7709 		sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE;
7710 	}
7711 	return err;
7712 }
7713 
7714 static int
iwx_deauth(struct iwx_softc * sc)7715 iwx_deauth(struct iwx_softc *sc)
7716 {
7717 	struct ieee80211com *ic = &sc->sc_ic;
7718 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
7719 	struct iwx_node *in = IWX_NODE(vap->iv_bss);
7720 	int err;
7721 
7722 	IWX_ASSERT_LOCKED(sc);
7723 
7724 	iwx_unprotect_session(sc, in);
7725 
7726 	if (sc->sc_flags & IWX_FLAG_STA_ACTIVE) {
7727 		err = iwx_rm_sta(sc, in);
7728 		if (err)
7729 			return err;
7730 		sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE;
7731 	}
7732 
7733 	if (sc->sc_flags & IWX_FLAG_BINDING_ACTIVE) {
7734 		err = iwx_binding_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE);
7735 		if (err) {
7736 			printf("%s: could not remove binding (error %d)\n",
7737 			    DEVNAME(sc), err);
7738 			return err;
7739 		}
7740 		sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE;
7741 	}
7742 
7743 	DPRINTF(("%s:  IWX_FLAG_MAC_ACTIVE=%d\n", __func__, sc->sc_flags &
7744 	    IWX_FLAG_MAC_ACTIVE));
7745 	if (sc->sc_flags & IWX_FLAG_MAC_ACTIVE) {
7746 		err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_REMOVE, 0);
7747 		if (err) {
7748 			printf("%s: could not remove MAC context (error %d)\n",
7749 			    DEVNAME(sc), err);
7750 			return err;
7751 		}
7752 		sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE;
7753 	}
7754 
7755 	/* Move unused PHY context to a default channel. */
7756 	//TODO uncommented in obsd, but stays on the way of auth->auth
7757 	err = iwx_phy_ctxt_update(sc, &sc->sc_phyctxt[0],
7758 	    &ic->ic_channels[1], 1, 1, 0, IEEE80211_HTOP0_SCO_SCN,
7759 	    IEEE80211_VHTOP0_CHAN_WIDTH_HT);
7760 	if (err)
7761 		return err;
7762 
7763 	return 0;
7764 }
7765 
7766 static int
iwx_run(struct ieee80211vap * vap,struct iwx_softc * sc)7767 iwx_run(struct ieee80211vap *vap, struct iwx_softc *sc)
7768 {
7769 	struct ieee80211com *ic = &sc->sc_ic;
7770 	struct iwx_node *in = IWX_NODE(vap->iv_bss);
7771 	struct ieee80211_node *ni = &in->in_ni;
7772 	struct iwx_vap *ivp = IWX_VAP(vap);
7773 	int err;
7774 
7775 	IWX_ASSERT_LOCKED(sc);
7776 
7777 	if (ni->ni_flags & IEEE80211_NODE_HT) {
7778 		uint8_t chains = iwx_mimo_enabled(sc) ? 2 : 1;
7779 		uint8_t sco, vht_chan_width;
7780 			sco = IEEE80211_HTOP0_SCO_SCN;
7781 		if ((ni->ni_flags & IEEE80211_NODE_VHT) &&
7782 		    IEEE80211_IS_CHAN_VHT80(ni->ni_chan))
7783 			vht_chan_width = IEEE80211_VHTOP0_CHAN_WIDTH_80;
7784 		else
7785 			vht_chan_width = IEEE80211_VHTOP0_CHAN_WIDTH_HT;
7786 		err = iwx_phy_ctxt_update(sc, ivp->phy_ctxt,
7787 		    ivp->phy_ctxt->channel, chains, chains,
7788 		    0, sco, vht_chan_width);
7789 		if (err) {
7790 			printf("%s: failed to update PHY\n", DEVNAME(sc));
7791 			return err;
7792 		}
7793 	}
7794 
7795 	/* Update STA again to apply HT and VHT settings. */
7796 	err = iwx_add_sta_cmd(sc, in, 1);
7797 	if (err) {
7798 		printf("%s: could not update STA (error %d)\n",
7799 		    DEVNAME(sc), err);
7800 		return err;
7801 	}
7802 
7803 	/* We have now been assigned an associd by the AP. */
7804 	err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_MODIFY, 1);
7805 	if (err) {
7806 		printf("%s: failed to update MAC\n", DEVNAME(sc));
7807 		return err;
7808 	}
7809 
7810 	err = iwx_sf_config(sc, IWX_SF_FULL_ON);
7811 	if (err) {
7812 		printf("%s: could not set sf full on (error %d)\n",
7813 		    DEVNAME(sc), err);
7814 		return err;
7815 	}
7816 
7817 	err = iwx_allow_mcast(sc);
7818 	if (err) {
7819 		printf("%s: could not allow mcast (error %d)\n",
7820 		    DEVNAME(sc), err);
7821 		return err;
7822 	}
7823 
7824 	err = iwx_power_update_device(sc);
7825 	if (err) {
7826 		printf("%s: could not send power command (error %d)\n",
7827 		    DEVNAME(sc), err);
7828 		return err;
7829 	}
7830 #ifdef notyet
7831 	/*
7832 	 * Disabled for now. Default beacon filter settings
7833 	 * prevent net80211 from getting ERP and HT protection
7834 	 * updates from beacons.
7835 	 */
7836 	err = iwx_enable_beacon_filter(sc, in);
7837 	if (err) {
7838 		printf("%s: could not enable beacon filter\n",
7839 		    DEVNAME(sc));
7840 		return err;
7841 	}
7842 #endif
7843 	err = iwx_power_mac_update_mode(sc, in);
7844 	if (err) {
7845 		printf("%s: could not update MAC power (error %d)\n",
7846 		    DEVNAME(sc), err);
7847 		return err;
7848 	}
7849 
7850 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
7851 		return 0;
7852 
7853 	err = iwx_rs_init(sc, in);
7854 	if (err) {
7855 		printf("%s: could not init rate scaling (error %d)\n",
7856 		    DEVNAME(sc), err);
7857 		return err;
7858 	}
7859 
7860 	return 0;
7861 }
7862 
7863 static int
iwx_run_stop(struct iwx_softc * sc)7864 iwx_run_stop(struct iwx_softc *sc)
7865 {
7866 	struct ieee80211com *ic = &sc->sc_ic;
7867 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
7868 	struct iwx_node *in = IWX_NODE(vap->iv_bss);
7869 	struct ieee80211_node *ni = &in->in_ni;
7870 	int err, i;
7871 
7872 	IWX_ASSERT_LOCKED(sc);
7873 
7874 	err = iwx_flush_sta(sc, in);
7875 	if (err) {
7876 		printf("%s: could not flush Tx path (error %d)\n",
7877 		    DEVNAME(sc), err);
7878 		return err;
7879 	}
7880 
7881 	/*
7882 	 * Stop Rx BA sessions now. We cannot rely on the BA task
7883 	 * for this when moving out of RUN state since it runs in a
7884 	 * separate thread.
7885 	 * Note that in->in_ni (struct ieee80211_node) already represents
7886 	 * our new access point in case we are roaming between APs.
7887 	 * This means we cannot rely on struct ieee802111_node to tell
7888 	 * us which BA sessions exist.
7889 	 */
7890 	// TODO agg
7891 	for (i = 0; i < nitems(sc->sc_rxba_data); i++) {
7892 		struct iwx_rxba_data *rxba = &sc->sc_rxba_data[i];
7893 		if (rxba->baid == IWX_RX_REORDER_DATA_INVALID_BAID)
7894 			continue;
7895 		iwx_sta_rx_agg(sc, ni, rxba->tid, 0, 0, 0, 0);
7896 	}
7897 
7898 	err = iwx_sf_config(sc, IWX_SF_INIT_OFF);
7899 	if (err)
7900 		return err;
7901 
7902 	err = iwx_disable_beacon_filter(sc);
7903 	if (err) {
7904 		printf("%s: could not disable beacon filter (error %d)\n",
7905 		    DEVNAME(sc), err);
7906 		return err;
7907 	}
7908 
7909 	/* Mark station as disassociated. */
7910 	err = iwx_mac_ctxt_cmd(sc, in, IWX_FW_CTXT_ACTION_MODIFY, 0);
7911 	if (err) {
7912 		printf("%s: failed to update MAC\n", DEVNAME(sc));
7913 		return err;
7914 	}
7915 
7916 	return 0;
7917 }
7918 
7919 static struct ieee80211_node *
iwx_node_alloc(struct ieee80211vap * vap,const uint8_t mac[IEEE80211_ADDR_LEN])7920 iwx_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
7921 {
7922 	return malloc(sizeof (struct iwx_node), M_80211_NODE,
7923 	    M_NOWAIT | M_ZERO);
7924 }
7925 
7926 #if 0
7927 int
7928 iwx_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
7929     struct ieee80211_key *k)
7930 {
7931 	struct iwx_softc *sc = ic->ic_softc;
7932 	struct iwx_node *in = (void *)ni;
7933 	struct iwx_setkey_task_arg *a;
7934 	int err;
7935 
7936 	if (k->k_cipher != IEEE80211_CIPHER_CCMP) {
7937 		/* Fallback to software crypto for other ciphers. */
7938 		err = ieee80211_set_key(ic, ni, k);
7939 		if (!err && in != NULL && (k->k_flags & IEEE80211_KEY_GROUP))
7940 			in->in_flags |= IWX_NODE_FLAG_HAVE_GROUP_KEY;
7941 		return err;
7942 	}
7943 
7944 	if (sc->setkey_nkeys >= nitems(sc->setkey_arg))
7945 		return ENOSPC;
7946 
7947 	a = &sc->setkey_arg[sc->setkey_cur];
7948 	a->sta_id = IWX_STATION_ID;
7949 	a->ni = ni;
7950 	a->k = k;
7951 	sc->setkey_cur = (sc->setkey_cur + 1) % nitems(sc->setkey_arg);
7952 	sc->setkey_nkeys++;
7953 	iwx_add_task(sc, systq, &sc->setkey_task);
7954 	return EBUSY;
7955 }
7956 
7957 int
7958 iwx_add_sta_key(struct iwx_softc *sc, int sta_id, struct ieee80211_node *ni,
7959     struct ieee80211_key *k)
7960 {
7961 	struct ieee80211com *ic = &sc->sc_ic;
7962 	struct iwx_node *in = (void *)ni;
7963 	struct iwx_add_sta_key_cmd cmd;
7964 	uint32_t status;
7965 	const int want_keymask = (IWX_NODE_FLAG_HAVE_PAIRWISE_KEY |
7966 	    IWX_NODE_FLAG_HAVE_GROUP_KEY);
7967 	int err;
7968 
7969 	/*
7970 	 * Keys are stored in 'ni' so 'k' is valid if 'ni' is valid.
7971 	 * Currently we only implement station mode where 'ni' is always
7972 	 * ic->ic_bss so there is no need to validate arguments beyond this:
7973 	 */
7974 	KASSERT(ni == ic->ic_bss);
7975 
7976 	memset(&cmd, 0, sizeof(cmd));
7977 
7978 	cmd.common.key_flags = htole16(IWX_STA_KEY_FLG_CCM |
7979 	    IWX_STA_KEY_FLG_WEP_KEY_MAP |
7980 	    ((k->k_id << IWX_STA_KEY_FLG_KEYID_POS) &
7981 	    IWX_STA_KEY_FLG_KEYID_MSK));
7982 	if (k->k_flags & IEEE80211_KEY_GROUP) {
7983 		cmd.common.key_offset = 1;
7984 		cmd.common.key_flags |= htole16(IWX_STA_KEY_MULTICAST);
7985 	} else
7986 		cmd.common.key_offset = 0;
7987 
7988 	memcpy(cmd.common.key, k->k_key, MIN(sizeof(cmd.common.key), k->k_len));
7989 	cmd.common.sta_id = sta_id;
7990 
7991 	cmd.transmit_seq_cnt = htole64(k->k_tsc);
7992 
7993 	status = IWX_ADD_STA_SUCCESS;
7994 	err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA_KEY, sizeof(cmd), &cmd,
7995 	    &status);
7996 	if (sc->sc_flags & IWX_FLAG_SHUTDOWN)
7997 		return ECANCELED;
7998 	if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS)
7999 		err = EIO;
8000 	if (err) {
8001 		IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
8002 		    IEEE80211_REASON_AUTH_LEAVE);
8003 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
8004 		return err;
8005 	}
8006 
8007 	if (k->k_flags & IEEE80211_KEY_GROUP)
8008 		in->in_flags |= IWX_NODE_FLAG_HAVE_GROUP_KEY;
8009 	else
8010 		in->in_flags |= IWX_NODE_FLAG_HAVE_PAIRWISE_KEY;
8011 
8012 	if ((in->in_flags & want_keymask) == want_keymask) {
8013 		DPRINTF(("marking port %s valid\n",
8014 		    ether_sprintf(ni->ni_macaddr)));
8015 		ni->ni_port_valid = 1;
8016 		ieee80211_set_link_state(ic, LINK_STATE_UP);
8017 	}
8018 
8019 	return 0;
8020 }
8021 
8022 void
8023 iwx_setkey_task(void *arg)
8024 {
8025 	struct iwx_softc *sc = arg;
8026 	struct iwx_setkey_task_arg *a;
8027 	int err = 0, s = splnet();
8028 
8029 	while (sc->setkey_nkeys > 0) {
8030 		if (err || (sc->sc_flags & IWX_FLAG_SHUTDOWN))
8031 			break;
8032 		a = &sc->setkey_arg[sc->setkey_tail];
8033 		err = iwx_add_sta_key(sc, a->sta_id, a->ni, a->k);
8034 		a->sta_id = 0;
8035 		a->ni = NULL;
8036 		a->k = NULL;
8037 		sc->setkey_tail = (sc->setkey_tail + 1) %
8038 		    nitems(sc->setkey_arg);
8039 		sc->setkey_nkeys--;
8040 	}
8041 
8042 	refcnt_rele_wake(&sc->task_refs);
8043 	splx(s);
8044 }
8045 
8046 void
8047 iwx_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
8048     struct ieee80211_key *k)
8049 {
8050 	struct iwx_softc *sc = ic->ic_softc;
8051 	struct iwx_add_sta_key_cmd cmd;
8052 
8053 	if (k->k_cipher != IEEE80211_CIPHER_CCMP) {
8054 		/* Fallback to software crypto for other ciphers. */
8055                 ieee80211_delete_key(ic, ni, k);
8056 		return;
8057 	}
8058 
8059 	if ((sc->sc_flags & IWX_FLAG_STA_ACTIVE) == 0)
8060 		return;
8061 
8062 	memset(&cmd, 0, sizeof(cmd));
8063 
8064 	cmd.common.key_flags = htole16(IWX_STA_KEY_NOT_VALID |
8065 	    IWX_STA_KEY_FLG_NO_ENC | IWX_STA_KEY_FLG_WEP_KEY_MAP |
8066 	    ((k->k_id << IWX_STA_KEY_FLG_KEYID_POS) &
8067 	    IWX_STA_KEY_FLG_KEYID_MSK));
8068 	memcpy(cmd.common.key, k->k_key, MIN(sizeof(cmd.common.key), k->k_len));
8069 	if (k->k_flags & IEEE80211_KEY_GROUP)
8070 		cmd.common.key_offset = 1;
8071 	else
8072 		cmd.common.key_offset = 0;
8073 	cmd.common.sta_id = IWX_STATION_ID;
8074 
8075 	iwx_send_cmd_pdu(sc, IWX_ADD_STA_KEY, IWX_CMD_ASYNC, sizeof(cmd), &cmd);
8076 }
8077 #endif
8078 
8079 static int
iwx_newstate_sub(struct ieee80211vap * vap,enum ieee80211_state nstate)8080 iwx_newstate_sub(struct ieee80211vap *vap, enum ieee80211_state nstate)
8081 {
8082 	struct ieee80211com *ic = vap->iv_ic;
8083 	struct iwx_softc *sc = ic->ic_softc;
8084 	enum ieee80211_state ostate = vap->iv_state;
8085 	int err = 0;
8086 
8087 	IWX_LOCK(sc);
8088 	if (sc->sc_flags & IWX_FLAG_SHUTDOWN) {
8089 		goto out;
8090 	}
8091 
8092 	if (nstate <= ostate || nstate > IEEE80211_S_RUN) {
8093 		switch (ostate) {
8094 		case IEEE80211_S_RUN:
8095 			err = iwx_run_stop(sc);
8096 			if (err)
8097 				goto out;
8098 			/* FALLTHROUGH */
8099 		case IEEE80211_S_ASSOC:
8100 		case IEEE80211_S_AUTH:
8101 			if (nstate <= IEEE80211_S_AUTH) {
8102 				err = iwx_deauth(sc);
8103 				if (err)
8104 					goto out;
8105 			}
8106 			/* FALLTHROUGH */
8107 		case IEEE80211_S_SCAN:
8108 		case IEEE80211_S_INIT:
8109 		default:
8110 			break;
8111 		}
8112 //
8113 //		/* Die now if iwx_stop() was called while we were sleeping. */
8114 //		if (sc->sc_flags & IWX_FLAG_SHUTDOWN) {
8115 //			refcnt_rele_wake(&sc->task_refs);
8116 //			splx(s);
8117 //			return;
8118 //		}
8119 	}
8120 
8121 	switch (nstate) {
8122 	case IEEE80211_S_INIT:
8123 		break;
8124 
8125 	case IEEE80211_S_SCAN:
8126 			break;
8127 
8128 	case IEEE80211_S_AUTH:
8129 		err = iwx_auth(vap, sc);
8130 		break;
8131 
8132 	case IEEE80211_S_ASSOC:
8133 		break;
8134 
8135 	case IEEE80211_S_RUN:
8136 		err = iwx_run(vap, sc);
8137 		break;
8138 	default:
8139 		break;
8140 	}
8141 
8142 out:
8143 	IWX_UNLOCK(sc);
8144 
8145 	return (err);
8146 }
8147 
8148 static int
iwx_newstate(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)8149 iwx_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8150 {
8151 	struct iwx_vap *ivp = IWX_VAP(vap);
8152 	struct ieee80211com *ic = vap->iv_ic;
8153 	enum ieee80211_state ostate = vap->iv_state;
8154 	int err;
8155 
8156 	/*
8157 	 * Prevent attempts to transition towards the same state, unless
8158 	 * we are scanning in which case a SCAN -> SCAN transition
8159 	 * triggers another scan iteration. And AUTH -> AUTH is needed
8160 	 * to support band-steering.
8161 	 */
8162 	if (ostate == nstate && nstate != IEEE80211_S_SCAN &&
8163 	    nstate != IEEE80211_S_AUTH)
8164 		return 0;
8165 	IEEE80211_UNLOCK(ic);
8166 	err = iwx_newstate_sub(vap, nstate);
8167 	IEEE80211_LOCK(ic);
8168 	if (err == 0)
8169 		err = ivp->iv_newstate(vap, nstate, arg);
8170 
8171 	return (err);
8172 }
8173 
8174 static void
iwx_endscan(struct iwx_softc * sc)8175 iwx_endscan(struct iwx_softc *sc)
8176 {
8177         struct ieee80211com *ic = &sc->sc_ic;
8178         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8179 
8180         if ((sc->sc_flags & (IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN)) == 0)
8181                 return;
8182 
8183         sc->sc_flags &= ~(IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN);
8184 
8185         ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps));
8186         wakeup(&vap->iv_state); /* wake up iwx_newstate */
8187 }
8188 
8189 /*
8190  * Aging and idle timeouts for the different possible scenarios
8191  * in default configuration
8192  */
8193 static const uint32_t
8194 iwx_sf_full_timeout_def[IWX_SF_NUM_SCENARIO][IWX_SF_NUM_TIMEOUT_TYPES] = {
8195 	{
8196 		htole32(IWX_SF_SINGLE_UNICAST_AGING_TIMER_DEF),
8197 		htole32(IWX_SF_SINGLE_UNICAST_IDLE_TIMER_DEF)
8198 	},
8199 	{
8200 		htole32(IWX_SF_AGG_UNICAST_AGING_TIMER_DEF),
8201 		htole32(IWX_SF_AGG_UNICAST_IDLE_TIMER_DEF)
8202 	},
8203 	{
8204 		htole32(IWX_SF_MCAST_AGING_TIMER_DEF),
8205 		htole32(IWX_SF_MCAST_IDLE_TIMER_DEF)
8206 	},
8207 	{
8208 		htole32(IWX_SF_BA_AGING_TIMER_DEF),
8209 		htole32(IWX_SF_BA_IDLE_TIMER_DEF)
8210 	},
8211 	{
8212 		htole32(IWX_SF_TX_RE_AGING_TIMER_DEF),
8213 		htole32(IWX_SF_TX_RE_IDLE_TIMER_DEF)
8214 	},
8215 };
8216 
8217 /*
8218  * Aging and idle timeouts for the different possible scenarios
8219  * in single BSS MAC configuration.
8220  */
8221 static const uint32_t
8222 iwx_sf_full_timeout[IWX_SF_NUM_SCENARIO][IWX_SF_NUM_TIMEOUT_TYPES] = {
8223 	{
8224 		htole32(IWX_SF_SINGLE_UNICAST_AGING_TIMER),
8225 		htole32(IWX_SF_SINGLE_UNICAST_IDLE_TIMER)
8226 	},
8227 	{
8228 		htole32(IWX_SF_AGG_UNICAST_AGING_TIMER),
8229 		htole32(IWX_SF_AGG_UNICAST_IDLE_TIMER)
8230 	},
8231 	{
8232 		htole32(IWX_SF_MCAST_AGING_TIMER),
8233 		htole32(IWX_SF_MCAST_IDLE_TIMER)
8234 	},
8235 	{
8236 		htole32(IWX_SF_BA_AGING_TIMER),
8237 		htole32(IWX_SF_BA_IDLE_TIMER)
8238 	},
8239 	{
8240 		htole32(IWX_SF_TX_RE_AGING_TIMER),
8241 		htole32(IWX_SF_TX_RE_IDLE_TIMER)
8242 	},
8243 };
8244 
8245 static void
iwx_fill_sf_command(struct iwx_softc * sc,struct iwx_sf_cfg_cmd * sf_cmd,struct ieee80211_node * ni)8246 iwx_fill_sf_command(struct iwx_softc *sc, struct iwx_sf_cfg_cmd *sf_cmd,
8247     struct ieee80211_node *ni)
8248 {
8249 	int i, j, watermark;
8250 
8251 	sf_cmd->watermark[IWX_SF_LONG_DELAY_ON] = htole32(IWX_SF_W_MARK_SCAN);
8252 
8253 	/*
8254 	 * If we are in association flow - check antenna configuration
8255 	 * capabilities of the AP station, and choose the watermark accordingly.
8256 	 */
8257 	if (ni) {
8258 		if (ni->ni_flags & IEEE80211_NODE_HT) {
8259 			struct ieee80211_htrateset *htrs = &ni->ni_htrates;
8260 			int hasmimo = 0;
8261 			for (i = 0; i < htrs->rs_nrates; i++) {
8262 				if (htrs->rs_rates[i] > 7) {
8263 					hasmimo = 1;
8264 					break;
8265 				}
8266 			}
8267 			if (hasmimo)
8268 				watermark = IWX_SF_W_MARK_MIMO2;
8269 			else
8270 				watermark = IWX_SF_W_MARK_SISO;
8271 		} else {
8272 			watermark = IWX_SF_W_MARK_LEGACY;
8273 		}
8274 	/* default watermark value for unassociated mode. */
8275 	} else {
8276 		watermark = IWX_SF_W_MARK_MIMO2;
8277 	}
8278 	sf_cmd->watermark[IWX_SF_FULL_ON] = htole32(watermark);
8279 
8280 	for (i = 0; i < IWX_SF_NUM_SCENARIO; i++) {
8281 		for (j = 0; j < IWX_SF_NUM_TIMEOUT_TYPES; j++) {
8282 			sf_cmd->long_delay_timeouts[i][j] =
8283 					htole32(IWX_SF_LONG_DELAY_AGING_TIMER);
8284 		}
8285 	}
8286 
8287 	if (ni) {
8288 		memcpy(sf_cmd->full_on_timeouts, iwx_sf_full_timeout,
8289 		       sizeof(iwx_sf_full_timeout));
8290 	} else {
8291 		memcpy(sf_cmd->full_on_timeouts, iwx_sf_full_timeout_def,
8292 		       sizeof(iwx_sf_full_timeout_def));
8293 	}
8294 
8295 }
8296 
8297 static int
iwx_sf_config(struct iwx_softc * sc,int new_state)8298 iwx_sf_config(struct iwx_softc *sc, int new_state)
8299 {
8300 	struct ieee80211com *ic = &sc->sc_ic;
8301 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8302 	struct ieee80211_node *ni = vap->iv_bss;
8303 	struct iwx_sf_cfg_cmd sf_cmd = {
8304 		.state = htole32(new_state),
8305 	};
8306 	int err = 0;
8307 
8308 	switch (new_state) {
8309 	case IWX_SF_UNINIT:
8310 	case IWX_SF_INIT_OFF:
8311 		iwx_fill_sf_command(sc, &sf_cmd, NULL);
8312 		break;
8313 	case IWX_SF_FULL_ON:
8314 		iwx_fill_sf_command(sc, &sf_cmd, ni);
8315 		break;
8316 	default:
8317 		return EINVAL;
8318 	}
8319 
8320 	err = iwx_send_cmd_pdu(sc, IWX_REPLY_SF_CFG_CMD, IWX_CMD_ASYNC,
8321 				   sizeof(sf_cmd), &sf_cmd);
8322 	return err;
8323 }
8324 
8325 static int
iwx_send_bt_init_conf(struct iwx_softc * sc)8326 iwx_send_bt_init_conf(struct iwx_softc *sc)
8327 {
8328 	struct iwx_bt_coex_cmd bt_cmd;
8329 
8330 	bzero(&bt_cmd, sizeof(struct iwx_bt_coex_cmd));
8331 
8332 	bt_cmd.mode = htole32(IWX_BT_COEX_NW);
8333 	bt_cmd.enabled_modules |= BT_COEX_SYNC2SCO_ENABLED;
8334 	bt_cmd.enabled_modules |= BT_COEX_HIGH_BAND_RET;
8335 
8336 
8337 	return iwx_send_cmd_pdu(sc, IWX_BT_CONFIG, 0, sizeof(bt_cmd),
8338 	    &bt_cmd);
8339 }
8340 
8341 static int
iwx_send_soc_conf(struct iwx_softc * sc)8342 iwx_send_soc_conf(struct iwx_softc *sc)
8343 {
8344 	struct iwx_soc_configuration_cmd cmd;
8345 	int err;
8346 	uint32_t cmd_id, flags = 0;
8347 
8348 	memset(&cmd, 0, sizeof(cmd));
8349 
8350 	/*
8351 	 * In VER_1 of this command, the discrete value is considered
8352 	 * an integer; In VER_2, it's a bitmask.  Since we have only 2
8353 	 * values in VER_1, this is backwards-compatible with VER_2,
8354 	 * as long as we don't set any other flag bits.
8355 	 */
8356 	if (!sc->sc_integrated) { /* VER_1 */
8357 		flags = IWX_SOC_CONFIG_CMD_FLAGS_DISCRETE;
8358 	} else { /* VER_2 */
8359 		uint8_t scan_cmd_ver;
8360 		if (sc->sc_ltr_delay != IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE)
8361 			flags |= (sc->sc_ltr_delay &
8362 			    IWX_SOC_FLAGS_LTR_APPLY_DELAY_MASK);
8363 		scan_cmd_ver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP,
8364 		    IWX_SCAN_REQ_UMAC);
8365 		if (scan_cmd_ver != IWX_FW_CMD_VER_UNKNOWN &&
8366 		    scan_cmd_ver >= 2 && sc->sc_low_latency_xtal)
8367 			flags |= IWX_SOC_CONFIG_CMD_FLAGS_LOW_LATENCY;
8368 	}
8369 	cmd.flags = htole32(flags);
8370 
8371 	cmd.latency = htole32(sc->sc_xtal_latency);
8372 
8373 	cmd_id = iwx_cmd_id(IWX_SOC_CONFIGURATION_CMD, IWX_SYSTEM_GROUP, 0);
8374 	err = iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd);
8375 	if (err)
8376 		printf("%s: failed to set soc latency: %d\n", DEVNAME(sc), err);
8377 	return err;
8378 }
8379 
8380 static int
iwx_send_update_mcc_cmd(struct iwx_softc * sc,const char * alpha2)8381 iwx_send_update_mcc_cmd(struct iwx_softc *sc, const char *alpha2)
8382 {
8383 	struct iwx_mcc_update_cmd mcc_cmd;
8384 	struct iwx_host_cmd hcmd = {
8385 		.id = IWX_MCC_UPDATE_CMD,
8386 		.flags = IWX_CMD_WANT_RESP,
8387 		.data = { &mcc_cmd },
8388 	};
8389 	struct iwx_rx_packet *pkt;
8390 	struct iwx_mcc_update_resp *resp;
8391 	size_t resp_len;
8392 	int err;
8393 
8394 	memset(&mcc_cmd, 0, sizeof(mcc_cmd));
8395 	mcc_cmd.mcc = htole16(alpha2[0] << 8 | alpha2[1]);
8396 	if (isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_WIFI_MCC_UPDATE) ||
8397 	    isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_LAR_MULTI_MCC))
8398 		mcc_cmd.source_id = IWX_MCC_SOURCE_GET_CURRENT;
8399 	else
8400 		mcc_cmd.source_id = IWX_MCC_SOURCE_OLD_FW;
8401 
8402 	hcmd.len[0] = sizeof(struct iwx_mcc_update_cmd);
8403 	hcmd.resp_pkt_len = IWX_CMD_RESP_MAX;
8404 
8405 	err = iwx_send_cmd(sc, &hcmd);
8406 	if (err)
8407 		return err;
8408 
8409 	pkt = hcmd.resp_pkt;
8410 	if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) {
8411 		err = EIO;
8412 		goto out;
8413 	}
8414 
8415 	resp_len = iwx_rx_packet_payload_len(pkt);
8416 	if (resp_len < sizeof(*resp)) {
8417 		err = EIO;
8418 		goto out;
8419 	}
8420 
8421 	resp = (void *)pkt->data;
8422 	if (resp_len != sizeof(*resp) +
8423 	    resp->n_channels * sizeof(resp->channels[0])) {
8424 		err = EIO;
8425 		goto out;
8426 	}
8427 
8428 	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",
8429 	    resp->status, resp->mcc, resp->cap, resp->time, resp->geo_info, resp->source_id, resp->n_channels));
8430 
8431 out:
8432 	iwx_free_resp(sc, &hcmd);
8433 
8434 	return err;
8435 }
8436 
8437 static int
iwx_send_temp_report_ths_cmd(struct iwx_softc * sc)8438 iwx_send_temp_report_ths_cmd(struct iwx_softc *sc)
8439 {
8440 	struct iwx_temp_report_ths_cmd cmd;
8441 	int err;
8442 
8443 	/*
8444 	 * In order to give responsibility for critical-temperature-kill
8445 	 * and TX backoff to FW we need to send an empty temperature
8446 	 * reporting command at init time.
8447 	 */
8448 	memset(&cmd, 0, sizeof(cmd));
8449 
8450 	err = iwx_send_cmd_pdu(sc,
8451 	    IWX_WIDE_ID(IWX_PHY_OPS_GROUP, IWX_TEMP_REPORTING_THRESHOLDS_CMD),
8452 	    0, sizeof(cmd), &cmd);
8453 	if (err)
8454 		printf("%s: TEMP_REPORT_THS_CMD command failed (error %d)\n",
8455 		    DEVNAME(sc), err);
8456 
8457 	return err;
8458 }
8459 
8460 static int
iwx_init_hw(struct iwx_softc * sc)8461 iwx_init_hw(struct iwx_softc *sc)
8462 {
8463 	struct ieee80211com *ic = &sc->sc_ic;
8464 	int err = 0, i;
8465 
8466 	err = iwx_run_init_mvm_ucode(sc, 0);
8467 	if (err)
8468 		return err;
8469 
8470 	if (!iwx_nic_lock(sc))
8471 		return EBUSY;
8472 
8473 	err = iwx_send_tx_ant_cfg(sc, iwx_fw_valid_tx_ant(sc));
8474 	if (err) {
8475 		printf("%s: could not init tx ant config (error %d)\n",
8476 		    DEVNAME(sc), err);
8477 		goto err;
8478 	}
8479 
8480 	if (sc->sc_tx_with_siso_diversity) {
8481 		err = iwx_send_phy_cfg_cmd(sc);
8482 		if (err) {
8483 			printf("%s: could not send phy config (error %d)\n",
8484 			    DEVNAME(sc), err);
8485 			goto err;
8486 		}
8487 	}
8488 
8489 	err = iwx_send_bt_init_conf(sc);
8490 	if (err) {
8491 		printf("%s: could not init bt coex (error %d)\n",
8492 		    DEVNAME(sc), err);
8493 		return err;
8494 	}
8495 
8496 	err = iwx_send_soc_conf(sc);
8497 	if (err) {
8498 		printf("%s: iwx_send_soc_conf failed\n", __func__);
8499 		return err;
8500 	}
8501 
8502 	if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_DQA_SUPPORT)) {
8503 		printf("%s: === IWX_UCODE_TLV_CAPA_DQA_SUPPORT\n", __func__);
8504 		err = iwx_send_dqa_cmd(sc);
8505 		if (err) {
8506 			printf("%s: IWX_UCODE_TLV_CAPA_DQA_SUPPORT "
8507 			    "failed (error %d)\n", __func__, err);
8508 			return err;
8509 		}
8510 	}
8511 	// TODO phyctxt
8512 	for (i = 0; i < IWX_NUM_PHY_CTX; i++) {
8513 		/*
8514 		 * The channel used here isn't relevant as it's
8515 		 * going to be overwritten in the other flows.
8516 		 * For now use the first channel we have.
8517 		 */
8518 		sc->sc_phyctxt[i].id = i;
8519 		sc->sc_phyctxt[i].channel = &ic->ic_channels[1];
8520 		err = iwx_phy_ctxt_cmd(sc, &sc->sc_phyctxt[i], 1, 1,
8521 		    IWX_FW_CTXT_ACTION_ADD, 0, 0, 0);
8522 		if (err) {
8523 			printf("%s: could not add phy context %d (error %d)\n",
8524 			    DEVNAME(sc), i, err);
8525 			goto err;
8526 		}
8527 		if (iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
8528 		    IWX_RLC_CONFIG_CMD) == 2) {
8529 			err = iwx_phy_send_rlc(sc, &sc->sc_phyctxt[i], 1, 1);
8530 			if (err) {
8531 				printf("%s: could not configure RLC for PHY "
8532 				    "%d (error %d)\n", DEVNAME(sc), i, err);
8533 				goto err;
8534 			}
8535 		}
8536 	}
8537 
8538 	err = iwx_config_ltr(sc);
8539 	if (err) {
8540 		printf("%s: PCIe LTR configuration failed (error %d)\n",
8541 		    DEVNAME(sc), err);
8542 	}
8543 
8544 	if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CT_KILL_BY_FW)) {
8545 		err = iwx_send_temp_report_ths_cmd(sc);
8546 		if (err) {
8547 			printf("%s: iwx_send_temp_report_ths_cmd failed\n",
8548 			    __func__);
8549 			goto err;
8550 		}
8551 	}
8552 
8553 	err = iwx_power_update_device(sc);
8554 	if (err) {
8555 		printf("%s: could not send power command (error %d)\n",
8556 		    DEVNAME(sc), err);
8557 		goto err;
8558 	}
8559 
8560 	if (sc->sc_nvm.lar_enabled) {
8561 		err = iwx_send_update_mcc_cmd(sc, "ZZ");
8562 		if (err) {
8563 			printf("%s: could not init LAR (error %d)\n",
8564 			    DEVNAME(sc), err);
8565 			goto err;
8566 		}
8567 	}
8568 
8569 	err = iwx_config_umac_scan_reduced(sc);
8570 	if (err) {
8571 		printf("%s: could not configure scan (error %d)\n",
8572 		    DEVNAME(sc), err);
8573 		goto err;
8574 	}
8575 
8576 	err = iwx_disable_beacon_filter(sc);
8577 	if (err) {
8578 		printf("%s: could not disable beacon filter (error %d)\n",
8579 		    DEVNAME(sc), err);
8580 		goto err;
8581 	}
8582 
8583 err:
8584 	iwx_nic_unlock(sc);
8585 	return err;
8586 }
8587 
8588 /* Allow multicast from our BSSID. */
8589 static int
iwx_allow_mcast(struct iwx_softc * sc)8590 iwx_allow_mcast(struct iwx_softc *sc)
8591 {
8592 	struct ieee80211com *ic = &sc->sc_ic;
8593 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8594 	struct iwx_node *in = IWX_NODE(vap->iv_bss);
8595 	struct iwx_mcast_filter_cmd *cmd;
8596 	size_t size;
8597 	int err;
8598 
8599 	size = roundup(sizeof(*cmd), 4);
8600 	cmd = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
8601 	if (cmd == NULL)
8602 		return ENOMEM;
8603 	cmd->filter_own = 1;
8604 	cmd->port_id = 0;
8605 	cmd->count = 0;
8606 	cmd->pass_all = 1;
8607 	IEEE80211_ADDR_COPY(cmd->bssid, in->in_macaddr);
8608 
8609 	err = iwx_send_cmd_pdu(sc, IWX_MCAST_FILTER_CMD,
8610 	    0, size, cmd);
8611 	free(cmd, M_DEVBUF);
8612 	return err;
8613 }
8614 
8615 static int
iwx_init(struct iwx_softc * sc)8616 iwx_init(struct iwx_softc *sc)
8617 {
8618 	int err, generation;
8619 	generation = ++sc->sc_generation;
8620 	iwx_preinit(sc);
8621 
8622 	err = iwx_start_hw(sc);
8623 	if (err) {
8624 		printf("%s: iwx_start_hw failed\n", __func__);
8625 		return err;
8626 	}
8627 
8628 	err = iwx_init_hw(sc);
8629 	if (err) {
8630 		if (generation == sc->sc_generation)
8631 			iwx_stop_device(sc);
8632 		printf("%s: iwx_init_hw failed (error %d)\n", __func__, err);
8633 		return err;
8634 	}
8635 
8636 	sc->sc_flags |= IWX_FLAG_HW_INITED;
8637 	callout_reset(&sc->watchdog_to, hz, iwx_watchdog, sc);
8638 
8639 	return 0;
8640 }
8641 
8642 static void
iwx_start(struct iwx_softc * sc)8643 iwx_start(struct iwx_softc *sc)
8644 {
8645         struct ieee80211_node *ni;
8646         struct mbuf *m;
8647 
8648         IWX_ASSERT_LOCKED(sc);
8649 
8650         while (sc->qfullmsk == 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
8651                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
8652                 if (iwx_tx(sc, m, ni) != 0) {
8653                       if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
8654                         continue;
8655                 }
8656         }
8657 }
8658 
8659 static void
iwx_stop(struct iwx_softc * sc)8660 iwx_stop(struct iwx_softc *sc)
8661 {
8662 	struct ieee80211com *ic = &sc->sc_ic;
8663 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8664 	struct iwx_vap *ivp = IWX_VAP(vap);
8665 
8666 	iwx_stop_device(sc);
8667 
8668 	/* Reset soft state. */
8669 	sc->sc_generation++;
8670 	ivp->phy_ctxt = NULL;
8671 
8672 	sc->sc_flags &= ~(IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN);
8673 	sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE;
8674 	sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE;
8675 	sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE;
8676 	sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE;
8677 	sc->sc_flags &= ~IWX_FLAG_HW_ERR;
8678 	sc->sc_flags &= ~IWX_FLAG_SHUTDOWN;
8679 	sc->sc_flags &= ~IWX_FLAG_TXFLUSH;
8680 
8681 	sc->sc_rx_ba_sessions = 0;
8682 	sc->ba_rx.start_tidmask = 0;
8683 	sc->ba_rx.stop_tidmask = 0;
8684 	memset(sc->aggqid, 0, sizeof(sc->aggqid));
8685 	sc->ba_tx.start_tidmask = 0;
8686 	sc->ba_tx.stop_tidmask = 0;
8687 }
8688 
8689 static void
iwx_watchdog(void * arg)8690 iwx_watchdog(void *arg)
8691 {
8692 	struct iwx_softc *sc = arg;
8693 	struct ieee80211com *ic = &sc->sc_ic;
8694 	int i;
8695 
8696 	/*
8697 	 * We maintain a separate timer for each Tx queue because
8698 	 * Tx aggregation queues can get "stuck" while other queues
8699 	 * keep working. The Linux driver uses a similar workaround.
8700 	 */
8701 	for (i = 0; i < nitems(sc->sc_tx_timer); i++) {
8702 		if (sc->sc_tx_timer[i] > 0) {
8703 			if (--sc->sc_tx_timer[i] == 0) {
8704 				printf("%s: device timeout\n", DEVNAME(sc));
8705 
8706 				iwx_nic_error(sc);
8707 				iwx_dump_driver_status(sc);
8708 				ieee80211_restart_all(ic);
8709 				return;
8710 			}
8711 		}
8712 	}
8713 	callout_reset(&sc->watchdog_to, hz, iwx_watchdog, sc);
8714 }
8715 
8716 /*
8717  * Note: This structure is read from the device with IO accesses,
8718  * and the reading already does the endian conversion. As it is
8719  * read with uint32_t-sized accesses, any members with a different size
8720  * need to be ordered correctly though!
8721  */
8722 struct iwx_error_event_table {
8723 	uint32_t valid;		/* (nonzero) valid, (0) log is empty */
8724 	uint32_t error_id;		/* type of error */
8725 	uint32_t trm_hw_status0;	/* TRM HW status */
8726 	uint32_t trm_hw_status1;	/* TRM HW status */
8727 	uint32_t blink2;		/* branch link */
8728 	uint32_t ilink1;		/* interrupt link */
8729 	uint32_t ilink2;		/* interrupt link */
8730 	uint32_t data1;		/* error-specific data */
8731 	uint32_t data2;		/* error-specific data */
8732 	uint32_t data3;		/* error-specific data */
8733 	uint32_t bcon_time;		/* beacon timer */
8734 	uint32_t tsf_low;		/* network timestamp function timer */
8735 	uint32_t tsf_hi;		/* network timestamp function timer */
8736 	uint32_t gp1;		/* GP1 timer register */
8737 	uint32_t gp2;		/* GP2 timer register */
8738 	uint32_t fw_rev_type;	/* firmware revision type */
8739 	uint32_t major;		/* uCode version major */
8740 	uint32_t minor;		/* uCode version minor */
8741 	uint32_t hw_ver;		/* HW Silicon version */
8742 	uint32_t brd_ver;		/* HW board version */
8743 	uint32_t log_pc;		/* log program counter */
8744 	uint32_t frame_ptr;		/* frame pointer */
8745 	uint32_t stack_ptr;		/* stack pointer */
8746 	uint32_t hcmd;		/* last host command header */
8747 	uint32_t isr0;		/* isr status register LMPM_NIC_ISR0:
8748 				 * rxtx_flag */
8749 	uint32_t isr1;		/* isr status register LMPM_NIC_ISR1:
8750 				 * host_flag */
8751 	uint32_t isr2;		/* isr status register LMPM_NIC_ISR2:
8752 				 * enc_flag */
8753 	uint32_t isr3;		/* isr status register LMPM_NIC_ISR3:
8754 				 * time_flag */
8755 	uint32_t isr4;		/* isr status register LMPM_NIC_ISR4:
8756 				 * wico interrupt */
8757 	uint32_t last_cmd_id;	/* last HCMD id handled by the firmware */
8758 	uint32_t wait_event;		/* wait event() caller address */
8759 	uint32_t l2p_control;	/* L2pControlField */
8760 	uint32_t l2p_duration;	/* L2pDurationField */
8761 	uint32_t l2p_mhvalid;	/* L2pMhValidBits */
8762 	uint32_t l2p_addr_match;	/* L2pAddrMatchStat */
8763 	uint32_t lmpm_pmg_sel;	/* indicate which clocks are turned on
8764 				 * (LMPM_PMG_SEL) */
8765 	uint32_t u_timestamp;	/* indicate when the date and time of the
8766 				 * compilation */
8767 	uint32_t flow_handler;	/* FH read/write pointers, RX credit */
8768 } __packed /* LOG_ERROR_TABLE_API_S_VER_3 */;
8769 
8770 /*
8771  * UMAC error struct - relevant starting from family 8000 chip.
8772  * Note: This structure is read from the device with IO accesses,
8773  * and the reading already does the endian conversion. As it is
8774  * read with u32-sized accesses, any members with a different size
8775  * need to be ordered correctly though!
8776  */
8777 struct iwx_umac_error_event_table {
8778 	uint32_t valid;		/* (nonzero) valid, (0) log is empty */
8779 	uint32_t error_id;	/* type of error */
8780 	uint32_t blink1;	/* branch link */
8781 	uint32_t blink2;	/* branch link */
8782 	uint32_t ilink1;	/* interrupt link */
8783 	uint32_t ilink2;	/* interrupt link */
8784 	uint32_t data1;		/* error-specific data */
8785 	uint32_t data2;		/* error-specific data */
8786 	uint32_t data3;		/* error-specific data */
8787 	uint32_t umac_major;
8788 	uint32_t umac_minor;
8789 	uint32_t frame_pointer;	/* core register 27*/
8790 	uint32_t stack_pointer;	/* core register 28 */
8791 	uint32_t cmd_header;	/* latest host cmd sent to UMAC */
8792 	uint32_t nic_isr_pref;	/* ISR status register */
8793 } __packed;
8794 
8795 #define ERROR_START_OFFSET  (1 * sizeof(uint32_t))
8796 #define ERROR_ELEM_SIZE     (7 * sizeof(uint32_t))
8797 
8798 static void
iwx_nic_umac_error(struct iwx_softc * sc)8799 iwx_nic_umac_error(struct iwx_softc *sc)
8800 {
8801 	struct iwx_umac_error_event_table table;
8802 	uint32_t base;
8803 
8804 	base = sc->sc_uc.uc_umac_error_event_table;
8805 
8806 	if (base < 0x400000) {
8807 		printf("%s: Invalid error log pointer 0x%08x\n",
8808 		    DEVNAME(sc), base);
8809 		return;
8810 	}
8811 
8812 	if (iwx_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t))) {
8813 		printf("%s: reading errlog failed\n", DEVNAME(sc));
8814 		return;
8815 	}
8816 
8817 	if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
8818 		printf("%s: Start UMAC Error Log Dump:\n", DEVNAME(sc));
8819 		printf("%s: Status: 0x%x, count: %d\n", DEVNAME(sc),
8820 			sc->sc_flags, table.valid);
8821 	}
8822 
8823 	printf("%s: 0x%08X | %s\n", DEVNAME(sc), table.error_id,
8824 		iwx_desc_lookup(table.error_id));
8825 	printf("%s: 0x%08X | umac branchlink1\n", DEVNAME(sc), table.blink1);
8826 	printf("%s: 0x%08X | umac branchlink2\n", DEVNAME(sc), table.blink2);
8827 	printf("%s: 0x%08X | umac interruptlink1\n", DEVNAME(sc), table.ilink1);
8828 	printf("%s: 0x%08X | umac interruptlink2\n", DEVNAME(sc), table.ilink2);
8829 	printf("%s: 0x%08X | umac data1\n", DEVNAME(sc), table.data1);
8830 	printf("%s: 0x%08X | umac data2\n", DEVNAME(sc), table.data2);
8831 	printf("%s: 0x%08X | umac data3\n", DEVNAME(sc), table.data3);
8832 	printf("%s: 0x%08X | umac major\n", DEVNAME(sc), table.umac_major);
8833 	printf("%s: 0x%08X | umac minor\n", DEVNAME(sc), table.umac_minor);
8834 	printf("%s: 0x%08X | frame pointer\n", DEVNAME(sc),
8835 	    table.frame_pointer);
8836 	printf("%s: 0x%08X | stack pointer\n", DEVNAME(sc),
8837 	    table.stack_pointer);
8838 	printf("%s: 0x%08X | last host cmd\n", DEVNAME(sc), table.cmd_header);
8839 	printf("%s: 0x%08X | isr status reg\n", DEVNAME(sc),
8840 	    table.nic_isr_pref);
8841 }
8842 
8843 #define IWX_FW_SYSASSERT_CPU_MASK 0xf0000000
8844 static struct {
8845 	const char *name;
8846 	uint8_t num;
8847 } advanced_lookup[] = {
8848 	{ "NMI_INTERRUPT_WDG", 0x34 },
8849 	{ "SYSASSERT", 0x35 },
8850 	{ "UCODE_VERSION_MISMATCH", 0x37 },
8851 	{ "BAD_COMMAND", 0x38 },
8852 	{ "BAD_COMMAND", 0x39 },
8853 	{ "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
8854 	{ "FATAL_ERROR", 0x3D },
8855 	{ "NMI_TRM_HW_ERR", 0x46 },
8856 	{ "NMI_INTERRUPT_TRM", 0x4C },
8857 	{ "NMI_INTERRUPT_BREAK_POINT", 0x54 },
8858 	{ "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
8859 	{ "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
8860 	{ "NMI_INTERRUPT_HOST", 0x66 },
8861 	{ "NMI_INTERRUPT_LMAC_FATAL", 0x70 },
8862 	{ "NMI_INTERRUPT_UMAC_FATAL", 0x71 },
8863 	{ "NMI_INTERRUPT_OTHER_LMAC_FATAL", 0x73 },
8864 	{ "NMI_INTERRUPT_ACTION_PT", 0x7C },
8865 	{ "NMI_INTERRUPT_UNKNOWN", 0x84 },
8866 	{ "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
8867 	{ "ADVANCED_SYSASSERT", 0 },
8868 };
8869 
8870 static const char *
iwx_desc_lookup(uint32_t num)8871 iwx_desc_lookup(uint32_t num)
8872 {
8873 	int i;
8874 
8875 	for (i = 0; i < nitems(advanced_lookup) - 1; i++)
8876 		if (advanced_lookup[i].num ==
8877 		    (num & ~IWX_FW_SYSASSERT_CPU_MASK))
8878 			return advanced_lookup[i].name;
8879 
8880 	/* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */
8881 	return advanced_lookup[i].name;
8882 }
8883 
8884 /*
8885  * Support for dumping the error log seemed like a good idea ...
8886  * but it's mostly hex junk and the only sensible thing is the
8887  * hw/ucode revision (which we know anyway).  Since it's here,
8888  * I'll just leave it in, just in case e.g. the Intel guys want to
8889  * help us decipher some "ADVANCED_SYSASSERT" later.
8890  */
8891 static void
iwx_nic_error(struct iwx_softc * sc)8892 iwx_nic_error(struct iwx_softc *sc)
8893 {
8894 	struct iwx_error_event_table table;
8895 	uint32_t base;
8896 
8897 	printf("%s: dumping device error log\n", DEVNAME(sc));
8898 	printf("%s: GOS-3758: 1\n", __func__);
8899 	base = sc->sc_uc.uc_lmac_error_event_table[0];
8900 	printf("%s: GOS-3758: 2\n", __func__);
8901 	if (base < 0x400000) {
8902 		printf("%s: Invalid error log pointer 0x%08x\n",
8903 		    DEVNAME(sc), base);
8904 		return;
8905 	}
8906 
8907 	printf("%s: GOS-3758: 3\n", __func__);
8908 	if (iwx_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t))) {
8909 		printf("%s: reading errlog failed\n", DEVNAME(sc));
8910 		return;
8911 	}
8912 
8913 	printf("%s: GOS-3758: 4\n", __func__);
8914 	if (!table.valid) {
8915 		printf("%s: errlog not found, skipping\n", DEVNAME(sc));
8916 		return;
8917 	}
8918 
8919 	printf("%s: GOS-3758: 5\n", __func__);
8920 	if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
8921 		printf("%s: Start Error Log Dump:\n", DEVNAME(sc));
8922 		printf("%s: Status: 0x%x, count: %d\n", DEVNAME(sc),
8923 		    sc->sc_flags, table.valid);
8924 	}
8925 
8926 	printf("%s: GOS-3758: 6\n", __func__);
8927 	printf("%s: 0x%08X | %-28s\n", DEVNAME(sc), table.error_id,
8928 	    iwx_desc_lookup(table.error_id));
8929 	printf("%s: %08X | trm_hw_status0\n", DEVNAME(sc),
8930 	    table.trm_hw_status0);
8931 	printf("%s: %08X | trm_hw_status1\n", DEVNAME(sc),
8932 	    table.trm_hw_status1);
8933 	printf("%s: %08X | branchlink2\n", DEVNAME(sc), table.blink2);
8934 	printf("%s: %08X | interruptlink1\n", DEVNAME(sc), table.ilink1);
8935 	printf("%s: %08X | interruptlink2\n", DEVNAME(sc), table.ilink2);
8936 	printf("%s: %08X | data1\n", DEVNAME(sc), table.data1);
8937 	printf("%s: %08X | data2\n", DEVNAME(sc), table.data2);
8938 	printf("%s: %08X | data3\n", DEVNAME(sc), table.data3);
8939 	printf("%s: %08X | beacon time\n", DEVNAME(sc), table.bcon_time);
8940 	printf("%s: %08X | tsf low\n", DEVNAME(sc), table.tsf_low);
8941 	printf("%s: %08X | tsf hi\n", DEVNAME(sc), table.tsf_hi);
8942 	printf("%s: %08X | time gp1\n", DEVNAME(sc), table.gp1);
8943 	printf("%s: %08X | time gp2\n", DEVNAME(sc), table.gp2);
8944 	printf("%s: %08X | uCode revision type\n", DEVNAME(sc),
8945 	    table.fw_rev_type);
8946 	printf("%s: %08X | uCode version major\n", DEVNAME(sc),
8947 	    table.major);
8948 	printf("%s: %08X | uCode version minor\n", DEVNAME(sc),
8949 	    table.minor);
8950 	printf("%s: %08X | hw version\n", DEVNAME(sc), table.hw_ver);
8951 	printf("%s: %08X | board version\n", DEVNAME(sc), table.brd_ver);
8952 	printf("%s: %08X | hcmd\n", DEVNAME(sc), table.hcmd);
8953 	printf("%s: %08X | isr0\n", DEVNAME(sc), table.isr0);
8954 	printf("%s: %08X | isr1\n", DEVNAME(sc), table.isr1);
8955 	printf("%s: %08X | isr2\n", DEVNAME(sc), table.isr2);
8956 	printf("%s: %08X | isr3\n", DEVNAME(sc), table.isr3);
8957 	printf("%s: %08X | isr4\n", DEVNAME(sc), table.isr4);
8958 	printf("%s: %08X | last cmd Id\n", DEVNAME(sc), table.last_cmd_id);
8959 	printf("%s: %08X | wait_event\n", DEVNAME(sc), table.wait_event);
8960 	printf("%s: %08X | l2p_control\n", DEVNAME(sc), table.l2p_control);
8961 	printf("%s: %08X | l2p_duration\n", DEVNAME(sc), table.l2p_duration);
8962 	printf("%s: %08X | l2p_mhvalid\n", DEVNAME(sc), table.l2p_mhvalid);
8963 	printf("%s: %08X | l2p_addr_match\n", DEVNAME(sc), table.l2p_addr_match);
8964 	printf("%s: %08X | lmpm_pmg_sel\n", DEVNAME(sc), table.lmpm_pmg_sel);
8965 	printf("%s: %08X | timestamp\n", DEVNAME(sc), table.u_timestamp);
8966 	printf("%s: %08X | flow_handler\n", DEVNAME(sc), table.flow_handler);
8967 
8968 	if (sc->sc_uc.uc_umac_error_event_table)
8969 		iwx_nic_umac_error(sc);
8970 }
8971 
8972 static void
iwx_dump_driver_status(struct iwx_softc * sc)8973 iwx_dump_driver_status(struct iwx_softc *sc)
8974 {
8975 	struct ieee80211com *ic = &sc->sc_ic;
8976 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8977 	enum ieee80211_state state = vap->iv_state;
8978 	int i;
8979 
8980 	printf("driver status:\n");
8981 	for (i = 0; i < nitems(sc->txq); i++) {
8982 		struct iwx_tx_ring *ring = &sc->txq[i];
8983 		printf("  tx ring %2d: qid=%-2d cur=%-3d "
8984 		    "cur_hw=%-3d queued=%-3d\n",
8985 		    i, ring->qid, ring->cur, ring->cur_hw,
8986 		    ring->queued);
8987 	}
8988 	printf("  rx ring: cur=%d\n", sc->rxq.cur);
8989 	printf("  802.11 state %s\n", ieee80211_state_name[state]);
8990 }
8991 
8992 #define SYNC_RESP_STRUCT(_var_, _pkt_)					\
8993 do {									\
8994 	bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); \
8995 	_var_ = (void *)((_pkt_)+1);					\
8996 } while (/*CONSTCOND*/0)
8997 
8998 static int
iwx_rx_pkt_valid(struct iwx_rx_packet * pkt)8999 iwx_rx_pkt_valid(struct iwx_rx_packet *pkt)
9000 {
9001 	int qid, idx, code;
9002 
9003 	qid = pkt->hdr.qid & ~0x80;
9004 	idx = pkt->hdr.idx;
9005 	code = IWX_WIDE_ID(pkt->hdr.flags, pkt->hdr.code);
9006 
9007 	return (!(qid == 0 && idx == 0 && code == 0) &&
9008 	    pkt->len_n_flags != htole32(IWX_FH_RSCSR_FRAME_INVALID));
9009 }
9010 
9011 static void
iwx_rx_pkt(struct iwx_softc * sc,struct iwx_rx_data * data,struct mbuf * ml)9012 iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *data, struct mbuf *ml)
9013 {
9014 	struct ieee80211com *ic = &sc->sc_ic;
9015 	struct iwx_rx_packet *pkt, *nextpkt;
9016 	uint32_t offset = 0, nextoff = 0, nmpdu = 0, len;
9017 	struct mbuf *m0, *m;
9018 	const size_t minsz = sizeof(pkt->len_n_flags) + sizeof(pkt->hdr);
9019 	int qid, idx, code, handled = 1;
9020 
9021 	m0 = data->m;
9022 	while (m0 && offset + minsz < IWX_RBUF_SIZE) {
9023 		pkt = (struct iwx_rx_packet *)(m0->m_data + offset);
9024 		qid = pkt->hdr.qid;
9025 		idx = pkt->hdr.idx;
9026 		code = IWX_WIDE_ID(pkt->hdr.flags, pkt->hdr.code);
9027 
9028 		if (!iwx_rx_pkt_valid(pkt))
9029 			break;
9030 
9031 		/*
9032 		 * XXX Intel inside (tm)
9033 		 * Any commands in the LONG_GROUP could actually be in the
9034 		 * LEGACY group. Firmware API versions >= 50 reject commands
9035 		 * in group 0, forcing us to use this hack.
9036 		 */
9037 		if (iwx_cmd_groupid(code) == IWX_LONG_GROUP) {
9038 			struct iwx_tx_ring *ring = &sc->txq[qid];
9039 			struct iwx_tx_data *txdata = &ring->data[idx];
9040 			if (txdata->flags & IWX_TXDATA_FLAG_CMD_IS_NARROW)
9041 				code = iwx_cmd_opcode(code);
9042 		}
9043 
9044 		len = sizeof(pkt->len_n_flags) + iwx_rx_packet_len(pkt);
9045 		if (len < minsz || len > (IWX_RBUF_SIZE - offset))
9046 			break;
9047 
9048 		// TODO ???
9049 		if (code == IWX_REPLY_RX_MPDU_CMD && ++nmpdu == 1) {
9050 			/* Take mbuf m0 off the RX ring. */
9051 			if (iwx_rx_addbuf(sc, IWX_RBUF_SIZE, sc->rxq.cur)) {
9052 				break;
9053 			}
9054 			KASSERT((data->m != m0), ("%s: data->m != m0", __func__));
9055 		}
9056 
9057 		switch (code) {
9058 		case IWX_REPLY_RX_PHY_CMD:
9059 			/* XXX-THJ: I've not managed to hit this path in testing */
9060 			iwx_rx_rx_phy_cmd(sc, pkt, data);
9061 			break;
9062 
9063 		case IWX_REPLY_RX_MPDU_CMD: {
9064 			size_t maxlen = IWX_RBUF_SIZE - offset - minsz;
9065 			nextoff = offset +
9066 			    roundup(len, IWX_FH_RSCSR_FRAME_ALIGN);
9067 			nextpkt = (struct iwx_rx_packet *)
9068 			    (m0->m_data + nextoff);
9069 			/* AX210 devices ship only one packet per Rx buffer. */
9070 			if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210 ||
9071 			    nextoff + minsz >= IWX_RBUF_SIZE ||
9072 			    !iwx_rx_pkt_valid(nextpkt)) {
9073 				/* No need to copy last frame in buffer. */
9074 				if (offset > 0)
9075 					m_adj(m0, offset);
9076 				iwx_rx_mpdu_mq(sc, m0, pkt->data, maxlen);
9077 				m0 = NULL; /* stack owns m0 now; abort loop */
9078 			} else {
9079 				/*
9080 				 * Create an mbuf which points to the current
9081 				 * packet. Always copy from offset zero to
9082 				 * preserve m_pkthdr.
9083 				 */
9084 				m = m_copym(m0, 0, M_COPYALL, M_NOWAIT);
9085 				if (m == NULL) {
9086 					m_freem(m0);
9087 					m0 = NULL;
9088 					break;
9089 				}
9090 				m_adj(m, offset);
9091 				iwx_rx_mpdu_mq(sc, m, pkt->data, maxlen);
9092 			}
9093 			break;
9094 		}
9095 
9096 //		case IWX_BAR_FRAME_RELEASE:
9097 //			iwx_rx_bar_frame_release(sc, pkt, ml);
9098 //			break;
9099 //
9100 		case IWX_TX_CMD:
9101 			iwx_rx_tx_cmd(sc, pkt, data);
9102 			break;
9103 
9104 		case IWX_BA_NOTIF:
9105 			iwx_rx_compressed_ba(sc, pkt);
9106 			break;
9107 
9108 		case IWX_MISSED_BEACONS_NOTIFICATION:
9109 			IWX_DPRINTF(sc, IWX_DEBUG_BEACON,
9110 			    "%s: IWX_MISSED_BEACONS_NOTIFICATION\n",
9111 			    __func__);
9112 			iwx_rx_bmiss(sc, pkt, data);
9113 			break;
9114 
9115 		case IWX_MFUART_LOAD_NOTIFICATION:
9116 			break;
9117 
9118 		case IWX_ALIVE: {
9119 			struct iwx_alive_resp_v4 *resp4;
9120 			struct iwx_alive_resp_v5 *resp5;
9121 			struct iwx_alive_resp_v6 *resp6;
9122 
9123 			DPRINTF(("%s: firmware alive\n", __func__));
9124 			sc->sc_uc.uc_ok = 0;
9125 
9126 			/*
9127 			 * For v5 and above, we can check the version, for older
9128 			 * versions we need to check the size.
9129 			 */
9130 			 if (iwx_lookup_notif_ver(sc, IWX_LEGACY_GROUP,
9131 			    IWX_ALIVE) == 6) {
9132 				SYNC_RESP_STRUCT(resp6, pkt);
9133 				if (iwx_rx_packet_payload_len(pkt) !=
9134 				    sizeof(*resp6)) {
9135 					sc->sc_uc.uc_intr = 1;
9136 					wakeup(&sc->sc_uc);
9137 					break;
9138 				}
9139 				sc->sc_uc.uc_lmac_error_event_table[0] = le32toh(
9140 				    resp6->lmac_data[0].dbg_ptrs.error_event_table_ptr);
9141 				sc->sc_uc.uc_lmac_error_event_table[1] = le32toh(
9142 				    resp6->lmac_data[1].dbg_ptrs.error_event_table_ptr);
9143 				sc->sc_uc.uc_log_event_table = le32toh(
9144 				    resp6->lmac_data[0].dbg_ptrs.log_event_table_ptr);
9145 				sc->sc_uc.uc_umac_error_event_table = le32toh(
9146 				    resp6->umac_data.dbg_ptrs.error_info_addr);
9147 				sc->sc_sku_id[0] =
9148 				    le32toh(resp6->sku_id.data[0]);
9149 				sc->sc_sku_id[1] =
9150 				    le32toh(resp6->sku_id.data[1]);
9151 				sc->sc_sku_id[2] =
9152 				    le32toh(resp6->sku_id.data[2]);
9153 				if (resp6->status == IWX_ALIVE_STATUS_OK) {
9154 					sc->sc_uc.uc_ok = 1;
9155 				}
9156 			 } else if (iwx_lookup_notif_ver(sc, IWX_LEGACY_GROUP,
9157 			    IWX_ALIVE) == 5) {
9158 				SYNC_RESP_STRUCT(resp5, pkt);
9159 				if (iwx_rx_packet_payload_len(pkt) !=
9160 				    sizeof(*resp5)) {
9161 					sc->sc_uc.uc_intr = 1;
9162 					wakeup(&sc->sc_uc);
9163 					break;
9164 				}
9165 				sc->sc_uc.uc_lmac_error_event_table[0] = le32toh(
9166 				    resp5->lmac_data[0].dbg_ptrs.error_event_table_ptr);
9167 				sc->sc_uc.uc_lmac_error_event_table[1] = le32toh(
9168 				    resp5->lmac_data[1].dbg_ptrs.error_event_table_ptr);
9169 				sc->sc_uc.uc_log_event_table = le32toh(
9170 				    resp5->lmac_data[0].dbg_ptrs.log_event_table_ptr);
9171 				sc->sc_uc.uc_umac_error_event_table = le32toh(
9172 				    resp5->umac_data.dbg_ptrs.error_info_addr);
9173 				sc->sc_sku_id[0] =
9174 				    le32toh(resp5->sku_id.data[0]);
9175 				sc->sc_sku_id[1] =
9176 				    le32toh(resp5->sku_id.data[1]);
9177 				sc->sc_sku_id[2] =
9178 				    le32toh(resp5->sku_id.data[2]);
9179 				if (resp5->status == IWX_ALIVE_STATUS_OK)
9180 					sc->sc_uc.uc_ok = 1;
9181 			} else if (iwx_rx_packet_payload_len(pkt) == sizeof(*resp4)) {
9182 				SYNC_RESP_STRUCT(resp4, pkt);
9183 				sc->sc_uc.uc_lmac_error_event_table[0] = le32toh(
9184 				    resp4->lmac_data[0].dbg_ptrs.error_event_table_ptr);
9185 				sc->sc_uc.uc_lmac_error_event_table[1] = le32toh(
9186 				    resp4->lmac_data[1].dbg_ptrs.error_event_table_ptr);
9187 				sc->sc_uc.uc_log_event_table = le32toh(
9188 				    resp4->lmac_data[0].dbg_ptrs.log_event_table_ptr);
9189 				sc->sc_uc.uc_umac_error_event_table = le32toh(
9190 				    resp4->umac_data.dbg_ptrs.error_info_addr);
9191 				if (resp4->status == IWX_ALIVE_STATUS_OK)
9192 					sc->sc_uc.uc_ok = 1;
9193 			} else
9194 				printf("unknown payload version");
9195 
9196 			sc->sc_uc.uc_intr = 1;
9197 			wakeup(&sc->sc_uc);
9198 			break;
9199 		}
9200 
9201 		/*
9202 		 * TODO: is this the right struct to use? Look at what
9203 		 * mvm is doing for statistics notification (eg
9204 		 * iwl_mvm_handle_rx_statistics() .
9205 		 */
9206 		case IWX_STATISTICS_NOTIFICATION: {
9207 			struct iwx_notif_statistics *stats;
9208 			SYNC_RESP_STRUCT(stats, pkt);
9209 			memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats));
9210 			sc->sc_noise = iwx_get_noise(sc, &stats->rx.general);
9211 			break;
9212 		}
9213 
9214 		case IWX_DTS_MEASUREMENT_NOTIFICATION:
9215 		case IWX_WIDE_ID(IWX_PHY_OPS_GROUP,
9216 				 IWX_DTS_MEASUREMENT_NOTIF_WIDE):
9217 		case IWX_WIDE_ID(IWX_PHY_OPS_GROUP,
9218 				 IWX_TEMP_REPORTING_THRESHOLDS_CMD):
9219 			break;
9220 
9221 		case IWX_WIDE_ID(IWX_PHY_OPS_GROUP,
9222 		    IWX_CT_KILL_NOTIFICATION): {
9223 			struct iwx_ct_kill_notif *notif;
9224 			SYNC_RESP_STRUCT(notif, pkt);
9225 			printf("%s: device at critical temperature (%u degC), "
9226 			    "stopping device\n",
9227 			    DEVNAME(sc), le16toh(notif->temperature));
9228 			sc->sc_flags |= IWX_FLAG_HW_ERR;
9229 			ieee80211_restart_all(ic);
9230 			break;
9231 		}
9232 
9233 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
9234 		    IWX_SCD_QUEUE_CONFIG_CMD):
9235 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
9236 		    IWX_RX_BAID_ALLOCATION_CONFIG_CMD):
9237 		case IWX_WIDE_ID(IWX_MAC_CONF_GROUP,
9238 		    IWX_SESSION_PROTECTION_CMD):
9239 		case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
9240 		    IWX_NVM_GET_INFO):
9241 		case IWX_ADD_STA_KEY:
9242 		case IWX_PHY_CONFIGURATION_CMD:
9243 		case IWX_TX_ANT_CONFIGURATION_CMD:
9244 		case IWX_ADD_STA:
9245 		case IWX_MAC_CONTEXT_CMD:
9246 		case IWX_REPLY_SF_CFG_CMD:
9247 		case IWX_POWER_TABLE_CMD:
9248 		case IWX_LTR_CONFIG:
9249 		case IWX_PHY_CONTEXT_CMD:
9250 		case IWX_BINDING_CONTEXT_CMD:
9251 		case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_CFG_CMD):
9252 		case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_REQ_UMAC):
9253 		case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_ABORT_UMAC):
9254 		case IWX_REPLY_BEACON_FILTERING_CMD:
9255 		case IWX_MAC_PM_POWER_TABLE:
9256 		case IWX_TIME_QUOTA_CMD:
9257 		case IWX_REMOVE_STA:
9258 		case IWX_TXPATH_FLUSH:
9259 		case IWX_BT_CONFIG:
9260 		case IWX_MCC_UPDATE_CMD:
9261 		case IWX_TIME_EVENT_CMD:
9262 		case IWX_STATISTICS_CMD:
9263 		case IWX_SCD_QUEUE_CFG: {
9264 			size_t pkt_len;
9265 
9266 			if (sc->sc_cmd_resp_pkt[idx] == NULL)
9267 				break;
9268 
9269 			bus_dmamap_sync(sc->rxq.data_dmat, data->map,
9270 			    BUS_DMASYNC_POSTREAD);
9271 
9272 			pkt_len = sizeof(pkt->len_n_flags) +
9273 			    iwx_rx_packet_len(pkt);
9274 
9275 			if ((pkt->hdr.flags & IWX_CMD_FAILED_MSK) ||
9276 			    pkt_len < sizeof(*pkt) ||
9277 			    pkt_len > sc->sc_cmd_resp_len[idx]) {
9278 				free(sc->sc_cmd_resp_pkt[idx], M_DEVBUF);
9279 				sc->sc_cmd_resp_pkt[idx] = NULL;
9280 				break;
9281 			}
9282 
9283 			bus_dmamap_sync(sc->rxq.data_dmat, data->map,
9284 			    BUS_DMASYNC_POSTREAD);
9285 			memcpy(sc->sc_cmd_resp_pkt[idx], pkt, pkt_len);
9286 			break;
9287 		}
9288 
9289 		case IWX_INIT_COMPLETE_NOTIF:
9290 			sc->sc_init_complete |= IWX_INIT_COMPLETE;
9291 			wakeup(&sc->sc_init_complete);
9292 			break;
9293 
9294 		case IWX_SCAN_COMPLETE_UMAC: {
9295 			DPRINTF(("%s: >>> IWX_SCAN_COMPLETE_UMAC\n", __func__));
9296 			struct iwx_umac_scan_complete *notif __attribute__((unused));
9297 			SYNC_RESP_STRUCT(notif, pkt);
9298 			DPRINTF(("%s: scan complete notif->status=%d\n", __func__,
9299 			    notif->status));
9300 			ieee80211_runtask(&sc->sc_ic, &sc->sc_es_task);
9301 			iwx_endscan(sc);
9302 			break;
9303 		}
9304 
9305 		case IWX_SCAN_ITERATION_COMPLETE_UMAC: {
9306 			DPRINTF(("%s: >>> IWX_SCAN_ITERATION_COMPLETE_UMAC\n",
9307 			    __func__));
9308 			struct iwx_umac_scan_iter_complete_notif *notif __attribute__((unused));
9309 			SYNC_RESP_STRUCT(notif, pkt);
9310 			DPRINTF(("%s: iter scan complete notif->status=%d\n", __func__,
9311 			    notif->status));
9312 			iwx_endscan(sc);
9313 			break;
9314 		}
9315 
9316 		case IWX_MCC_CHUB_UPDATE_CMD: {
9317 			struct iwx_mcc_chub_notif *notif;
9318 			SYNC_RESP_STRUCT(notif, pkt);
9319 			iwx_mcc_update(sc, notif);
9320 			break;
9321 		}
9322 
9323 		case IWX_REPLY_ERROR: {
9324 			struct iwx_error_resp *resp;
9325 			SYNC_RESP_STRUCT(resp, pkt);
9326 			printf("%s: firmware error 0x%x, cmd 0x%x\n",
9327 				DEVNAME(sc), le32toh(resp->error_type),
9328 				resp->cmd_id);
9329 			break;
9330 		}
9331 
9332 		case IWX_TIME_EVENT_NOTIFICATION: {
9333 			struct iwx_time_event_notif *notif;
9334 			uint32_t action;
9335 			SYNC_RESP_STRUCT(notif, pkt);
9336 
9337 			if (sc->sc_time_event_uid != le32toh(notif->unique_id))
9338 				break;
9339 			action = le32toh(notif->action);
9340 			if (action & IWX_TE_V2_NOTIF_HOST_EVENT_END)
9341 				sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE;
9342 			break;
9343 		}
9344 
9345 		case IWX_WIDE_ID(IWX_MAC_CONF_GROUP,
9346 		    IWX_SESSION_PROTECTION_NOTIF): {
9347 			struct iwx_session_prot_notif *notif;
9348 			uint32_t status, start, conf_id;
9349 
9350 			SYNC_RESP_STRUCT(notif, pkt);
9351 
9352 			status = le32toh(notif->status);
9353 			start = le32toh(notif->start);
9354 			conf_id = le32toh(notif->conf_id);
9355 			/* Check for end of successful PROTECT_CONF_ASSOC. */
9356 			if (status == 1 && start == 0 &&
9357 			    conf_id == IWX_SESSION_PROTECT_CONF_ASSOC)
9358 				sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE;
9359 			break;
9360 		}
9361 
9362 		case IWX_WIDE_ID(IWX_SYSTEM_GROUP,
9363 		    IWX_FSEQ_VER_MISMATCH_NOTIFICATION):
9364 		    break;
9365 
9366 		/*
9367 		 * Firmware versions 21 and 22 generate some DEBUG_LOG_MSG
9368 		 * messages. Just ignore them for now.
9369 		 */
9370 		case IWX_DEBUG_LOG_MSG:
9371 			break;
9372 
9373 		case IWX_MCAST_FILTER_CMD:
9374 			break;
9375 
9376 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_DQA_ENABLE_CMD):
9377 			break;
9378 
9379 		case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_SOC_CONFIGURATION_CMD):
9380 			break;
9381 
9382 		case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_INIT_EXTENDED_CFG_CMD):
9383 			break;
9384 
9385 		case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
9386 		    IWX_NVM_ACCESS_COMPLETE):
9387 			break;
9388 
9389 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_RX_NO_DATA_NOTIF):
9390 			break; /* happens in monitor mode; ignore for now */
9391 
9392 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_TLC_MNG_CONFIG_CMD):
9393 			break;
9394 
9395 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
9396 		    IWX_TLC_MNG_UPDATE_NOTIF): {
9397 			struct iwx_tlc_update_notif *notif;
9398 			SYNC_RESP_STRUCT(notif, pkt);
9399 			(void)notif;
9400 			if (iwx_rx_packet_payload_len(pkt) == sizeof(*notif))
9401 				iwx_rs_update(sc, notif);
9402 			break;
9403 		}
9404 
9405 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_RLC_CONFIG_CMD):
9406 			break;
9407 
9408 		/* undocumented notification from iwx-ty-a0-gf-a0-77 image */
9409 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 0xf8):
9410 			break;
9411 
9412 		case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
9413 		    IWX_PNVM_INIT_COMPLETE):
9414 			DPRINTF(("%s: IWX_PNVM_INIT_COMPLETE\n", __func__));
9415 			sc->sc_init_complete |= IWX_PNVM_COMPLETE;
9416 			wakeup(&sc->sc_init_complete);
9417 			break;
9418 
9419 		default:
9420 			handled = 0;
9421 			/* XXX wulf: Get rid of bluetooth-related spam */
9422 			if ((code == 0xc2 && pkt->len_n_flags == 0x0000000c) ||
9423 			    (code == 0xce && pkt->len_n_flags == 0x2000002c))
9424 				break;
9425 			printf("%s: unhandled firmware response 0x%x/0x%x "
9426 			    "rx ring %d[%d]\n",
9427 			    DEVNAME(sc), code, pkt->len_n_flags,
9428 			    (qid & ~0x80), idx);
9429 			break;
9430 		}
9431 
9432 		/*
9433 		 * uCode sets bit 0x80 when it originates the notification,
9434 		 * i.e. when the notification is not a direct response to a
9435 		 * command sent by the driver.
9436 		 * For example, uCode issues IWX_REPLY_RX when it sends a
9437 		 * received frame to the driver.
9438 		 */
9439 		if (handled && !(qid & (1 << 7))) {
9440 			iwx_cmd_done(sc, qid, idx, code);
9441 		}
9442 
9443 		offset += roundup(len, IWX_FH_RSCSR_FRAME_ALIGN);
9444 
9445 		/* AX210 devices ship only one packet per Rx buffer. */
9446 		if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
9447 			break;
9448 	}
9449 
9450 	if (m0 && m0 != data->m)
9451 		m_freem(m0);
9452 }
9453 
9454 static void
iwx_notif_intr(struct iwx_softc * sc)9455 iwx_notif_intr(struct iwx_softc *sc)
9456 {
9457 	struct mbuf m;
9458 	uint16_t hw;
9459 
9460 	bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map,
9461 	    BUS_DMASYNC_POSTREAD);
9462 
9463 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
9464 		uint16_t *status = sc->rxq.stat_dma.vaddr;
9465 		hw = le16toh(*status) & 0xfff;
9466 	} else
9467 		hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff;
9468 	hw &= (IWX_RX_MQ_RING_COUNT - 1);
9469 	while (sc->rxq.cur != hw) {
9470 		struct iwx_rx_data *data = &sc->rxq.data[sc->rxq.cur];
9471 
9472 		bus_dmamap_sync(sc->rxq.data_dmat, data->map,
9473 		BUS_DMASYNC_POSTREAD);
9474 
9475 		iwx_rx_pkt(sc, data, &m);
9476 		sc->rxq.cur = (sc->rxq.cur + 1) % IWX_RX_MQ_RING_COUNT;
9477 	}
9478 
9479 	/*
9480 	 * Tell the firmware what we have processed.
9481 	 * Seems like the hardware gets upset unless we align the write by 8??
9482 	 */
9483 	hw = (hw == 0) ? IWX_RX_MQ_RING_COUNT - 1 : hw - 1;
9484 	IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, hw & ~7);
9485 }
9486 
9487 #if 0
9488 int
9489 iwx_intr(void *arg)
9490 {
9491 	struct iwx_softc *sc = arg;
9492 	struct ieee80211com *ic = &sc->sc_ic;
9493 	struct ifnet *ifp = IC2IFP(ic);
9494 	int r1, r2, rv = 0;
9495 
9496 	IWX_WRITE(sc, IWX_CSR_INT_MASK, 0);
9497 
9498 	if (sc->sc_flags & IWX_FLAG_USE_ICT) {
9499 		uint32_t *ict = sc->ict_dma.vaddr;
9500 		int tmp;
9501 
9502 		tmp = htole32(ict[sc->ict_cur]);
9503 		if (!tmp)
9504 			goto out_ena;
9505 
9506 		/*
9507 		 * ok, there was something.  keep plowing until we have all.
9508 		 */
9509 		r1 = r2 = 0;
9510 		while (tmp) {
9511 			r1 |= tmp;
9512 			ict[sc->ict_cur] = 0;
9513 			sc->ict_cur = (sc->ict_cur+1) % IWX_ICT_COUNT;
9514 			tmp = htole32(ict[sc->ict_cur]);
9515 		}
9516 
9517 		/* this is where the fun begins.  don't ask */
9518 		if (r1 == 0xffffffff)
9519 			r1 = 0;
9520 
9521 		/* i am not expected to understand this */
9522 		if (r1 & 0xc0000)
9523 			r1 |= 0x8000;
9524 		r1 = (0xff & r1) | ((0xff00 & r1) << 16);
9525 	} else {
9526 		r1 = IWX_READ(sc, IWX_CSR_INT);
9527 		if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
9528 			goto out;
9529 		r2 = IWX_READ(sc, IWX_CSR_FH_INT_STATUS);
9530 	}
9531 	if (r1 == 0 && r2 == 0) {
9532 		goto out_ena;
9533 	}
9534 
9535 	IWX_WRITE(sc, IWX_CSR_INT, r1 | ~sc->sc_intmask);
9536 
9537 	if (r1 & IWX_CSR_INT_BIT_ALIVE) {
9538 #if 0
9539 		int i;
9540 		/* Firmware has now configured the RFH. */
9541 		for (i = 0; i < IWX_RX_MQ_RING_COUNT; i++)
9542 			iwx_update_rx_desc(sc, &sc->rxq, i);
9543 #endif
9544 		IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, 8);
9545 	}
9546 
9547 
9548 	if (r1 & IWX_CSR_INT_BIT_RF_KILL) {
9549 		iwx_check_rfkill(sc);
9550 		rv = 1;
9551 		goto out_ena;
9552 	}
9553 
9554 	if (r1 & IWX_CSR_INT_BIT_SW_ERR) {
9555 		if (ifp->if_flags & IFF_DEBUG) {
9556 			iwx_nic_error(sc);
9557 			iwx_dump_driver_status(sc);
9558 		}
9559 		printf("%s: fatal firmware error\n", DEVNAME(sc));
9560 		ieee80211_restart_all(ic);
9561 		rv = 1;
9562 		goto out;
9563 
9564 	}
9565 
9566 	if (r1 & IWX_CSR_INT_BIT_HW_ERR) {
9567 		printf("%s: hardware error, stopping device \n", DEVNAME(sc));
9568 		iwx_stop(sc);
9569 		rv = 1;
9570 		goto out;
9571 	}
9572 
9573 	/* firmware chunk loaded */
9574 	if (r1 & IWX_CSR_INT_BIT_FH_TX) {
9575 		IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, IWX_CSR_FH_INT_TX_MASK);
9576 
9577 		sc->sc_fw_chunk_done = 1;
9578 		wakeup(&sc->sc_fw);
9579 	}
9580 
9581 	if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX |
9582 	    IWX_CSR_INT_BIT_RX_PERIODIC)) {
9583 		if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX)) {
9584 			IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, IWX_CSR_FH_INT_RX_MASK);
9585 		}
9586 		if (r1 & IWX_CSR_INT_BIT_RX_PERIODIC) {
9587 			IWX_WRITE(sc, IWX_CSR_INT, IWX_CSR_INT_BIT_RX_PERIODIC);
9588 		}
9589 
9590 		/* Disable periodic interrupt; we use it as just a one-shot. */
9591 		IWX_WRITE_1(sc, IWX_CSR_INT_PERIODIC_REG, IWX_CSR_INT_PERIODIC_DIS);
9592 
9593 		/*
9594 		 * Enable periodic interrupt in 8 msec only if we received
9595 		 * real RX interrupt (instead of just periodic int), to catch
9596 		 * any dangling Rx interrupt.  If it was just the periodic
9597 		 * interrupt, there was no dangling Rx activity, and no need
9598 		 * to extend the periodic interrupt; one-shot is enough.
9599 		 */
9600 		if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX))
9601 			IWX_WRITE_1(sc, IWX_CSR_INT_PERIODIC_REG,
9602 			    IWX_CSR_INT_PERIODIC_ENA);
9603 
9604 		iwx_notif_intr(sc);
9605 	}
9606 
9607 	rv = 1;
9608 
9609  out_ena:
9610 	iwx_restore_interrupts(sc);
9611  out:
9612 	return rv;
9613 }
9614 #endif
9615 
9616 static void
iwx_intr_msix(void * arg)9617 iwx_intr_msix(void *arg)
9618 {
9619 	struct iwx_softc *sc = arg;
9620 	struct ieee80211com *ic = &sc->sc_ic;
9621 	uint32_t inta_fh, inta_hw;
9622 	int vector = 0;
9623 
9624 	IWX_LOCK(sc);
9625 
9626 	inta_fh = IWX_READ(sc, IWX_CSR_MSIX_FH_INT_CAUSES_AD);
9627 	inta_hw = IWX_READ(sc, IWX_CSR_MSIX_HW_INT_CAUSES_AD);
9628 	IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_CAUSES_AD, inta_fh);
9629 	IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_CAUSES_AD, inta_hw);
9630 	inta_fh &= sc->sc_fh_mask;
9631 	inta_hw &= sc->sc_hw_mask;
9632 
9633 	if (inta_fh & IWX_MSIX_FH_INT_CAUSES_Q0 ||
9634 	    inta_fh & IWX_MSIX_FH_INT_CAUSES_Q1) {
9635 		iwx_notif_intr(sc);
9636 	}
9637 
9638 	/* firmware chunk loaded */
9639 	if (inta_fh & IWX_MSIX_FH_INT_CAUSES_D2S_CH0_NUM) {
9640 		sc->sc_fw_chunk_done = 1;
9641 		wakeup(&sc->sc_fw);
9642 	}
9643 
9644 	if ((inta_fh & IWX_MSIX_FH_INT_CAUSES_FH_ERR) ||
9645 	    (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_SW_ERR) ||
9646 	    (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_SW_ERR_V2)) {
9647 		if (sc->sc_debug) {
9648 			iwx_nic_error(sc);
9649 			iwx_dump_driver_status(sc);
9650 		}
9651 		printf("%s: fatal firmware error\n", DEVNAME(sc));
9652 		ieee80211_restart_all(ic);
9653 		goto out;
9654 	}
9655 
9656 	if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_RF_KILL) {
9657 		iwx_check_rfkill(sc);
9658 	}
9659 
9660 	if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_HW_ERR) {
9661 		printf("%s: hardware error, stopping device \n", DEVNAME(sc));
9662 		sc->sc_flags |= IWX_FLAG_HW_ERR;
9663 		iwx_stop(sc);
9664 		goto out;
9665 	}
9666 
9667 	if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_ALIVE) {
9668 		IWX_DPRINTF(sc, IWX_DEBUG_TRACE,
9669 		    "%s:%d WARNING: Skipping rx desc update\n",
9670 		    __func__, __LINE__);
9671 #if 0
9672 		/*
9673 		 * XXX-THJ: we don't have the dma segment handy. This is hacked
9674 		 * out in the fc release, return to it if we ever get this
9675 		 * warning.
9676 		 */
9677 		/* Firmware has now configured the RFH. */
9678 		for (int i = 0; i < IWX_RX_MQ_RING_COUNT; i++)
9679 			iwx_update_rx_desc(sc, &sc->rxq, i);
9680 #endif
9681 		IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, 8);
9682 	}
9683 
9684 	/*
9685 	 * Before sending the interrupt the HW disables it to prevent
9686 	 * a nested interrupt. This is done by writing 1 to the corresponding
9687 	 * bit in the mask register. After handling the interrupt, it should be
9688 	 * re-enabled by clearing this bit. This register is defined as
9689 	 * write 1 clear (W1C) register, meaning that it's being clear
9690 	 * by writing 1 to the bit.
9691 	 */
9692 	IWX_WRITE(sc, IWX_CSR_MSIX_AUTOMASK_ST_AD, 1 << vector);
9693 out:
9694 	IWX_UNLOCK(sc);
9695 	return;
9696 }
9697 
9698 /*
9699  * The device info table below contains device-specific config overrides.
9700  * The most important parameter derived from this table is the name of the
9701  * firmware image to load.
9702  *
9703  * The Linux iwlwifi driver uses an "old" and a "new" device info table.
9704  * The "old" table matches devices based on PCI vendor/product IDs only.
9705  * The "new" table extends this with various device parameters derived
9706  * from MAC type, and RF type.
9707  *
9708  * In iwlwifi "old" and "new" tables share the same array, where "old"
9709  * entries contain dummy values for data defined only for "new" entries.
9710  * As of 2022, Linux developers are still in the process of moving entries
9711  * from "old" to "new" style and it looks like this effort has stalled in
9712  * in some work-in-progress state for quite a while. Linux commits moving
9713  * entries from "old" to "new" have at times been reverted due to regressions.
9714  * Part of this complexity comes from iwlwifi supporting both iwm(4) and iwx(4)
9715  * devices in the same driver.
9716  *
9717  * Our table below contains mostly "new" entries declared in iwlwifi
9718  * with the _IWL_DEV_INFO() macro (with a leading underscore).
9719  * Other devices are matched based on PCI vendor/product ID as usual,
9720  * unless matching specific PCI subsystem vendor/product IDs is required.
9721  *
9722  * Some "old"-style entries are required to identify the firmware image to use.
9723  * Others might be used to print a specific marketing name into Linux dmesg,
9724  * but we can't be sure whether the corresponding devices would be matched
9725  * correctly in the absence of their entries. So we include them just in case.
9726  */
9727 
9728 struct iwx_dev_info {
9729 	uint16_t device;
9730 	uint16_t subdevice;
9731 	uint16_t mac_type;
9732 	uint16_t rf_type;
9733 	uint8_t mac_step;
9734 	uint8_t rf_id;
9735 	uint8_t no_160;
9736 	uint8_t cores;
9737 	uint8_t cdb;
9738 	uint8_t jacket;
9739 	const struct iwx_device_cfg *cfg;
9740 };
9741 
9742 #define _IWX_DEV_INFO(_device, _subdevice, _mac_type, _mac_step, _rf_type, \
9743 		      _rf_id, _no_160, _cores, _cdb, _jacket, _cfg) \
9744 	{ .device = (_device), .subdevice = (_subdevice), .cfg = &(_cfg),  \
9745 	  .mac_type = _mac_type, .rf_type = _rf_type,	   \
9746 	  .no_160 = _no_160, .cores = _cores, .rf_id = _rf_id,		   \
9747 	  .mac_step = _mac_step, .cdb = _cdb, .jacket = _jacket }
9748 
9749 #define IWX_DEV_INFO(_device, _subdevice, _cfg) \
9750 	_IWX_DEV_INFO(_device, _subdevice, IWX_CFG_ANY, IWX_CFG_ANY,	   \
9751 		      IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_ANY,  \
9752 		      IWX_CFG_ANY, IWX_CFG_ANY, _cfg)
9753 
9754 /*
9755  * When adding entries to this table keep in mind that entries must
9756  * be listed in the same order as in the Linux driver. Code walks this
9757  * table backwards and uses the first matching entry it finds.
9758  * Device firmware must be available in fw_update(8).
9759  */
9760 static const struct iwx_dev_info iwx_dev_info_table[] = {
9761 	/* So with HR */
9762 	IWX_DEV_INFO(0x2725, 0x0090, iwx_2ax_cfg_so_gf_a0),
9763 	IWX_DEV_INFO(0x2725, 0x0020, iwx_2ax_cfg_ty_gf_a0),
9764 	IWX_DEV_INFO(0x2725, 0x2020, iwx_2ax_cfg_ty_gf_a0),
9765 	IWX_DEV_INFO(0x2725, 0x0024, iwx_2ax_cfg_ty_gf_a0),
9766 	IWX_DEV_INFO(0x2725, 0x0310, iwx_2ax_cfg_ty_gf_a0),
9767 	IWX_DEV_INFO(0x2725, 0x0510, iwx_2ax_cfg_ty_gf_a0),
9768 	IWX_DEV_INFO(0x2725, 0x0A10, iwx_2ax_cfg_ty_gf_a0),
9769 	IWX_DEV_INFO(0x2725, 0xE020, iwx_2ax_cfg_ty_gf_a0),
9770 	IWX_DEV_INFO(0x2725, 0xE024, iwx_2ax_cfg_ty_gf_a0),
9771 	IWX_DEV_INFO(0x2725, 0x4020, iwx_2ax_cfg_ty_gf_a0),
9772 	IWX_DEV_INFO(0x2725, 0x6020, iwx_2ax_cfg_ty_gf_a0),
9773 	IWX_DEV_INFO(0x2725, 0x6024, iwx_2ax_cfg_ty_gf_a0),
9774 	IWX_DEV_INFO(0x2725, 0x1673, iwx_2ax_cfg_ty_gf_a0), /* killer_1675w */
9775 	IWX_DEV_INFO(0x2725, 0x1674, iwx_2ax_cfg_ty_gf_a0), /* killer_1675x */
9776 	IWX_DEV_INFO(0x51f0, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */
9777 	IWX_DEV_INFO(0x51f0, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */
9778 	IWX_DEV_INFO(0x51f1, 0x1691, iwx_2ax_cfg_so_gf4_a0),
9779 	IWX_DEV_INFO(0x51f1, 0x1692, iwx_2ax_cfg_so_gf4_a0),
9780 	IWX_DEV_INFO(0x54f0, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */
9781 	IWX_DEV_INFO(0x54f0, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */
9782 	IWX_DEV_INFO(0x7a70, 0x0090, iwx_2ax_cfg_so_gf_a0_long),
9783 	IWX_DEV_INFO(0x7a70, 0x0098, iwx_2ax_cfg_so_gf_a0_long),
9784 	IWX_DEV_INFO(0x7a70, 0x00b0, iwx_2ax_cfg_so_gf4_a0_long),
9785 	IWX_DEV_INFO(0x7a70, 0x0310, iwx_2ax_cfg_so_gf_a0_long),
9786 	IWX_DEV_INFO(0x7a70, 0x0510, iwx_2ax_cfg_so_gf_a0_long),
9787 	IWX_DEV_INFO(0x7a70, 0x0a10, iwx_2ax_cfg_so_gf_a0_long),
9788 	IWX_DEV_INFO(0x7af0, 0x0090, iwx_2ax_cfg_so_gf_a0),
9789 	IWX_DEV_INFO(0x7af0, 0x0098, iwx_2ax_cfg_so_gf_a0),
9790 	IWX_DEV_INFO(0x7af0, 0x00b0, iwx_2ax_cfg_so_gf4_a0),
9791 	IWX_DEV_INFO(0x7a70, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */
9792 	IWX_DEV_INFO(0x7a70, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */
9793 	IWX_DEV_INFO(0x7af0, 0x0310, iwx_2ax_cfg_so_gf_a0),
9794 	IWX_DEV_INFO(0x7af0, 0x0510, iwx_2ax_cfg_so_gf_a0),
9795 	IWX_DEV_INFO(0x7af0, 0x0a10, iwx_2ax_cfg_so_gf_a0),
9796 	IWX_DEV_INFO(0x7f70, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */
9797 	IWX_DEV_INFO(0x7f70, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */
9798 
9799 	/* So with GF2 */
9800 	IWX_DEV_INFO(0x2726, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9801 	IWX_DEV_INFO(0x2726, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9802 	IWX_DEV_INFO(0x51f0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9803 	IWX_DEV_INFO(0x51f0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9804 	IWX_DEV_INFO(0x54f0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9805 	IWX_DEV_INFO(0x54f0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9806 	IWX_DEV_INFO(0x7a70, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9807 	IWX_DEV_INFO(0x7a70, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9808 	IWX_DEV_INFO(0x7af0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9809 	IWX_DEV_INFO(0x7af0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9810 	IWX_DEV_INFO(0x7f70, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9811 	IWX_DEV_INFO(0x7f70, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9812 
9813 	/* Qu with Jf, C step */
9814 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9815 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9816 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
9817 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9818 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9461_160 */
9819 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9820 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9821 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
9822 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9823 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* iwl9461 */
9824 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9825 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9826 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9827 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9828 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9462_160 */
9829 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9830 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9831 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9832 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9833 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9462 */
9834 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9835 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9836 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9837 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9838 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9560_160 */
9839 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9840 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9841 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9842 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9843 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9560 */
9844 	_IWX_DEV_INFO(IWX_CFG_ANY, 0x1551,
9845 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9846 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9847 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9848 		      IWX_CFG_ANY,
9849 		      iwx_9560_qu_c0_jf_b0_cfg), /* 9560_killer_1550s */
9850 	_IWX_DEV_INFO(IWX_CFG_ANY, 0x1552,
9851 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9852 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9853 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9854 		      IWX_CFG_ANY,
9855 		      iwx_9560_qu_c0_jf_b0_cfg), /* 9560_killer_1550i */
9856 
9857 	/* QuZ with Jf */
9858 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9859 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9860 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9861 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9862 		      IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9461_160 */
9863 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9864 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9865 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9866 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9867 		      IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9461 */
9868 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9869 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9870 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9871 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9872 		      IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9462_160 */
9873 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9874 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9875 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9876 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9877 		      IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9462 */
9878 	_IWX_DEV_INFO(IWX_CFG_ANY, 0x1551,
9879 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9880 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9881 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9882 		      IWX_CFG_ANY,
9883 		      iwx_9560_quz_a0_jf_b0_cfg), /* killer_1550s */
9884 	_IWX_DEV_INFO(IWX_CFG_ANY, 0x1552,
9885 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9886 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9887 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9888 		      IWX_CFG_ANY,
9889 		      iwx_9560_quz_a0_jf_b0_cfg), /* 9560_killer_1550i */
9890 
9891 	/* Qu with Hr, B step */
9892 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9893 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_B_STEP,
9894 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9895 		      IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9896 		      iwx_qu_b0_hr1_b0), /* AX101 */
9897 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9898 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_B_STEP,
9899 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9900 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9901 		      iwx_qu_b0_hr_b0), /* AX203 */
9902 
9903 	/* Qu with Hr, C step */
9904 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9905 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9906 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9907 		      IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9908 		      iwx_qu_c0_hr1_b0), /* AX101 */
9909 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9910 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9911 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9912 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9913 		      iwx_qu_c0_hr_b0), /* AX203 */
9914 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9915 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9916 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9917 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9918 		      iwx_qu_c0_hr_b0), /* AX201 */
9919 
9920 	/* QuZ with Hr */
9921 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9922 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9923 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9924 		      IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9925 		      iwx_quz_a0_hr1_b0), /* AX101 */
9926 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9927 		      IWX_CFG_MAC_TYPE_QUZ, IWX_SILICON_B_STEP,
9928 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9929 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9930 		      iwx_cfg_quz_a0_hr_b0), /* AX203 */
9931 
9932 	/* SoF with JF2 */
9933 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9934 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9935 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9936 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9937 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560_160 */
9938 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9939 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9940 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9941 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9942 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560 */
9943 
9944 	/* SoF with JF */
9945 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9946 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9947 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
9948 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9949 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_160 */
9950 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9951 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9952 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9953 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9954 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462_160 */
9955 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9956 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9957 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
9958 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9959 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_name */
9960 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9961 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9962 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9963 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9964 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462 */
9965 
9966 	/* So with Hr */
9967 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9968 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
9969 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9970 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9971 		      iwx_cfg_so_a0_hr_b0), /* AX203 */
9972 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9973 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
9974 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9975 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9976 		      iwx_cfg_so_a0_hr_b0), /* ax101 */
9977 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9978 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
9979 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9980 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9981 		      iwx_cfg_so_a0_hr_b0), /* ax201 */
9982 
9983 	/* So-F with Hr */
9984 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9985 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9986 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9987 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9988 		      iwx_cfg_so_a0_hr_b0), /* AX203 */
9989 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9990 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9991 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9992 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9993 		      iwx_cfg_so_a0_hr_b0), /* AX101 */
9994 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9995 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9996 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9997 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9998 		      iwx_cfg_so_a0_hr_b0), /* AX201 */
9999 
10000 	/* So-F with GF */
10001 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10002 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
10003 		      IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY,
10004 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
10005 		      iwx_2ax_cfg_so_gf_a0), /* AX211 */
10006 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10007 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
10008 		      IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY,
10009 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_CDB, IWX_CFG_ANY,
10010 		      iwx_2ax_cfg_so_gf4_a0), /* AX411 */
10011 
10012 	/* So with GF */
10013 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10014 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10015 		      IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY,
10016 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
10017 		      iwx_2ax_cfg_so_gf_a0), /* AX211 */
10018 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10019 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10020 		      IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY,
10021 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_CDB, IWX_CFG_ANY,
10022 		      iwx_2ax_cfg_so_gf4_a0), /* AX411 */
10023 
10024 	/* So with JF2 */
10025 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10026 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10027 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
10028 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10029 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560_160 */
10030 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10031 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10032 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
10033 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10034 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560 */
10035 
10036 	/* So with JF */
10037 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10038 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10039 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
10040 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10041 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_160 */
10042 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10043 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10044 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
10045 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10046 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462_160 */
10047 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10048 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10049 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
10050 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10051 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* iwl9461 */
10052 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10053 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10054 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
10055 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10056 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462 */
10057 };
10058 
10059 static int
iwx_preinit(struct iwx_softc * sc)10060 iwx_preinit(struct iwx_softc *sc)
10061 {
10062 	struct ieee80211com *ic = &sc->sc_ic;
10063 	int err;
10064 
10065 	err = iwx_prepare_card_hw(sc);
10066 	if (err) {
10067 		printf("%s: could not initialize hardware\n", DEVNAME(sc));
10068 		return err;
10069 	}
10070 
10071 	if (sc->attached) {
10072 		return 0;
10073 	}
10074 
10075 	err = iwx_start_hw(sc);
10076 	if (err) {
10077 		printf("%s: could not initialize hardware\n", DEVNAME(sc));
10078 		return err;
10079 	}
10080 
10081 	err = iwx_run_init_mvm_ucode(sc, 1);
10082 	iwx_stop_device(sc);
10083 	if (err) {
10084 		printf("%s: failed to stop device\n", DEVNAME(sc));
10085 		return err;
10086 	}
10087 
10088 	/* Print version info and MAC address on first successful fw load. */
10089 	sc->attached = 1;
10090 	if (sc->sc_pnvm_ver) {
10091 		printf("%s: hw rev 0x%x, fw %s, pnvm %08x, "
10092 		    "address %s\n",
10093 		    DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK,
10094 		    sc->sc_fwver, sc->sc_pnvm_ver,
10095 		    ether_sprintf(sc->sc_nvm.hw_addr));
10096 	} else {
10097 		printf("%s: hw rev 0x%x, fw %s, address %s\n",
10098 		    DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK,
10099 		    sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr));
10100 	}
10101 
10102 	/* not all hardware can do 5GHz band */
10103 	if (!sc->sc_nvm.sku_cap_band_52GHz_enable)
10104 		memset(&ic->ic_sup_rates[IEEE80211_MODE_11A], 0,
10105 		    sizeof(ic->ic_sup_rates[IEEE80211_MODE_11A]));
10106 
10107 	return 0;
10108 }
10109 
10110 static void
iwx_attach_hook(void * self)10111 iwx_attach_hook(void *self)
10112 {
10113 	struct iwx_softc *sc = (void *)self;
10114 	struct ieee80211com *ic = &sc->sc_ic;
10115 	int err;
10116 
10117 	IWX_LOCK(sc);
10118 	err = iwx_preinit(sc);
10119 	IWX_UNLOCK(sc);
10120 	if (err != 0)
10121 		goto out;
10122 
10123 	iwx_init_channel_map(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
10124 	    ic->ic_channels);
10125 
10126 	ieee80211_ifattach(ic);
10127 	ic->ic_vap_create = iwx_vap_create;
10128 	ic->ic_vap_delete = iwx_vap_delete;
10129 	ic->ic_raw_xmit = iwx_raw_xmit;
10130 	ic->ic_node_alloc = iwx_node_alloc;
10131 	ic->ic_scan_start = iwx_scan_start;
10132 	ic->ic_scan_end = iwx_scan_end;
10133 	ic->ic_update_mcast = iwx_update_mcast;
10134 	ic->ic_getradiocaps = iwx_init_channel_map;
10135 
10136 	ic->ic_set_channel = iwx_set_channel;
10137 	ic->ic_scan_curchan = iwx_scan_curchan;
10138 	ic->ic_scan_mindwell = iwx_scan_mindwell;
10139 	ic->ic_wme.wme_update = iwx_wme_update;
10140 	ic->ic_parent = iwx_parent;
10141 	ic->ic_transmit = iwx_transmit;
10142 
10143 	sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start;
10144 	ic->ic_ampdu_rx_start = iwx_ampdu_rx_start;
10145 	sc->sc_ampdu_rx_stop = ic->ic_ampdu_rx_stop;
10146 	ic->ic_ampdu_rx_stop = iwx_ampdu_rx_stop;
10147 
10148 	sc->sc_addba_request = ic->ic_addba_request;
10149 	ic->ic_addba_request = iwx_addba_request;
10150 	sc->sc_addba_response = ic->ic_addba_response;
10151 	ic->ic_addba_response = iwx_addba_response;
10152 
10153 	iwx_radiotap_attach(sc);
10154 	ieee80211_announce(ic);
10155 out:
10156 	config_intrhook_disestablish(&sc->sc_preinit_hook);
10157 }
10158 
10159 const struct iwx_device_cfg *
iwx_find_device_cfg(struct iwx_softc * sc)10160 iwx_find_device_cfg(struct iwx_softc *sc)
10161 {
10162 	uint16_t sdev_id, mac_type, rf_type;
10163 	uint8_t mac_step, cdb, jacket, rf_id, no_160, cores;
10164 	int i;
10165 
10166 	sdev_id = pci_get_subdevice(sc->sc_dev);
10167 	mac_type = IWX_CSR_HW_REV_TYPE(sc->sc_hw_rev);
10168 	mac_step = IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2);
10169 	rf_type = IWX_CSR_HW_RFID_TYPE(sc->sc_hw_rf_id);
10170 	cdb = IWX_CSR_HW_RFID_IS_CDB(sc->sc_hw_rf_id);
10171 	jacket = IWX_CSR_HW_RFID_IS_JACKET(sc->sc_hw_rf_id);
10172 
10173 	rf_id = IWX_SUBDEVICE_RF_ID(sdev_id);
10174 	no_160 = IWX_SUBDEVICE_NO_160(sdev_id);
10175 	cores = IWX_SUBDEVICE_CORES(sdev_id);
10176 
10177 	for (i = nitems(iwx_dev_info_table) - 1; i >= 0; i--) {
10178 		 const struct iwx_dev_info *dev_info = &iwx_dev_info_table[i];
10179 
10180 		if (dev_info->device != (uint16_t)IWX_CFG_ANY &&
10181 		    dev_info->device != sc->sc_pid)
10182 			continue;
10183 
10184 		if (dev_info->subdevice != (uint16_t)IWX_CFG_ANY &&
10185 		    dev_info->subdevice != sdev_id)
10186 			continue;
10187 
10188 		if (dev_info->mac_type != (uint16_t)IWX_CFG_ANY &&
10189 		    dev_info->mac_type != mac_type)
10190 			continue;
10191 
10192 		if (dev_info->mac_step != (uint8_t)IWX_CFG_ANY &&
10193 		    dev_info->mac_step != mac_step)
10194 			continue;
10195 
10196 		if (dev_info->rf_type != (uint16_t)IWX_CFG_ANY &&
10197 		    dev_info->rf_type != rf_type)
10198 			continue;
10199 
10200 		if (dev_info->cdb != (uint8_t)IWX_CFG_ANY &&
10201 		    dev_info->cdb != cdb)
10202 			continue;
10203 
10204 		if (dev_info->jacket != (uint8_t)IWX_CFG_ANY &&
10205 		    dev_info->jacket != jacket)
10206 			continue;
10207 
10208 		if (dev_info->rf_id != (uint8_t)IWX_CFG_ANY &&
10209 		    dev_info->rf_id != rf_id)
10210 			continue;
10211 
10212 		if (dev_info->no_160 != (uint8_t)IWX_CFG_ANY &&
10213 		    dev_info->no_160 != no_160)
10214 			continue;
10215 
10216 		if (dev_info->cores != (uint8_t)IWX_CFG_ANY &&
10217 		    dev_info->cores != cores)
10218 			continue;
10219 
10220 		return dev_info->cfg;
10221 	}
10222 
10223 	return NULL;
10224 }
10225 
10226 static int
iwx_probe(device_t dev)10227 iwx_probe(device_t dev)
10228 {
10229 	int i;
10230 
10231 	for (i = 0; i < nitems(iwx_devices); i++) {
10232 		if (pci_get_vendor(dev) == PCI_VENDOR_INTEL &&
10233 		    pci_get_device(dev) == iwx_devices[i].device) {
10234 			device_set_desc(dev, iwx_devices[i].name);
10235 
10236 			/*
10237 			 * Due to significant existing deployments using
10238 			 * iwlwifi lower the priority of iwx.
10239 			 *
10240 			 * This inverts the advice in bus.h where drivers
10241 			 * supporting newer hardware should return
10242 			 * BUS_PROBE_DEFAULT and drivers for older devices
10243 			 * return BUS_PROBE_LOW_PRIORITY.
10244 			 *
10245 			 */
10246 			return (BUS_PROBE_LOW_PRIORITY);
10247 		}
10248 	}
10249 
10250 	return (ENXIO);
10251 }
10252 
10253 static int
iwx_attach(device_t dev)10254 iwx_attach(device_t dev)
10255 {
10256 	struct iwx_softc *sc = device_get_softc(dev);
10257 	struct ieee80211com *ic = &sc->sc_ic;
10258 	const struct iwx_device_cfg *cfg;
10259 	int err;
10260 	int txq_i, i, j;
10261 	size_t ctxt_info_size;
10262 	int rid;
10263 	int count;
10264 	int error;
10265 	sc->sc_dev = dev;
10266 	sc->sc_pid = pci_get_device(dev);
10267 	sc->sc_dmat = bus_get_dma_tag(sc->sc_dev);
10268 
10269 	TASK_INIT(&sc->sc_es_task, 0, iwx_endscan_cb, sc);
10270 	IWX_LOCK_INIT(sc);
10271 	mbufq_init(&sc->sc_snd, ifqmaxlen);
10272 	TASK_INIT(&sc->ba_rx_task, 0, iwx_ba_rx_task, sc);
10273 	TASK_INIT(&sc->ba_tx_task, 0, iwx_ba_tx_task, sc);
10274 	sc->sc_tq = taskqueue_create("iwm_taskq", M_WAITOK,
10275 	    taskqueue_thread_enqueue, &sc->sc_tq);
10276 	error = taskqueue_start_threads(&sc->sc_tq, 1, 0, "iwm_taskq");
10277 	if (error != 0) {
10278 		device_printf(dev, "can't start taskq thread, error %d\n",
10279 		    error);
10280 		return (ENXIO);
10281 	}
10282 
10283 	pci_find_cap(dev, PCIY_EXPRESS, &sc->sc_cap_off);
10284 	if (sc->sc_cap_off == 0) {
10285 		device_printf(dev, "PCIe capability structure not found!\n");
10286 		return (ENXIO);
10287 	}
10288 
10289 	/*
10290 	 * We disable the RETRY_TIMEOUT register (0x41) to keep
10291 	 * PCI Tx retries from interfering with C3 CPU state.
10292 	 */
10293 	pci_write_config(dev, PCI_CFG_RETRY_TIMEOUT, 0x00, 1);
10294 
10295 	if (pci_msix_count(dev)) {
10296 		sc->sc_msix = 1;
10297 	} else {
10298 		device_printf(dev, "no MSI-X found\n");
10299 		return (ENXIO);
10300 	}
10301 
10302 	pci_enable_busmaster(dev);
10303 	rid = PCIR_BAR(0);
10304 	sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
10305 	    RF_ACTIVE);
10306 	if (sc->sc_mem == NULL) {
10307 		device_printf(sc->sc_dev, "can't map mem space\n");
10308 		return (ENXIO);
10309 	}
10310 	sc->sc_st = rman_get_bustag(sc->sc_mem);
10311 	sc->sc_sh = rman_get_bushandle(sc->sc_mem);
10312 
10313 	count = 1;
10314 	rid = 0;
10315 	if (pci_alloc_msix(dev, &count) == 0)
10316 		rid = 1;
10317 	DPRINTF(("%s: count=%d\n", __func__, count));
10318 	sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE |
10319 	    (rid != 0 ? 0 : RF_SHAREABLE));
10320 	if (sc->sc_irq == NULL) {
10321 		device_printf(dev, "can't map interrupt\n");
10322 		return (ENXIO);
10323 	}
10324 	error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_NET | INTR_MPSAFE,
10325 	    NULL, iwx_intr_msix, sc, &sc->sc_ih);
10326 	if (error != 0) {
10327 		device_printf(dev, "can't establish interrupt\n");
10328 		return (ENXIO);
10329 	}
10330 
10331 	/* Clear pending interrupts. */
10332 	IWX_WRITE(sc, IWX_CSR_INT_MASK, 0);
10333 	IWX_WRITE(sc, IWX_CSR_INT, ~0);
10334 	IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, ~0);
10335 
10336 	sc->sc_hw_rev = IWX_READ(sc, IWX_CSR_HW_REV);
10337 	DPRINTF(("%s: sc->sc_hw_rev=%d\n", __func__, sc->sc_hw_rev));
10338 	sc->sc_hw_rf_id = IWX_READ(sc, IWX_CSR_HW_RF_ID);
10339 	DPRINTF(("%s: sc->sc_hw_rf_id =%d\n", __func__, sc->sc_hw_rf_id));
10340 
10341 	/*
10342 	 * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have
10343 	 * changed, and now the revision step also includes bit 0-1 (no more
10344 	 * "dash" value). To keep hw_rev backwards compatible - we'll store it
10345 	 * in the old format.
10346 	 */
10347 	sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) |
10348 			(IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2);
10349 
10350 	switch (sc->sc_pid) {
10351 	case PCI_PRODUCT_INTEL_WL_22500_1:
10352 		sc->sc_fwname = IWX_CC_A_FW;
10353 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10354 		sc->sc_integrated = 0;
10355 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE;
10356 		sc->sc_low_latency_xtal = 0;
10357 		sc->sc_xtal_latency = 0;
10358 		sc->sc_tx_with_siso_diversity = 0;
10359 		sc->sc_uhb_supported = 0;
10360 		break;
10361 	case PCI_PRODUCT_INTEL_WL_22500_2:
10362 	case PCI_PRODUCT_INTEL_WL_22500_5:
10363 		/* These devices should be QuZ only. */
10364 		if (sc->sc_hw_rev != IWX_CSR_HW_REV_TYPE_QUZ) {
10365 			device_printf(dev, "unsupported AX201 adapter\n");
10366 			return (ENXIO);
10367 		}
10368 		sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
10369 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10370 		sc->sc_integrated = 1;
10371 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200;
10372 		sc->sc_low_latency_xtal = 0;
10373 		sc->sc_xtal_latency = 500;
10374 		sc->sc_tx_with_siso_diversity = 0;
10375 		sc->sc_uhb_supported = 0;
10376 		break;
10377 	case PCI_PRODUCT_INTEL_WL_22500_3:
10378 		if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
10379 			sc->sc_fwname = IWX_QU_C_HR_B_FW;
10380 		else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
10381 			sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
10382 		else
10383 			sc->sc_fwname = IWX_QU_B_HR_B_FW;
10384 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10385 		sc->sc_integrated = 1;
10386 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200;
10387 		sc->sc_low_latency_xtal = 0;
10388 		sc->sc_xtal_latency = 500;
10389 		sc->sc_tx_with_siso_diversity = 0;
10390 		sc->sc_uhb_supported = 0;
10391 		break;
10392 	case PCI_PRODUCT_INTEL_WL_22500_4:
10393 	case PCI_PRODUCT_INTEL_WL_22500_7:
10394 	case PCI_PRODUCT_INTEL_WL_22500_8:
10395 		if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
10396 			sc->sc_fwname = IWX_QU_C_HR_B_FW;
10397 		else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
10398 			sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
10399 		else
10400 			sc->sc_fwname = IWX_QU_B_HR_B_FW;
10401 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10402 		sc->sc_integrated = 1;
10403 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_1820;
10404 		sc->sc_low_latency_xtal = 0;
10405 		sc->sc_xtal_latency = 1820;
10406 		sc->sc_tx_with_siso_diversity = 0;
10407 		sc->sc_uhb_supported = 0;
10408 		break;
10409 	case PCI_PRODUCT_INTEL_WL_22500_6:
10410 		if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
10411 			sc->sc_fwname = IWX_QU_C_HR_B_FW;
10412 		else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
10413 			sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
10414 		else
10415 			sc->sc_fwname = IWX_QU_B_HR_B_FW;
10416 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10417 		sc->sc_integrated = 1;
10418 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500;
10419 		sc->sc_low_latency_xtal = 1;
10420 		sc->sc_xtal_latency = 12000;
10421 		sc->sc_tx_with_siso_diversity = 0;
10422 		sc->sc_uhb_supported = 0;
10423 		break;
10424 	case PCI_PRODUCT_INTEL_WL_22500_9:
10425 	case PCI_PRODUCT_INTEL_WL_22500_10:
10426 	case PCI_PRODUCT_INTEL_WL_22500_11:
10427 	case PCI_PRODUCT_INTEL_WL_22500_13:
10428 	/* _14 is an MA device, not yet supported */
10429 	case PCI_PRODUCT_INTEL_WL_22500_15:
10430 	case PCI_PRODUCT_INTEL_WL_22500_16:
10431 		sc->sc_fwname = IWX_SO_A_GF_A_FW;
10432 		sc->sc_pnvm_name = IWX_SO_A_GF_A_PNVM;
10433 		sc->sc_device_family = IWX_DEVICE_FAMILY_AX210;
10434 		sc->sc_integrated = 0;
10435 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE;
10436 		sc->sc_low_latency_xtal = 0;
10437 		sc->sc_xtal_latency = 0;
10438 		sc->sc_tx_with_siso_diversity = 0;
10439 		sc->sc_uhb_supported = 1;
10440 		break;
10441 	case PCI_PRODUCT_INTEL_WL_22500_12:
10442 	case PCI_PRODUCT_INTEL_WL_22500_17:
10443 		sc->sc_fwname = IWX_SO_A_GF_A_FW;
10444 		sc->sc_pnvm_name = IWX_SO_A_GF_A_PNVM;
10445 		sc->sc_device_family = IWX_DEVICE_FAMILY_AX210;
10446 		sc->sc_integrated = 1;
10447 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500;
10448 		sc->sc_low_latency_xtal = 1;
10449 		sc->sc_xtal_latency = 12000;
10450 		sc->sc_tx_with_siso_diversity = 0;
10451 		sc->sc_uhb_supported = 0;
10452 		sc->sc_imr_enabled = 1;
10453 		break;
10454 	default:
10455 		device_printf(dev, "unknown adapter type\n");
10456 		return (ENXIO);
10457 	}
10458 
10459 	cfg = iwx_find_device_cfg(sc);
10460 	DPRINTF(("%s: cfg=%p\n", __func__, cfg));
10461 	if (cfg) {
10462 		sc->sc_fwname = cfg->fw_name;
10463 		sc->sc_pnvm_name = cfg->pnvm_name;
10464 		sc->sc_tx_with_siso_diversity = cfg->tx_with_siso_diversity;
10465 		sc->sc_uhb_supported = cfg->uhb_supported;
10466 		if (cfg->xtal_latency) {
10467 			sc->sc_xtal_latency = cfg->xtal_latency;
10468 			sc->sc_low_latency_xtal = cfg->low_latency_xtal;
10469 		}
10470 	}
10471 
10472 	sc->mac_addr_from_csr = 0x380; /* differs on BZ hw generation */
10473 
10474 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
10475 		sc->sc_umac_prph_offset = 0x300000;
10476 		sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX_GEN3;
10477 	} else
10478 		sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX;
10479 
10480 	/* Allocate DMA memory for loading firmware. */
10481 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
10482 		ctxt_info_size = sizeof(struct iwx_context_info_gen3);
10483 	else
10484 		ctxt_info_size = sizeof(struct iwx_context_info);
10485 	err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ctxt_info_dma,
10486 	    ctxt_info_size, 1);
10487 	if (err) {
10488 		device_printf(dev,
10489 		    "could not allocate memory for loading firmware\n");
10490 		return (ENXIO);
10491 	}
10492 
10493 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
10494 		err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->prph_scratch_dma,
10495 		    sizeof(struct iwx_prph_scratch), 1);
10496 		if (err) {
10497 			device_printf(dev,
10498 			    "could not allocate prph scratch memory\n");
10499 			goto fail1;
10500 		}
10501 
10502 		/*
10503 		 * Allocate prph information. The driver doesn't use this.
10504 		 * We use the second half of this page to give the device
10505 		 * some dummy TR/CR tail pointers - which shouldn't be
10506 		 * necessary as we don't use this, but the hardware still
10507 		 * reads/writes there and we can't let it go do that with
10508 		 * a NULL pointer.
10509 		 */
10510 		KASSERT((sizeof(struct iwx_prph_info) < PAGE_SIZE / 2),
10511 		    ("iwx_prph_info has wrong size"));
10512 		err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->prph_info_dma,
10513 		    PAGE_SIZE, 1);
10514 		if (err) {
10515 			device_printf(dev,
10516 			    "could not allocate prph info memory\n");
10517 			goto fail1;
10518 		}
10519 	}
10520 
10521 	/* Allocate interrupt cause table (ICT).*/
10522 	err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma,
10523 	    IWX_ICT_SIZE, 1<<IWX_ICT_PADDR_SHIFT);
10524 	if (err) {
10525 		device_printf(dev, "could not allocate ICT table\n");
10526 		goto fail1;
10527 	}
10528 
10529 	for (txq_i = 0; txq_i < nitems(sc->txq); txq_i++) {
10530 		err = iwx_alloc_tx_ring(sc, &sc->txq[txq_i], txq_i);
10531 		if (err) {
10532 			device_printf(dev, "could not allocate TX ring %d\n",
10533 			    txq_i);
10534 			goto fail4;
10535 		}
10536 	}
10537 
10538 	err = iwx_alloc_rx_ring(sc, &sc->rxq);
10539 	if (err) {
10540 		device_printf(sc->sc_dev, "could not allocate RX ring\n");
10541 		goto fail4;
10542 	}
10543 
10544 #ifdef IWX_DEBUG
10545 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10546 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "debug",
10547 	    CTLFLAG_RWTUN, &sc->sc_debug, 0, "bitmask to control debugging");
10548 
10549 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10550 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "himark",
10551 	    CTLFLAG_RW, &iwx_himark, 0, "queues high watermark");
10552 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10553 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "lomark",
10554 	    CTLFLAG_RW, &iwx_lomark, 0, "queues low watermark");
10555 
10556 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10557 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "qfullmsk",
10558 	    CTLFLAG_RD, &sc->qfullmsk, 0, "queue fullmask");
10559 
10560 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10561 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue0",
10562 	    CTLFLAG_RD, &sc->txq[0].queued, 0, "queue 0");
10563 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10564 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue1",
10565 	    CTLFLAG_RD, &sc->txq[1].queued, 0, "queue 1");
10566 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10567 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue2",
10568 	    CTLFLAG_RD, &sc->txq[2].queued, 0, "queue 2");
10569 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10570 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue3",
10571 	    CTLFLAG_RD, &sc->txq[3].queued, 0, "queue 3");
10572 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10573 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue4",
10574 	    CTLFLAG_RD, &sc->txq[4].queued, 0, "queue 4");
10575 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10576 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue5",
10577 	    CTLFLAG_RD, &sc->txq[5].queued, 0, "queue 5");
10578 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10579 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue6",
10580 	    CTLFLAG_RD, &sc->txq[6].queued, 0, "queue 6");
10581 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10582 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue7",
10583 	    CTLFLAG_RD, &sc->txq[7].queued, 0, "queue 7");
10584 #endif
10585 	ic->ic_softc = sc;
10586 	ic->ic_name = device_get_nameunit(sc->sc_dev);
10587 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
10588 	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
10589 
10590 	/* Set device capabilities. */
10591 	ic->ic_caps =
10592 	    IEEE80211_C_STA |
10593 	    IEEE80211_C_MONITOR |
10594 	    IEEE80211_C_WPA |		/* WPA/RSN */
10595 	    IEEE80211_C_WME |
10596 	    IEEE80211_C_PMGT |
10597 	    IEEE80211_C_SHSLOT |	/* short slot time supported */
10598 	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
10599 	    IEEE80211_C_BGSCAN		/* capable of bg scanning */
10600 	    ;
10601 	ic->ic_flags_ext = IEEE80211_FEXT_SCAN_OFFLOAD;
10602 	/* Enable seqno offload */
10603 	ic->ic_flags_ext |= IEEE80211_FEXT_SEQNO_OFFLOAD;
10604 	/* Don't send null data frames; let firmware do it */
10605 	ic->ic_flags_ext |= IEEE80211_FEXT_NO_NULLDATA;
10606 
10607 	ic->ic_txstream = 2;
10608 	ic->ic_rxstream = 2;
10609 	ic->ic_htcaps |= IEEE80211_HTC_HT
10610 			| IEEE80211_HTCAP_SMPS_OFF
10611 			| IEEE80211_HTCAP_SHORTGI20	/* short GI in 20MHz */
10612 			| IEEE80211_HTCAP_SHORTGI40	/* short GI in 40MHz */
10613 			| IEEE80211_HTCAP_CHWIDTH40	/* 40MHz channel width*/
10614 			| IEEE80211_HTC_AMPDU		/* tx A-MPDU */
10615 //			| IEEE80211_HTC_RX_AMSDU_AMPDU	/* TODO: hw reorder */
10616 			| IEEE80211_HTCAP_MAXAMSDU_3839;	/* max A-MSDU length */
10617 
10618 	ic->ic_cryptocaps |= IEEE80211_CRYPTO_AES_CCM;
10619 
10620 	/*
10621 	 * XXX: setupcurchan() expects vhtcaps to be non-zero
10622 	 * https://bugs.freebsd.org/274156
10623 	 */
10624 	ic->ic_vht_cap.vht_cap_info |= IEEE80211_VHTCAP_MAX_MPDU_LENGTH_3895
10625 			| IEEE80211_VHTCAP_SHORT_GI_80
10626 			| 3 << IEEE80211_VHTCAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_S
10627 			| IEEE80211_VHTCAP_RX_ANTENNA_PATTERN
10628 			| IEEE80211_VHTCAP_TX_ANTENNA_PATTERN;
10629 
10630 	ic->ic_flags_ext |= IEEE80211_FEXT_VHT;
10631 	int mcsmap = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
10632 		  IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
10633 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
10634 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
10635 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
10636 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
10637 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
10638 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 14;
10639 	ic->ic_vht_cap.supp_mcs.tx_mcs_map = htole16(mcsmap);
10640 	ic->ic_vht_cap.supp_mcs.rx_mcs_map = htole16(mcsmap);
10641 
10642 	callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0);
10643 	for (i = 0; i < nitems(sc->sc_rxba_data); i++) {
10644 		struct iwx_rxba_data *rxba = &sc->sc_rxba_data[i];
10645 		rxba->baid = IWX_RX_REORDER_DATA_INVALID_BAID;
10646 		rxba->sc = sc;
10647 		for (j = 0; j < nitems(rxba->entries); j++)
10648 			mbufq_init(&rxba->entries[j].frames, ifqmaxlen);
10649 	}
10650 
10651 	/* Initialize to something to have a chance to get S:N values. */
10652 	sc->sc_noise = IWX_DEFAULT_NF;
10653 
10654 	sc->sc_preinit_hook.ich_func = iwx_attach_hook;
10655 	sc->sc_preinit_hook.ich_arg = sc;
10656 	if (config_intrhook_establish(&sc->sc_preinit_hook) != 0) {
10657 		device_printf(dev,
10658 		    "config_intrhook_establish failed\n");
10659 		goto fail4;
10660 	}
10661 
10662 	return (0);
10663 
10664 fail4:
10665 	while (--txq_i >= 0)
10666 		iwx_free_tx_ring(sc, &sc->txq[txq_i]);
10667 	iwx_free_rx_ring(sc, &sc->rxq);
10668 	if (sc->ict_dma.vaddr != NULL)
10669 		iwx_dma_contig_free(&sc->ict_dma);
10670 
10671 fail1:
10672 	iwx_dma_contig_free(&sc->ctxt_info_dma);
10673 	iwx_dma_contig_free(&sc->prph_scratch_dma);
10674 	iwx_dma_contig_free(&sc->prph_info_dma);
10675 	return (ENXIO);
10676 }
10677 
10678 static int
iwx_detach(device_t dev)10679 iwx_detach(device_t dev)
10680 {
10681 	struct iwx_softc *sc = device_get_softc(dev);
10682 	int txq_i;
10683 
10684 	iwx_stop_device(sc);
10685 	sc->sc_flags |= IWX_FLAG_SHUTDOWN;
10686 
10687 	taskqueue_drain_all(sc->sc_tq);
10688 	taskqueue_free(sc->sc_tq);
10689 
10690 	ieee80211_ifdetach(&sc->sc_ic);
10691 
10692 	callout_drain(&sc->watchdog_to);
10693 
10694 	for (txq_i = 0; txq_i < nitems(sc->txq); txq_i++)
10695 		iwx_free_tx_ring(sc, &sc->txq[txq_i]);
10696 	iwx_free_rx_ring(sc, &sc->rxq);
10697 
10698 	if (sc->sc_fwp != NULL) {
10699 		firmware_put(sc->sc_fwp, FIRMWARE_UNLOAD);
10700 		sc->sc_fwp = NULL;
10701 	}
10702 
10703 	if (sc->sc_pnvm != NULL) {
10704 		firmware_put(sc->sc_pnvm, FIRMWARE_UNLOAD);
10705 		sc->sc_pnvm = NULL;
10706 	}
10707 
10708 	if (sc->sc_irq != NULL) {
10709 		bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
10710 		bus_release_resource(dev, SYS_RES_IRQ,
10711 		    rman_get_rid(sc->sc_irq), sc->sc_irq);
10712 		pci_release_msi(dev);
10713         }
10714 	if (sc->sc_mem != NULL)
10715 		bus_release_resource(dev, SYS_RES_MEMORY,
10716 		    rman_get_rid(sc->sc_mem), sc->sc_mem);
10717 
10718 	IWX_LOCK_DESTROY(sc);
10719 
10720 	return (0);
10721 }
10722 
10723 static void
iwx_radiotap_attach(struct iwx_softc * sc)10724 iwx_radiotap_attach(struct iwx_softc *sc)
10725 {
10726 	struct ieee80211com *ic = &sc->sc_ic;
10727 
10728 	IWX_DPRINTF(sc, IWX_DEBUG_RESET | IWX_DEBUG_TRACE,
10729 	    "->%s begin\n", __func__);
10730 
10731 	ieee80211_radiotap_attach(ic,
10732 	    &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
10733 		IWX_TX_RADIOTAP_PRESENT,
10734 	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
10735 		IWX_RX_RADIOTAP_PRESENT);
10736 
10737 	IWX_DPRINTF(sc, IWX_DEBUG_RESET | IWX_DEBUG_TRACE,
10738 	    "->%s end\n", __func__);
10739 }
10740 
10741 struct ieee80211vap *
iwx_vap_create(struct ieee80211com * ic,const char name[IFNAMSIZ],int unit,enum ieee80211_opmode opmode,int flags,const uint8_t bssid[IEEE80211_ADDR_LEN],const uint8_t mac[IEEE80211_ADDR_LEN])10742 iwx_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
10743     enum ieee80211_opmode opmode, int flags,
10744     const uint8_t bssid[IEEE80211_ADDR_LEN],
10745     const uint8_t mac[IEEE80211_ADDR_LEN])
10746 {
10747 	struct iwx_vap *ivp;
10748 	struct ieee80211vap *vap;
10749 
10750 	if (!TAILQ_EMPTY(&ic->ic_vaps))         /* only one at a time */
10751 		return NULL;
10752 	ivp = malloc(sizeof(struct iwx_vap), M_80211_VAP, M_WAITOK | M_ZERO);
10753 	vap = &ivp->iv_vap;
10754 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
10755 	vap->iv_bmissthreshold = 10;            /* override default */
10756 	/* Override with driver methods. */
10757 	ivp->iv_newstate = vap->iv_newstate;
10758 	vap->iv_newstate = iwx_newstate;
10759 
10760 	ivp->id = IWX_DEFAULT_MACID;
10761 	ivp->color = IWX_DEFAULT_COLOR;
10762 
10763 	ivp->have_wme = TRUE;
10764 	ivp->ps_disabled = FALSE;
10765 
10766 	vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K;
10767 	vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_4;
10768 
10769 	/* h/w crypto support */
10770 	vap->iv_key_alloc = iwx_key_alloc;
10771 	vap->iv_key_delete = iwx_key_delete;
10772 	vap->iv_key_set = iwx_key_set;
10773 	vap->iv_key_update_begin = iwx_key_update_begin;
10774 	vap->iv_key_update_end = iwx_key_update_end;
10775 
10776 	ieee80211_ratectl_init(vap);
10777 	/* Complete setup. */
10778 	ieee80211_vap_attach(vap, ieee80211_media_change,
10779 	    ieee80211_media_status, mac);
10780 	ic->ic_opmode = opmode;
10781 
10782 	return vap;
10783 }
10784 
10785 static void
iwx_vap_delete(struct ieee80211vap * vap)10786 iwx_vap_delete(struct ieee80211vap *vap)
10787 {
10788 	struct iwx_vap *ivp = IWX_VAP(vap);
10789 
10790 	ieee80211_ratectl_deinit(vap);
10791 	ieee80211_vap_detach(vap);
10792 	free(ivp, M_80211_VAP);
10793 }
10794 
10795 static void
iwx_parent(struct ieee80211com * ic)10796 iwx_parent(struct ieee80211com *ic)
10797 {
10798 	struct iwx_softc *sc = ic->ic_softc;
10799 	IWX_LOCK(sc);
10800 
10801 	if (sc->sc_flags & IWX_FLAG_HW_INITED) {
10802 		iwx_stop(sc);
10803 		sc->sc_flags &= ~IWX_FLAG_HW_INITED;
10804 	} else {
10805 		iwx_init(sc);
10806 		ieee80211_start_all(ic);
10807 	}
10808 	IWX_UNLOCK(sc);
10809 }
10810 
10811 static int
iwx_suspend(device_t dev)10812 iwx_suspend(device_t dev)
10813 {
10814 	struct iwx_softc *sc = device_get_softc(dev);
10815 	struct ieee80211com *ic = &sc->sc_ic;
10816 
10817 	/*
10818 	 * Suspend everything first, then shutdown hardware if it's
10819 	 * still up.
10820 	 */
10821 	ieee80211_suspend_all(ic);
10822 
10823 	if (sc->sc_flags & IWX_FLAG_HW_INITED) {
10824 		iwx_stop(sc);
10825 		sc->sc_flags &= ~IWX_FLAG_HW_INITED;
10826 	}
10827 	return (0);
10828 }
10829 
10830 static int
iwx_resume(device_t dev)10831 iwx_resume(device_t dev)
10832 {
10833 	struct iwx_softc *sc = device_get_softc(dev);
10834 	struct ieee80211com *ic = &sc->sc_ic;
10835 
10836 	/*
10837 	 * We disable the RETRY_TIMEOUT register (0x41) to keep
10838 	 * PCI Tx retries from interfering with C3 CPU state.
10839 	 */
10840 	pci_write_config(dev, PCI_CFG_RETRY_TIMEOUT, 0x00, 1);
10841 
10842 	IWX_LOCK(sc);
10843 
10844 	/* Stop the hardware here if it's still thought of as "up" */
10845 	if (sc->sc_flags & IWX_FLAG_HW_INITED) {
10846 		iwx_stop(sc);
10847 		sc->sc_flags &= ~IWX_FLAG_HW_INITED;
10848 	}
10849 
10850 	IWX_UNLOCK(sc);
10851 
10852 	/* Start the VAPs, which will bring the hardware back up again */
10853 	ieee80211_resume_all(ic);
10854 	return (0);
10855 }
10856 
10857 static void
iwx_scan_start(struct ieee80211com * ic)10858 iwx_scan_start(struct ieee80211com *ic)
10859 {
10860 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
10861 	struct iwx_softc *sc = ic->ic_softc;
10862 	int err;
10863 
10864 	IWX_LOCK(sc);
10865 	if ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) == 0)
10866 		err = iwx_scan(sc);
10867 	else
10868 		err = iwx_bgscan(ic);
10869 	IWX_UNLOCK(sc);
10870 	if (err)
10871 		ieee80211_cancel_scan(vap);
10872 
10873 	return;
10874 }
10875 
10876 static void
iwx_update_mcast(struct ieee80211com * ic)10877 iwx_update_mcast(struct ieee80211com *ic)
10878 {
10879 }
10880 
10881 static void
iwx_scan_curchan(struct ieee80211_scan_state * ss,unsigned long maxdwell)10882 iwx_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
10883 {
10884 }
10885 
10886 static void
iwx_scan_mindwell(struct ieee80211_scan_state * ss)10887 iwx_scan_mindwell(struct ieee80211_scan_state *ss)
10888 {
10889 }
10890 
10891 static void
iwx_scan_end(struct ieee80211com * ic)10892 iwx_scan_end(struct ieee80211com *ic)
10893 {
10894 	iwx_endscan(ic->ic_softc);
10895 }
10896 
10897 static void
iwx_set_channel(struct ieee80211com * ic)10898 iwx_set_channel(struct ieee80211com *ic)
10899 {
10900 #if 0
10901         struct iwx_softc *sc = ic->ic_softc;
10902         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
10903 
10904         IWX_DPRINTF(sc, IWX_DEBUG_NI , "%s:%d NOT IMPLEMENTED\n", __func__, __LINE__);
10905         iwx_phy_ctxt_task((void *)sc);
10906 #endif
10907 }
10908 
10909 static void
iwx_endscan_cb(void * arg,int pending)10910 iwx_endscan_cb(void *arg, int pending)
10911 {
10912 	struct iwx_softc *sc = arg;
10913 	struct ieee80211com *ic = &sc->sc_ic;
10914 
10915 	DPRINTF(("scan ended\n"));
10916 	ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps));
10917 }
10918 
10919 static int
iwx_wme_update(struct ieee80211com * ic)10920 iwx_wme_update(struct ieee80211com *ic)
10921 {
10922 	return 0;
10923 }
10924 
10925 static int
iwx_raw_xmit(struct ieee80211_node * ni,struct mbuf * m,const struct ieee80211_bpf_params * params)10926 iwx_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
10927     const struct ieee80211_bpf_params *params)
10928 {
10929 	struct ieee80211com *ic = ni->ni_ic;
10930 	struct iwx_softc *sc = ic->ic_softc;
10931 	int err;
10932 
10933 	IWX_LOCK(sc);
10934 	if (sc->sc_flags & IWX_FLAG_STA_ACTIVE) {
10935 		err = iwx_tx(sc, m, ni);
10936 		IWX_UNLOCK(sc);
10937 		return err;
10938 	} else {
10939 		IWX_UNLOCK(sc);
10940 		return EIO;
10941 	}
10942 }
10943 
10944 static int
iwx_transmit(struct ieee80211com * ic,struct mbuf * m)10945 iwx_transmit(struct ieee80211com *ic, struct mbuf *m)
10946 {
10947 	struct iwx_softc *sc = ic->ic_softc;
10948 	int error;
10949 
10950 	// TODO: mbufq_enqueue in iwm
10951 	// TODO dequeue in iwm_start, counters, locking
10952 	IWX_LOCK(sc);
10953 	error = mbufq_enqueue(&sc->sc_snd, m);
10954 	if (error) {
10955 		IWX_UNLOCK(sc);
10956 		return (error);
10957 	}
10958 
10959 	iwx_start(sc);
10960 	IWX_UNLOCK(sc);
10961 	return (0);
10962 }
10963 
10964 static int
iwx_ampdu_rx_start(struct ieee80211_node * ni,struct ieee80211_rx_ampdu * rap,int baparamset,int batimeout,int baseqctl)10965 iwx_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
10966     int baparamset, int batimeout, int baseqctl)
10967 {
10968 	struct ieee80211com *ic = ni->ni_ic;
10969 	struct iwx_softc *sc = ic->ic_softc;
10970 	int tid;
10971 
10972 	tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID);
10973 	sc->ni_rx_ba[tid].ba_winstart =
10974 	    _IEEE80211_MASKSHIFT(le16toh(baseqctl), IEEE80211_BASEQ_START);
10975 	sc->ni_rx_ba[tid].ba_winsize =
10976 	    _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_BUFSIZ);
10977 	sc->ni_rx_ba[tid].ba_timeout_val = batimeout;
10978 
10979 	if (sc->sc_rx_ba_sessions >= IWX_MAX_RX_BA_SESSIONS ||
10980 	    tid >= IWX_MAX_TID_COUNT)
10981 		return ENOSPC;
10982 
10983 	if (sc->ba_rx.start_tidmask & (1 << tid)) {
10984 		DPRINTF(("%s: tid %d already added\n", __func__, tid));
10985 		return EBUSY;
10986 	}
10987 	DPRINTF(("%s: sc->ba_rx.start_tidmask=%x\n", __func__, sc->ba_rx.start_tidmask));
10988 
10989 	sc->ba_rx.start_tidmask |= (1 << tid);
10990 	DPRINTF(("%s: tid=%i\n", __func__, tid));
10991 	DPRINTF(("%s: ba_winstart=%i\n", __func__, sc->ni_rx_ba[tid].ba_winstart));
10992 	DPRINTF(("%s: ba_winsize=%i\n", __func__, sc->ni_rx_ba[tid].ba_winsize));
10993 	DPRINTF(("%s: ba_timeout_val=%i\n", __func__, sc->ni_rx_ba[tid].ba_timeout_val));
10994 
10995 	taskqueue_enqueue(sc->sc_tq, &sc->ba_rx_task);
10996 
10997 	// TODO:misha move to ba_task (serialize)
10998 	sc->sc_ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl);
10999 
11000 	return (0);
11001 }
11002 
11003 static void
iwx_ampdu_rx_stop(struct ieee80211_node * ni,struct ieee80211_rx_ampdu * rap)11004 iwx_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
11005 {
11006 	return;
11007 }
11008 
11009 /**
11010  * @brief Called by net80211 to request an A-MPDU session be established.
11011  *
11012  * This is called by net80211 to see if an A-MPDU session can be established.
11013  * However, the iwx(4) firmware will take care of establishing the BA
11014  * session for us.  net80211 doesn't have to send any action frames here;
11015  * it just needs to plumb up the ampdu session once the BA has been sent.
11016  *
11017  * If we return 0 here then the firmware will set up the state but net80211
11018  * will not; so it's on us to actually complete it via a call to
11019  * ieee80211_ampdu_tx_request_active_ext() .
11020  *
11021  * @param ni	ieee80211_node to establish A-MPDU session for
11022  * @param tap	pointer to the per-TID state struct
11023  * @param dialogtoken	dialogtoken field from the BA request
11024  * @param baparamset	baparamset field from the BA request
11025  * @param batimeout	batimeout field from the BA request
11026  *
11027  * @returns 0 so net80211 doesn't send the BA action frame to establish A-MPDU.
11028  */
11029 static int
iwx_addba_request(struct ieee80211_node * ni,struct ieee80211_tx_ampdu * tap,int dialogtoken,int baparamset,int batimeout)11030 iwx_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
11031     int dialogtoken, int baparamset, int batimeout)
11032 {
11033 	struct iwx_softc *sc = ni->ni_ic->ic_softc;
11034 	int tid;
11035 
11036 	tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID);
11037 	IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT,
11038 	    "%s: queuing AMPDU start on tid %i\n", __func__, tid);
11039 
11040 	/* There's no nice way right now to tell net80211 that we're in the
11041 	 * middle of an asynchronous ADDBA setup session.  So, bump the timeout
11042 	 * to hz ticks, hopefully we'll get a response by then.
11043 	 */
11044 	tap->txa_nextrequest = ticks + hz;
11045 
11046 	IWX_LOCK(sc);
11047 	sc->ba_tx.start_tidmask |= (1 << tid);
11048 	IWX_UNLOCK(sc);
11049 
11050 	taskqueue_enqueue(sc->sc_tq, &sc->ba_tx_task);
11051 
11052 	return (0);
11053 }
11054 
11055 
11056 static int
iwx_addba_response(struct ieee80211_node * ni,struct ieee80211_tx_ampdu * tap,int code,int baparamset,int batimeout)11057 iwx_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
11058     int code, int baparamset, int batimeout)
11059 {
11060 	return 0;
11061 }
11062 
11063 static void
iwx_key_update_begin(struct ieee80211vap * vap)11064 iwx_key_update_begin(struct ieee80211vap *vap)
11065 {
11066 	return;
11067 }
11068 
11069 static void
iwx_key_update_end(struct ieee80211vap * vap)11070 iwx_key_update_end(struct ieee80211vap *vap)
11071 {
11072 	return;
11073 }
11074 
11075 static int
iwx_key_alloc(struct ieee80211vap * vap,struct ieee80211_key * k,ieee80211_keyix * keyix,ieee80211_keyix * rxkeyix)11076 iwx_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
11077 	ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
11078 {
11079 
11080 	if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) {
11081 		return (1);
11082 	}
11083 
11084 	if (ieee80211_is_key_unicast(vap, k)) {
11085 		*keyix = 0;	/* NB: use key index 0 for ucast key */
11086 	} else if (ieee80211_is_key_global(vap, k)) {
11087 		*keyix = ieee80211_crypto_get_key_wepidx(vap, k);
11088 	} else {
11089 		net80211_vap_printf(vap, "%s: invalid crypto key type\n",
11090 		    __func__);
11091 		return (0);
11092 	}
11093 	*rxkeyix = IEEE80211_KEYIX_NONE;	/* XXX maybe *keyix? */
11094 	return (1);
11095 }
11096 
11097 static int
iwx_key_set(struct ieee80211vap * vap,const struct ieee80211_key * k)11098 iwx_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
11099 {
11100 	struct ieee80211com *ic = vap->iv_ic;
11101 	struct iwx_softc *sc = ic->ic_softc;
11102 	struct iwx_add_sta_key_cmd cmd;
11103 	uint32_t status;
11104 	int err;
11105 	int id;
11106 
11107 	if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_AES_CCM) {
11108 		return 1;
11109 	}
11110 
11111 	/*
11112 	 * Keys are stored in 'ni' so 'k' is valid if 'ni' is valid.
11113 	 * Currently we only implement station mode where 'ni' is always
11114 	 * ic->ic_bss so there is no need to validate arguments beyond this:
11115 	 */
11116 
11117 	memset(&cmd, 0, sizeof(cmd));
11118 
11119 	if (ieee80211_is_key_global(vap, k)) {
11120 		id = ieee80211_crypto_get_key_wepidx(vap, k);
11121 		IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: adding group key\n",
11122 		    __func__);
11123 	} else if (ieee80211_is_key_unicast(vap, k)) {
11124 		IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: adding key\n",
11125 		    __func__);
11126 		id = 0; /* net80211 currently only supports unicast key 0 */
11127 	} else {
11128 		net80211_vap_printf(vap, "%s: unknown key type\n", __func__);
11129 		return (ENXIO);
11130 	}
11131 
11132 	IWX_LOCK(sc);
11133 
11134 	cmd.common.key_flags = htole16(IWX_STA_KEY_FLG_CCM |
11135 	    IWX_STA_KEY_FLG_WEP_KEY_MAP |
11136 	    ((id << IWX_STA_KEY_FLG_KEYID_POS) &
11137 	    IWX_STA_KEY_FLG_KEYID_MSK));
11138 	if (ieee80211_is_key_global(vap, k)) {
11139 		cmd.common.key_offset = 1;
11140 		cmd.common.key_flags |= htole16(IWX_STA_KEY_MULTICAST);
11141 	} else if (ieee80211_is_key_unicast(vap, k)) {
11142 		cmd.common.key_offset = 0;
11143 	} else {
11144 		net80211_vap_printf(vap, "%s: unknown key type\n", __func__);
11145 		IWX_UNLOCK(sc);
11146 		return (ENXIO);
11147 	}
11148 	memcpy(cmd.common.key, ieee80211_crypto_get_key_data(k),
11149 	    MIN(sizeof(cmd.common.key), ieee80211_crypto_get_key_len(k)));
11150 	IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: key: id=%d, len=%i, key=%*D\n",
11151 	    __func__, id,
11152 	    ieee80211_crypto_get_key_len(k),
11153 	    ieee80211_crypto_get_key_len(k),
11154 	    (const unsigned char *) ieee80211_crypto_get_key_data(k), "");
11155 	cmd.common.sta_id = IWX_STATION_ID;
11156 
11157 	cmd.transmit_seq_cnt = htole64(k->wk_keytsc);
11158 	IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: k->wk_keytsc=%" PRIu64 "\n",
11159 	    __func__, k->wk_keytsc);
11160 
11161 	status = IWX_ADD_STA_SUCCESS;
11162 	err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA_KEY, sizeof(cmd), &cmd,
11163 	    &status);
11164 	if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS)
11165 		err = EIO;
11166 	if (err) {
11167 		net80211_vap_printf(vap,
11168 		    "%s: can't set wpa2 keys (error %d)\n", __func__, err);
11169 		IWX_UNLOCK(sc);
11170 		return err;
11171 	} else
11172 		IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT,
11173 		    "%s: key added successfully\n", __func__);
11174 	IWX_UNLOCK(sc);
11175 	return (1);
11176 }
11177 
11178 static int
iwx_key_delete(struct ieee80211vap * vap,const struct ieee80211_key * k)11179 iwx_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
11180 {
11181 	/*
11182 	 * Note: since there's no key allocations to track - it's either
11183 	 * the 4 static WEP keys or the single unicast key - there's nothing
11184 	 * else to do here.
11185 	 *
11186 	 * This would need some further work to support IBSS/mesh/AP modes.
11187 	 */
11188 	return (1);
11189 }
11190 
11191 static device_method_t iwx_pci_methods[] = {
11192 	/* Device interface */
11193 	DEVMETHOD(device_probe,		iwx_probe),
11194 	DEVMETHOD(device_attach,	iwx_attach),
11195 	DEVMETHOD(device_detach,	iwx_detach),
11196 	DEVMETHOD(device_suspend,	iwx_suspend),
11197 	DEVMETHOD(device_resume,	iwx_resume),
11198 
11199 	DEVMETHOD_END
11200 };
11201 
11202 static driver_t iwx_pci_driver = {
11203 	"iwx",
11204 	iwx_pci_methods,
11205 	sizeof (struct iwx_softc)
11206 };
11207 
11208 DRIVER_MODULE(iwx, pci, iwx_pci_driver, NULL, NULL);
11209 MODULE_PNP_INFO("U16:device;D:#;T:vendor=0x8086", pci, iwx_pci_driver,
11210     iwx_devices, nitems(iwx_devices));
11211 MODULE_DEPEND(iwx, firmware, 1, 1, 1);
11212 MODULE_DEPEND(iwx, pci, 1, 1, 1);
11213 MODULE_DEPEND(iwx, wlan, 1, 1, 1);
11214