Wed Apr 15 05:40:48 2015 UTC ()
Register iwm(4) with pmf(9).

Patch from Pierre Pronchery.


(nonaka)
diff -r1.29 -r1.30 src/sys/dev/pci/if_iwm.c

cvs diff -r1.29 -r1.30 src/sys/dev/pci/if_iwm.c (switch to unified diff)

--- src/sys/dev/pci/if_iwm.c 2015/03/26 14:42:56 1.29
+++ src/sys/dev/pci/if_iwm.c 2015/04/15 05:40:48 1.30
@@ -1,1107 +1,1107 @@ @@ -1,1107 +1,1107 @@
1/* $NetBSD: if_iwm.c,v 1.29 2015/03/26 14:42:56 nonaka Exp $ */ 1/* $NetBSD: if_iwm.c,v 1.30 2015/04/15 05:40:48 nonaka Exp $ */
2/* OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp */ 2/* OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp */
3 3
4/* 4/*
5 * Copyright (c) 2014 genua mbh <info@genua.de> 5 * Copyright (c) 2014 genua mbh <info@genua.de>
6 * Copyright (c) 2014 Fixup Software Ltd. 6 * Copyright (c) 2014 Fixup Software Ltd.
7 * 7 *
8 * Permission to use, copy, modify, and distribute this software for any 8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above 9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies. 10 * copyright notice and this permission notice appear in all copies.
11 * 11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */ 19 */
20 20
21/*- 21/*-
22 * Based on BSD-licensed source modules in the Linux iwlwifi driver, 22 * Based on BSD-licensed source modules in the Linux iwlwifi driver,
23 * which were used as the reference documentation for this implementation. 23 * which were used as the reference documentation for this implementation.
24 * 24 *
25 * Driver version we are currently based off of is 25 * Driver version we are currently based off of is
26 * Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd) 26 * Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
27 * 27 *
28 *********************************************************************** 28 ***********************************************************************
29 * 29 *
30 * This file is provided under a dual BSD/GPLv2 license. When using or 30 * This file is provided under a dual BSD/GPLv2 license. When using or
31 * redistributing this file, you may do so under either license. 31 * redistributing this file, you may do so under either license.
32 * 32 *
33 * GPL LICENSE SUMMARY 33 * GPL LICENSE SUMMARY
34 * 34 *
35 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 35 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
36 * 36 *
37 * This program is free software; you can redistribute it and/or modify 37 * This program is free software; you can redistribute it and/or modify
38 * it under the terms of version 2 of the GNU General Public License as 38 * it under the terms of version 2 of the GNU General Public License as
39 * published by the Free Software Foundation. 39 * published by the Free Software Foundation.
40 * 40 *
41 * This program is distributed in the hope that it will be useful, but 41 * This program is distributed in the hope that it will be useful, but
42 * WITHOUT ANY WARRANTY; without even the implied warranty of 42 * WITHOUT ANY WARRANTY; without even the implied warranty of
43 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 43 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44 * General Public License for more details. 44 * General Public License for more details.
45 * 45 *
46 * You should have received a copy of the GNU General Public License 46 * You should have received a copy of the GNU General Public License
47 * along with this program; if not, write to the Free Software 47 * along with this program; if not, write to the Free Software
48 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, 48 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
49 * USA 49 * USA
50 * 50 *
51 * The full GNU General Public License is included in this distribution 51 * The full GNU General Public License is included in this distribution
52 * in the file called COPYING. 52 * in the file called COPYING.
53 * 53 *
54 * Contact Information: 54 * Contact Information:
55 * Intel Linux Wireless <ilw@linux.intel.com> 55 * Intel Linux Wireless <ilw@linux.intel.com>
56 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 56 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
57 * 57 *
58 * 58 *
59 * BSD LICENSE 59 * BSD LICENSE
60 * 60 *
61 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 61 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
62 * All rights reserved. 62 * All rights reserved.
63 * 63 *
64 * Redistribution and use in source and binary forms, with or without 64 * Redistribution and use in source and binary forms, with or without
65 * modification, are permitted provided that the following conditions 65 * modification, are permitted provided that the following conditions
66 * are met: 66 * are met:
67 * 67 *
68 * * Redistributions of source code must retain the above copyright 68 * * Redistributions of source code must retain the above copyright
69 * notice, this list of conditions and the following disclaimer. 69 * notice, this list of conditions and the following disclaimer.
70 * * Redistributions in binary form must reproduce the above copyright 70 * * Redistributions in binary form must reproduce the above copyright
71 * notice, this list of conditions and the following disclaimer in 71 * notice, this list of conditions and the following disclaimer in
72 * the documentation and/or other materials provided with the 72 * the documentation and/or other materials provided with the
73 * distribution. 73 * distribution.
74 * * Neither the name Intel Corporation nor the names of its 74 * * Neither the name Intel Corporation nor the names of its
75 * contributors may be used to endorse or promote products derived 75 * contributors may be used to endorse or promote products derived
76 * from this software without specific prior written permission. 76 * from this software without specific prior written permission.
77 * 77 *
78 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 78 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
79 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 79 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
80 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 80 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
81 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 81 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
82 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 82 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
83 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 83 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
84 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 84 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
85 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 85 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
86 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 86 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 87 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
88 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 88 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89 */ 89 */
90 90
91/*- 91/*-
92 * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr> 92 * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
93 * 93 *
94 * Permission to use, copy, modify, and distribute this software for any 94 * Permission to use, copy, modify, and distribute this software for any
95 * purpose with or without fee is hereby granted, provided that the above 95 * purpose with or without fee is hereby granted, provided that the above
96 * copyright notice and this permission notice appear in all copies. 96 * copyright notice and this permission notice appear in all copies.
97 * 97 *
98 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 98 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
99 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 99 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
100 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 100 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
101 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 101 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
102 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 102 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
103 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 103 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
104 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 104 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
105 */ 105 */
106 106
107#include <sys/cdefs.h> 107#include <sys/cdefs.h>
108__KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.29 2015/03/26 14:42:56 nonaka Exp $"); 108__KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.30 2015/04/15 05:40:48 nonaka Exp $");
109 109
110#include <sys/param.h> 110#include <sys/param.h>
111#include <sys/conf.h> 111#include <sys/conf.h>
112#include <sys/kernel.h> 112#include <sys/kernel.h>
113#include <sys/kmem.h> 113#include <sys/kmem.h>
114#include <sys/mbuf.h> 114#include <sys/mbuf.h>
115#include <sys/mutex.h> 115#include <sys/mutex.h>
116#include <sys/proc.h> 116#include <sys/proc.h>
117#include <sys/socket.h> 117#include <sys/socket.h>
118#include <sys/sockio.h> 118#include <sys/sockio.h>
119#include <sys/systm.h> 119#include <sys/systm.h>
120 120
121#include <sys/cpu.h> 121#include <sys/cpu.h>
122#include <sys/bus.h> 122#include <sys/bus.h>
123#include <sys/workqueue.h> 123#include <sys/workqueue.h>
124#include <machine/endian.h> 124#include <machine/endian.h>
125#include <machine/intr.h> 125#include <machine/intr.h>
126 126
127#include <dev/pci/pcireg.h> 127#include <dev/pci/pcireg.h>
128#include <dev/pci/pcivar.h> 128#include <dev/pci/pcivar.h>
129#include <dev/pci/pcidevs.h> 129#include <dev/pci/pcidevs.h>
130#include <dev/firmload.h> 130#include <dev/firmload.h>
131 131
132#include <net/bpf.h> 132#include <net/bpf.h>
133#include <net/if.h> 133#include <net/if.h>
134#include <net/if_arp.h> 134#include <net/if_arp.h>
135#include <net/if_dl.h> 135#include <net/if_dl.h>
136#include <net/if_media.h> 136#include <net/if_media.h>
137#include <net/if_types.h> 137#include <net/if_types.h>
138#include <net/if_ether.h> 138#include <net/if_ether.h>
139 139
140#include <netinet/in.h> 140#include <netinet/in.h>
141#include <netinet/in_systm.h> 141#include <netinet/in_systm.h>
142#include <netinet/ip.h> 142#include <netinet/ip.h>
143 143
144#include <net80211/ieee80211_var.h> 144#include <net80211/ieee80211_var.h>
145#include <net80211/ieee80211_amrr.h> 145#include <net80211/ieee80211_amrr.h>
146#include <net80211/ieee80211_radiotap.h> 146#include <net80211/ieee80211_radiotap.h>
147 147
148#define DEVNAME(_s) device_xname((_s)->sc_dev) 148#define DEVNAME(_s) device_xname((_s)->sc_dev)
149#define IC2IFP(_ic_) ((_ic_)->ic_ifp) 149#define IC2IFP(_ic_) ((_ic_)->ic_ifp)
150 150
151#define le16_to_cpup(_a_) (le16toh(*(const uint16_t *)(_a_))) 151#define le16_to_cpup(_a_) (le16toh(*(const uint16_t *)(_a_)))
152#define le32_to_cpup(_a_) (le32toh(*(const uint32_t *)(_a_))) 152#define le32_to_cpup(_a_) (le32toh(*(const uint32_t *)(_a_)))
153 153
154#ifdef IWM_DEBUG 154#ifdef IWM_DEBUG
155#define DPRINTF(x) do { if (iwm_debug > 0) printf x; } while (0) 155#define DPRINTF(x) do { if (iwm_debug > 0) printf x; } while (0)
156#define DPRINTFN(n, x) do { if (iwm_debug >= (n)) printf x; } while (0) 156#define DPRINTFN(n, x) do { if (iwm_debug >= (n)) printf x; } while (0)
157int iwm_debug = 1; 157int iwm_debug = 1;
158#else 158#else
159#define DPRINTF(x) do { ; } while (0) 159#define DPRINTF(x) do { ; } while (0)
160#define DPRINTFN(n, x) do { ; } while (0) 160#define DPRINTFN(n, x) do { ; } while (0)
161#endif 161#endif
162 162
163#include <dev/pci/if_iwmreg.h> 163#include <dev/pci/if_iwmreg.h>
164#include <dev/pci/if_iwmvar.h> 164#include <dev/pci/if_iwmvar.h>
165 165
166static const uint8_t iwm_nvm_channels[] = { 166static const uint8_t iwm_nvm_channels[] = {
167 /* 2.4 GHz */ 167 /* 2.4 GHz */
168 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 168 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
169 /* 5 GHz */ 169 /* 5 GHz */
170 36, 40, 44 , 48, 52, 56, 60, 64, 170 36, 40, 44 , 48, 52, 56, 60, 64,
171 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 171 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
172 149, 153, 157, 161, 165 172 149, 153, 157, 161, 165
173}; 173};
174#define IWM_NUM_2GHZ_CHANNELS 14 174#define IWM_NUM_2GHZ_CHANNELS 14
175 175
176static const struct iwm_rate { 176static const struct iwm_rate {
177 uint8_t rate; 177 uint8_t rate;
178 uint8_t plcp; 178 uint8_t plcp;
179} iwm_rates[] = { 179} iwm_rates[] = {
180 { 2, IWM_RATE_1M_PLCP }, 180 { 2, IWM_RATE_1M_PLCP },
181 { 4, IWM_RATE_2M_PLCP }, 181 { 4, IWM_RATE_2M_PLCP },
182 { 11, IWM_RATE_5M_PLCP }, 182 { 11, IWM_RATE_5M_PLCP },
183 { 22, IWM_RATE_11M_PLCP }, 183 { 22, IWM_RATE_11M_PLCP },
184 { 12, IWM_RATE_6M_PLCP }, 184 { 12, IWM_RATE_6M_PLCP },
185 { 18, IWM_RATE_9M_PLCP }, 185 { 18, IWM_RATE_9M_PLCP },
186 { 24, IWM_RATE_12M_PLCP }, 186 { 24, IWM_RATE_12M_PLCP },
187 { 36, IWM_RATE_18M_PLCP }, 187 { 36, IWM_RATE_18M_PLCP },
188 { 48, IWM_RATE_24M_PLCP }, 188 { 48, IWM_RATE_24M_PLCP },
189 { 72, IWM_RATE_36M_PLCP }, 189 { 72, IWM_RATE_36M_PLCP },
190 { 96, IWM_RATE_48M_PLCP }, 190 { 96, IWM_RATE_48M_PLCP },
191 { 108, IWM_RATE_54M_PLCP }, 191 { 108, IWM_RATE_54M_PLCP },
192}; 192};
193#define IWM_RIDX_CCK 0 193#define IWM_RIDX_CCK 0
194#define IWM_RIDX_OFDM 4 194#define IWM_RIDX_OFDM 4
195#define IWM_RIDX_MAX (__arraycount(iwm_rates)-1) 195#define IWM_RIDX_MAX (__arraycount(iwm_rates)-1)
196#define IWM_RIDX_IS_CCK(_i_) ((_i_) < IWM_RIDX_OFDM) 196#define IWM_RIDX_IS_CCK(_i_) ((_i_) < IWM_RIDX_OFDM)
197#define IWM_RIDX_IS_OFDM(_i_) ((_i_) >= IWM_RIDX_OFDM) 197#define IWM_RIDX_IS_OFDM(_i_) ((_i_) >= IWM_RIDX_OFDM)
198 198
199struct iwm_newstate_state { 199struct iwm_newstate_state {
200 struct work ns_wk; 200 struct work ns_wk;
201 enum ieee80211_state ns_nstate; 201 enum ieee80211_state ns_nstate;
202 int ns_arg; 202 int ns_arg;
203 int ns_generation; 203 int ns_generation;
204}; 204};
205 205
206static int iwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t); 206static int iwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t);
207static int iwm_firmware_store_section(struct iwm_softc *, 207static int iwm_firmware_store_section(struct iwm_softc *,
208 enum iwm_ucode_type, uint8_t *, size_t); 208 enum iwm_ucode_type, uint8_t *, size_t);
209static int iwm_set_default_calib(struct iwm_softc *, const void *); 209static int iwm_set_default_calib(struct iwm_softc *, const void *);
210static int iwm_read_firmware(struct iwm_softc *); 210static int iwm_read_firmware(struct iwm_softc *);
211static uint32_t iwm_read_prph(struct iwm_softc *, uint32_t); 211static uint32_t iwm_read_prph(struct iwm_softc *, uint32_t);
212static void iwm_write_prph(struct iwm_softc *, uint32_t, uint32_t); 212static void iwm_write_prph(struct iwm_softc *, uint32_t, uint32_t);
213#ifdef IWM_DEBUG 213#ifdef IWM_DEBUG
214static int iwm_read_mem(struct iwm_softc *, uint32_t, void *, int); 214static int iwm_read_mem(struct iwm_softc *, uint32_t, void *, int);
215#endif 215#endif
216static int iwm_write_mem(struct iwm_softc *, uint32_t, const void *, int); 216static int iwm_write_mem(struct iwm_softc *, uint32_t, const void *, int);
217static int iwm_write_mem32(struct iwm_softc *, uint32_t, uint32_t); 217static int iwm_write_mem32(struct iwm_softc *, uint32_t, uint32_t);
218static int iwm_poll_bit(struct iwm_softc *, int, uint32_t, uint32_t, int); 218static int iwm_poll_bit(struct iwm_softc *, int, uint32_t, uint32_t, int);
219static int iwm_nic_lock(struct iwm_softc *); 219static int iwm_nic_lock(struct iwm_softc *);
220static void iwm_nic_unlock(struct iwm_softc *); 220static void iwm_nic_unlock(struct iwm_softc *);
221static void iwm_set_bits_mask_prph(struct iwm_softc *, uint32_t, uint32_t, 221static void iwm_set_bits_mask_prph(struct iwm_softc *, uint32_t, uint32_t,
222 uint32_t); 222 uint32_t);
223static void iwm_set_bits_prph(struct iwm_softc *, uint32_t, uint32_t); 223static void iwm_set_bits_prph(struct iwm_softc *, uint32_t, uint32_t);
224static void iwm_clear_bits_prph(struct iwm_softc *, uint32_t, uint32_t); 224static void iwm_clear_bits_prph(struct iwm_softc *, uint32_t, uint32_t);
225static int iwm_dma_contig_alloc(bus_dma_tag_t, struct iwm_dma_info *, 225static int iwm_dma_contig_alloc(bus_dma_tag_t, struct iwm_dma_info *,
226 bus_size_t, bus_size_t); 226 bus_size_t, bus_size_t);
227static void iwm_dma_contig_free(struct iwm_dma_info *); 227static void iwm_dma_contig_free(struct iwm_dma_info *);
228static int iwm_alloc_fwmem(struct iwm_softc *); 228static int iwm_alloc_fwmem(struct iwm_softc *);
229static void iwm_free_fwmem(struct iwm_softc *); 229static void iwm_free_fwmem(struct iwm_softc *);
230static int iwm_alloc_sched(struct iwm_softc *); 230static int iwm_alloc_sched(struct iwm_softc *);
231static void iwm_free_sched(struct iwm_softc *); 231static void iwm_free_sched(struct iwm_softc *);
232static int iwm_alloc_kw(struct iwm_softc *); 232static int iwm_alloc_kw(struct iwm_softc *);
233static void iwm_free_kw(struct iwm_softc *); 233static void iwm_free_kw(struct iwm_softc *);
234static int iwm_alloc_ict(struct iwm_softc *); 234static int iwm_alloc_ict(struct iwm_softc *);
235static void iwm_free_ict(struct iwm_softc *); 235static void iwm_free_ict(struct iwm_softc *);
236static int iwm_alloc_rx_ring(struct iwm_softc *, struct iwm_rx_ring *); 236static int iwm_alloc_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
237static void iwm_reset_rx_ring(struct iwm_softc *, struct iwm_rx_ring *); 237static void iwm_reset_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
238static void iwm_free_rx_ring(struct iwm_softc *, struct iwm_rx_ring *); 238static void iwm_free_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
239static int iwm_alloc_tx_ring(struct iwm_softc *, struct iwm_tx_ring *, 239static int iwm_alloc_tx_ring(struct iwm_softc *, struct iwm_tx_ring *,
240 int); 240 int);
241static void iwm_reset_tx_ring(struct iwm_softc *, struct iwm_tx_ring *); 241static void iwm_reset_tx_ring(struct iwm_softc *, struct iwm_tx_ring *);
242static void iwm_free_tx_ring(struct iwm_softc *, struct iwm_tx_ring *); 242static void iwm_free_tx_ring(struct iwm_softc *, struct iwm_tx_ring *);
243static void iwm_enable_rfkill_int(struct iwm_softc *); 243static void iwm_enable_rfkill_int(struct iwm_softc *);
244static int iwm_check_rfkill(struct iwm_softc *); 244static int iwm_check_rfkill(struct iwm_softc *);
245static void iwm_enable_interrupts(struct iwm_softc *); 245static void iwm_enable_interrupts(struct iwm_softc *);
246static void iwm_restore_interrupts(struct iwm_softc *); 246static void iwm_restore_interrupts(struct iwm_softc *);
247static void iwm_disable_interrupts(struct iwm_softc *); 247static void iwm_disable_interrupts(struct iwm_softc *);
248static void iwm_ict_reset(struct iwm_softc *); 248static void iwm_ict_reset(struct iwm_softc *);
249static int iwm_set_hw_ready(struct iwm_softc *); 249static int iwm_set_hw_ready(struct iwm_softc *);
250static int iwm_prepare_card_hw(struct iwm_softc *); 250static int iwm_prepare_card_hw(struct iwm_softc *);
251static void iwm_apm_config(struct iwm_softc *); 251static void iwm_apm_config(struct iwm_softc *);
252static int iwm_apm_init(struct iwm_softc *); 252static int iwm_apm_init(struct iwm_softc *);
253static void iwm_apm_stop(struct iwm_softc *); 253static void iwm_apm_stop(struct iwm_softc *);
254static int iwm_allow_mcast(struct iwm_softc *); 254static int iwm_allow_mcast(struct iwm_softc *);
255static int iwm_start_hw(struct iwm_softc *); 255static int iwm_start_hw(struct iwm_softc *);
256static void iwm_stop_device(struct iwm_softc *); 256static void iwm_stop_device(struct iwm_softc *);
257static void iwm_set_pwr(struct iwm_softc *); 257static void iwm_set_pwr(struct iwm_softc *);
258static void iwm_mvm_nic_config(struct iwm_softc *); 258static void iwm_mvm_nic_config(struct iwm_softc *);
259static int iwm_nic_rx_init(struct iwm_softc *); 259static int iwm_nic_rx_init(struct iwm_softc *);
260static int iwm_nic_tx_init(struct iwm_softc *); 260static int iwm_nic_tx_init(struct iwm_softc *);
261static int iwm_nic_init(struct iwm_softc *); 261static int iwm_nic_init(struct iwm_softc *);
262static void iwm_enable_txq(struct iwm_softc *, int, int); 262static void iwm_enable_txq(struct iwm_softc *, int, int);
263static int iwm_post_alive(struct iwm_softc *); 263static int iwm_post_alive(struct iwm_softc *);
264static int iwm_is_valid_channel(uint16_t); 264static int iwm_is_valid_channel(uint16_t);
265static uint8_t iwm_ch_id_to_ch_index(uint16_t); 265static uint8_t iwm_ch_id_to_ch_index(uint16_t);
266static uint16_t iwm_channel_id_to_papd(uint16_t); 266static uint16_t iwm_channel_id_to_papd(uint16_t);
267static uint16_t iwm_channel_id_to_txp(struct iwm_softc *, uint16_t); 267static uint16_t iwm_channel_id_to_txp(struct iwm_softc *, uint16_t);
268static int iwm_phy_db_get_section_data(struct iwm_softc *, uint32_t, 268static int iwm_phy_db_get_section_data(struct iwm_softc *, uint32_t,
269 uint8_t **, uint16_t *, uint16_t); 269 uint8_t **, uint16_t *, uint16_t);
270static int iwm_send_phy_db_cmd(struct iwm_softc *, uint16_t, uint16_t, 270static int iwm_send_phy_db_cmd(struct iwm_softc *, uint16_t, uint16_t,
271 void *); 271 void *);
272static int iwm_send_phy_db_data(struct iwm_softc *); 272static int iwm_send_phy_db_data(struct iwm_softc *);
273static int iwm_send_phy_db_data(struct iwm_softc *); 273static int iwm_send_phy_db_data(struct iwm_softc *);
274static void iwm_mvm_te_v2_to_v1(const struct iwm_time_event_cmd_v2 *, 274static void iwm_mvm_te_v2_to_v1(const struct iwm_time_event_cmd_v2 *,
275 struct iwm_time_event_cmd_v1 *); 275 struct iwm_time_event_cmd_v1 *);
276static int iwm_mvm_send_time_event_cmd(struct iwm_softc *, 276static int iwm_mvm_send_time_event_cmd(struct iwm_softc *,
277 const struct iwm_time_event_cmd_v2 *); 277 const struct iwm_time_event_cmd_v2 *);
278static int iwm_mvm_time_event_send_add(struct iwm_softc *, 278static int iwm_mvm_time_event_send_add(struct iwm_softc *,
279 struct iwm_node *, void *, struct iwm_time_event_cmd_v2 *); 279 struct iwm_node *, void *, struct iwm_time_event_cmd_v2 *);
280static void iwm_mvm_protect_session(struct iwm_softc *, struct iwm_node *, 280static void iwm_mvm_protect_session(struct iwm_softc *, struct iwm_node *,
281 uint32_t, uint32_t, uint32_t); 281 uint32_t, uint32_t, uint32_t);
282static int iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, uint16_t, 282static int iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, uint16_t,
283 uint16_t, uint8_t *, uint16_t *); 283 uint16_t, uint8_t *, uint16_t *);
284static int iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *, 284static int iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *,
285 uint16_t *); 285 uint16_t *);
286static void iwm_init_channel_map(struct iwm_softc *, 286static void iwm_init_channel_map(struct iwm_softc *,
287 const uint16_t * const); 287 const uint16_t * const);
288static int iwm_parse_nvm_data(struct iwm_softc *, const uint16_t *, 288static int iwm_parse_nvm_data(struct iwm_softc *, const uint16_t *,
289 const uint16_t *, const uint16_t *, uint8_t, uint8_t); 289 const uint16_t *, const uint16_t *, uint8_t, uint8_t);
290static int iwm_nvm_init(struct iwm_softc *); 290static int iwm_nvm_init(struct iwm_softc *);
291static int iwm_firmware_load_chunk(struct iwm_softc *, uint32_t, 291static int iwm_firmware_load_chunk(struct iwm_softc *, uint32_t,
292 const uint8_t *, uint32_t); 292 const uint8_t *, uint32_t);
293static int iwm_load_firmware(struct iwm_softc *, enum iwm_ucode_type); 293static int iwm_load_firmware(struct iwm_softc *, enum iwm_ucode_type);
294static int iwm_start_fw(struct iwm_softc *, enum iwm_ucode_type); 294static int iwm_start_fw(struct iwm_softc *, enum iwm_ucode_type);
295static int iwm_fw_alive(struct iwm_softc *, uint32_t); 295static int iwm_fw_alive(struct iwm_softc *, uint32_t);
296static int iwm_send_tx_ant_cfg(struct iwm_softc *, uint8_t); 296static int iwm_send_tx_ant_cfg(struct iwm_softc *, uint8_t);
297static int iwm_send_phy_cfg_cmd(struct iwm_softc *); 297static int iwm_send_phy_cfg_cmd(struct iwm_softc *);
298static int iwm_mvm_load_ucode_wait_alive(struct iwm_softc *, 298static int iwm_mvm_load_ucode_wait_alive(struct iwm_softc *,
299 enum iwm_ucode_type); 299 enum iwm_ucode_type);
300static int iwm_run_init_mvm_ucode(struct iwm_softc *, int); 300static int iwm_run_init_mvm_ucode(struct iwm_softc *, int);
301static int iwm_rx_addbuf(struct iwm_softc *, int, int); 301static int iwm_rx_addbuf(struct iwm_softc *, int, int);
302static int iwm_mvm_calc_rssi(struct iwm_softc *, struct iwm_rx_phy_info *); 302static int iwm_mvm_calc_rssi(struct iwm_softc *, struct iwm_rx_phy_info *);
303static int iwm_mvm_get_signal_strength(struct iwm_softc *, 303static int iwm_mvm_get_signal_strength(struct iwm_softc *,
304 struct iwm_rx_phy_info *); 304 struct iwm_rx_phy_info *);
305static void iwm_mvm_rx_rx_phy_cmd(struct iwm_softc *, 305static void iwm_mvm_rx_rx_phy_cmd(struct iwm_softc *,
306 struct iwm_rx_packet *, struct iwm_rx_data *); 306 struct iwm_rx_packet *, struct iwm_rx_data *);
307static int iwm_get_noise(const struct iwm_mvm_statistics_rx_non_phy *); 307static int iwm_get_noise(const struct iwm_mvm_statistics_rx_non_phy *);
308static void iwm_mvm_rx_rx_mpdu(struct iwm_softc *, struct iwm_rx_packet *, 308static void iwm_mvm_rx_rx_mpdu(struct iwm_softc *, struct iwm_rx_packet *,
309 struct iwm_rx_data *); 309 struct iwm_rx_data *);
310static void iwm_mvm_rx_tx_cmd_single(struct iwm_softc *, 310static void iwm_mvm_rx_tx_cmd_single(struct iwm_softc *,
311 struct iwm_rx_packet *, struct iwm_node *); 311 struct iwm_rx_packet *, struct iwm_node *);
312static void iwm_mvm_rx_tx_cmd(struct iwm_softc *, struct iwm_rx_packet *, 312static void iwm_mvm_rx_tx_cmd(struct iwm_softc *, struct iwm_rx_packet *,
313 struct iwm_rx_data *); 313 struct iwm_rx_data *);
314static int iwm_mvm_binding_cmd(struct iwm_softc *, struct iwm_node *, 314static int iwm_mvm_binding_cmd(struct iwm_softc *, struct iwm_node *,
315 uint32_t); 315 uint32_t);
316static int iwm_mvm_binding_update(struct iwm_softc *, struct iwm_node *, 316static int iwm_mvm_binding_update(struct iwm_softc *, struct iwm_node *,
317 int); 317 int);
318static int iwm_mvm_binding_add_vif(struct iwm_softc *, struct iwm_node *); 318static int iwm_mvm_binding_add_vif(struct iwm_softc *, struct iwm_node *);
319static void iwm_mvm_phy_ctxt_cmd_hdr(struct iwm_softc *, 319static void iwm_mvm_phy_ctxt_cmd_hdr(struct iwm_softc *,
320 struct iwm_mvm_phy_ctxt *, struct iwm_phy_context_cmd *, 320 struct iwm_mvm_phy_ctxt *, struct iwm_phy_context_cmd *,
321 uint32_t, uint32_t); 321 uint32_t, uint32_t);
322static void iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *, 322static void iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *,
323 struct iwm_phy_context_cmd *, struct ieee80211_channel *, 323 struct iwm_phy_context_cmd *, struct ieee80211_channel *,
324 uint8_t, uint8_t); 324 uint8_t, uint8_t);
325static int iwm_mvm_phy_ctxt_apply(struct iwm_softc *, 325static int iwm_mvm_phy_ctxt_apply(struct iwm_softc *,
326 struct iwm_mvm_phy_ctxt *, uint8_t, uint8_t, uint32_t, 326 struct iwm_mvm_phy_ctxt *, uint8_t, uint8_t, uint32_t,
327 uint32_t); 327 uint32_t);
328static int iwm_mvm_phy_ctxt_add(struct iwm_softc *, 328static int iwm_mvm_phy_ctxt_add(struct iwm_softc *,
329 struct iwm_mvm_phy_ctxt *, struct ieee80211_channel *, 329 struct iwm_mvm_phy_ctxt *, struct ieee80211_channel *,
330 uint8_t, uint8_t); 330 uint8_t, uint8_t);
331static int iwm_mvm_phy_ctxt_changed(struct iwm_softc *, 331static int iwm_mvm_phy_ctxt_changed(struct iwm_softc *,
332 struct iwm_mvm_phy_ctxt *, struct ieee80211_channel *, 332 struct iwm_mvm_phy_ctxt *, struct ieee80211_channel *,
333 uint8_t, uint8_t); 333 uint8_t, uint8_t);
334static int iwm_send_cmd(struct iwm_softc *, struct iwm_host_cmd *); 334static int iwm_send_cmd(struct iwm_softc *, struct iwm_host_cmd *);
335static int iwm_mvm_send_cmd_pdu(struct iwm_softc *, uint8_t, uint32_t, 335static int iwm_mvm_send_cmd_pdu(struct iwm_softc *, uint8_t, uint32_t,
336 uint16_t, const void *); 336 uint16_t, const void *);
337static int iwm_mvm_send_cmd_status(struct iwm_softc *, 337static int iwm_mvm_send_cmd_status(struct iwm_softc *,
338 struct iwm_host_cmd *, uint32_t *); 338 struct iwm_host_cmd *, uint32_t *);
339static int iwm_mvm_send_cmd_pdu_status(struct iwm_softc *, uint8_t, 339static int iwm_mvm_send_cmd_pdu_status(struct iwm_softc *, uint8_t,
340 uint16_t, const void *, uint32_t *); 340 uint16_t, const void *, uint32_t *);
341static void iwm_free_resp(struct iwm_softc *, struct iwm_host_cmd *); 341static void iwm_free_resp(struct iwm_softc *, struct iwm_host_cmd *);
342static void iwm_cmd_done(struct iwm_softc *, struct iwm_rx_packet *); 342static void iwm_cmd_done(struct iwm_softc *, struct iwm_rx_packet *);
343#if 0 343#if 0
344static void iwm_update_sched(struct iwm_softc *, int, int, uint8_t, 344static void iwm_update_sched(struct iwm_softc *, int, int, uint8_t,
345 uint16_t); 345 uint16_t);
346#endif 346#endif
347static const struct iwm_rate *iwm_tx_fill_cmd(struct iwm_softc *, 347static const struct iwm_rate *iwm_tx_fill_cmd(struct iwm_softc *,
348 struct iwm_node *, struct ieee80211_frame *, 348 struct iwm_node *, struct ieee80211_frame *,
349 struct iwm_tx_cmd *); 349 struct iwm_tx_cmd *);
350static int iwm_tx(struct iwm_softc *, struct mbuf *, 350static int iwm_tx(struct iwm_softc *, struct mbuf *,
351 struct ieee80211_node *, int); 351 struct ieee80211_node *, int);
352static int iwm_mvm_beacon_filter_send_cmd(struct iwm_softc *, 352static int iwm_mvm_beacon_filter_send_cmd(struct iwm_softc *,
353 struct iwm_beacon_filter_cmd *); 353 struct iwm_beacon_filter_cmd *);
354static void iwm_mvm_beacon_filter_set_cqm_params(struct iwm_softc *, 354static void iwm_mvm_beacon_filter_set_cqm_params(struct iwm_softc *,
355 struct iwm_node *, struct iwm_beacon_filter_cmd *); 355 struct iwm_node *, struct iwm_beacon_filter_cmd *);
356static int iwm_mvm_update_beacon_abort(struct iwm_softc *, 356static int iwm_mvm_update_beacon_abort(struct iwm_softc *,
357 struct iwm_node *, int); 357 struct iwm_node *, int);
358static void iwm_mvm_power_log(struct iwm_softc *, 358static void iwm_mvm_power_log(struct iwm_softc *,
359 struct iwm_mac_power_cmd *); 359 struct iwm_mac_power_cmd *);
360static void iwm_mvm_power_build_cmd(struct iwm_softc *, struct iwm_node *, 360static void iwm_mvm_power_build_cmd(struct iwm_softc *, struct iwm_node *,
361 struct iwm_mac_power_cmd *); 361 struct iwm_mac_power_cmd *);
362static int iwm_mvm_power_mac_update_mode(struct iwm_softc *, 362static int iwm_mvm_power_mac_update_mode(struct iwm_softc *,
363 struct iwm_node *); 363 struct iwm_node *);
364static int iwm_mvm_power_update_device(struct iwm_softc *); 364static int iwm_mvm_power_update_device(struct iwm_softc *);
365static int iwm_mvm_enable_beacon_filter(struct iwm_softc *, 365static int iwm_mvm_enable_beacon_filter(struct iwm_softc *,
366 struct iwm_node *); 366 struct iwm_node *);
367static int iwm_mvm_disable_beacon_filter(struct iwm_softc *, 367static int iwm_mvm_disable_beacon_filter(struct iwm_softc *,
368 struct iwm_node *); 368 struct iwm_node *);
369static void iwm_mvm_add_sta_cmd_v6_to_v5(struct iwm_mvm_add_sta_cmd_v6 *, 369static void iwm_mvm_add_sta_cmd_v6_to_v5(struct iwm_mvm_add_sta_cmd_v6 *,
370 struct iwm_mvm_add_sta_cmd_v5 *); 370 struct iwm_mvm_add_sta_cmd_v5 *);
371static int iwm_mvm_send_add_sta_cmd_status(struct iwm_softc *, 371static int iwm_mvm_send_add_sta_cmd_status(struct iwm_softc *,
372 struct iwm_mvm_add_sta_cmd_v6 *, int *); 372 struct iwm_mvm_add_sta_cmd_v6 *, int *);
373static int iwm_mvm_sta_send_to_fw(struct iwm_softc *, struct iwm_node *, 373static int iwm_mvm_sta_send_to_fw(struct iwm_softc *, struct iwm_node *,
374 int); 374 int);
375static int iwm_mvm_add_sta(struct iwm_softc *, struct iwm_node *); 375static int iwm_mvm_add_sta(struct iwm_softc *, struct iwm_node *);
376static int iwm_mvm_update_sta(struct iwm_softc *, struct iwm_node *); 376static int iwm_mvm_update_sta(struct iwm_softc *, struct iwm_node *);
377static int iwm_mvm_add_int_sta_common(struct iwm_softc *, 377static int iwm_mvm_add_int_sta_common(struct iwm_softc *,
378 struct iwm_int_sta *, const uint8_t *, uint16_t, uint16_t); 378 struct iwm_int_sta *, const uint8_t *, uint16_t, uint16_t);
379static int iwm_mvm_add_aux_sta(struct iwm_softc *); 379static int iwm_mvm_add_aux_sta(struct iwm_softc *);
380static uint16_t iwm_mvm_scan_rx_chain(struct iwm_softc *); 380static uint16_t iwm_mvm_scan_rx_chain(struct iwm_softc *);
381static uint32_t iwm_mvm_scan_max_out_time(struct iwm_softc *, uint32_t, int); 381static uint32_t iwm_mvm_scan_max_out_time(struct iwm_softc *, uint32_t, int);
382static uint32_t iwm_mvm_scan_suspend_time(struct iwm_softc *, int); 382static uint32_t iwm_mvm_scan_suspend_time(struct iwm_softc *, int);
383static uint32_t iwm_mvm_scan_rxon_flags(struct iwm_softc *, int); 383static uint32_t iwm_mvm_scan_rxon_flags(struct iwm_softc *, int);
384static uint32_t iwm_mvm_scan_rate_n_flags(struct iwm_softc *, int, int); 384static uint32_t iwm_mvm_scan_rate_n_flags(struct iwm_softc *, int, int);
385static uint16_t iwm_mvm_get_active_dwell(struct iwm_softc *, int, int); 385static uint16_t iwm_mvm_get_active_dwell(struct iwm_softc *, int, int);
386static uint16_t iwm_mvm_get_passive_dwell(struct iwm_softc *, int); 386static uint16_t iwm_mvm_get_passive_dwell(struct iwm_softc *, int);
387static int iwm_mvm_scan_fill_channels(struct iwm_softc *, 387static int iwm_mvm_scan_fill_channels(struct iwm_softc *,
388 struct iwm_scan_cmd *, int, int, int); 388 struct iwm_scan_cmd *, int, int, int);
389static uint16_t iwm_mvm_fill_probe_req(struct iwm_softc *, 389static uint16_t iwm_mvm_fill_probe_req(struct iwm_softc *,
390 struct ieee80211_frame *, const uint8_t *, int, 390 struct ieee80211_frame *, const uint8_t *, int,
391 const uint8_t *, int, const uint8_t *, int, int); 391 const uint8_t *, int, const uint8_t *, int, int);
392static int iwm_mvm_scan_request(struct iwm_softc *, int, int, uint8_t *, 392static int iwm_mvm_scan_request(struct iwm_softc *, int, int, uint8_t *,
393 int); 393 int);
394static void iwm_mvm_ack_rates(struct iwm_softc *, struct iwm_node *, int *, 394static void iwm_mvm_ack_rates(struct iwm_softc *, struct iwm_node *, int *,
395 int *); 395 int *);
396static void iwm_mvm_mac_ctxt_cmd_common(struct iwm_softc *, 396static void iwm_mvm_mac_ctxt_cmd_common(struct iwm_softc *,
397 struct iwm_node *, struct iwm_mac_ctx_cmd *, uint32_t); 397 struct iwm_node *, struct iwm_mac_ctx_cmd *, uint32_t);
398static int iwm_mvm_mac_ctxt_send_cmd(struct iwm_softc *, 398static int iwm_mvm_mac_ctxt_send_cmd(struct iwm_softc *,
399 struct iwm_mac_ctx_cmd *); 399 struct iwm_mac_ctx_cmd *);
400static void iwm_mvm_mac_ctxt_cmd_fill_sta(struct iwm_softc *, 400static void iwm_mvm_mac_ctxt_cmd_fill_sta(struct iwm_softc *,
401 struct iwm_node *, struct iwm_mac_data_sta *, int); 401 struct iwm_node *, struct iwm_mac_data_sta *, int);
402static int iwm_mvm_mac_ctxt_cmd_station(struct iwm_softc *, 402static int iwm_mvm_mac_ctxt_cmd_station(struct iwm_softc *,
403 struct iwm_node *, uint32_t); 403 struct iwm_node *, uint32_t);
404static int iwm_mvm_mac_ctx_send(struct iwm_softc *, struct iwm_node *, 404static int iwm_mvm_mac_ctx_send(struct iwm_softc *, struct iwm_node *,
405 uint32_t); 405 uint32_t);
406static int iwm_mvm_mac_ctxt_add(struct iwm_softc *, struct iwm_node *); 406static int iwm_mvm_mac_ctxt_add(struct iwm_softc *, struct iwm_node *);
407static int iwm_mvm_mac_ctxt_changed(struct iwm_softc *, struct iwm_node *); 407static int iwm_mvm_mac_ctxt_changed(struct iwm_softc *, struct iwm_node *);
408static int iwm_mvm_update_quotas(struct iwm_softc *, struct iwm_node *); 408static int iwm_mvm_update_quotas(struct iwm_softc *, struct iwm_node *);
409static int iwm_auth(struct iwm_softc *); 409static int iwm_auth(struct iwm_softc *);
410static int iwm_assoc(struct iwm_softc *); 410static int iwm_assoc(struct iwm_softc *);
411static int iwm_release(struct iwm_softc *, struct iwm_node *); 411static int iwm_release(struct iwm_softc *, struct iwm_node *);
412static void iwm_calib_timeout(void *); 412static void iwm_calib_timeout(void *);
413static void iwm_setrates(struct iwm_node *); 413static void iwm_setrates(struct iwm_node *);
414static int iwm_media_change(struct ifnet *); 414static int iwm_media_change(struct ifnet *);
415static void iwm_newstate_cb(struct work *, void *); 415static void iwm_newstate_cb(struct work *, void *);
416static int iwm_newstate(struct ieee80211com *, enum ieee80211_state, int); 416static int iwm_newstate(struct ieee80211com *, enum ieee80211_state, int);
417static void iwm_endscan_cb(struct work *, void *); 417static void iwm_endscan_cb(struct work *, void *);
418static int iwm_init_hw(struct iwm_softc *); 418static int iwm_init_hw(struct iwm_softc *);
419static int iwm_init(struct ifnet *); 419static int iwm_init(struct ifnet *);
420static void iwm_start(struct ifnet *); 420static void iwm_start(struct ifnet *);
421static void iwm_stop(struct ifnet *, int); 421static void iwm_stop(struct ifnet *, int);
422static void iwm_watchdog(struct ifnet *); 422static void iwm_watchdog(struct ifnet *);
423static int iwm_ioctl(struct ifnet *, u_long, void *); 423static int iwm_ioctl(struct ifnet *, u_long, void *);
424#ifdef IWM_DEBUG 424#ifdef IWM_DEBUG
425static const char *iwm_desc_lookup(uint32_t); 425static const char *iwm_desc_lookup(uint32_t);
426static void iwm_nic_error(struct iwm_softc *); 426static void iwm_nic_error(struct iwm_softc *);
427#endif 427#endif
428static void iwm_notif_intr(struct iwm_softc *); 428static void iwm_notif_intr(struct iwm_softc *);
429static int iwm_intr(void *); 429static int iwm_intr(void *);
430static int iwm_preinit(struct iwm_softc *); 430static int iwm_preinit(struct iwm_softc *);
431static void iwm_attach_hook(device_t); 431static void iwm_attach_hook(device_t);
432static void iwm_attach(device_t, device_t, void *); 432static void iwm_attach(device_t, device_t, void *);
433#if 0 433#if 0
434static void iwm_init_task(void *); 434static void iwm_init_task(void *);
435static int iwm_activate(device_t, enum devact); 435static int iwm_activate(device_t, enum devact);
436static void iwm_wakeup(struct iwm_softc *); 436static void iwm_wakeup(struct iwm_softc *);
437#endif 437#endif
438static void iwm_radiotap_attach(struct iwm_softc *); 438static void iwm_radiotap_attach(struct iwm_softc *);
439 439
440static int 440static int
441iwm_firmload(struct iwm_softc *sc) 441iwm_firmload(struct iwm_softc *sc)
442{ 442{
443 struct iwm_fw_info *fw = &sc->sc_fw; 443 struct iwm_fw_info *fw = &sc->sc_fw;
444 firmware_handle_t fwh; 444 firmware_handle_t fwh;
445 int error; 445 int error;
446 446
447 /* Open firmware image. */ 447 /* Open firmware image. */
448 if ((error = firmware_open("if_iwm", sc->sc_fwname, &fwh)) != 0) { 448 if ((error = firmware_open("if_iwm", sc->sc_fwname, &fwh)) != 0) {
449 aprint_error_dev(sc->sc_dev, 449 aprint_error_dev(sc->sc_dev,
450 "could not get firmware handle %s\n", sc->sc_fwname); 450 "could not get firmware handle %s\n", sc->sc_fwname);
451 return error; 451 return error;
452 } 452 }
453 453
454 fw->fw_rawsize = firmware_get_size(fwh); 454 fw->fw_rawsize = firmware_get_size(fwh);
455 /* 455 /*
456 * Well, this is how the Linux driver checks it .... 456 * Well, this is how the Linux driver checks it ....
457 */ 457 */
458 if (fw->fw_rawsize < sizeof(uint32_t)) { 458 if (fw->fw_rawsize < sizeof(uint32_t)) {
459 aprint_error_dev(sc->sc_dev, 459 aprint_error_dev(sc->sc_dev,
460 "firmware too short: %zd bytes\n", fw->fw_rawsize); 460 "firmware too short: %zd bytes\n", fw->fw_rawsize);
461 error = EINVAL; 461 error = EINVAL;
462 goto out; 462 goto out;
463 } 463 }
464 464
465 /* some sanity */ 465 /* some sanity */
466 if (fw->fw_rawsize > IWM_FWMAXSIZE) { 466 if (fw->fw_rawsize > IWM_FWMAXSIZE) {
467 aprint_error_dev(sc->sc_dev, 467 aprint_error_dev(sc->sc_dev,
468 "firmware size is ridiculous: %zd bytes\n", 468 "firmware size is ridiculous: %zd bytes\n",
469 fw->fw_rawsize); 469 fw->fw_rawsize);
470 error = EINVAL; 470 error = EINVAL;
471 goto out; 471 goto out;
472 } 472 }
473 473
474 /* Read the firmware. */ 474 /* Read the firmware. */
475 fw->fw_rawdata = kmem_alloc(fw->fw_rawsize, KM_SLEEP); 475 fw->fw_rawdata = kmem_alloc(fw->fw_rawsize, KM_SLEEP);
476 if (fw->fw_rawdata == NULL) { 476 if (fw->fw_rawdata == NULL) {
477 aprint_error_dev(sc->sc_dev, 477 aprint_error_dev(sc->sc_dev,
478 "not enough memory to stock firmware %s\n", sc->sc_fwname); 478 "not enough memory to stock firmware %s\n", sc->sc_fwname);
479 error = ENOMEM; 479 error = ENOMEM;
480 goto out; 480 goto out;
481 } 481 }
482 error = firmware_read(fwh, 0, fw->fw_rawdata, fw->fw_rawsize); 482 error = firmware_read(fwh, 0, fw->fw_rawdata, fw->fw_rawsize);
483 if (error) { 483 if (error) {
484 aprint_error_dev(sc->sc_dev, 484 aprint_error_dev(sc->sc_dev,
485 "could not read firmware %s\n", sc->sc_fwname); 485 "could not read firmware %s\n", sc->sc_fwname);
486 goto out; 486 goto out;
487 } 487 }
488 488
489 out: 489 out:
490 /* caller will release memory, if necessary */ 490 /* caller will release memory, if necessary */
491 491
492 firmware_close(fwh); 492 firmware_close(fwh);
493 return error; 493 return error;
494} 494}
495 495
496/* 496/*
497 * just maintaining status quo. 497 * just maintaining status quo.
498 */ 498 */
499static void 499static void
500iwm_fix_channel(struct ieee80211com *ic, struct mbuf *m) 500iwm_fix_channel(struct ieee80211com *ic, struct mbuf *m)
501{ 501{
502 struct ieee80211_frame *wh; 502 struct ieee80211_frame *wh;
503 uint8_t subtype; 503 uint8_t subtype;
504 uint8_t *frm, *efrm; 504 uint8_t *frm, *efrm;
505 505
506 wh = mtod(m, struct ieee80211_frame *); 506 wh = mtod(m, struct ieee80211_frame *);
507 507
508 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT) 508 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
509 return; 509 return;
510 510
511 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 511 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
512 512
513 if (subtype != IEEE80211_FC0_SUBTYPE_BEACON && 513 if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
514 subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) 514 subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP)
515 return; 515 return;
516 516
517 frm = (uint8_t *)(wh + 1); 517 frm = (uint8_t *)(wh + 1);
518 efrm = mtod(m, uint8_t *) + m->m_len; 518 efrm = mtod(m, uint8_t *) + m->m_len;
519 519
520 frm += 12; /* skip tstamp, bintval and capinfo fields */ 520 frm += 12; /* skip tstamp, bintval and capinfo fields */
521 while (frm < efrm) { 521 while (frm < efrm) {
522 if (*frm == IEEE80211_ELEMID_DSPARMS) { 522 if (*frm == IEEE80211_ELEMID_DSPARMS) {
523#if IEEE80211_CHAN_MAX < 255 523#if IEEE80211_CHAN_MAX < 255
524 if (frm[2] <= IEEE80211_CHAN_MAX) 524 if (frm[2] <= IEEE80211_CHAN_MAX)
525#endif 525#endif
526 ic->ic_curchan = &ic->ic_channels[frm[2]]; 526 ic->ic_curchan = &ic->ic_channels[frm[2]];
527 } 527 }
528 frm += frm[1] + 2; 528 frm += frm[1] + 2;
529 } 529 }
530} 530}
531 531
532/* 532/*
533 * Firmware parser. 533 * Firmware parser.
534 */ 534 */
535 535
536static int 536static int
537iwm_store_cscheme(struct iwm_softc *sc, uint8_t *data, size_t dlen) 537iwm_store_cscheme(struct iwm_softc *sc, uint8_t *data, size_t dlen)
538{ 538{
539 struct iwm_fw_cscheme_list *l = (void *)data; 539 struct iwm_fw_cscheme_list *l = (void *)data;
540 540
541 if (dlen < sizeof(*l) || 541 if (dlen < sizeof(*l) ||
542 dlen < sizeof(l->size) + l->size * sizeof(*l->cs)) 542 dlen < sizeof(l->size) + l->size * sizeof(*l->cs))
543 return EINVAL; 543 return EINVAL;
544 544
545 /* we don't actually store anything for now, always use s/w crypto */ 545 /* we don't actually store anything for now, always use s/w crypto */
546 546
547 return 0; 547 return 0;
548} 548}
549 549
550static int 550static int
551iwm_firmware_store_section(struct iwm_softc *sc, 551iwm_firmware_store_section(struct iwm_softc *sc,
552 enum iwm_ucode_type type, uint8_t *data, size_t dlen) 552 enum iwm_ucode_type type, uint8_t *data, size_t dlen)
553{ 553{
554 struct iwm_fw_sects *fws; 554 struct iwm_fw_sects *fws;
555 struct iwm_fw_onesect *fwone; 555 struct iwm_fw_onesect *fwone;
556 556
557 if (type >= IWM_UCODE_TYPE_MAX) 557 if (type >= IWM_UCODE_TYPE_MAX)
558 return EINVAL; 558 return EINVAL;
559 if (dlen < sizeof(uint32_t)) 559 if (dlen < sizeof(uint32_t))
560 return EINVAL; 560 return EINVAL;
561 561
562 fws = &sc->sc_fw.fw_sects[type]; 562 fws = &sc->sc_fw.fw_sects[type];
563 if (fws->fw_count >= IWM_UCODE_SECT_MAX) 563 if (fws->fw_count >= IWM_UCODE_SECT_MAX)
564 return EINVAL; 564 return EINVAL;
565 565
566 fwone = &fws->fw_sect[fws->fw_count]; 566 fwone = &fws->fw_sect[fws->fw_count];
567 567
568 /* first 32bit are device load offset */ 568 /* first 32bit are device load offset */
569 memcpy(&fwone->fws_devoff, data, sizeof(uint32_t)); 569 memcpy(&fwone->fws_devoff, data, sizeof(uint32_t));
570 570
571 /* rest is data */ 571 /* rest is data */
572 fwone->fws_data = data + sizeof(uint32_t); 572 fwone->fws_data = data + sizeof(uint32_t);
573 fwone->fws_len = dlen - sizeof(uint32_t); 573 fwone->fws_len = dlen - sizeof(uint32_t);
574 574
575 /* for freeing the buffer during driver unload */ 575 /* for freeing the buffer during driver unload */
576 fwone->fws_alloc = data; 576 fwone->fws_alloc = data;
577 fwone->fws_allocsize = dlen; 577 fwone->fws_allocsize = dlen;
578 578
579 fws->fw_count++; 579 fws->fw_count++;
580 fws->fw_totlen += fwone->fws_len; 580 fws->fw_totlen += fwone->fws_len;
581 581
582 return 0; 582 return 0;
583} 583}
584 584
585/* iwlwifi: iwl-drv.c */ 585/* iwlwifi: iwl-drv.c */
586struct iwm_tlv_calib_data { 586struct iwm_tlv_calib_data {
587 uint32_t ucode_type; 587 uint32_t ucode_type;
588 struct iwm_tlv_calib_ctrl calib; 588 struct iwm_tlv_calib_ctrl calib;
589} __packed; 589} __packed;
590 590
591static int 591static int
592iwm_set_default_calib(struct iwm_softc *sc, const void *data) 592iwm_set_default_calib(struct iwm_softc *sc, const void *data)
593{ 593{
594 const struct iwm_tlv_calib_data *def_calib = data; 594 const struct iwm_tlv_calib_data *def_calib = data;
595 uint32_t ucode_type = le32toh(def_calib->ucode_type); 595 uint32_t ucode_type = le32toh(def_calib->ucode_type);
596 596
597 if (ucode_type >= IWM_UCODE_TYPE_MAX) { 597 if (ucode_type >= IWM_UCODE_TYPE_MAX) {
598 DPRINTF(("%s: Wrong ucode_type %u for default " 598 DPRINTF(("%s: Wrong ucode_type %u for default "
599 "calibration.\n", DEVNAME(sc), ucode_type)); 599 "calibration.\n", DEVNAME(sc), ucode_type));
600 return EINVAL; 600 return EINVAL;
601 } 601 }
602 602
603 sc->sc_default_calib[ucode_type].flow_trigger = 603 sc->sc_default_calib[ucode_type].flow_trigger =
604 def_calib->calib.flow_trigger; 604 def_calib->calib.flow_trigger;
605 sc->sc_default_calib[ucode_type].event_trigger = 605 sc->sc_default_calib[ucode_type].event_trigger =
606 def_calib->calib.event_trigger; 606 def_calib->calib.event_trigger;
607 607
608 return 0; 608 return 0;
609} 609}
610 610
611static int 611static int
612iwm_read_firmware(struct iwm_softc *sc) 612iwm_read_firmware(struct iwm_softc *sc)
613{ 613{
614 struct iwm_fw_info *fw = &sc->sc_fw; 614 struct iwm_fw_info *fw = &sc->sc_fw;
615 struct iwm_tlv_ucode_header *uhdr; 615 struct iwm_tlv_ucode_header *uhdr;
616 struct iwm_ucode_tlv tlv; 616 struct iwm_ucode_tlv tlv;
617 enum iwm_ucode_tlv_type tlv_type; 617 enum iwm_ucode_tlv_type tlv_type;
618 uint8_t *data; 618 uint8_t *data;
619 int error, status; 619 int error, status;
620 size_t len; 620 size_t len;
621 621
622 if (fw->fw_status == IWM_FW_STATUS_NONE) { 622 if (fw->fw_status == IWM_FW_STATUS_NONE) {
623 fw->fw_status = IWM_FW_STATUS_INPROGRESS; 623 fw->fw_status = IWM_FW_STATUS_INPROGRESS;
624 } else { 624 } else {
625 while (fw->fw_status == IWM_FW_STATUS_INPROGRESS) 625 while (fw->fw_status == IWM_FW_STATUS_INPROGRESS)
626 tsleep(&sc->sc_fw, 0, "iwmfwp", 0); 626 tsleep(&sc->sc_fw, 0, "iwmfwp", 0);
627 } 627 }
628 status = fw->fw_status; 628 status = fw->fw_status;
629 629
630 if (status == IWM_FW_STATUS_DONE) 630 if (status == IWM_FW_STATUS_DONE)
631 return 0; 631 return 0;
632 632
633 /* 633 /*
634 * Load firmware into driver memory. 634 * Load firmware into driver memory.
635 * fw_rawdata and fw_rawsize will be set. 635 * fw_rawdata and fw_rawsize will be set.
636 */ 636 */
637 error = iwm_firmload(sc); 637 error = iwm_firmload(sc);
638 if (error != 0) { 638 if (error != 0) {
639 aprint_error_dev(sc->sc_dev, 639 aprint_error_dev(sc->sc_dev,
640 "could not read firmware %s (error %d)\n", 640 "could not read firmware %s (error %d)\n",
641 sc->sc_fwname, error); 641 sc->sc_fwname, error);
642 goto out; 642 goto out;
643 } 643 }
644 644
645 /* 645 /*
646 * Parse firmware contents 646 * Parse firmware contents
647 */ 647 */
648 648
649 uhdr = (void *)fw->fw_rawdata; 649 uhdr = (void *)fw->fw_rawdata;
650 if (*(uint32_t *)fw->fw_rawdata != 0 650 if (*(uint32_t *)fw->fw_rawdata != 0
651 || le32toh(uhdr->magic) != IWM_TLV_UCODE_MAGIC) { 651 || le32toh(uhdr->magic) != IWM_TLV_UCODE_MAGIC) {
652 aprint_error_dev(sc->sc_dev, "invalid firmware %s\n", 652 aprint_error_dev(sc->sc_dev, "invalid firmware %s\n",
653 sc->sc_fwname); 653 sc->sc_fwname);
654 error = EINVAL; 654 error = EINVAL;
655 goto out; 655 goto out;
656 } 656 }
657 657
658 sc->sc_fwver = le32toh(uhdr->ver); 658 sc->sc_fwver = le32toh(uhdr->ver);
659 data = uhdr->data; 659 data = uhdr->data;
660 len = fw->fw_rawsize - sizeof(*uhdr); 660 len = fw->fw_rawsize - sizeof(*uhdr);
661 661
662 while (len >= sizeof(tlv)) { 662 while (len >= sizeof(tlv)) {
663 size_t tlv_len; 663 size_t tlv_len;
664 void *tlv_data; 664 void *tlv_data;
665 665
666 memcpy(&tlv, data, sizeof(tlv)); 666 memcpy(&tlv, data, sizeof(tlv));
667 tlv_len = le32toh(tlv.length); 667 tlv_len = le32toh(tlv.length);
668 tlv_type = le32toh(tlv.type); 668 tlv_type = le32toh(tlv.type);
669 669
670 len -= sizeof(tlv); 670 len -= sizeof(tlv);
671 data += sizeof(tlv); 671 data += sizeof(tlv);
672 tlv_data = data; 672 tlv_data = data;
673 673
674 if (len < tlv_len) { 674 if (len < tlv_len) {
675 aprint_error_dev(sc->sc_dev, 675 aprint_error_dev(sc->sc_dev,
676 "firmware too short: %zu bytes\n", len); 676 "firmware too short: %zu bytes\n", len);
677 error = EINVAL; 677 error = EINVAL;
678 goto parse_out; 678 goto parse_out;
679 } 679 }
680 680
681 switch ((int)tlv_type) { 681 switch ((int)tlv_type) {
682 case IWM_UCODE_TLV_PROBE_MAX_LEN: 682 case IWM_UCODE_TLV_PROBE_MAX_LEN:
683 if (tlv_len < sizeof(uint32_t)) { 683 if (tlv_len < sizeof(uint32_t)) {
684 error = EINVAL; 684 error = EINVAL;
685 goto parse_out; 685 goto parse_out;
686 } 686 }
687 sc->sc_capa_max_probe_len 687 sc->sc_capa_max_probe_len
688 = le32toh(*(uint32_t *)tlv_data); 688 = le32toh(*(uint32_t *)tlv_data);
689 /* limit it to something sensible */ 689 /* limit it to something sensible */
690 if (sc->sc_capa_max_probe_len > (1<<16)) { 690 if (sc->sc_capa_max_probe_len > (1<<16)) {
691 DPRINTF(("%s: IWM_UCODE_TLV_PROBE_MAX_LEN " 691 DPRINTF(("%s: IWM_UCODE_TLV_PROBE_MAX_LEN "
692 "ridiculous\n", DEVNAME(sc))); 692 "ridiculous\n", DEVNAME(sc)));
693 error = EINVAL; 693 error = EINVAL;
694 goto parse_out; 694 goto parse_out;
695 } 695 }
696 break; 696 break;
697 case IWM_UCODE_TLV_PAN: 697 case IWM_UCODE_TLV_PAN:
698 if (tlv_len) { 698 if (tlv_len) {
699 error = EINVAL; 699 error = EINVAL;
700 goto parse_out; 700 goto parse_out;
701 } 701 }
702 sc->sc_capaflags |= IWM_UCODE_TLV_FLAGS_PAN; 702 sc->sc_capaflags |= IWM_UCODE_TLV_FLAGS_PAN;
703 break; 703 break;
704 case IWM_UCODE_TLV_FLAGS: 704 case IWM_UCODE_TLV_FLAGS:
705 if (tlv_len < sizeof(uint32_t)) { 705 if (tlv_len < sizeof(uint32_t)) {
706 error = EINVAL; 706 error = EINVAL;
707 goto parse_out; 707 goto parse_out;
708 } 708 }
709 /* 709 /*
710 * Apparently there can be many flags, but Linux driver 710 * Apparently there can be many flags, but Linux driver
711 * parses only the first one, and so do we. 711 * parses only the first one, and so do we.
712 * 712 *
713 * XXX: why does this override IWM_UCODE_TLV_PAN? 713 * XXX: why does this override IWM_UCODE_TLV_PAN?
714 * Intentional or a bug? Observations from 714 * Intentional or a bug? Observations from
715 * current firmware file: 715 * current firmware file:
716 * 1) TLV_PAN is parsed first 716 * 1) TLV_PAN is parsed first
717 * 2) TLV_FLAGS contains TLV_FLAGS_PAN 717 * 2) TLV_FLAGS contains TLV_FLAGS_PAN
718 * ==> this resets TLV_PAN to itself... hnnnk 718 * ==> this resets TLV_PAN to itself... hnnnk
719 */ 719 */
720 sc->sc_capaflags = le32toh(*(uint32_t *)tlv_data); 720 sc->sc_capaflags = le32toh(*(uint32_t *)tlv_data);
721 break; 721 break;
722 case IWM_UCODE_TLV_CSCHEME: 722 case IWM_UCODE_TLV_CSCHEME:
723 if ((error = iwm_store_cscheme(sc, 723 if ((error = iwm_store_cscheme(sc,
724 tlv_data, tlv_len)) != 0) 724 tlv_data, tlv_len)) != 0)
725 goto parse_out; 725 goto parse_out;
726 break; 726 break;
727 case IWM_UCODE_TLV_NUM_OF_CPU: 727 case IWM_UCODE_TLV_NUM_OF_CPU:
728 if (tlv_len != sizeof(uint32_t)) { 728 if (tlv_len != sizeof(uint32_t)) {
729 error = EINVAL; 729 error = EINVAL;
730 goto parse_out; 730 goto parse_out;
731 } 731 }
732 if (le32toh(*(uint32_t*)tlv_data) != 1) { 732 if (le32toh(*(uint32_t*)tlv_data) != 1) {
733 DPRINTF(("%s: driver supports " 733 DPRINTF(("%s: driver supports "
734 "only TLV_NUM_OF_CPU == 1", DEVNAME(sc))); 734 "only TLV_NUM_OF_CPU == 1", DEVNAME(sc)));
735 error = EINVAL; 735 error = EINVAL;
736 goto parse_out; 736 goto parse_out;
737 } 737 }
738 break; 738 break;
739 case IWM_UCODE_TLV_SEC_RT: 739 case IWM_UCODE_TLV_SEC_RT:
740 if ((error = iwm_firmware_store_section(sc, 740 if ((error = iwm_firmware_store_section(sc,
741 IWM_UCODE_TYPE_REGULAR, tlv_data, tlv_len)) != 0) 741 IWM_UCODE_TYPE_REGULAR, tlv_data, tlv_len)) != 0)
742 goto parse_out; 742 goto parse_out;
743 break; 743 break;
744 case IWM_UCODE_TLV_SEC_INIT: 744 case IWM_UCODE_TLV_SEC_INIT:
745 if ((error = iwm_firmware_store_section(sc, 745 if ((error = iwm_firmware_store_section(sc,
746 IWM_UCODE_TYPE_INIT, tlv_data, tlv_len)) != 0) 746 IWM_UCODE_TYPE_INIT, tlv_data, tlv_len)) != 0)
747 goto parse_out; 747 goto parse_out;
748 break; 748 break;
749 case IWM_UCODE_TLV_SEC_WOWLAN: 749 case IWM_UCODE_TLV_SEC_WOWLAN:
750 if ((error = iwm_firmware_store_section(sc, 750 if ((error = iwm_firmware_store_section(sc,
751 IWM_UCODE_TYPE_WOW, tlv_data, tlv_len)) != 0) 751 IWM_UCODE_TYPE_WOW, tlv_data, tlv_len)) != 0)
752 goto parse_out; 752 goto parse_out;
753 break; 753 break;
754 case IWM_UCODE_TLV_DEF_CALIB: 754 case IWM_UCODE_TLV_DEF_CALIB:
755 if (tlv_len != sizeof(struct iwm_tlv_calib_data)) { 755 if (tlv_len != sizeof(struct iwm_tlv_calib_data)) {
756 error = EINVAL; 756 error = EINVAL;
757 goto parse_out; 757 goto parse_out;
758 } 758 }
759 if ((error = iwm_set_default_calib(sc, tlv_data)) != 0) 759 if ((error = iwm_set_default_calib(sc, tlv_data)) != 0)
760 goto parse_out; 760 goto parse_out;
761 break; 761 break;
762 case IWM_UCODE_TLV_PHY_SKU: 762 case IWM_UCODE_TLV_PHY_SKU:
763 if (tlv_len != sizeof(uint32_t)) { 763 if (tlv_len != sizeof(uint32_t)) {
764 error = EINVAL; 764 error = EINVAL;
765 goto parse_out; 765 goto parse_out;
766 } 766 }
767 sc->sc_fw_phy_config = le32toh(*(uint32_t *)tlv_data); 767 sc->sc_fw_phy_config = le32toh(*(uint32_t *)tlv_data);
768 break; 768 break;
769 769
770 case IWM_UCODE_TLV_API_CHANGES_SET: 770 case IWM_UCODE_TLV_API_CHANGES_SET:
771 case IWM_UCODE_TLV_ENABLED_CAPABILITIES: 771 case IWM_UCODE_TLV_ENABLED_CAPABILITIES:
772 /* ignore, not used by current driver */ 772 /* ignore, not used by current driver */
773 break; 773 break;
774 774
775 default: 775 default:
776 DPRINTF(("%s: unknown firmware section %d, abort\n", 776 DPRINTF(("%s: unknown firmware section %d, abort\n",
777 DEVNAME(sc), tlv_type)); 777 DEVNAME(sc), tlv_type));
778 error = EINVAL; 778 error = EINVAL;
779 goto parse_out; 779 goto parse_out;
780 } 780 }
781 781
782 len -= roundup(tlv_len, 4); 782 len -= roundup(tlv_len, 4);
783 data += roundup(tlv_len, 4); 783 data += roundup(tlv_len, 4);
784 } 784 }
785 785
786 KASSERT(error == 0); 786 KASSERT(error == 0);
787 787
788 parse_out: 788 parse_out:
789 if (error) { 789 if (error) {
790 aprint_error_dev(sc->sc_dev, 790 aprint_error_dev(sc->sc_dev,
791 "firmware parse error, section type %d\n", tlv_type); 791 "firmware parse error, section type %d\n", tlv_type);
792 } 792 }
793 793
794 if (!(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) { 794 if (!(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) {
795 aprint_error_dev(sc->sc_dev, 795 aprint_error_dev(sc->sc_dev,
796 "device uses unsupported power ops\n"); 796 "device uses unsupported power ops\n");
797 error = ENOTSUP; 797 error = ENOTSUP;
798 } 798 }
799 799
800 out: 800 out:
801 if (error) 801 if (error)
802 fw->fw_status = IWM_FW_STATUS_NONE; 802 fw->fw_status = IWM_FW_STATUS_NONE;
803 else 803 else
804 fw->fw_status = IWM_FW_STATUS_DONE; 804 fw->fw_status = IWM_FW_STATUS_DONE;
805 wakeup(&sc->sc_fw); 805 wakeup(&sc->sc_fw);
806 806
807 if (error && fw->fw_rawdata != NULL) { 807 if (error && fw->fw_rawdata != NULL) {
808 kmem_free(fw->fw_rawdata, fw->fw_rawsize); 808 kmem_free(fw->fw_rawdata, fw->fw_rawsize);
809 fw->fw_rawdata = NULL; 809 fw->fw_rawdata = NULL;
810 } 810 }
811 return error; 811 return error;
812} 812}
813 813
814/* 814/*
815 * basic device access 815 * basic device access
816 */ 816 */
817 817
818static uint32_t 818static uint32_t
819iwm_read_prph(struct iwm_softc *sc, uint32_t addr) 819iwm_read_prph(struct iwm_softc *sc, uint32_t addr)
820{ 820{
821 IWM_WRITE(sc, 821 IWM_WRITE(sc,
822 IWM_HBUS_TARG_PRPH_RADDR, ((addr & 0x000fffff) | (3 << 24))); 822 IWM_HBUS_TARG_PRPH_RADDR, ((addr & 0x000fffff) | (3 << 24)));
823 IWM_BARRIER_READ_WRITE(sc); 823 IWM_BARRIER_READ_WRITE(sc);
824 return IWM_READ(sc, IWM_HBUS_TARG_PRPH_RDAT); 824 return IWM_READ(sc, IWM_HBUS_TARG_PRPH_RDAT);
825} 825}
826 826
827static void 827static void
828iwm_write_prph(struct iwm_softc *sc, uint32_t addr, uint32_t val) 828iwm_write_prph(struct iwm_softc *sc, uint32_t addr, uint32_t val)
829{ 829{
830 IWM_WRITE(sc, 830 IWM_WRITE(sc,
831 IWM_HBUS_TARG_PRPH_WADDR, ((addr & 0x000fffff) | (3 << 24))); 831 IWM_HBUS_TARG_PRPH_WADDR, ((addr & 0x000fffff) | (3 << 24)));
832 IWM_BARRIER_WRITE(sc); 832 IWM_BARRIER_WRITE(sc);
833 IWM_WRITE(sc, IWM_HBUS_TARG_PRPH_WDAT, val); 833 IWM_WRITE(sc, IWM_HBUS_TARG_PRPH_WDAT, val);
834} 834}
835 835
836#ifdef IWM_DEBUG 836#ifdef IWM_DEBUG
837/* iwlwifi: pcie/trans.c */ 837/* iwlwifi: pcie/trans.c */
838static int 838static int
839iwm_read_mem(struct iwm_softc *sc, uint32_t addr, void *buf, int dwords) 839iwm_read_mem(struct iwm_softc *sc, uint32_t addr, void *buf, int dwords)
840{ 840{
841 int offs, ret = 0; 841 int offs, ret = 0;
842 uint32_t *vals = buf; 842 uint32_t *vals = buf;
843 843
844 if (iwm_nic_lock(sc)) { 844 if (iwm_nic_lock(sc)) {
845 IWM_WRITE(sc, IWM_HBUS_TARG_MEM_RADDR, addr); 845 IWM_WRITE(sc, IWM_HBUS_TARG_MEM_RADDR, addr);
846 for (offs = 0; offs < dwords; offs++) 846 for (offs = 0; offs < dwords; offs++)
847 vals[offs] = IWM_READ(sc, IWM_HBUS_TARG_MEM_RDAT); 847 vals[offs] = IWM_READ(sc, IWM_HBUS_TARG_MEM_RDAT);
848 iwm_nic_unlock(sc); 848 iwm_nic_unlock(sc);
849 } else { 849 } else {
850 ret = EBUSY; 850 ret = EBUSY;
851 } 851 }
852 return ret; 852 return ret;
853} 853}
854#endif 854#endif
855 855
856/* iwlwifi: pcie/trans.c */ 856/* iwlwifi: pcie/trans.c */
857static int 857static int
858iwm_write_mem(struct iwm_softc *sc, uint32_t addr, const void *buf, int dwords) 858iwm_write_mem(struct iwm_softc *sc, uint32_t addr, const void *buf, int dwords)
859{ 859{
860 int offs; 860 int offs;
861 const uint32_t *vals = buf; 861 const uint32_t *vals = buf;
862 862
863 if (iwm_nic_lock(sc)) { 863 if (iwm_nic_lock(sc)) {
864 IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WADDR, addr); 864 IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WADDR, addr);
865 /* WADDR auto-increments */ 865 /* WADDR auto-increments */
866 for (offs = 0; offs < dwords; offs++) { 866 for (offs = 0; offs < dwords; offs++) {
867 uint32_t val = vals ? vals[offs] : 0; 867 uint32_t val = vals ? vals[offs] : 0;
868 IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WDAT, val); 868 IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WDAT, val);
869 } 869 }
870 iwm_nic_unlock(sc); 870 iwm_nic_unlock(sc);
871 } else { 871 } else {
872 DPRINTF(("%s: write_mem failed\n", DEVNAME(sc))); 872 DPRINTF(("%s: write_mem failed\n", DEVNAME(sc)));
873 return EBUSY; 873 return EBUSY;
874 } 874 }
875 return 0; 875 return 0;
876} 876}
877 877
878static int 878static int
879iwm_write_mem32(struct iwm_softc *sc, uint32_t addr, uint32_t val) 879iwm_write_mem32(struct iwm_softc *sc, uint32_t addr, uint32_t val)
880{ 880{
881 return iwm_write_mem(sc, addr, &val, 1); 881 return iwm_write_mem(sc, addr, &val, 1);
882} 882}
883 883
884static int 884static int
885iwm_poll_bit(struct iwm_softc *sc, int reg, 885iwm_poll_bit(struct iwm_softc *sc, int reg,
886 uint32_t bits, uint32_t mask, int timo) 886 uint32_t bits, uint32_t mask, int timo)
887{ 887{
888 for (;;) { 888 for (;;) {
889 if ((IWM_READ(sc, reg) & mask) == (bits & mask)) { 889 if ((IWM_READ(sc, reg) & mask) == (bits & mask)) {
890 return 1; 890 return 1;
891 } 891 }
892 if (timo < 10) { 892 if (timo < 10) {
893 return 0; 893 return 0;
894 } 894 }
895 timo -= 10; 895 timo -= 10;
896 DELAY(10); 896 DELAY(10);
897 } 897 }
898} 898}
899 899
900static int 900static int
901iwm_nic_lock(struct iwm_softc *sc) 901iwm_nic_lock(struct iwm_softc *sc)
902{ 902{
903 int rv = 0; 903 int rv = 0;
904 904
905 IWM_SETBITS(sc, IWM_CSR_GP_CNTRL, 905 IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
906 IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 906 IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
907 907
908 if (iwm_poll_bit(sc, IWM_CSR_GP_CNTRL, 908 if (iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
909 IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, 909 IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
910 IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY 910 IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
911 | IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP, 15000)) { 911 | IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP, 15000)) {
912 rv = 1; 912 rv = 1;
913 } else { 913 } else {
914 /* jolt */ 914 /* jolt */
915 IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_FORCE_NMI); 915 IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_FORCE_NMI);
916 } 916 }
917 917
918 return rv; 918 return rv;
919} 919}
920 920
921static void 921static void
922iwm_nic_unlock(struct iwm_softc *sc) 922iwm_nic_unlock(struct iwm_softc *sc)
923{ 923{
924 IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL, 924 IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
925 IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 925 IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
926} 926}
927 927
928static void 928static void
929iwm_set_bits_mask_prph(struct iwm_softc *sc, 929iwm_set_bits_mask_prph(struct iwm_softc *sc,
930 uint32_t reg, uint32_t bits, uint32_t mask) 930 uint32_t reg, uint32_t bits, uint32_t mask)
931{ 931{
932 uint32_t val; 932 uint32_t val;
933 933
934 /* XXX: no error path? */ 934 /* XXX: no error path? */
935 if (iwm_nic_lock(sc)) { 935 if (iwm_nic_lock(sc)) {
936 val = iwm_read_prph(sc, reg) & mask; 936 val = iwm_read_prph(sc, reg) & mask;
937 val |= bits; 937 val |= bits;
938 iwm_write_prph(sc, reg, val); 938 iwm_write_prph(sc, reg, val);
939 iwm_nic_unlock(sc); 939 iwm_nic_unlock(sc);
940 } 940 }
941} 941}
942 942
943static void 943static void
944iwm_set_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits) 944iwm_set_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits)
945{ 945{
946 iwm_set_bits_mask_prph(sc, reg, bits, ~0); 946 iwm_set_bits_mask_prph(sc, reg, bits, ~0);
947} 947}
948 948
949static void 949static void
950iwm_clear_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits) 950iwm_clear_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits)
951{ 951{
952 iwm_set_bits_mask_prph(sc, reg, 0, ~bits); 952 iwm_set_bits_mask_prph(sc, reg, 0, ~bits);
953} 953}
954 954
955/* 955/*
956 * DMA resource routines 956 * DMA resource routines
957 */ 957 */
958 958
959static int 959static int
960iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma, 960iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
961 bus_size_t size, bus_size_t alignment) 961 bus_size_t size, bus_size_t alignment)
962{ 962{
963 int nsegs, error; 963 int nsegs, error;
964 void *va; 964 void *va;
965 965
966 dma->tag = tag; 966 dma->tag = tag;
967 dma->size = size; 967 dma->size = size;
968 968
969 error = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT, 969 error = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT,
970 &dma->map); 970 &dma->map);
971 if (error != 0) 971 if (error != 0)
972 goto fail; 972 goto fail;
973 973
974 error = bus_dmamem_alloc(tag, size, alignment, 0, &dma->seg, 1, &nsegs, 974 error = bus_dmamem_alloc(tag, size, alignment, 0, &dma->seg, 1, &nsegs,
975 BUS_DMA_NOWAIT); 975 BUS_DMA_NOWAIT);
976 if (error != 0) 976 if (error != 0)
977 goto fail; 977 goto fail;
978 978
979 error = bus_dmamem_map(tag, &dma->seg, 1, size, &va, 979 error = bus_dmamem_map(tag, &dma->seg, 1, size, &va,
980 BUS_DMA_NOWAIT); 980 BUS_DMA_NOWAIT);
981 if (error != 0) 981 if (error != 0)
982 goto fail; 982 goto fail;
983 dma->vaddr = va; 983 dma->vaddr = va;
984 984
985 error = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL, 985 error = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
986 BUS_DMA_NOWAIT); 986 BUS_DMA_NOWAIT);
987 if (error != 0) 987 if (error != 0)
988 goto fail; 988 goto fail;
989 989
990 memset(dma->vaddr, 0, size); 990 memset(dma->vaddr, 0, size);
991 bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE); 991 bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
992 dma->paddr = dma->map->dm_segs[0].ds_addr; 992 dma->paddr = dma->map->dm_segs[0].ds_addr;
993 993
994 return 0; 994 return 0;
995 995
996fail: iwm_dma_contig_free(dma); 996fail: iwm_dma_contig_free(dma);
997 return error; 997 return error;
998} 998}
999 999
1000static void 1000static void
1001iwm_dma_contig_free(struct iwm_dma_info *dma) 1001iwm_dma_contig_free(struct iwm_dma_info *dma)
1002{ 1002{
1003 if (dma->map != NULL) { 1003 if (dma->map != NULL) {
1004 if (dma->vaddr != NULL) { 1004 if (dma->vaddr != NULL) {
1005 bus_dmamap_sync(dma->tag, dma->map, 0, dma->size, 1005 bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,
1006 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1006 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1007 bus_dmamap_unload(dma->tag, dma->map); 1007 bus_dmamap_unload(dma->tag, dma->map);
1008 bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size); 1008 bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size);
1009 bus_dmamem_free(dma->tag, &dma->seg, 1); 1009 bus_dmamem_free(dma->tag, &dma->seg, 1);
1010 dma->vaddr = NULL; 1010 dma->vaddr = NULL;
1011 } 1011 }
1012 bus_dmamap_destroy(dma->tag, dma->map); 1012 bus_dmamap_destroy(dma->tag, dma->map);
1013 dma->map = NULL; 1013 dma->map = NULL;
1014 } 1014 }
1015} 1015}
1016 1016
1017/* fwmem is used to load firmware onto the card */ 1017/* fwmem is used to load firmware onto the card */
1018static int 1018static int
1019iwm_alloc_fwmem(struct iwm_softc *sc) 1019iwm_alloc_fwmem(struct iwm_softc *sc)
1020{ 1020{
1021 /* Must be aligned on a 16-byte boundary. */ 1021 /* Must be aligned on a 16-byte boundary. */
1022 return iwm_dma_contig_alloc(sc->sc_dmat, &sc->fw_dma, 1022 return iwm_dma_contig_alloc(sc->sc_dmat, &sc->fw_dma,
1023 sc->sc_fwdmasegsz, 16); 1023 sc->sc_fwdmasegsz, 16);
1024} 1024}
1025 1025
1026static void 1026static void
1027iwm_free_fwmem(struct iwm_softc *sc) 1027iwm_free_fwmem(struct iwm_softc *sc)
1028{ 1028{
1029 iwm_dma_contig_free(&sc->fw_dma); 1029 iwm_dma_contig_free(&sc->fw_dma);
1030} 1030}
1031 1031
1032/* tx scheduler rings. not used? */ 1032/* tx scheduler rings. not used? */
1033static int 1033static int
1034iwm_alloc_sched(struct iwm_softc *sc) 1034iwm_alloc_sched(struct iwm_softc *sc)
1035{ 1035{
1036 int rv; 1036 int rv;
1037 1037
1038 /* TX scheduler rings must be aligned on a 1KB boundary. */ 1038 /* TX scheduler rings must be aligned on a 1KB boundary. */
1039 rv = iwm_dma_contig_alloc(sc->sc_dmat, &sc->sched_dma, 1039 rv = iwm_dma_contig_alloc(sc->sc_dmat, &sc->sched_dma,
1040 __arraycount(sc->txq) * sizeof(struct iwm_agn_scd_bc_tbl), 1024); 1040 __arraycount(sc->txq) * sizeof(struct iwm_agn_scd_bc_tbl), 1024);
1041 return rv; 1041 return rv;
1042} 1042}
1043 1043
1044static void 1044static void
1045iwm_free_sched(struct iwm_softc *sc) 1045iwm_free_sched(struct iwm_softc *sc)
1046{ 1046{
1047 iwm_dma_contig_free(&sc->sched_dma); 1047 iwm_dma_contig_free(&sc->sched_dma);
1048} 1048}
1049 1049
1050/* keep-warm page is used internally by the card. see iwl-fh.h for more info */ 1050/* keep-warm page is used internally by the card. see iwl-fh.h for more info */
1051static int 1051static int
1052iwm_alloc_kw(struct iwm_softc *sc) 1052iwm_alloc_kw(struct iwm_softc *sc)
1053{ 1053{
1054 return iwm_dma_contig_alloc(sc->sc_dmat, &sc->kw_dma, 4096, 4096); 1054 return iwm_dma_contig_alloc(sc->sc_dmat, &sc->kw_dma, 4096, 4096);
1055} 1055}
1056 1056
1057static void 1057static void
1058iwm_free_kw(struct iwm_softc *sc) 1058iwm_free_kw(struct iwm_softc *sc)
1059{ 1059{
1060 iwm_dma_contig_free(&sc->kw_dma); 1060 iwm_dma_contig_free(&sc->kw_dma);
1061} 1061}
1062 1062
1063/* interrupt cause table */ 1063/* interrupt cause table */
1064static int 1064static int
1065iwm_alloc_ict(struct iwm_softc *sc) 1065iwm_alloc_ict(struct iwm_softc *sc)
1066{ 1066{
1067 return iwm_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma, 1067 return iwm_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma,
1068 IWM_ICT_SIZE, 1<<IWM_ICT_PADDR_SHIFT); 1068 IWM_ICT_SIZE, 1<<IWM_ICT_PADDR_SHIFT);
1069} 1069}
1070 1070
1071static void 1071static void
1072iwm_free_ict(struct iwm_softc *sc) 1072iwm_free_ict(struct iwm_softc *sc)
1073{ 1073{
1074 iwm_dma_contig_free(&sc->ict_dma); 1074 iwm_dma_contig_free(&sc->ict_dma);
1075} 1075}
1076 1076
1077static int 1077static int
1078iwm_alloc_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring) 1078iwm_alloc_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
1079{ 1079{
1080 bus_size_t size; 1080 bus_size_t size;
1081 int i, error; 1081 int i, error;
1082 1082
1083 ring->cur = 0; 1083 ring->cur = 0;
1084 1084
1085 /* Allocate RX descriptors (256-byte aligned). */ 1085 /* Allocate RX descriptors (256-byte aligned). */
1086 size = IWM_RX_RING_COUNT * sizeof(uint32_t); 1086 size = IWM_RX_RING_COUNT * sizeof(uint32_t);
1087 error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256); 1087 error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256);
1088 if (error != 0) { 1088 if (error != 0) {
1089 aprint_error_dev(sc->sc_dev, 1089 aprint_error_dev(sc->sc_dev,
1090 "could not allocate RX ring DMA memory\n"); 1090 "could not allocate RX ring DMA memory\n");
1091 goto fail; 1091 goto fail;
1092 } 1092 }
1093 ring->desc = ring->desc_dma.vaddr; 1093 ring->desc = ring->desc_dma.vaddr;
1094 1094
1095 /* Allocate RX status area (16-byte aligned). */ 1095 /* Allocate RX status area (16-byte aligned). */
1096 error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma, 1096 error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma,
1097 sizeof(*ring->stat), 16); 1097 sizeof(*ring->stat), 16);
1098 if (error != 0) { 1098 if (error != 0) {
1099 aprint_error_dev(sc->sc_dev, 1099 aprint_error_dev(sc->sc_dev,
1100 "could not allocate RX status DMA memory\n"); 1100 "could not allocate RX status DMA memory\n");
1101 goto fail; 1101 goto fail;
1102 } 1102 }
1103 ring->stat = ring->stat_dma.vaddr; 1103 ring->stat = ring->stat_dma.vaddr;
1104 1104
1105 /* 1105 /*
1106 * Allocate and map RX buffers. 1106 * Allocate and map RX buffers.
1107 */ 1107 */
@@ -5620,1254 +5620,1259 @@ iwm_init_hw(struct iwm_softc *sc) @@ -5620,1254 +5620,1259 @@ iwm_init_hw(struct iwm_softc *sc)
5620 if ((error = iwm_preinit(sc)) != 0) 5620 if ((error = iwm_preinit(sc)) != 0)
5621 return error; 5621 return error;
5622 5622
5623 if ((error = iwm_start_hw(sc)) != 0) 5623 if ((error = iwm_start_hw(sc)) != 0)
5624 return error; 5624 return error;
5625 5625
5626 if ((error = iwm_run_init_mvm_ucode(sc, 0)) != 0) { 5626 if ((error = iwm_run_init_mvm_ucode(sc, 0)) != 0) {
5627 return error; 5627 return error;
5628 } 5628 }
5629 5629
5630 /* 5630 /*
5631 * should stop and start HW since that INIT 5631 * should stop and start HW since that INIT
5632 * image just loaded 5632 * image just loaded
5633 */ 5633 */
5634 iwm_stop_device(sc); 5634 iwm_stop_device(sc);
5635 if ((error = iwm_start_hw(sc)) != 0) { 5635 if ((error = iwm_start_hw(sc)) != 0) {
5636 aprint_error_dev(sc->sc_dev, "could not initialize hardware\n"); 5636 aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
5637 return error; 5637 return error;
5638 } 5638 }
5639 5639
5640 /* omstart, this time with the regular firmware */ 5640 /* omstart, this time with the regular firmware */
5641 error = iwm_mvm_load_ucode_wait_alive(sc, IWM_UCODE_TYPE_REGULAR); 5641 error = iwm_mvm_load_ucode_wait_alive(sc, IWM_UCODE_TYPE_REGULAR);
5642 if (error) { 5642 if (error) {
5643 aprint_error_dev(sc->sc_dev, "could not load firmware\n"); 5643 aprint_error_dev(sc->sc_dev, "could not load firmware\n");
5644 goto error; 5644 goto error;
5645 } 5645 }
5646 5646
5647 if ((error = iwm_send_tx_ant_cfg(sc, IWM_FW_VALID_TX_ANT(sc))) != 0) 5647 if ((error = iwm_send_tx_ant_cfg(sc, IWM_FW_VALID_TX_ANT(sc))) != 0)
5648 goto error; 5648 goto error;
5649 5649
5650 /* Send phy db control command and then phy db calibration*/ 5650 /* Send phy db control command and then phy db calibration*/
5651 if ((error = iwm_send_phy_db_data(sc)) != 0) 5651 if ((error = iwm_send_phy_db_data(sc)) != 0)
5652 goto error; 5652 goto error;
5653 5653
5654 if ((error = iwm_send_phy_cfg_cmd(sc)) != 0) 5654 if ((error = iwm_send_phy_cfg_cmd(sc)) != 0)
5655 goto error; 5655 goto error;
5656 5656
5657 /* Add auxiliary station for scanning */ 5657 /* Add auxiliary station for scanning */
5658 if ((error = iwm_mvm_add_aux_sta(sc)) != 0) 5658 if ((error = iwm_mvm_add_aux_sta(sc)) != 0)
5659 goto error; 5659 goto error;
5660 5660
5661 for (i = 0; i < IWM_NUM_PHY_CTX; i++) { 5661 for (i = 0; i < IWM_NUM_PHY_CTX; i++) {
5662 /* 5662 /*
5663 * The channel used here isn't relevant as it's 5663 * The channel used here isn't relevant as it's
5664 * going to be overwritten in the other flows. 5664 * going to be overwritten in the other flows.
5665 * For now use the first channel we have. 5665 * For now use the first channel we have.
5666 */ 5666 */
5667 if ((error = iwm_mvm_phy_ctxt_add(sc, 5667 if ((error = iwm_mvm_phy_ctxt_add(sc,
5668 &sc->sc_phyctxt[i], &ic->ic_channels[1], 1, 1)) != 0) 5668 &sc->sc_phyctxt[i], &ic->ic_channels[1], 1, 1)) != 0)
5669 goto error; 5669 goto error;
5670 } 5670 }
5671 5671
5672 error = iwm_mvm_power_update_device(sc); 5672 error = iwm_mvm_power_update_device(sc);
5673 if (error) 5673 if (error)
5674 goto error; 5674 goto error;
5675 5675
5676 /* Mark TX rings as active. */ 5676 /* Mark TX rings as active. */
5677 for (qid = 0; qid < 4; qid++) { 5677 for (qid = 0; qid < 4; qid++) {
5678 iwm_enable_txq(sc, qid, qid); 5678 iwm_enable_txq(sc, qid, qid);
5679 } 5679 }
5680 5680
5681 return 0; 5681 return 0;
5682 5682
5683 error: 5683 error:
5684 iwm_stop_device(sc); 5684 iwm_stop_device(sc);
5685 return error; 5685 return error;
5686} 5686}
5687 5687
5688/* Allow multicast from our BSSID. */ 5688/* Allow multicast from our BSSID. */
5689static int 5689static int
5690iwm_allow_mcast(struct iwm_softc *sc) 5690iwm_allow_mcast(struct iwm_softc *sc)
5691{ 5691{
5692 struct ieee80211com *ic = &sc->sc_ic; 5692 struct ieee80211com *ic = &sc->sc_ic;
5693 struct ieee80211_node *ni = ic->ic_bss; 5693 struct ieee80211_node *ni = ic->ic_bss;
5694 struct iwm_mcast_filter_cmd *cmd; 5694 struct iwm_mcast_filter_cmd *cmd;
5695 size_t size; 5695 size_t size;
5696 int error; 5696 int error;
5697 5697
5698 size = roundup(sizeof(*cmd), 4); 5698 size = roundup(sizeof(*cmd), 4);
5699 cmd = kmem_intr_zalloc(size, KM_NOSLEEP); 5699 cmd = kmem_intr_zalloc(size, KM_NOSLEEP);
5700 if (cmd == NULL) 5700 if (cmd == NULL)
5701 return ENOMEM; 5701 return ENOMEM;
5702 cmd->filter_own = 1; 5702 cmd->filter_own = 1;
5703 cmd->port_id = 0; 5703 cmd->port_id = 0;
5704 cmd->count = 0; 5704 cmd->count = 0;
5705 cmd->pass_all = 1; 5705 cmd->pass_all = 1;
5706 IEEE80211_ADDR_COPY(cmd->bssid, ni->ni_bssid); 5706 IEEE80211_ADDR_COPY(cmd->bssid, ni->ni_bssid);
5707 5707
5708 error = iwm_mvm_send_cmd_pdu(sc, IWM_MCAST_FILTER_CMD, 5708 error = iwm_mvm_send_cmd_pdu(sc, IWM_MCAST_FILTER_CMD,
5709 IWM_CMD_SYNC, size, cmd); 5709 IWM_CMD_SYNC, size, cmd);
5710 kmem_intr_free(cmd, size); 5710 kmem_intr_free(cmd, size);
5711 return error; 5711 return error;
5712} 5712}
5713 5713
5714/* 5714/*
5715 * ifnet interfaces 5715 * ifnet interfaces
5716 */ 5716 */
5717 5717
5718static int 5718static int
5719iwm_init(struct ifnet *ifp) 5719iwm_init(struct ifnet *ifp)
5720{ 5720{
5721 struct iwm_softc *sc = ifp->if_softc; 5721 struct iwm_softc *sc = ifp->if_softc;
5722 int error; 5722 int error;
5723 5723
5724 if (sc->sc_flags & IWM_FLAG_HW_INITED) { 5724 if (sc->sc_flags & IWM_FLAG_HW_INITED) {
5725 return 0; 5725 return 0;
5726 } 5726 }
5727 sc->sc_generation++; 5727 sc->sc_generation++;
5728 sc->sc_flags &= ~IWM_FLAG_STOPPED; 5728 sc->sc_flags &= ~IWM_FLAG_STOPPED;
5729 5729
5730 if ((error = iwm_init_hw(sc)) != 0) { 5730 if ((error = iwm_init_hw(sc)) != 0) {
5731 iwm_stop(ifp, 1); 5731 iwm_stop(ifp, 1);
5732 return error; 5732 return error;
5733 } 5733 }
5734 5734
5735 /* 5735 /*
5736 * Ok, firmware loaded and we are jogging 5736 * Ok, firmware loaded and we are jogging
5737 */ 5737 */
5738 5738
5739 ifp->if_flags &= ~IFF_OACTIVE; 5739 ifp->if_flags &= ~IFF_OACTIVE;
5740 ifp->if_flags |= IFF_RUNNING; 5740 ifp->if_flags |= IFF_RUNNING;
5741 5741
5742 ieee80211_begin_scan(&sc->sc_ic, 0); 5742 ieee80211_begin_scan(&sc->sc_ic, 0);
5743 sc->sc_flags |= IWM_FLAG_HW_INITED; 5743 sc->sc_flags |= IWM_FLAG_HW_INITED;
5744 5744
5745 return 0; 5745 return 0;
5746} 5746}
5747 5747
5748/* 5748/*
5749 * Dequeue packets from sendq and call send. 5749 * Dequeue packets from sendq and call send.
5750 * mostly from iwn 5750 * mostly from iwn
5751 */ 5751 */
5752static void 5752static void
5753iwm_start(struct ifnet *ifp) 5753iwm_start(struct ifnet *ifp)
5754{ 5754{
5755 struct iwm_softc *sc = ifp->if_softc; 5755 struct iwm_softc *sc = ifp->if_softc;
5756 struct ieee80211com *ic = &sc->sc_ic; 5756 struct ieee80211com *ic = &sc->sc_ic;
5757 struct ieee80211_node *ni; 5757 struct ieee80211_node *ni;
5758 struct ether_header *eh; 5758 struct ether_header *eh;
5759 struct mbuf *m; 5759 struct mbuf *m;
5760 int ac; 5760 int ac;
5761 5761
5762 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 5762 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
5763 return; 5763 return;
5764 5764
5765 for (;;) { 5765 for (;;) {
5766 /* why isn't this done per-queue? */ 5766 /* why isn't this done per-queue? */
5767 if (sc->qfullmsk != 0) { 5767 if (sc->qfullmsk != 0) {
5768 ifp->if_flags |= IFF_OACTIVE; 5768 ifp->if_flags |= IFF_OACTIVE;
5769 break; 5769 break;
5770 } 5770 }
5771 5771
5772 /* need to send management frames even if we're not RUNning */ 5772 /* need to send management frames even if we're not RUNning */
5773 IF_DEQUEUE(&ic->ic_mgtq, m); 5773 IF_DEQUEUE(&ic->ic_mgtq, m);
5774 if (m) { 5774 if (m) {
5775 ni = (void *)m->m_pkthdr.rcvif; 5775 ni = (void *)m->m_pkthdr.rcvif;
5776 ac = 0; 5776 ac = 0;
5777 goto sendit; 5777 goto sendit;
5778 } 5778 }
5779 if (ic->ic_state != IEEE80211_S_RUN) { 5779 if (ic->ic_state != IEEE80211_S_RUN) {
5780 break; 5780 break;
5781 } 5781 }
5782 5782
5783 IFQ_DEQUEUE(&ifp->if_snd, m); 5783 IFQ_DEQUEUE(&ifp->if_snd, m);
5784 if (!m) 5784 if (!m)
5785 break; 5785 break;
5786 if (m->m_len < sizeof (*eh) && 5786 if (m->m_len < sizeof (*eh) &&
5787 (m = m_pullup(m, sizeof (*eh))) == NULL) { 5787 (m = m_pullup(m, sizeof (*eh))) == NULL) {
5788 ifp->if_oerrors++; 5788 ifp->if_oerrors++;
5789 continue; 5789 continue;
5790 } 5790 }
5791 if (ifp->if_bpf != NULL) 5791 if (ifp->if_bpf != NULL)
5792 bpf_mtap(ifp, m); 5792 bpf_mtap(ifp, m);
5793 5793
5794 eh = mtod(m, struct ether_header *); 5794 eh = mtod(m, struct ether_header *);
5795 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 5795 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
5796 if (ni == NULL) { 5796 if (ni == NULL) {
5797 m_freem(m); 5797 m_freem(m);
5798 ifp->if_oerrors++; 5798 ifp->if_oerrors++;
5799 continue; 5799 continue;
5800 } 5800 }
5801 /* classify mbuf so we can find which tx ring to use */ 5801 /* classify mbuf so we can find which tx ring to use */
5802 if (ieee80211_classify(ic, m, ni) != 0) { 5802 if (ieee80211_classify(ic, m, ni) != 0) {
5803 m_freem(m); 5803 m_freem(m);
5804 ieee80211_free_node(ni); 5804 ieee80211_free_node(ni);
5805 ifp->if_oerrors++; 5805 ifp->if_oerrors++;
5806 continue; 5806 continue;
5807 } 5807 }
5808 5808
5809 /* No QoS encapsulation for EAPOL frames. */ 5809 /* No QoS encapsulation for EAPOL frames. */
5810 ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ? 5810 ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
5811 M_WME_GETAC(m) : WME_AC_BE; 5811 M_WME_GETAC(m) : WME_AC_BE;
5812 5812
5813 if ((m = ieee80211_encap(ic, m, ni)) == NULL) { 5813 if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
5814 ieee80211_free_node(ni); 5814 ieee80211_free_node(ni);
5815 ifp->if_oerrors++; 5815 ifp->if_oerrors++;
5816 continue; 5816 continue;
5817 } 5817 }
5818 5818
5819 sendit: 5819 sendit:
5820 if (ic->ic_rawbpf != NULL) 5820 if (ic->ic_rawbpf != NULL)
5821 bpf_mtap3(ic->ic_rawbpf, m); 5821 bpf_mtap3(ic->ic_rawbpf, m);
5822 if (iwm_tx(sc, m, ni, ac) != 0) { 5822 if (iwm_tx(sc, m, ni, ac) != 0) {
5823 ieee80211_free_node(ni); 5823 ieee80211_free_node(ni);
5824 ifp->if_oerrors++; 5824 ifp->if_oerrors++;
5825 continue; 5825 continue;
5826 } 5826 }
5827 5827
5828 if (ifp->if_flags & IFF_UP) { 5828 if (ifp->if_flags & IFF_UP) {
5829 sc->sc_tx_timer = 15; 5829 sc->sc_tx_timer = 15;
5830 ifp->if_timer = 1; 5830 ifp->if_timer = 1;
5831 } 5831 }
5832 } 5832 }
5833 5833
5834 return; 5834 return;
5835} 5835}
5836 5836
5837static void 5837static void
5838iwm_stop(struct ifnet *ifp, int disable) 5838iwm_stop(struct ifnet *ifp, int disable)
5839{ 5839{
5840 struct iwm_softc *sc = ifp->if_softc; 5840 struct iwm_softc *sc = ifp->if_softc;
5841 struct ieee80211com *ic = &sc->sc_ic; 5841 struct ieee80211com *ic = &sc->sc_ic;
5842 5842
5843 sc->sc_flags &= ~IWM_FLAG_HW_INITED; 5843 sc->sc_flags &= ~IWM_FLAG_HW_INITED;
5844 sc->sc_flags |= IWM_FLAG_STOPPED; 5844 sc->sc_flags |= IWM_FLAG_STOPPED;
5845 sc->sc_generation++; 5845 sc->sc_generation++;
5846 sc->sc_scanband = 0; 5846 sc->sc_scanband = 0;
5847 sc->sc_auth_prot = 0; 5847 sc->sc_auth_prot = 0;
5848 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 5848 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
5849 5849
5850 if (ic->ic_state != IEEE80211_S_INIT) 5850 if (ic->ic_state != IEEE80211_S_INIT)
5851 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 5851 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
5852 5852
5853 callout_stop(&sc->sc_calib_to); 5853 callout_stop(&sc->sc_calib_to);
5854 ifp->if_timer = sc->sc_tx_timer = 0; 5854 ifp->if_timer = sc->sc_tx_timer = 0;
5855 iwm_stop_device(sc); 5855 iwm_stop_device(sc);
5856} 5856}
5857 5857
5858static void 5858static void
5859iwm_watchdog(struct ifnet *ifp) 5859iwm_watchdog(struct ifnet *ifp)
5860{ 5860{
5861 struct iwm_softc *sc = ifp->if_softc; 5861 struct iwm_softc *sc = ifp->if_softc;
5862 5862
5863 ifp->if_timer = 0; 5863 ifp->if_timer = 0;
5864 if (sc->sc_tx_timer > 0) { 5864 if (sc->sc_tx_timer > 0) {
5865 if (--sc->sc_tx_timer == 0) { 5865 if (--sc->sc_tx_timer == 0) {
5866 aprint_error_dev(sc->sc_dev, "device timeout\n"); 5866 aprint_error_dev(sc->sc_dev, "device timeout\n");
5867#ifdef IWM_DEBUG 5867#ifdef IWM_DEBUG
5868 iwm_nic_error(sc); 5868 iwm_nic_error(sc);
5869#endif 5869#endif
5870 ifp->if_flags &= ~IFF_UP; 5870 ifp->if_flags &= ~IFF_UP;
5871 iwm_stop(ifp, 1); 5871 iwm_stop(ifp, 1);
5872 ifp->if_oerrors++; 5872 ifp->if_oerrors++;
5873 return; 5873 return;
5874 } 5874 }
5875 ifp->if_timer = 1; 5875 ifp->if_timer = 1;
5876 } 5876 }
5877 5877
5878 ieee80211_watchdog(&sc->sc_ic); 5878 ieee80211_watchdog(&sc->sc_ic);
5879} 5879}
5880 5880
5881static int 5881static int
5882iwm_ioctl(struct ifnet *ifp, u_long cmd, void *data) 5882iwm_ioctl(struct ifnet *ifp, u_long cmd, void *data)
5883{ 5883{
5884 struct iwm_softc *sc = ifp->if_softc; 5884 struct iwm_softc *sc = ifp->if_softc;
5885 struct ieee80211com *ic = &sc->sc_ic; 5885 struct ieee80211com *ic = &sc->sc_ic;
5886 const struct sockaddr *sa; 5886 const struct sockaddr *sa;
5887 int s, error = 0; 5887 int s, error = 0;
5888 5888
5889 s = splnet(); 5889 s = splnet();
5890 5890
5891 switch (cmd) { 5891 switch (cmd) {
5892 case SIOCSIFADDR: 5892 case SIOCSIFADDR:
5893 ifp->if_flags |= IFF_UP; 5893 ifp->if_flags |= IFF_UP;
5894 /* FALLTHROUGH */ 5894 /* FALLTHROUGH */
5895 case SIOCSIFFLAGS: 5895 case SIOCSIFFLAGS:
5896 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 5896 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
5897 break; 5897 break;
5898 if (ifp->if_flags & IFF_UP) { 5898 if (ifp->if_flags & IFF_UP) {
5899 if (!(ifp->if_flags & IFF_RUNNING)) { 5899 if (!(ifp->if_flags & IFF_RUNNING)) {
5900 if ((error = iwm_init(ifp)) != 0) 5900 if ((error = iwm_init(ifp)) != 0)
5901 ifp->if_flags &= ~IFF_UP; 5901 ifp->if_flags &= ~IFF_UP;
5902 } 5902 }
5903 } else { 5903 } else {
5904 if (ifp->if_flags & IFF_RUNNING) 5904 if (ifp->if_flags & IFF_RUNNING)
5905 iwm_stop(ifp, 1); 5905 iwm_stop(ifp, 1);
5906 } 5906 }
5907 break; 5907 break;
5908 5908
5909 case SIOCADDMULTI: 5909 case SIOCADDMULTI:
5910 case SIOCDELMULTI: 5910 case SIOCDELMULTI:
5911 sa = ifreq_getaddr(SIOCADDMULTI, (struct ifreq *)data); 5911 sa = ifreq_getaddr(SIOCADDMULTI, (struct ifreq *)data);
5912 error = (cmd == SIOCADDMULTI) ? 5912 error = (cmd == SIOCADDMULTI) ?
5913 ether_addmulti(sa, &sc->sc_ec) : 5913 ether_addmulti(sa, &sc->sc_ec) :
5914 ether_delmulti(sa, &sc->sc_ec); 5914 ether_delmulti(sa, &sc->sc_ec);
5915 5915
5916 if (error == ENETRESET) 5916 if (error == ENETRESET)
5917 error = 0; 5917 error = 0;
5918 break; 5918 break;
5919 5919
5920 default: 5920 default:
5921 error = ieee80211_ioctl(ic, cmd, data); 5921 error = ieee80211_ioctl(ic, cmd, data);
5922 } 5922 }
5923 5923
5924 if (error == ENETRESET) { 5924 if (error == ENETRESET) {
5925 error = 0; 5925 error = 0;
5926 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 5926 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
5927 (IFF_UP | IFF_RUNNING)) { 5927 (IFF_UP | IFF_RUNNING)) {
5928 iwm_stop(ifp, 0); 5928 iwm_stop(ifp, 0);
5929 error = iwm_init(ifp); 5929 error = iwm_init(ifp);
5930 } 5930 }
5931 } 5931 }
5932 5932
5933 splx(s); 5933 splx(s);
5934 return error; 5934 return error;
5935} 5935}
5936 5936
5937/* 5937/*
5938 * The interrupt side of things 5938 * The interrupt side of things
5939 */ 5939 */
5940 5940
5941/* 5941/*
5942 * error dumping routines are from iwlwifi/mvm/utils.c 5942 * error dumping routines are from iwlwifi/mvm/utils.c
5943 */ 5943 */
5944 5944
5945/* 5945/*
5946 * Note: This structure is read from the device with IO accesses, 5946 * Note: This structure is read from the device with IO accesses,
5947 * and the reading already does the endian conversion. As it is 5947 * and the reading already does the endian conversion. As it is
5948 * read with uint32_t-sized accesses, any members with a different size 5948 * read with uint32_t-sized accesses, any members with a different size
5949 * need to be ordered correctly though! 5949 * need to be ordered correctly though!
5950 */ 5950 */
5951struct iwm_error_event_table { 5951struct iwm_error_event_table {
5952 uint32_t valid; /* (nonzero) valid, (0) log is empty */ 5952 uint32_t valid; /* (nonzero) valid, (0) log is empty */
5953 uint32_t error_id; /* type of error */ 5953 uint32_t error_id; /* type of error */
5954 uint32_t pc; /* program counter */ 5954 uint32_t pc; /* program counter */
5955 uint32_t blink1; /* branch link */ 5955 uint32_t blink1; /* branch link */
5956 uint32_t blink2; /* branch link */ 5956 uint32_t blink2; /* branch link */
5957 uint32_t ilink1; /* interrupt link */ 5957 uint32_t ilink1; /* interrupt link */
5958 uint32_t ilink2; /* interrupt link */ 5958 uint32_t ilink2; /* interrupt link */
5959 uint32_t data1; /* error-specific data */ 5959 uint32_t data1; /* error-specific data */
5960 uint32_t data2; /* error-specific data */ 5960 uint32_t data2; /* error-specific data */
5961 uint32_t data3; /* error-specific data */ 5961 uint32_t data3; /* error-specific data */
5962 uint32_t bcon_time; /* beacon timer */ 5962 uint32_t bcon_time; /* beacon timer */
5963 uint32_t tsf_low; /* network timestamp function timer */ 5963 uint32_t tsf_low; /* network timestamp function timer */
5964 uint32_t tsf_hi; /* network timestamp function timer */ 5964 uint32_t tsf_hi; /* network timestamp function timer */
5965 uint32_t gp1; /* GP1 timer register */ 5965 uint32_t gp1; /* GP1 timer register */
5966 uint32_t gp2; /* GP2 timer register */ 5966 uint32_t gp2; /* GP2 timer register */
5967 uint32_t gp3; /* GP3 timer register */ 5967 uint32_t gp3; /* GP3 timer register */
5968 uint32_t ucode_ver; /* uCode version */ 5968 uint32_t ucode_ver; /* uCode version */
5969 uint32_t hw_ver; /* HW Silicon version */ 5969 uint32_t hw_ver; /* HW Silicon version */
5970 uint32_t brd_ver; /* HW board version */ 5970 uint32_t brd_ver; /* HW board version */
5971 uint32_t log_pc; /* log program counter */ 5971 uint32_t log_pc; /* log program counter */
5972 uint32_t frame_ptr; /* frame pointer */ 5972 uint32_t frame_ptr; /* frame pointer */
5973 uint32_t stack_ptr; /* stack pointer */ 5973 uint32_t stack_ptr; /* stack pointer */
5974 uint32_t hcmd; /* last host command header */ 5974 uint32_t hcmd; /* last host command header */
5975 uint32_t isr0; /* isr status register LMPM_NIC_ISR0: 5975 uint32_t isr0; /* isr status register LMPM_NIC_ISR0:
5976 * rxtx_flag */ 5976 * rxtx_flag */
5977 uint32_t isr1; /* isr status register LMPM_NIC_ISR1: 5977 uint32_t isr1; /* isr status register LMPM_NIC_ISR1:
5978 * host_flag */ 5978 * host_flag */
5979 uint32_t isr2; /* isr status register LMPM_NIC_ISR2: 5979 uint32_t isr2; /* isr status register LMPM_NIC_ISR2:
5980 * enc_flag */ 5980 * enc_flag */
5981 uint32_t isr3; /* isr status register LMPM_NIC_ISR3: 5981 uint32_t isr3; /* isr status register LMPM_NIC_ISR3:
5982 * time_flag */ 5982 * time_flag */
5983 uint32_t isr4; /* isr status register LMPM_NIC_ISR4: 5983 uint32_t isr4; /* isr status register LMPM_NIC_ISR4:
5984 * wico interrupt */ 5984 * wico interrupt */
5985 uint32_t isr_pref; /* isr status register LMPM_NIC_PREF_STAT */ 5985 uint32_t isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
5986 uint32_t wait_event; /* wait event() caller address */ 5986 uint32_t wait_event; /* wait event() caller address */
5987 uint32_t l2p_control; /* L2pControlField */ 5987 uint32_t l2p_control; /* L2pControlField */
5988 uint32_t l2p_duration; /* L2pDurationField */ 5988 uint32_t l2p_duration; /* L2pDurationField */
5989 uint32_t l2p_mhvalid; /* L2pMhValidBits */ 5989 uint32_t l2p_mhvalid; /* L2pMhValidBits */
5990 uint32_t l2p_addr_match; /* L2pAddrMatchStat */ 5990 uint32_t l2p_addr_match; /* L2pAddrMatchStat */
5991 uint32_t lmpm_pmg_sel; /* indicate which clocks are turned on 5991 uint32_t lmpm_pmg_sel; /* indicate which clocks are turned on
5992 * (LMPM_PMG_SEL) */ 5992 * (LMPM_PMG_SEL) */
5993 uint32_t u_timestamp; /* indicate when the date and time of the 5993 uint32_t u_timestamp; /* indicate when the date and time of the
5994 * compilation */ 5994 * compilation */
5995 uint32_t flow_handler; /* FH read/write pointers, RX credit */ 5995 uint32_t flow_handler; /* FH read/write pointers, RX credit */
5996} __packed; 5996} __packed;
5997 5997
5998#define ERROR_START_OFFSET (1 * sizeof(uint32_t)) 5998#define ERROR_START_OFFSET (1 * sizeof(uint32_t))
5999#define ERROR_ELEM_SIZE (7 * sizeof(uint32_t)) 5999#define ERROR_ELEM_SIZE (7 * sizeof(uint32_t))
6000 6000
6001#ifdef IWM_DEBUG 6001#ifdef IWM_DEBUG
6002static const struct { 6002static const struct {
6003 const char *name; 6003 const char *name;
6004 uint8_t num; 6004 uint8_t num;
6005} advanced_lookup[] = { 6005} advanced_lookup[] = {
6006 { "NMI_INTERRUPT_WDG", 0x34 }, 6006 { "NMI_INTERRUPT_WDG", 0x34 },
6007 { "SYSASSERT", 0x35 }, 6007 { "SYSASSERT", 0x35 },
6008 { "UCODE_VERSION_MISMATCH", 0x37 }, 6008 { "UCODE_VERSION_MISMATCH", 0x37 },
6009 { "BAD_COMMAND", 0x38 }, 6009 { "BAD_COMMAND", 0x38 },
6010 { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C }, 6010 { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
6011 { "FATAL_ERROR", 0x3D }, 6011 { "FATAL_ERROR", 0x3D },
6012 { "NMI_TRM_HW_ERR", 0x46 }, 6012 { "NMI_TRM_HW_ERR", 0x46 },
6013 { "NMI_INTERRUPT_TRM", 0x4C }, 6013 { "NMI_INTERRUPT_TRM", 0x4C },
6014 { "NMI_INTERRUPT_BREAK_POINT", 0x54 }, 6014 { "NMI_INTERRUPT_BREAK_POINT", 0x54 },
6015 { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C }, 6015 { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
6016 { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 }, 6016 { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
6017 { "NMI_INTERRUPT_HOST", 0x66 }, 6017 { "NMI_INTERRUPT_HOST", 0x66 },
6018 { "NMI_INTERRUPT_ACTION_PT", 0x7C }, 6018 { "NMI_INTERRUPT_ACTION_PT", 0x7C },
6019 { "NMI_INTERRUPT_UNKNOWN", 0x84 }, 6019 { "NMI_INTERRUPT_UNKNOWN", 0x84 },
6020 { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 }, 6020 { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
6021 { "ADVANCED_SYSASSERT", 0 }, 6021 { "ADVANCED_SYSASSERT", 0 },
6022}; 6022};
6023 6023
6024static const char * 6024static const char *
6025iwm_desc_lookup(uint32_t num) 6025iwm_desc_lookup(uint32_t num)
6026{ 6026{
6027 int i; 6027 int i;
6028 6028
6029 for (i = 0; i < __arraycount(advanced_lookup) - 1; i++) 6029 for (i = 0; i < __arraycount(advanced_lookup) - 1; i++)
6030 if (advanced_lookup[i].num == num) 6030 if (advanced_lookup[i].num == num)
6031 return advanced_lookup[i].name; 6031 return advanced_lookup[i].name;
6032 6032
6033 /* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */ 6033 /* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */
6034 return advanced_lookup[i].name; 6034 return advanced_lookup[i].name;
6035} 6035}
6036 6036
6037/* 6037/*
6038 * Support for dumping the error log seemed like a good idea ... 6038 * Support for dumping the error log seemed like a good idea ...
6039 * but it's mostly hex junk and the only sensible thing is the 6039 * but it's mostly hex junk and the only sensible thing is the
6040 * hw/ucode revision (which we know anyway). Since it's here, 6040 * hw/ucode revision (which we know anyway). Since it's here,
6041 * I'll just leave it in, just in case e.g. the Intel guys want to 6041 * I'll just leave it in, just in case e.g. the Intel guys want to
6042 * help us decipher some "ADVANCED_SYSASSERT" later. 6042 * help us decipher some "ADVANCED_SYSASSERT" later.
6043 */ 6043 */
6044static void 6044static void
6045iwm_nic_error(struct iwm_softc *sc) 6045iwm_nic_error(struct iwm_softc *sc)
6046{ 6046{
6047 struct iwm_error_event_table table; 6047 struct iwm_error_event_table table;
6048 uint32_t base; 6048 uint32_t base;
6049 6049
6050 aprint_error_dev(sc->sc_dev, "dumping device error log\n"); 6050 aprint_error_dev(sc->sc_dev, "dumping device error log\n");
6051 base = sc->sc_uc.uc_error_event_table; 6051 base = sc->sc_uc.uc_error_event_table;
6052 if (base < 0x800000 || base >= 0x80C000) { 6052 if (base < 0x800000 || base >= 0x80C000) {
6053 aprint_error_dev(sc->sc_dev, 6053 aprint_error_dev(sc->sc_dev,
6054 "Not valid error log pointer 0x%08x\n", base); 6054 "Not valid error log pointer 0x%08x\n", base);
6055 return; 6055 return;
6056 } 6056 }
6057 6057
6058 if (iwm_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t)) != 0) { 6058 if (iwm_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t)) != 0) {
6059 aprint_error_dev(sc->sc_dev, "reading errlog failed\n"); 6059 aprint_error_dev(sc->sc_dev, "reading errlog failed\n");
6060 return; 6060 return;
6061 } 6061 }
6062 6062
6063 if (!table.valid) { 6063 if (!table.valid) {
6064 aprint_error_dev(sc->sc_dev, "errlog not found, skipping\n"); 6064 aprint_error_dev(sc->sc_dev, "errlog not found, skipping\n");
6065 return; 6065 return;
6066 } 6066 }
6067 6067
6068 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { 6068 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
6069 aprint_error_dev(sc->sc_dev, "Start IWL Error Log Dump:\n"); 6069 aprint_error_dev(sc->sc_dev, "Start IWL Error Log Dump:\n");
6070 aprint_error_dev(sc->sc_dev, "Status: 0x%x, count: %d\n", 6070 aprint_error_dev(sc->sc_dev, "Status: 0x%x, count: %d\n",
6071 sc->sc_flags, table.valid); 6071 sc->sc_flags, table.valid);
6072 } 6072 }
6073 6073
6074 aprint_error_dev(sc->sc_dev, "%08X | %-28s\n", table.error_id, 6074 aprint_error_dev(sc->sc_dev, "%08X | %-28s\n", table.error_id,
6075 iwm_desc_lookup(table.error_id)); 6075 iwm_desc_lookup(table.error_id));
6076 aprint_error_dev(sc->sc_dev, "%08X | uPc\n", table.pc); 6076 aprint_error_dev(sc->sc_dev, "%08X | uPc\n", table.pc);
6077 aprint_error_dev(sc->sc_dev, "%08X | branchlink1\n", table.blink1); 6077 aprint_error_dev(sc->sc_dev, "%08X | branchlink1\n", table.blink1);
6078 aprint_error_dev(sc->sc_dev, "%08X | branchlink2\n", table.blink2); 6078 aprint_error_dev(sc->sc_dev, "%08X | branchlink2\n", table.blink2);
6079 aprint_error_dev(sc->sc_dev, "%08X | interruptlink1\n", table.ilink1); 6079 aprint_error_dev(sc->sc_dev, "%08X | interruptlink1\n", table.ilink1);
6080 aprint_error_dev(sc->sc_dev, "%08X | interruptlink2\n", table.ilink2); 6080 aprint_error_dev(sc->sc_dev, "%08X | interruptlink2\n", table.ilink2);
6081 aprint_error_dev(sc->sc_dev, "%08X | data1\n", table.data1); 6081 aprint_error_dev(sc->sc_dev, "%08X | data1\n", table.data1);
6082 aprint_error_dev(sc->sc_dev, "%08X | data2\n", table.data2); 6082 aprint_error_dev(sc->sc_dev, "%08X | data2\n", table.data2);
6083 aprint_error_dev(sc->sc_dev, "%08X | data3\n", table.data3); 6083 aprint_error_dev(sc->sc_dev, "%08X | data3\n", table.data3);
6084 aprint_error_dev(sc->sc_dev, "%08X | beacon time\n", table.bcon_time); 6084 aprint_error_dev(sc->sc_dev, "%08X | beacon time\n", table.bcon_time);
6085 aprint_error_dev(sc->sc_dev, "%08X | tsf low\n", table.tsf_low); 6085 aprint_error_dev(sc->sc_dev, "%08X | tsf low\n", table.tsf_low);
6086 aprint_error_dev(sc->sc_dev, "%08X | tsf hi\n", table.tsf_hi); 6086 aprint_error_dev(sc->sc_dev, "%08X | tsf hi\n", table.tsf_hi);
6087 aprint_error_dev(sc->sc_dev, "%08X | time gp1\n", table.gp1); 6087 aprint_error_dev(sc->sc_dev, "%08X | time gp1\n", table.gp1);
6088 aprint_error_dev(sc->sc_dev, "%08X | time gp2\n", table.gp2); 6088 aprint_error_dev(sc->sc_dev, "%08X | time gp2\n", table.gp2);
6089 aprint_error_dev(sc->sc_dev, "%08X | time gp3\n", table.gp3); 6089 aprint_error_dev(sc->sc_dev, "%08X | time gp3\n", table.gp3);
6090 aprint_error_dev(sc->sc_dev, "%08X | uCode version\n", table.ucode_ver); 6090 aprint_error_dev(sc->sc_dev, "%08X | uCode version\n", table.ucode_ver);
6091 aprint_error_dev(sc->sc_dev, "%08X | hw version\n", table.hw_ver); 6091 aprint_error_dev(sc->sc_dev, "%08X | hw version\n", table.hw_ver);
6092 aprint_error_dev(sc->sc_dev, "%08X | board version\n", table.brd_ver); 6092 aprint_error_dev(sc->sc_dev, "%08X | board version\n", table.brd_ver);
6093 aprint_error_dev(sc->sc_dev, "%08X | hcmd\n", table.hcmd); 6093 aprint_error_dev(sc->sc_dev, "%08X | hcmd\n", table.hcmd);
6094 aprint_error_dev(sc->sc_dev, "%08X | isr0\n", table.isr0); 6094 aprint_error_dev(sc->sc_dev, "%08X | isr0\n", table.isr0);
6095 aprint_error_dev(sc->sc_dev, "%08X | isr1\n", table.isr1); 6095 aprint_error_dev(sc->sc_dev, "%08X | isr1\n", table.isr1);
6096 aprint_error_dev(sc->sc_dev, "%08X | isr2\n", table.isr2); 6096 aprint_error_dev(sc->sc_dev, "%08X | isr2\n", table.isr2);
6097 aprint_error_dev(sc->sc_dev, "%08X | isr3\n", table.isr3); 6097 aprint_error_dev(sc->sc_dev, "%08X | isr3\n", table.isr3);
6098 aprint_error_dev(sc->sc_dev, "%08X | isr4\n", table.isr4); 6098 aprint_error_dev(sc->sc_dev, "%08X | isr4\n", table.isr4);
6099 aprint_error_dev(sc->sc_dev, "%08X | isr_pref\n", table.isr_pref); 6099 aprint_error_dev(sc->sc_dev, "%08X | isr_pref\n", table.isr_pref);
6100 aprint_error_dev(sc->sc_dev, "%08X | wait_event\n", table.wait_event); 6100 aprint_error_dev(sc->sc_dev, "%08X | wait_event\n", table.wait_event);
6101 aprint_error_dev(sc->sc_dev, "%08X | l2p_control\n", table.l2p_control); 6101 aprint_error_dev(sc->sc_dev, "%08X | l2p_control\n", table.l2p_control);
6102 aprint_error_dev(sc->sc_dev, "%08X | l2p_duration\n", 6102 aprint_error_dev(sc->sc_dev, "%08X | l2p_duration\n",
6103 table.l2p_duration); 6103 table.l2p_duration);
6104 aprint_error_dev(sc->sc_dev, "%08X | l2p_mhvalid\n", table.l2p_mhvalid); 6104 aprint_error_dev(sc->sc_dev, "%08X | l2p_mhvalid\n", table.l2p_mhvalid);
6105 aprint_error_dev(sc->sc_dev, "%08X | l2p_addr_match\n", 6105 aprint_error_dev(sc->sc_dev, "%08X | l2p_addr_match\n",
6106 table.l2p_addr_match); 6106 table.l2p_addr_match);
6107 aprint_error_dev(sc->sc_dev, "%08X | lmpm_pmg_sel\n", 6107 aprint_error_dev(sc->sc_dev, "%08X | lmpm_pmg_sel\n",
6108 table.lmpm_pmg_sel); 6108 table.lmpm_pmg_sel);
6109 aprint_error_dev(sc->sc_dev, "%08X | timestamp\n", table.u_timestamp); 6109 aprint_error_dev(sc->sc_dev, "%08X | timestamp\n", table.u_timestamp);
6110 aprint_error_dev(sc->sc_dev, "%08X | flow_handler\n", 6110 aprint_error_dev(sc->sc_dev, "%08X | flow_handler\n",
6111 table.flow_handler); 6111 table.flow_handler);
6112} 6112}
6113#endif 6113#endif
6114 6114
6115#define SYNC_RESP_STRUCT(_var_, _pkt_) \ 6115#define SYNC_RESP_STRUCT(_var_, _pkt_) \
6116do { \ 6116do { \
6117 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*(_pkt_)), \ 6117 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*(_pkt_)), \
6118 sizeof(*(_var_)), BUS_DMASYNC_POSTREAD); \ 6118 sizeof(*(_var_)), BUS_DMASYNC_POSTREAD); \
6119 _var_ = (void *)((_pkt_)+1); \ 6119 _var_ = (void *)((_pkt_)+1); \
6120} while (/*CONSTCOND*/0) 6120} while (/*CONSTCOND*/0)
6121 6121
6122#define SYNC_RESP_PTR(_ptr_, _len_, _pkt_) \ 6122#define SYNC_RESP_PTR(_ptr_, _len_, _pkt_) \
6123do { \ 6123do { \
6124 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*(_pkt_)), \ 6124 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*(_pkt_)), \
6125 sizeof(len), BUS_DMASYNC_POSTREAD); \ 6125 sizeof(len), BUS_DMASYNC_POSTREAD); \
6126 _ptr_ = (void *)((_pkt_)+1); \ 6126 _ptr_ = (void *)((_pkt_)+1); \
6127} while (/*CONSTCOND*/0) 6127} while (/*CONSTCOND*/0)
6128 6128
6129#define ADVANCE_RXQ(sc) (sc->rxq.cur = (sc->rxq.cur + 1) % IWM_RX_RING_COUNT); 6129#define ADVANCE_RXQ(sc) (sc->rxq.cur = (sc->rxq.cur + 1) % IWM_RX_RING_COUNT);
6130 6130
6131/* 6131/*
6132 * Process an IWM_CSR_INT_BIT_FH_RX or IWM_CSR_INT_BIT_SW_RX interrupt. 6132 * Process an IWM_CSR_INT_BIT_FH_RX or IWM_CSR_INT_BIT_SW_RX interrupt.
6133 * Basic structure from if_iwn 6133 * Basic structure from if_iwn
6134 */ 6134 */
6135static void 6135static void
6136iwm_notif_intr(struct iwm_softc *sc) 6136iwm_notif_intr(struct iwm_softc *sc)
6137{ 6137{
6138 uint16_t hw; 6138 uint16_t hw;
6139 6139
6140 bus_dmamap_sync(sc->sc_dmat, sc->rxq.stat_dma.map, 6140 bus_dmamap_sync(sc->sc_dmat, sc->rxq.stat_dma.map,
6141 0, sc->rxq.stat_dma.size, BUS_DMASYNC_POSTREAD); 6141 0, sc->rxq.stat_dma.size, BUS_DMASYNC_POSTREAD);
6142 6142
6143 hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff; 6143 hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff;
6144 while (sc->rxq.cur != hw) { 6144 while (sc->rxq.cur != hw) {
6145 struct iwm_rx_data *data = &sc->rxq.data[sc->rxq.cur]; 6145 struct iwm_rx_data *data = &sc->rxq.data[sc->rxq.cur];
6146 struct iwm_rx_packet *pkt, tmppkt; 6146 struct iwm_rx_packet *pkt, tmppkt;
6147 struct iwm_cmd_response *cresp; 6147 struct iwm_cmd_response *cresp;
6148 int qid, idx; 6148 int qid, idx;
6149 6149
6150 bus_dmamap_sync(sc->sc_dmat, data->map, 0, sizeof(*pkt), 6150 bus_dmamap_sync(sc->sc_dmat, data->map, 0, sizeof(*pkt),
6151 BUS_DMASYNC_POSTREAD); 6151 BUS_DMASYNC_POSTREAD);
6152 pkt = mtod(data->m, struct iwm_rx_packet *); 6152 pkt = mtod(data->m, struct iwm_rx_packet *);
6153 6153
6154 qid = pkt->hdr.qid & ~0x80; 6154 qid = pkt->hdr.qid & ~0x80;
6155 idx = pkt->hdr.idx; 6155 idx = pkt->hdr.idx;
6156 6156
6157 DPRINTFN(12, ("rx packet qid=%d idx=%d flags=%x type=%x %d %d\n", 6157 DPRINTFN(12, ("rx packet qid=%d idx=%d flags=%x type=%x %d %d\n",
6158 pkt->hdr.qid & ~0x80, pkt->hdr.idx, pkt->hdr.flags, 6158 pkt->hdr.qid & ~0x80, pkt->hdr.idx, pkt->hdr.flags,
6159 pkt->hdr.code, sc->rxq.cur, hw)); 6159 pkt->hdr.code, sc->rxq.cur, hw));
6160 6160
6161 /* 6161 /*
6162 * randomly get these from the firmware, no idea why. 6162 * randomly get these from the firmware, no idea why.
6163 * they at least seem harmless, so just ignore them for now 6163 * they at least seem harmless, so just ignore them for now
6164 */ 6164 */
6165 if (__predict_false((pkt->hdr.code == 0 && qid == 0 && idx == 0) 6165 if (__predict_false((pkt->hdr.code == 0 && qid == 0 && idx == 0)
6166 || pkt->len_n_flags == htole32(0x55550000))) { 6166 || pkt->len_n_flags == htole32(0x55550000))) {
6167 ADVANCE_RXQ(sc); 6167 ADVANCE_RXQ(sc);
6168 continue; 6168 continue;
6169 } 6169 }
6170 6170
6171 switch (pkt->hdr.code) { 6171 switch (pkt->hdr.code) {
6172 case IWM_REPLY_RX_PHY_CMD: 6172 case IWM_REPLY_RX_PHY_CMD:
6173 iwm_mvm_rx_rx_phy_cmd(sc, pkt, data); 6173 iwm_mvm_rx_rx_phy_cmd(sc, pkt, data);
6174 break; 6174 break;
6175 6175
6176 case IWM_REPLY_RX_MPDU_CMD: 6176 case IWM_REPLY_RX_MPDU_CMD:
6177 tmppkt = *pkt; // XXX m is freed by ieee80211_input() 6177 tmppkt = *pkt; // XXX m is freed by ieee80211_input()
6178 iwm_mvm_rx_rx_mpdu(sc, pkt, data); 6178 iwm_mvm_rx_rx_mpdu(sc, pkt, data);
6179 pkt = &tmppkt; 6179 pkt = &tmppkt;
6180 break; 6180 break;
6181 6181
6182 case IWM_TX_CMD: 6182 case IWM_TX_CMD:
6183 iwm_mvm_rx_tx_cmd(sc, pkt, data); 6183 iwm_mvm_rx_tx_cmd(sc, pkt, data);
6184 break; 6184 break;
6185 6185
6186 case IWM_MISSED_BEACONS_NOTIFICATION: 6186 case IWM_MISSED_BEACONS_NOTIFICATION:
6187 iwm_mvm_rx_missed_beacons_notif(sc, pkt, data); 6187 iwm_mvm_rx_missed_beacons_notif(sc, pkt, data);
6188 break; 6188 break;
6189 6189
6190 case IWM_MVM_ALIVE: { 6190 case IWM_MVM_ALIVE: {
6191 struct iwm_mvm_alive_resp *resp; 6191 struct iwm_mvm_alive_resp *resp;
6192 SYNC_RESP_STRUCT(resp, pkt); 6192 SYNC_RESP_STRUCT(resp, pkt);
6193 6193
6194 sc->sc_uc.uc_error_event_table 6194 sc->sc_uc.uc_error_event_table
6195 = le32toh(resp->error_event_table_ptr); 6195 = le32toh(resp->error_event_table_ptr);
6196 sc->sc_uc.uc_log_event_table 6196 sc->sc_uc.uc_log_event_table
6197 = le32toh(resp->log_event_table_ptr); 6197 = le32toh(resp->log_event_table_ptr);
6198 sc->sched_base = le32toh(resp->scd_base_ptr); 6198 sc->sched_base = le32toh(resp->scd_base_ptr);
6199 sc->sc_uc.uc_ok = resp->status == IWM_ALIVE_STATUS_OK; 6199 sc->sc_uc.uc_ok = resp->status == IWM_ALIVE_STATUS_OK;
6200 6200
6201 sc->sc_uc.uc_intr = 1; 6201 sc->sc_uc.uc_intr = 1;
6202 wakeup(&sc->sc_uc); 6202 wakeup(&sc->sc_uc);
6203 break; } 6203 break; }
6204 6204
6205 case IWM_CALIB_RES_NOTIF_PHY_DB: { 6205 case IWM_CALIB_RES_NOTIF_PHY_DB: {
6206 struct iwm_calib_res_notif_phy_db *phy_db_notif; 6206 struct iwm_calib_res_notif_phy_db *phy_db_notif;
6207 SYNC_RESP_STRUCT(phy_db_notif, pkt); 6207 SYNC_RESP_STRUCT(phy_db_notif, pkt);
6208 6208
6209 uint16_t size = le16toh(phy_db_notif->length); 6209 uint16_t size = le16toh(phy_db_notif->length);
6210 bus_dmamap_sync(sc->sc_dmat, data->map, 6210 bus_dmamap_sync(sc->sc_dmat, data->map,
6211 sizeof(*pkt) + sizeof(*phy_db_notif), 6211 sizeof(*pkt) + sizeof(*phy_db_notif),
6212 size, BUS_DMASYNC_POSTREAD); 6212 size, BUS_DMASYNC_POSTREAD);
6213 iwm_phy_db_set_section(sc, phy_db_notif, size); 6213 iwm_phy_db_set_section(sc, phy_db_notif, size);
6214 6214
6215 break; } 6215 break; }
6216 6216
6217 case IWM_STATISTICS_NOTIFICATION: { 6217 case IWM_STATISTICS_NOTIFICATION: {
6218 struct iwm_notif_statistics *stats; 6218 struct iwm_notif_statistics *stats;
6219 SYNC_RESP_STRUCT(stats, pkt); 6219 SYNC_RESP_STRUCT(stats, pkt);
6220 memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats)); 6220 memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats));
6221 sc->sc_noise = iwm_get_noise(&stats->rx.general); 6221 sc->sc_noise = iwm_get_noise(&stats->rx.general);
6222 break; } 6222 break; }
6223 6223
6224 case IWM_NVM_ACCESS_CMD: 6224 case IWM_NVM_ACCESS_CMD:
6225 if (sc->sc_wantresp == ((qid << 16) | idx)) { 6225 if (sc->sc_wantresp == ((qid << 16) | idx)) {
6226 bus_dmamap_sync(sc->sc_dmat, data->map, 0, 6226 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
6227 sizeof(sc->sc_cmd_resp), 6227 sizeof(sc->sc_cmd_resp),
6228 BUS_DMASYNC_POSTREAD); 6228 BUS_DMASYNC_POSTREAD);
6229 memcpy(sc->sc_cmd_resp, 6229 memcpy(sc->sc_cmd_resp,
6230 pkt, sizeof(sc->sc_cmd_resp)); 6230 pkt, sizeof(sc->sc_cmd_resp));
6231 } 6231 }
6232 break; 6232 break;
6233 6233
6234 case IWM_PHY_CONFIGURATION_CMD: 6234 case IWM_PHY_CONFIGURATION_CMD:
6235 case IWM_TX_ANT_CONFIGURATION_CMD: 6235 case IWM_TX_ANT_CONFIGURATION_CMD:
6236 case IWM_ADD_STA: 6236 case IWM_ADD_STA:
6237 case IWM_MAC_CONTEXT_CMD: 6237 case IWM_MAC_CONTEXT_CMD:
6238 case IWM_REPLY_SF_CFG_CMD: 6238 case IWM_REPLY_SF_CFG_CMD:
6239 case IWM_POWER_TABLE_CMD: 6239 case IWM_POWER_TABLE_CMD:
6240 case IWM_PHY_CONTEXT_CMD: 6240 case IWM_PHY_CONTEXT_CMD:
6241 case IWM_BINDING_CONTEXT_CMD: 6241 case IWM_BINDING_CONTEXT_CMD:
6242 case IWM_TIME_EVENT_CMD: 6242 case IWM_TIME_EVENT_CMD:
6243 case IWM_SCAN_REQUEST_CMD: 6243 case IWM_SCAN_REQUEST_CMD:
6244 case IWM_REPLY_BEACON_FILTERING_CMD: 6244 case IWM_REPLY_BEACON_FILTERING_CMD:
6245 case IWM_MAC_PM_POWER_TABLE: 6245 case IWM_MAC_PM_POWER_TABLE:
6246 case IWM_TIME_QUOTA_CMD: 6246 case IWM_TIME_QUOTA_CMD:
6247 case IWM_REMOVE_STA: 6247 case IWM_REMOVE_STA:
6248 case IWM_TXPATH_FLUSH: 6248 case IWM_TXPATH_FLUSH:
6249 case IWM_LQ_CMD: 6249 case IWM_LQ_CMD:
6250 SYNC_RESP_STRUCT(cresp, pkt); 6250 SYNC_RESP_STRUCT(cresp, pkt);
6251 if (sc->sc_wantresp == ((qid << 16) | idx)) { 6251 if (sc->sc_wantresp == ((qid << 16) | idx)) {
6252 memcpy(sc->sc_cmd_resp, 6252 memcpy(sc->sc_cmd_resp,
6253 pkt, sizeof(*pkt)+sizeof(*cresp)); 6253 pkt, sizeof(*pkt)+sizeof(*cresp));
6254 } 6254 }
6255 break; 6255 break;
6256 6256
6257 /* ignore */ 6257 /* ignore */
6258 case 0x6c: /* IWM_PHY_DB_CMD, no idea why it's not in fw-api.h */ 6258 case 0x6c: /* IWM_PHY_DB_CMD, no idea why it's not in fw-api.h */
6259 break; 6259 break;
6260 6260
6261 case IWM_INIT_COMPLETE_NOTIF: 6261 case IWM_INIT_COMPLETE_NOTIF:
6262 sc->sc_init_complete = 1; 6262 sc->sc_init_complete = 1;
6263 wakeup(&sc->sc_init_complete); 6263 wakeup(&sc->sc_init_complete);
6264 break; 6264 break;
6265 6265
6266 case IWM_SCAN_COMPLETE_NOTIFICATION: { 6266 case IWM_SCAN_COMPLETE_NOTIFICATION: {
6267 struct iwm_scan_complete_notif *notif; 6267 struct iwm_scan_complete_notif *notif;
6268 SYNC_RESP_STRUCT(notif, pkt); 6268 SYNC_RESP_STRUCT(notif, pkt);
6269 6269
6270 workqueue_enqueue(sc->sc_eswq, &sc->sc_eswk, NULL); 6270 workqueue_enqueue(sc->sc_eswq, &sc->sc_eswk, NULL);
6271 break; } 6271 break; }
6272 6272
6273 case IWM_REPLY_ERROR: { 6273 case IWM_REPLY_ERROR: {
6274 struct iwm_error_resp *resp; 6274 struct iwm_error_resp *resp;
6275 SYNC_RESP_STRUCT(resp, pkt); 6275 SYNC_RESP_STRUCT(resp, pkt);
6276 6276
6277 aprint_error_dev(sc->sc_dev, 6277 aprint_error_dev(sc->sc_dev,
6278 "firmware error 0x%x, cmd 0x%x\n", 6278 "firmware error 0x%x, cmd 0x%x\n",
6279 le32toh(resp->error_type), resp->cmd_id); 6279 le32toh(resp->error_type), resp->cmd_id);
6280 break; } 6280 break; }
6281 6281
6282 case IWM_TIME_EVENT_NOTIFICATION: { 6282 case IWM_TIME_EVENT_NOTIFICATION: {
6283 struct iwm_time_event_notif *notif; 6283 struct iwm_time_event_notif *notif;
6284 SYNC_RESP_STRUCT(notif, pkt); 6284 SYNC_RESP_STRUCT(notif, pkt);
6285 6285
6286 if (notif->status) { 6286 if (notif->status) {
6287 if (le32toh(notif->action) & 6287 if (le32toh(notif->action) &
6288 IWM_TE_V2_NOTIF_HOST_EVENT_START) 6288 IWM_TE_V2_NOTIF_HOST_EVENT_START)
6289 sc->sc_auth_prot = 2; 6289 sc->sc_auth_prot = 2;
6290 else 6290 else
6291 sc->sc_auth_prot = 0; 6291 sc->sc_auth_prot = 0;
6292 } else { 6292 } else {
6293 sc->sc_auth_prot = -1; 6293 sc->sc_auth_prot = -1;
6294 } 6294 }
6295 wakeup(&sc->sc_auth_prot); 6295 wakeup(&sc->sc_auth_prot);
6296 break; } 6296 break; }
6297 6297
6298 case IWM_MCAST_FILTER_CMD: 6298 case IWM_MCAST_FILTER_CMD:
6299 break; 6299 break;
6300 6300
6301 default: 6301 default:
6302 aprint_error_dev(sc->sc_dev, 6302 aprint_error_dev(sc->sc_dev,
6303 "code %02x frame %d/%d %x UNHANDLED " 6303 "code %02x frame %d/%d %x UNHANDLED "
6304 "(this should not happen)\n", 6304 "(this should not happen)\n",
6305 pkt->hdr.code, qid, idx, pkt->len_n_flags); 6305 pkt->hdr.code, qid, idx, pkt->len_n_flags);
6306 break; 6306 break;
6307 } 6307 }
6308 6308
6309 /* 6309 /*
6310 * Why test bit 0x80? The Linux driver: 6310 * Why test bit 0x80? The Linux driver:
6311 * 6311 *
6312 * There is one exception: uCode sets bit 15 when it 6312 * There is one exception: uCode sets bit 15 when it
6313 * originates the response/notification, i.e. when the 6313 * originates the response/notification, i.e. when the
6314 * response/notification is not a direct response to a 6314 * response/notification is not a direct response to a
6315 * command sent by the driver. For example, uCode issues 6315 * command sent by the driver. For example, uCode issues
6316 * IWM_REPLY_RX when it sends a received frame to the driver; 6316 * IWM_REPLY_RX when it sends a received frame to the driver;
6317 * it is not a direct response to any driver command. 6317 * it is not a direct response to any driver command.
6318 * 6318 *
6319 * Ok, so since when is 7 == 15? Well, the Linux driver 6319 * Ok, so since when is 7 == 15? Well, the Linux driver
6320 * uses a slightly different format for pkt->hdr, and "qid" 6320 * uses a slightly different format for pkt->hdr, and "qid"
6321 * is actually the upper byte of a two-byte field. 6321 * is actually the upper byte of a two-byte field.
6322 */ 6322 */
6323 if (!(pkt->hdr.qid & (1 << 7))) { 6323 if (!(pkt->hdr.qid & (1 << 7))) {
6324 iwm_cmd_done(sc, pkt); 6324 iwm_cmd_done(sc, pkt);
6325 } 6325 }
6326 6326
6327 ADVANCE_RXQ(sc); 6327 ADVANCE_RXQ(sc);
6328 } 6328 }
6329 6329
6330 IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL, 6330 IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
6331 IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 6331 IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
6332 6332
6333 /* 6333 /*
6334 * Tell the firmware what we have processed. 6334 * Tell the firmware what we have processed.
6335 * Seems like the hardware gets upset unless we align 6335 * Seems like the hardware gets upset unless we align
6336 * the write by 8?? 6336 * the write by 8??
6337 */ 6337 */
6338 hw = (hw == 0) ? IWM_RX_RING_COUNT - 1 : hw - 1; 6338 hw = (hw == 0) ? IWM_RX_RING_COUNT - 1 : hw - 1;
6339 IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, hw & ~7); 6339 IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, hw & ~7);
6340} 6340}
6341 6341
6342static int 6342static int
6343iwm_intr(void *arg) 6343iwm_intr(void *arg)
6344{ 6344{
6345 struct iwm_softc *sc = arg; 6345 struct iwm_softc *sc = arg;
6346 struct ifnet *ifp = IC2IFP(&sc->sc_ic); 6346 struct ifnet *ifp = IC2IFP(&sc->sc_ic);
6347 int handled = 0; 6347 int handled = 0;
6348 int r1, r2, rv = 0; 6348 int r1, r2, rv = 0;
6349 int isperiodic = 0; 6349 int isperiodic = 0;
6350 6350
6351 IWM_WRITE(sc, IWM_CSR_INT_MASK, 0); 6351 IWM_WRITE(sc, IWM_CSR_INT_MASK, 0);
6352 6352
6353 if (sc->sc_flags & IWM_FLAG_USE_ICT) { 6353 if (sc->sc_flags & IWM_FLAG_USE_ICT) {
6354 uint32_t *ict = sc->ict_dma.vaddr; 6354 uint32_t *ict = sc->ict_dma.vaddr;
6355 int tmp; 6355 int tmp;
6356 6356
6357 tmp = htole32(ict[sc->ict_cur]); 6357 tmp = htole32(ict[sc->ict_cur]);
6358 if (!tmp) 6358 if (!tmp)
6359 goto out_ena; 6359 goto out_ena;
6360 6360
6361 /* 6361 /*
6362 * ok, there was something. keep plowing until we have all. 6362 * ok, there was something. keep plowing until we have all.
6363 */ 6363 */
6364 r1 = r2 = 0; 6364 r1 = r2 = 0;
6365 while (tmp) { 6365 while (tmp) {
6366 r1 |= tmp; 6366 r1 |= tmp;
6367 ict[sc->ict_cur] = 0; 6367 ict[sc->ict_cur] = 0;
6368 sc->ict_cur = (sc->ict_cur+1) % IWM_ICT_COUNT; 6368 sc->ict_cur = (sc->ict_cur+1) % IWM_ICT_COUNT;
6369 tmp = htole32(ict[sc->ict_cur]); 6369 tmp = htole32(ict[sc->ict_cur]);
6370 } 6370 }
6371 6371
6372 /* this is where the fun begins. don't ask */ 6372 /* this is where the fun begins. don't ask */
6373 if (r1 == 0xffffffff) 6373 if (r1 == 0xffffffff)
6374 r1 = 0; 6374 r1 = 0;
6375 6375
6376 /* i am not expected to understand this */ 6376 /* i am not expected to understand this */
6377 if (r1 & 0xc0000) 6377 if (r1 & 0xc0000)
6378 r1 |= 0x8000; 6378 r1 |= 0x8000;
6379 r1 = (0xff & r1) | ((0xff00 & r1) << 16); 6379 r1 = (0xff & r1) | ((0xff00 & r1) << 16);
6380 } else { 6380 } else {
6381 r1 = IWM_READ(sc, IWM_CSR_INT); 6381 r1 = IWM_READ(sc, IWM_CSR_INT);
6382 /* "hardware gone" (where, fishing?) */ 6382 /* "hardware gone" (where, fishing?) */
6383 if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0) 6383 if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
6384 goto out; 6384 goto out;
6385 r2 = IWM_READ(sc, IWM_CSR_FH_INT_STATUS); 6385 r2 = IWM_READ(sc, IWM_CSR_FH_INT_STATUS);
6386 } 6386 }
6387 if (r1 == 0 && r2 == 0) { 6387 if (r1 == 0 && r2 == 0) {
6388 goto out_ena; 6388 goto out_ena;
6389 } 6389 }
6390 6390
6391 IWM_WRITE(sc, IWM_CSR_INT, r1 | ~sc->sc_intmask); 6391 IWM_WRITE(sc, IWM_CSR_INT, r1 | ~sc->sc_intmask);
6392 6392
6393 /* ignored */ 6393 /* ignored */
6394 handled |= (r1 & (IWM_CSR_INT_BIT_ALIVE /*| IWM_CSR_INT_BIT_SCD*/)); 6394 handled |= (r1 & (IWM_CSR_INT_BIT_ALIVE /*| IWM_CSR_INT_BIT_SCD*/));
6395 6395
6396 if (r1 & IWM_CSR_INT_BIT_SW_ERR) { 6396 if (r1 & IWM_CSR_INT_BIT_SW_ERR) {
6397#ifdef IWM_DEBUG 6397#ifdef IWM_DEBUG
6398 int i; 6398 int i;
6399 6399
6400 iwm_nic_error(sc); 6400 iwm_nic_error(sc);
6401 6401
6402 /* Dump driver status (TX and RX rings) while we're here. */ 6402 /* Dump driver status (TX and RX rings) while we're here. */
6403 DPRINTF(("driver status:\n")); 6403 DPRINTF(("driver status:\n"));
6404 for (i = 0; i < IWM_MVM_MAX_QUEUES; i++) { 6404 for (i = 0; i < IWM_MVM_MAX_QUEUES; i++) {
6405 struct iwm_tx_ring *ring = &sc->txq[i]; 6405 struct iwm_tx_ring *ring = &sc->txq[i];
6406 DPRINTF((" tx ring %2d: qid=%-2d cur=%-3d " 6406 DPRINTF((" tx ring %2d: qid=%-2d cur=%-3d "
6407 "queued=%-3d\n", 6407 "queued=%-3d\n",
6408 i, ring->qid, ring->cur, ring->queued)); 6408 i, ring->qid, ring->cur, ring->queued));
6409 } 6409 }
6410 DPRINTF((" rx ring: cur=%d\n", sc->rxq.cur)); 6410 DPRINTF((" rx ring: cur=%d\n", sc->rxq.cur));
6411 DPRINTF((" 802.11 state %d\n", sc->sc_ic.ic_state)); 6411 DPRINTF((" 802.11 state %d\n", sc->sc_ic.ic_state));
6412#endif 6412#endif
6413 6413
6414 aprint_error_dev(sc->sc_dev, "fatal firmware error\n"); 6414 aprint_error_dev(sc->sc_dev, "fatal firmware error\n");
6415 ifp->if_flags &= ~IFF_UP; 6415 ifp->if_flags &= ~IFF_UP;
6416 iwm_stop(ifp, 1); 6416 iwm_stop(ifp, 1);
6417 rv = 1; 6417 rv = 1;
6418 goto out; 6418 goto out;
6419 6419
6420 } 6420 }
6421 6421
6422 if (r1 & IWM_CSR_INT_BIT_HW_ERR) { 6422 if (r1 & IWM_CSR_INT_BIT_HW_ERR) {
6423 handled |= IWM_CSR_INT_BIT_HW_ERR; 6423 handled |= IWM_CSR_INT_BIT_HW_ERR;
6424 aprint_error_dev(sc->sc_dev, 6424 aprint_error_dev(sc->sc_dev,
6425 "hardware error, stopping device\n"); 6425 "hardware error, stopping device\n");
6426 ifp->if_flags &= ~IFF_UP; 6426 ifp->if_flags &= ~IFF_UP;
6427 iwm_stop(ifp, 1); 6427 iwm_stop(ifp, 1);
6428 rv = 1; 6428 rv = 1;
6429 goto out; 6429 goto out;
6430 } 6430 }
6431 6431
6432 /* firmware chunk loaded */ 6432 /* firmware chunk loaded */
6433 if (r1 & IWM_CSR_INT_BIT_FH_TX) { 6433 if (r1 & IWM_CSR_INT_BIT_FH_TX) {
6434 IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_TX_MASK); 6434 IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_TX_MASK);
6435 handled |= IWM_CSR_INT_BIT_FH_TX; 6435 handled |= IWM_CSR_INT_BIT_FH_TX;
6436 6436
6437 sc->sc_fw_chunk_done = 1; 6437 sc->sc_fw_chunk_done = 1;
6438 wakeup(&sc->sc_fw); 6438 wakeup(&sc->sc_fw);
6439 } 6439 }
6440 6440
6441 if (r1 & IWM_CSR_INT_BIT_RF_KILL) { 6441 if (r1 & IWM_CSR_INT_BIT_RF_KILL) {
6442 handled |= IWM_CSR_INT_BIT_RF_KILL; 6442 handled |= IWM_CSR_INT_BIT_RF_KILL;
6443 if (iwm_check_rfkill(sc) && (ifp->if_flags & IFF_UP)) { 6443 if (iwm_check_rfkill(sc) && (ifp->if_flags & IFF_UP)) {
6444 DPRINTF(("%s: rfkill switch, disabling interface\n", 6444 DPRINTF(("%s: rfkill switch, disabling interface\n",
6445 DEVNAME(sc))); 6445 DEVNAME(sc)));
6446 ifp->if_flags &= ~IFF_UP; 6446 ifp->if_flags &= ~IFF_UP;
6447 iwm_stop(ifp, 1); 6447 iwm_stop(ifp, 1);
6448 } 6448 }
6449 } 6449 }
6450 6450
6451 /* 6451 /*
6452 * The Linux driver uses periodic interrupts to avoid races. 6452 * The Linux driver uses periodic interrupts to avoid races.
6453 * We cargo-cult like it's going out of fashion. 6453 * We cargo-cult like it's going out of fashion.
6454 */ 6454 */
6455 if (r1 & IWM_CSR_INT_BIT_RX_PERIODIC) { 6455 if (r1 & IWM_CSR_INT_BIT_RX_PERIODIC) {
6456 handled |= IWM_CSR_INT_BIT_RX_PERIODIC; 6456 handled |= IWM_CSR_INT_BIT_RX_PERIODIC;
6457 IWM_WRITE(sc, IWM_CSR_INT, IWM_CSR_INT_BIT_RX_PERIODIC); 6457 IWM_WRITE(sc, IWM_CSR_INT, IWM_CSR_INT_BIT_RX_PERIODIC);
6458 if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) == 0) 6458 if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) == 0)
6459 IWM_WRITE_1(sc, 6459 IWM_WRITE_1(sc,
6460 IWM_CSR_INT_PERIODIC_REG, IWM_CSR_INT_PERIODIC_DIS); 6460 IWM_CSR_INT_PERIODIC_REG, IWM_CSR_INT_PERIODIC_DIS);
6461 isperiodic = 1; 6461 isperiodic = 1;
6462 } 6462 }
6463 6463
6464 if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) || isperiodic) { 6464 if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) || isperiodic) {
6465 handled |= (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX); 6465 handled |= (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX);
6466 IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_RX_MASK); 6466 IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_RX_MASK);
6467 6467
6468 iwm_notif_intr(sc); 6468 iwm_notif_intr(sc);
6469 6469
6470 /* enable periodic interrupt, see above */ 6470 /* enable periodic interrupt, see above */
6471 if (r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX) && !isperiodic) 6471 if (r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX) && !isperiodic)
6472 IWM_WRITE_1(sc, IWM_CSR_INT_PERIODIC_REG, 6472 IWM_WRITE_1(sc, IWM_CSR_INT_PERIODIC_REG,
6473 IWM_CSR_INT_PERIODIC_ENA); 6473 IWM_CSR_INT_PERIODIC_ENA);
6474 } 6474 }
6475 6475
6476 if (__predict_false(r1 & ~handled)) 6476 if (__predict_false(r1 & ~handled))
6477 DPRINTF(("%s: unhandled interrupts: %x\n", DEVNAME(sc), r1)); 6477 DPRINTF(("%s: unhandled interrupts: %x\n", DEVNAME(sc), r1));
6478 rv = 1; 6478 rv = 1;
6479 6479
6480 out_ena: 6480 out_ena:
6481 iwm_restore_interrupts(sc); 6481 iwm_restore_interrupts(sc);
6482 out: 6482 out:
6483 return rv; 6483 return rv;
6484} 6484}
6485 6485
6486/* 6486/*
6487 * Autoconf glue-sniffing 6487 * Autoconf glue-sniffing
6488 */ 6488 */
6489 6489
6490static const pci_product_id_t iwm_devices[] = { 6490static const pci_product_id_t iwm_devices[] = {
6491 PCI_PRODUCT_INTEL_WIFI_LINK_7260_1, 6491 PCI_PRODUCT_INTEL_WIFI_LINK_7260_1,
6492 PCI_PRODUCT_INTEL_WIFI_LINK_7260_2, 6492 PCI_PRODUCT_INTEL_WIFI_LINK_7260_2,
6493 PCI_PRODUCT_INTEL_WIFI_LINK_3160_1, 6493 PCI_PRODUCT_INTEL_WIFI_LINK_3160_1,
6494 PCI_PRODUCT_INTEL_WIFI_LINK_3160_2, 6494 PCI_PRODUCT_INTEL_WIFI_LINK_3160_2,
6495 PCI_PRODUCT_INTEL_WIFI_LINK_7265_1, 6495 PCI_PRODUCT_INTEL_WIFI_LINK_7265_1,
6496 PCI_PRODUCT_INTEL_WIFI_LINK_7265_2, 6496 PCI_PRODUCT_INTEL_WIFI_LINK_7265_2,
6497}; 6497};
6498 6498
6499static int 6499static int
6500iwm_match(device_t parent, cfdata_t match __unused, void *aux) 6500iwm_match(device_t parent, cfdata_t match __unused, void *aux)
6501{ 6501{
6502 struct pci_attach_args *pa = aux; 6502 struct pci_attach_args *pa = aux;
6503 6503
6504 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) 6504 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
6505 return 0; 6505 return 0;
6506 6506
6507 for (size_t i = 0; i < __arraycount(iwm_devices); i++) 6507 for (size_t i = 0; i < __arraycount(iwm_devices); i++)
6508 if (PCI_PRODUCT(pa->pa_id) == iwm_devices[i]) 6508 if (PCI_PRODUCT(pa->pa_id) == iwm_devices[i])
6509 return 1; 6509 return 1;
6510 6510
6511 return 0; 6511 return 0;
6512} 6512}
6513 6513
6514static int 6514static int
6515iwm_preinit(struct iwm_softc *sc) 6515iwm_preinit(struct iwm_softc *sc)
6516{ 6516{
6517 int error; 6517 int error;
6518 6518
6519 if ((error = iwm_prepare_card_hw(sc)) != 0) { 6519 if ((error = iwm_prepare_card_hw(sc)) != 0) {
6520 aprint_error_dev(sc->sc_dev, "could not initialize hardware\n"); 6520 aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
6521 return error; 6521 return error;
6522 } 6522 }
6523 6523
6524 if (sc->sc_flags & IWM_FLAG_ATTACHED) 6524 if (sc->sc_flags & IWM_FLAG_ATTACHED)
6525 return 0; 6525 return 0;
6526 6526
6527 if ((error = iwm_start_hw(sc)) != 0) { 6527 if ((error = iwm_start_hw(sc)) != 0) {
6528 aprint_error_dev(sc->sc_dev, "could not initialize hardware\n"); 6528 aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
6529 return error; 6529 return error;
6530 } 6530 }
6531 6531
6532 error = iwm_run_init_mvm_ucode(sc, 1); 6532 error = iwm_run_init_mvm_ucode(sc, 1);
6533 iwm_stop_device(sc); 6533 iwm_stop_device(sc);
6534 return error; 6534 return error;
6535} 6535}
6536 6536
6537static void 6537static void
6538iwm_attach_hook(device_t dev) 6538iwm_attach_hook(device_t dev)
6539{ 6539{
6540 struct iwm_softc *sc = device_private(dev); 6540 struct iwm_softc *sc = device_private(dev);
6541 struct ieee80211com *ic = &sc->sc_ic; 6541 struct ieee80211com *ic = &sc->sc_ic;
6542 struct ifnet *ifp = &sc->sc_ec.ec_if; 6542 struct ifnet *ifp = &sc->sc_ec.ec_if;
6543 6543
6544 KASSERT(!cold); 6544 KASSERT(!cold);
6545 6545
6546 if (iwm_preinit(sc) != 0) 6546 if (iwm_preinit(sc) != 0)
6547 return; 6547 return;
6548 6548
6549 sc->sc_flags |= IWM_FLAG_ATTACHED; 6549 sc->sc_flags |= IWM_FLAG_ATTACHED;
6550 6550
6551 aprint_normal_dev(sc->sc_dev, 6551 aprint_normal_dev(sc->sc_dev,
6552 "hw rev: 0x%x, fw ver %d.%d (API ver %d), address %s\n", 6552 "hw rev: 0x%x, fw ver %d.%d (API ver %d), address %s\n",
6553 sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK, 6553 sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK,
6554 IWM_UCODE_MAJOR(sc->sc_fwver), 6554 IWM_UCODE_MAJOR(sc->sc_fwver),
6555 IWM_UCODE_MINOR(sc->sc_fwver), 6555 IWM_UCODE_MINOR(sc->sc_fwver),
6556 IWM_UCODE_API(sc->sc_fwver), 6556 IWM_UCODE_API(sc->sc_fwver),
6557 ether_sprintf(sc->sc_nvm.hw_addr)); 6557 ether_sprintf(sc->sc_nvm.hw_addr));
6558 6558
6559 ic->ic_ifp = ifp; 6559 ic->ic_ifp = ifp;
6560 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 6560 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
6561 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 6561 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
6562 ic->ic_state = IEEE80211_S_INIT; 6562 ic->ic_state = IEEE80211_S_INIT;
6563 6563
6564 /* Set device capabilities. */ 6564 /* Set device capabilities. */
6565 ic->ic_caps = 6565 ic->ic_caps =
6566 IEEE80211_C_WEP | /* WEP */ 6566 IEEE80211_C_WEP | /* WEP */
6567 IEEE80211_C_WPA | /* 802.11i */ 6567 IEEE80211_C_WPA | /* 802.11i */
6568 IEEE80211_C_SHSLOT | /* short slot time supported */ 6568 IEEE80211_C_SHSLOT | /* short slot time supported */
6569 IEEE80211_C_SHPREAMBLE; /* short preamble supported */ 6569 IEEE80211_C_SHPREAMBLE; /* short preamble supported */
6570 6570
6571 /* not all hardware can do 5GHz band */ 6571 /* not all hardware can do 5GHz band */
6572 if (sc->sc_nvm.sku_cap_band_52GHz_enable) 6572 if (sc->sc_nvm.sku_cap_band_52GHz_enable)
6573 ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a; 6573 ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a;
6574 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; 6574 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
6575 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g; 6575 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
6576 6576
6577 for (int i = 0; i < __arraycount(sc->sc_phyctxt); i++) { 6577 for (int i = 0; i < __arraycount(sc->sc_phyctxt); i++) {
6578 sc->sc_phyctxt[i].id = i; 6578 sc->sc_phyctxt[i].id = i;
6579 } 6579 }
6580 6580
6581 sc->sc_amrr.amrr_min_success_threshold = 1; 6581 sc->sc_amrr.amrr_min_success_threshold = 1;
6582 sc->sc_amrr.amrr_max_success_threshold = 15; 6582 sc->sc_amrr.amrr_max_success_threshold = 15;
6583 6583
6584 /* IBSS channel undefined for now. */ 6584 /* IBSS channel undefined for now. */
6585 ic->ic_ibss_chan = &ic->ic_channels[1]; 6585 ic->ic_ibss_chan = &ic->ic_channels[1];
6586 6586
6587#if 0 6587#if 0
6588 /* Max RSSI */ 6588 /* Max RSSI */
6589 ic->ic_max_rssi = IWM_MAX_DBM - IWM_MIN_DBM; 6589 ic->ic_max_rssi = IWM_MAX_DBM - IWM_MIN_DBM;
6590#endif 6590#endif
6591 6591
6592 ifp->if_softc = sc; 6592 ifp->if_softc = sc;
6593 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 6593 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
6594 ifp->if_init = iwm_init; 6594 ifp->if_init = iwm_init;
6595 ifp->if_stop = iwm_stop; 6595 ifp->if_stop = iwm_stop;
6596 ifp->if_ioctl = iwm_ioctl; 6596 ifp->if_ioctl = iwm_ioctl;
6597 ifp->if_start = iwm_start; 6597 ifp->if_start = iwm_start;
6598 ifp->if_watchdog = iwm_watchdog; 6598 ifp->if_watchdog = iwm_watchdog;
6599 IFQ_SET_READY(&ifp->if_snd); 6599 IFQ_SET_READY(&ifp->if_snd);
6600 memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ); 6600 memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
6601 6601
6602 if_initialize(ifp); 6602 if_initialize(ifp);
6603 ieee80211_ifattach(ic); 6603 ieee80211_ifattach(ic);
6604 if_register(ifp); 6604 if_register(ifp);
6605 6605
6606 ic->ic_node_alloc = iwm_node_alloc; 6606 ic->ic_node_alloc = iwm_node_alloc;
6607 6607
6608 /* Override 802.11 state transition machine. */ 6608 /* Override 802.11 state transition machine. */
6609 sc->sc_newstate = ic->ic_newstate; 6609 sc->sc_newstate = ic->ic_newstate;
6610 ic->ic_newstate = iwm_newstate; 6610 ic->ic_newstate = iwm_newstate;
6611 ieee80211_media_init(ic, iwm_media_change, ieee80211_media_status); 6611 ieee80211_media_init(ic, iwm_media_change, ieee80211_media_status);
6612 ieee80211_announce(ic); 6612 ieee80211_announce(ic);
6613 6613
6614 iwm_radiotap_attach(sc); 6614 iwm_radiotap_attach(sc);
6615 callout_init(&sc->sc_calib_to, 0); 6615 callout_init(&sc->sc_calib_to, 0);
6616 callout_setfunc(&sc->sc_calib_to, iwm_calib_timeout, sc); 6616 callout_setfunc(&sc->sc_calib_to, iwm_calib_timeout, sc);
6617 6617
6618 //task_set(&sc->init_task, iwm_init_task, sc); 6618 //task_set(&sc->init_task, iwm_init_task, sc);
 6619
 6620 if (pmf_device_register(dev, NULL, NULL))
 6621 pmf_class_network_register(dev, ifp);
 6622 else
 6623 aprint_error_dev(dev, "couldn't establish power handler\n");
6619} 6624}
6620 6625
6621static void 6626static void
6622iwm_attach(device_t parent, device_t self, void *aux) 6627iwm_attach(device_t parent, device_t self, void *aux)
6623{ 6628{
6624 struct iwm_softc *sc = device_private(self); 6629 struct iwm_softc *sc = device_private(self);
6625 struct pci_attach_args *pa = aux; 6630 struct pci_attach_args *pa = aux;
6626 pci_intr_handle_t ih; 6631 pci_intr_handle_t ih;
6627 pcireg_t reg, memtype; 6632 pcireg_t reg, memtype;
6628 const char *intrstr; 6633 const char *intrstr;
6629 int error; 6634 int error;
6630 int txq_i; 6635 int txq_i;
6631 6636
6632 sc->sc_dev = self; 6637 sc->sc_dev = self;
6633 sc->sc_pct = pa->pa_pc; 6638 sc->sc_pct = pa->pa_pc;
6634 sc->sc_pcitag = pa->pa_tag; 6639 sc->sc_pcitag = pa->pa_tag;
6635 sc->sc_dmat = pa->pa_dmat; 6640 sc->sc_dmat = pa->pa_dmat;
6636 sc->sc_pciid = pa->pa_id; 6641 sc->sc_pciid = pa->pa_id;
6637 6642
6638 pci_aprint_devinfo(pa, NULL); 6643 pci_aprint_devinfo(pa, NULL);
6639 6644
6640 /* 6645 /*
6641 * Get the offset of the PCI Express Capability Structure in PCI 6646 * Get the offset of the PCI Express Capability Structure in PCI
6642 * Configuration Space. 6647 * Configuration Space.
6643 */ 6648 */
6644 error = pci_get_capability(sc->sc_pct, sc->sc_pcitag, 6649 error = pci_get_capability(sc->sc_pct, sc->sc_pcitag,
6645 PCI_CAP_PCIEXPRESS, &sc->sc_cap_off, NULL); 6650 PCI_CAP_PCIEXPRESS, &sc->sc_cap_off, NULL);
6646 if (error == 0) { 6651 if (error == 0) {
6647 aprint_error_dev(self, 6652 aprint_error_dev(self,
6648 "PCIe capability structure not found!\n"); 6653 "PCIe capability structure not found!\n");
6649 return; 6654 return;
6650 } 6655 }
6651 6656
6652 /* Clear device-specific "PCI retry timeout" register (41h). */ 6657 /* Clear device-specific "PCI retry timeout" register (41h). */
6653 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40); 6658 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
6654 pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00); 6659 pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
6655 6660
6656 /* Enable bus-mastering and hardware bug workaround. */ 6661 /* Enable bus-mastering and hardware bug workaround. */
6657 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG); 6662 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
6658 reg |= PCI_COMMAND_MASTER_ENABLE; 6663 reg |= PCI_COMMAND_MASTER_ENABLE;
6659 /* if !MSI */ 6664 /* if !MSI */
6660 if (reg & PCI_COMMAND_INTERRUPT_DISABLE) { 6665 if (reg & PCI_COMMAND_INTERRUPT_DISABLE) {
6661 reg &= ~PCI_COMMAND_INTERRUPT_DISABLE; 6666 reg &= ~PCI_COMMAND_INTERRUPT_DISABLE;
6662 } 6667 }
6663 pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg); 6668 pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
6664 6669
6665 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START); 6670 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START);
6666 error = pci_mapreg_map(pa, PCI_MAPREG_START, memtype, 0, 6671 error = pci_mapreg_map(pa, PCI_MAPREG_START, memtype, 0,
6667 &sc->sc_st, &sc->sc_sh, NULL, &sc->sc_sz); 6672 &sc->sc_st, &sc->sc_sh, NULL, &sc->sc_sz);
6668 if (error != 0) { 6673 if (error != 0) {
6669 aprint_error_dev(self, "can't map mem space\n"); 6674 aprint_error_dev(self, "can't map mem space\n");
6670 return; 6675 return;
6671 } 6676 }
6672 6677
6673 /* Install interrupt handler. */ 6678 /* Install interrupt handler. */
6674 if (pci_intr_map(pa, &ih)) { 6679 if (pci_intr_map(pa, &ih)) {
6675 aprint_error_dev(self, "can't map interrupt\n"); 6680 aprint_error_dev(self, "can't map interrupt\n");
6676 return; 6681 return;
6677 } 6682 }
6678 6683
6679 char intrbuf[PCI_INTRSTR_LEN]; 6684 char intrbuf[PCI_INTRSTR_LEN];
6680 intrstr = pci_intr_string(sc->sc_pct, ih, intrbuf, sizeof(intrbuf)); 6685 intrstr = pci_intr_string(sc->sc_pct, ih, intrbuf, sizeof(intrbuf));
6681 sc->sc_ih = pci_intr_establish(sc->sc_pct, ih, IPL_NET, iwm_intr, sc); 6686 sc->sc_ih = pci_intr_establish(sc->sc_pct, ih, IPL_NET, iwm_intr, sc);
6682 if (sc->sc_ih == NULL) { 6687 if (sc->sc_ih == NULL) {
6683 aprint_error_dev(self, "can't establish interrupt"); 6688 aprint_error_dev(self, "can't establish interrupt");
6684 if (intrstr != NULL) 6689 if (intrstr != NULL)
6685 aprint_error(" at %s", intrstr); 6690 aprint_error(" at %s", intrstr);
6686 aprint_error("\n"); 6691 aprint_error("\n");
6687 return; 6692 return;
6688 } 6693 }
6689 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 6694 aprint_normal_dev(self, "interrupting at %s\n", intrstr);
6690 6695
6691 sc->sc_wantresp = -1; 6696 sc->sc_wantresp = -1;
6692 6697
6693 switch (PCI_PRODUCT(sc->sc_pciid)) { 6698 switch (PCI_PRODUCT(sc->sc_pciid)) {
6694 case PCI_PRODUCT_INTEL_WIFI_LINK_7260_1: 6699 case PCI_PRODUCT_INTEL_WIFI_LINK_7260_1:
6695 case PCI_PRODUCT_INTEL_WIFI_LINK_7260_2: 6700 case PCI_PRODUCT_INTEL_WIFI_LINK_7260_2:
6696 sc->sc_fwname = "iwlwifi-7260-9.ucode"; 6701 sc->sc_fwname = "iwlwifi-7260-9.ucode";
6697 sc->host_interrupt_operation_mode = 1; 6702 sc->host_interrupt_operation_mode = 1;
6698 break; 6703 break;
6699 case PCI_PRODUCT_INTEL_WIFI_LINK_3160_1: 6704 case PCI_PRODUCT_INTEL_WIFI_LINK_3160_1:
6700 case PCI_PRODUCT_INTEL_WIFI_LINK_3160_2: 6705 case PCI_PRODUCT_INTEL_WIFI_LINK_3160_2:
6701 sc->sc_fwname = "iwlwifi-3160-9.ucode"; 6706 sc->sc_fwname = "iwlwifi-3160-9.ucode";
6702 sc->host_interrupt_operation_mode = 1; 6707 sc->host_interrupt_operation_mode = 1;
6703 break; 6708 break;
6704 case PCI_PRODUCT_INTEL_WIFI_LINK_7265_1: 6709 case PCI_PRODUCT_INTEL_WIFI_LINK_7265_1:
6705 case PCI_PRODUCT_INTEL_WIFI_LINK_7265_2: 6710 case PCI_PRODUCT_INTEL_WIFI_LINK_7265_2:
6706 sc->sc_fwname = "iwlwifi-7265-9.ucode"; 6711 sc->sc_fwname = "iwlwifi-7265-9.ucode";
6707 sc->host_interrupt_operation_mode = 0; 6712 sc->host_interrupt_operation_mode = 0;
6708 break; 6713 break;
6709 default: 6714 default:
6710 aprint_error_dev(self, "unknown product %#x", 6715 aprint_error_dev(self, "unknown product %#x",
6711 PCI_PRODUCT(sc->sc_pciid)); 6716 PCI_PRODUCT(sc->sc_pciid));
6712 return; 6717 return;
6713 } 6718 }
6714 DPRINTF(("%s: firmware=%s\n", DEVNAME(sc), sc->sc_fwname)); 6719 DPRINTF(("%s: firmware=%s\n", DEVNAME(sc), sc->sc_fwname));
6715 sc->sc_fwdmasegsz = IWM_FWDMASEGSZ; 6720 sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
6716 6721
6717 /* 6722 /*
6718 * We now start fiddling with the hardware 6723 * We now start fiddling with the hardware
6719 */ 6724 */
6720 6725
6721 sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV); 6726 sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV);
6722 if (iwm_prepare_card_hw(sc) != 0) { 6727 if (iwm_prepare_card_hw(sc) != 0) {
6723 aprint_error_dev(sc->sc_dev, "could not initialize hardware\n"); 6728 aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
6724 return; 6729 return;
6725 } 6730 }
6726 6731
6727 /* Allocate DMA memory for firmware transfers. */ 6732 /* Allocate DMA memory for firmware transfers. */
6728 if ((error = iwm_alloc_fwmem(sc)) != 0) { 6733 if ((error = iwm_alloc_fwmem(sc)) != 0) {
6729 aprint_error_dev(sc->sc_dev, 6734 aprint_error_dev(sc->sc_dev,
6730 "could not allocate memory for firmware\n"); 6735 "could not allocate memory for firmware\n");
6731 return; 6736 return;
6732 } 6737 }
6733 6738
6734 /* Allocate "Keep Warm" page. */ 6739 /* Allocate "Keep Warm" page. */
6735 if ((error = iwm_alloc_kw(sc)) != 0) { 6740 if ((error = iwm_alloc_kw(sc)) != 0) {
6736 aprint_error_dev(sc->sc_dev, 6741 aprint_error_dev(sc->sc_dev,
6737 "could not allocate keep warm page\n"); 6742 "could not allocate keep warm page\n");
6738 goto fail1; 6743 goto fail1;
6739 } 6744 }
6740 6745
6741 /* We use ICT interrupts */ 6746 /* We use ICT interrupts */
6742 if ((error = iwm_alloc_ict(sc)) != 0) { 6747 if ((error = iwm_alloc_ict(sc)) != 0) {
6743 aprint_error_dev(sc->sc_dev, "could not allocate ICT table\n"); 6748 aprint_error_dev(sc->sc_dev, "could not allocate ICT table\n");
6744 goto fail2; 6749 goto fail2;
6745 } 6750 }
6746 6751
6747 /* Allocate TX scheduler "rings". */ 6752 /* Allocate TX scheduler "rings". */
6748 if ((error = iwm_alloc_sched(sc)) != 0) { 6753 if ((error = iwm_alloc_sched(sc)) != 0) {
6749 aprint_error_dev(sc->sc_dev, 6754 aprint_error_dev(sc->sc_dev,
6750 "could not allocate TX scheduler rings\n"); 6755 "could not allocate TX scheduler rings\n");
6751 goto fail3; 6756 goto fail3;
6752 } 6757 }
6753 6758
6754 /* Allocate TX rings */ 6759 /* Allocate TX rings */
6755 for (txq_i = 0; txq_i < __arraycount(sc->txq); txq_i++) { 6760 for (txq_i = 0; txq_i < __arraycount(sc->txq); txq_i++) {
6756 if ((error = iwm_alloc_tx_ring(sc, 6761 if ((error = iwm_alloc_tx_ring(sc,
6757 &sc->txq[txq_i], txq_i)) != 0) { 6762 &sc->txq[txq_i], txq_i)) != 0) {
6758 aprint_error_dev(sc->sc_dev, 6763 aprint_error_dev(sc->sc_dev,
6759 "could not allocate TX ring %d\n", txq_i); 6764 "could not allocate TX ring %d\n", txq_i);
6760 goto fail4; 6765 goto fail4;
6761 } 6766 }
6762 } 6767 }
6763 6768
6764 /* Allocate RX ring. */ 6769 /* Allocate RX ring. */
6765 if ((error = iwm_alloc_rx_ring(sc, &sc->rxq)) != 0) { 6770 if ((error = iwm_alloc_rx_ring(sc, &sc->rxq)) != 0) {
6766 aprint_error_dev(sc->sc_dev, "could not allocate RX ring\n"); 6771 aprint_error_dev(sc->sc_dev, "could not allocate RX ring\n");
6767 goto fail4; 6772 goto fail4;
6768 } 6773 }
6769 6774
6770 workqueue_create(&sc->sc_eswq, "iwmes", 6775 workqueue_create(&sc->sc_eswq, "iwmes",
6771 iwm_endscan_cb, sc, PRI_NONE, IPL_NET, 0); 6776 iwm_endscan_cb, sc, PRI_NONE, IPL_NET, 0);
6772 workqueue_create(&sc->sc_nswq, "iwmns", 6777 workqueue_create(&sc->sc_nswq, "iwmns",
6773 iwm_newstate_cb, sc, PRI_NONE, IPL_NET, 0); 6778 iwm_newstate_cb, sc, PRI_NONE, IPL_NET, 0);
6774 6779
6775 /* Clear pending interrupts. */ 6780 /* Clear pending interrupts. */
6776 IWM_WRITE(sc, IWM_CSR_INT, 0xffffffff); 6781 IWM_WRITE(sc, IWM_CSR_INT, 0xffffffff);
6777 6782
6778 /* 6783 /*
6779 * We can't do normal attach before the file system is mounted 6784 * We can't do normal attach before the file system is mounted
6780 * because we cannot read the MAC address without loading the 6785 * because we cannot read the MAC address without loading the
6781 * firmware from disk. So we postpone until mountroot is done. 6786 * firmware from disk. So we postpone until mountroot is done.
6782 * Notably, this will require a full driver unload/load cycle 6787 * Notably, this will require a full driver unload/load cycle
6783 * (or reboot) in case the firmware is not present when the 6788 * (or reboot) in case the firmware is not present when the
6784 * hook runs. 6789 * hook runs.
6785 */ 6790 */
6786 config_mountroot(self, iwm_attach_hook); 6791 config_mountroot(self, iwm_attach_hook);
6787 6792
6788 return; 6793 return;
6789 6794
6790 /* Free allocated memory if something failed during attachment. */ 6795 /* Free allocated memory if something failed during attachment. */
6791fail4: while (--txq_i >= 0) 6796fail4: while (--txq_i >= 0)
6792 iwm_free_tx_ring(sc, &sc->txq[txq_i]); 6797 iwm_free_tx_ring(sc, &sc->txq[txq_i]);
6793 iwm_free_sched(sc); 6798 iwm_free_sched(sc);
6794fail3: if (sc->ict_dma.vaddr != NULL) 6799fail3: if (sc->ict_dma.vaddr != NULL)
6795 iwm_free_ict(sc); 6800 iwm_free_ict(sc);
6796fail2: iwm_free_kw(sc); 6801fail2: iwm_free_kw(sc);
6797fail1: iwm_free_fwmem(sc); 6802fail1: iwm_free_fwmem(sc);
6798} 6803}
6799 6804
6800/* 6805/*
6801 * Attach the interface to 802.11 radiotap. 6806 * Attach the interface to 802.11 radiotap.
6802 */ 6807 */
6803void 6808void
6804iwm_radiotap_attach(struct iwm_softc *sc) 6809iwm_radiotap_attach(struct iwm_softc *sc)
6805{ 6810{
6806 struct ifnet *ifp = sc->sc_ic.ic_ifp; 6811 struct ifnet *ifp = sc->sc_ic.ic_ifp;
6807 6812
6808 bpf_attach2(ifp, DLT_IEEE802_11_RADIO, 6813 bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
6809 sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, 6814 sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
6810 &sc->sc_drvbpf); 6815 &sc->sc_drvbpf);
6811 6816
6812 sc->sc_rxtap_len = sizeof sc->sc_rxtapu; 6817 sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
6813 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 6818 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
6814 sc->sc_rxtap.wr_ihdr.it_present = htole32(IWM_RX_RADIOTAP_PRESENT); 6819 sc->sc_rxtap.wr_ihdr.it_present = htole32(IWM_RX_RADIOTAP_PRESENT);
6815 6820
6816 sc->sc_txtap_len = sizeof sc->sc_txtapu; 6821 sc->sc_txtap_len = sizeof sc->sc_txtapu;
6817 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 6822 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
6818 sc->sc_txtap.wt_ihdr.it_present = htole32(IWM_TX_RADIOTAP_PRESENT); 6823 sc->sc_txtap.wt_ihdr.it_present = htole32(IWM_TX_RADIOTAP_PRESENT);
6819} 6824}
6820 6825
6821#if 0 6826#if 0
6822static void 6827static void
6823iwm_init_task(void *arg1) 6828iwm_init_task(void *arg1)
6824{ 6829{
6825 struct iwm_softc *sc = arg1; 6830 struct iwm_softc *sc = arg1;
6826 struct ifnet *ifp = &sc->sc_ic.ic_if; 6831 struct ifnet *ifp = &sc->sc_ic.ic_if;
6827 int s; 6832 int s;
6828 6833
6829 s = splnet(); 6834 s = splnet();
6830 while (sc->sc_flags & IWM_FLAG_BUSY) 6835 while (sc->sc_flags & IWM_FLAG_BUSY)
6831 tsleep(&sc->sc_flags, 0, "iwmpwr", 0); 6836 tsleep(&sc->sc_flags, 0, "iwmpwr", 0);
6832 sc->sc_flags |= IWM_FLAG_BUSY; 6837 sc->sc_flags |= IWM_FLAG_BUSY;
6833 6838
6834 iwm_stop(ifp, 0); 6839 iwm_stop(ifp, 0);
6835 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP) 6840 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
6836 iwm_init(ifp); 6841 iwm_init(ifp);
6837 6842
6838 sc->sc_flags &= ~IWM_FLAG_BUSY; 6843 sc->sc_flags &= ~IWM_FLAG_BUSY;
6839 wakeup(&sc->sc_flags); 6844 wakeup(&sc->sc_flags);
6840 splx(s); 6845 splx(s);
6841} 6846}
6842 6847
6843static void 6848static void
6844iwm_wakeup(struct iwm_softc *sc) 6849iwm_wakeup(struct iwm_softc *sc)
6845{ 6850{
6846 pcireg_t reg; 6851 pcireg_t reg;
6847 6852
6848 /* Clear device-specific "PCI retry timeout" register (41h). */ 6853 /* Clear device-specific "PCI retry timeout" register (41h). */
6849 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40); 6854 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
6850 pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00); 6855 pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
6851 6856
6852 iwm_init_task(sc); 6857 iwm_init_task(sc);
6853} 6858}
6854 6859
6855static int 6860static int
6856iwm_activate(device_t self, enum devact act) 6861iwm_activate(device_t self, enum devact act)
6857{ 6862{
6858 struct iwm_softc *sc = device_private(self); 6863 struct iwm_softc *sc = device_private(self);
6859 struct ifnet *ifp = IC2IFP(&sc->sc_ic); 6864 struct ifnet *ifp = IC2IFP(&sc->sc_ic);
6860 6865
6861 switch (act) { 6866 switch (act) {
6862 case DVACT_DEACTIVATE: 6867 case DVACT_DEACTIVATE:
6863 if (ifp->if_flags & IFF_RUNNING) 6868 if (ifp->if_flags & IFF_RUNNING)
6864 iwm_stop(ifp, 0); 6869 iwm_stop(ifp, 0);
6865 return 0; 6870 return 0;
6866 default: 6871 default:
6867 return EOPNOTSUPP; 6872 return EOPNOTSUPP;
6868 } 6873 }
6869} 6874}
6870#endif 6875#endif
6871 6876
6872CFATTACH_DECL_NEW(iwm, sizeof(struct iwm_softc), iwm_match, iwm_attach, 6877CFATTACH_DECL_NEW(iwm, sizeof(struct iwm_softc), iwm_match, iwm_attach,
6873 NULL, NULL); 6878 NULL, NULL);