xref: /freebsd/sys/dev/iwx/if_iwx.c (revision e56f7becc7efe05acbb08162961dca574b152720)
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 
8089 	if (nstate <= ostate || nstate > IEEE80211_S_RUN) {
8090 		switch (ostate) {
8091 		case IEEE80211_S_RUN:
8092 			err = iwx_run_stop(sc);
8093 			if (err)
8094 				goto out;
8095 			/* FALLTHROUGH */
8096 		case IEEE80211_S_ASSOC:
8097 		case IEEE80211_S_AUTH:
8098 			if (nstate <= IEEE80211_S_AUTH) {
8099 				err = iwx_deauth(sc);
8100 				if (err)
8101 					goto out;
8102 			}
8103 			/* FALLTHROUGH */
8104 		case IEEE80211_S_SCAN:
8105 		case IEEE80211_S_INIT:
8106 		default:
8107 			break;
8108 		}
8109 //
8110 //		/* Die now if iwx_stop() was called while we were sleeping. */
8111 //		if (sc->sc_flags & IWX_FLAG_SHUTDOWN) {
8112 //			refcnt_rele_wake(&sc->task_refs);
8113 //			splx(s);
8114 //			return;
8115 //		}
8116 	}
8117 
8118 	switch (nstate) {
8119 	case IEEE80211_S_INIT:
8120 		break;
8121 
8122 	case IEEE80211_S_SCAN:
8123 			break;
8124 
8125 	case IEEE80211_S_AUTH:
8126 		err = iwx_auth(vap, sc);
8127 		break;
8128 
8129 	case IEEE80211_S_ASSOC:
8130 		break;
8131 
8132 	case IEEE80211_S_RUN:
8133 		err = iwx_run(vap, sc);
8134 		break;
8135 	default:
8136 		break;
8137 	}
8138 
8139 out:
8140 	IWX_UNLOCK(sc);
8141 
8142 	return (err);
8143 }
8144 
8145 static int
iwx_newstate(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)8146 iwx_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
8147 {
8148 	struct iwx_vap *ivp = IWX_VAP(vap);
8149 	struct ieee80211com *ic = vap->iv_ic;
8150 	enum ieee80211_state ostate = vap->iv_state;
8151 	int err;
8152 
8153 	/*
8154 	 * Prevent attempts to transition towards the same state, unless
8155 	 * we are scanning in which case a SCAN -> SCAN transition
8156 	 * triggers another scan iteration. And AUTH -> AUTH is needed
8157 	 * to support band-steering.
8158 	 */
8159 	if (ostate == nstate && nstate != IEEE80211_S_SCAN &&
8160 	    nstate != IEEE80211_S_AUTH)
8161 		return 0;
8162 	IEEE80211_UNLOCK(ic);
8163 	err = iwx_newstate_sub(vap, nstate);
8164 	IEEE80211_LOCK(ic);
8165 	if (err == 0)
8166 		err = ivp->iv_newstate(vap, nstate, arg);
8167 
8168 	return (err);
8169 }
8170 
8171 static void
iwx_endscan(struct iwx_softc * sc)8172 iwx_endscan(struct iwx_softc *sc)
8173 {
8174         struct ieee80211com *ic = &sc->sc_ic;
8175         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8176 
8177         if ((sc->sc_flags & (IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN)) == 0)
8178                 return;
8179 
8180         sc->sc_flags &= ~(IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN);
8181 
8182         ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps));
8183         wakeup(&vap->iv_state); /* wake up iwx_newstate */
8184 }
8185 
8186 /*
8187  * Aging and idle timeouts for the different possible scenarios
8188  * in default configuration
8189  */
8190 static const uint32_t
8191 iwx_sf_full_timeout_def[IWX_SF_NUM_SCENARIO][IWX_SF_NUM_TIMEOUT_TYPES] = {
8192 	{
8193 		htole32(IWX_SF_SINGLE_UNICAST_AGING_TIMER_DEF),
8194 		htole32(IWX_SF_SINGLE_UNICAST_IDLE_TIMER_DEF)
8195 	},
8196 	{
8197 		htole32(IWX_SF_AGG_UNICAST_AGING_TIMER_DEF),
8198 		htole32(IWX_SF_AGG_UNICAST_IDLE_TIMER_DEF)
8199 	},
8200 	{
8201 		htole32(IWX_SF_MCAST_AGING_TIMER_DEF),
8202 		htole32(IWX_SF_MCAST_IDLE_TIMER_DEF)
8203 	},
8204 	{
8205 		htole32(IWX_SF_BA_AGING_TIMER_DEF),
8206 		htole32(IWX_SF_BA_IDLE_TIMER_DEF)
8207 	},
8208 	{
8209 		htole32(IWX_SF_TX_RE_AGING_TIMER_DEF),
8210 		htole32(IWX_SF_TX_RE_IDLE_TIMER_DEF)
8211 	},
8212 };
8213 
8214 /*
8215  * Aging and idle timeouts for the different possible scenarios
8216  * in single BSS MAC configuration.
8217  */
8218 static const uint32_t
8219 iwx_sf_full_timeout[IWX_SF_NUM_SCENARIO][IWX_SF_NUM_TIMEOUT_TYPES] = {
8220 	{
8221 		htole32(IWX_SF_SINGLE_UNICAST_AGING_TIMER),
8222 		htole32(IWX_SF_SINGLE_UNICAST_IDLE_TIMER)
8223 	},
8224 	{
8225 		htole32(IWX_SF_AGG_UNICAST_AGING_TIMER),
8226 		htole32(IWX_SF_AGG_UNICAST_IDLE_TIMER)
8227 	},
8228 	{
8229 		htole32(IWX_SF_MCAST_AGING_TIMER),
8230 		htole32(IWX_SF_MCAST_IDLE_TIMER)
8231 	},
8232 	{
8233 		htole32(IWX_SF_BA_AGING_TIMER),
8234 		htole32(IWX_SF_BA_IDLE_TIMER)
8235 	},
8236 	{
8237 		htole32(IWX_SF_TX_RE_AGING_TIMER),
8238 		htole32(IWX_SF_TX_RE_IDLE_TIMER)
8239 	},
8240 };
8241 
8242 static void
iwx_fill_sf_command(struct iwx_softc * sc,struct iwx_sf_cfg_cmd * sf_cmd,struct ieee80211_node * ni)8243 iwx_fill_sf_command(struct iwx_softc *sc, struct iwx_sf_cfg_cmd *sf_cmd,
8244     struct ieee80211_node *ni)
8245 {
8246 	int i, j, watermark;
8247 
8248 	sf_cmd->watermark[IWX_SF_LONG_DELAY_ON] = htole32(IWX_SF_W_MARK_SCAN);
8249 
8250 	/*
8251 	 * If we are in association flow - check antenna configuration
8252 	 * capabilities of the AP station, and choose the watermark accordingly.
8253 	 */
8254 	if (ni) {
8255 		if (ni->ni_flags & IEEE80211_NODE_HT) {
8256 			struct ieee80211_htrateset *htrs = &ni->ni_htrates;
8257 			int hasmimo = 0;
8258 			for (i = 0; i < htrs->rs_nrates; i++) {
8259 				if (htrs->rs_rates[i] > 7) {
8260 					hasmimo = 1;
8261 					break;
8262 				}
8263 			}
8264 			if (hasmimo)
8265 				watermark = IWX_SF_W_MARK_MIMO2;
8266 			else
8267 				watermark = IWX_SF_W_MARK_SISO;
8268 		} else {
8269 			watermark = IWX_SF_W_MARK_LEGACY;
8270 		}
8271 	/* default watermark value for unassociated mode. */
8272 	} else {
8273 		watermark = IWX_SF_W_MARK_MIMO2;
8274 	}
8275 	sf_cmd->watermark[IWX_SF_FULL_ON] = htole32(watermark);
8276 
8277 	for (i = 0; i < IWX_SF_NUM_SCENARIO; i++) {
8278 		for (j = 0; j < IWX_SF_NUM_TIMEOUT_TYPES; j++) {
8279 			sf_cmd->long_delay_timeouts[i][j] =
8280 					htole32(IWX_SF_LONG_DELAY_AGING_TIMER);
8281 		}
8282 	}
8283 
8284 	if (ni) {
8285 		memcpy(sf_cmd->full_on_timeouts, iwx_sf_full_timeout,
8286 		       sizeof(iwx_sf_full_timeout));
8287 	} else {
8288 		memcpy(sf_cmd->full_on_timeouts, iwx_sf_full_timeout_def,
8289 		       sizeof(iwx_sf_full_timeout_def));
8290 	}
8291 
8292 }
8293 
8294 static int
iwx_sf_config(struct iwx_softc * sc,int new_state)8295 iwx_sf_config(struct iwx_softc *sc, int new_state)
8296 {
8297 	struct ieee80211com *ic = &sc->sc_ic;
8298 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8299 	struct ieee80211_node *ni = vap->iv_bss;
8300 	struct iwx_sf_cfg_cmd sf_cmd = {
8301 		.state = htole32(new_state),
8302 	};
8303 	int err = 0;
8304 
8305 	switch (new_state) {
8306 	case IWX_SF_UNINIT:
8307 	case IWX_SF_INIT_OFF:
8308 		iwx_fill_sf_command(sc, &sf_cmd, NULL);
8309 		break;
8310 	case IWX_SF_FULL_ON:
8311 		iwx_fill_sf_command(sc, &sf_cmd, ni);
8312 		break;
8313 	default:
8314 		return EINVAL;
8315 	}
8316 
8317 	err = iwx_send_cmd_pdu(sc, IWX_REPLY_SF_CFG_CMD, IWX_CMD_ASYNC,
8318 				   sizeof(sf_cmd), &sf_cmd);
8319 	return err;
8320 }
8321 
8322 static int
iwx_send_bt_init_conf(struct iwx_softc * sc)8323 iwx_send_bt_init_conf(struct iwx_softc *sc)
8324 {
8325 	struct iwx_bt_coex_cmd bt_cmd;
8326 
8327 	bzero(&bt_cmd, sizeof(struct iwx_bt_coex_cmd));
8328 
8329 	bt_cmd.mode = htole32(IWX_BT_COEX_NW);
8330 	bt_cmd.enabled_modules |= BT_COEX_SYNC2SCO_ENABLED;
8331 	bt_cmd.enabled_modules |= BT_COEX_HIGH_BAND_RET;
8332 
8333 
8334 	return iwx_send_cmd_pdu(sc, IWX_BT_CONFIG, 0, sizeof(bt_cmd),
8335 	    &bt_cmd);
8336 }
8337 
8338 static int
iwx_send_soc_conf(struct iwx_softc * sc)8339 iwx_send_soc_conf(struct iwx_softc *sc)
8340 {
8341 	struct iwx_soc_configuration_cmd cmd;
8342 	int err;
8343 	uint32_t cmd_id, flags = 0;
8344 
8345 	memset(&cmd, 0, sizeof(cmd));
8346 
8347 	/*
8348 	 * In VER_1 of this command, the discrete value is considered
8349 	 * an integer; In VER_2, it's a bitmask.  Since we have only 2
8350 	 * values in VER_1, this is backwards-compatible with VER_2,
8351 	 * as long as we don't set any other flag bits.
8352 	 */
8353 	if (!sc->sc_integrated) { /* VER_1 */
8354 		flags = IWX_SOC_CONFIG_CMD_FLAGS_DISCRETE;
8355 	} else { /* VER_2 */
8356 		uint8_t scan_cmd_ver;
8357 		if (sc->sc_ltr_delay != IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE)
8358 			flags |= (sc->sc_ltr_delay &
8359 			    IWX_SOC_FLAGS_LTR_APPLY_DELAY_MASK);
8360 		scan_cmd_ver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP,
8361 		    IWX_SCAN_REQ_UMAC);
8362 		if (scan_cmd_ver != IWX_FW_CMD_VER_UNKNOWN &&
8363 		    scan_cmd_ver >= 2 && sc->sc_low_latency_xtal)
8364 			flags |= IWX_SOC_CONFIG_CMD_FLAGS_LOW_LATENCY;
8365 	}
8366 	cmd.flags = htole32(flags);
8367 
8368 	cmd.latency = htole32(sc->sc_xtal_latency);
8369 
8370 	cmd_id = iwx_cmd_id(IWX_SOC_CONFIGURATION_CMD, IWX_SYSTEM_GROUP, 0);
8371 	err = iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd);
8372 	if (err)
8373 		printf("%s: failed to set soc latency: %d\n", DEVNAME(sc), err);
8374 	return err;
8375 }
8376 
8377 static int
iwx_send_update_mcc_cmd(struct iwx_softc * sc,const char * alpha2)8378 iwx_send_update_mcc_cmd(struct iwx_softc *sc, const char *alpha2)
8379 {
8380 	struct iwx_mcc_update_cmd mcc_cmd;
8381 	struct iwx_host_cmd hcmd = {
8382 		.id = IWX_MCC_UPDATE_CMD,
8383 		.flags = IWX_CMD_WANT_RESP,
8384 		.data = { &mcc_cmd },
8385 	};
8386 	struct iwx_rx_packet *pkt;
8387 	struct iwx_mcc_update_resp *resp;
8388 	size_t resp_len;
8389 	int err;
8390 
8391 	memset(&mcc_cmd, 0, sizeof(mcc_cmd));
8392 	mcc_cmd.mcc = htole16(alpha2[0] << 8 | alpha2[1]);
8393 	if (isset(sc->sc_ucode_api, IWX_UCODE_TLV_API_WIFI_MCC_UPDATE) ||
8394 	    isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_LAR_MULTI_MCC))
8395 		mcc_cmd.source_id = IWX_MCC_SOURCE_GET_CURRENT;
8396 	else
8397 		mcc_cmd.source_id = IWX_MCC_SOURCE_OLD_FW;
8398 
8399 	hcmd.len[0] = sizeof(struct iwx_mcc_update_cmd);
8400 	hcmd.resp_pkt_len = IWX_CMD_RESP_MAX;
8401 
8402 	err = iwx_send_cmd(sc, &hcmd);
8403 	if (err)
8404 		return err;
8405 
8406 	pkt = hcmd.resp_pkt;
8407 	if (!pkt || (pkt->hdr.flags & IWX_CMD_FAILED_MSK)) {
8408 		err = EIO;
8409 		goto out;
8410 	}
8411 
8412 	resp_len = iwx_rx_packet_payload_len(pkt);
8413 	if (resp_len < sizeof(*resp)) {
8414 		err = EIO;
8415 		goto out;
8416 	}
8417 
8418 	resp = (void *)pkt->data;
8419 	if (resp_len != sizeof(*resp) +
8420 	    resp->n_channels * sizeof(resp->channels[0])) {
8421 		err = EIO;
8422 		goto out;
8423 	}
8424 
8425 	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",
8426 	    resp->status, resp->mcc, resp->cap, resp->time, resp->geo_info, resp->source_id, resp->n_channels));
8427 
8428 out:
8429 	iwx_free_resp(sc, &hcmd);
8430 
8431 	return err;
8432 }
8433 
8434 static int
iwx_send_temp_report_ths_cmd(struct iwx_softc * sc)8435 iwx_send_temp_report_ths_cmd(struct iwx_softc *sc)
8436 {
8437 	struct iwx_temp_report_ths_cmd cmd;
8438 	int err;
8439 
8440 	/*
8441 	 * In order to give responsibility for critical-temperature-kill
8442 	 * and TX backoff to FW we need to send an empty temperature
8443 	 * reporting command at init time.
8444 	 */
8445 	memset(&cmd, 0, sizeof(cmd));
8446 
8447 	err = iwx_send_cmd_pdu(sc,
8448 	    IWX_WIDE_ID(IWX_PHY_OPS_GROUP, IWX_TEMP_REPORTING_THRESHOLDS_CMD),
8449 	    0, sizeof(cmd), &cmd);
8450 	if (err)
8451 		printf("%s: TEMP_REPORT_THS_CMD command failed (error %d)\n",
8452 		    DEVNAME(sc), err);
8453 
8454 	return err;
8455 }
8456 
8457 static int
iwx_init_hw(struct iwx_softc * sc)8458 iwx_init_hw(struct iwx_softc *sc)
8459 {
8460 	struct ieee80211com *ic = &sc->sc_ic;
8461 	int err = 0, i;
8462 
8463 	err = iwx_run_init_mvm_ucode(sc, 0);
8464 	if (err)
8465 		return err;
8466 
8467 	if (!iwx_nic_lock(sc))
8468 		return EBUSY;
8469 
8470 	err = iwx_send_tx_ant_cfg(sc, iwx_fw_valid_tx_ant(sc));
8471 	if (err) {
8472 		printf("%s: could not init tx ant config (error %d)\n",
8473 		    DEVNAME(sc), err);
8474 		goto err;
8475 	}
8476 
8477 	if (sc->sc_tx_with_siso_diversity) {
8478 		err = iwx_send_phy_cfg_cmd(sc);
8479 		if (err) {
8480 			printf("%s: could not send phy config (error %d)\n",
8481 			    DEVNAME(sc), err);
8482 			goto err;
8483 		}
8484 	}
8485 
8486 	err = iwx_send_bt_init_conf(sc);
8487 	if (err) {
8488 		printf("%s: could not init bt coex (error %d)\n",
8489 		    DEVNAME(sc), err);
8490 		return err;
8491 	}
8492 
8493 	err = iwx_send_soc_conf(sc);
8494 	if (err) {
8495 		printf("%s: iwx_send_soc_conf failed\n", __func__);
8496 		return err;
8497 	}
8498 
8499 	if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_DQA_SUPPORT)) {
8500 		printf("%s: === IWX_UCODE_TLV_CAPA_DQA_SUPPORT\n", __func__);
8501 		err = iwx_send_dqa_cmd(sc);
8502 		if (err) {
8503 			printf("%s: IWX_UCODE_TLV_CAPA_DQA_SUPPORT "
8504 			    "failed (error %d)\n", __func__, err);
8505 			return err;
8506 		}
8507 	}
8508 	// TODO phyctxt
8509 	for (i = 0; i < IWX_NUM_PHY_CTX; i++) {
8510 		/*
8511 		 * The channel used here isn't relevant as it's
8512 		 * going to be overwritten in the other flows.
8513 		 * For now use the first channel we have.
8514 		 */
8515 		sc->sc_phyctxt[i].id = i;
8516 		sc->sc_phyctxt[i].channel = &ic->ic_channels[1];
8517 		err = iwx_phy_ctxt_cmd(sc, &sc->sc_phyctxt[i], 1, 1,
8518 		    IWX_FW_CTXT_ACTION_ADD, 0, 0, 0);
8519 		if (err) {
8520 			printf("%s: could not add phy context %d (error %d)\n",
8521 			    DEVNAME(sc), i, err);
8522 			goto err;
8523 		}
8524 		if (iwx_lookup_cmd_ver(sc, IWX_DATA_PATH_GROUP,
8525 		    IWX_RLC_CONFIG_CMD) == 2) {
8526 			err = iwx_phy_send_rlc(sc, &sc->sc_phyctxt[i], 1, 1);
8527 			if (err) {
8528 				printf("%s: could not configure RLC for PHY "
8529 				    "%d (error %d)\n", DEVNAME(sc), i, err);
8530 				goto err;
8531 			}
8532 		}
8533 	}
8534 
8535 	err = iwx_config_ltr(sc);
8536 	if (err) {
8537 		printf("%s: PCIe LTR configuration failed (error %d)\n",
8538 		    DEVNAME(sc), err);
8539 	}
8540 
8541 	if (isset(sc->sc_enabled_capa, IWX_UCODE_TLV_CAPA_CT_KILL_BY_FW)) {
8542 		err = iwx_send_temp_report_ths_cmd(sc);
8543 		if (err) {
8544 			printf("%s: iwx_send_temp_report_ths_cmd failed\n",
8545 			    __func__);
8546 			goto err;
8547 		}
8548 	}
8549 
8550 	err = iwx_power_update_device(sc);
8551 	if (err) {
8552 		printf("%s: could not send power command (error %d)\n",
8553 		    DEVNAME(sc), err);
8554 		goto err;
8555 	}
8556 
8557 	if (sc->sc_nvm.lar_enabled) {
8558 		err = iwx_send_update_mcc_cmd(sc, "ZZ");
8559 		if (err) {
8560 			printf("%s: could not init LAR (error %d)\n",
8561 			    DEVNAME(sc), err);
8562 			goto err;
8563 		}
8564 	}
8565 
8566 	err = iwx_config_umac_scan_reduced(sc);
8567 	if (err) {
8568 		printf("%s: could not configure scan (error %d)\n",
8569 		    DEVNAME(sc), err);
8570 		goto err;
8571 	}
8572 
8573 	err = iwx_disable_beacon_filter(sc);
8574 	if (err) {
8575 		printf("%s: could not disable beacon filter (error %d)\n",
8576 		    DEVNAME(sc), err);
8577 		goto err;
8578 	}
8579 
8580 err:
8581 	iwx_nic_unlock(sc);
8582 	return err;
8583 }
8584 
8585 /* Allow multicast from our BSSID. */
8586 static int
iwx_allow_mcast(struct iwx_softc * sc)8587 iwx_allow_mcast(struct iwx_softc *sc)
8588 {
8589 	struct ieee80211com *ic = &sc->sc_ic;
8590 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8591 	struct iwx_node *in = IWX_NODE(vap->iv_bss);
8592 	struct iwx_mcast_filter_cmd *cmd;
8593 	size_t size;
8594 	int err;
8595 
8596 	size = roundup(sizeof(*cmd), 4);
8597 	cmd = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
8598 	if (cmd == NULL)
8599 		return ENOMEM;
8600 	cmd->filter_own = 1;
8601 	cmd->port_id = 0;
8602 	cmd->count = 0;
8603 	cmd->pass_all = 1;
8604 	IEEE80211_ADDR_COPY(cmd->bssid, in->in_macaddr);
8605 
8606 	err = iwx_send_cmd_pdu(sc, IWX_MCAST_FILTER_CMD,
8607 	    0, size, cmd);
8608 	free(cmd, M_DEVBUF);
8609 	return err;
8610 }
8611 
8612 static int
iwx_init(struct iwx_softc * sc)8613 iwx_init(struct iwx_softc *sc)
8614 {
8615 	int err, generation;
8616 	generation = ++sc->sc_generation;
8617 	iwx_preinit(sc);
8618 
8619 	err = iwx_start_hw(sc);
8620 	if (err) {
8621 		printf("%s: iwx_start_hw failed\n", __func__);
8622 		return err;
8623 	}
8624 
8625 	err = iwx_init_hw(sc);
8626 	if (err) {
8627 		if (generation == sc->sc_generation)
8628 			iwx_stop_device(sc);
8629 		printf("%s: iwx_init_hw failed (error %d)\n", __func__, err);
8630 		return err;
8631 	}
8632 
8633 	sc->sc_flags |= IWX_FLAG_HW_INITED;
8634 	callout_reset(&sc->watchdog_to, hz, iwx_watchdog, sc);
8635 
8636 	return 0;
8637 }
8638 
8639 static void
iwx_start(struct iwx_softc * sc)8640 iwx_start(struct iwx_softc *sc)
8641 {
8642         struct ieee80211_node *ni;
8643         struct mbuf *m;
8644 
8645         IWX_ASSERT_LOCKED(sc);
8646 
8647         while (sc->qfullmsk == 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
8648                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
8649                 if (iwx_tx(sc, m, ni) != 0) {
8650                       if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
8651                         continue;
8652                 }
8653         }
8654 }
8655 
8656 static void
iwx_stop(struct iwx_softc * sc)8657 iwx_stop(struct iwx_softc *sc)
8658 {
8659 	struct ieee80211com *ic = &sc->sc_ic;
8660 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8661 	struct iwx_vap *ivp = IWX_VAP(vap);
8662 
8663 	iwx_stop_device(sc);
8664 
8665 	/* Reset soft state. */
8666 	sc->sc_generation++;
8667 	ivp->phy_ctxt = NULL;
8668 
8669 	sc->sc_flags &= ~(IWX_FLAG_SCANNING | IWX_FLAG_BGSCAN);
8670 	sc->sc_flags &= ~IWX_FLAG_MAC_ACTIVE;
8671 	sc->sc_flags &= ~IWX_FLAG_BINDING_ACTIVE;
8672 	sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE;
8673 	sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE;
8674 	sc->sc_flags &= ~IWX_FLAG_HW_ERR;
8675 	sc->sc_flags &= ~IWX_FLAG_SHUTDOWN;
8676 	sc->sc_flags &= ~IWX_FLAG_TXFLUSH;
8677 
8678 	sc->sc_rx_ba_sessions = 0;
8679 	sc->ba_rx.start_tidmask = 0;
8680 	sc->ba_rx.stop_tidmask = 0;
8681 	memset(sc->aggqid, 0, sizeof(sc->aggqid));
8682 	sc->ba_tx.start_tidmask = 0;
8683 	sc->ba_tx.stop_tidmask = 0;
8684 }
8685 
8686 static void
iwx_watchdog(void * arg)8687 iwx_watchdog(void *arg)
8688 {
8689 	struct iwx_softc *sc = arg;
8690 	struct ieee80211com *ic = &sc->sc_ic;
8691 	int i;
8692 
8693 	/*
8694 	 * We maintain a separate timer for each Tx queue because
8695 	 * Tx aggregation queues can get "stuck" while other queues
8696 	 * keep working. The Linux driver uses a similar workaround.
8697 	 */
8698 	for (i = 0; i < nitems(sc->sc_tx_timer); i++) {
8699 		if (sc->sc_tx_timer[i] > 0) {
8700 			if (--sc->sc_tx_timer[i] == 0) {
8701 				printf("%s: device timeout\n", DEVNAME(sc));
8702 
8703 				iwx_nic_error(sc);
8704 				iwx_dump_driver_status(sc);
8705 				ieee80211_restart_all(ic);
8706 				return;
8707 			}
8708 		}
8709 	}
8710 	callout_reset(&sc->watchdog_to, hz, iwx_watchdog, sc);
8711 }
8712 
8713 /*
8714  * Note: This structure is read from the device with IO accesses,
8715  * and the reading already does the endian conversion. As it is
8716  * read with uint32_t-sized accesses, any members with a different size
8717  * need to be ordered correctly though!
8718  */
8719 struct iwx_error_event_table {
8720 	uint32_t valid;		/* (nonzero) valid, (0) log is empty */
8721 	uint32_t error_id;		/* type of error */
8722 	uint32_t trm_hw_status0;	/* TRM HW status */
8723 	uint32_t trm_hw_status1;	/* TRM HW status */
8724 	uint32_t blink2;		/* branch link */
8725 	uint32_t ilink1;		/* interrupt link */
8726 	uint32_t ilink2;		/* interrupt link */
8727 	uint32_t data1;		/* error-specific data */
8728 	uint32_t data2;		/* error-specific data */
8729 	uint32_t data3;		/* error-specific data */
8730 	uint32_t bcon_time;		/* beacon timer */
8731 	uint32_t tsf_low;		/* network timestamp function timer */
8732 	uint32_t tsf_hi;		/* network timestamp function timer */
8733 	uint32_t gp1;		/* GP1 timer register */
8734 	uint32_t gp2;		/* GP2 timer register */
8735 	uint32_t fw_rev_type;	/* firmware revision type */
8736 	uint32_t major;		/* uCode version major */
8737 	uint32_t minor;		/* uCode version minor */
8738 	uint32_t hw_ver;		/* HW Silicon version */
8739 	uint32_t brd_ver;		/* HW board version */
8740 	uint32_t log_pc;		/* log program counter */
8741 	uint32_t frame_ptr;		/* frame pointer */
8742 	uint32_t stack_ptr;		/* stack pointer */
8743 	uint32_t hcmd;		/* last host command header */
8744 	uint32_t isr0;		/* isr status register LMPM_NIC_ISR0:
8745 				 * rxtx_flag */
8746 	uint32_t isr1;		/* isr status register LMPM_NIC_ISR1:
8747 				 * host_flag */
8748 	uint32_t isr2;		/* isr status register LMPM_NIC_ISR2:
8749 				 * enc_flag */
8750 	uint32_t isr3;		/* isr status register LMPM_NIC_ISR3:
8751 				 * time_flag */
8752 	uint32_t isr4;		/* isr status register LMPM_NIC_ISR4:
8753 				 * wico interrupt */
8754 	uint32_t last_cmd_id;	/* last HCMD id handled by the firmware */
8755 	uint32_t wait_event;		/* wait event() caller address */
8756 	uint32_t l2p_control;	/* L2pControlField */
8757 	uint32_t l2p_duration;	/* L2pDurationField */
8758 	uint32_t l2p_mhvalid;	/* L2pMhValidBits */
8759 	uint32_t l2p_addr_match;	/* L2pAddrMatchStat */
8760 	uint32_t lmpm_pmg_sel;	/* indicate which clocks are turned on
8761 				 * (LMPM_PMG_SEL) */
8762 	uint32_t u_timestamp;	/* indicate when the date and time of the
8763 				 * compilation */
8764 	uint32_t flow_handler;	/* FH read/write pointers, RX credit */
8765 } __packed /* LOG_ERROR_TABLE_API_S_VER_3 */;
8766 
8767 /*
8768  * UMAC error struct - relevant starting from family 8000 chip.
8769  * Note: This structure is read from the device with IO accesses,
8770  * and the reading already does the endian conversion. As it is
8771  * read with u32-sized accesses, any members with a different size
8772  * need to be ordered correctly though!
8773  */
8774 struct iwx_umac_error_event_table {
8775 	uint32_t valid;		/* (nonzero) valid, (0) log is empty */
8776 	uint32_t error_id;	/* type of error */
8777 	uint32_t blink1;	/* branch link */
8778 	uint32_t blink2;	/* branch link */
8779 	uint32_t ilink1;	/* interrupt link */
8780 	uint32_t ilink2;	/* interrupt link */
8781 	uint32_t data1;		/* error-specific data */
8782 	uint32_t data2;		/* error-specific data */
8783 	uint32_t data3;		/* error-specific data */
8784 	uint32_t umac_major;
8785 	uint32_t umac_minor;
8786 	uint32_t frame_pointer;	/* core register 27*/
8787 	uint32_t stack_pointer;	/* core register 28 */
8788 	uint32_t cmd_header;	/* latest host cmd sent to UMAC */
8789 	uint32_t nic_isr_pref;	/* ISR status register */
8790 } __packed;
8791 
8792 #define ERROR_START_OFFSET  (1 * sizeof(uint32_t))
8793 #define ERROR_ELEM_SIZE     (7 * sizeof(uint32_t))
8794 
8795 static void
iwx_nic_umac_error(struct iwx_softc * sc)8796 iwx_nic_umac_error(struct iwx_softc *sc)
8797 {
8798 	struct iwx_umac_error_event_table table;
8799 	uint32_t base;
8800 
8801 	base = sc->sc_uc.uc_umac_error_event_table;
8802 
8803 	if (base < 0x400000) {
8804 		printf("%s: Invalid error log pointer 0x%08x\n",
8805 		    DEVNAME(sc), base);
8806 		return;
8807 	}
8808 
8809 	if (iwx_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t))) {
8810 		printf("%s: reading errlog failed\n", DEVNAME(sc));
8811 		return;
8812 	}
8813 
8814 	if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
8815 		printf("%s: Start UMAC Error Log Dump:\n", DEVNAME(sc));
8816 		printf("%s: Status: 0x%x, count: %d\n", DEVNAME(sc),
8817 			sc->sc_flags, table.valid);
8818 	}
8819 
8820 	printf("%s: 0x%08X | %s\n", DEVNAME(sc), table.error_id,
8821 		iwx_desc_lookup(table.error_id));
8822 	printf("%s: 0x%08X | umac branchlink1\n", DEVNAME(sc), table.blink1);
8823 	printf("%s: 0x%08X | umac branchlink2\n", DEVNAME(sc), table.blink2);
8824 	printf("%s: 0x%08X | umac interruptlink1\n", DEVNAME(sc), table.ilink1);
8825 	printf("%s: 0x%08X | umac interruptlink2\n", DEVNAME(sc), table.ilink2);
8826 	printf("%s: 0x%08X | umac data1\n", DEVNAME(sc), table.data1);
8827 	printf("%s: 0x%08X | umac data2\n", DEVNAME(sc), table.data2);
8828 	printf("%s: 0x%08X | umac data3\n", DEVNAME(sc), table.data3);
8829 	printf("%s: 0x%08X | umac major\n", DEVNAME(sc), table.umac_major);
8830 	printf("%s: 0x%08X | umac minor\n", DEVNAME(sc), table.umac_minor);
8831 	printf("%s: 0x%08X | frame pointer\n", DEVNAME(sc),
8832 	    table.frame_pointer);
8833 	printf("%s: 0x%08X | stack pointer\n", DEVNAME(sc),
8834 	    table.stack_pointer);
8835 	printf("%s: 0x%08X | last host cmd\n", DEVNAME(sc), table.cmd_header);
8836 	printf("%s: 0x%08X | isr status reg\n", DEVNAME(sc),
8837 	    table.nic_isr_pref);
8838 }
8839 
8840 #define IWX_FW_SYSASSERT_CPU_MASK 0xf0000000
8841 static struct {
8842 	const char *name;
8843 	uint8_t num;
8844 } advanced_lookup[] = {
8845 	{ "NMI_INTERRUPT_WDG", 0x34 },
8846 	{ "SYSASSERT", 0x35 },
8847 	{ "UCODE_VERSION_MISMATCH", 0x37 },
8848 	{ "BAD_COMMAND", 0x38 },
8849 	{ "BAD_COMMAND", 0x39 },
8850 	{ "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
8851 	{ "FATAL_ERROR", 0x3D },
8852 	{ "NMI_TRM_HW_ERR", 0x46 },
8853 	{ "NMI_INTERRUPT_TRM", 0x4C },
8854 	{ "NMI_INTERRUPT_BREAK_POINT", 0x54 },
8855 	{ "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
8856 	{ "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
8857 	{ "NMI_INTERRUPT_HOST", 0x66 },
8858 	{ "NMI_INTERRUPT_LMAC_FATAL", 0x70 },
8859 	{ "NMI_INTERRUPT_UMAC_FATAL", 0x71 },
8860 	{ "NMI_INTERRUPT_OTHER_LMAC_FATAL", 0x73 },
8861 	{ "NMI_INTERRUPT_ACTION_PT", 0x7C },
8862 	{ "NMI_INTERRUPT_UNKNOWN", 0x84 },
8863 	{ "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
8864 	{ "ADVANCED_SYSASSERT", 0 },
8865 };
8866 
8867 static const char *
iwx_desc_lookup(uint32_t num)8868 iwx_desc_lookup(uint32_t num)
8869 {
8870 	int i;
8871 
8872 	for (i = 0; i < nitems(advanced_lookup) - 1; i++)
8873 		if (advanced_lookup[i].num ==
8874 		    (num & ~IWX_FW_SYSASSERT_CPU_MASK))
8875 			return advanced_lookup[i].name;
8876 
8877 	/* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */
8878 	return advanced_lookup[i].name;
8879 }
8880 
8881 /*
8882  * Support for dumping the error log seemed like a good idea ...
8883  * but it's mostly hex junk and the only sensible thing is the
8884  * hw/ucode revision (which we know anyway).  Since it's here,
8885  * I'll just leave it in, just in case e.g. the Intel guys want to
8886  * help us decipher some "ADVANCED_SYSASSERT" later.
8887  */
8888 static void
iwx_nic_error(struct iwx_softc * sc)8889 iwx_nic_error(struct iwx_softc *sc)
8890 {
8891 	struct iwx_error_event_table table;
8892 	uint32_t base;
8893 
8894 	printf("%s: dumping device error log\n", DEVNAME(sc));
8895 	printf("%s: GOS-3758: 1\n", __func__);
8896 	base = sc->sc_uc.uc_lmac_error_event_table[0];
8897 	printf("%s: GOS-3758: 2\n", __func__);
8898 	if (base < 0x400000) {
8899 		printf("%s: Invalid error log pointer 0x%08x\n",
8900 		    DEVNAME(sc), base);
8901 		return;
8902 	}
8903 
8904 	printf("%s: GOS-3758: 3\n", __func__);
8905 	if (iwx_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t))) {
8906 		printf("%s: reading errlog failed\n", DEVNAME(sc));
8907 		return;
8908 	}
8909 
8910 	printf("%s: GOS-3758: 4\n", __func__);
8911 	if (!table.valid) {
8912 		printf("%s: errlog not found, skipping\n", DEVNAME(sc));
8913 		return;
8914 	}
8915 
8916 	printf("%s: GOS-3758: 5\n", __func__);
8917 	if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
8918 		printf("%s: Start Error Log Dump:\n", DEVNAME(sc));
8919 		printf("%s: Status: 0x%x, count: %d\n", DEVNAME(sc),
8920 		    sc->sc_flags, table.valid);
8921 	}
8922 
8923 	printf("%s: GOS-3758: 6\n", __func__);
8924 	printf("%s: 0x%08X | %-28s\n", DEVNAME(sc), table.error_id,
8925 	    iwx_desc_lookup(table.error_id));
8926 	printf("%s: %08X | trm_hw_status0\n", DEVNAME(sc),
8927 	    table.trm_hw_status0);
8928 	printf("%s: %08X | trm_hw_status1\n", DEVNAME(sc),
8929 	    table.trm_hw_status1);
8930 	printf("%s: %08X | branchlink2\n", DEVNAME(sc), table.blink2);
8931 	printf("%s: %08X | interruptlink1\n", DEVNAME(sc), table.ilink1);
8932 	printf("%s: %08X | interruptlink2\n", DEVNAME(sc), table.ilink2);
8933 	printf("%s: %08X | data1\n", DEVNAME(sc), table.data1);
8934 	printf("%s: %08X | data2\n", DEVNAME(sc), table.data2);
8935 	printf("%s: %08X | data3\n", DEVNAME(sc), table.data3);
8936 	printf("%s: %08X | beacon time\n", DEVNAME(sc), table.bcon_time);
8937 	printf("%s: %08X | tsf low\n", DEVNAME(sc), table.tsf_low);
8938 	printf("%s: %08X | tsf hi\n", DEVNAME(sc), table.tsf_hi);
8939 	printf("%s: %08X | time gp1\n", DEVNAME(sc), table.gp1);
8940 	printf("%s: %08X | time gp2\n", DEVNAME(sc), table.gp2);
8941 	printf("%s: %08X | uCode revision type\n", DEVNAME(sc),
8942 	    table.fw_rev_type);
8943 	printf("%s: %08X | uCode version major\n", DEVNAME(sc),
8944 	    table.major);
8945 	printf("%s: %08X | uCode version minor\n", DEVNAME(sc),
8946 	    table.minor);
8947 	printf("%s: %08X | hw version\n", DEVNAME(sc), table.hw_ver);
8948 	printf("%s: %08X | board version\n", DEVNAME(sc), table.brd_ver);
8949 	printf("%s: %08X | hcmd\n", DEVNAME(sc), table.hcmd);
8950 	printf("%s: %08X | isr0\n", DEVNAME(sc), table.isr0);
8951 	printf("%s: %08X | isr1\n", DEVNAME(sc), table.isr1);
8952 	printf("%s: %08X | isr2\n", DEVNAME(sc), table.isr2);
8953 	printf("%s: %08X | isr3\n", DEVNAME(sc), table.isr3);
8954 	printf("%s: %08X | isr4\n", DEVNAME(sc), table.isr4);
8955 	printf("%s: %08X | last cmd Id\n", DEVNAME(sc), table.last_cmd_id);
8956 	printf("%s: %08X | wait_event\n", DEVNAME(sc), table.wait_event);
8957 	printf("%s: %08X | l2p_control\n", DEVNAME(sc), table.l2p_control);
8958 	printf("%s: %08X | l2p_duration\n", DEVNAME(sc), table.l2p_duration);
8959 	printf("%s: %08X | l2p_mhvalid\n", DEVNAME(sc), table.l2p_mhvalid);
8960 	printf("%s: %08X | l2p_addr_match\n", DEVNAME(sc), table.l2p_addr_match);
8961 	printf("%s: %08X | lmpm_pmg_sel\n", DEVNAME(sc), table.lmpm_pmg_sel);
8962 	printf("%s: %08X | timestamp\n", DEVNAME(sc), table.u_timestamp);
8963 	printf("%s: %08X | flow_handler\n", DEVNAME(sc), table.flow_handler);
8964 
8965 	if (sc->sc_uc.uc_umac_error_event_table)
8966 		iwx_nic_umac_error(sc);
8967 }
8968 
8969 static void
iwx_dump_driver_status(struct iwx_softc * sc)8970 iwx_dump_driver_status(struct iwx_softc *sc)
8971 {
8972 	struct ieee80211com *ic = &sc->sc_ic;
8973 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
8974 	enum ieee80211_state state = vap->iv_state;
8975 	int i;
8976 
8977 	printf("driver status:\n");
8978 	for (i = 0; i < nitems(sc->txq); i++) {
8979 		struct iwx_tx_ring *ring = &sc->txq[i];
8980 		printf("  tx ring %2d: qid=%-2d cur=%-3d "
8981 		    "cur_hw=%-3d queued=%-3d\n",
8982 		    i, ring->qid, ring->cur, ring->cur_hw,
8983 		    ring->queued);
8984 	}
8985 	printf("  rx ring: cur=%d\n", sc->rxq.cur);
8986 	printf("  802.11 state %s\n", ieee80211_state_name[state]);
8987 }
8988 
8989 #define SYNC_RESP_STRUCT(_var_, _pkt_)					\
8990 do {									\
8991 	bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); \
8992 	_var_ = (void *)((_pkt_)+1);					\
8993 } while (/*CONSTCOND*/0)
8994 
8995 static int
iwx_rx_pkt_valid(struct iwx_rx_packet * pkt)8996 iwx_rx_pkt_valid(struct iwx_rx_packet *pkt)
8997 {
8998 	int qid, idx, code;
8999 
9000 	qid = pkt->hdr.qid & ~0x80;
9001 	idx = pkt->hdr.idx;
9002 	code = IWX_WIDE_ID(pkt->hdr.flags, pkt->hdr.code);
9003 
9004 	return (!(qid == 0 && idx == 0 && code == 0) &&
9005 	    pkt->len_n_flags != htole32(IWX_FH_RSCSR_FRAME_INVALID));
9006 }
9007 
9008 static void
iwx_rx_pkt(struct iwx_softc * sc,struct iwx_rx_data * data,struct mbuf * ml)9009 iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *data, struct mbuf *ml)
9010 {
9011 	struct ieee80211com *ic = &sc->sc_ic;
9012 	struct iwx_rx_packet *pkt, *nextpkt;
9013 	uint32_t offset = 0, nextoff = 0, nmpdu = 0, len;
9014 	struct mbuf *m0, *m;
9015 	const size_t minsz = sizeof(pkt->len_n_flags) + sizeof(pkt->hdr);
9016 	int qid, idx, code, handled = 1;
9017 
9018 	m0 = data->m;
9019 	while (m0 && offset + minsz < IWX_RBUF_SIZE) {
9020 		pkt = (struct iwx_rx_packet *)(m0->m_data + offset);
9021 		qid = pkt->hdr.qid;
9022 		idx = pkt->hdr.idx;
9023 		code = IWX_WIDE_ID(pkt->hdr.flags, pkt->hdr.code);
9024 
9025 		if (!iwx_rx_pkt_valid(pkt))
9026 			break;
9027 
9028 		/*
9029 		 * XXX Intel inside (tm)
9030 		 * Any commands in the LONG_GROUP could actually be in the
9031 		 * LEGACY group. Firmware API versions >= 50 reject commands
9032 		 * in group 0, forcing us to use this hack.
9033 		 */
9034 		if (iwx_cmd_groupid(code) == IWX_LONG_GROUP) {
9035 			struct iwx_tx_ring *ring = &sc->txq[qid];
9036 			struct iwx_tx_data *txdata = &ring->data[idx];
9037 			if (txdata->flags & IWX_TXDATA_FLAG_CMD_IS_NARROW)
9038 				code = iwx_cmd_opcode(code);
9039 		}
9040 
9041 		len = sizeof(pkt->len_n_flags) + iwx_rx_packet_len(pkt);
9042 		if (len < minsz || len > (IWX_RBUF_SIZE - offset))
9043 			break;
9044 
9045 		// TODO ???
9046 		if (code == IWX_REPLY_RX_MPDU_CMD && ++nmpdu == 1) {
9047 			/* Take mbuf m0 off the RX ring. */
9048 			if (iwx_rx_addbuf(sc, IWX_RBUF_SIZE, sc->rxq.cur)) {
9049 				break;
9050 			}
9051 			KASSERT((data->m != m0), ("%s: data->m != m0", __func__));
9052 		}
9053 
9054 		switch (code) {
9055 		case IWX_REPLY_RX_PHY_CMD:
9056 			/* XXX-THJ: I've not managed to hit this path in testing */
9057 			iwx_rx_rx_phy_cmd(sc, pkt, data);
9058 			break;
9059 
9060 		case IWX_REPLY_RX_MPDU_CMD: {
9061 			size_t maxlen = IWX_RBUF_SIZE - offset - minsz;
9062 			nextoff = offset +
9063 			    roundup(len, IWX_FH_RSCSR_FRAME_ALIGN);
9064 			nextpkt = (struct iwx_rx_packet *)
9065 			    (m0->m_data + nextoff);
9066 			/* AX210 devices ship only one packet per Rx buffer. */
9067 			if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210 ||
9068 			    nextoff + minsz >= IWX_RBUF_SIZE ||
9069 			    !iwx_rx_pkt_valid(nextpkt)) {
9070 				/* No need to copy last frame in buffer. */
9071 				if (offset > 0)
9072 					m_adj(m0, offset);
9073 				iwx_rx_mpdu_mq(sc, m0, pkt->data, maxlen);
9074 				m0 = NULL; /* stack owns m0 now; abort loop */
9075 			} else {
9076 				/*
9077 				 * Create an mbuf which points to the current
9078 				 * packet. Always copy from offset zero to
9079 				 * preserve m_pkthdr.
9080 				 */
9081 				m = m_copym(m0, 0, M_COPYALL, M_NOWAIT);
9082 				if (m == NULL) {
9083 					m_freem(m0);
9084 					m0 = NULL;
9085 					break;
9086 				}
9087 				m_adj(m, offset);
9088 				iwx_rx_mpdu_mq(sc, m, pkt->data, maxlen);
9089 			}
9090 			break;
9091 		}
9092 
9093 //		case IWX_BAR_FRAME_RELEASE:
9094 //			iwx_rx_bar_frame_release(sc, pkt, ml);
9095 //			break;
9096 //
9097 		case IWX_TX_CMD:
9098 			iwx_rx_tx_cmd(sc, pkt, data);
9099 			break;
9100 
9101 		case IWX_BA_NOTIF:
9102 			iwx_rx_compressed_ba(sc, pkt);
9103 			break;
9104 
9105 		case IWX_MISSED_BEACONS_NOTIFICATION:
9106 			IWX_DPRINTF(sc, IWX_DEBUG_BEACON,
9107 			    "%s: IWX_MISSED_BEACONS_NOTIFICATION\n",
9108 			    __func__);
9109 			iwx_rx_bmiss(sc, pkt, data);
9110 			break;
9111 
9112 		case IWX_MFUART_LOAD_NOTIFICATION:
9113 			break;
9114 
9115 		case IWX_ALIVE: {
9116 			struct iwx_alive_resp_v4 *resp4;
9117 			struct iwx_alive_resp_v5 *resp5;
9118 			struct iwx_alive_resp_v6 *resp6;
9119 
9120 			DPRINTF(("%s: firmware alive\n", __func__));
9121 			sc->sc_uc.uc_ok = 0;
9122 
9123 			/*
9124 			 * For v5 and above, we can check the version, for older
9125 			 * versions we need to check the size.
9126 			 */
9127 			 if (iwx_lookup_notif_ver(sc, IWX_LEGACY_GROUP,
9128 			    IWX_ALIVE) == 6) {
9129 				SYNC_RESP_STRUCT(resp6, pkt);
9130 				if (iwx_rx_packet_payload_len(pkt) !=
9131 				    sizeof(*resp6)) {
9132 					sc->sc_uc.uc_intr = 1;
9133 					wakeup(&sc->sc_uc);
9134 					break;
9135 				}
9136 				sc->sc_uc.uc_lmac_error_event_table[0] = le32toh(
9137 				    resp6->lmac_data[0].dbg_ptrs.error_event_table_ptr);
9138 				sc->sc_uc.uc_lmac_error_event_table[1] = le32toh(
9139 				    resp6->lmac_data[1].dbg_ptrs.error_event_table_ptr);
9140 				sc->sc_uc.uc_log_event_table = le32toh(
9141 				    resp6->lmac_data[0].dbg_ptrs.log_event_table_ptr);
9142 				sc->sc_uc.uc_umac_error_event_table = le32toh(
9143 				    resp6->umac_data.dbg_ptrs.error_info_addr);
9144 				sc->sc_sku_id[0] =
9145 				    le32toh(resp6->sku_id.data[0]);
9146 				sc->sc_sku_id[1] =
9147 				    le32toh(resp6->sku_id.data[1]);
9148 				sc->sc_sku_id[2] =
9149 				    le32toh(resp6->sku_id.data[2]);
9150 				if (resp6->status == IWX_ALIVE_STATUS_OK) {
9151 					sc->sc_uc.uc_ok = 1;
9152 				}
9153 			 } else if (iwx_lookup_notif_ver(sc, IWX_LEGACY_GROUP,
9154 			    IWX_ALIVE) == 5) {
9155 				SYNC_RESP_STRUCT(resp5, pkt);
9156 				if (iwx_rx_packet_payload_len(pkt) !=
9157 				    sizeof(*resp5)) {
9158 					sc->sc_uc.uc_intr = 1;
9159 					wakeup(&sc->sc_uc);
9160 					break;
9161 				}
9162 				sc->sc_uc.uc_lmac_error_event_table[0] = le32toh(
9163 				    resp5->lmac_data[0].dbg_ptrs.error_event_table_ptr);
9164 				sc->sc_uc.uc_lmac_error_event_table[1] = le32toh(
9165 				    resp5->lmac_data[1].dbg_ptrs.error_event_table_ptr);
9166 				sc->sc_uc.uc_log_event_table = le32toh(
9167 				    resp5->lmac_data[0].dbg_ptrs.log_event_table_ptr);
9168 				sc->sc_uc.uc_umac_error_event_table = le32toh(
9169 				    resp5->umac_data.dbg_ptrs.error_info_addr);
9170 				sc->sc_sku_id[0] =
9171 				    le32toh(resp5->sku_id.data[0]);
9172 				sc->sc_sku_id[1] =
9173 				    le32toh(resp5->sku_id.data[1]);
9174 				sc->sc_sku_id[2] =
9175 				    le32toh(resp5->sku_id.data[2]);
9176 				if (resp5->status == IWX_ALIVE_STATUS_OK)
9177 					sc->sc_uc.uc_ok = 1;
9178 			} else if (iwx_rx_packet_payload_len(pkt) == sizeof(*resp4)) {
9179 				SYNC_RESP_STRUCT(resp4, pkt);
9180 				sc->sc_uc.uc_lmac_error_event_table[0] = le32toh(
9181 				    resp4->lmac_data[0].dbg_ptrs.error_event_table_ptr);
9182 				sc->sc_uc.uc_lmac_error_event_table[1] = le32toh(
9183 				    resp4->lmac_data[1].dbg_ptrs.error_event_table_ptr);
9184 				sc->sc_uc.uc_log_event_table = le32toh(
9185 				    resp4->lmac_data[0].dbg_ptrs.log_event_table_ptr);
9186 				sc->sc_uc.uc_umac_error_event_table = le32toh(
9187 				    resp4->umac_data.dbg_ptrs.error_info_addr);
9188 				if (resp4->status == IWX_ALIVE_STATUS_OK)
9189 					sc->sc_uc.uc_ok = 1;
9190 			} else
9191 				printf("unknown payload version");
9192 
9193 			sc->sc_uc.uc_intr = 1;
9194 			wakeup(&sc->sc_uc);
9195 			break;
9196 		}
9197 
9198 		/*
9199 		 * TODO: is this the right struct to use? Look at what
9200 		 * mvm is doing for statistics notification (eg
9201 		 * iwl_mvm_handle_rx_statistics() .
9202 		 */
9203 		case IWX_STATISTICS_NOTIFICATION: {
9204 			struct iwx_notif_statistics *stats;
9205 			SYNC_RESP_STRUCT(stats, pkt);
9206 			memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats));
9207 			sc->sc_noise = iwx_get_noise(sc, &stats->rx.general);
9208 			break;
9209 		}
9210 
9211 		case IWX_DTS_MEASUREMENT_NOTIFICATION:
9212 		case IWX_WIDE_ID(IWX_PHY_OPS_GROUP,
9213 				 IWX_DTS_MEASUREMENT_NOTIF_WIDE):
9214 		case IWX_WIDE_ID(IWX_PHY_OPS_GROUP,
9215 				 IWX_TEMP_REPORTING_THRESHOLDS_CMD):
9216 			break;
9217 
9218 		case IWX_WIDE_ID(IWX_PHY_OPS_GROUP,
9219 		    IWX_CT_KILL_NOTIFICATION): {
9220 			struct iwx_ct_kill_notif *notif;
9221 			SYNC_RESP_STRUCT(notif, pkt);
9222 			printf("%s: device at critical temperature (%u degC), "
9223 			    "stopping device\n",
9224 			    DEVNAME(sc), le16toh(notif->temperature));
9225 			sc->sc_flags |= IWX_FLAG_HW_ERR;
9226 			ieee80211_restart_all(ic);
9227 			break;
9228 		}
9229 
9230 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
9231 		    IWX_SCD_QUEUE_CONFIG_CMD):
9232 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
9233 		    IWX_RX_BAID_ALLOCATION_CONFIG_CMD):
9234 		case IWX_WIDE_ID(IWX_MAC_CONF_GROUP,
9235 		    IWX_SESSION_PROTECTION_CMD):
9236 		case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
9237 		    IWX_NVM_GET_INFO):
9238 		case IWX_ADD_STA_KEY:
9239 		case IWX_PHY_CONFIGURATION_CMD:
9240 		case IWX_TX_ANT_CONFIGURATION_CMD:
9241 		case IWX_ADD_STA:
9242 		case IWX_MAC_CONTEXT_CMD:
9243 		case IWX_REPLY_SF_CFG_CMD:
9244 		case IWX_POWER_TABLE_CMD:
9245 		case IWX_LTR_CONFIG:
9246 		case IWX_PHY_CONTEXT_CMD:
9247 		case IWX_BINDING_CONTEXT_CMD:
9248 		case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_CFG_CMD):
9249 		case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_REQ_UMAC):
9250 		case IWX_WIDE_ID(IWX_LONG_GROUP, IWX_SCAN_ABORT_UMAC):
9251 		case IWX_REPLY_BEACON_FILTERING_CMD:
9252 		case IWX_MAC_PM_POWER_TABLE:
9253 		case IWX_TIME_QUOTA_CMD:
9254 		case IWX_REMOVE_STA:
9255 		case IWX_TXPATH_FLUSH:
9256 		case IWX_BT_CONFIG:
9257 		case IWX_MCC_UPDATE_CMD:
9258 		case IWX_TIME_EVENT_CMD:
9259 		case IWX_STATISTICS_CMD:
9260 		case IWX_SCD_QUEUE_CFG: {
9261 			size_t pkt_len;
9262 
9263 			if (sc->sc_cmd_resp_pkt[idx] == NULL)
9264 				break;
9265 
9266 			bus_dmamap_sync(sc->rxq.data_dmat, data->map,
9267 			    BUS_DMASYNC_POSTREAD);
9268 
9269 			pkt_len = sizeof(pkt->len_n_flags) +
9270 			    iwx_rx_packet_len(pkt);
9271 
9272 			if ((pkt->hdr.flags & IWX_CMD_FAILED_MSK) ||
9273 			    pkt_len < sizeof(*pkt) ||
9274 			    pkt_len > sc->sc_cmd_resp_len[idx]) {
9275 				free(sc->sc_cmd_resp_pkt[idx], M_DEVBUF);
9276 				sc->sc_cmd_resp_pkt[idx] = NULL;
9277 				break;
9278 			}
9279 
9280 			bus_dmamap_sync(sc->rxq.data_dmat, data->map,
9281 			    BUS_DMASYNC_POSTREAD);
9282 			memcpy(sc->sc_cmd_resp_pkt[idx], pkt, pkt_len);
9283 			break;
9284 		}
9285 
9286 		case IWX_INIT_COMPLETE_NOTIF:
9287 			sc->sc_init_complete |= IWX_INIT_COMPLETE;
9288 			wakeup(&sc->sc_init_complete);
9289 			break;
9290 
9291 		case IWX_SCAN_COMPLETE_UMAC: {
9292 			DPRINTF(("%s: >>> IWX_SCAN_COMPLETE_UMAC\n", __func__));
9293 			struct iwx_umac_scan_complete *notif __attribute__((unused));
9294 			SYNC_RESP_STRUCT(notif, pkt);
9295 			DPRINTF(("%s: scan complete notif->status=%d\n", __func__,
9296 			    notif->status));
9297 			ieee80211_runtask(&sc->sc_ic, &sc->sc_es_task);
9298 			iwx_endscan(sc);
9299 			break;
9300 		}
9301 
9302 		case IWX_SCAN_ITERATION_COMPLETE_UMAC: {
9303 			DPRINTF(("%s: >>> IWX_SCAN_ITERATION_COMPLETE_UMAC\n",
9304 			    __func__));
9305 			struct iwx_umac_scan_iter_complete_notif *notif __attribute__((unused));
9306 			SYNC_RESP_STRUCT(notif, pkt);
9307 			DPRINTF(("%s: iter scan complete notif->status=%d\n", __func__,
9308 			    notif->status));
9309 			iwx_endscan(sc);
9310 			break;
9311 		}
9312 
9313 		case IWX_MCC_CHUB_UPDATE_CMD: {
9314 			struct iwx_mcc_chub_notif *notif;
9315 			SYNC_RESP_STRUCT(notif, pkt);
9316 			iwx_mcc_update(sc, notif);
9317 			break;
9318 		}
9319 
9320 		case IWX_REPLY_ERROR: {
9321 			struct iwx_error_resp *resp;
9322 			SYNC_RESP_STRUCT(resp, pkt);
9323 			printf("%s: firmware error 0x%x, cmd 0x%x\n",
9324 				DEVNAME(sc), le32toh(resp->error_type),
9325 				resp->cmd_id);
9326 			break;
9327 		}
9328 
9329 		case IWX_TIME_EVENT_NOTIFICATION: {
9330 			struct iwx_time_event_notif *notif;
9331 			uint32_t action;
9332 			SYNC_RESP_STRUCT(notif, pkt);
9333 
9334 			if (sc->sc_time_event_uid != le32toh(notif->unique_id))
9335 				break;
9336 			action = le32toh(notif->action);
9337 			if (action & IWX_TE_V2_NOTIF_HOST_EVENT_END)
9338 				sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE;
9339 			break;
9340 		}
9341 
9342 		case IWX_WIDE_ID(IWX_MAC_CONF_GROUP,
9343 		    IWX_SESSION_PROTECTION_NOTIF): {
9344 			struct iwx_session_prot_notif *notif;
9345 			uint32_t status, start, conf_id;
9346 
9347 			SYNC_RESP_STRUCT(notif, pkt);
9348 
9349 			status = le32toh(notif->status);
9350 			start = le32toh(notif->start);
9351 			conf_id = le32toh(notif->conf_id);
9352 			/* Check for end of successful PROTECT_CONF_ASSOC. */
9353 			if (status == 1 && start == 0 &&
9354 			    conf_id == IWX_SESSION_PROTECT_CONF_ASSOC)
9355 				sc->sc_flags &= ~IWX_FLAG_TE_ACTIVE;
9356 			break;
9357 		}
9358 
9359 		case IWX_WIDE_ID(IWX_SYSTEM_GROUP,
9360 		    IWX_FSEQ_VER_MISMATCH_NOTIFICATION):
9361 		    break;
9362 
9363 		/*
9364 		 * Firmware versions 21 and 22 generate some DEBUG_LOG_MSG
9365 		 * messages. Just ignore them for now.
9366 		 */
9367 		case IWX_DEBUG_LOG_MSG:
9368 			break;
9369 
9370 		case IWX_MCAST_FILTER_CMD:
9371 			break;
9372 
9373 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_DQA_ENABLE_CMD):
9374 			break;
9375 
9376 		case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_SOC_CONFIGURATION_CMD):
9377 			break;
9378 
9379 		case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_INIT_EXTENDED_CFG_CMD):
9380 			break;
9381 
9382 		case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
9383 		    IWX_NVM_ACCESS_COMPLETE):
9384 			break;
9385 
9386 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_RX_NO_DATA_NOTIF):
9387 			break; /* happens in monitor mode; ignore for now */
9388 
9389 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_TLC_MNG_CONFIG_CMD):
9390 			break;
9391 
9392 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP,
9393 		    IWX_TLC_MNG_UPDATE_NOTIF): {
9394 			struct iwx_tlc_update_notif *notif;
9395 			SYNC_RESP_STRUCT(notif, pkt);
9396 			(void)notif;
9397 			if (iwx_rx_packet_payload_len(pkt) == sizeof(*notif))
9398 				iwx_rs_update(sc, notif);
9399 			break;
9400 		}
9401 
9402 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_RLC_CONFIG_CMD):
9403 			break;
9404 
9405 		/* undocumented notification from iwx-ty-a0-gf-a0-77 image */
9406 		case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, 0xf8):
9407 			break;
9408 
9409 		case IWX_WIDE_ID(IWX_REGULATORY_AND_NVM_GROUP,
9410 		    IWX_PNVM_INIT_COMPLETE):
9411 			DPRINTF(("%s: IWX_PNVM_INIT_COMPLETE\n", __func__));
9412 			sc->sc_init_complete |= IWX_PNVM_COMPLETE;
9413 			wakeup(&sc->sc_init_complete);
9414 			break;
9415 
9416 		default:
9417 			handled = 0;
9418 			/* XXX wulf: Get rid of bluetooth-related spam */
9419 			if ((code == 0xc2 && pkt->len_n_flags == 0x0000000c) ||
9420 			    (code == 0xce && pkt->len_n_flags == 0x2000002c))
9421 				break;
9422 			printf("%s: unhandled firmware response 0x%x/0x%x "
9423 			    "rx ring %d[%d]\n",
9424 			    DEVNAME(sc), code, pkt->len_n_flags,
9425 			    (qid & ~0x80), idx);
9426 			break;
9427 		}
9428 
9429 		/*
9430 		 * uCode sets bit 0x80 when it originates the notification,
9431 		 * i.e. when the notification is not a direct response to a
9432 		 * command sent by the driver.
9433 		 * For example, uCode issues IWX_REPLY_RX when it sends a
9434 		 * received frame to the driver.
9435 		 */
9436 		if (handled && !(qid & (1 << 7))) {
9437 			iwx_cmd_done(sc, qid, idx, code);
9438 		}
9439 
9440 		offset += roundup(len, IWX_FH_RSCSR_FRAME_ALIGN);
9441 
9442 		/* AX210 devices ship only one packet per Rx buffer. */
9443 		if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
9444 			break;
9445 	}
9446 
9447 	if (m0 && m0 != data->m)
9448 		m_freem(m0);
9449 }
9450 
9451 static void
iwx_notif_intr(struct iwx_softc * sc)9452 iwx_notif_intr(struct iwx_softc *sc)
9453 {
9454 	struct mbuf m;
9455 	uint16_t hw;
9456 
9457 	bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map,
9458 	    BUS_DMASYNC_POSTREAD);
9459 
9460 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
9461 		uint16_t *status = sc->rxq.stat_dma.vaddr;
9462 		hw = le16toh(*status) & 0xfff;
9463 	} else
9464 		hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff;
9465 	hw &= (IWX_RX_MQ_RING_COUNT - 1);
9466 	while (sc->rxq.cur != hw) {
9467 		struct iwx_rx_data *data = &sc->rxq.data[sc->rxq.cur];
9468 
9469 		bus_dmamap_sync(sc->rxq.data_dmat, data->map,
9470 		BUS_DMASYNC_POSTREAD);
9471 
9472 		iwx_rx_pkt(sc, data, &m);
9473 		sc->rxq.cur = (sc->rxq.cur + 1) % IWX_RX_MQ_RING_COUNT;
9474 	}
9475 
9476 	/*
9477 	 * Tell the firmware what we have processed.
9478 	 * Seems like the hardware gets upset unless we align the write by 8??
9479 	 */
9480 	hw = (hw == 0) ? IWX_RX_MQ_RING_COUNT - 1 : hw - 1;
9481 	IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, hw & ~7);
9482 }
9483 
9484 #if 0
9485 int
9486 iwx_intr(void *arg)
9487 {
9488 	struct iwx_softc *sc = arg;
9489 	struct ieee80211com *ic = &sc->sc_ic;
9490 	struct ifnet *ifp = IC2IFP(ic);
9491 	int r1, r2, rv = 0;
9492 
9493 	IWX_WRITE(sc, IWX_CSR_INT_MASK, 0);
9494 
9495 	if (sc->sc_flags & IWX_FLAG_USE_ICT) {
9496 		uint32_t *ict = sc->ict_dma.vaddr;
9497 		int tmp;
9498 
9499 		tmp = htole32(ict[sc->ict_cur]);
9500 		if (!tmp)
9501 			goto out_ena;
9502 
9503 		/*
9504 		 * ok, there was something.  keep plowing until we have all.
9505 		 */
9506 		r1 = r2 = 0;
9507 		while (tmp) {
9508 			r1 |= tmp;
9509 			ict[sc->ict_cur] = 0;
9510 			sc->ict_cur = (sc->ict_cur+1) % IWX_ICT_COUNT;
9511 			tmp = htole32(ict[sc->ict_cur]);
9512 		}
9513 
9514 		/* this is where the fun begins.  don't ask */
9515 		if (r1 == 0xffffffff)
9516 			r1 = 0;
9517 
9518 		/* i am not expected to understand this */
9519 		if (r1 & 0xc0000)
9520 			r1 |= 0x8000;
9521 		r1 = (0xff & r1) | ((0xff00 & r1) << 16);
9522 	} else {
9523 		r1 = IWX_READ(sc, IWX_CSR_INT);
9524 		if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
9525 			goto out;
9526 		r2 = IWX_READ(sc, IWX_CSR_FH_INT_STATUS);
9527 	}
9528 	if (r1 == 0 && r2 == 0) {
9529 		goto out_ena;
9530 	}
9531 
9532 	IWX_WRITE(sc, IWX_CSR_INT, r1 | ~sc->sc_intmask);
9533 
9534 	if (r1 & IWX_CSR_INT_BIT_ALIVE) {
9535 #if 0
9536 		int i;
9537 		/* Firmware has now configured the RFH. */
9538 		for (i = 0; i < IWX_RX_MQ_RING_COUNT; i++)
9539 			iwx_update_rx_desc(sc, &sc->rxq, i);
9540 #endif
9541 		IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, 8);
9542 	}
9543 
9544 
9545 	if (r1 & IWX_CSR_INT_BIT_RF_KILL) {
9546 		iwx_check_rfkill(sc);
9547 		rv = 1;
9548 		goto out_ena;
9549 	}
9550 
9551 	if (r1 & IWX_CSR_INT_BIT_SW_ERR) {
9552 		if (ifp->if_flags & IFF_DEBUG) {
9553 			iwx_nic_error(sc);
9554 			iwx_dump_driver_status(sc);
9555 		}
9556 		printf("%s: fatal firmware error\n", DEVNAME(sc));
9557 		ieee80211_restart_all(ic);
9558 		rv = 1;
9559 		goto out;
9560 
9561 	}
9562 
9563 	if (r1 & IWX_CSR_INT_BIT_HW_ERR) {
9564 		printf("%s: hardware error, stopping device \n", DEVNAME(sc));
9565 		iwx_stop(sc);
9566 		rv = 1;
9567 		goto out;
9568 	}
9569 
9570 	/* firmware chunk loaded */
9571 	if (r1 & IWX_CSR_INT_BIT_FH_TX) {
9572 		IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, IWX_CSR_FH_INT_TX_MASK);
9573 
9574 		sc->sc_fw_chunk_done = 1;
9575 		wakeup(&sc->sc_fw);
9576 	}
9577 
9578 	if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX |
9579 	    IWX_CSR_INT_BIT_RX_PERIODIC)) {
9580 		if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX)) {
9581 			IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, IWX_CSR_FH_INT_RX_MASK);
9582 		}
9583 		if (r1 & IWX_CSR_INT_BIT_RX_PERIODIC) {
9584 			IWX_WRITE(sc, IWX_CSR_INT, IWX_CSR_INT_BIT_RX_PERIODIC);
9585 		}
9586 
9587 		/* Disable periodic interrupt; we use it as just a one-shot. */
9588 		IWX_WRITE_1(sc, IWX_CSR_INT_PERIODIC_REG, IWX_CSR_INT_PERIODIC_DIS);
9589 
9590 		/*
9591 		 * Enable periodic interrupt in 8 msec only if we received
9592 		 * real RX interrupt (instead of just periodic int), to catch
9593 		 * any dangling Rx interrupt.  If it was just the periodic
9594 		 * interrupt, there was no dangling Rx activity, and no need
9595 		 * to extend the periodic interrupt; one-shot is enough.
9596 		 */
9597 		if (r1 & (IWX_CSR_INT_BIT_FH_RX | IWX_CSR_INT_BIT_SW_RX))
9598 			IWX_WRITE_1(sc, IWX_CSR_INT_PERIODIC_REG,
9599 			    IWX_CSR_INT_PERIODIC_ENA);
9600 
9601 		iwx_notif_intr(sc);
9602 	}
9603 
9604 	rv = 1;
9605 
9606  out_ena:
9607 	iwx_restore_interrupts(sc);
9608  out:
9609 	return rv;
9610 }
9611 #endif
9612 
9613 static void
iwx_intr_msix(void * arg)9614 iwx_intr_msix(void *arg)
9615 {
9616 	struct iwx_softc *sc = arg;
9617 	struct ieee80211com *ic = &sc->sc_ic;
9618 	uint32_t inta_fh, inta_hw;
9619 	int vector = 0;
9620 
9621 	IWX_LOCK(sc);
9622 
9623 	inta_fh = IWX_READ(sc, IWX_CSR_MSIX_FH_INT_CAUSES_AD);
9624 	inta_hw = IWX_READ(sc, IWX_CSR_MSIX_HW_INT_CAUSES_AD);
9625 	IWX_WRITE(sc, IWX_CSR_MSIX_FH_INT_CAUSES_AD, inta_fh);
9626 	IWX_WRITE(sc, IWX_CSR_MSIX_HW_INT_CAUSES_AD, inta_hw);
9627 	inta_fh &= sc->sc_fh_mask;
9628 	inta_hw &= sc->sc_hw_mask;
9629 
9630 	if (inta_fh & IWX_MSIX_FH_INT_CAUSES_Q0 ||
9631 	    inta_fh & IWX_MSIX_FH_INT_CAUSES_Q1) {
9632 		iwx_notif_intr(sc);
9633 	}
9634 
9635 	/* firmware chunk loaded */
9636 	if (inta_fh & IWX_MSIX_FH_INT_CAUSES_D2S_CH0_NUM) {
9637 		sc->sc_fw_chunk_done = 1;
9638 		wakeup(&sc->sc_fw);
9639 	}
9640 
9641 	if ((inta_fh & IWX_MSIX_FH_INT_CAUSES_FH_ERR) ||
9642 	    (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_SW_ERR) ||
9643 	    (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_SW_ERR_V2)) {
9644 		if (sc->sc_debug) {
9645 			iwx_nic_error(sc);
9646 			iwx_dump_driver_status(sc);
9647 		}
9648 		printf("%s: fatal firmware error\n", DEVNAME(sc));
9649 		ieee80211_restart_all(ic);
9650 		goto out;
9651 	}
9652 
9653 	if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_RF_KILL) {
9654 		iwx_check_rfkill(sc);
9655 	}
9656 
9657 	if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_HW_ERR) {
9658 		printf("%s: hardware error, stopping device \n", DEVNAME(sc));
9659 		sc->sc_flags |= IWX_FLAG_HW_ERR;
9660 		iwx_stop(sc);
9661 		goto out;
9662 	}
9663 
9664 	if (inta_hw & IWX_MSIX_HW_INT_CAUSES_REG_ALIVE) {
9665 		IWX_DPRINTF(sc, IWX_DEBUG_TRACE,
9666 		    "%s:%d WARNING: Skipping rx desc update\n",
9667 		    __func__, __LINE__);
9668 #if 0
9669 		/*
9670 		 * XXX-THJ: we don't have the dma segment handy. This is hacked
9671 		 * out in the fc release, return to it if we ever get this
9672 		 * warning.
9673 		 */
9674 		/* Firmware has now configured the RFH. */
9675 		for (int i = 0; i < IWX_RX_MQ_RING_COUNT; i++)
9676 			iwx_update_rx_desc(sc, &sc->rxq, i);
9677 #endif
9678 		IWX_WRITE(sc, IWX_RFH_Q0_FRBDCB_WIDX_TRG, 8);
9679 	}
9680 
9681 	/*
9682 	 * Before sending the interrupt the HW disables it to prevent
9683 	 * a nested interrupt. This is done by writing 1 to the corresponding
9684 	 * bit in the mask register. After handling the interrupt, it should be
9685 	 * re-enabled by clearing this bit. This register is defined as
9686 	 * write 1 clear (W1C) register, meaning that it's being clear
9687 	 * by writing 1 to the bit.
9688 	 */
9689 	IWX_WRITE(sc, IWX_CSR_MSIX_AUTOMASK_ST_AD, 1 << vector);
9690 out:
9691 	IWX_UNLOCK(sc);
9692 	return;
9693 }
9694 
9695 /*
9696  * The device info table below contains device-specific config overrides.
9697  * The most important parameter derived from this table is the name of the
9698  * firmware image to load.
9699  *
9700  * The Linux iwlwifi driver uses an "old" and a "new" device info table.
9701  * The "old" table matches devices based on PCI vendor/product IDs only.
9702  * The "new" table extends this with various device parameters derived
9703  * from MAC type, and RF type.
9704  *
9705  * In iwlwifi "old" and "new" tables share the same array, where "old"
9706  * entries contain dummy values for data defined only for "new" entries.
9707  * As of 2022, Linux developers are still in the process of moving entries
9708  * from "old" to "new" style and it looks like this effort has stalled in
9709  * in some work-in-progress state for quite a while. Linux commits moving
9710  * entries from "old" to "new" have at times been reverted due to regressions.
9711  * Part of this complexity comes from iwlwifi supporting both iwm(4) and iwx(4)
9712  * devices in the same driver.
9713  *
9714  * Our table below contains mostly "new" entries declared in iwlwifi
9715  * with the _IWL_DEV_INFO() macro (with a leading underscore).
9716  * Other devices are matched based on PCI vendor/product ID as usual,
9717  * unless matching specific PCI subsystem vendor/product IDs is required.
9718  *
9719  * Some "old"-style entries are required to identify the firmware image to use.
9720  * Others might be used to print a specific marketing name into Linux dmesg,
9721  * but we can't be sure whether the corresponding devices would be matched
9722  * correctly in the absence of their entries. So we include them just in case.
9723  */
9724 
9725 struct iwx_dev_info {
9726 	uint16_t device;
9727 	uint16_t subdevice;
9728 	uint16_t mac_type;
9729 	uint16_t rf_type;
9730 	uint8_t mac_step;
9731 	uint8_t rf_id;
9732 	uint8_t no_160;
9733 	uint8_t cores;
9734 	uint8_t cdb;
9735 	uint8_t jacket;
9736 	const struct iwx_device_cfg *cfg;
9737 };
9738 
9739 #define _IWX_DEV_INFO(_device, _subdevice, _mac_type, _mac_step, _rf_type, \
9740 		      _rf_id, _no_160, _cores, _cdb, _jacket, _cfg) \
9741 	{ .device = (_device), .subdevice = (_subdevice), .cfg = &(_cfg),  \
9742 	  .mac_type = _mac_type, .rf_type = _rf_type,	   \
9743 	  .no_160 = _no_160, .cores = _cores, .rf_id = _rf_id,		   \
9744 	  .mac_step = _mac_step, .cdb = _cdb, .jacket = _jacket }
9745 
9746 #define IWX_DEV_INFO(_device, _subdevice, _cfg) \
9747 	_IWX_DEV_INFO(_device, _subdevice, IWX_CFG_ANY, IWX_CFG_ANY,	   \
9748 		      IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_ANY,  \
9749 		      IWX_CFG_ANY, IWX_CFG_ANY, _cfg)
9750 
9751 /*
9752  * When adding entries to this table keep in mind that entries must
9753  * be listed in the same order as in the Linux driver. Code walks this
9754  * table backwards and uses the first matching entry it finds.
9755  * Device firmware must be available in fw_update(8).
9756  */
9757 static const struct iwx_dev_info iwx_dev_info_table[] = {
9758 	/* So with HR */
9759 	IWX_DEV_INFO(0x2725, 0x0090, iwx_2ax_cfg_so_gf_a0),
9760 	IWX_DEV_INFO(0x2725, 0x0020, iwx_2ax_cfg_ty_gf_a0),
9761 	IWX_DEV_INFO(0x2725, 0x2020, iwx_2ax_cfg_ty_gf_a0),
9762 	IWX_DEV_INFO(0x2725, 0x0024, iwx_2ax_cfg_ty_gf_a0),
9763 	IWX_DEV_INFO(0x2725, 0x0310, iwx_2ax_cfg_ty_gf_a0),
9764 	IWX_DEV_INFO(0x2725, 0x0510, iwx_2ax_cfg_ty_gf_a0),
9765 	IWX_DEV_INFO(0x2725, 0x0A10, iwx_2ax_cfg_ty_gf_a0),
9766 	IWX_DEV_INFO(0x2725, 0xE020, iwx_2ax_cfg_ty_gf_a0),
9767 	IWX_DEV_INFO(0x2725, 0xE024, iwx_2ax_cfg_ty_gf_a0),
9768 	IWX_DEV_INFO(0x2725, 0x4020, iwx_2ax_cfg_ty_gf_a0),
9769 	IWX_DEV_INFO(0x2725, 0x6020, iwx_2ax_cfg_ty_gf_a0),
9770 	IWX_DEV_INFO(0x2725, 0x6024, iwx_2ax_cfg_ty_gf_a0),
9771 	IWX_DEV_INFO(0x2725, 0x1673, iwx_2ax_cfg_ty_gf_a0), /* killer_1675w */
9772 	IWX_DEV_INFO(0x2725, 0x1674, iwx_2ax_cfg_ty_gf_a0), /* killer_1675x */
9773 	IWX_DEV_INFO(0x51f0, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */
9774 	IWX_DEV_INFO(0x51f0, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */
9775 	IWX_DEV_INFO(0x51f1, 0x1691, iwx_2ax_cfg_so_gf4_a0),
9776 	IWX_DEV_INFO(0x51f1, 0x1692, iwx_2ax_cfg_so_gf4_a0),
9777 	IWX_DEV_INFO(0x54f0, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */
9778 	IWX_DEV_INFO(0x54f0, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */
9779 	IWX_DEV_INFO(0x7a70, 0x0090, iwx_2ax_cfg_so_gf_a0_long),
9780 	IWX_DEV_INFO(0x7a70, 0x0098, iwx_2ax_cfg_so_gf_a0_long),
9781 	IWX_DEV_INFO(0x7a70, 0x00b0, iwx_2ax_cfg_so_gf4_a0_long),
9782 	IWX_DEV_INFO(0x7a70, 0x0310, iwx_2ax_cfg_so_gf_a0_long),
9783 	IWX_DEV_INFO(0x7a70, 0x0510, iwx_2ax_cfg_so_gf_a0_long),
9784 	IWX_DEV_INFO(0x7a70, 0x0a10, iwx_2ax_cfg_so_gf_a0_long),
9785 	IWX_DEV_INFO(0x7af0, 0x0090, iwx_2ax_cfg_so_gf_a0),
9786 	IWX_DEV_INFO(0x7af0, 0x0098, iwx_2ax_cfg_so_gf_a0),
9787 	IWX_DEV_INFO(0x7af0, 0x00b0, iwx_2ax_cfg_so_gf4_a0),
9788 	IWX_DEV_INFO(0x7a70, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */
9789 	IWX_DEV_INFO(0x7a70, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */
9790 	IWX_DEV_INFO(0x7af0, 0x0310, iwx_2ax_cfg_so_gf_a0),
9791 	IWX_DEV_INFO(0x7af0, 0x0510, iwx_2ax_cfg_so_gf_a0),
9792 	IWX_DEV_INFO(0x7af0, 0x0a10, iwx_2ax_cfg_so_gf_a0),
9793 	IWX_DEV_INFO(0x7f70, 0x1691, iwx_2ax_cfg_so_gf4_a0), /* killer_1690s */
9794 	IWX_DEV_INFO(0x7f70, 0x1692, iwx_2ax_cfg_so_gf4_a0), /* killer_1690i */
9795 
9796 	/* So with GF2 */
9797 	IWX_DEV_INFO(0x2726, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9798 	IWX_DEV_INFO(0x2726, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9799 	IWX_DEV_INFO(0x51f0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9800 	IWX_DEV_INFO(0x51f0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9801 	IWX_DEV_INFO(0x54f0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9802 	IWX_DEV_INFO(0x54f0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9803 	IWX_DEV_INFO(0x7a70, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9804 	IWX_DEV_INFO(0x7a70, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9805 	IWX_DEV_INFO(0x7af0, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9806 	IWX_DEV_INFO(0x7af0, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9807 	IWX_DEV_INFO(0x7f70, 0x1671, iwx_2ax_cfg_so_gf_a0), /* killer_1675s */
9808 	IWX_DEV_INFO(0x7f70, 0x1672, iwx_2ax_cfg_so_gf_a0), /* killer_1675i */
9809 
9810 	/* Qu with Jf, C step */
9811 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9812 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9813 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
9814 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9815 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9461_160 */
9816 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9817 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9818 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
9819 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9820 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* iwl9461 */
9821 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9822 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9823 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9824 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9825 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9462_160 */
9826 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9827 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9828 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9829 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9830 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9462 */
9831 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9832 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9833 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9834 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9835 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9560_160 */
9836 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9837 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9838 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9839 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9840 		      IWX_CFG_ANY, iwx_9560_qu_c0_jf_b0_cfg), /* 9560 */
9841 	_IWX_DEV_INFO(IWX_CFG_ANY, 0x1551,
9842 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9843 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9844 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9845 		      IWX_CFG_ANY,
9846 		      iwx_9560_qu_c0_jf_b0_cfg), /* 9560_killer_1550s */
9847 	_IWX_DEV_INFO(IWX_CFG_ANY, 0x1552,
9848 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9849 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9850 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9851 		      IWX_CFG_ANY,
9852 		      iwx_9560_qu_c0_jf_b0_cfg), /* 9560_killer_1550i */
9853 
9854 	/* QuZ with Jf */
9855 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9856 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9857 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9858 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9859 		      IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9461_160 */
9860 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9861 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9862 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9863 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9864 		      IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9461 */
9865 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9866 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9867 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9868 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9869 		      IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9462_160 */
9870 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9871 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9872 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9873 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9874 		      IWX_CFG_ANY, iwx_9560_quz_a0_jf_b0_cfg), /* 9462 */
9875 	_IWX_DEV_INFO(IWX_CFG_ANY, 0x1551,
9876 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9877 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9878 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9879 		      IWX_CFG_ANY,
9880 		      iwx_9560_quz_a0_jf_b0_cfg), /* killer_1550s */
9881 	_IWX_DEV_INFO(IWX_CFG_ANY, 0x1552,
9882 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9883 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9884 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9885 		      IWX_CFG_ANY,
9886 		      iwx_9560_quz_a0_jf_b0_cfg), /* 9560_killer_1550i */
9887 
9888 	/* Qu with Hr, B step */
9889 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9890 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_B_STEP,
9891 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9892 		      IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9893 		      iwx_qu_b0_hr1_b0), /* AX101 */
9894 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9895 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_B_STEP,
9896 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9897 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9898 		      iwx_qu_b0_hr_b0), /* AX203 */
9899 
9900 	/* Qu with Hr, C step */
9901 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9902 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9903 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9904 		      IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9905 		      iwx_qu_c0_hr1_b0), /* AX101 */
9906 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9907 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9908 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9909 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9910 		      iwx_qu_c0_hr_b0), /* AX203 */
9911 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9912 		      IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP,
9913 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9914 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9915 		      iwx_qu_c0_hr_b0), /* AX201 */
9916 
9917 	/* QuZ with Hr */
9918 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9919 		      IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY,
9920 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9921 		      IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9922 		      iwx_quz_a0_hr1_b0), /* AX101 */
9923 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9924 		      IWX_CFG_MAC_TYPE_QUZ, IWX_SILICON_B_STEP,
9925 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9926 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9927 		      iwx_cfg_quz_a0_hr_b0), /* AX203 */
9928 
9929 	/* SoF with JF2 */
9930 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9931 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9932 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9933 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9934 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560_160 */
9935 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9936 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9937 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
9938 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9939 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560 */
9940 
9941 	/* SoF with JF */
9942 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9943 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9944 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
9945 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9946 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_160 */
9947 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9948 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9949 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9950 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9951 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462_160 */
9952 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9953 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9954 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
9955 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9956 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_name */
9957 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9958 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9959 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
9960 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
9961 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462 */
9962 
9963 	/* So with Hr */
9964 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9965 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
9966 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9967 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9968 		      iwx_cfg_so_a0_hr_b0), /* AX203 */
9969 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9970 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
9971 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9972 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9973 		      iwx_cfg_so_a0_hr_b0), /* ax101 */
9974 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9975 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
9976 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9977 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9978 		      iwx_cfg_so_a0_hr_b0), /* ax201 */
9979 
9980 	/* So-F with Hr */
9981 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9982 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9983 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9984 		      IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9985 		      iwx_cfg_so_a0_hr_b0), /* AX203 */
9986 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9987 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9988 		      IWX_CFG_RF_TYPE_HR1, IWX_CFG_ANY,
9989 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9990 		      iwx_cfg_so_a0_hr_b0), /* AX101 */
9991 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9992 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
9993 		      IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY,
9994 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
9995 		      iwx_cfg_so_a0_hr_b0), /* AX201 */
9996 
9997 	/* So-F with GF */
9998 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
9999 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
10000 		      IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY,
10001 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
10002 		      iwx_2ax_cfg_so_gf_a0), /* AX211 */
10003 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10004 		      IWX_CFG_MAC_TYPE_SOF, IWX_CFG_ANY,
10005 		      IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY,
10006 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_CDB, IWX_CFG_ANY,
10007 		      iwx_2ax_cfg_so_gf4_a0), /* AX411 */
10008 
10009 	/* So with GF */
10010 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10011 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10012 		      IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY,
10013 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY,
10014 		      iwx_2ax_cfg_so_gf_a0), /* AX211 */
10015 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10016 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10017 		      IWX_CFG_RF_TYPE_GF, IWX_CFG_ANY,
10018 		      IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_CDB, IWX_CFG_ANY,
10019 		      iwx_2ax_cfg_so_gf4_a0), /* AX411 */
10020 
10021 	/* So with JF2 */
10022 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10023 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10024 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
10025 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10026 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560_160 */
10027 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10028 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10029 		      IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF,
10030 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10031 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9560 */
10032 
10033 	/* So with JF */
10034 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10035 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10036 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
10037 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10038 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9461_160 */
10039 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10040 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10041 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
10042 		      IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10043 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462_160 */
10044 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10045 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10046 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1,
10047 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10048 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* iwl9461 */
10049 	_IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY,
10050 		      IWX_CFG_MAC_TYPE_SO, IWX_CFG_ANY,
10051 		      IWX_CFG_RF_TYPE_JF1, IWX_CFG_RF_ID_JF1_DIV,
10052 		      IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB,
10053 		      IWX_CFG_ANY, iwx_2ax_cfg_so_jf_b0), /* 9462 */
10054 };
10055 
10056 static int
iwx_preinit(struct iwx_softc * sc)10057 iwx_preinit(struct iwx_softc *sc)
10058 {
10059 	struct ieee80211com *ic = &sc->sc_ic;
10060 	int err;
10061 
10062 	err = iwx_prepare_card_hw(sc);
10063 	if (err) {
10064 		printf("%s: could not initialize hardware\n", DEVNAME(sc));
10065 		return err;
10066 	}
10067 
10068 	if (sc->attached) {
10069 		return 0;
10070 	}
10071 
10072 	err = iwx_start_hw(sc);
10073 	if (err) {
10074 		printf("%s: could not initialize hardware\n", DEVNAME(sc));
10075 		return err;
10076 	}
10077 
10078 	err = iwx_run_init_mvm_ucode(sc, 1);
10079 	iwx_stop_device(sc);
10080 	if (err) {
10081 		printf("%s: failed to stop device\n", DEVNAME(sc));
10082 		return err;
10083 	}
10084 
10085 	/* Print version info and MAC address on first successful fw load. */
10086 	sc->attached = 1;
10087 	if (sc->sc_pnvm_ver) {
10088 		printf("%s: hw rev 0x%x, fw %s, pnvm %08x, "
10089 		    "address %s\n",
10090 		    DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK,
10091 		    sc->sc_fwver, sc->sc_pnvm_ver,
10092 		    ether_sprintf(sc->sc_nvm.hw_addr));
10093 	} else {
10094 		printf("%s: hw rev 0x%x, fw %s, address %s\n",
10095 		    DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK,
10096 		    sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr));
10097 	}
10098 
10099 	/* not all hardware can do 5GHz band */
10100 	if (!sc->sc_nvm.sku_cap_band_52GHz_enable)
10101 		memset(&ic->ic_sup_rates[IEEE80211_MODE_11A], 0,
10102 		    sizeof(ic->ic_sup_rates[IEEE80211_MODE_11A]));
10103 
10104 	return 0;
10105 }
10106 
10107 static void
iwx_attach_hook(void * self)10108 iwx_attach_hook(void *self)
10109 {
10110 	struct iwx_softc *sc = (void *)self;
10111 	struct ieee80211com *ic = &sc->sc_ic;
10112 	int err;
10113 
10114 	IWX_LOCK(sc);
10115 	err = iwx_preinit(sc);
10116 	IWX_UNLOCK(sc);
10117 	if (err != 0)
10118 		goto out;
10119 
10120 	iwx_init_channel_map(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
10121 	    ic->ic_channels);
10122 
10123 	ieee80211_ifattach(ic);
10124 	ic->ic_vap_create = iwx_vap_create;
10125 	ic->ic_vap_delete = iwx_vap_delete;
10126 	ic->ic_raw_xmit = iwx_raw_xmit;
10127 	ic->ic_node_alloc = iwx_node_alloc;
10128 	ic->ic_scan_start = iwx_scan_start;
10129 	ic->ic_scan_end = iwx_scan_end;
10130 	ic->ic_update_mcast = iwx_update_mcast;
10131 	ic->ic_getradiocaps = iwx_init_channel_map;
10132 
10133 	ic->ic_set_channel = iwx_set_channel;
10134 	ic->ic_scan_curchan = iwx_scan_curchan;
10135 	ic->ic_scan_mindwell = iwx_scan_mindwell;
10136 	ic->ic_wme.wme_update = iwx_wme_update;
10137 	ic->ic_parent = iwx_parent;
10138 	ic->ic_transmit = iwx_transmit;
10139 
10140 	sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start;
10141 	ic->ic_ampdu_rx_start = iwx_ampdu_rx_start;
10142 	sc->sc_ampdu_rx_stop = ic->ic_ampdu_rx_stop;
10143 	ic->ic_ampdu_rx_stop = iwx_ampdu_rx_stop;
10144 
10145 	sc->sc_addba_request = ic->ic_addba_request;
10146 	ic->ic_addba_request = iwx_addba_request;
10147 	sc->sc_addba_response = ic->ic_addba_response;
10148 	ic->ic_addba_response = iwx_addba_response;
10149 
10150 	iwx_radiotap_attach(sc);
10151 	ieee80211_announce(ic);
10152 out:
10153 	config_intrhook_disestablish(&sc->sc_preinit_hook);
10154 }
10155 
10156 const struct iwx_device_cfg *
iwx_find_device_cfg(struct iwx_softc * sc)10157 iwx_find_device_cfg(struct iwx_softc *sc)
10158 {
10159 	uint16_t sdev_id, mac_type, rf_type;
10160 	uint8_t mac_step, cdb, jacket, rf_id, no_160, cores;
10161 	int i;
10162 
10163 	sdev_id = pci_get_subdevice(sc->sc_dev);
10164 	mac_type = IWX_CSR_HW_REV_TYPE(sc->sc_hw_rev);
10165 	mac_step = IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2);
10166 	rf_type = IWX_CSR_HW_RFID_TYPE(sc->sc_hw_rf_id);
10167 	cdb = IWX_CSR_HW_RFID_IS_CDB(sc->sc_hw_rf_id);
10168 	jacket = IWX_CSR_HW_RFID_IS_JACKET(sc->sc_hw_rf_id);
10169 
10170 	rf_id = IWX_SUBDEVICE_RF_ID(sdev_id);
10171 	no_160 = IWX_SUBDEVICE_NO_160(sdev_id);
10172 	cores = IWX_SUBDEVICE_CORES(sdev_id);
10173 
10174 	for (i = nitems(iwx_dev_info_table) - 1; i >= 0; i--) {
10175 		 const struct iwx_dev_info *dev_info = &iwx_dev_info_table[i];
10176 
10177 		if (dev_info->device != (uint16_t)IWX_CFG_ANY &&
10178 		    dev_info->device != sc->sc_pid)
10179 			continue;
10180 
10181 		if (dev_info->subdevice != (uint16_t)IWX_CFG_ANY &&
10182 		    dev_info->subdevice != sdev_id)
10183 			continue;
10184 
10185 		if (dev_info->mac_type != (uint16_t)IWX_CFG_ANY &&
10186 		    dev_info->mac_type != mac_type)
10187 			continue;
10188 
10189 		if (dev_info->mac_step != (uint8_t)IWX_CFG_ANY &&
10190 		    dev_info->mac_step != mac_step)
10191 			continue;
10192 
10193 		if (dev_info->rf_type != (uint16_t)IWX_CFG_ANY &&
10194 		    dev_info->rf_type != rf_type)
10195 			continue;
10196 
10197 		if (dev_info->cdb != (uint8_t)IWX_CFG_ANY &&
10198 		    dev_info->cdb != cdb)
10199 			continue;
10200 
10201 		if (dev_info->jacket != (uint8_t)IWX_CFG_ANY &&
10202 		    dev_info->jacket != jacket)
10203 			continue;
10204 
10205 		if (dev_info->rf_id != (uint8_t)IWX_CFG_ANY &&
10206 		    dev_info->rf_id != rf_id)
10207 			continue;
10208 
10209 		if (dev_info->no_160 != (uint8_t)IWX_CFG_ANY &&
10210 		    dev_info->no_160 != no_160)
10211 			continue;
10212 
10213 		if (dev_info->cores != (uint8_t)IWX_CFG_ANY &&
10214 		    dev_info->cores != cores)
10215 			continue;
10216 
10217 		return dev_info->cfg;
10218 	}
10219 
10220 	return NULL;
10221 }
10222 
10223 static int
iwx_probe(device_t dev)10224 iwx_probe(device_t dev)
10225 {
10226 	int i;
10227 
10228 	for (i = 0; i < nitems(iwx_devices); i++) {
10229 		if (pci_get_vendor(dev) == PCI_VENDOR_INTEL &&
10230 		    pci_get_device(dev) == iwx_devices[i].device) {
10231 			device_set_desc(dev, iwx_devices[i].name);
10232 
10233 			/*
10234 			 * Due to significant existing deployments using
10235 			 * iwlwifi lower the priority of iwx.
10236 			 *
10237 			 * This inverts the advice in bus.h where drivers
10238 			 * supporting newer hardware should return
10239 			 * BUS_PROBE_DEFAULT and drivers for older devices
10240 			 * return BUS_PROBE_LOW_PRIORITY.
10241 			 *
10242 			 */
10243 			return (BUS_PROBE_LOW_PRIORITY);
10244 		}
10245 	}
10246 
10247 	return (ENXIO);
10248 }
10249 
10250 static int
iwx_attach(device_t dev)10251 iwx_attach(device_t dev)
10252 {
10253 	struct iwx_softc *sc = device_get_softc(dev);
10254 	struct ieee80211com *ic = &sc->sc_ic;
10255 	const struct iwx_device_cfg *cfg;
10256 	int err;
10257 	int txq_i, i, j;
10258 	size_t ctxt_info_size;
10259 	int rid;
10260 	int count;
10261 	int error;
10262 	sc->sc_dev = dev;
10263 	sc->sc_pid = pci_get_device(dev);
10264 	sc->sc_dmat = bus_get_dma_tag(sc->sc_dev);
10265 
10266 	TASK_INIT(&sc->sc_es_task, 0, iwx_endscan_cb, sc);
10267 	IWX_LOCK_INIT(sc);
10268 	mbufq_init(&sc->sc_snd, ifqmaxlen);
10269 	TASK_INIT(&sc->ba_rx_task, 0, iwx_ba_rx_task, sc);
10270 	TASK_INIT(&sc->ba_tx_task, 0, iwx_ba_tx_task, sc);
10271 	sc->sc_tq = taskqueue_create("iwm_taskq", M_WAITOK,
10272 	    taskqueue_thread_enqueue, &sc->sc_tq);
10273 	error = taskqueue_start_threads(&sc->sc_tq, 1, 0, "iwm_taskq");
10274 	if (error != 0) {
10275 		device_printf(dev, "can't start taskq thread, error %d\n",
10276 		    error);
10277 		return (ENXIO);
10278 	}
10279 
10280 	pci_find_cap(dev, PCIY_EXPRESS, &sc->sc_cap_off);
10281 	if (sc->sc_cap_off == 0) {
10282 		device_printf(dev, "PCIe capability structure not found!\n");
10283 		return (ENXIO);
10284 	}
10285 
10286 	/*
10287 	 * We disable the RETRY_TIMEOUT register (0x41) to keep
10288 	 * PCI Tx retries from interfering with C3 CPU state.
10289 	 */
10290 	pci_write_config(dev, PCI_CFG_RETRY_TIMEOUT, 0x00, 1);
10291 
10292 	if (pci_msix_count(dev)) {
10293 		sc->sc_msix = 1;
10294 	} else {
10295 		device_printf(dev, "no MSI-X found\n");
10296 		return (ENXIO);
10297 	}
10298 
10299 	pci_enable_busmaster(dev);
10300 	rid = PCIR_BAR(0);
10301 	sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
10302 	    RF_ACTIVE);
10303 	if (sc->sc_mem == NULL) {
10304 		device_printf(sc->sc_dev, "can't map mem space\n");
10305 		return (ENXIO);
10306 	}
10307 	sc->sc_st = rman_get_bustag(sc->sc_mem);
10308 	sc->sc_sh = rman_get_bushandle(sc->sc_mem);
10309 
10310 	count = 1;
10311 	rid = 0;
10312 	if (pci_alloc_msix(dev, &count) == 0)
10313 		rid = 1;
10314 	DPRINTF(("%s: count=%d\n", __func__, count));
10315 	sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE |
10316 	    (rid != 0 ? 0 : RF_SHAREABLE));
10317 	if (sc->sc_irq == NULL) {
10318 		device_printf(dev, "can't map interrupt\n");
10319 		return (ENXIO);
10320 	}
10321 	error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_NET | INTR_MPSAFE,
10322 	    NULL, iwx_intr_msix, sc, &sc->sc_ih);
10323 	if (error != 0) {
10324 		device_printf(dev, "can't establish interrupt\n");
10325 		return (ENXIO);
10326 	}
10327 
10328 	/* Clear pending interrupts. */
10329 	IWX_WRITE(sc, IWX_CSR_INT_MASK, 0);
10330 	IWX_WRITE(sc, IWX_CSR_INT, ~0);
10331 	IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, ~0);
10332 
10333 	sc->sc_hw_rev = IWX_READ(sc, IWX_CSR_HW_REV);
10334 	DPRINTF(("%s: sc->sc_hw_rev=%d\n", __func__, sc->sc_hw_rev));
10335 	sc->sc_hw_rf_id = IWX_READ(sc, IWX_CSR_HW_RF_ID);
10336 	DPRINTF(("%s: sc->sc_hw_rf_id =%d\n", __func__, sc->sc_hw_rf_id));
10337 
10338 	/*
10339 	 * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have
10340 	 * changed, and now the revision step also includes bit 0-1 (no more
10341 	 * "dash" value). To keep hw_rev backwards compatible - we'll store it
10342 	 * in the old format.
10343 	 */
10344 	sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) |
10345 			(IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2);
10346 
10347 	switch (sc->sc_pid) {
10348 	case PCI_PRODUCT_INTEL_WL_22500_1:
10349 		sc->sc_fwname = IWX_CC_A_FW;
10350 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10351 		sc->sc_integrated = 0;
10352 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE;
10353 		sc->sc_low_latency_xtal = 0;
10354 		sc->sc_xtal_latency = 0;
10355 		sc->sc_tx_with_siso_diversity = 0;
10356 		sc->sc_uhb_supported = 0;
10357 		break;
10358 	case PCI_PRODUCT_INTEL_WL_22500_2:
10359 	case PCI_PRODUCT_INTEL_WL_22500_5:
10360 		/* These devices should be QuZ only. */
10361 		if (sc->sc_hw_rev != IWX_CSR_HW_REV_TYPE_QUZ) {
10362 			device_printf(dev, "unsupported AX201 adapter\n");
10363 			return (ENXIO);
10364 		}
10365 		sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
10366 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10367 		sc->sc_integrated = 1;
10368 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200;
10369 		sc->sc_low_latency_xtal = 0;
10370 		sc->sc_xtal_latency = 500;
10371 		sc->sc_tx_with_siso_diversity = 0;
10372 		sc->sc_uhb_supported = 0;
10373 		break;
10374 	case PCI_PRODUCT_INTEL_WL_22500_3:
10375 		if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
10376 			sc->sc_fwname = IWX_QU_C_HR_B_FW;
10377 		else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
10378 			sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
10379 		else
10380 			sc->sc_fwname = IWX_QU_B_HR_B_FW;
10381 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10382 		sc->sc_integrated = 1;
10383 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200;
10384 		sc->sc_low_latency_xtal = 0;
10385 		sc->sc_xtal_latency = 500;
10386 		sc->sc_tx_with_siso_diversity = 0;
10387 		sc->sc_uhb_supported = 0;
10388 		break;
10389 	case PCI_PRODUCT_INTEL_WL_22500_4:
10390 	case PCI_PRODUCT_INTEL_WL_22500_7:
10391 	case PCI_PRODUCT_INTEL_WL_22500_8:
10392 		if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
10393 			sc->sc_fwname = IWX_QU_C_HR_B_FW;
10394 		else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
10395 			sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
10396 		else
10397 			sc->sc_fwname = IWX_QU_B_HR_B_FW;
10398 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10399 		sc->sc_integrated = 1;
10400 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_1820;
10401 		sc->sc_low_latency_xtal = 0;
10402 		sc->sc_xtal_latency = 1820;
10403 		sc->sc_tx_with_siso_diversity = 0;
10404 		sc->sc_uhb_supported = 0;
10405 		break;
10406 	case PCI_PRODUCT_INTEL_WL_22500_6:
10407 		if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QU_C0)
10408 			sc->sc_fwname = IWX_QU_C_HR_B_FW;
10409 		else if (sc->sc_hw_rev == IWX_CSR_HW_REV_TYPE_QUZ)
10410 			sc->sc_fwname = IWX_QUZ_A_HR_B_FW;
10411 		else
10412 			sc->sc_fwname = IWX_QU_B_HR_B_FW;
10413 		sc->sc_device_family = IWX_DEVICE_FAMILY_22000;
10414 		sc->sc_integrated = 1;
10415 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500;
10416 		sc->sc_low_latency_xtal = 1;
10417 		sc->sc_xtal_latency = 12000;
10418 		sc->sc_tx_with_siso_diversity = 0;
10419 		sc->sc_uhb_supported = 0;
10420 		break;
10421 	case PCI_PRODUCT_INTEL_WL_22500_9:
10422 	case PCI_PRODUCT_INTEL_WL_22500_10:
10423 	case PCI_PRODUCT_INTEL_WL_22500_11:
10424 	case PCI_PRODUCT_INTEL_WL_22500_13:
10425 	/* _14 is an MA device, not yet supported */
10426 	case PCI_PRODUCT_INTEL_WL_22500_15:
10427 	case PCI_PRODUCT_INTEL_WL_22500_16:
10428 		sc->sc_fwname = IWX_SO_A_GF_A_FW;
10429 		sc->sc_pnvm_name = IWX_SO_A_GF_A_PNVM;
10430 		sc->sc_device_family = IWX_DEVICE_FAMILY_AX210;
10431 		sc->sc_integrated = 0;
10432 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE;
10433 		sc->sc_low_latency_xtal = 0;
10434 		sc->sc_xtal_latency = 0;
10435 		sc->sc_tx_with_siso_diversity = 0;
10436 		sc->sc_uhb_supported = 1;
10437 		break;
10438 	case PCI_PRODUCT_INTEL_WL_22500_12:
10439 	case PCI_PRODUCT_INTEL_WL_22500_17:
10440 		sc->sc_fwname = IWX_SO_A_GF_A_FW;
10441 		sc->sc_pnvm_name = IWX_SO_A_GF_A_PNVM;
10442 		sc->sc_device_family = IWX_DEVICE_FAMILY_AX210;
10443 		sc->sc_integrated = 1;
10444 		sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500;
10445 		sc->sc_low_latency_xtal = 1;
10446 		sc->sc_xtal_latency = 12000;
10447 		sc->sc_tx_with_siso_diversity = 0;
10448 		sc->sc_uhb_supported = 0;
10449 		sc->sc_imr_enabled = 1;
10450 		break;
10451 	default:
10452 		device_printf(dev, "unknown adapter type\n");
10453 		return (ENXIO);
10454 	}
10455 
10456 	cfg = iwx_find_device_cfg(sc);
10457 	DPRINTF(("%s: cfg=%p\n", __func__, cfg));
10458 	if (cfg) {
10459 		sc->sc_fwname = cfg->fw_name;
10460 		sc->sc_pnvm_name = cfg->pnvm_name;
10461 		sc->sc_tx_with_siso_diversity = cfg->tx_with_siso_diversity;
10462 		sc->sc_uhb_supported = cfg->uhb_supported;
10463 		if (cfg->xtal_latency) {
10464 			sc->sc_xtal_latency = cfg->xtal_latency;
10465 			sc->sc_low_latency_xtal = cfg->low_latency_xtal;
10466 		}
10467 	}
10468 
10469 	sc->mac_addr_from_csr = 0x380; /* differs on BZ hw generation */
10470 
10471 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
10472 		sc->sc_umac_prph_offset = 0x300000;
10473 		sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX_GEN3;
10474 	} else
10475 		sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX;
10476 
10477 	/* Allocate DMA memory for loading firmware. */
10478 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210)
10479 		ctxt_info_size = sizeof(struct iwx_context_info_gen3);
10480 	else
10481 		ctxt_info_size = sizeof(struct iwx_context_info);
10482 	err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ctxt_info_dma,
10483 	    ctxt_info_size, 1);
10484 	if (err) {
10485 		device_printf(dev,
10486 		    "could not allocate memory for loading firmware\n");
10487 		return (ENXIO);
10488 	}
10489 
10490 	if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
10491 		err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->prph_scratch_dma,
10492 		    sizeof(struct iwx_prph_scratch), 1);
10493 		if (err) {
10494 			device_printf(dev,
10495 			    "could not allocate prph scratch memory\n");
10496 			goto fail1;
10497 		}
10498 
10499 		/*
10500 		 * Allocate prph information. The driver doesn't use this.
10501 		 * We use the second half of this page to give the device
10502 		 * some dummy TR/CR tail pointers - which shouldn't be
10503 		 * necessary as we don't use this, but the hardware still
10504 		 * reads/writes there and we can't let it go do that with
10505 		 * a NULL pointer.
10506 		 */
10507 		KASSERT((sizeof(struct iwx_prph_info) < PAGE_SIZE / 2),
10508 		    ("iwx_prph_info has wrong size"));
10509 		err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->prph_info_dma,
10510 		    PAGE_SIZE, 1);
10511 		if (err) {
10512 			device_printf(dev,
10513 			    "could not allocate prph info memory\n");
10514 			goto fail1;
10515 		}
10516 	}
10517 
10518 	/* Allocate interrupt cause table (ICT).*/
10519 	err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma,
10520 	    IWX_ICT_SIZE, 1<<IWX_ICT_PADDR_SHIFT);
10521 	if (err) {
10522 		device_printf(dev, "could not allocate ICT table\n");
10523 		goto fail1;
10524 	}
10525 
10526 	for (txq_i = 0; txq_i < nitems(sc->txq); txq_i++) {
10527 		err = iwx_alloc_tx_ring(sc, &sc->txq[txq_i], txq_i);
10528 		if (err) {
10529 			device_printf(dev, "could not allocate TX ring %d\n",
10530 			    txq_i);
10531 			goto fail4;
10532 		}
10533 	}
10534 
10535 	err = iwx_alloc_rx_ring(sc, &sc->rxq);
10536 	if (err) {
10537 		device_printf(sc->sc_dev, "could not allocate RX ring\n");
10538 		goto fail4;
10539 	}
10540 
10541 #ifdef IWX_DEBUG
10542 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10543 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "debug",
10544 	    CTLFLAG_RWTUN, &sc->sc_debug, 0, "bitmask to control debugging");
10545 
10546 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10547 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "himark",
10548 	    CTLFLAG_RW, &iwx_himark, 0, "queues high watermark");
10549 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10550 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "lomark",
10551 	    CTLFLAG_RW, &iwx_lomark, 0, "queues low watermark");
10552 
10553 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10554 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "qfullmsk",
10555 	    CTLFLAG_RD, &sc->qfullmsk, 0, "queue fullmask");
10556 
10557 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10558 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue0",
10559 	    CTLFLAG_RD, &sc->txq[0].queued, 0, "queue 0");
10560 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10561 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue1",
10562 	    CTLFLAG_RD, &sc->txq[1].queued, 0, "queue 1");
10563 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10564 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue2",
10565 	    CTLFLAG_RD, &sc->txq[2].queued, 0, "queue 2");
10566 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10567 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue3",
10568 	    CTLFLAG_RD, &sc->txq[3].queued, 0, "queue 3");
10569 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10570 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue4",
10571 	    CTLFLAG_RD, &sc->txq[4].queued, 0, "queue 4");
10572 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10573 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue5",
10574 	    CTLFLAG_RD, &sc->txq[5].queued, 0, "queue 5");
10575 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10576 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue6",
10577 	    CTLFLAG_RD, &sc->txq[6].queued, 0, "queue 6");
10578 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
10579 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "queue7",
10580 	    CTLFLAG_RD, &sc->txq[7].queued, 0, "queue 7");
10581 #endif
10582 	ic->ic_softc = sc;
10583 	ic->ic_name = device_get_nameunit(sc->sc_dev);
10584 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
10585 	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
10586 
10587 	/* Set device capabilities. */
10588 	ic->ic_caps =
10589 	    IEEE80211_C_STA |
10590 	    IEEE80211_C_MONITOR |
10591 	    IEEE80211_C_WPA |		/* WPA/RSN */
10592 	    IEEE80211_C_WME |
10593 	    IEEE80211_C_PMGT |
10594 	    IEEE80211_C_SHSLOT |	/* short slot time supported */
10595 	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
10596 	    IEEE80211_C_BGSCAN		/* capable of bg scanning */
10597 	    ;
10598 	ic->ic_flags_ext = IEEE80211_FEXT_SCAN_OFFLOAD;
10599 	/* Enable seqno offload */
10600 	ic->ic_flags_ext |= IEEE80211_FEXT_SEQNO_OFFLOAD;
10601 	/* Don't send null data frames; let firmware do it */
10602 	ic->ic_flags_ext |= IEEE80211_FEXT_NO_NULLDATA;
10603 
10604 	ic->ic_txstream = 2;
10605 	ic->ic_rxstream = 2;
10606 	ic->ic_htcaps |= IEEE80211_HTC_HT
10607 			| IEEE80211_HTCAP_SMPS_OFF
10608 			| IEEE80211_HTCAP_SHORTGI20	/* short GI in 20MHz */
10609 			| IEEE80211_HTCAP_SHORTGI40	/* short GI in 40MHz */
10610 			| IEEE80211_HTCAP_CHWIDTH40	/* 40MHz channel width*/
10611 			| IEEE80211_HTC_AMPDU		/* tx A-MPDU */
10612 //			| IEEE80211_HTC_RX_AMSDU_AMPDU	/* TODO: hw reorder */
10613 			| IEEE80211_HTCAP_MAXAMSDU_3839;	/* max A-MSDU length */
10614 
10615 	ic->ic_cryptocaps |= IEEE80211_CRYPTO_AES_CCM;
10616 
10617 	/*
10618 	 * XXX: setupcurchan() expects vhtcaps to be non-zero
10619 	 * https://bugs.freebsd.org/274156
10620 	 */
10621 	ic->ic_vht_cap.vht_cap_info |= IEEE80211_VHTCAP_MAX_MPDU_LENGTH_3895
10622 			| IEEE80211_VHTCAP_SHORT_GI_80
10623 			| 3 << IEEE80211_VHTCAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_S
10624 			| IEEE80211_VHTCAP_RX_ANTENNA_PATTERN
10625 			| IEEE80211_VHTCAP_TX_ANTENNA_PATTERN;
10626 
10627 	ic->ic_flags_ext |= IEEE80211_FEXT_VHT;
10628 	int mcsmap = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
10629 		  IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
10630 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
10631 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
10632 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
10633 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
10634 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
10635 		  IEEE80211_VHT_MCS_NOT_SUPPORTED << 14;
10636 	ic->ic_vht_cap.supp_mcs.tx_mcs_map = htole16(mcsmap);
10637 	ic->ic_vht_cap.supp_mcs.rx_mcs_map = htole16(mcsmap);
10638 
10639 	callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0);
10640 	for (i = 0; i < nitems(sc->sc_rxba_data); i++) {
10641 		struct iwx_rxba_data *rxba = &sc->sc_rxba_data[i];
10642 		rxba->baid = IWX_RX_REORDER_DATA_INVALID_BAID;
10643 		rxba->sc = sc;
10644 		for (j = 0; j < nitems(rxba->entries); j++)
10645 			mbufq_init(&rxba->entries[j].frames, ifqmaxlen);
10646 	}
10647 
10648 	/* Initialize to something to have a chance to get S:N values. */
10649 	sc->sc_noise = IWX_DEFAULT_NF;
10650 
10651 	sc->sc_preinit_hook.ich_func = iwx_attach_hook;
10652 	sc->sc_preinit_hook.ich_arg = sc;
10653 	if (config_intrhook_establish(&sc->sc_preinit_hook) != 0) {
10654 		device_printf(dev,
10655 		    "config_intrhook_establish failed\n");
10656 		goto fail4;
10657 	}
10658 
10659 	return (0);
10660 
10661 fail4:
10662 	while (--txq_i >= 0)
10663 		iwx_free_tx_ring(sc, &sc->txq[txq_i]);
10664 	iwx_free_rx_ring(sc, &sc->rxq);
10665 	if (sc->ict_dma.vaddr != NULL)
10666 		iwx_dma_contig_free(&sc->ict_dma);
10667 
10668 fail1:
10669 	iwx_dma_contig_free(&sc->ctxt_info_dma);
10670 	iwx_dma_contig_free(&sc->prph_scratch_dma);
10671 	iwx_dma_contig_free(&sc->prph_info_dma);
10672 	return (ENXIO);
10673 }
10674 
10675 static int
iwx_detach(device_t dev)10676 iwx_detach(device_t dev)
10677 {
10678 	struct iwx_softc *sc = device_get_softc(dev);
10679 	int txq_i;
10680 
10681 	iwx_stop_device(sc);
10682 
10683 	taskqueue_drain_all(sc->sc_tq);
10684 	taskqueue_free(sc->sc_tq);
10685 
10686 	ieee80211_ifdetach(&sc->sc_ic);
10687 
10688 	callout_drain(&sc->watchdog_to);
10689 
10690 	for (txq_i = 0; txq_i < nitems(sc->txq); txq_i++)
10691 		iwx_free_tx_ring(sc, &sc->txq[txq_i]);
10692 	iwx_free_rx_ring(sc, &sc->rxq);
10693 
10694 	if (sc->sc_fwp != NULL) {
10695 		firmware_put(sc->sc_fwp, FIRMWARE_UNLOAD);
10696 		sc->sc_fwp = NULL;
10697 	}
10698 
10699 	if (sc->sc_pnvm != NULL) {
10700 		firmware_put(sc->sc_pnvm, FIRMWARE_UNLOAD);
10701 		sc->sc_pnvm = NULL;
10702 	}
10703 
10704 	if (sc->sc_irq != NULL) {
10705 		bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
10706 		bus_release_resource(dev, SYS_RES_IRQ,
10707 		    rman_get_rid(sc->sc_irq), sc->sc_irq);
10708 		pci_release_msi(dev);
10709         }
10710 	if (sc->sc_mem != NULL)
10711 		bus_release_resource(dev, SYS_RES_MEMORY,
10712 		    rman_get_rid(sc->sc_mem), sc->sc_mem);
10713 
10714 	IWX_LOCK_DESTROY(sc);
10715 
10716 	return (0);
10717 }
10718 
10719 static void
iwx_radiotap_attach(struct iwx_softc * sc)10720 iwx_radiotap_attach(struct iwx_softc *sc)
10721 {
10722 	struct ieee80211com *ic = &sc->sc_ic;
10723 
10724 	IWX_DPRINTF(sc, IWX_DEBUG_RESET | IWX_DEBUG_TRACE,
10725 	    "->%s begin\n", __func__);
10726 
10727 	ieee80211_radiotap_attach(ic,
10728 	    &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
10729 		IWX_TX_RADIOTAP_PRESENT,
10730 	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
10731 		IWX_RX_RADIOTAP_PRESENT);
10732 
10733 	IWX_DPRINTF(sc, IWX_DEBUG_RESET | IWX_DEBUG_TRACE,
10734 	    "->%s end\n", __func__);
10735 }
10736 
10737 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])10738 iwx_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
10739     enum ieee80211_opmode opmode, int flags,
10740     const uint8_t bssid[IEEE80211_ADDR_LEN],
10741     const uint8_t mac[IEEE80211_ADDR_LEN])
10742 {
10743 	struct iwx_vap *ivp;
10744 	struct ieee80211vap *vap;
10745 
10746 	if (!TAILQ_EMPTY(&ic->ic_vaps))         /* only one at a time */
10747 		return NULL;
10748 	ivp = malloc(sizeof(struct iwx_vap), M_80211_VAP, M_WAITOK | M_ZERO);
10749 	vap = &ivp->iv_vap;
10750 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
10751 	vap->iv_bmissthreshold = 10;            /* override default */
10752 	/* Override with driver methods. */
10753 	ivp->iv_newstate = vap->iv_newstate;
10754 	vap->iv_newstate = iwx_newstate;
10755 
10756 	ivp->id = IWX_DEFAULT_MACID;
10757 	ivp->color = IWX_DEFAULT_COLOR;
10758 
10759 	ivp->have_wme = TRUE;
10760 	ivp->ps_disabled = FALSE;
10761 
10762 	vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K;
10763 	vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_4;
10764 
10765 	/* h/w crypto support */
10766 	vap->iv_key_alloc = iwx_key_alloc;
10767 	vap->iv_key_delete = iwx_key_delete;
10768 	vap->iv_key_set = iwx_key_set;
10769 	vap->iv_key_update_begin = iwx_key_update_begin;
10770 	vap->iv_key_update_end = iwx_key_update_end;
10771 
10772 	ieee80211_ratectl_init(vap);
10773 	/* Complete setup. */
10774 	ieee80211_vap_attach(vap, ieee80211_media_change,
10775 	    ieee80211_media_status, mac);
10776 	ic->ic_opmode = opmode;
10777 
10778 	return vap;
10779 }
10780 
10781 static void
iwx_vap_delete(struct ieee80211vap * vap)10782 iwx_vap_delete(struct ieee80211vap *vap)
10783 {
10784 	struct iwx_vap *ivp = IWX_VAP(vap);
10785 
10786 	ieee80211_ratectl_deinit(vap);
10787 	ieee80211_vap_detach(vap);
10788 	free(ivp, M_80211_VAP);
10789 }
10790 
10791 static void
iwx_parent(struct ieee80211com * ic)10792 iwx_parent(struct ieee80211com *ic)
10793 {
10794 	struct iwx_softc *sc = ic->ic_softc;
10795 	IWX_LOCK(sc);
10796 
10797 	if (sc->sc_flags & IWX_FLAG_HW_INITED) {
10798 		iwx_stop(sc);
10799 		sc->sc_flags &= ~IWX_FLAG_HW_INITED;
10800 	} else {
10801 		iwx_init(sc);
10802 		ieee80211_start_all(ic);
10803 	}
10804 	IWX_UNLOCK(sc);
10805 }
10806 
10807 static int
iwx_suspend(device_t dev)10808 iwx_suspend(device_t dev)
10809 {
10810 	struct iwx_softc *sc = device_get_softc(dev);
10811 	struct ieee80211com *ic = &sc->sc_ic;
10812 
10813 	/*
10814 	 * Suspend everything first, then shutdown hardware if it's
10815 	 * still up.
10816 	 */
10817 	ieee80211_suspend_all(ic);
10818 
10819 	if (sc->sc_flags & IWX_FLAG_HW_INITED) {
10820 		iwx_stop(sc);
10821 		sc->sc_flags &= ~IWX_FLAG_HW_INITED;
10822 	}
10823 	return (0);
10824 }
10825 
10826 static int
iwx_resume(device_t dev)10827 iwx_resume(device_t dev)
10828 {
10829 	struct iwx_softc *sc = device_get_softc(dev);
10830 	struct ieee80211com *ic = &sc->sc_ic;
10831 
10832 	/*
10833 	 * We disable the RETRY_TIMEOUT register (0x41) to keep
10834 	 * PCI Tx retries from interfering with C3 CPU state.
10835 	 */
10836 	pci_write_config(dev, PCI_CFG_RETRY_TIMEOUT, 0x00, 1);
10837 
10838 	IWX_LOCK(sc);
10839 
10840 	/* Stop the hardware here if it's still thought of as "up" */
10841 	if (sc->sc_flags & IWX_FLAG_HW_INITED) {
10842 		iwx_stop(sc);
10843 		sc->sc_flags &= ~IWX_FLAG_HW_INITED;
10844 	}
10845 
10846 	IWX_UNLOCK(sc);
10847 
10848 	/* Start the VAPs, which will bring the hardware back up again */
10849 	ieee80211_resume_all(ic);
10850 	return (0);
10851 }
10852 
10853 static void
iwx_scan_start(struct ieee80211com * ic)10854 iwx_scan_start(struct ieee80211com *ic)
10855 {
10856 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
10857 	struct iwx_softc *sc = ic->ic_softc;
10858 	int err;
10859 
10860 	IWX_LOCK(sc);
10861 	if ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) == 0)
10862 		err = iwx_scan(sc);
10863 	else
10864 		err = iwx_bgscan(ic);
10865 	IWX_UNLOCK(sc);
10866 	if (err)
10867 		ieee80211_cancel_scan(vap);
10868 
10869 	return;
10870 }
10871 
10872 static void
iwx_update_mcast(struct ieee80211com * ic)10873 iwx_update_mcast(struct ieee80211com *ic)
10874 {
10875 }
10876 
10877 static void
iwx_scan_curchan(struct ieee80211_scan_state * ss,unsigned long maxdwell)10878 iwx_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
10879 {
10880 }
10881 
10882 static void
iwx_scan_mindwell(struct ieee80211_scan_state * ss)10883 iwx_scan_mindwell(struct ieee80211_scan_state *ss)
10884 {
10885 }
10886 
10887 static void
iwx_scan_end(struct ieee80211com * ic)10888 iwx_scan_end(struct ieee80211com *ic)
10889 {
10890 	iwx_endscan(ic->ic_softc);
10891 }
10892 
10893 static void
iwx_set_channel(struct ieee80211com * ic)10894 iwx_set_channel(struct ieee80211com *ic)
10895 {
10896 #if 0
10897         struct iwx_softc *sc = ic->ic_softc;
10898         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
10899 
10900         IWX_DPRINTF(sc, IWX_DEBUG_NI , "%s:%d NOT IMPLEMENTED\n", __func__, __LINE__);
10901         iwx_phy_ctxt_task((void *)sc);
10902 #endif
10903 }
10904 
10905 static void
iwx_endscan_cb(void * arg,int pending)10906 iwx_endscan_cb(void *arg, int pending)
10907 {
10908 	struct iwx_softc *sc = arg;
10909 	struct ieee80211com *ic = &sc->sc_ic;
10910 
10911 	DPRINTF(("scan ended\n"));
10912 	ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps));
10913 }
10914 
10915 static int
iwx_wme_update(struct ieee80211com * ic)10916 iwx_wme_update(struct ieee80211com *ic)
10917 {
10918 	return 0;
10919 }
10920 
10921 static int
iwx_raw_xmit(struct ieee80211_node * ni,struct mbuf * m,const struct ieee80211_bpf_params * params)10922 iwx_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
10923     const struct ieee80211_bpf_params *params)
10924 {
10925 	struct ieee80211com *ic = ni->ni_ic;
10926 	struct iwx_softc *sc = ic->ic_softc;
10927 	int err;
10928 
10929 	IWX_LOCK(sc);
10930 	if (sc->sc_flags & IWX_FLAG_STA_ACTIVE) {
10931 		err = iwx_tx(sc, m, ni);
10932 		IWX_UNLOCK(sc);
10933 		return err;
10934 	} else {
10935 		IWX_UNLOCK(sc);
10936 		return EIO;
10937 	}
10938 }
10939 
10940 static int
iwx_transmit(struct ieee80211com * ic,struct mbuf * m)10941 iwx_transmit(struct ieee80211com *ic, struct mbuf *m)
10942 {
10943 	struct iwx_softc *sc = ic->ic_softc;
10944 	int error;
10945 
10946 	// TODO: mbufq_enqueue in iwm
10947 	// TODO dequeue in iwm_start, counters, locking
10948 	IWX_LOCK(sc);
10949 	error = mbufq_enqueue(&sc->sc_snd, m);
10950 	if (error) {
10951 		IWX_UNLOCK(sc);
10952 		return (error);
10953 	}
10954 
10955 	iwx_start(sc);
10956 	IWX_UNLOCK(sc);
10957 	return (0);
10958 }
10959 
10960 static int
iwx_ampdu_rx_start(struct ieee80211_node * ni,struct ieee80211_rx_ampdu * rap,int baparamset,int batimeout,int baseqctl)10961 iwx_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
10962     int baparamset, int batimeout, int baseqctl)
10963 {
10964 	struct ieee80211com *ic = ni->ni_ic;
10965 	struct iwx_softc *sc = ic->ic_softc;
10966 	int tid;
10967 
10968 	tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID);
10969 	sc->ni_rx_ba[tid].ba_winstart =
10970 	    _IEEE80211_MASKSHIFT(le16toh(baseqctl), IEEE80211_BASEQ_START);
10971 	sc->ni_rx_ba[tid].ba_winsize =
10972 	    _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_BUFSIZ);
10973 	sc->ni_rx_ba[tid].ba_timeout_val = batimeout;
10974 
10975 	if (sc->sc_rx_ba_sessions >= IWX_MAX_RX_BA_SESSIONS ||
10976 	    tid >= IWX_MAX_TID_COUNT)
10977 		return ENOSPC;
10978 
10979 	if (sc->ba_rx.start_tidmask & (1 << tid)) {
10980 		DPRINTF(("%s: tid %d already added\n", __func__, tid));
10981 		return EBUSY;
10982 	}
10983 	DPRINTF(("%s: sc->ba_rx.start_tidmask=%x\n", __func__, sc->ba_rx.start_tidmask));
10984 
10985 	sc->ba_rx.start_tidmask |= (1 << tid);
10986 	DPRINTF(("%s: tid=%i\n", __func__, tid));
10987 	DPRINTF(("%s: ba_winstart=%i\n", __func__, sc->ni_rx_ba[tid].ba_winstart));
10988 	DPRINTF(("%s: ba_winsize=%i\n", __func__, sc->ni_rx_ba[tid].ba_winsize));
10989 	DPRINTF(("%s: ba_timeout_val=%i\n", __func__, sc->ni_rx_ba[tid].ba_timeout_val));
10990 
10991 	taskqueue_enqueue(sc->sc_tq, &sc->ba_rx_task);
10992 
10993 	// TODO:misha move to ba_task (serialize)
10994 	sc->sc_ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl);
10995 
10996 	return (0);
10997 }
10998 
10999 static void
iwx_ampdu_rx_stop(struct ieee80211_node * ni,struct ieee80211_rx_ampdu * rap)11000 iwx_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
11001 {
11002 	return;
11003 }
11004 
11005 /**
11006  * @brief Called by net80211 to request an A-MPDU session be established.
11007  *
11008  * This is called by net80211 to see if an A-MPDU session can be established.
11009  * However, the iwx(4) firmware will take care of establishing the BA
11010  * session for us.  net80211 doesn't have to send any action frames here;
11011  * it just needs to plumb up the ampdu session once the BA has been sent.
11012  *
11013  * If we return 0 here then the firmware will set up the state but net80211
11014  * will not; so it's on us to actually complete it via a call to
11015  * ieee80211_ampdu_tx_request_active_ext() .
11016  *
11017  * @param ni	ieee80211_node to establish A-MPDU session for
11018  * @param tap	pointer to the per-TID state struct
11019  * @param dialogtoken	dialogtoken field from the BA request
11020  * @param baparamset	baparamset field from the BA request
11021  * @param batimeout	batimeout field from the BA request
11022  *
11023  * @returns 0 so net80211 doesn't send the BA action frame to establish A-MPDU.
11024  */
11025 static int
iwx_addba_request(struct ieee80211_node * ni,struct ieee80211_tx_ampdu * tap,int dialogtoken,int baparamset,int batimeout)11026 iwx_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
11027     int dialogtoken, int baparamset, int batimeout)
11028 {
11029 	struct iwx_softc *sc = ni->ni_ic->ic_softc;
11030 	int tid;
11031 
11032 	tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID);
11033 	IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT,
11034 	    "%s: queuing AMPDU start on tid %i\n", __func__, tid);
11035 
11036 	/* There's no nice way right now to tell net80211 that we're in the
11037 	 * middle of an asynchronous ADDBA setup session.  So, bump the timeout
11038 	 * to hz ticks, hopefully we'll get a response by then.
11039 	 */
11040 	tap->txa_nextrequest = ticks + hz;
11041 
11042 	IWX_LOCK(sc);
11043 	sc->ba_tx.start_tidmask |= (1 << tid);
11044 	IWX_UNLOCK(sc);
11045 
11046 	taskqueue_enqueue(sc->sc_tq, &sc->ba_tx_task);
11047 
11048 	return (0);
11049 }
11050 
11051 
11052 static int
iwx_addba_response(struct ieee80211_node * ni,struct ieee80211_tx_ampdu * tap,int code,int baparamset,int batimeout)11053 iwx_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
11054     int code, int baparamset, int batimeout)
11055 {
11056 	return 0;
11057 }
11058 
11059 static void
iwx_key_update_begin(struct ieee80211vap * vap)11060 iwx_key_update_begin(struct ieee80211vap *vap)
11061 {
11062 	return;
11063 }
11064 
11065 static void
iwx_key_update_end(struct ieee80211vap * vap)11066 iwx_key_update_end(struct ieee80211vap *vap)
11067 {
11068 	return;
11069 }
11070 
11071 static int
iwx_key_alloc(struct ieee80211vap * vap,struct ieee80211_key * k,ieee80211_keyix * keyix,ieee80211_keyix * rxkeyix)11072 iwx_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
11073 	ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
11074 {
11075 
11076 	if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) {
11077 		return (1);
11078 	}
11079 
11080 	if (ieee80211_is_key_unicast(vap, k)) {
11081 		*keyix = 0;	/* NB: use key index 0 for ucast key */
11082 	} else if (ieee80211_is_key_global(vap, k)) {
11083 		*keyix = ieee80211_crypto_get_key_wepidx(vap, k);
11084 	} else {
11085 		net80211_vap_printf(vap, "%s: invalid crypto key type\n",
11086 		    __func__);
11087 		return (0);
11088 	}
11089 	*rxkeyix = IEEE80211_KEYIX_NONE;	/* XXX maybe *keyix? */
11090 	return (1);
11091 }
11092 
11093 static int
iwx_key_set(struct ieee80211vap * vap,const struct ieee80211_key * k)11094 iwx_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
11095 {
11096 	struct ieee80211com *ic = vap->iv_ic;
11097 	struct iwx_softc *sc = ic->ic_softc;
11098 	struct iwx_add_sta_key_cmd cmd;
11099 	uint32_t status;
11100 	int err;
11101 	int id;
11102 
11103 	if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_AES_CCM) {
11104 		return 1;
11105 	}
11106 
11107 	/*
11108 	 * Keys are stored in 'ni' so 'k' is valid if 'ni' is valid.
11109 	 * Currently we only implement station mode where 'ni' is always
11110 	 * ic->ic_bss so there is no need to validate arguments beyond this:
11111 	 */
11112 
11113 	memset(&cmd, 0, sizeof(cmd));
11114 
11115 	if (ieee80211_is_key_global(vap, k)) {
11116 		id = ieee80211_crypto_get_key_wepidx(vap, k);
11117 		IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: adding group key\n",
11118 		    __func__);
11119 	} else if (ieee80211_is_key_unicast(vap, k)) {
11120 		IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: adding key\n",
11121 		    __func__);
11122 		id = 0; /* net80211 currently only supports unicast key 0 */
11123 	} else {
11124 		net80211_vap_printf(vap, "%s: unknown key type\n", __func__);
11125 		return (ENXIO);
11126 	}
11127 
11128 	IWX_LOCK(sc);
11129 
11130 	cmd.common.key_flags = htole16(IWX_STA_KEY_FLG_CCM |
11131 	    IWX_STA_KEY_FLG_WEP_KEY_MAP |
11132 	    ((id << IWX_STA_KEY_FLG_KEYID_POS) &
11133 	    IWX_STA_KEY_FLG_KEYID_MSK));
11134 	if (ieee80211_is_key_global(vap, k)) {
11135 		cmd.common.key_offset = 1;
11136 		cmd.common.key_flags |= htole16(IWX_STA_KEY_MULTICAST);
11137 	} else if (ieee80211_is_key_unicast(vap, k)) {
11138 		cmd.common.key_offset = 0;
11139 	} else {
11140 		net80211_vap_printf(vap, "%s: unknown key type\n", __func__);
11141 		IWX_UNLOCK(sc);
11142 		return (ENXIO);
11143 	}
11144 	memcpy(cmd.common.key, ieee80211_crypto_get_key_data(k),
11145 	    MIN(sizeof(cmd.common.key), ieee80211_crypto_get_key_len(k)));
11146 	IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: key: id=%d, len=%i, key=%*D\n",
11147 	    __func__, id,
11148 	    ieee80211_crypto_get_key_len(k),
11149 	    ieee80211_crypto_get_key_len(k),
11150 	    (const unsigned char *) ieee80211_crypto_get_key_data(k), "");
11151 	cmd.common.sta_id = IWX_STATION_ID;
11152 
11153 	cmd.transmit_seq_cnt = htole64(k->wk_keytsc);
11154 	IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: k->wk_keytsc=%" PRIu64 "\n",
11155 	    __func__, k->wk_keytsc);
11156 
11157 	status = IWX_ADD_STA_SUCCESS;
11158 	err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA_KEY, sizeof(cmd), &cmd,
11159 	    &status);
11160 	if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS)
11161 		err = EIO;
11162 	if (err) {
11163 		net80211_vap_printf(vap,
11164 		    "%s: can't set wpa2 keys (error %d)\n", __func__, err);
11165 		IWX_UNLOCK(sc);
11166 		return err;
11167 	} else
11168 		IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT,
11169 		    "%s: key added successfully\n", __func__);
11170 	IWX_UNLOCK(sc);
11171 	return (1);
11172 }
11173 
11174 static int
iwx_key_delete(struct ieee80211vap * vap,const struct ieee80211_key * k)11175 iwx_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
11176 {
11177 	/*
11178 	 * Note: since there's no key allocations to track - it's either
11179 	 * the 4 static WEP keys or the single unicast key - there's nothing
11180 	 * else to do here.
11181 	 *
11182 	 * This would need some further work to support IBSS/mesh/AP modes.
11183 	 */
11184 	return (1);
11185 }
11186 
11187 static device_method_t iwx_pci_methods[] = {
11188 	/* Device interface */
11189 	DEVMETHOD(device_probe,		iwx_probe),
11190 	DEVMETHOD(device_attach,	iwx_attach),
11191 	DEVMETHOD(device_detach,	iwx_detach),
11192 	DEVMETHOD(device_suspend,	iwx_suspend),
11193 	DEVMETHOD(device_resume,	iwx_resume),
11194 
11195 	DEVMETHOD_END
11196 };
11197 
11198 static driver_t iwx_pci_driver = {
11199 	"iwx",
11200 	iwx_pci_methods,
11201 	sizeof (struct iwx_softc)
11202 };
11203 
11204 DRIVER_MODULE(iwx, pci, iwx_pci_driver, NULL, NULL);
11205 MODULE_PNP_INFO("U16:device;D:#;T:vendor=0x8086", pci, iwx_pci_driver,
11206     iwx_devices, nitems(iwx_devices));
11207 MODULE_DEPEND(iwx, firmware, 1, 1, 1);
11208 MODULE_DEPEND(iwx, pci, 1, 1, 1);
11209 MODULE_DEPEND(iwx, wlan, 1, 1, 1);
11210