if_iwm.c revision 1.89 1 1.89 mlelstv /* $NetBSD: if_iwm.c,v 1.89 2024/02/09 06:01:03 mlelstv Exp $ */
2 1.56 nonaka /* OpenBSD: if_iwm.c,v 1.148 2016/11/19 21:07:08 stsp Exp */
3 1.45 nonaka #define IEEE80211_NO_HT
4 1.1 pooka /*
5 1.45 nonaka * Copyright (c) 2014, 2016 genua gmbh <info (at) genua.de>
6 1.45 nonaka * Author: Stefan Sperling <stsp (at) openbsd.org>
7 1.1 pooka * Copyright (c) 2014 Fixup Software Ltd.
8 1.1 pooka *
9 1.1 pooka * Permission to use, copy, modify, and distribute this software for any
10 1.1 pooka * purpose with or without fee is hereby granted, provided that the above
11 1.1 pooka * copyright notice and this permission notice appear in all copies.
12 1.1 pooka *
13 1.1 pooka * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 1.1 pooka * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 1.1 pooka * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 1.1 pooka * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 1.1 pooka * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 1.1 pooka * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 1.1 pooka * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 1.1 pooka */
21 1.1 pooka
22 1.1 pooka /*-
23 1.1 pooka * Based on BSD-licensed source modules in the Linux iwlwifi driver,
24 1.1 pooka * which were used as the reference documentation for this implementation.
25 1.1 pooka *
26 1.1 pooka ***********************************************************************
27 1.1 pooka *
28 1.1 pooka * This file is provided under a dual BSD/GPLv2 license. When using or
29 1.1 pooka * redistributing this file, you may do so under either license.
30 1.1 pooka *
31 1.1 pooka * GPL LICENSE SUMMARY
32 1.1 pooka *
33 1.71 nonaka * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
34 1.45 nonaka * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
35 1.71 nonaka * Copyright(c) 2016 Intel Deutschland GmbH
36 1.1 pooka *
37 1.1 pooka * This program is free software; you can redistribute it and/or modify
38 1.1 pooka * it under the terms of version 2 of the GNU General Public License as
39 1.1 pooka * published by the Free Software Foundation.
40 1.1 pooka *
41 1.1 pooka * This program is distributed in the hope that it will be useful, but
42 1.1 pooka * WITHOUT ANY WARRANTY; without even the implied warranty of
43 1.1 pooka * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44 1.1 pooka * General Public License for more details.
45 1.1 pooka *
46 1.1 pooka * You should have received a copy of the GNU General Public License
47 1.1 pooka * along with this program; if not, write to the Free Software
48 1.1 pooka * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
49 1.1 pooka * USA
50 1.1 pooka *
51 1.1 pooka * The full GNU General Public License is included in this distribution
52 1.1 pooka * in the file called COPYING.
53 1.1 pooka *
54 1.1 pooka * Contact Information:
55 1.71 nonaka * Intel Linux Wireless <linuxwifi (at) intel.com>
56 1.1 pooka * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
57 1.1 pooka *
58 1.1 pooka * BSD LICENSE
59 1.1 pooka *
60 1.71 nonaka * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
61 1.45 nonaka * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
62 1.71 nonaka * Copyright(c) 2016 Intel Deutschland GmbH
63 1.1 pooka * All rights reserved.
64 1.1 pooka *
65 1.1 pooka * Redistribution and use in source and binary forms, with or without
66 1.1 pooka * modification, are permitted provided that the following conditions
67 1.1 pooka * are met:
68 1.1 pooka *
69 1.1 pooka * * Redistributions of source code must retain the above copyright
70 1.1 pooka * notice, this list of conditions and the following disclaimer.
71 1.1 pooka * * Redistributions in binary form must reproduce the above copyright
72 1.1 pooka * notice, this list of conditions and the following disclaimer in
73 1.1 pooka * the documentation and/or other materials provided with the
74 1.1 pooka * distribution.
75 1.1 pooka * * Neither the name Intel Corporation nor the names of its
76 1.1 pooka * contributors may be used to endorse or promote products derived
77 1.1 pooka * from this software without specific prior written permission.
78 1.1 pooka *
79 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
80 1.1 pooka * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
81 1.1 pooka * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
82 1.1 pooka * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
83 1.1 pooka * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
84 1.1 pooka * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
85 1.1 pooka * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
86 1.1 pooka * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
87 1.1 pooka * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88 1.1 pooka * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
89 1.1 pooka * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90 1.1 pooka */
91 1.1 pooka
92 1.1 pooka /*-
93 1.1 pooka * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini (at) free.fr>
94 1.1 pooka *
95 1.1 pooka * Permission to use, copy, modify, and distribute this software for any
96 1.1 pooka * purpose with or without fee is hereby granted, provided that the above
97 1.1 pooka * copyright notice and this permission notice appear in all copies.
98 1.1 pooka *
99 1.1 pooka * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
100 1.1 pooka * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
101 1.1 pooka * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
102 1.1 pooka * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
103 1.1 pooka * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
104 1.1 pooka * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
105 1.1 pooka * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
106 1.1 pooka */
107 1.1 pooka
108 1.1 pooka #include <sys/cdefs.h>
109 1.89 mlelstv __KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.89 2024/02/09 06:01:03 mlelstv Exp $");
110 1.1 pooka
111 1.1 pooka #include <sys/param.h>
112 1.1 pooka #include <sys/conf.h>
113 1.1 pooka #include <sys/kernel.h>
114 1.1 pooka #include <sys/kmem.h>
115 1.1 pooka #include <sys/mbuf.h>
116 1.1 pooka #include <sys/mutex.h>
117 1.1 pooka #include <sys/proc.h>
118 1.1 pooka #include <sys/socket.h>
119 1.1 pooka #include <sys/sockio.h>
120 1.32 nonaka #include <sys/sysctl.h>
121 1.1 pooka #include <sys/systm.h>
122 1.1 pooka
123 1.1 pooka #include <sys/cpu.h>
124 1.1 pooka #include <sys/bus.h>
125 1.1 pooka #include <sys/workqueue.h>
126 1.1 pooka #include <machine/endian.h>
127 1.66 nonaka #include <sys/intr.h>
128 1.1 pooka
129 1.1 pooka #include <dev/pci/pcireg.h>
130 1.1 pooka #include <dev/pci/pcivar.h>
131 1.1 pooka #include <dev/pci/pcidevs.h>
132 1.1 pooka #include <dev/firmload.h>
133 1.1 pooka
134 1.1 pooka #include <net/bpf.h>
135 1.1 pooka #include <net/if.h>
136 1.1 pooka #include <net/if_dl.h>
137 1.1 pooka #include <net/if_media.h>
138 1.1 pooka #include <net/if_ether.h>
139 1.1 pooka
140 1.1 pooka #include <netinet/in.h>
141 1.1 pooka #include <netinet/ip.h>
142 1.1 pooka
143 1.1 pooka #include <net80211/ieee80211_var.h>
144 1.1 pooka #include <net80211/ieee80211_amrr.h>
145 1.1 pooka #include <net80211/ieee80211_radiotap.h>
146 1.1 pooka
147 1.1 pooka #define DEVNAME(_s) device_xname((_s)->sc_dev)
148 1.1 pooka #define IC2IFP(_ic_) ((_ic_)->ic_ifp)
149 1.1 pooka
150 1.1 pooka #define le16_to_cpup(_a_) (le16toh(*(const uint16_t *)(_a_)))
151 1.1 pooka #define le32_to_cpup(_a_) (le32toh(*(const uint32_t *)(_a_)))
152 1.1 pooka
153 1.1 pooka #ifdef IWM_DEBUG
154 1.1 pooka #define DPRINTF(x) do { if (iwm_debug > 0) printf x; } while (0)
155 1.1 pooka #define DPRINTFN(n, x) do { if (iwm_debug >= (n)) printf x; } while (0)
156 1.32 nonaka int iwm_debug = 0;
157 1.1 pooka #else
158 1.1 pooka #define DPRINTF(x) do { ; } while (0)
159 1.1 pooka #define DPRINTFN(n, x) do { ; } while (0)
160 1.1 pooka #endif
161 1.1 pooka
162 1.1 pooka #include <dev/pci/if_iwmreg.h>
163 1.1 pooka #include <dev/pci/if_iwmvar.h>
164 1.1 pooka
165 1.4 nonaka static const uint8_t iwm_nvm_channels[] = {
166 1.1 pooka /* 2.4 GHz */
167 1.1 pooka 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
168 1.1 pooka /* 5 GHz */
169 1.45 nonaka 36, 40, 44, 48, 52, 56, 60, 64,
170 1.1 pooka 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
171 1.1 pooka 149, 153, 157, 161, 165
172 1.1 pooka };
173 1.45 nonaka
174 1.45 nonaka static const uint8_t iwm_nvm_channels_8000[] = {
175 1.45 nonaka /* 2.4 GHz */
176 1.45 nonaka 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
177 1.45 nonaka /* 5 GHz */
178 1.45 nonaka 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
179 1.45 nonaka 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
180 1.45 nonaka 149, 153, 157, 161, 165, 169, 173, 177, 181
181 1.45 nonaka };
182 1.45 nonaka
183 1.1 pooka #define IWM_NUM_2GHZ_CHANNELS 14
184 1.1 pooka
185 1.4 nonaka static const struct iwm_rate {
186 1.1 pooka uint8_t rate;
187 1.1 pooka uint8_t plcp;
188 1.45 nonaka uint8_t ht_plcp;
189 1.1 pooka } iwm_rates[] = {
190 1.45 nonaka /* Legacy */ /* HT */
191 1.45 nonaka { 2, IWM_RATE_1M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP },
192 1.45 nonaka { 4, IWM_RATE_2M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP },
193 1.45 nonaka { 11, IWM_RATE_5M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP },
194 1.45 nonaka { 22, IWM_RATE_11M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP },
195 1.45 nonaka { 12, IWM_RATE_6M_PLCP, IWM_RATE_HT_SISO_MCS_0_PLCP },
196 1.45 nonaka { 18, IWM_RATE_9M_PLCP, IWM_RATE_HT_SISO_MCS_INV_PLCP },
197 1.45 nonaka { 24, IWM_RATE_12M_PLCP, IWM_RATE_HT_SISO_MCS_1_PLCP },
198 1.45 nonaka { 36, IWM_RATE_18M_PLCP, IWM_RATE_HT_SISO_MCS_2_PLCP },
199 1.45 nonaka { 48, IWM_RATE_24M_PLCP, IWM_RATE_HT_SISO_MCS_3_PLCP },
200 1.45 nonaka { 72, IWM_RATE_36M_PLCP, IWM_RATE_HT_SISO_MCS_4_PLCP },
201 1.45 nonaka { 96, IWM_RATE_48M_PLCP, IWM_RATE_HT_SISO_MCS_5_PLCP },
202 1.45 nonaka { 108, IWM_RATE_54M_PLCP, IWM_RATE_HT_SISO_MCS_6_PLCP },
203 1.45 nonaka { 128, IWM_RATE_INVM_PLCP, IWM_RATE_HT_SISO_MCS_7_PLCP },
204 1.1 pooka };
205 1.1 pooka #define IWM_RIDX_CCK 0
206 1.1 pooka #define IWM_RIDX_OFDM 4
207 1.1 pooka #define IWM_RIDX_MAX (__arraycount(iwm_rates)-1)
208 1.1 pooka #define IWM_RIDX_IS_CCK(_i_) ((_i_) < IWM_RIDX_OFDM)
209 1.1 pooka #define IWM_RIDX_IS_OFDM(_i_) ((_i_) >= IWM_RIDX_OFDM)
210 1.1 pooka
211 1.45 nonaka #ifndef IEEE80211_NO_HT
212 1.45 nonaka /* Convert an MCS index into an iwm_rates[] index. */
213 1.45 nonaka static const int iwm_mcs2ridx[] = {
214 1.45 nonaka IWM_RATE_MCS_0_INDEX,
215 1.45 nonaka IWM_RATE_MCS_1_INDEX,
216 1.45 nonaka IWM_RATE_MCS_2_INDEX,
217 1.45 nonaka IWM_RATE_MCS_3_INDEX,
218 1.45 nonaka IWM_RATE_MCS_4_INDEX,
219 1.45 nonaka IWM_RATE_MCS_5_INDEX,
220 1.45 nonaka IWM_RATE_MCS_6_INDEX,
221 1.45 nonaka IWM_RATE_MCS_7_INDEX,
222 1.45 nonaka };
223 1.45 nonaka #endif
224 1.45 nonaka
225 1.45 nonaka struct iwm_nvm_section {
226 1.45 nonaka uint16_t length;
227 1.45 nonaka uint8_t *data;
228 1.45 nonaka };
229 1.45 nonaka
230 1.1 pooka struct iwm_newstate_state {
231 1.1 pooka struct work ns_wk;
232 1.1 pooka enum ieee80211_state ns_nstate;
233 1.1 pooka int ns_arg;
234 1.1 pooka int ns_generation;
235 1.1 pooka };
236 1.1 pooka
237 1.4 nonaka static int iwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t);
238 1.4 nonaka static int iwm_firmware_store_section(struct iwm_softc *,
239 1.4 nonaka enum iwm_ucode_type, uint8_t *, size_t);
240 1.4 nonaka static int iwm_set_default_calib(struct iwm_softc *, const void *);
241 1.61 nonaka static int iwm_read_firmware(struct iwm_softc *, enum iwm_ucode_type);
242 1.4 nonaka static uint32_t iwm_read_prph(struct iwm_softc *, uint32_t);
243 1.4 nonaka static void iwm_write_prph(struct iwm_softc *, uint32_t, uint32_t);
244 1.2 nonaka #ifdef IWM_DEBUG
245 1.4 nonaka static int iwm_read_mem(struct iwm_softc *, uint32_t, void *, int);
246 1.2 nonaka #endif
247 1.4 nonaka static int iwm_write_mem(struct iwm_softc *, uint32_t, const void *, int);
248 1.4 nonaka static int iwm_write_mem32(struct iwm_softc *, uint32_t, uint32_t);
249 1.4 nonaka static int iwm_poll_bit(struct iwm_softc *, int, uint32_t, uint32_t, int);
250 1.4 nonaka static int iwm_nic_lock(struct iwm_softc *);
251 1.4 nonaka static void iwm_nic_unlock(struct iwm_softc *);
252 1.4 nonaka static void iwm_set_bits_mask_prph(struct iwm_softc *, uint32_t, uint32_t,
253 1.8 nonaka uint32_t);
254 1.4 nonaka static void iwm_set_bits_prph(struct iwm_softc *, uint32_t, uint32_t);
255 1.4 nonaka static void iwm_clear_bits_prph(struct iwm_softc *, uint32_t, uint32_t);
256 1.4 nonaka static int iwm_dma_contig_alloc(bus_dma_tag_t, struct iwm_dma_info *,
257 1.4 nonaka bus_size_t, bus_size_t);
258 1.4 nonaka static void iwm_dma_contig_free(struct iwm_dma_info *);
259 1.4 nonaka static int iwm_alloc_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
260 1.45 nonaka static void iwm_disable_rx_dma(struct iwm_softc *);
261 1.4 nonaka static void iwm_reset_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
262 1.4 nonaka static void iwm_free_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
263 1.4 nonaka static int iwm_alloc_tx_ring(struct iwm_softc *, struct iwm_tx_ring *,
264 1.4 nonaka int);
265 1.4 nonaka static void iwm_reset_tx_ring(struct iwm_softc *, struct iwm_tx_ring *);
266 1.4 nonaka static void iwm_free_tx_ring(struct iwm_softc *, struct iwm_tx_ring *);
267 1.4 nonaka static void iwm_enable_rfkill_int(struct iwm_softc *);
268 1.4 nonaka static int iwm_check_rfkill(struct iwm_softc *);
269 1.4 nonaka static void iwm_enable_interrupts(struct iwm_softc *);
270 1.4 nonaka static void iwm_restore_interrupts(struct iwm_softc *);
271 1.4 nonaka static void iwm_disable_interrupts(struct iwm_softc *);
272 1.4 nonaka static void iwm_ict_reset(struct iwm_softc *);
273 1.4 nonaka static int iwm_set_hw_ready(struct iwm_softc *);
274 1.4 nonaka static int iwm_prepare_card_hw(struct iwm_softc *);
275 1.4 nonaka static void iwm_apm_config(struct iwm_softc *);
276 1.4 nonaka static int iwm_apm_init(struct iwm_softc *);
277 1.4 nonaka static void iwm_apm_stop(struct iwm_softc *);
278 1.11 nonaka static int iwm_allow_mcast(struct iwm_softc *);
279 1.4 nonaka static int iwm_start_hw(struct iwm_softc *);
280 1.4 nonaka static void iwm_stop_device(struct iwm_softc *);
281 1.45 nonaka static void iwm_nic_config(struct iwm_softc *);
282 1.4 nonaka static int iwm_nic_rx_init(struct iwm_softc *);
283 1.4 nonaka static int iwm_nic_tx_init(struct iwm_softc *);
284 1.4 nonaka static int iwm_nic_init(struct iwm_softc *);
285 1.45 nonaka static int iwm_enable_txq(struct iwm_softc *, int, int, int);
286 1.4 nonaka static int iwm_post_alive(struct iwm_softc *);
287 1.45 nonaka static struct iwm_phy_db_entry *
288 1.45 nonaka iwm_phy_db_get_section(struct iwm_softc *,
289 1.45 nonaka enum iwm_phy_db_section_type, uint16_t);
290 1.45 nonaka static int iwm_phy_db_set_section(struct iwm_softc *,
291 1.45 nonaka struct iwm_calib_res_notif_phy_db *, uint16_t);
292 1.4 nonaka static int iwm_is_valid_channel(uint16_t);
293 1.4 nonaka static uint8_t iwm_ch_id_to_ch_index(uint16_t);
294 1.4 nonaka static uint16_t iwm_channel_id_to_papd(uint16_t);
295 1.4 nonaka static uint16_t iwm_channel_id_to_txp(struct iwm_softc *, uint16_t);
296 1.4 nonaka static int iwm_phy_db_get_section_data(struct iwm_softc *, uint32_t,
297 1.4 nonaka uint8_t **, uint16_t *, uint16_t);
298 1.4 nonaka static int iwm_send_phy_db_cmd(struct iwm_softc *, uint16_t, uint16_t,
299 1.4 nonaka void *);
300 1.45 nonaka static int iwm_phy_db_send_all_channel_groups(struct iwm_softc *,
301 1.45 nonaka enum iwm_phy_db_section_type, uint8_t);
302 1.4 nonaka static int iwm_send_phy_db_data(struct iwm_softc *);
303 1.45 nonaka static void iwm_te_v2_to_v1(const struct iwm_time_event_cmd_v2 *,
304 1.4 nonaka struct iwm_time_event_cmd_v1 *);
305 1.45 nonaka static int iwm_send_time_event_cmd(struct iwm_softc *,
306 1.4 nonaka const struct iwm_time_event_cmd_v2 *);
307 1.45 nonaka static void iwm_protect_session(struct iwm_softc *, struct iwm_node *,
308 1.45 nonaka uint32_t, uint32_t);
309 1.4 nonaka static int iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, uint16_t,
310 1.4 nonaka uint16_t, uint8_t *, uint16_t *);
311 1.4 nonaka static int iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *,
312 1.45 nonaka uint16_t *, size_t);
313 1.45 nonaka static void iwm_init_channel_map(struct iwm_softc *, const uint16_t * const,
314 1.45 nonaka const uint8_t *, size_t);
315 1.45 nonaka #ifndef IEEE80211_NO_HT
316 1.45 nonaka static void iwm_setup_ht_rates(struct iwm_softc *);
317 1.45 nonaka static void iwm_htprot_task(void *);
318 1.45 nonaka static void iwm_update_htprot(struct ieee80211com *,
319 1.45 nonaka struct ieee80211_node *);
320 1.45 nonaka static int iwm_ampdu_rx_start(struct ieee80211com *,
321 1.45 nonaka struct ieee80211_node *, uint8_t);
322 1.45 nonaka static void iwm_ampdu_rx_stop(struct ieee80211com *,
323 1.45 nonaka struct ieee80211_node *, uint8_t);
324 1.45 nonaka static void iwm_sta_rx_agg(struct iwm_softc *, struct ieee80211_node *,
325 1.45 nonaka uint8_t, uint16_t, int);
326 1.45 nonaka #ifdef notyet
327 1.45 nonaka static int iwm_ampdu_tx_start(struct ieee80211com *,
328 1.45 nonaka struct ieee80211_node *, uint8_t);
329 1.45 nonaka static void iwm_ampdu_tx_stop(struct ieee80211com *,
330 1.45 nonaka struct ieee80211_node *, uint8_t);
331 1.45 nonaka #endif
332 1.45 nonaka static void iwm_ba_task(void *);
333 1.45 nonaka #endif
334 1.45 nonaka
335 1.4 nonaka static int iwm_parse_nvm_data(struct iwm_softc *, const uint16_t *,
336 1.45 nonaka const uint16_t *, const uint16_t *, const uint16_t *,
337 1.45 nonaka const uint16_t *, const uint16_t *);
338 1.45 nonaka static void iwm_set_hw_address_8000(struct iwm_softc *,
339 1.45 nonaka struct iwm_nvm_data *, const uint16_t *, const uint16_t *);
340 1.45 nonaka static int iwm_parse_nvm_sections(struct iwm_softc *,
341 1.45 nonaka struct iwm_nvm_section *);
342 1.4 nonaka static int iwm_nvm_init(struct iwm_softc *);
343 1.45 nonaka static int iwm_firmware_load_sect(struct iwm_softc *, uint32_t,
344 1.45 nonaka const uint8_t *, uint32_t);
345 1.4 nonaka static int iwm_firmware_load_chunk(struct iwm_softc *, uint32_t,
346 1.4 nonaka const uint8_t *, uint32_t);
347 1.71 nonaka static int iwm_load_cpu_sections_7000(struct iwm_softc *,
348 1.71 nonaka struct iwm_fw_sects *, int , int *);
349 1.45 nonaka static int iwm_load_firmware_7000(struct iwm_softc *, enum iwm_ucode_type);
350 1.45 nonaka static int iwm_load_cpu_sections_8000(struct iwm_softc *,
351 1.45 nonaka struct iwm_fw_sects *, int , int *);
352 1.45 nonaka static int iwm_load_firmware_8000(struct iwm_softc *, enum iwm_ucode_type);
353 1.4 nonaka static int iwm_load_firmware(struct iwm_softc *, enum iwm_ucode_type);
354 1.4 nonaka static int iwm_start_fw(struct iwm_softc *, enum iwm_ucode_type);
355 1.4 nonaka static int iwm_send_tx_ant_cfg(struct iwm_softc *, uint8_t);
356 1.4 nonaka static int iwm_send_phy_cfg_cmd(struct iwm_softc *);
357 1.45 nonaka static int iwm_load_ucode_wait_alive(struct iwm_softc *,
358 1.4 nonaka enum iwm_ucode_type);
359 1.4 nonaka static int iwm_run_init_mvm_ucode(struct iwm_softc *, int);
360 1.4 nonaka static int iwm_rx_addbuf(struct iwm_softc *, int, int);
361 1.45 nonaka static int iwm_calc_rssi(struct iwm_softc *, struct iwm_rx_phy_info *);
362 1.45 nonaka static int iwm_get_signal_strength(struct iwm_softc *,
363 1.4 nonaka struct iwm_rx_phy_info *);
364 1.45 nonaka static void iwm_rx_rx_phy_cmd(struct iwm_softc *,
365 1.4 nonaka struct iwm_rx_packet *, struct iwm_rx_data *);
366 1.45 nonaka static int iwm_get_noise(const struct iwm_statistics_rx_non_phy *);
367 1.45 nonaka static void iwm_rx_rx_mpdu(struct iwm_softc *, struct iwm_rx_packet *,
368 1.4 nonaka struct iwm_rx_data *);
369 1.45 nonaka static void iwm_rx_tx_cmd_single(struct iwm_softc *, struct iwm_rx_packet *, struct iwm_node *);
370 1.45 nonaka static void iwm_rx_tx_cmd(struct iwm_softc *, struct iwm_rx_packet *,
371 1.4 nonaka struct iwm_rx_data *);
372 1.45 nonaka static int iwm_binding_cmd(struct iwm_softc *, struct iwm_node *,
373 1.4 nonaka uint32_t);
374 1.45 nonaka #if 0
375 1.45 nonaka static int iwm_binding_update(struct iwm_softc *, struct iwm_node *, int);
376 1.45 nonaka static int iwm_binding_add_vif(struct iwm_softc *, struct iwm_node *);
377 1.45 nonaka #endif
378 1.45 nonaka static void iwm_phy_ctxt_cmd_hdr(struct iwm_softc *, struct iwm_phy_ctxt *,
379 1.45 nonaka struct iwm_phy_context_cmd *, uint32_t, uint32_t);
380 1.45 nonaka static void iwm_phy_ctxt_cmd_data(struct iwm_softc *,
381 1.4 nonaka struct iwm_phy_context_cmd *, struct ieee80211_channel *,
382 1.4 nonaka uint8_t, uint8_t);
383 1.45 nonaka static int iwm_phy_ctxt_cmd(struct iwm_softc *, struct iwm_phy_ctxt *,
384 1.45 nonaka uint8_t, uint8_t, uint32_t, uint32_t);
385 1.4 nonaka static int iwm_send_cmd(struct iwm_softc *, struct iwm_host_cmd *);
386 1.45 nonaka static int iwm_send_cmd_pdu(struct iwm_softc *, uint32_t, uint32_t,
387 1.4 nonaka uint16_t, const void *);
388 1.45 nonaka static int iwm_send_cmd_status(struct iwm_softc *, struct iwm_host_cmd *,
389 1.45 nonaka uint32_t *);
390 1.45 nonaka static int iwm_send_cmd_pdu_status(struct iwm_softc *, uint32_t, uint16_t,
391 1.45 nonaka const void *, uint32_t *);
392 1.4 nonaka static void iwm_free_resp(struct iwm_softc *, struct iwm_host_cmd *);
393 1.45 nonaka static void iwm_cmd_done(struct iwm_softc *, int qid, int idx);
394 1.4 nonaka #if 0
395 1.4 nonaka static void iwm_update_sched(struct iwm_softc *, int, int, uint8_t,
396 1.4 nonaka uint16_t);
397 1.4 nonaka #endif
398 1.45 nonaka static const struct iwm_rate *
399 1.45 nonaka iwm_tx_fill_cmd(struct iwm_softc *, struct iwm_node *,
400 1.45 nonaka struct ieee80211_frame *, struct iwm_tx_cmd *);
401 1.4 nonaka static int iwm_tx(struct iwm_softc *, struct mbuf *,
402 1.4 nonaka struct ieee80211_node *, int);
403 1.45 nonaka static void iwm_led_enable(struct iwm_softc *);
404 1.45 nonaka static void iwm_led_disable(struct iwm_softc *);
405 1.45 nonaka static int iwm_led_is_enabled(struct iwm_softc *);
406 1.45 nonaka static void iwm_led_blink_timeout(void *);
407 1.45 nonaka static void iwm_led_blink_start(struct iwm_softc *);
408 1.45 nonaka static void iwm_led_blink_stop(struct iwm_softc *);
409 1.45 nonaka static int iwm_beacon_filter_send_cmd(struct iwm_softc *,
410 1.4 nonaka struct iwm_beacon_filter_cmd *);
411 1.45 nonaka static void iwm_beacon_filter_set_cqm_params(struct iwm_softc *,
412 1.4 nonaka struct iwm_node *, struct iwm_beacon_filter_cmd *);
413 1.45 nonaka static int iwm_update_beacon_abort(struct iwm_softc *, struct iwm_node *,
414 1.45 nonaka int);
415 1.45 nonaka static void iwm_power_build_cmd(struct iwm_softc *, struct iwm_node *,
416 1.4 nonaka struct iwm_mac_power_cmd *);
417 1.45 nonaka static int iwm_power_mac_update_mode(struct iwm_softc *,
418 1.4 nonaka struct iwm_node *);
419 1.45 nonaka static int iwm_power_update_device(struct iwm_softc *);
420 1.45 nonaka #ifdef notyet
421 1.45 nonaka static int iwm_enable_beacon_filter(struct iwm_softc *, struct iwm_node *);
422 1.45 nonaka #endif
423 1.45 nonaka static int iwm_disable_beacon_filter(struct iwm_softc *);
424 1.45 nonaka static int iwm_add_sta_cmd(struct iwm_softc *, struct iwm_node *, int);
425 1.45 nonaka static int iwm_add_aux_sta(struct iwm_softc *);
426 1.45 nonaka static uint16_t iwm_scan_rx_chain(struct iwm_softc *);
427 1.45 nonaka static uint32_t iwm_scan_rate_n_flags(struct iwm_softc *, int, int);
428 1.45 nonaka #ifdef notyet
429 1.45 nonaka static uint16_t iwm_get_active_dwell(struct iwm_softc *, int, int);
430 1.45 nonaka static uint16_t iwm_get_passive_dwell(struct iwm_softc *, int);
431 1.45 nonaka #endif
432 1.45 nonaka static uint8_t iwm_lmac_scan_fill_channels(struct iwm_softc *,
433 1.45 nonaka struct iwm_scan_channel_cfg_lmac *, int);
434 1.45 nonaka static int iwm_fill_probe_req(struct iwm_softc *,
435 1.45 nonaka struct iwm_scan_probe_req *);
436 1.45 nonaka static int iwm_lmac_scan(struct iwm_softc *);
437 1.45 nonaka static int iwm_config_umac_scan(struct iwm_softc *);
438 1.45 nonaka static int iwm_umac_scan(struct iwm_softc *);
439 1.45 nonaka static uint8_t iwm_ridx2rate(struct ieee80211_rateset *, int);
440 1.45 nonaka static void iwm_ack_rates(struct iwm_softc *, struct iwm_node *, int *,
441 1.4 nonaka int *);
442 1.45 nonaka static void iwm_mac_ctxt_cmd_common(struct iwm_softc *, struct iwm_node *,
443 1.45 nonaka struct iwm_mac_ctx_cmd *, uint32_t, int);
444 1.45 nonaka static void iwm_mac_ctxt_cmd_fill_sta(struct iwm_softc *, struct iwm_node *,
445 1.45 nonaka struct iwm_mac_data_sta *, int);
446 1.45 nonaka static int iwm_mac_ctxt_cmd(struct iwm_softc *, struct iwm_node *,
447 1.45 nonaka uint32_t, int);
448 1.45 nonaka static int iwm_update_quotas(struct iwm_softc *, struct iwm_node *);
449 1.4 nonaka static int iwm_auth(struct iwm_softc *);
450 1.4 nonaka static int iwm_assoc(struct iwm_softc *);
451 1.4 nonaka static void iwm_calib_timeout(void *);
452 1.45 nonaka #ifndef IEEE80211_NO_HT
453 1.45 nonaka static void iwm_setrates_task(void *);
454 1.45 nonaka static int iwm_setrates(struct iwm_node *);
455 1.45 nonaka #endif
456 1.4 nonaka static int iwm_media_change(struct ifnet *);
457 1.65 nonaka static int iwm_do_newstate(struct ieee80211com *, enum ieee80211_state,
458 1.65 nonaka int);
459 1.5 nonaka static void iwm_newstate_cb(struct work *, void *);
460 1.4 nonaka static int iwm_newstate(struct ieee80211com *, enum ieee80211_state, int);
461 1.50 nonaka static void iwm_endscan(struct iwm_softc *);
462 1.45 nonaka static void iwm_fill_sf_command(struct iwm_softc *, struct iwm_sf_cfg_cmd *,
463 1.45 nonaka struct ieee80211_node *);
464 1.45 nonaka static int iwm_sf_config(struct iwm_softc *, int);
465 1.45 nonaka static int iwm_send_bt_init_conf(struct iwm_softc *);
466 1.45 nonaka static int iwm_send_update_mcc_cmd(struct iwm_softc *, const char *);
467 1.45 nonaka static void iwm_tt_tx_backoff(struct iwm_softc *, uint32_t);
468 1.4 nonaka static int iwm_init_hw(struct iwm_softc *);
469 1.4 nonaka static int iwm_init(struct ifnet *);
470 1.4 nonaka static void iwm_start(struct ifnet *);
471 1.4 nonaka static void iwm_stop(struct ifnet *, int);
472 1.4 nonaka static void iwm_watchdog(struct ifnet *);
473 1.4 nonaka static int iwm_ioctl(struct ifnet *, u_long, void *);
474 1.4 nonaka #ifdef IWM_DEBUG
475 1.4 nonaka static const char *iwm_desc_lookup(uint32_t);
476 1.4 nonaka static void iwm_nic_error(struct iwm_softc *);
477 1.45 nonaka static void iwm_nic_umac_error(struct iwm_softc *);
478 1.4 nonaka #endif
479 1.4 nonaka static void iwm_notif_intr(struct iwm_softc *);
480 1.61 nonaka static int iwm_intr(void *);
481 1.50 nonaka static void iwm_softintr(void *);
482 1.4 nonaka static int iwm_preinit(struct iwm_softc *);
483 1.4 nonaka static void iwm_attach_hook(device_t);
484 1.4 nonaka static void iwm_attach(device_t, device_t, void *);
485 1.87 riastrad static int iwm_config_complete(struct iwm_softc *);
486 1.4 nonaka #if 0
487 1.4 nonaka static void iwm_init_task(void *);
488 1.4 nonaka static int iwm_activate(device_t, enum devact);
489 1.4 nonaka static void iwm_wakeup(struct iwm_softc *);
490 1.4 nonaka #endif
491 1.4 nonaka static void iwm_radiotap_attach(struct iwm_softc *);
492 1.36 nonaka static int iwm_sysctl_fw_loaded_handler(SYSCTLFN_PROTO);
493 1.36 nonaka
494 1.36 nonaka static int iwm_sysctl_root_num;
495 1.60 nonaka static int iwm_lar_disable;
496 1.1 pooka
497 1.61 nonaka #ifndef IWM_DEFAULT_MCC
498 1.61 nonaka #define IWM_DEFAULT_MCC "ZZ"
499 1.61 nonaka #endif
500 1.61 nonaka static char iwm_default_mcc[3] = IWM_DEFAULT_MCC;
501 1.61 nonaka
502 1.1 pooka static int
503 1.1 pooka iwm_firmload(struct iwm_softc *sc)
504 1.1 pooka {
505 1.1 pooka struct iwm_fw_info *fw = &sc->sc_fw;
506 1.1 pooka firmware_handle_t fwh;
507 1.45 nonaka int err;
508 1.1 pooka
509 1.36 nonaka if (ISSET(sc->sc_flags, IWM_FLAG_FW_LOADED))
510 1.36 nonaka return 0;
511 1.36 nonaka
512 1.1 pooka /* Open firmware image. */
513 1.45 nonaka err = firmware_open("if_iwm", sc->sc_fwname, &fwh);
514 1.45 nonaka if (err) {
515 1.1 pooka aprint_error_dev(sc->sc_dev,
516 1.1 pooka "could not get firmware handle %s\n", sc->sc_fwname);
517 1.45 nonaka return err;
518 1.1 pooka }
519 1.1 pooka
520 1.36 nonaka if (fw->fw_rawdata != NULL && fw->fw_rawsize > 0) {
521 1.36 nonaka kmem_free(fw->fw_rawdata, fw->fw_rawsize);
522 1.36 nonaka fw->fw_rawdata = NULL;
523 1.36 nonaka }
524 1.36 nonaka
525 1.1 pooka fw->fw_rawsize = firmware_get_size(fwh);
526 1.1 pooka /*
527 1.1 pooka * Well, this is how the Linux driver checks it ....
528 1.1 pooka */
529 1.1 pooka if (fw->fw_rawsize < sizeof(uint32_t)) {
530 1.1 pooka aprint_error_dev(sc->sc_dev,
531 1.1 pooka "firmware too short: %zd bytes\n", fw->fw_rawsize);
532 1.45 nonaka err = EINVAL;
533 1.1 pooka goto out;
534 1.1 pooka }
535 1.1 pooka
536 1.1 pooka /* Read the firmware. */
537 1.1 pooka fw->fw_rawdata = kmem_alloc(fw->fw_rawsize, KM_SLEEP);
538 1.45 nonaka err = firmware_read(fwh, 0, fw->fw_rawdata, fw->fw_rawsize);
539 1.45 nonaka if (err) {
540 1.1 pooka aprint_error_dev(sc->sc_dev,
541 1.1 pooka "could not read firmware %s\n", sc->sc_fwname);
542 1.1 pooka goto out;
543 1.1 pooka }
544 1.1 pooka
545 1.36 nonaka SET(sc->sc_flags, IWM_FLAG_FW_LOADED);
546 1.1 pooka out:
547 1.1 pooka /* caller will release memory, if necessary */
548 1.1 pooka
549 1.1 pooka firmware_close(fwh);
550 1.45 nonaka return err;
551 1.1 pooka }
552 1.1 pooka
553 1.1 pooka /*
554 1.1 pooka * just maintaining status quo.
555 1.1 pooka */
556 1.1 pooka static void
557 1.45 nonaka iwm_fix_channel(struct iwm_softc *sc, struct mbuf *m)
558 1.1 pooka {
559 1.45 nonaka struct ieee80211com *ic = &sc->sc_ic;
560 1.1 pooka struct ieee80211_frame *wh;
561 1.1 pooka uint8_t subtype;
562 1.1 pooka
563 1.1 pooka wh = mtod(m, struct ieee80211_frame *);
564 1.1 pooka
565 1.1 pooka if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
566 1.1 pooka return;
567 1.1 pooka
568 1.1 pooka subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
569 1.1 pooka
570 1.1 pooka if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
571 1.1 pooka subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP)
572 1.1 pooka return;
573 1.1 pooka
574 1.45 nonaka int chan = le32toh(sc->sc_last_phy_info.channel);
575 1.45 nonaka if (chan < __arraycount(ic->ic_channels))
576 1.45 nonaka ic->ic_curchan = &ic->ic_channels[chan];
577 1.1 pooka }
578 1.1 pooka
579 1.4 nonaka static int
580 1.1 pooka iwm_store_cscheme(struct iwm_softc *sc, uint8_t *data, size_t dlen)
581 1.1 pooka {
582 1.45 nonaka struct iwm_fw_cscheme_list *l = (struct iwm_fw_cscheme_list *)data;
583 1.1 pooka
584 1.1 pooka if (dlen < sizeof(*l) ||
585 1.1 pooka dlen < sizeof(l->size) + l->size * sizeof(*l->cs))
586 1.1 pooka return EINVAL;
587 1.1 pooka
588 1.1 pooka /* we don't actually store anything for now, always use s/w crypto */
589 1.1 pooka
590 1.1 pooka return 0;
591 1.1 pooka }
592 1.1 pooka
593 1.4 nonaka static int
594 1.45 nonaka iwm_firmware_store_section(struct iwm_softc *sc, enum iwm_ucode_type type,
595 1.45 nonaka uint8_t *data, size_t dlen)
596 1.1 pooka {
597 1.1 pooka struct iwm_fw_sects *fws;
598 1.1 pooka struct iwm_fw_onesect *fwone;
599 1.1 pooka
600 1.1 pooka if (type >= IWM_UCODE_TYPE_MAX)
601 1.1 pooka return EINVAL;
602 1.1 pooka if (dlen < sizeof(uint32_t))
603 1.1 pooka return EINVAL;
604 1.1 pooka
605 1.1 pooka fws = &sc->sc_fw.fw_sects[type];
606 1.1 pooka if (fws->fw_count >= IWM_UCODE_SECT_MAX)
607 1.1 pooka return EINVAL;
608 1.1 pooka
609 1.1 pooka fwone = &fws->fw_sect[fws->fw_count];
610 1.1 pooka
611 1.1 pooka /* first 32bit are device load offset */
612 1.1 pooka memcpy(&fwone->fws_devoff, data, sizeof(uint32_t));
613 1.1 pooka
614 1.1 pooka /* rest is data */
615 1.1 pooka fwone->fws_data = data + sizeof(uint32_t);
616 1.1 pooka fwone->fws_len = dlen - sizeof(uint32_t);
617 1.1 pooka
618 1.1 pooka /* for freeing the buffer during driver unload */
619 1.1 pooka fwone->fws_alloc = data;
620 1.1 pooka fwone->fws_allocsize = dlen;
621 1.1 pooka
622 1.1 pooka fws->fw_count++;
623 1.1 pooka fws->fw_totlen += fwone->fws_len;
624 1.1 pooka
625 1.1 pooka return 0;
626 1.1 pooka }
627 1.1 pooka
628 1.1 pooka struct iwm_tlv_calib_data {
629 1.1 pooka uint32_t ucode_type;
630 1.1 pooka struct iwm_tlv_calib_ctrl calib;
631 1.1 pooka } __packed;
632 1.1 pooka
633 1.4 nonaka static int
634 1.1 pooka iwm_set_default_calib(struct iwm_softc *sc, const void *data)
635 1.1 pooka {
636 1.1 pooka const struct iwm_tlv_calib_data *def_calib = data;
637 1.1 pooka uint32_t ucode_type = le32toh(def_calib->ucode_type);
638 1.1 pooka
639 1.1 pooka if (ucode_type >= IWM_UCODE_TYPE_MAX) {
640 1.45 nonaka DPRINTF(("%s: Wrong ucode_type %u for default calibration.\n",
641 1.45 nonaka DEVNAME(sc), ucode_type));
642 1.1 pooka return EINVAL;
643 1.1 pooka }
644 1.1 pooka
645 1.1 pooka sc->sc_default_calib[ucode_type].flow_trigger =
646 1.1 pooka def_calib->calib.flow_trigger;
647 1.1 pooka sc->sc_default_calib[ucode_type].event_trigger =
648 1.1 pooka def_calib->calib.event_trigger;
649 1.1 pooka
650 1.1 pooka return 0;
651 1.1 pooka }
652 1.1 pooka
653 1.4 nonaka static int
654 1.61 nonaka iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
655 1.1 pooka {
656 1.1 pooka struct iwm_fw_info *fw = &sc->sc_fw;
657 1.8 nonaka struct iwm_tlv_ucode_header *uhdr;
658 1.8 nonaka struct iwm_ucode_tlv tlv;
659 1.1 pooka enum iwm_ucode_tlv_type tlv_type;
660 1.1 pooka uint8_t *data;
661 1.45 nonaka int err, status;
662 1.2 nonaka size_t len;
663 1.1 pooka
664 1.61 nonaka if (ucode_type != IWM_UCODE_TYPE_INIT &&
665 1.61 nonaka fw->fw_status == IWM_FW_STATUS_DONE)
666 1.61 nonaka return 0;
667 1.61 nonaka
668 1.1 pooka if (fw->fw_status == IWM_FW_STATUS_NONE) {
669 1.1 pooka fw->fw_status = IWM_FW_STATUS_INPROGRESS;
670 1.1 pooka } else {
671 1.1 pooka while (fw->fw_status == IWM_FW_STATUS_INPROGRESS)
672 1.1 pooka tsleep(&sc->sc_fw, 0, "iwmfwp", 0);
673 1.1 pooka }
674 1.1 pooka status = fw->fw_status;
675 1.1 pooka
676 1.1 pooka if (status == IWM_FW_STATUS_DONE)
677 1.1 pooka return 0;
678 1.1 pooka
679 1.45 nonaka err = iwm_firmload(sc);
680 1.45 nonaka if (err) {
681 1.3 nonaka aprint_error_dev(sc->sc_dev,
682 1.3 nonaka "could not read firmware %s (error %d)\n",
683 1.45 nonaka sc->sc_fwname, err);
684 1.1 pooka goto out;
685 1.1 pooka }
686 1.1 pooka
687 1.45 nonaka sc->sc_capaflags = 0;
688 1.45 nonaka sc->sc_capa_n_scan_channels = IWM_MAX_NUM_SCAN_CHANNELS;
689 1.45 nonaka memset(sc->sc_enabled_capa, 0, sizeof(sc->sc_enabled_capa));
690 1.45 nonaka memset(sc->sc_fw_mcc, 0, sizeof(sc->sc_fw_mcc));
691 1.1 pooka
692 1.1 pooka uhdr = (void *)fw->fw_rawdata;
693 1.1 pooka if (*(uint32_t *)fw->fw_rawdata != 0
694 1.1 pooka || le32toh(uhdr->magic) != IWM_TLV_UCODE_MAGIC) {
695 1.3 nonaka aprint_error_dev(sc->sc_dev, "invalid firmware %s\n",
696 1.3 nonaka sc->sc_fwname);
697 1.45 nonaka err = EINVAL;
698 1.1 pooka goto out;
699 1.1 pooka }
700 1.1 pooka
701 1.45 nonaka snprintf(sc->sc_fwver, sizeof(sc->sc_fwver), "%d.%d (API ver %d)",
702 1.45 nonaka IWM_UCODE_MAJOR(le32toh(uhdr->ver)),
703 1.45 nonaka IWM_UCODE_MINOR(le32toh(uhdr->ver)),
704 1.45 nonaka IWM_UCODE_API(le32toh(uhdr->ver)));
705 1.1 pooka data = uhdr->data;
706 1.1 pooka len = fw->fw_rawsize - sizeof(*uhdr);
707 1.1 pooka
708 1.1 pooka while (len >= sizeof(tlv)) {
709 1.2 nonaka size_t tlv_len;
710 1.1 pooka void *tlv_data;
711 1.1 pooka
712 1.1 pooka memcpy(&tlv, data, sizeof(tlv));
713 1.1 pooka tlv_len = le32toh(tlv.length);
714 1.1 pooka tlv_type = le32toh(tlv.type);
715 1.1 pooka
716 1.1 pooka len -= sizeof(tlv);
717 1.1 pooka data += sizeof(tlv);
718 1.1 pooka tlv_data = data;
719 1.1 pooka
720 1.1 pooka if (len < tlv_len) {
721 1.3 nonaka aprint_error_dev(sc->sc_dev,
722 1.3 nonaka "firmware too short: %zu bytes\n", len);
723 1.45 nonaka err = EINVAL;
724 1.1 pooka goto parse_out;
725 1.1 pooka }
726 1.1 pooka
727 1.45 nonaka switch (tlv_type) {
728 1.1 pooka case IWM_UCODE_TLV_PROBE_MAX_LEN:
729 1.1 pooka if (tlv_len < sizeof(uint32_t)) {
730 1.45 nonaka err = EINVAL;
731 1.1 pooka goto parse_out;
732 1.1 pooka }
733 1.1 pooka sc->sc_capa_max_probe_len
734 1.1 pooka = le32toh(*(uint32_t *)tlv_data);
735 1.1 pooka /* limit it to something sensible */
736 1.45 nonaka if (sc->sc_capa_max_probe_len >
737 1.45 nonaka IWM_SCAN_OFFLOAD_PROBE_REQ_SIZE) {
738 1.45 nonaka err = EINVAL;
739 1.1 pooka goto parse_out;
740 1.1 pooka }
741 1.1 pooka break;
742 1.1 pooka case IWM_UCODE_TLV_PAN:
743 1.1 pooka if (tlv_len) {
744 1.45 nonaka err = EINVAL;
745 1.1 pooka goto parse_out;
746 1.1 pooka }
747 1.1 pooka sc->sc_capaflags |= IWM_UCODE_TLV_FLAGS_PAN;
748 1.1 pooka break;
749 1.1 pooka case IWM_UCODE_TLV_FLAGS:
750 1.1 pooka if (tlv_len < sizeof(uint32_t)) {
751 1.45 nonaka err = EINVAL;
752 1.1 pooka goto parse_out;
753 1.1 pooka }
754 1.71 nonaka if (tlv_len % sizeof(uint32_t)) {
755 1.71 nonaka err = EINVAL;
756 1.71 nonaka goto parse_out;
757 1.71 nonaka }
758 1.1 pooka /*
759 1.1 pooka * Apparently there can be many flags, but Linux driver
760 1.1 pooka * parses only the first one, and so do we.
761 1.1 pooka *
762 1.1 pooka * XXX: why does this override IWM_UCODE_TLV_PAN?
763 1.1 pooka * Intentional or a bug? Observations from
764 1.1 pooka * current firmware file:
765 1.1 pooka * 1) TLV_PAN is parsed first
766 1.1 pooka * 2) TLV_FLAGS contains TLV_FLAGS_PAN
767 1.1 pooka * ==> this resets TLV_PAN to itself... hnnnk
768 1.1 pooka */
769 1.1 pooka sc->sc_capaflags = le32toh(*(uint32_t *)tlv_data);
770 1.1 pooka break;
771 1.1 pooka case IWM_UCODE_TLV_CSCHEME:
772 1.45 nonaka err = iwm_store_cscheme(sc, tlv_data, tlv_len);
773 1.45 nonaka if (err)
774 1.1 pooka goto parse_out;
775 1.1 pooka break;
776 1.45 nonaka case IWM_UCODE_TLV_NUM_OF_CPU: {
777 1.45 nonaka uint32_t num_cpu;
778 1.1 pooka if (tlv_len != sizeof(uint32_t)) {
779 1.45 nonaka err = EINVAL;
780 1.1 pooka goto parse_out;
781 1.1 pooka }
782 1.45 nonaka num_cpu = le32toh(*(uint32_t *)tlv_data);
783 1.71 nonaka if (num_cpu == 2) {
784 1.71 nonaka fw->fw_sects[IWM_UCODE_TYPE_REGULAR].is_dual_cpus =
785 1.71 nonaka true;
786 1.71 nonaka fw->fw_sects[IWM_UCODE_TYPE_INIT].is_dual_cpus =
787 1.71 nonaka true;
788 1.71 nonaka fw->fw_sects[IWM_UCODE_TYPE_WOW].is_dual_cpus =
789 1.71 nonaka true;
790 1.71 nonaka } else if (num_cpu < 1 || num_cpu > 2) {
791 1.45 nonaka err = EINVAL;
792 1.1 pooka goto parse_out;
793 1.1 pooka }
794 1.1 pooka break;
795 1.45 nonaka }
796 1.1 pooka case IWM_UCODE_TLV_SEC_RT:
797 1.45 nonaka err = iwm_firmware_store_section(sc,
798 1.45 nonaka IWM_UCODE_TYPE_REGULAR, tlv_data, tlv_len);
799 1.45 nonaka if (err)
800 1.1 pooka goto parse_out;
801 1.1 pooka break;
802 1.1 pooka case IWM_UCODE_TLV_SEC_INIT:
803 1.45 nonaka err = iwm_firmware_store_section(sc,
804 1.45 nonaka IWM_UCODE_TYPE_INIT, tlv_data, tlv_len);
805 1.45 nonaka if (err)
806 1.1 pooka goto parse_out;
807 1.1 pooka break;
808 1.1 pooka case IWM_UCODE_TLV_SEC_WOWLAN:
809 1.45 nonaka err = iwm_firmware_store_section(sc,
810 1.45 nonaka IWM_UCODE_TYPE_WOW, tlv_data, tlv_len);
811 1.45 nonaka if (err)
812 1.1 pooka goto parse_out;
813 1.1 pooka break;
814 1.1 pooka case IWM_UCODE_TLV_DEF_CALIB:
815 1.1 pooka if (tlv_len != sizeof(struct iwm_tlv_calib_data)) {
816 1.45 nonaka err = EINVAL;
817 1.1 pooka goto parse_out;
818 1.1 pooka }
819 1.45 nonaka err = iwm_set_default_calib(sc, tlv_data);
820 1.45 nonaka if (err)
821 1.1 pooka goto parse_out;
822 1.1 pooka break;
823 1.1 pooka case IWM_UCODE_TLV_PHY_SKU:
824 1.1 pooka if (tlv_len != sizeof(uint32_t)) {
825 1.45 nonaka err = EINVAL;
826 1.1 pooka goto parse_out;
827 1.1 pooka }
828 1.1 pooka sc->sc_fw_phy_config = le32toh(*(uint32_t *)tlv_data);
829 1.1 pooka break;
830 1.1 pooka
831 1.45 nonaka case IWM_UCODE_TLV_API_CHANGES_SET: {
832 1.45 nonaka struct iwm_ucode_api *api;
833 1.71 nonaka uint32_t idx, bits;
834 1.71 nonaka int i;
835 1.45 nonaka if (tlv_len != sizeof(*api)) {
836 1.45 nonaka err = EINVAL;
837 1.45 nonaka goto parse_out;
838 1.45 nonaka }
839 1.45 nonaka api = (struct iwm_ucode_api *)tlv_data;
840 1.71 nonaka idx = le32toh(api->api_index);
841 1.71 nonaka bits = le32toh(api->api_flags);
842 1.71 nonaka if (idx >= howmany(IWM_NUM_UCODE_TLV_API, 32)) {
843 1.61 nonaka err = EINVAL;
844 1.45 nonaka goto parse_out;
845 1.45 nonaka }
846 1.71 nonaka for (i = 0; i < 32; i++) {
847 1.71 nonaka if (!ISSET(bits, __BIT(i)))
848 1.71 nonaka continue;
849 1.71 nonaka setbit(sc->sc_ucode_api, i + (32 * idx));
850 1.71 nonaka }
851 1.45 nonaka break;
852 1.45 nonaka }
853 1.45 nonaka
854 1.45 nonaka case IWM_UCODE_TLV_ENABLED_CAPABILITIES: {
855 1.45 nonaka struct iwm_ucode_capa *capa;
856 1.71 nonaka uint32_t idx, bits;
857 1.71 nonaka int i;
858 1.45 nonaka if (tlv_len != sizeof(*capa)) {
859 1.45 nonaka err = EINVAL;
860 1.45 nonaka goto parse_out;
861 1.45 nonaka }
862 1.45 nonaka capa = (struct iwm_ucode_capa *)tlv_data;
863 1.45 nonaka idx = le32toh(capa->api_index);
864 1.71 nonaka bits = le32toh(capa->api_capa);
865 1.45 nonaka if (idx >= howmany(IWM_NUM_UCODE_TLV_CAPA, 32)) {
866 1.61 nonaka err = EINVAL;
867 1.45 nonaka goto parse_out;
868 1.45 nonaka }
869 1.45 nonaka for (i = 0; i < 32; i++) {
870 1.71 nonaka if (!ISSET(bits, __BIT(i)))
871 1.45 nonaka continue;
872 1.45 nonaka setbit(sc->sc_enabled_capa, i + (32 * idx));
873 1.45 nonaka }
874 1.45 nonaka break;
875 1.45 nonaka }
876 1.45 nonaka
877 1.45 nonaka case IWM_UCODE_TLV_FW_UNDOCUMENTED1:
878 1.45 nonaka case IWM_UCODE_TLV_SDIO_ADMA_ADDR:
879 1.45 nonaka case IWM_UCODE_TLV_FW_GSCAN_CAPA:
880 1.71 nonaka case IWM_UCODE_TLV_FW_MEM_SEG:
881 1.1 pooka /* ignore, not used by current driver */
882 1.1 pooka break;
883 1.1 pooka
884 1.45 nonaka case IWM_UCODE_TLV_SEC_RT_USNIFFER:
885 1.45 nonaka err = iwm_firmware_store_section(sc,
886 1.45 nonaka IWM_UCODE_TYPE_REGULAR_USNIFFER, tlv_data,
887 1.45 nonaka tlv_len);
888 1.45 nonaka if (err)
889 1.45 nonaka goto parse_out;
890 1.45 nonaka break;
891 1.45 nonaka
892 1.71 nonaka case IWM_UCODE_TLV_PAGING: {
893 1.71 nonaka uint32_t paging_mem_size;
894 1.71 nonaka if (tlv_len != sizeof(paging_mem_size)) {
895 1.71 nonaka err = EINVAL;
896 1.71 nonaka goto parse_out;
897 1.71 nonaka }
898 1.71 nonaka paging_mem_size = le32toh(*(uint32_t *)tlv_data);
899 1.71 nonaka if (paging_mem_size > IWM_MAX_PAGING_IMAGE_SIZE) {
900 1.71 nonaka err = EINVAL;
901 1.71 nonaka goto parse_out;
902 1.71 nonaka }
903 1.71 nonaka if (paging_mem_size & (IWM_FW_PAGING_SIZE - 1)) {
904 1.71 nonaka err = EINVAL;
905 1.71 nonaka goto parse_out;
906 1.71 nonaka }
907 1.71 nonaka fw->fw_sects[IWM_UCODE_TYPE_REGULAR].paging_mem_size =
908 1.71 nonaka paging_mem_size;
909 1.71 nonaka fw->fw_sects[IWM_UCODE_TYPE_REGULAR_USNIFFER].paging_mem_size =
910 1.71 nonaka paging_mem_size;
911 1.71 nonaka break;
912 1.71 nonaka }
913 1.71 nonaka
914 1.45 nonaka case IWM_UCODE_TLV_N_SCAN_CHANNELS:
915 1.45 nonaka if (tlv_len != sizeof(uint32_t)) {
916 1.45 nonaka err = EINVAL;
917 1.45 nonaka goto parse_out;
918 1.45 nonaka }
919 1.45 nonaka sc->sc_capa_n_scan_channels =
920 1.45 nonaka le32toh(*(uint32_t *)tlv_data);
921 1.45 nonaka break;
922 1.45 nonaka
923 1.45 nonaka case IWM_UCODE_TLV_FW_VERSION:
924 1.45 nonaka if (tlv_len != sizeof(uint32_t) * 3) {
925 1.45 nonaka err = EINVAL;
926 1.45 nonaka goto parse_out;
927 1.45 nonaka }
928 1.45 nonaka snprintf(sc->sc_fwver, sizeof(sc->sc_fwver),
929 1.45 nonaka "%d.%d.%d",
930 1.45 nonaka le32toh(((uint32_t *)tlv_data)[0]),
931 1.45 nonaka le32toh(((uint32_t *)tlv_data)[1]),
932 1.45 nonaka le32toh(((uint32_t *)tlv_data)[2]));
933 1.45 nonaka break;
934 1.45 nonaka
935 1.1 pooka default:
936 1.2 nonaka DPRINTF(("%s: unknown firmware section %d, abort\n",
937 1.2 nonaka DEVNAME(sc), tlv_type));
938 1.45 nonaka err = EINVAL;
939 1.1 pooka goto parse_out;
940 1.1 pooka }
941 1.1 pooka
942 1.1 pooka len -= roundup(tlv_len, 4);
943 1.1 pooka data += roundup(tlv_len, 4);
944 1.1 pooka }
945 1.1 pooka
946 1.45 nonaka KASSERT(err == 0);
947 1.1 pooka
948 1.1 pooka parse_out:
949 1.45 nonaka if (err) {
950 1.3 nonaka aprint_error_dev(sc->sc_dev,
951 1.3 nonaka "firmware parse error, section type %d\n", tlv_type);
952 1.1 pooka }
953 1.1 pooka
954 1.1 pooka if (!(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) {
955 1.3 nonaka aprint_error_dev(sc->sc_dev,
956 1.3 nonaka "device uses unsupported power ops\n");
957 1.45 nonaka err = ENOTSUP;
958 1.1 pooka }
959 1.1 pooka
960 1.1 pooka out:
961 1.45 nonaka if (err)
962 1.2 nonaka fw->fw_status = IWM_FW_STATUS_NONE;
963 1.2 nonaka else
964 1.1 pooka fw->fw_status = IWM_FW_STATUS_DONE;
965 1.1 pooka wakeup(&sc->sc_fw);
966 1.1 pooka
967 1.45 nonaka if (err && fw->fw_rawdata != NULL) {
968 1.1 pooka kmem_free(fw->fw_rawdata, fw->fw_rawsize);
969 1.1 pooka fw->fw_rawdata = NULL;
970 1.36 nonaka CLR(sc->sc_flags, IWM_FLAG_FW_LOADED);
971 1.45 nonaka /* don't touch fw->fw_status */
972 1.45 nonaka memset(fw->fw_sects, 0, sizeof(fw->fw_sects));
973 1.1 pooka }
974 1.45 nonaka return err;
975 1.1 pooka }
976 1.1 pooka
977 1.4 nonaka static uint32_t
978 1.1 pooka iwm_read_prph(struct iwm_softc *sc, uint32_t addr)
979 1.1 pooka {
980 1.1 pooka IWM_WRITE(sc,
981 1.1 pooka IWM_HBUS_TARG_PRPH_RADDR, ((addr & 0x000fffff) | (3 << 24)));
982 1.1 pooka IWM_BARRIER_READ_WRITE(sc);
983 1.1 pooka return IWM_READ(sc, IWM_HBUS_TARG_PRPH_RDAT);
984 1.1 pooka }
985 1.1 pooka
986 1.4 nonaka static void
987 1.1 pooka iwm_write_prph(struct iwm_softc *sc, uint32_t addr, uint32_t val)
988 1.1 pooka {
989 1.1 pooka IWM_WRITE(sc,
990 1.1 pooka IWM_HBUS_TARG_PRPH_WADDR, ((addr & 0x000fffff) | (3 << 24)));
991 1.1 pooka IWM_BARRIER_WRITE(sc);
992 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_PRPH_WDAT, val);
993 1.1 pooka }
994 1.1 pooka
995 1.4 nonaka #ifdef IWM_DEBUG
996 1.4 nonaka static int
997 1.1 pooka iwm_read_mem(struct iwm_softc *sc, uint32_t addr, void *buf, int dwords)
998 1.1 pooka {
999 1.53 nonaka int offs;
1000 1.1 pooka uint32_t *vals = buf;
1001 1.1 pooka
1002 1.1 pooka if (iwm_nic_lock(sc)) {
1003 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_MEM_RADDR, addr);
1004 1.1 pooka for (offs = 0; offs < dwords; offs++)
1005 1.1 pooka vals[offs] = IWM_READ(sc, IWM_HBUS_TARG_MEM_RDAT);
1006 1.1 pooka iwm_nic_unlock(sc);
1007 1.53 nonaka return 0;
1008 1.1 pooka }
1009 1.53 nonaka return EBUSY;
1010 1.1 pooka }
1011 1.4 nonaka #endif
1012 1.1 pooka
1013 1.4 nonaka static int
1014 1.1 pooka iwm_write_mem(struct iwm_softc *sc, uint32_t addr, const void *buf, int dwords)
1015 1.1 pooka {
1016 1.5 nonaka int offs;
1017 1.1 pooka const uint32_t *vals = buf;
1018 1.1 pooka
1019 1.1 pooka if (iwm_nic_lock(sc)) {
1020 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WADDR, addr);
1021 1.1 pooka /* WADDR auto-increments */
1022 1.1 pooka for (offs = 0; offs < dwords; offs++) {
1023 1.1 pooka uint32_t val = vals ? vals[offs] : 0;
1024 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WDAT, val);
1025 1.1 pooka }
1026 1.1 pooka iwm_nic_unlock(sc);
1027 1.53 nonaka return 0;
1028 1.1 pooka }
1029 1.53 nonaka return EBUSY;
1030 1.1 pooka }
1031 1.1 pooka
1032 1.4 nonaka static int
1033 1.1 pooka iwm_write_mem32(struct iwm_softc *sc, uint32_t addr, uint32_t val)
1034 1.1 pooka {
1035 1.1 pooka return iwm_write_mem(sc, addr, &val, 1);
1036 1.1 pooka }
1037 1.1 pooka
1038 1.4 nonaka static int
1039 1.45 nonaka iwm_poll_bit(struct iwm_softc *sc, int reg, uint32_t bits, uint32_t mask,
1040 1.45 nonaka int timo)
1041 1.1 pooka {
1042 1.1 pooka for (;;) {
1043 1.1 pooka if ((IWM_READ(sc, reg) & mask) == (bits & mask)) {
1044 1.1 pooka return 1;
1045 1.1 pooka }
1046 1.1 pooka if (timo < 10) {
1047 1.1 pooka return 0;
1048 1.1 pooka }
1049 1.1 pooka timo -= 10;
1050 1.1 pooka DELAY(10);
1051 1.1 pooka }
1052 1.1 pooka }
1053 1.1 pooka
1054 1.4 nonaka static int
1055 1.1 pooka iwm_nic_lock(struct iwm_softc *sc)
1056 1.1 pooka {
1057 1.1 pooka int rv = 0;
1058 1.1 pooka
1059 1.59 nonaka if (sc->sc_cmd_hold_nic_awake)
1060 1.59 nonaka return 1;
1061 1.59 nonaka
1062 1.1 pooka IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
1063 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1064 1.1 pooka
1065 1.45 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000)
1066 1.45 nonaka DELAY(2);
1067 1.45 nonaka
1068 1.1 pooka if (iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
1069 1.1 pooka IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
1070 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
1071 1.1 pooka | IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP, 15000)) {
1072 1.38 ozaki rv = 1;
1073 1.1 pooka } else {
1074 1.69 nonaka DPRINTF(("%s: resetting device via NMI\n", DEVNAME(sc)));
1075 1.1 pooka IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_FORCE_NMI);
1076 1.1 pooka }
1077 1.1 pooka
1078 1.1 pooka return rv;
1079 1.1 pooka }
1080 1.1 pooka
1081 1.4 nonaka static void
1082 1.1 pooka iwm_nic_unlock(struct iwm_softc *sc)
1083 1.1 pooka {
1084 1.59 nonaka
1085 1.59 nonaka if (sc->sc_cmd_hold_nic_awake)
1086 1.59 nonaka return;
1087 1.59 nonaka
1088 1.1 pooka IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
1089 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1090 1.1 pooka }
1091 1.1 pooka
1092 1.4 nonaka static void
1093 1.45 nonaka iwm_set_bits_mask_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits,
1094 1.45 nonaka uint32_t mask)
1095 1.1 pooka {
1096 1.1 pooka uint32_t val;
1097 1.1 pooka
1098 1.1 pooka /* XXX: no error path? */
1099 1.1 pooka if (iwm_nic_lock(sc)) {
1100 1.1 pooka val = iwm_read_prph(sc, reg) & mask;
1101 1.1 pooka val |= bits;
1102 1.1 pooka iwm_write_prph(sc, reg, val);
1103 1.1 pooka iwm_nic_unlock(sc);
1104 1.1 pooka }
1105 1.1 pooka }
1106 1.1 pooka
1107 1.4 nonaka static void
1108 1.1 pooka iwm_set_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits)
1109 1.1 pooka {
1110 1.1 pooka iwm_set_bits_mask_prph(sc, reg, bits, ~0);
1111 1.1 pooka }
1112 1.1 pooka
1113 1.4 nonaka static void
1114 1.1 pooka iwm_clear_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits)
1115 1.1 pooka {
1116 1.1 pooka iwm_set_bits_mask_prph(sc, reg, 0, ~bits);
1117 1.1 pooka }
1118 1.1 pooka
1119 1.4 nonaka static int
1120 1.1 pooka iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
1121 1.1 pooka bus_size_t size, bus_size_t alignment)
1122 1.1 pooka {
1123 1.45 nonaka int nsegs, err;
1124 1.1 pooka void *va;
1125 1.1 pooka
1126 1.1 pooka dma->tag = tag;
1127 1.1 pooka dma->size = size;
1128 1.1 pooka
1129 1.45 nonaka err = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT,
1130 1.1 pooka &dma->map);
1131 1.45 nonaka if (err)
1132 1.1 pooka goto fail;
1133 1.1 pooka
1134 1.45 nonaka err = bus_dmamem_alloc(tag, size, alignment, 0, &dma->seg, 1, &nsegs,
1135 1.1 pooka BUS_DMA_NOWAIT);
1136 1.45 nonaka if (err)
1137 1.1 pooka goto fail;
1138 1.1 pooka
1139 1.45 nonaka err = bus_dmamem_map(tag, &dma->seg, 1, size, &va, BUS_DMA_NOWAIT);
1140 1.45 nonaka if (err)
1141 1.1 pooka goto fail;
1142 1.1 pooka dma->vaddr = va;
1143 1.1 pooka
1144 1.45 nonaka err = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
1145 1.1 pooka BUS_DMA_NOWAIT);
1146 1.45 nonaka if (err)
1147 1.1 pooka goto fail;
1148 1.1 pooka
1149 1.1 pooka memset(dma->vaddr, 0, size);
1150 1.1 pooka bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
1151 1.1 pooka dma->paddr = dma->map->dm_segs[0].ds_addr;
1152 1.1 pooka
1153 1.1 pooka return 0;
1154 1.1 pooka
1155 1.1 pooka fail: iwm_dma_contig_free(dma);
1156 1.45 nonaka return err;
1157 1.1 pooka }
1158 1.1 pooka
1159 1.4 nonaka static void
1160 1.1 pooka iwm_dma_contig_free(struct iwm_dma_info *dma)
1161 1.1 pooka {
1162 1.1 pooka if (dma->map != NULL) {
1163 1.1 pooka if (dma->vaddr != NULL) {
1164 1.1 pooka bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,
1165 1.1 pooka BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1166 1.1 pooka bus_dmamap_unload(dma->tag, dma->map);
1167 1.1 pooka bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size);
1168 1.1 pooka bus_dmamem_free(dma->tag, &dma->seg, 1);
1169 1.1 pooka dma->vaddr = NULL;
1170 1.1 pooka }
1171 1.1 pooka bus_dmamap_destroy(dma->tag, dma->map);
1172 1.1 pooka dma->map = NULL;
1173 1.1 pooka }
1174 1.1 pooka }
1175 1.1 pooka
1176 1.4 nonaka static int
1177 1.1 pooka iwm_alloc_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
1178 1.1 pooka {
1179 1.1 pooka bus_size_t size;
1180 1.45 nonaka int i, err;
1181 1.1 pooka
1182 1.1 pooka ring->cur = 0;
1183 1.1 pooka
1184 1.1 pooka /* Allocate RX descriptors (256-byte aligned). */
1185 1.1 pooka size = IWM_RX_RING_COUNT * sizeof(uint32_t);
1186 1.45 nonaka err = iwm_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256);
1187 1.45 nonaka if (err) {
1188 1.3 nonaka aprint_error_dev(sc->sc_dev,
1189 1.3 nonaka "could not allocate RX ring DMA memory\n");
1190 1.1 pooka goto fail;
1191 1.1 pooka }
1192 1.1 pooka ring->desc = ring->desc_dma.vaddr;
1193 1.1 pooka
1194 1.1 pooka /* Allocate RX status area (16-byte aligned). */
1195 1.45 nonaka err = iwm_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma,
1196 1.1 pooka sizeof(*ring->stat), 16);
1197 1.45 nonaka if (err) {
1198 1.3 nonaka aprint_error_dev(sc->sc_dev,
1199 1.3 nonaka "could not allocate RX status DMA memory\n");
1200 1.1 pooka goto fail;
1201 1.1 pooka }
1202 1.1 pooka ring->stat = ring->stat_dma.vaddr;
1203 1.1 pooka
1204 1.1 pooka for (i = 0; i < IWM_RX_RING_COUNT; i++) {
1205 1.1 pooka struct iwm_rx_data *data = &ring->data[i];
1206 1.1 pooka
1207 1.1 pooka memset(data, 0, sizeof(*data));
1208 1.45 nonaka err = bus_dmamap_create(sc->sc_dmat, IWM_RBUF_SIZE, 1,
1209 1.1 pooka IWM_RBUF_SIZE, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
1210 1.1 pooka &data->map);
1211 1.45 nonaka if (err) {
1212 1.3 nonaka aprint_error_dev(sc->sc_dev,
1213 1.3 nonaka "could not create RX buf DMA map\n");
1214 1.1 pooka goto fail;
1215 1.1 pooka }
1216 1.1 pooka
1217 1.45 nonaka err = iwm_rx_addbuf(sc, IWM_RBUF_SIZE, i);
1218 1.45 nonaka if (err)
1219 1.1 pooka goto fail;
1220 1.1 pooka }
1221 1.1 pooka return 0;
1222 1.1 pooka
1223 1.1 pooka fail: iwm_free_rx_ring(sc, ring);
1224 1.45 nonaka return err;
1225 1.1 pooka }
1226 1.1 pooka
1227 1.4 nonaka static void
1228 1.45 nonaka iwm_disable_rx_dma(struct iwm_softc *sc)
1229 1.1 pooka {
1230 1.1 pooka int ntries;
1231 1.1 pooka
1232 1.1 pooka if (iwm_nic_lock(sc)) {
1233 1.1 pooka IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
1234 1.1 pooka for (ntries = 0; ntries < 1000; ntries++) {
1235 1.1 pooka if (IWM_READ(sc, IWM_FH_MEM_RSSR_RX_STATUS_REG) &
1236 1.1 pooka IWM_FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE)
1237 1.1 pooka break;
1238 1.1 pooka DELAY(10);
1239 1.1 pooka }
1240 1.1 pooka iwm_nic_unlock(sc);
1241 1.1 pooka }
1242 1.45 nonaka }
1243 1.45 nonaka
1244 1.45 nonaka void
1245 1.45 nonaka iwm_reset_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
1246 1.45 nonaka {
1247 1.1 pooka ring->cur = 0;
1248 1.45 nonaka memset(ring->stat, 0, sizeof(*ring->stat));
1249 1.45 nonaka bus_dmamap_sync(sc->sc_dmat, ring->stat_dma.map, 0,
1250 1.45 nonaka ring->stat_dma.size, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1251 1.1 pooka }
1252 1.1 pooka
1253 1.4 nonaka static void
1254 1.1 pooka iwm_free_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
1255 1.1 pooka {
1256 1.1 pooka int i;
1257 1.1 pooka
1258 1.1 pooka iwm_dma_contig_free(&ring->desc_dma);
1259 1.1 pooka iwm_dma_contig_free(&ring->stat_dma);
1260 1.1 pooka
1261 1.1 pooka for (i = 0; i < IWM_RX_RING_COUNT; i++) {
1262 1.1 pooka struct iwm_rx_data *data = &ring->data[i];
1263 1.1 pooka
1264 1.1 pooka if (data->m != NULL) {
1265 1.89 mlelstv bus_size_t sz = data->m->m_pkthdr.len;
1266 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1267 1.89 mlelstv sz, BUS_DMASYNC_POSTREAD);
1268 1.1 pooka bus_dmamap_unload(sc->sc_dmat, data->map);
1269 1.1 pooka m_freem(data->m);
1270 1.45 nonaka data->m = NULL;
1271 1.1 pooka }
1272 1.45 nonaka if (data->map != NULL) {
1273 1.1 pooka bus_dmamap_destroy(sc->sc_dmat, data->map);
1274 1.45 nonaka data->map = NULL;
1275 1.45 nonaka }
1276 1.1 pooka }
1277 1.1 pooka }
1278 1.1 pooka
1279 1.4 nonaka static int
1280 1.1 pooka iwm_alloc_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring, int qid)
1281 1.1 pooka {
1282 1.1 pooka bus_addr_t paddr;
1283 1.1 pooka bus_size_t size;
1284 1.61 nonaka int i, err, nsegs;
1285 1.1 pooka
1286 1.1 pooka ring->qid = qid;
1287 1.1 pooka ring->queued = 0;
1288 1.1 pooka ring->cur = 0;
1289 1.1 pooka
1290 1.1 pooka /* Allocate TX descriptors (256-byte aligned). */
1291 1.1 pooka size = IWM_TX_RING_COUNT * sizeof (struct iwm_tfd);
1292 1.45 nonaka err = iwm_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256);
1293 1.45 nonaka if (err) {
1294 1.3 nonaka aprint_error_dev(sc->sc_dev,
1295 1.3 nonaka "could not allocate TX ring DMA memory\n");
1296 1.1 pooka goto fail;
1297 1.1 pooka }
1298 1.1 pooka ring->desc = ring->desc_dma.vaddr;
1299 1.1 pooka
1300 1.1 pooka /*
1301 1.1 pooka * We only use rings 0 through 9 (4 EDCA + cmd) so there is no need
1302 1.1 pooka * to allocate commands space for other rings.
1303 1.1 pooka */
1304 1.45 nonaka if (qid > IWM_CMD_QUEUE)
1305 1.1 pooka return 0;
1306 1.1 pooka
1307 1.1 pooka size = IWM_TX_RING_COUNT * sizeof(struct iwm_device_cmd);
1308 1.45 nonaka err = iwm_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma, size, 4);
1309 1.45 nonaka if (err) {
1310 1.3 nonaka aprint_error_dev(sc->sc_dev,
1311 1.3 nonaka "could not allocate TX cmd DMA memory\n");
1312 1.1 pooka goto fail;
1313 1.1 pooka }
1314 1.1 pooka ring->cmd = ring->cmd_dma.vaddr;
1315 1.1 pooka
1316 1.1 pooka paddr = ring->cmd_dma.paddr;
1317 1.1 pooka for (i = 0; i < IWM_TX_RING_COUNT; i++) {
1318 1.1 pooka struct iwm_tx_data *data = &ring->data[i];
1319 1.45 nonaka size_t mapsize;
1320 1.1 pooka
1321 1.1 pooka data->cmd_paddr = paddr;
1322 1.1 pooka data->scratch_paddr = paddr + sizeof(struct iwm_cmd_header)
1323 1.1 pooka + offsetof(struct iwm_tx_cmd, scratch);
1324 1.1 pooka paddr += sizeof(struct iwm_device_cmd);
1325 1.1 pooka
1326 1.45 nonaka /* FW commands may require more mapped space than packets. */
1327 1.61 nonaka if (qid == IWM_CMD_QUEUE) {
1328 1.61 nonaka mapsize = IWM_RBUF_SIZE;
1329 1.61 nonaka nsegs = 1;
1330 1.61 nonaka } else {
1331 1.45 nonaka mapsize = MCLBYTES;
1332 1.61 nonaka nsegs = IWM_NUM_OF_TBS - 2;
1333 1.61 nonaka }
1334 1.61 nonaka err = bus_dmamap_create(sc->sc_dmat, mapsize, nsegs, mapsize,
1335 1.61 nonaka 0, BUS_DMA_NOWAIT, &data->map);
1336 1.45 nonaka if (err) {
1337 1.3 nonaka aprint_error_dev(sc->sc_dev,
1338 1.3 nonaka "could not create TX buf DMA map\n");
1339 1.1 pooka goto fail;
1340 1.1 pooka }
1341 1.1 pooka }
1342 1.1 pooka KASSERT(paddr == ring->cmd_dma.paddr + size);
1343 1.1 pooka return 0;
1344 1.1 pooka
1345 1.1 pooka fail: iwm_free_tx_ring(sc, ring);
1346 1.45 nonaka return err;
1347 1.1 pooka }
1348 1.1 pooka
1349 1.4 nonaka static void
1350 1.59 nonaka iwm_clear_cmd_in_flight(struct iwm_softc *sc)
1351 1.59 nonaka {
1352 1.59 nonaka
1353 1.59 nonaka if (!sc->apmg_wake_up_wa)
1354 1.59 nonaka return;
1355 1.59 nonaka
1356 1.59 nonaka if (!sc->sc_cmd_hold_nic_awake) {
1357 1.59 nonaka aprint_error_dev(sc->sc_dev,
1358 1.59 nonaka "cmd_hold_nic_awake not set\n");
1359 1.59 nonaka return;
1360 1.59 nonaka }
1361 1.59 nonaka
1362 1.59 nonaka sc->sc_cmd_hold_nic_awake = 0;
1363 1.59 nonaka IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
1364 1.59 nonaka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1365 1.59 nonaka }
1366 1.59 nonaka
1367 1.59 nonaka static int
1368 1.59 nonaka iwm_set_cmd_in_flight(struct iwm_softc *sc)
1369 1.59 nonaka {
1370 1.59 nonaka int ret;
1371 1.59 nonaka
1372 1.59 nonaka /*
1373 1.59 nonaka * wake up the NIC to make sure that the firmware will see the host
1374 1.59 nonaka * command - we will let the NIC sleep once all the host commands
1375 1.59 nonaka * returned. This needs to be done only on NICs that have
1376 1.59 nonaka * apmg_wake_up_wa set.
1377 1.59 nonaka */
1378 1.59 nonaka if (sc->apmg_wake_up_wa && !sc->sc_cmd_hold_nic_awake) {
1379 1.59 nonaka
1380 1.59 nonaka IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
1381 1.59 nonaka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1382 1.59 nonaka
1383 1.59 nonaka ret = iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
1384 1.59 nonaka IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
1385 1.59 nonaka (IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
1386 1.59 nonaka IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
1387 1.59 nonaka 15000);
1388 1.59 nonaka if (ret == 0) {
1389 1.59 nonaka IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
1390 1.59 nonaka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1391 1.59 nonaka aprint_error_dev(sc->sc_dev,
1392 1.59 nonaka "failed to wake NIC for hcmd\n");
1393 1.59 nonaka return EIO;
1394 1.59 nonaka }
1395 1.59 nonaka sc->sc_cmd_hold_nic_awake = 1;
1396 1.59 nonaka }
1397 1.59 nonaka
1398 1.59 nonaka return 0;
1399 1.59 nonaka }
1400 1.59 nonaka static void
1401 1.1 pooka iwm_reset_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring)
1402 1.1 pooka {
1403 1.1 pooka int i;
1404 1.1 pooka
1405 1.1 pooka for (i = 0; i < IWM_TX_RING_COUNT; i++) {
1406 1.1 pooka struct iwm_tx_data *data = &ring->data[i];
1407 1.1 pooka
1408 1.1 pooka if (data->m != NULL) {
1409 1.89 mlelstv bus_size_t sz = data->m->m_pkthdr.len;
1410 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1411 1.89 mlelstv sz, BUS_DMASYNC_POSTWRITE);
1412 1.1 pooka bus_dmamap_unload(sc->sc_dmat, data->map);
1413 1.1 pooka m_freem(data->m);
1414 1.1 pooka data->m = NULL;
1415 1.1 pooka }
1416 1.1 pooka }
1417 1.1 pooka /* Clear TX descriptors. */
1418 1.1 pooka memset(ring->desc, 0, ring->desc_dma.size);
1419 1.1 pooka bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0,
1420 1.1 pooka ring->desc_dma.size, BUS_DMASYNC_PREWRITE);
1421 1.1 pooka sc->qfullmsk &= ~(1 << ring->qid);
1422 1.1 pooka ring->queued = 0;
1423 1.1 pooka ring->cur = 0;
1424 1.59 nonaka
1425 1.59 nonaka if (ring->qid == IWM_CMD_QUEUE && sc->sc_cmd_hold_nic_awake)
1426 1.59 nonaka iwm_clear_cmd_in_flight(sc);
1427 1.1 pooka }
1428 1.1 pooka
1429 1.4 nonaka static void
1430 1.1 pooka iwm_free_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring)
1431 1.1 pooka {
1432 1.1 pooka int i;
1433 1.1 pooka
1434 1.1 pooka iwm_dma_contig_free(&ring->desc_dma);
1435 1.1 pooka iwm_dma_contig_free(&ring->cmd_dma);
1436 1.1 pooka
1437 1.1 pooka for (i = 0; i < IWM_TX_RING_COUNT; i++) {
1438 1.1 pooka struct iwm_tx_data *data = &ring->data[i];
1439 1.1 pooka
1440 1.1 pooka if (data->m != NULL) {
1441 1.89 mlelstv bus_size_t sz = data->m->m_pkthdr.len;
1442 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1443 1.89 mlelstv sz, BUS_DMASYNC_POSTWRITE);
1444 1.1 pooka bus_dmamap_unload(sc->sc_dmat, data->map);
1445 1.1 pooka m_freem(data->m);
1446 1.57 nonaka data->m = NULL;
1447 1.1 pooka }
1448 1.45 nonaka if (data->map != NULL) {
1449 1.1 pooka bus_dmamap_destroy(sc->sc_dmat, data->map);
1450 1.45 nonaka data->map = NULL;
1451 1.45 nonaka }
1452 1.1 pooka }
1453 1.1 pooka }
1454 1.1 pooka
1455 1.4 nonaka static void
1456 1.1 pooka iwm_enable_rfkill_int(struct iwm_softc *sc)
1457 1.1 pooka {
1458 1.1 pooka sc->sc_intmask = IWM_CSR_INT_BIT_RF_KILL;
1459 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
1460 1.1 pooka }
1461 1.1 pooka
1462 1.4 nonaka static int
1463 1.1 pooka iwm_check_rfkill(struct iwm_softc *sc)
1464 1.1 pooka {
1465 1.1 pooka uint32_t v;
1466 1.1 pooka int s;
1467 1.1 pooka int rv;
1468 1.8 nonaka
1469 1.1 pooka s = splnet();
1470 1.1 pooka
1471 1.1 pooka /*
1472 1.1 pooka * "documentation" is not really helpful here:
1473 1.1 pooka * 27: HW_RF_KILL_SW
1474 1.1 pooka * Indicates state of (platform's) hardware RF-Kill switch
1475 1.1 pooka *
1476 1.1 pooka * But apparently when it's off, it's on ...
1477 1.1 pooka */
1478 1.1 pooka v = IWM_READ(sc, IWM_CSR_GP_CNTRL);
1479 1.1 pooka rv = (v & IWM_CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) == 0;
1480 1.1 pooka if (rv) {
1481 1.1 pooka sc->sc_flags |= IWM_FLAG_RFKILL;
1482 1.1 pooka } else {
1483 1.1 pooka sc->sc_flags &= ~IWM_FLAG_RFKILL;
1484 1.1 pooka }
1485 1.1 pooka
1486 1.1 pooka splx(s);
1487 1.1 pooka return rv;
1488 1.1 pooka }
1489 1.1 pooka
1490 1.4 nonaka static void
1491 1.1 pooka iwm_enable_interrupts(struct iwm_softc *sc)
1492 1.1 pooka {
1493 1.1 pooka sc->sc_intmask = IWM_CSR_INI_SET_MASK;
1494 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
1495 1.1 pooka }
1496 1.1 pooka
1497 1.4 nonaka static void
1498 1.1 pooka iwm_restore_interrupts(struct iwm_softc *sc)
1499 1.1 pooka {
1500 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
1501 1.1 pooka }
1502 1.1 pooka
1503 1.4 nonaka static void
1504 1.1 pooka iwm_disable_interrupts(struct iwm_softc *sc)
1505 1.1 pooka {
1506 1.1 pooka int s = splnet();
1507 1.1 pooka
1508 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT_MASK, 0);
1509 1.1 pooka
1510 1.1 pooka /* acknowledge all interrupts */
1511 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT, ~0);
1512 1.1 pooka IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, ~0);
1513 1.1 pooka
1514 1.1 pooka splx(s);
1515 1.1 pooka }
1516 1.1 pooka
1517 1.4 nonaka static void
1518 1.1 pooka iwm_ict_reset(struct iwm_softc *sc)
1519 1.1 pooka {
1520 1.1 pooka iwm_disable_interrupts(sc);
1521 1.1 pooka
1522 1.1 pooka memset(sc->ict_dma.vaddr, 0, IWM_ICT_SIZE);
1523 1.89 mlelstv bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map, 0, sc->ict_dma.size,
1524 1.45 nonaka BUS_DMASYNC_PREWRITE);
1525 1.1 pooka sc->ict_cur = 0;
1526 1.1 pooka
1527 1.45 nonaka /* Set physical address of ICT (4KB aligned). */
1528 1.1 pooka IWM_WRITE(sc, IWM_CSR_DRAM_INT_TBL_REG,
1529 1.1 pooka IWM_CSR_DRAM_INT_TBL_ENABLE
1530 1.1 pooka | IWM_CSR_DRAM_INIT_TBL_WRAP_CHECK
1531 1.45 nonaka | IWM_CSR_DRAM_INIT_TBL_WRITE_POINTER
1532 1.1 pooka | sc->ict_dma.paddr >> IWM_ICT_PADDR_SHIFT);
1533 1.1 pooka
1534 1.1 pooka /* Switch to ICT interrupt mode in driver. */
1535 1.1 pooka sc->sc_flags |= IWM_FLAG_USE_ICT;
1536 1.1 pooka
1537 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT, ~0);
1538 1.1 pooka iwm_enable_interrupts(sc);
1539 1.1 pooka }
1540 1.1 pooka
1541 1.1 pooka #define IWM_HW_READY_TIMEOUT 50
1542 1.4 nonaka static int
1543 1.1 pooka iwm_set_hw_ready(struct iwm_softc *sc)
1544 1.1 pooka {
1545 1.45 nonaka int ready;
1546 1.45 nonaka
1547 1.1 pooka IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
1548 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
1549 1.1 pooka
1550 1.45 nonaka ready = iwm_poll_bit(sc, IWM_CSR_HW_IF_CONFIG_REG,
1551 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
1552 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
1553 1.1 pooka IWM_HW_READY_TIMEOUT);
1554 1.45 nonaka if (ready)
1555 1.45 nonaka IWM_SETBITS(sc, IWM_CSR_MBOX_SET_REG,
1556 1.45 nonaka IWM_CSR_MBOX_SET_REG_OS_ALIVE);
1557 1.45 nonaka
1558 1.45 nonaka return ready;
1559 1.1 pooka }
1560 1.1 pooka #undef IWM_HW_READY_TIMEOUT
1561 1.1 pooka
1562 1.4 nonaka static int
1563 1.1 pooka iwm_prepare_card_hw(struct iwm_softc *sc)
1564 1.1 pooka {
1565 1.1 pooka int t = 0;
1566 1.1 pooka
1567 1.10 nonaka if (iwm_set_hw_ready(sc))
1568 1.45 nonaka return 0;
1569 1.45 nonaka
1570 1.45 nonaka DELAY(100);
1571 1.1 pooka
1572 1.1 pooka /* If HW is not ready, prepare the conditions to check again */
1573 1.1 pooka IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
1574 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_PREPARE);
1575 1.1 pooka
1576 1.1 pooka do {
1577 1.1 pooka if (iwm_set_hw_ready(sc))
1578 1.45 nonaka return 0;
1579 1.1 pooka DELAY(200);
1580 1.1 pooka t += 200;
1581 1.1 pooka } while (t < 150000);
1582 1.1 pooka
1583 1.45 nonaka return ETIMEDOUT;
1584 1.1 pooka }
1585 1.1 pooka
1586 1.4 nonaka static void
1587 1.1 pooka iwm_apm_config(struct iwm_softc *sc)
1588 1.1 pooka {
1589 1.1 pooka pcireg_t reg;
1590 1.1 pooka
1591 1.1 pooka reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
1592 1.1 pooka sc->sc_cap_off + PCIE_LCSR);
1593 1.1 pooka if (reg & PCIE_LCSR_ASPM_L1) {
1594 1.1 pooka /* Um the Linux driver prints "Disabling L0S for this one ... */
1595 1.1 pooka IWM_SETBITS(sc, IWM_CSR_GIO_REG,
1596 1.1 pooka IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
1597 1.1 pooka } else {
1598 1.1 pooka /* ... and "Enabling" here */
1599 1.1 pooka IWM_CLRBITS(sc, IWM_CSR_GIO_REG,
1600 1.1 pooka IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
1601 1.1 pooka }
1602 1.1 pooka }
1603 1.1 pooka
1604 1.1 pooka /*
1605 1.1 pooka * Start up NIC's basic functionality after it has been reset
1606 1.45 nonaka * e.g. after platform boot or shutdown.
1607 1.1 pooka * NOTE: This does not load uCode nor start the embedded processor
1608 1.1 pooka */
1609 1.4 nonaka static int
1610 1.1 pooka iwm_apm_init(struct iwm_softc *sc)
1611 1.1 pooka {
1612 1.45 nonaka int err = 0;
1613 1.1 pooka
1614 1.45 nonaka /* Disable L0S exit timer (platform NMI workaround) */
1615 1.61 nonaka if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) {
1616 1.45 nonaka IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS,
1617 1.45 nonaka IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
1618 1.61 nonaka }
1619 1.1 pooka
1620 1.1 pooka /*
1621 1.1 pooka * Disable L0s without affecting L1;
1622 1.1 pooka * don't wait for ICH L0s (ICH bug W/A)
1623 1.1 pooka */
1624 1.1 pooka IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS,
1625 1.1 pooka IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
1626 1.1 pooka
1627 1.1 pooka /* Set FH wait threshold to maximum (HW error during stress W/A) */
1628 1.1 pooka IWM_SETBITS(sc, IWM_CSR_DBG_HPET_MEM_REG, IWM_CSR_DBG_HPET_MEM_REG_VAL);
1629 1.1 pooka
1630 1.1 pooka /*
1631 1.1 pooka * Enable HAP INTA (interrupt from management bus) to
1632 1.1 pooka * wake device's PCI Express link L1a -> L0s
1633 1.1 pooka */
1634 1.1 pooka IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
1635 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
1636 1.1 pooka
1637 1.1 pooka iwm_apm_config(sc);
1638 1.1 pooka
1639 1.45 nonaka #if 0 /* not for 7k/8k */
1640 1.1 pooka /* Configure analog phase-lock-loop before activating to D0A */
1641 1.1 pooka if (trans->cfg->base_params->pll_cfg_val)
1642 1.1 pooka IWM_SETBITS(trans, IWM_CSR_ANA_PLL_CFG,
1643 1.1 pooka trans->cfg->base_params->pll_cfg_val);
1644 1.1 pooka #endif
1645 1.1 pooka
1646 1.1 pooka /*
1647 1.1 pooka * Set "initialization complete" bit to move adapter from
1648 1.1 pooka * D0U* --> D0A* (powered-up active) state.
1649 1.1 pooka */
1650 1.1 pooka IWM_SETBITS(sc, IWM_CSR_GP_CNTRL, IWM_CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
1651 1.1 pooka
1652 1.1 pooka /*
1653 1.1 pooka * Wait for clock stabilization; once stabilized, access to
1654 1.1 pooka * device-internal resources is supported, e.g. iwm_write_prph()
1655 1.1 pooka * and accesses to uCode SRAM.
1656 1.1 pooka */
1657 1.1 pooka if (!iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
1658 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
1659 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000)) {
1660 1.3 nonaka aprint_error_dev(sc->sc_dev,
1661 1.3 nonaka "timeout waiting for clock stabilization\n");
1662 1.45 nonaka err = ETIMEDOUT;
1663 1.1 pooka goto out;
1664 1.1 pooka }
1665 1.1 pooka
1666 1.17 nonaka if (sc->host_interrupt_operation_mode) {
1667 1.17 nonaka /*
1668 1.17 nonaka * This is a bit of an abuse - This is needed for 7260 / 3160
1669 1.17 nonaka * only check host_interrupt_operation_mode even if this is
1670 1.17 nonaka * not related to host_interrupt_operation_mode.
1671 1.17 nonaka *
1672 1.17 nonaka * Enable the oscillator to count wake up time for L1 exit. This
1673 1.17 nonaka * consumes slightly more power (100uA) - but allows to be sure
1674 1.17 nonaka * that we wake up from L1 on time.
1675 1.17 nonaka *
1676 1.17 nonaka * This looks weird: read twice the same register, discard the
1677 1.17 nonaka * value, set a bit, and yet again, read that same register
1678 1.17 nonaka * just to discard the value. But that's the way the hardware
1679 1.17 nonaka * seems to like it.
1680 1.17 nonaka */
1681 1.17 nonaka iwm_read_prph(sc, IWM_OSC_CLK);
1682 1.17 nonaka iwm_read_prph(sc, IWM_OSC_CLK);
1683 1.17 nonaka iwm_set_bits_prph(sc, IWM_OSC_CLK, IWM_OSC_CLK_FORCE_CONTROL);
1684 1.17 nonaka iwm_read_prph(sc, IWM_OSC_CLK);
1685 1.17 nonaka iwm_read_prph(sc, IWM_OSC_CLK);
1686 1.17 nonaka }
1687 1.1 pooka
1688 1.1 pooka /*
1689 1.1 pooka * Enable DMA clock and wait for it to stabilize.
1690 1.1 pooka *
1691 1.1 pooka * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
1692 1.1 pooka * do not disable clocks. This preserves any hardware bits already
1693 1.1 pooka * set by default in "CLK_CTRL_REG" after reset.
1694 1.1 pooka */
1695 1.45 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
1696 1.45 nonaka iwm_write_prph(sc, IWM_APMG_CLK_EN_REG,
1697 1.45 nonaka IWM_APMG_CLK_VAL_DMA_CLK_RQT);
1698 1.45 nonaka DELAY(20);
1699 1.45 nonaka
1700 1.45 nonaka /* Disable L1-Active */
1701 1.45 nonaka iwm_set_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
1702 1.45 nonaka IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
1703 1.45 nonaka
1704 1.45 nonaka /* Clear the interrupt in APMG if the NIC is in RFKILL */
1705 1.45 nonaka iwm_write_prph(sc, IWM_APMG_RTC_INT_STT_REG,
1706 1.45 nonaka IWM_APMG_RTC_INT_STT_RFKILL);
1707 1.45 nonaka }
1708 1.1 pooka out:
1709 1.45 nonaka if (err)
1710 1.45 nonaka aprint_error_dev(sc->sc_dev, "apm init error %d\n", err);
1711 1.45 nonaka return err;
1712 1.1 pooka }
1713 1.1 pooka
1714 1.4 nonaka static void
1715 1.1 pooka iwm_apm_stop(struct iwm_softc *sc)
1716 1.1 pooka {
1717 1.1 pooka /* stop device's busmaster DMA activity */
1718 1.1 pooka IWM_SETBITS(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_STOP_MASTER);
1719 1.1 pooka
1720 1.1 pooka if (!iwm_poll_bit(sc, IWM_CSR_RESET,
1721 1.1 pooka IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED,
1722 1.1 pooka IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED, 100))
1723 1.3 nonaka aprint_error_dev(sc->sc_dev, "timeout waiting for master\n");
1724 1.3 nonaka DPRINTF(("iwm apm stop\n"));
1725 1.1 pooka }
1726 1.1 pooka
1727 1.4 nonaka static int
1728 1.1 pooka iwm_start_hw(struct iwm_softc *sc)
1729 1.1 pooka {
1730 1.45 nonaka int err;
1731 1.1 pooka
1732 1.45 nonaka err = iwm_prepare_card_hw(sc);
1733 1.45 nonaka if (err)
1734 1.45 nonaka return err;
1735 1.1 pooka
1736 1.8 nonaka /* Reset the entire device */
1737 1.45 nonaka IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_SW_RESET);
1738 1.1 pooka DELAY(10);
1739 1.1 pooka
1740 1.45 nonaka err = iwm_apm_init(sc);
1741 1.45 nonaka if (err)
1742 1.45 nonaka return err;
1743 1.1 pooka
1744 1.1 pooka iwm_enable_rfkill_int(sc);
1745 1.1 pooka iwm_check_rfkill(sc);
1746 1.1 pooka
1747 1.1 pooka return 0;
1748 1.1 pooka }
1749 1.1 pooka
1750 1.4 nonaka static void
1751 1.1 pooka iwm_stop_device(struct iwm_softc *sc)
1752 1.1 pooka {
1753 1.1 pooka int chnl, ntries;
1754 1.1 pooka int qid;
1755 1.1 pooka
1756 1.1 pooka iwm_disable_interrupts(sc);
1757 1.1 pooka sc->sc_flags &= ~IWM_FLAG_USE_ICT;
1758 1.1 pooka
1759 1.45 nonaka /* Deactivate TX scheduler. */
1760 1.1 pooka iwm_write_prph(sc, IWM_SCD_TXFACT, 0);
1761 1.1 pooka
1762 1.1 pooka /* Stop all DMA channels. */
1763 1.1 pooka if (iwm_nic_lock(sc)) {
1764 1.1 pooka for (chnl = 0; chnl < IWM_FH_TCSR_CHNL_NUM; chnl++) {
1765 1.1 pooka IWM_WRITE(sc,
1766 1.1 pooka IWM_FH_TCSR_CHNL_TX_CONFIG_REG(chnl), 0);
1767 1.1 pooka for (ntries = 0; ntries < 200; ntries++) {
1768 1.1 pooka uint32_t r;
1769 1.1 pooka
1770 1.1 pooka r = IWM_READ(sc, IWM_FH_TSSR_TX_STATUS_REG);
1771 1.1 pooka if (r & IWM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(
1772 1.1 pooka chnl))
1773 1.1 pooka break;
1774 1.1 pooka DELAY(20);
1775 1.1 pooka }
1776 1.1 pooka }
1777 1.1 pooka iwm_nic_unlock(sc);
1778 1.1 pooka }
1779 1.45 nonaka iwm_disable_rx_dma(sc);
1780 1.1 pooka
1781 1.1 pooka iwm_reset_rx_ring(sc, &sc->rxq);
1782 1.1 pooka
1783 1.1 pooka for (qid = 0; qid < __arraycount(sc->txq); qid++)
1784 1.1 pooka iwm_reset_tx_ring(sc, &sc->txq[qid]);
1785 1.1 pooka
1786 1.61 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
1787 1.61 nonaka /* Power-down device's busmaster DMA clocks */
1788 1.61 nonaka if (iwm_nic_lock(sc)) {
1789 1.61 nonaka iwm_write_prph(sc, IWM_APMG_CLK_DIS_REG,
1790 1.61 nonaka IWM_APMG_CLK_VAL_DMA_CLK_RQT);
1791 1.61 nonaka DELAY(5);
1792 1.61 nonaka iwm_nic_unlock(sc);
1793 1.61 nonaka }
1794 1.61 nonaka }
1795 1.1 pooka
1796 1.1 pooka /* Make sure (redundant) we've released our request to stay awake */
1797 1.1 pooka IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
1798 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1799 1.1 pooka
1800 1.1 pooka /* Stop the device, and put it in low power state */
1801 1.1 pooka iwm_apm_stop(sc);
1802 1.1 pooka
1803 1.45 nonaka /*
1804 1.45 nonaka * Upon stop, the APM issues an interrupt if HW RF kill is set.
1805 1.8 nonaka * Clean again the interrupt here
1806 1.8 nonaka */
1807 1.1 pooka iwm_disable_interrupts(sc);
1808 1.1 pooka
1809 1.45 nonaka /* Reset the on-board processor. */
1810 1.45 nonaka IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_SW_RESET);
1811 1.45 nonaka
1812 1.45 nonaka /* Even though we stop the HW we still want the RF kill interrupt. */
1813 1.1 pooka iwm_enable_rfkill_int(sc);
1814 1.1 pooka iwm_check_rfkill(sc);
1815 1.1 pooka }
1816 1.1 pooka
1817 1.4 nonaka static void
1818 1.45 nonaka iwm_nic_config(struct iwm_softc *sc)
1819 1.1 pooka {
1820 1.1 pooka uint8_t radio_cfg_type, radio_cfg_step, radio_cfg_dash;
1821 1.1 pooka uint32_t reg_val = 0;
1822 1.1 pooka
1823 1.1 pooka radio_cfg_type = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_TYPE) >>
1824 1.1 pooka IWM_FW_PHY_CFG_RADIO_TYPE_POS;
1825 1.1 pooka radio_cfg_step = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_STEP) >>
1826 1.1 pooka IWM_FW_PHY_CFG_RADIO_STEP_POS;
1827 1.1 pooka radio_cfg_dash = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_DASH) >>
1828 1.1 pooka IWM_FW_PHY_CFG_RADIO_DASH_POS;
1829 1.1 pooka
1830 1.1 pooka reg_val |= IWM_CSR_HW_REV_STEP(sc->sc_hw_rev) <<
1831 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_POS_MAC_STEP;
1832 1.1 pooka reg_val |= IWM_CSR_HW_REV_DASH(sc->sc_hw_rev) <<
1833 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_POS_MAC_DASH;
1834 1.1 pooka
1835 1.1 pooka /* radio configuration */
1836 1.1 pooka reg_val |= radio_cfg_type << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE;
1837 1.1 pooka reg_val |= radio_cfg_step << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_STEP;
1838 1.1 pooka reg_val |= radio_cfg_dash << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_DASH;
1839 1.1 pooka
1840 1.1 pooka IWM_WRITE(sc, IWM_CSR_HW_IF_CONFIG_REG, reg_val);
1841 1.1 pooka
1842 1.8 nonaka DPRINTF(("Radio type=0x%x-0x%x-0x%x\n", radio_cfg_type,
1843 1.8 nonaka radio_cfg_step, radio_cfg_dash));
1844 1.1 pooka
1845 1.1 pooka /*
1846 1.1 pooka * W/A : NIC is stuck in a reset state after Early PCIe power off
1847 1.1 pooka * (PCIe power is lost before PERST# is asserted), causing ME FW
1848 1.1 pooka * to lose ownership and not being able to obtain it back.
1849 1.1 pooka */
1850 1.61 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
1851 1.45 nonaka iwm_set_bits_mask_prph(sc, IWM_APMG_PS_CTRL_REG,
1852 1.45 nonaka IWM_APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
1853 1.45 nonaka ~IWM_APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
1854 1.61 nonaka }
1855 1.1 pooka }
1856 1.1 pooka
1857 1.4 nonaka static int
1858 1.1 pooka iwm_nic_rx_init(struct iwm_softc *sc)
1859 1.1 pooka {
1860 1.1 pooka if (!iwm_nic_lock(sc))
1861 1.1 pooka return EBUSY;
1862 1.1 pooka
1863 1.1 pooka memset(sc->rxq.stat, 0, sizeof(*sc->rxq.stat));
1864 1.45 nonaka bus_dmamap_sync(sc->sc_dmat, sc->rxq.stat_dma.map,
1865 1.45 nonaka 0, sc->rxq.stat_dma.size,
1866 1.45 nonaka BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1867 1.1 pooka
1868 1.45 nonaka iwm_disable_rx_dma(sc);
1869 1.1 pooka IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_RBDCB_WPTR, 0);
1870 1.1 pooka IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ, 0);
1871 1.1 pooka IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_RDPTR, 0);
1872 1.1 pooka IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
1873 1.1 pooka
1874 1.1 pooka /* Set physical address of RX ring (256-byte aligned). */
1875 1.1 pooka IWM_WRITE(sc,
1876 1.1 pooka IWM_FH_RSCSR_CHNL0_RBDCB_BASE_REG, sc->rxq.desc_dma.paddr >> 8);
1877 1.1 pooka
1878 1.1 pooka /* Set physical address of RX status (16-byte aligned). */
1879 1.1 pooka IWM_WRITE(sc,
1880 1.1 pooka IWM_FH_RSCSR_CHNL0_STTS_WPTR_REG, sc->rxq.stat_dma.paddr >> 4);
1881 1.1 pooka
1882 1.1 pooka /* Enable RX. */
1883 1.1 pooka IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG,
1884 1.1 pooka IWM_FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
1885 1.1 pooka IWM_FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | /* HW bug */
1886 1.1 pooka IWM_FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
1887 1.45 nonaka IWM_FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK |
1888 1.61 nonaka IWM_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K |
1889 1.45 nonaka (IWM_RX_RB_TIMEOUT << IWM_FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS) |
1890 1.1 pooka IWM_RX_QUEUE_SIZE_LOG << IWM_FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS);
1891 1.1 pooka
1892 1.1 pooka IWM_WRITE_1(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_TIMEOUT_DEF);
1893 1.17 nonaka
1894 1.17 nonaka /* W/A for interrupt coalescing bug in 7260 and 3160 */
1895 1.17 nonaka if (sc->host_interrupt_operation_mode)
1896 1.17 nonaka IWM_SETBITS(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_OPER_MODE);
1897 1.1 pooka
1898 1.1 pooka /*
1899 1.45 nonaka * This value should initially be 0 (before preparing any RBs),
1900 1.45 nonaka * and should be 8 after preparing the first 8 RBs (for example).
1901 1.1 pooka */
1902 1.1 pooka IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, 8);
1903 1.1 pooka
1904 1.1 pooka iwm_nic_unlock(sc);
1905 1.1 pooka
1906 1.1 pooka return 0;
1907 1.1 pooka }
1908 1.1 pooka
1909 1.4 nonaka static int
1910 1.1 pooka iwm_nic_tx_init(struct iwm_softc *sc)
1911 1.1 pooka {
1912 1.1 pooka int qid;
1913 1.1 pooka
1914 1.1 pooka if (!iwm_nic_lock(sc))
1915 1.1 pooka return EBUSY;
1916 1.1 pooka
1917 1.1 pooka /* Deactivate TX scheduler. */
1918 1.1 pooka iwm_write_prph(sc, IWM_SCD_TXFACT, 0);
1919 1.1 pooka
1920 1.1 pooka /* Set physical address of "keep warm" page (16-byte aligned). */
1921 1.1 pooka IWM_WRITE(sc, IWM_FH_KW_MEM_ADDR_REG, sc->kw_dma.paddr >> 4);
1922 1.1 pooka
1923 1.1 pooka for (qid = 0; qid < __arraycount(sc->txq); qid++) {
1924 1.1 pooka struct iwm_tx_ring *txq = &sc->txq[qid];
1925 1.1 pooka
1926 1.1 pooka /* Set physical address of TX ring (256-byte aligned). */
1927 1.1 pooka IWM_WRITE(sc, IWM_FH_MEM_CBBC_QUEUE(qid),
1928 1.1 pooka txq->desc_dma.paddr >> 8);
1929 1.9 nonaka DPRINTF(("loading ring %d descriptors (%p) at %"PRIxMAX"\n",
1930 1.9 nonaka qid, txq->desc, (uintmax_t)(txq->desc_dma.paddr >> 8)));
1931 1.1 pooka }
1932 1.45 nonaka
1933 1.45 nonaka iwm_write_prph(sc, IWM_SCD_GP_CTRL, IWM_SCD_GP_CTRL_AUTO_ACTIVE_MODE);
1934 1.45 nonaka
1935 1.1 pooka iwm_nic_unlock(sc);
1936 1.1 pooka
1937 1.1 pooka return 0;
1938 1.1 pooka }
1939 1.1 pooka
1940 1.4 nonaka static int
1941 1.1 pooka iwm_nic_init(struct iwm_softc *sc)
1942 1.1 pooka {
1943 1.45 nonaka int err;
1944 1.1 pooka
1945 1.1 pooka iwm_apm_init(sc);
1946 1.61 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
1947 1.45 nonaka iwm_set_bits_mask_prph(sc, IWM_APMG_PS_CTRL_REG,
1948 1.45 nonaka IWM_APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
1949 1.45 nonaka ~IWM_APMG_PS_CTRL_MSK_PWR_SRC);
1950 1.61 nonaka }
1951 1.1 pooka
1952 1.45 nonaka iwm_nic_config(sc);
1953 1.1 pooka
1954 1.45 nonaka err = iwm_nic_rx_init(sc);
1955 1.45 nonaka if (err)
1956 1.45 nonaka return err;
1957 1.1 pooka
1958 1.45 nonaka err = iwm_nic_tx_init(sc);
1959 1.45 nonaka if (err)
1960 1.45 nonaka return err;
1961 1.1 pooka
1962 1.1 pooka DPRINTF(("shadow registers enabled\n"));
1963 1.1 pooka IWM_SETBITS(sc, IWM_CSR_MAC_SHADOW_REG_CTRL, 0x800fffff);
1964 1.1 pooka
1965 1.8 nonaka return 0;
1966 1.1 pooka }
1967 1.1 pooka
1968 1.45 nonaka static const uint8_t iwm_ac_to_tx_fifo[] = {
1969 1.45 nonaka IWM_TX_FIFO_VO,
1970 1.45 nonaka IWM_TX_FIFO_VI,
1971 1.45 nonaka IWM_TX_FIFO_BE,
1972 1.45 nonaka IWM_TX_FIFO_BK,
1973 1.1 pooka };
1974 1.1 pooka
1975 1.45 nonaka static int
1976 1.45 nonaka iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
1977 1.1 pooka {
1978 1.1 pooka if (!iwm_nic_lock(sc)) {
1979 1.2 nonaka DPRINTF(("%s: cannot enable txq %d\n", DEVNAME(sc), qid));
1980 1.45 nonaka return EBUSY;
1981 1.1 pooka }
1982 1.1 pooka
1983 1.45 nonaka IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, qid << 8 | 0);
1984 1.45 nonaka
1985 1.45 nonaka if (qid == IWM_CMD_QUEUE) {
1986 1.45 nonaka iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
1987 1.45 nonaka (0 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE)
1988 1.45 nonaka | (1 << IWM_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
1989 1.45 nonaka
1990 1.61 nonaka iwm_nic_unlock(sc);
1991 1.61 nonaka
1992 1.45 nonaka iwm_clear_bits_prph(sc, IWM_SCD_AGGR_SEL, (1 << qid));
1993 1.45 nonaka
1994 1.61 nonaka if (!iwm_nic_lock(sc))
1995 1.61 nonaka return EBUSY;
1996 1.45 nonaka iwm_write_prph(sc, IWM_SCD_QUEUE_RDPTR(qid), 0);
1997 1.61 nonaka iwm_nic_unlock(sc);
1998 1.45 nonaka
1999 1.45 nonaka iwm_write_mem32(sc,
2000 1.45 nonaka sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid), 0);
2001 1.45 nonaka
2002 1.45 nonaka /* Set scheduler window size and frame limit. */
2003 1.45 nonaka iwm_write_mem32(sc,
2004 1.45 nonaka sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid) +
2005 1.45 nonaka sizeof(uint32_t),
2006 1.45 nonaka ((IWM_FRAME_LIMIT << IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
2007 1.45 nonaka IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
2008 1.45 nonaka ((IWM_FRAME_LIMIT
2009 1.45 nonaka << IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
2010 1.45 nonaka IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
2011 1.45 nonaka
2012 1.61 nonaka if (!iwm_nic_lock(sc))
2013 1.61 nonaka return EBUSY;
2014 1.45 nonaka iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
2015 1.45 nonaka (1 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
2016 1.45 nonaka (fifo << IWM_SCD_QUEUE_STTS_REG_POS_TXF) |
2017 1.45 nonaka (1 << IWM_SCD_QUEUE_STTS_REG_POS_WSL) |
2018 1.45 nonaka IWM_SCD_QUEUE_STTS_REG_MSK);
2019 1.45 nonaka } else {
2020 1.45 nonaka struct iwm_scd_txq_cfg_cmd cmd;
2021 1.45 nonaka int err;
2022 1.1 pooka
2023 1.45 nonaka iwm_nic_unlock(sc);
2024 1.1 pooka
2025 1.45 nonaka memset(&cmd, 0, sizeof(cmd));
2026 1.45 nonaka cmd.scd_queue = qid;
2027 1.45 nonaka cmd.enable = 1;
2028 1.45 nonaka cmd.sta_id = sta_id;
2029 1.45 nonaka cmd.tx_fifo = fifo;
2030 1.45 nonaka cmd.aggregate = 0;
2031 1.45 nonaka cmd.window = IWM_FRAME_LIMIT;
2032 1.45 nonaka
2033 1.45 nonaka err = iwm_send_cmd_pdu(sc, IWM_SCD_QUEUE_CFG, 0, sizeof(cmd),
2034 1.45 nonaka &cmd);
2035 1.45 nonaka if (err)
2036 1.45 nonaka return err;
2037 1.1 pooka
2038 1.45 nonaka if (!iwm_nic_lock(sc))
2039 1.45 nonaka return EBUSY;
2040 1.45 nonaka }
2041 1.1 pooka
2042 1.45 nonaka iwm_write_prph(sc, IWM_SCD_EN_CTRL,
2043 1.45 nonaka iwm_read_prph(sc, IWM_SCD_EN_CTRL) | qid);
2044 1.1 pooka
2045 1.1 pooka iwm_nic_unlock(sc);
2046 1.1 pooka
2047 1.1 pooka DPRINTF(("enabled txq %d FIFO %d\n", qid, fifo));
2048 1.45 nonaka
2049 1.45 nonaka return 0;
2050 1.1 pooka }
2051 1.1 pooka
2052 1.4 nonaka static int
2053 1.1 pooka iwm_post_alive(struct iwm_softc *sc)
2054 1.1 pooka {
2055 1.61 nonaka int nwords = (IWM_SCD_TRANS_TBL_MEM_UPPER_BOUND -
2056 1.61 nonaka IWM_SCD_CONTEXT_MEM_LOWER_BOUND) / sizeof(uint32_t);
2057 1.45 nonaka int err, chnl;
2058 1.45 nonaka uint32_t base;
2059 1.1 pooka
2060 1.1 pooka if (!iwm_nic_lock(sc))
2061 1.1 pooka return EBUSY;
2062 1.1 pooka
2063 1.45 nonaka base = iwm_read_prph(sc, IWM_SCD_SRAM_BASE_ADDR);
2064 1.45 nonaka if (sc->sched_base != base) {
2065 1.45 nonaka DPRINTF(("%s: sched addr mismatch: 0x%08x != 0x%08x\n",
2066 1.45 nonaka DEVNAME(sc), sc->sched_base, base));
2067 1.61 nonaka sc->sched_base = base;
2068 1.1 pooka }
2069 1.1 pooka
2070 1.61 nonaka iwm_nic_unlock(sc);
2071 1.61 nonaka
2072 1.1 pooka iwm_ict_reset(sc);
2073 1.1 pooka
2074 1.1 pooka /* Clear TX scheduler state in SRAM. */
2075 1.45 nonaka err = iwm_write_mem(sc,
2076 1.61 nonaka sc->sched_base + IWM_SCD_CONTEXT_MEM_LOWER_BOUND, NULL, nwords);
2077 1.45 nonaka if (err)
2078 1.61 nonaka return err;
2079 1.61 nonaka
2080 1.61 nonaka if (!iwm_nic_lock(sc))
2081 1.61 nonaka return EBUSY;
2082 1.1 pooka
2083 1.1 pooka /* Set physical address of TX scheduler rings (1KB aligned). */
2084 1.1 pooka iwm_write_prph(sc, IWM_SCD_DRAM_BASE_ADDR, sc->sched_dma.paddr >> 10);
2085 1.1 pooka
2086 1.1 pooka iwm_write_prph(sc, IWM_SCD_CHAINEXT_EN, 0);
2087 1.1 pooka
2088 1.45 nonaka iwm_nic_unlock(sc);
2089 1.45 nonaka
2090 1.1 pooka /* enable command channel */
2091 1.45 nonaka err = iwm_enable_txq(sc, 0 /* unused */, IWM_CMD_QUEUE, 7);
2092 1.45 nonaka if (err)
2093 1.45 nonaka return err;
2094 1.45 nonaka
2095 1.45 nonaka if (!iwm_nic_lock(sc))
2096 1.45 nonaka return EBUSY;
2097 1.1 pooka
2098 1.45 nonaka /* Activate TX scheduler. */
2099 1.1 pooka iwm_write_prph(sc, IWM_SCD_TXFACT, 0xff);
2100 1.1 pooka
2101 1.1 pooka /* Enable DMA channels. */
2102 1.1 pooka for (chnl = 0; chnl < IWM_FH_TCSR_CHNL_NUM; chnl++) {
2103 1.1 pooka IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(chnl),
2104 1.1 pooka IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
2105 1.1 pooka IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
2106 1.1 pooka }
2107 1.1 pooka
2108 1.1 pooka IWM_SETBITS(sc, IWM_FH_TX_CHICKEN_BITS_REG,
2109 1.1 pooka IWM_FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
2110 1.1 pooka
2111 1.8 nonaka /* Enable L1-Active */
2112 1.61 nonaka if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) {
2113 1.45 nonaka iwm_clear_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
2114 1.45 nonaka IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
2115 1.61 nonaka }
2116 1.1 pooka
2117 1.38 ozaki iwm_nic_unlock(sc);
2118 1.61 nonaka
2119 1.61 nonaka return 0;
2120 1.1 pooka }
2121 1.1 pooka
2122 1.1 pooka static struct iwm_phy_db_entry *
2123 1.45 nonaka iwm_phy_db_get_section(struct iwm_softc *sc, enum iwm_phy_db_section_type type,
2124 1.45 nonaka uint16_t chg_id)
2125 1.1 pooka {
2126 1.1 pooka struct iwm_phy_db *phy_db = &sc->sc_phy_db;
2127 1.1 pooka
2128 1.1 pooka if (type >= IWM_PHY_DB_MAX)
2129 1.1 pooka return NULL;
2130 1.1 pooka
2131 1.1 pooka switch (type) {
2132 1.1 pooka case IWM_PHY_DB_CFG:
2133 1.1 pooka return &phy_db->cfg;
2134 1.1 pooka case IWM_PHY_DB_CALIB_NCH:
2135 1.1 pooka return &phy_db->calib_nch;
2136 1.1 pooka case IWM_PHY_DB_CALIB_CHG_PAPD:
2137 1.1 pooka if (chg_id >= IWM_NUM_PAPD_CH_GROUPS)
2138 1.1 pooka return NULL;
2139 1.1 pooka return &phy_db->calib_ch_group_papd[chg_id];
2140 1.1 pooka case IWM_PHY_DB_CALIB_CHG_TXP:
2141 1.1 pooka if (chg_id >= IWM_NUM_TXP_CH_GROUPS)
2142 1.1 pooka return NULL;
2143 1.1 pooka return &phy_db->calib_ch_group_txp[chg_id];
2144 1.1 pooka default:
2145 1.1 pooka return NULL;
2146 1.1 pooka }
2147 1.1 pooka return NULL;
2148 1.1 pooka }
2149 1.1 pooka
2150 1.1 pooka static int
2151 1.1 pooka iwm_phy_db_set_section(struct iwm_softc *sc,
2152 1.5 nonaka struct iwm_calib_res_notif_phy_db *phy_db_notif, uint16_t size)
2153 1.1 pooka {
2154 1.45 nonaka struct iwm_phy_db_entry *entry;
2155 1.1 pooka enum iwm_phy_db_section_type type = le16toh(phy_db_notif->type);
2156 1.1 pooka uint16_t chg_id = 0;
2157 1.1 pooka
2158 1.1 pooka if (type == IWM_PHY_DB_CALIB_CHG_PAPD ||
2159 1.1 pooka type == IWM_PHY_DB_CALIB_CHG_TXP)
2160 1.1 pooka chg_id = le16toh(*(uint16_t *)phy_db_notif->data);
2161 1.1 pooka
2162 1.1 pooka entry = iwm_phy_db_get_section(sc, type, chg_id);
2163 1.1 pooka if (!entry)
2164 1.1 pooka return EINVAL;
2165 1.1 pooka
2166 1.1 pooka if (entry->data)
2167 1.5 nonaka kmem_intr_free(entry->data, entry->size);
2168 1.5 nonaka entry->data = kmem_intr_alloc(size, KM_NOSLEEP);
2169 1.1 pooka if (!entry->data) {
2170 1.1 pooka entry->size = 0;
2171 1.1 pooka return ENOMEM;
2172 1.1 pooka }
2173 1.1 pooka memcpy(entry->data, phy_db_notif->data, size);
2174 1.1 pooka entry->size = size;
2175 1.1 pooka
2176 1.5 nonaka DPRINTFN(10, ("%s(%d): [PHYDB]SET: Type %d, Size: %d, data: %p\n",
2177 1.1 pooka __func__, __LINE__, type, size, entry->data));
2178 1.1 pooka
2179 1.1 pooka return 0;
2180 1.1 pooka }
2181 1.1 pooka
2182 1.4 nonaka static int
2183 1.1 pooka iwm_is_valid_channel(uint16_t ch_id)
2184 1.1 pooka {
2185 1.1 pooka if (ch_id <= 14 ||
2186 1.1 pooka (36 <= ch_id && ch_id <= 64 && ch_id % 4 == 0) ||
2187 1.1 pooka (100 <= ch_id && ch_id <= 140 && ch_id % 4 == 0) ||
2188 1.1 pooka (145 <= ch_id && ch_id <= 165 && ch_id % 4 == 1))
2189 1.1 pooka return 1;
2190 1.1 pooka return 0;
2191 1.1 pooka }
2192 1.1 pooka
2193 1.4 nonaka static uint8_t
2194 1.1 pooka iwm_ch_id_to_ch_index(uint16_t ch_id)
2195 1.1 pooka {
2196 1.1 pooka if (!iwm_is_valid_channel(ch_id))
2197 1.1 pooka return 0xff;
2198 1.1 pooka
2199 1.1 pooka if (ch_id <= 14)
2200 1.1 pooka return ch_id - 1;
2201 1.1 pooka if (ch_id <= 64)
2202 1.1 pooka return (ch_id + 20) / 4;
2203 1.1 pooka if (ch_id <= 140)
2204 1.1 pooka return (ch_id - 12) / 4;
2205 1.1 pooka return (ch_id - 13) / 4;
2206 1.1 pooka }
2207 1.1 pooka
2208 1.1 pooka
2209 1.4 nonaka static uint16_t
2210 1.1 pooka iwm_channel_id_to_papd(uint16_t ch_id)
2211 1.1 pooka {
2212 1.1 pooka if (!iwm_is_valid_channel(ch_id))
2213 1.1 pooka return 0xff;
2214 1.1 pooka
2215 1.1 pooka if (1 <= ch_id && ch_id <= 14)
2216 1.1 pooka return 0;
2217 1.1 pooka if (36 <= ch_id && ch_id <= 64)
2218 1.1 pooka return 1;
2219 1.1 pooka if (100 <= ch_id && ch_id <= 140)
2220 1.1 pooka return 2;
2221 1.1 pooka return 3;
2222 1.1 pooka }
2223 1.1 pooka
2224 1.4 nonaka static uint16_t
2225 1.1 pooka iwm_channel_id_to_txp(struct iwm_softc *sc, uint16_t ch_id)
2226 1.1 pooka {
2227 1.1 pooka struct iwm_phy_db *phy_db = &sc->sc_phy_db;
2228 1.1 pooka struct iwm_phy_db_chg_txp *txp_chg;
2229 1.1 pooka int i;
2230 1.1 pooka uint8_t ch_index = iwm_ch_id_to_ch_index(ch_id);
2231 1.1 pooka
2232 1.1 pooka if (ch_index == 0xff)
2233 1.1 pooka return 0xff;
2234 1.1 pooka
2235 1.1 pooka for (i = 0; i < IWM_NUM_TXP_CH_GROUPS; i++) {
2236 1.1 pooka txp_chg = (void *)phy_db->calib_ch_group_txp[i].data;
2237 1.1 pooka if (!txp_chg)
2238 1.1 pooka return 0xff;
2239 1.1 pooka /*
2240 1.45 nonaka * Looking for the first channel group the max channel
2241 1.45 nonaka * of which is higher than the requested channel.
2242 1.1 pooka */
2243 1.1 pooka if (le16toh(txp_chg->max_channel_idx) >= ch_index)
2244 1.1 pooka return i;
2245 1.1 pooka }
2246 1.1 pooka return 0xff;
2247 1.1 pooka }
2248 1.1 pooka
2249 1.4 nonaka static int
2250 1.45 nonaka iwm_phy_db_get_section_data(struct iwm_softc *sc, uint32_t type, uint8_t **data,
2251 1.45 nonaka uint16_t *size, uint16_t ch_id)
2252 1.1 pooka {
2253 1.1 pooka struct iwm_phy_db_entry *entry;
2254 1.1 pooka uint16_t ch_group_id = 0;
2255 1.1 pooka
2256 1.1 pooka if (type == IWM_PHY_DB_CALIB_CHG_PAPD)
2257 1.1 pooka ch_group_id = iwm_channel_id_to_papd(ch_id);
2258 1.1 pooka else if (type == IWM_PHY_DB_CALIB_CHG_TXP)
2259 1.1 pooka ch_group_id = iwm_channel_id_to_txp(sc, ch_id);
2260 1.1 pooka
2261 1.1 pooka entry = iwm_phy_db_get_section(sc, type, ch_group_id);
2262 1.1 pooka if (!entry)
2263 1.1 pooka return EINVAL;
2264 1.1 pooka
2265 1.1 pooka *data = entry->data;
2266 1.1 pooka *size = entry->size;
2267 1.1 pooka
2268 1.1 pooka DPRINTFN(10, ("%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
2269 1.1 pooka __func__, __LINE__, type, *size));
2270 1.1 pooka
2271 1.1 pooka return 0;
2272 1.1 pooka }
2273 1.1 pooka
2274 1.4 nonaka static int
2275 1.45 nonaka iwm_send_phy_db_cmd(struct iwm_softc *sc, uint16_t type, uint16_t length,
2276 1.45 nonaka void *data)
2277 1.1 pooka {
2278 1.1 pooka struct iwm_phy_db_cmd phy_db_cmd;
2279 1.1 pooka struct iwm_host_cmd cmd = {
2280 1.1 pooka .id = IWM_PHY_DB_CMD,
2281 1.45 nonaka .flags = IWM_CMD_ASYNC,
2282 1.1 pooka };
2283 1.1 pooka
2284 1.5 nonaka DPRINTFN(10, ("Sending PHY-DB hcmd of type %d, of length %d\n",
2285 1.5 nonaka type, length));
2286 1.1 pooka
2287 1.1 pooka phy_db_cmd.type = le16toh(type);
2288 1.1 pooka phy_db_cmd.length = le16toh(length);
2289 1.1 pooka
2290 1.1 pooka cmd.data[0] = &phy_db_cmd;
2291 1.1 pooka cmd.len[0] = sizeof(struct iwm_phy_db_cmd);
2292 1.1 pooka cmd.data[1] = data;
2293 1.1 pooka cmd.len[1] = length;
2294 1.1 pooka
2295 1.1 pooka return iwm_send_cmd(sc, &cmd);
2296 1.1 pooka }
2297 1.1 pooka
2298 1.1 pooka static int
2299 1.1 pooka iwm_phy_db_send_all_channel_groups(struct iwm_softc *sc,
2300 1.45 nonaka enum iwm_phy_db_section_type type, uint8_t max_ch_groups)
2301 1.1 pooka {
2302 1.1 pooka uint16_t i;
2303 1.1 pooka int err;
2304 1.1 pooka struct iwm_phy_db_entry *entry;
2305 1.1 pooka
2306 1.1 pooka /* Send all the channel-specific groups to operational fw */
2307 1.1 pooka for (i = 0; i < max_ch_groups; i++) {
2308 1.1 pooka entry = iwm_phy_db_get_section(sc, type, i);
2309 1.1 pooka if (!entry)
2310 1.1 pooka return EINVAL;
2311 1.1 pooka
2312 1.1 pooka if (!entry->size)
2313 1.1 pooka continue;
2314 1.1 pooka
2315 1.1 pooka err = iwm_send_phy_db_cmd(sc, type, entry->size, entry->data);
2316 1.1 pooka if (err) {
2317 1.2 nonaka DPRINTF(("%s: Can't SEND phy_db section %d (%d), "
2318 1.2 nonaka "err %d\n", DEVNAME(sc), type, i, err));
2319 1.1 pooka return err;
2320 1.1 pooka }
2321 1.1 pooka
2322 1.45 nonaka DPRINTFN(10, ("%s: Sent PHY_DB HCMD, type = %d num = %d\n",
2323 1.45 nonaka DEVNAME(sc), type, i));
2324 1.45 nonaka
2325 1.45 nonaka DELAY(1000);
2326 1.1 pooka }
2327 1.1 pooka
2328 1.1 pooka return 0;
2329 1.1 pooka }
2330 1.1 pooka
2331 1.4 nonaka static int
2332 1.1 pooka iwm_send_phy_db_data(struct iwm_softc *sc)
2333 1.1 pooka {
2334 1.1 pooka uint8_t *data = NULL;
2335 1.1 pooka uint16_t size = 0;
2336 1.1 pooka int err;
2337 1.1 pooka
2338 1.1 pooka err = iwm_phy_db_get_section_data(sc, IWM_PHY_DB_CFG, &data, &size, 0);
2339 1.45 nonaka if (err)
2340 1.1 pooka return err;
2341 1.1 pooka
2342 1.1 pooka err = iwm_send_phy_db_cmd(sc, IWM_PHY_DB_CFG, size, data);
2343 1.45 nonaka if (err)
2344 1.1 pooka return err;
2345 1.1 pooka
2346 1.1 pooka err = iwm_phy_db_get_section_data(sc, IWM_PHY_DB_CALIB_NCH,
2347 1.1 pooka &data, &size, 0);
2348 1.45 nonaka if (err)
2349 1.1 pooka return err;
2350 1.1 pooka
2351 1.1 pooka err = iwm_send_phy_db_cmd(sc, IWM_PHY_DB_CALIB_NCH, size, data);
2352 1.45 nonaka if (err)
2353 1.1 pooka return err;
2354 1.1 pooka
2355 1.1 pooka err = iwm_phy_db_send_all_channel_groups(sc,
2356 1.1 pooka IWM_PHY_DB_CALIB_CHG_PAPD, IWM_NUM_PAPD_CH_GROUPS);
2357 1.45 nonaka if (err)
2358 1.1 pooka return err;
2359 1.1 pooka
2360 1.1 pooka err = iwm_phy_db_send_all_channel_groups(sc,
2361 1.1 pooka IWM_PHY_DB_CALIB_CHG_TXP, IWM_NUM_TXP_CH_GROUPS);
2362 1.45 nonaka if (err)
2363 1.1 pooka return err;
2364 1.1 pooka
2365 1.1 pooka return 0;
2366 1.1 pooka }
2367 1.1 pooka
2368 1.1 pooka /*
2369 1.1 pooka * For the high priority TE use a time event type that has similar priority to
2370 1.1 pooka * the FW's action scan priority.
2371 1.1 pooka */
2372 1.45 nonaka #define IWM_ROC_TE_TYPE_NORMAL IWM_TE_P2P_DEVICE_DISCOVERABLE
2373 1.45 nonaka #define IWM_ROC_TE_TYPE_MGMT_TX IWM_TE_P2P_CLIENT_ASSOC
2374 1.1 pooka
2375 1.1 pooka /* used to convert from time event API v2 to v1 */
2376 1.1 pooka #define IWM_TE_V2_DEP_POLICY_MSK (IWM_TE_V2_DEP_OTHER | IWM_TE_V2_DEP_TSF |\
2377 1.1 pooka IWM_TE_V2_EVENT_SOCIOPATHIC)
2378 1.1 pooka static inline uint16_t
2379 1.1 pooka iwm_te_v2_get_notify(uint16_t policy)
2380 1.1 pooka {
2381 1.1 pooka return le16toh(policy) & IWM_TE_V2_NOTIF_MSK;
2382 1.1 pooka }
2383 1.1 pooka
2384 1.1 pooka static inline uint16_t
2385 1.1 pooka iwm_te_v2_get_dep_policy(uint16_t policy)
2386 1.1 pooka {
2387 1.1 pooka return (le16toh(policy) & IWM_TE_V2_DEP_POLICY_MSK) >>
2388 1.1 pooka IWM_TE_V2_PLACEMENT_POS;
2389 1.1 pooka }
2390 1.1 pooka
2391 1.1 pooka static inline uint16_t
2392 1.1 pooka iwm_te_v2_get_absence(uint16_t policy)
2393 1.1 pooka {
2394 1.1 pooka return (le16toh(policy) & IWM_TE_V2_ABSENCE) >> IWM_TE_V2_ABSENCE_POS;
2395 1.1 pooka }
2396 1.1 pooka
2397 1.4 nonaka static void
2398 1.45 nonaka iwm_te_v2_to_v1(const struct iwm_time_event_cmd_v2 *cmd_v2,
2399 1.45 nonaka struct iwm_time_event_cmd_v1 *cmd_v1)
2400 1.1 pooka {
2401 1.1 pooka cmd_v1->id_and_color = cmd_v2->id_and_color;
2402 1.1 pooka cmd_v1->action = cmd_v2->action;
2403 1.1 pooka cmd_v1->id = cmd_v2->id;
2404 1.1 pooka cmd_v1->apply_time = cmd_v2->apply_time;
2405 1.1 pooka cmd_v1->max_delay = cmd_v2->max_delay;
2406 1.1 pooka cmd_v1->depends_on = cmd_v2->depends_on;
2407 1.1 pooka cmd_v1->interval = cmd_v2->interval;
2408 1.1 pooka cmd_v1->duration = cmd_v2->duration;
2409 1.1 pooka if (cmd_v2->repeat == IWM_TE_V2_REPEAT_ENDLESS)
2410 1.1 pooka cmd_v1->repeat = htole32(IWM_TE_V1_REPEAT_ENDLESS);
2411 1.1 pooka else
2412 1.1 pooka cmd_v1->repeat = htole32(cmd_v2->repeat);
2413 1.1 pooka cmd_v1->max_frags = htole32(cmd_v2->max_frags);
2414 1.1 pooka cmd_v1->interval_reciprocal = 0; /* unused */
2415 1.1 pooka
2416 1.1 pooka cmd_v1->dep_policy = htole32(iwm_te_v2_get_dep_policy(cmd_v2->policy));
2417 1.1 pooka cmd_v1->is_present = htole32(!iwm_te_v2_get_absence(cmd_v2->policy));
2418 1.1 pooka cmd_v1->notify = htole32(iwm_te_v2_get_notify(cmd_v2->policy));
2419 1.1 pooka }
2420 1.1 pooka
2421 1.4 nonaka static int
2422 1.45 nonaka iwm_send_time_event_cmd(struct iwm_softc *sc,
2423 1.45 nonaka const struct iwm_time_event_cmd_v2 *cmd)
2424 1.1 pooka {
2425 1.1 pooka struct iwm_time_event_cmd_v1 cmd_v1;
2426 1.1 pooka
2427 1.1 pooka if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_TIME_EVENT_API_V2)
2428 1.45 nonaka return iwm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(*cmd),
2429 1.45 nonaka cmd);
2430 1.1 pooka
2431 1.45 nonaka iwm_te_v2_to_v1(cmd, &cmd_v1);
2432 1.45 nonaka return iwm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(cmd_v1),
2433 1.45 nonaka &cmd_v1);
2434 1.1 pooka }
2435 1.1 pooka
2436 1.4 nonaka static void
2437 1.45 nonaka iwm_protect_session(struct iwm_softc *sc, struct iwm_node *in,
2438 1.45 nonaka uint32_t duration, uint32_t max_delay)
2439 1.1 pooka {
2440 1.1 pooka struct iwm_time_event_cmd_v2 time_cmd;
2441 1.1 pooka
2442 1.1 pooka memset(&time_cmd, 0, sizeof(time_cmd));
2443 1.1 pooka
2444 1.1 pooka time_cmd.action = htole32(IWM_FW_CTXT_ACTION_ADD);
2445 1.1 pooka time_cmd.id_and_color =
2446 1.1 pooka htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
2447 1.1 pooka time_cmd.id = htole32(IWM_TE_BSS_STA_AGGRESSIVE_ASSOC);
2448 1.1 pooka
2449 1.45 nonaka time_cmd.apply_time = htole32(0);
2450 1.1 pooka
2451 1.1 pooka time_cmd.max_frags = IWM_TE_V2_FRAG_NONE;
2452 1.1 pooka time_cmd.max_delay = htole32(max_delay);
2453 1.1 pooka /* TODO: why do we need to interval = bi if it is not periodic? */
2454 1.1 pooka time_cmd.interval = htole32(1);
2455 1.1 pooka time_cmd.duration = htole32(duration);
2456 1.1 pooka time_cmd.repeat = 1;
2457 1.1 pooka time_cmd.policy
2458 1.45 nonaka = htole16(IWM_TE_V2_NOTIF_HOST_EVENT_START |
2459 1.45 nonaka IWM_TE_V2_NOTIF_HOST_EVENT_END |
2460 1.45 nonaka IWM_T2_V2_START_IMMEDIATELY);
2461 1.1 pooka
2462 1.45 nonaka iwm_send_time_event_cmd(sc, &time_cmd);
2463 1.1 pooka }
2464 1.1 pooka
2465 1.1 pooka /*
2466 1.1 pooka * NVM read access and content parsing. We do not support
2467 1.1 pooka * external NVM or writing NVM.
2468 1.1 pooka */
2469 1.1 pooka
2470 1.1 pooka /* list of NVM sections we are allowed/need to read */
2471 1.45 nonaka static const int iwm_nvm_to_read[] = {
2472 1.1 pooka IWM_NVM_SECTION_TYPE_HW,
2473 1.1 pooka IWM_NVM_SECTION_TYPE_SW,
2474 1.45 nonaka IWM_NVM_SECTION_TYPE_REGULATORY,
2475 1.1 pooka IWM_NVM_SECTION_TYPE_CALIBRATION,
2476 1.1 pooka IWM_NVM_SECTION_TYPE_PRODUCTION,
2477 1.45 nonaka IWM_NVM_SECTION_TYPE_HW_8000,
2478 1.45 nonaka IWM_NVM_SECTION_TYPE_MAC_OVERRIDE,
2479 1.45 nonaka IWM_NVM_SECTION_TYPE_PHY_SKU,
2480 1.1 pooka };
2481 1.1 pooka
2482 1.1 pooka /* Default NVM size to read */
2483 1.45 nonaka #define IWM_NVM_DEFAULT_CHUNK_SIZE (2*1024)
2484 1.61 nonaka #define IWM_MAX_NVM_SECTION_SIZE_7000 (16 * 512 * sizeof(uint16_t)) /*16 KB*/
2485 1.61 nonaka #define IWM_MAX_NVM_SECTION_SIZE_8000 (32 * 512 * sizeof(uint16_t)) /*32 KB*/
2486 1.1 pooka
2487 1.1 pooka #define IWM_NVM_WRITE_OPCODE 1
2488 1.1 pooka #define IWM_NVM_READ_OPCODE 0
2489 1.1 pooka
2490 1.4 nonaka static int
2491 1.45 nonaka iwm_nvm_read_chunk(struct iwm_softc *sc, uint16_t section, uint16_t offset,
2492 1.45 nonaka uint16_t length, uint8_t *data, uint16_t *len)
2493 1.1 pooka {
2494 1.1 pooka offset = 0;
2495 1.1 pooka struct iwm_nvm_access_cmd nvm_access_cmd = {
2496 1.1 pooka .offset = htole16(offset),
2497 1.1 pooka .length = htole16(length),
2498 1.1 pooka .type = htole16(section),
2499 1.1 pooka .op_code = IWM_NVM_READ_OPCODE,
2500 1.1 pooka };
2501 1.1 pooka struct iwm_nvm_access_resp *nvm_resp;
2502 1.1 pooka struct iwm_rx_packet *pkt;
2503 1.1 pooka struct iwm_host_cmd cmd = {
2504 1.1 pooka .id = IWM_NVM_ACCESS_CMD,
2505 1.45 nonaka .flags = (IWM_CMD_WANT_SKB | IWM_CMD_SEND_IN_RFKILL),
2506 1.1 pooka .data = { &nvm_access_cmd, },
2507 1.1 pooka };
2508 1.45 nonaka int err, offset_read;
2509 1.45 nonaka size_t bytes_read;
2510 1.1 pooka uint8_t *resp_data;
2511 1.1 pooka
2512 1.1 pooka cmd.len[0] = sizeof(struct iwm_nvm_access_cmd);
2513 1.1 pooka
2514 1.45 nonaka err = iwm_send_cmd(sc, &cmd);
2515 1.45 nonaka if (err) {
2516 1.45 nonaka DPRINTF(("%s: Could not send NVM_ACCESS command (error=%d)\n",
2517 1.45 nonaka DEVNAME(sc), err));
2518 1.45 nonaka return err;
2519 1.45 nonaka }
2520 1.1 pooka
2521 1.1 pooka pkt = cmd.resp_pkt;
2522 1.1 pooka if (pkt->hdr.flags & IWM_CMD_FAILED_MSK) {
2523 1.45 nonaka err = EIO;
2524 1.1 pooka goto exit;
2525 1.1 pooka }
2526 1.1 pooka
2527 1.1 pooka /* Extract NVM response */
2528 1.1 pooka nvm_resp = (void *)pkt->data;
2529 1.1 pooka
2530 1.45 nonaka err = le16toh(nvm_resp->status);
2531 1.1 pooka bytes_read = le16toh(nvm_resp->length);
2532 1.1 pooka offset_read = le16toh(nvm_resp->offset);
2533 1.1 pooka resp_data = nvm_resp->data;
2534 1.45 nonaka if (err) {
2535 1.45 nonaka err = EINVAL;
2536 1.1 pooka goto exit;
2537 1.1 pooka }
2538 1.1 pooka
2539 1.1 pooka if (offset_read != offset) {
2540 1.45 nonaka err = EINVAL;
2541 1.45 nonaka goto exit;
2542 1.45 nonaka }
2543 1.45 nonaka if (bytes_read > length) {
2544 1.45 nonaka err = EINVAL;
2545 1.1 pooka goto exit;
2546 1.1 pooka }
2547 1.1 pooka
2548 1.1 pooka memcpy(data + offset, resp_data, bytes_read);
2549 1.1 pooka *len = bytes_read;
2550 1.1 pooka
2551 1.1 pooka exit:
2552 1.1 pooka iwm_free_resp(sc, &cmd);
2553 1.45 nonaka return err;
2554 1.1 pooka }
2555 1.1 pooka
2556 1.1 pooka /*
2557 1.1 pooka * Reads an NVM section completely.
2558 1.1 pooka * NICs prior to 7000 family doesn't have a real NVM, but just read
2559 1.1 pooka * section 0 which is the EEPROM. Because the EEPROM reading is unlimited
2560 1.1 pooka * by uCode, we need to manually check in this case that we don't
2561 1.1 pooka * overflow and try to read more than the EEPROM size.
2562 1.1 pooka */
2563 1.4 nonaka static int
2564 1.45 nonaka iwm_nvm_read_section(struct iwm_softc *sc, uint16_t section, uint8_t *data,
2565 1.45 nonaka uint16_t *len, size_t max_len)
2566 1.1 pooka {
2567 1.45 nonaka uint16_t chunklen, seglen;
2568 1.45 nonaka int err;
2569 1.1 pooka
2570 1.45 nonaka chunklen = seglen = IWM_NVM_DEFAULT_CHUNK_SIZE;
2571 1.1 pooka *len = 0;
2572 1.1 pooka
2573 1.45 nonaka /* Read NVM chunks until exhausted (reading less than requested) */
2574 1.45 nonaka while (seglen == chunklen && *len < max_len) {
2575 1.45 nonaka err = iwm_nvm_read_chunk(sc, section, *len, chunklen, data,
2576 1.45 nonaka &seglen);
2577 1.45 nonaka if (err) {
2578 1.61 nonaka DPRINTF(("%s: Cannot read NVM from section %d "
2579 1.45 nonaka "offset %d, length %d\n",
2580 1.45 nonaka DEVNAME(sc), section, *len, chunklen));
2581 1.45 nonaka return err;
2582 1.1 pooka }
2583 1.1 pooka *len += seglen;
2584 1.1 pooka }
2585 1.1 pooka
2586 1.1 pooka DPRINTFN(4, ("NVM section %d read completed\n", section));
2587 1.1 pooka return 0;
2588 1.1 pooka }
2589 1.1 pooka
2590 1.45 nonaka static uint8_t
2591 1.45 nonaka iwm_fw_valid_tx_ant(struct iwm_softc *sc)
2592 1.45 nonaka {
2593 1.45 nonaka uint8_t tx_ant;
2594 1.45 nonaka
2595 1.45 nonaka tx_ant = ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_TX_CHAIN)
2596 1.45 nonaka >> IWM_FW_PHY_CFG_TX_CHAIN_POS);
2597 1.45 nonaka
2598 1.45 nonaka if (sc->sc_nvm.valid_tx_ant)
2599 1.45 nonaka tx_ant &= sc->sc_nvm.valid_tx_ant;
2600 1.45 nonaka
2601 1.45 nonaka return tx_ant;
2602 1.45 nonaka }
2603 1.1 pooka
2604 1.45 nonaka static uint8_t
2605 1.45 nonaka iwm_fw_valid_rx_ant(struct iwm_softc *sc)
2606 1.45 nonaka {
2607 1.45 nonaka uint8_t rx_ant;
2608 1.1 pooka
2609 1.45 nonaka rx_ant = ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RX_CHAIN)
2610 1.45 nonaka >> IWM_FW_PHY_CFG_RX_CHAIN_POS);
2611 1.1 pooka
2612 1.45 nonaka if (sc->sc_nvm.valid_rx_ant)
2613 1.45 nonaka rx_ant &= sc->sc_nvm.valid_rx_ant;
2614 1.1 pooka
2615 1.45 nonaka return rx_ant;
2616 1.45 nonaka }
2617 1.1 pooka
2618 1.4 nonaka static void
2619 1.45 nonaka iwm_init_channel_map(struct iwm_softc *sc, const uint16_t * const nvm_ch_flags,
2620 1.45 nonaka const uint8_t *nvm_channels, size_t nchan)
2621 1.1 pooka {
2622 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
2623 1.1 pooka struct iwm_nvm_data *data = &sc->sc_nvm;
2624 1.1 pooka int ch_idx;
2625 1.1 pooka struct ieee80211_channel *channel;
2626 1.1 pooka uint16_t ch_flags;
2627 1.1 pooka int is_5ghz;
2628 1.1 pooka int flags, hw_value;
2629 1.1 pooka
2630 1.45 nonaka for (ch_idx = 0; ch_idx < nchan; ch_idx++) {
2631 1.1 pooka ch_flags = le16_to_cpup(nvm_ch_flags + ch_idx);
2632 1.64 nonaka aprint_debug_dev(sc->sc_dev,
2633 1.64 nonaka "Ch. %d: %svalid %cibss %s %cradar %cdfs"
2634 1.64 nonaka " %cwide %c40MHz %c80MHz %c160MHz\n",
2635 1.64 nonaka nvm_channels[ch_idx],
2636 1.64 nonaka ch_flags & IWM_NVM_CHANNEL_VALID ? "" : "in",
2637 1.64 nonaka ch_flags & IWM_NVM_CHANNEL_IBSS ? '+' : '-',
2638 1.64 nonaka ch_flags & IWM_NVM_CHANNEL_ACTIVE ? "active" : "passive",
2639 1.64 nonaka ch_flags & IWM_NVM_CHANNEL_RADAR ? '+' : '-',
2640 1.64 nonaka ch_flags & IWM_NVM_CHANNEL_DFS ? '+' : '-',
2641 1.64 nonaka ch_flags & IWM_NVM_CHANNEL_WIDE ? '+' : '-',
2642 1.64 nonaka ch_flags & IWM_NVM_CHANNEL_40MHZ ? '+' : '-',
2643 1.64 nonaka ch_flags & IWM_NVM_CHANNEL_80MHZ ? '+' : '-',
2644 1.64 nonaka ch_flags & IWM_NVM_CHANNEL_160MHZ ? '+' : '-');
2645 1.1 pooka
2646 1.1 pooka if (ch_idx >= IWM_NUM_2GHZ_CHANNELS &&
2647 1.1 pooka !data->sku_cap_band_52GHz_enable)
2648 1.1 pooka ch_flags &= ~IWM_NVM_CHANNEL_VALID;
2649 1.1 pooka
2650 1.1 pooka if (!(ch_flags & IWM_NVM_CHANNEL_VALID)) {
2651 1.1 pooka DPRINTF(("Ch. %d Flags %x [%sGHz] - No traffic\n",
2652 1.64 nonaka nvm_channels[ch_idx], ch_flags,
2653 1.64 nonaka (ch_idx >= IWM_NUM_2GHZ_CHANNELS) ? "5" : "2.4"));
2654 1.1 pooka continue;
2655 1.1 pooka }
2656 1.1 pooka
2657 1.45 nonaka hw_value = nvm_channels[ch_idx];
2658 1.1 pooka channel = &ic->ic_channels[hw_value];
2659 1.1 pooka
2660 1.1 pooka is_5ghz = ch_idx >= IWM_NUM_2GHZ_CHANNELS;
2661 1.1 pooka if (!is_5ghz) {
2662 1.1 pooka flags = IEEE80211_CHAN_2GHZ;
2663 1.1 pooka channel->ic_flags
2664 1.1 pooka = IEEE80211_CHAN_CCK
2665 1.1 pooka | IEEE80211_CHAN_OFDM
2666 1.1 pooka | IEEE80211_CHAN_DYN
2667 1.1 pooka | IEEE80211_CHAN_2GHZ;
2668 1.1 pooka } else {
2669 1.1 pooka flags = IEEE80211_CHAN_5GHZ;
2670 1.1 pooka channel->ic_flags =
2671 1.1 pooka IEEE80211_CHAN_A;
2672 1.1 pooka }
2673 1.1 pooka channel->ic_freq = ieee80211_ieee2mhz(hw_value, flags);
2674 1.1 pooka
2675 1.1 pooka if (!(ch_flags & IWM_NVM_CHANNEL_ACTIVE))
2676 1.1 pooka channel->ic_flags |= IEEE80211_CHAN_PASSIVE;
2677 1.45 nonaka
2678 1.45 nonaka #ifndef IEEE80211_NO_HT
2679 1.45 nonaka if (data->sku_cap_11n_enable)
2680 1.45 nonaka channel->ic_flags |= IEEE80211_CHAN_HT;
2681 1.45 nonaka #endif
2682 1.45 nonaka }
2683 1.45 nonaka }
2684 1.45 nonaka
2685 1.45 nonaka #ifndef IEEE80211_NO_HT
2686 1.45 nonaka static void
2687 1.45 nonaka iwm_setup_ht_rates(struct iwm_softc *sc)
2688 1.45 nonaka {
2689 1.45 nonaka struct ieee80211com *ic = &sc->sc_ic;
2690 1.45 nonaka
2691 1.45 nonaka /* TX is supported with the same MCS as RX. */
2692 1.45 nonaka ic->ic_tx_mcs_set = IEEE80211_TX_MCS_SET_DEFINED;
2693 1.45 nonaka
2694 1.45 nonaka ic->ic_sup_mcs[0] = 0xff; /* MCS 0-7 */
2695 1.45 nonaka
2696 1.45 nonaka #ifdef notyet
2697 1.45 nonaka if (sc->sc_nvm.sku_cap_mimo_disable)
2698 1.45 nonaka return;
2699 1.45 nonaka
2700 1.45 nonaka if (iwm_fw_valid_rx_ant(sc) > 1)
2701 1.45 nonaka ic->ic_sup_mcs[1] = 0xff; /* MCS 8-15 */
2702 1.45 nonaka if (iwm_fw_valid_rx_ant(sc) > 2)
2703 1.45 nonaka ic->ic_sup_mcs[2] = 0xff; /* MCS 16-23 */
2704 1.45 nonaka #endif
2705 1.45 nonaka }
2706 1.45 nonaka
2707 1.45 nonaka #define IWM_MAX_RX_BA_SESSIONS 16
2708 1.45 nonaka
2709 1.45 nonaka static void
2710 1.45 nonaka iwm_sta_rx_agg(struct iwm_softc *sc, struct ieee80211_node *ni, uint8_t tid,
2711 1.45 nonaka uint16_t ssn, int start)
2712 1.45 nonaka {
2713 1.45 nonaka struct ieee80211com *ic = &sc->sc_ic;
2714 1.45 nonaka struct iwm_add_sta_cmd_v7 cmd;
2715 1.45 nonaka struct iwm_node *in = (struct iwm_node *)ni;
2716 1.45 nonaka int err, s;
2717 1.45 nonaka uint32_t status;
2718 1.45 nonaka
2719 1.45 nonaka if (start && sc->sc_rx_ba_sessions >= IWM_MAX_RX_BA_SESSIONS) {
2720 1.45 nonaka ieee80211_addba_req_refuse(ic, ni, tid);
2721 1.45 nonaka return;
2722 1.45 nonaka }
2723 1.45 nonaka
2724 1.45 nonaka memset(&cmd, 0, sizeof(cmd));
2725 1.45 nonaka
2726 1.45 nonaka cmd.sta_id = IWM_STATION_ID;
2727 1.45 nonaka cmd.mac_id_n_color
2728 1.45 nonaka = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
2729 1.45 nonaka cmd.add_modify = IWM_STA_MODE_MODIFY;
2730 1.45 nonaka
2731 1.45 nonaka if (start) {
2732 1.45 nonaka cmd.add_immediate_ba_tid = (uint8_t)tid;
2733 1.45 nonaka cmd.add_immediate_ba_ssn = ssn;
2734 1.45 nonaka } else {
2735 1.45 nonaka cmd.remove_immediate_ba_tid = (uint8_t)tid;
2736 1.45 nonaka }
2737 1.45 nonaka cmd.modify_mask = start ? IWM_STA_MODIFY_ADD_BA_TID :
2738 1.45 nonaka IWM_STA_MODIFY_REMOVE_BA_TID;
2739 1.45 nonaka
2740 1.45 nonaka status = IWM_ADD_STA_SUCCESS;
2741 1.45 nonaka err = iwm_send_cmd_pdu_status(sc, IWM_ADD_STA, sizeof(cmd), &cmd,
2742 1.45 nonaka &status);
2743 1.45 nonaka
2744 1.45 nonaka s = splnet();
2745 1.45 nonaka if (err == 0 && status == IWM_ADD_STA_SUCCESS) {
2746 1.45 nonaka if (start) {
2747 1.45 nonaka sc->sc_rx_ba_sessions++;
2748 1.45 nonaka ieee80211_addba_req_accept(ic, ni, tid);
2749 1.45 nonaka } else if (sc->sc_rx_ba_sessions > 0)
2750 1.45 nonaka sc->sc_rx_ba_sessions--;
2751 1.45 nonaka } else if (start)
2752 1.45 nonaka ieee80211_addba_req_refuse(ic, ni, tid);
2753 1.45 nonaka splx(s);
2754 1.45 nonaka }
2755 1.45 nonaka
2756 1.45 nonaka static void
2757 1.45 nonaka iwm_htprot_task(void *arg)
2758 1.45 nonaka {
2759 1.45 nonaka struct iwm_softc *sc = arg;
2760 1.45 nonaka struct ieee80211com *ic = &sc->sc_ic;
2761 1.45 nonaka struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
2762 1.45 nonaka int err;
2763 1.45 nonaka
2764 1.45 nonaka /* This call updates HT protection based on in->in_ni.ni_htop1. */
2765 1.45 nonaka err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY, 1);
2766 1.45 nonaka if (err)
2767 1.45 nonaka aprint_error_dev(sc->sc_dev,
2768 1.45 nonaka "could not change HT protection: error %d\n", err);
2769 1.45 nonaka }
2770 1.45 nonaka
2771 1.45 nonaka /*
2772 1.45 nonaka * This function is called by upper layer when HT protection settings in
2773 1.45 nonaka * beacons have changed.
2774 1.45 nonaka */
2775 1.45 nonaka static void
2776 1.45 nonaka iwm_update_htprot(struct ieee80211com *ic, struct ieee80211_node *ni)
2777 1.45 nonaka {
2778 1.45 nonaka struct iwm_softc *sc = ic->ic_softc;
2779 1.45 nonaka
2780 1.45 nonaka /* assumes that ni == ic->ic_bss */
2781 1.45 nonaka task_add(systq, &sc->htprot_task);
2782 1.45 nonaka }
2783 1.45 nonaka
2784 1.45 nonaka static void
2785 1.45 nonaka iwm_ba_task(void *arg)
2786 1.45 nonaka {
2787 1.45 nonaka struct iwm_softc *sc = arg;
2788 1.45 nonaka struct ieee80211com *ic = &sc->sc_ic;
2789 1.45 nonaka struct ieee80211_node *ni = ic->ic_bss;
2790 1.45 nonaka
2791 1.45 nonaka if (sc->ba_start)
2792 1.45 nonaka iwm_sta_rx_agg(sc, ni, sc->ba_tid, sc->ba_ssn, 1);
2793 1.45 nonaka else
2794 1.45 nonaka iwm_sta_rx_agg(sc, ni, sc->ba_tid, 0, 0);
2795 1.45 nonaka }
2796 1.45 nonaka
2797 1.45 nonaka /*
2798 1.45 nonaka * This function is called by upper layer when an ADDBA request is received
2799 1.45 nonaka * from another STA and before the ADDBA response is sent.
2800 1.45 nonaka */
2801 1.45 nonaka static int
2802 1.45 nonaka iwm_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
2803 1.45 nonaka uint8_t tid)
2804 1.45 nonaka {
2805 1.45 nonaka struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
2806 1.45 nonaka struct iwm_softc *sc = IC2IFP(ic)->if_softc;
2807 1.45 nonaka
2808 1.45 nonaka if (sc->sc_rx_ba_sessions >= IWM_MAX_RX_BA_SESSIONS)
2809 1.45 nonaka return ENOSPC;
2810 1.45 nonaka
2811 1.45 nonaka sc->ba_start = 1;
2812 1.45 nonaka sc->ba_tid = tid;
2813 1.45 nonaka sc->ba_ssn = htole16(ba->ba_winstart);
2814 1.45 nonaka task_add(systq, &sc->ba_task);
2815 1.45 nonaka
2816 1.45 nonaka return EBUSY;
2817 1.45 nonaka }
2818 1.45 nonaka
2819 1.45 nonaka /*
2820 1.45 nonaka * This function is called by upper layer on teardown of an HT-immediate
2821 1.45 nonaka * Block Ack agreement (eg. upon receipt of a DELBA frame).
2822 1.45 nonaka */
2823 1.45 nonaka static void
2824 1.45 nonaka iwm_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
2825 1.45 nonaka uint8_t tid)
2826 1.45 nonaka {
2827 1.45 nonaka struct iwm_softc *sc = IC2IFP(ic)->if_softc;
2828 1.45 nonaka
2829 1.45 nonaka sc->ba_start = 0;
2830 1.45 nonaka sc->ba_tid = tid;
2831 1.45 nonaka task_add(systq, &sc->ba_task);
2832 1.45 nonaka }
2833 1.45 nonaka #endif
2834 1.45 nonaka
2835 1.45 nonaka static void
2836 1.71 nonaka iwm_free_fw_paging(struct iwm_softc *sc)
2837 1.71 nonaka {
2838 1.71 nonaka int i;
2839 1.71 nonaka
2840 1.71 nonaka if (sc->fw_paging_db[0].fw_paging_block.vaddr == NULL)
2841 1.71 nonaka return;
2842 1.71 nonaka
2843 1.71 nonaka for (i = 0; i < IWM_NUM_OF_FW_PAGING_BLOCKS; i++) {
2844 1.71 nonaka iwm_dma_contig_free(&sc->fw_paging_db[i].fw_paging_block);
2845 1.71 nonaka }
2846 1.71 nonaka
2847 1.71 nonaka memset(sc->fw_paging_db, 0, sizeof(sc->fw_paging_db));
2848 1.71 nonaka }
2849 1.71 nonaka
2850 1.71 nonaka static int
2851 1.71 nonaka iwm_fill_paging_mem(struct iwm_softc *sc, const struct iwm_fw_sects *fws)
2852 1.71 nonaka {
2853 1.71 nonaka int sec_idx, idx;
2854 1.71 nonaka uint32_t offset = 0;
2855 1.71 nonaka
2856 1.71 nonaka /*
2857 1.71 nonaka * find where is the paging image start point:
2858 1.71 nonaka * if CPU2 exist and it's in paging format, then the image looks like:
2859 1.71 nonaka * CPU1 sections (2 or more)
2860 1.71 nonaka * CPU1_CPU2_SEPARATOR_SECTION delimiter - separate between CPU1 to CPU2
2861 1.71 nonaka * CPU2 sections (not paged)
2862 1.71 nonaka * PAGING_SEPARATOR_SECTION delimiter - separate between CPU2
2863 1.71 nonaka * non paged to CPU2 paging sec
2864 1.71 nonaka * CPU2 paging CSS
2865 1.71 nonaka * CPU2 paging image (including instruction and data)
2866 1.71 nonaka */
2867 1.71 nonaka for (sec_idx = 0; sec_idx < IWM_UCODE_SECT_MAX; sec_idx++) {
2868 1.71 nonaka if (fws->fw_sect[sec_idx].fws_devoff ==
2869 1.71 nonaka IWM_PAGING_SEPARATOR_SECTION) {
2870 1.71 nonaka sec_idx++;
2871 1.71 nonaka break;
2872 1.71 nonaka }
2873 1.71 nonaka }
2874 1.71 nonaka
2875 1.71 nonaka /*
2876 1.71 nonaka * If paging is enabled there should be at least 2 more sections left
2877 1.71 nonaka * (one for CSS and one for Paging data)
2878 1.71 nonaka */
2879 1.71 nonaka if (sec_idx >= __arraycount(fws->fw_sect) - 1) {
2880 1.71 nonaka aprint_verbose_dev(sc->sc_dev,
2881 1.71 nonaka "Paging: Missing CSS and/or paging sections\n");
2882 1.71 nonaka iwm_free_fw_paging(sc);
2883 1.71 nonaka return EINVAL;
2884 1.71 nonaka }
2885 1.71 nonaka
2886 1.71 nonaka /* copy the CSS block to the dram */
2887 1.71 nonaka DPRINTF(("%s: Paging: load paging CSS to FW, sec = %d\n", DEVNAME(sc),
2888 1.71 nonaka sec_idx));
2889 1.71 nonaka
2890 1.71 nonaka memcpy(sc->fw_paging_db[0].fw_paging_block.vaddr,
2891 1.71 nonaka fws->fw_sect[sec_idx].fws_data, sc->fw_paging_db[0].fw_paging_size);
2892 1.71 nonaka
2893 1.71 nonaka DPRINTF(("%s: Paging: copied %d CSS bytes to first block\n",
2894 1.71 nonaka DEVNAME(sc), sc->fw_paging_db[0].fw_paging_size));
2895 1.71 nonaka
2896 1.71 nonaka sec_idx++;
2897 1.71 nonaka
2898 1.71 nonaka /*
2899 1.71 nonaka * copy the paging blocks to the dram
2900 1.71 nonaka * loop index start from 1 since that CSS block already copied to dram
2901 1.71 nonaka * and CSS index is 0.
2902 1.71 nonaka * loop stop at num_of_paging_blk since that last block is not full.
2903 1.71 nonaka */
2904 1.71 nonaka for (idx = 1; idx < sc->num_of_paging_blk; idx++) {
2905 1.71 nonaka memcpy(sc->fw_paging_db[idx].fw_paging_block.vaddr,
2906 1.71 nonaka (const char *)fws->fw_sect[sec_idx].fws_data + offset,
2907 1.71 nonaka sc->fw_paging_db[idx].fw_paging_size);
2908 1.71 nonaka
2909 1.71 nonaka DPRINTF(("%s: Paging: copied %d paging bytes to block %d\n",
2910 1.71 nonaka DEVNAME(sc), sc->fw_paging_db[idx].fw_paging_size, idx));
2911 1.71 nonaka
2912 1.71 nonaka offset += sc->fw_paging_db[idx].fw_paging_size;
2913 1.71 nonaka }
2914 1.71 nonaka
2915 1.71 nonaka /* copy the last paging block */
2916 1.71 nonaka if (sc->num_of_pages_in_last_blk > 0) {
2917 1.71 nonaka memcpy(sc->fw_paging_db[idx].fw_paging_block.vaddr,
2918 1.71 nonaka (const char *)fws->fw_sect[sec_idx].fws_data + offset,
2919 1.71 nonaka IWM_FW_PAGING_SIZE * sc->num_of_pages_in_last_blk);
2920 1.71 nonaka
2921 1.71 nonaka DPRINTF(("%s: Paging: copied %d pages in the last block %d\n",
2922 1.71 nonaka DEVNAME(sc), sc->num_of_pages_in_last_blk, idx));
2923 1.71 nonaka }
2924 1.71 nonaka
2925 1.71 nonaka return 0;
2926 1.71 nonaka }
2927 1.71 nonaka
2928 1.71 nonaka static int
2929 1.71 nonaka iwm_alloc_fw_paging_mem(struct iwm_softc *sc, const struct iwm_fw_sects *fws)
2930 1.71 nonaka {
2931 1.71 nonaka int blk_idx = 0;
2932 1.71 nonaka int error, num_of_pages;
2933 1.71 nonaka bus_dmamap_t dmap;
2934 1.71 nonaka
2935 1.71 nonaka if (sc->fw_paging_db[0].fw_paging_block.vaddr != NULL) {
2936 1.71 nonaka int i;
2937 1.71 nonaka /* Device got reset, and we setup firmware paging again */
2938 1.71 nonaka for (i = 0; i < sc->num_of_paging_blk + 1; i++) {
2939 1.71 nonaka dmap = sc->fw_paging_db[i].fw_paging_block.map;
2940 1.71 nonaka bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
2941 1.71 nonaka BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
2942 1.71 nonaka }
2943 1.71 nonaka return 0;
2944 1.71 nonaka }
2945 1.71 nonaka
2946 1.71 nonaka /* ensure IWM_BLOCK_2_EXP_SIZE is power of 2 of IWM_PAGING_BLOCK_SIZE */
2947 1.71 nonaka CTASSERT(__BIT(IWM_BLOCK_2_EXP_SIZE) == IWM_PAGING_BLOCK_SIZE);
2948 1.71 nonaka
2949 1.71 nonaka num_of_pages = fws->paging_mem_size / IWM_FW_PAGING_SIZE;
2950 1.71 nonaka sc->num_of_paging_blk =
2951 1.71 nonaka howmany(num_of_pages, IWM_NUM_OF_PAGE_PER_GROUP);
2952 1.71 nonaka sc->num_of_pages_in_last_blk = num_of_pages -
2953 1.71 nonaka IWM_NUM_OF_PAGE_PER_GROUP * (sc->num_of_paging_blk - 1);
2954 1.71 nonaka
2955 1.71 nonaka DPRINTF(("%s: Paging: allocating mem for %d paging blocks, "
2956 1.71 nonaka "each block holds 8 pages, last block holds %d pages\n",
2957 1.71 nonaka DEVNAME(sc), sc->num_of_paging_blk, sc->num_of_pages_in_last_blk));
2958 1.71 nonaka
2959 1.71 nonaka /* allocate block of 4Kbytes for paging CSS */
2960 1.71 nonaka error = iwm_dma_contig_alloc(sc->sc_dmat,
2961 1.71 nonaka &sc->fw_paging_db[blk_idx].fw_paging_block, IWM_FW_PAGING_SIZE,
2962 1.71 nonaka 4096);
2963 1.71 nonaka if (error) {
2964 1.71 nonaka /* free all the previous pages since we failed */
2965 1.71 nonaka iwm_free_fw_paging(sc);
2966 1.71 nonaka return ENOMEM;
2967 1.71 nonaka }
2968 1.71 nonaka
2969 1.71 nonaka sc->fw_paging_db[blk_idx].fw_paging_size = IWM_FW_PAGING_SIZE;
2970 1.71 nonaka
2971 1.71 nonaka DPRINTF(("%s: Paging: allocated 4K(CSS) bytes for firmware paging.\n",
2972 1.71 nonaka DEVNAME(sc)));
2973 1.71 nonaka
2974 1.71 nonaka /*
2975 1.71 nonaka * allocate blocks in dram.
2976 1.71 nonaka * since that CSS allocated in fw_paging_db[0] loop start from index 1
2977 1.71 nonaka */
2978 1.71 nonaka for (blk_idx = 1; blk_idx < sc->num_of_paging_blk + 1; blk_idx++) {
2979 1.71 nonaka /* allocate block of IWM_PAGING_BLOCK_SIZE (32K) */
2980 1.71 nonaka /* XXX Use iwm_dma_contig_alloc for allocating */
2981 1.71 nonaka error = iwm_dma_contig_alloc(sc->sc_dmat,
2982 1.71 nonaka &sc->fw_paging_db[blk_idx].fw_paging_block,
2983 1.71 nonaka IWM_PAGING_BLOCK_SIZE, 4096);
2984 1.71 nonaka if (error) {
2985 1.71 nonaka /* free all the previous pages since we failed */
2986 1.71 nonaka iwm_free_fw_paging(sc);
2987 1.71 nonaka return ENOMEM;
2988 1.71 nonaka }
2989 1.71 nonaka
2990 1.71 nonaka sc->fw_paging_db[blk_idx].fw_paging_size =
2991 1.71 nonaka IWM_PAGING_BLOCK_SIZE;
2992 1.71 nonaka
2993 1.71 nonaka DPRINTF(("%s: Paging: allocated 32K bytes for firmware "
2994 1.71 nonaka "paging.\n", DEVNAME(sc)));
2995 1.71 nonaka }
2996 1.71 nonaka
2997 1.71 nonaka return 0;
2998 1.71 nonaka }
2999 1.71 nonaka
3000 1.71 nonaka static int
3001 1.71 nonaka iwm_save_fw_paging(struct iwm_softc *sc, const struct iwm_fw_sects *fws)
3002 1.71 nonaka {
3003 1.71 nonaka int err;
3004 1.71 nonaka
3005 1.71 nonaka err = iwm_alloc_fw_paging_mem(sc, fws);
3006 1.71 nonaka if (err)
3007 1.71 nonaka return err;
3008 1.71 nonaka
3009 1.71 nonaka return iwm_fill_paging_mem(sc, fws);
3010 1.71 nonaka }
3011 1.71 nonaka
3012 1.71 nonaka static bool
3013 1.71 nonaka iwm_has_new_tx_api(struct iwm_softc *sc)
3014 1.71 nonaka {
3015 1.71 nonaka /* XXX */
3016 1.71 nonaka return false;
3017 1.71 nonaka }
3018 1.71 nonaka
3019 1.71 nonaka /* send paging cmd to FW in case CPU2 has paging image */
3020 1.71 nonaka static int
3021 1.71 nonaka iwm_send_paging_cmd(struct iwm_softc *sc, const struct iwm_fw_sects *fws)
3022 1.71 nonaka {
3023 1.71 nonaka struct iwm_fw_paging_cmd fw_paging_cmd = {
3024 1.71 nonaka .flags = htole32(IWM_PAGING_CMD_IS_SECURED |
3025 1.71 nonaka IWM_PAGING_CMD_IS_ENABLED |
3026 1.71 nonaka (sc->num_of_pages_in_last_blk <<
3027 1.71 nonaka IWM_PAGING_CMD_NUM_OF_PAGES_IN_LAST_GRP_POS)),
3028 1.71 nonaka .block_size = htole32(IWM_BLOCK_2_EXP_SIZE),
3029 1.71 nonaka .block_num = htole32(sc->num_of_paging_blk),
3030 1.71 nonaka };
3031 1.71 nonaka size_t size = sizeof(fw_paging_cmd);
3032 1.71 nonaka int blk_idx;
3033 1.71 nonaka bus_dmamap_t dmap;
3034 1.71 nonaka
3035 1.71 nonaka if (!iwm_has_new_tx_api(sc))
3036 1.71 nonaka size -= (sizeof(uint64_t) - sizeof(uint32_t)) *
3037 1.71 nonaka IWM_NUM_OF_FW_PAGING_BLOCKS;
3038 1.71 nonaka
3039 1.88 msaitoh /* loop for all paging blocks + CSS block */
3040 1.71 nonaka for (blk_idx = 0; blk_idx < sc->num_of_paging_blk + 1; blk_idx++) {
3041 1.71 nonaka bus_addr_t dev_phy_addr =
3042 1.71 nonaka sc->fw_paging_db[blk_idx].fw_paging_block.paddr;
3043 1.71 nonaka if (iwm_has_new_tx_api(sc)) {
3044 1.71 nonaka fw_paging_cmd.device_phy_addr.addr64[blk_idx] =
3045 1.71 nonaka htole64(dev_phy_addr);
3046 1.71 nonaka } else {
3047 1.71 nonaka dev_phy_addr = dev_phy_addr >> IWM_PAGE_2_EXP_SIZE;
3048 1.71 nonaka fw_paging_cmd.device_phy_addr.addr32[blk_idx] =
3049 1.71 nonaka htole32(dev_phy_addr);
3050 1.71 nonaka }
3051 1.74 nonaka dmap = sc->fw_paging_db[blk_idx].fw_paging_block.map;
3052 1.71 nonaka bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
3053 1.71 nonaka BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3054 1.71 nonaka }
3055 1.71 nonaka
3056 1.71 nonaka return iwm_send_cmd_pdu(sc,
3057 1.71 nonaka iwm_cmd_id(IWM_FW_PAGING_BLOCK_CMD, IWM_ALWAYS_LONG_GROUP, 0),
3058 1.71 nonaka 0, size, &fw_paging_cmd);
3059 1.71 nonaka }
3060 1.71 nonaka
3061 1.71 nonaka static void
3062 1.45 nonaka iwm_set_hw_address_8000(struct iwm_softc *sc, struct iwm_nvm_data *data,
3063 1.45 nonaka const uint16_t *mac_override, const uint16_t *nvm_hw)
3064 1.45 nonaka {
3065 1.45 nonaka static const uint8_t reserved_mac[ETHER_ADDR_LEN] = {
3066 1.45 nonaka 0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00
3067 1.45 nonaka };
3068 1.45 nonaka static const u_int8_t etheranyaddr[ETHER_ADDR_LEN] = {
3069 1.45 nonaka 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3070 1.45 nonaka };
3071 1.45 nonaka const uint8_t *hw_addr;
3072 1.45 nonaka
3073 1.45 nonaka if (mac_override) {
3074 1.45 nonaka hw_addr = (const uint8_t *)(mac_override +
3075 1.45 nonaka IWM_MAC_ADDRESS_OVERRIDE_8000);
3076 1.45 nonaka
3077 1.45 nonaka /*
3078 1.45 nonaka * Store the MAC address from MAO section.
3079 1.45 nonaka * No byte swapping is required in MAO section
3080 1.45 nonaka */
3081 1.45 nonaka memcpy(data->hw_addr, hw_addr, ETHER_ADDR_LEN);
3082 1.45 nonaka
3083 1.45 nonaka /*
3084 1.45 nonaka * Force the use of the OTP MAC address in case of reserved MAC
3085 1.45 nonaka * address in the NVM, or if address is given but invalid.
3086 1.45 nonaka */
3087 1.45 nonaka if (memcmp(reserved_mac, hw_addr, ETHER_ADDR_LEN) != 0 &&
3088 1.45 nonaka (memcmp(etherbroadcastaddr, data->hw_addr,
3089 1.45 nonaka sizeof(etherbroadcastaddr)) != 0) &&
3090 1.45 nonaka (memcmp(etheranyaddr, data->hw_addr,
3091 1.45 nonaka sizeof(etheranyaddr)) != 0) &&
3092 1.45 nonaka !ETHER_IS_MULTICAST(data->hw_addr))
3093 1.45 nonaka return;
3094 1.45 nonaka }
3095 1.45 nonaka
3096 1.45 nonaka if (nvm_hw) {
3097 1.45 nonaka /* Read the mac address from WFMP registers. */
3098 1.45 nonaka uint32_t mac_addr0 =
3099 1.45 nonaka htole32(iwm_read_prph(sc, IWM_WFMP_MAC_ADDR_0));
3100 1.45 nonaka uint32_t mac_addr1 =
3101 1.45 nonaka htole32(iwm_read_prph(sc, IWM_WFMP_MAC_ADDR_1));
3102 1.45 nonaka
3103 1.45 nonaka hw_addr = (const uint8_t *)&mac_addr0;
3104 1.45 nonaka data->hw_addr[0] = hw_addr[3];
3105 1.45 nonaka data->hw_addr[1] = hw_addr[2];
3106 1.45 nonaka data->hw_addr[2] = hw_addr[1];
3107 1.45 nonaka data->hw_addr[3] = hw_addr[0];
3108 1.45 nonaka
3109 1.45 nonaka hw_addr = (const uint8_t *)&mac_addr1;
3110 1.45 nonaka data->hw_addr[4] = hw_addr[1];
3111 1.45 nonaka data->hw_addr[5] = hw_addr[0];
3112 1.45 nonaka
3113 1.45 nonaka return;
3114 1.1 pooka }
3115 1.45 nonaka
3116 1.45 nonaka aprint_error_dev(sc->sc_dev, "mac address not found\n");
3117 1.45 nonaka memset(data->hw_addr, 0, sizeof(data->hw_addr));
3118 1.1 pooka }
3119 1.1 pooka
3120 1.4 nonaka static int
3121 1.45 nonaka iwm_parse_nvm_data(struct iwm_softc *sc, const uint16_t *nvm_hw,
3122 1.45 nonaka const uint16_t *nvm_sw, const uint16_t *nvm_calib,
3123 1.45 nonaka const uint16_t *mac_override, const uint16_t *phy_sku,
3124 1.45 nonaka const uint16_t *regulatory)
3125 1.1 pooka {
3126 1.1 pooka struct iwm_nvm_data *data = &sc->sc_nvm;
3127 1.1 pooka uint8_t hw_addr[ETHER_ADDR_LEN];
3128 1.45 nonaka uint32_t sku;
3129 1.1 pooka
3130 1.45 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
3131 1.45 nonaka uint16_t radio_cfg = le16_to_cpup(nvm_sw + IWM_RADIO_CFG);
3132 1.45 nonaka data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK(radio_cfg);
3133 1.45 nonaka data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK(radio_cfg);
3134 1.45 nonaka data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK(radio_cfg);
3135 1.45 nonaka data->radio_cfg_pnum = IWM_NVM_RF_CFG_PNUM_MSK(radio_cfg);
3136 1.45 nonaka
3137 1.61 nonaka data->nvm_version = le16_to_cpup(nvm_sw + IWM_NVM_VERSION);
3138 1.45 nonaka sku = le16_to_cpup(nvm_sw + IWM_SKU);
3139 1.45 nonaka } else {
3140 1.61 nonaka uint32_t radio_cfg = le32_to_cpup(phy_sku + IWM_RADIO_CFG_8000);
3141 1.45 nonaka data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK_8000(radio_cfg);
3142 1.45 nonaka data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK_8000(radio_cfg);
3143 1.45 nonaka data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK_8000(radio_cfg);
3144 1.45 nonaka data->radio_cfg_pnum = IWM_NVM_RF_CFG_PNUM_MSK_8000(radio_cfg);
3145 1.45 nonaka data->valid_tx_ant = IWM_NVM_RF_CFG_TX_ANT_MSK_8000(radio_cfg);
3146 1.45 nonaka data->valid_rx_ant = IWM_NVM_RF_CFG_RX_ANT_MSK_8000(radio_cfg);
3147 1.45 nonaka
3148 1.61 nonaka data->nvm_version = le32_to_cpup(nvm_sw + IWM_NVM_VERSION_8000);
3149 1.61 nonaka sku = le32_to_cpup(phy_sku + IWM_SKU_8000);
3150 1.45 nonaka }
3151 1.1 pooka
3152 1.1 pooka data->sku_cap_band_24GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_24GHZ;
3153 1.1 pooka data->sku_cap_band_52GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_52GHZ;
3154 1.45 nonaka data->sku_cap_11n_enable = sku & IWM_NVM_SKU_CAP_11N_ENABLE;
3155 1.45 nonaka data->sku_cap_mimo_disable = sku & IWM_NVM_SKU_CAP_MIMO_DISABLE;
3156 1.1 pooka
3157 1.1 pooka data->n_hw_addrs = le16_to_cpup(nvm_sw + IWM_N_HW_ADDRS);
3158 1.1 pooka
3159 1.45 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
3160 1.45 nonaka memcpy(hw_addr, nvm_hw + IWM_HW_ADDR, ETHER_ADDR_LEN);
3161 1.45 nonaka data->hw_addr[0] = hw_addr[1];
3162 1.45 nonaka data->hw_addr[1] = hw_addr[0];
3163 1.45 nonaka data->hw_addr[2] = hw_addr[3];
3164 1.45 nonaka data->hw_addr[3] = hw_addr[2];
3165 1.45 nonaka data->hw_addr[4] = hw_addr[5];
3166 1.45 nonaka data->hw_addr[5] = hw_addr[4];
3167 1.45 nonaka } else
3168 1.45 nonaka iwm_set_hw_address_8000(sc, data, mac_override, nvm_hw);
3169 1.1 pooka
3170 1.60 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) {
3171 1.60 nonaka uint16_t lar_offset, lar_config;
3172 1.60 nonaka lar_offset = data->nvm_version < 0xE39 ?
3173 1.60 nonaka IWM_NVM_LAR_OFFSET_8000_OLD : IWM_NVM_LAR_OFFSET_8000;
3174 1.60 nonaka lar_config = le16_to_cpup(regulatory + lar_offset);
3175 1.60 nonaka data->lar_enabled = !!(lar_config & IWM_NVM_LAR_ENABLED_8000);
3176 1.60 nonaka }
3177 1.60 nonaka
3178 1.45 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000)
3179 1.45 nonaka iwm_init_channel_map(sc, &nvm_sw[IWM_NVM_CHANNELS],
3180 1.45 nonaka iwm_nvm_channels, __arraycount(iwm_nvm_channels));
3181 1.45 nonaka else
3182 1.45 nonaka iwm_init_channel_map(sc, ®ulatory[IWM_NVM_CHANNELS_8000],
3183 1.45 nonaka iwm_nvm_channels_8000, __arraycount(iwm_nvm_channels_8000));
3184 1.1 pooka
3185 1.1 pooka data->calib_version = 255; /* TODO:
3186 1.1 pooka this value will prevent some checks from
3187 1.1 pooka failing, we need to check if this
3188 1.1 pooka field is still needed, and if it does,
3189 1.1 pooka where is it in the NVM */
3190 1.1 pooka
3191 1.1 pooka return 0;
3192 1.1 pooka }
3193 1.1 pooka
3194 1.1 pooka static int
3195 1.1 pooka iwm_parse_nvm_sections(struct iwm_softc *sc, struct iwm_nvm_section *sections)
3196 1.1 pooka {
3197 1.45 nonaka const uint16_t *hw, *sw, *calib, *mac_override = NULL, *phy_sku = NULL;
3198 1.45 nonaka const uint16_t *regulatory = NULL;
3199 1.1 pooka
3200 1.1 pooka /* Checking for required sections */
3201 1.45 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
3202 1.45 nonaka if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
3203 1.45 nonaka !sections[IWM_NVM_SECTION_TYPE_HW].data) {
3204 1.45 nonaka return ENOENT;
3205 1.45 nonaka }
3206 1.45 nonaka
3207 1.45 nonaka hw = (const uint16_t *) sections[IWM_NVM_SECTION_TYPE_HW].data;
3208 1.45 nonaka } else if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) {
3209 1.45 nonaka /* SW and REGULATORY sections are mandatory */
3210 1.45 nonaka if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
3211 1.45 nonaka !sections[IWM_NVM_SECTION_TYPE_REGULATORY].data) {
3212 1.45 nonaka return ENOENT;
3213 1.45 nonaka }
3214 1.45 nonaka /* MAC_OVERRIDE or at least HW section must exist */
3215 1.45 nonaka if (!sections[IWM_NVM_SECTION_TYPE_HW_8000].data &&
3216 1.45 nonaka !sections[IWM_NVM_SECTION_TYPE_MAC_OVERRIDE].data) {
3217 1.45 nonaka return ENOENT;
3218 1.45 nonaka }
3219 1.45 nonaka
3220 1.45 nonaka /* PHY_SKU section is mandatory in B0 */
3221 1.45 nonaka if (!sections[IWM_NVM_SECTION_TYPE_PHY_SKU].data) {
3222 1.45 nonaka return ENOENT;
3223 1.45 nonaka }
3224 1.45 nonaka
3225 1.45 nonaka regulatory = (const uint16_t *)
3226 1.45 nonaka sections[IWM_NVM_SECTION_TYPE_REGULATORY].data;
3227 1.45 nonaka hw = (const uint16_t *)
3228 1.45 nonaka sections[IWM_NVM_SECTION_TYPE_HW_8000].data;
3229 1.45 nonaka mac_override =
3230 1.45 nonaka (const uint16_t *)
3231 1.45 nonaka sections[IWM_NVM_SECTION_TYPE_MAC_OVERRIDE].data;
3232 1.45 nonaka phy_sku = (const uint16_t *)
3233 1.45 nonaka sections[IWM_NVM_SECTION_TYPE_PHY_SKU].data;
3234 1.45 nonaka } else {
3235 1.45 nonaka panic("unknown device family %d\n", sc->sc_device_family);
3236 1.1 pooka }
3237 1.1 pooka
3238 1.1 pooka sw = (const uint16_t *)sections[IWM_NVM_SECTION_TYPE_SW].data;
3239 1.45 nonaka calib = (const uint16_t *)
3240 1.45 nonaka sections[IWM_NVM_SECTION_TYPE_CALIBRATION].data;
3241 1.45 nonaka
3242 1.45 nonaka return iwm_parse_nvm_data(sc, hw, sw, calib, mac_override,
3243 1.45 nonaka phy_sku, regulatory);
3244 1.1 pooka }
3245 1.1 pooka
3246 1.4 nonaka static int
3247 1.1 pooka iwm_nvm_init(struct iwm_softc *sc)
3248 1.1 pooka {
3249 1.1 pooka struct iwm_nvm_section nvm_sections[IWM_NVM_NUM_OF_SECTIONS];
3250 1.45 nonaka int i, section, err;
3251 1.1 pooka uint16_t len;
3252 1.45 nonaka uint8_t *buf;
3253 1.61 nonaka const size_t bufsz = (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) ?
3254 1.61 nonaka IWM_MAX_NVM_SECTION_SIZE_8000 : IWM_MAX_NVM_SECTION_SIZE_7000;
3255 1.1 pooka
3256 1.1 pooka /* Read From FW NVM */
3257 1.1 pooka DPRINTF(("Read NVM\n"));
3258 1.1 pooka
3259 1.45 nonaka memset(nvm_sections, 0, sizeof(nvm_sections));
3260 1.45 nonaka
3261 1.45 nonaka buf = kmem_alloc(bufsz, KM_SLEEP);
3262 1.45 nonaka
3263 1.45 nonaka for (i = 0; i < __arraycount(iwm_nvm_to_read); i++) {
3264 1.45 nonaka section = iwm_nvm_to_read[i];
3265 1.45 nonaka KASSERT(section <= IWM_NVM_NUM_OF_SECTIONS);
3266 1.45 nonaka
3267 1.45 nonaka err = iwm_nvm_read_section(sc, section, buf, &len, bufsz);
3268 1.45 nonaka if (err) {
3269 1.45 nonaka err = 0;
3270 1.45 nonaka continue;
3271 1.45 nonaka }
3272 1.45 nonaka nvm_sections[section].data = kmem_alloc(len, KM_SLEEP);
3273 1.45 nonaka memcpy(nvm_sections[section].data, buf, len);
3274 1.45 nonaka nvm_sections[section].length = len;
3275 1.45 nonaka }
3276 1.45 nonaka kmem_free(buf, bufsz);
3277 1.45 nonaka if (err == 0)
3278 1.45 nonaka err = iwm_parse_nvm_sections(sc, nvm_sections);
3279 1.1 pooka
3280 1.45 nonaka for (i = 0; i < IWM_NVM_NUM_OF_SECTIONS; i++) {
3281 1.45 nonaka if (nvm_sections[i].data != NULL)
3282 1.45 nonaka kmem_free(nvm_sections[i].data, nvm_sections[i].length);
3283 1.1 pooka }
3284 1.1 pooka
3285 1.45 nonaka return err;
3286 1.1 pooka }
3287 1.1 pooka
3288 1.45 nonaka static int
3289 1.45 nonaka iwm_firmware_load_sect(struct iwm_softc *sc, uint32_t dst_addr,
3290 1.45 nonaka const uint8_t *section, uint32_t byte_cnt)
3291 1.45 nonaka {
3292 1.45 nonaka int err = EINVAL;
3293 1.45 nonaka uint32_t chunk_sz, offset;
3294 1.45 nonaka
3295 1.45 nonaka chunk_sz = MIN(IWM_FH_MEM_TB_MAX_LENGTH, byte_cnt);
3296 1.45 nonaka
3297 1.45 nonaka for (offset = 0; offset < byte_cnt; offset += chunk_sz) {
3298 1.45 nonaka uint32_t addr, len;
3299 1.45 nonaka const uint8_t *data;
3300 1.61 nonaka bool is_extended = false;
3301 1.45 nonaka
3302 1.45 nonaka addr = dst_addr + offset;
3303 1.45 nonaka len = MIN(chunk_sz, byte_cnt - offset);
3304 1.45 nonaka data = section + offset;
3305 1.45 nonaka
3306 1.61 nonaka if (addr >= IWM_FW_MEM_EXTENDED_START &&
3307 1.61 nonaka addr <= IWM_FW_MEM_EXTENDED_END)
3308 1.61 nonaka is_extended = true;
3309 1.61 nonaka
3310 1.61 nonaka if (is_extended)
3311 1.61 nonaka iwm_set_bits_prph(sc, IWM_LMPM_CHICK,
3312 1.61 nonaka IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
3313 1.61 nonaka
3314 1.45 nonaka err = iwm_firmware_load_chunk(sc, addr, data, len);
3315 1.61 nonaka
3316 1.61 nonaka if (is_extended)
3317 1.61 nonaka iwm_clear_bits_prph(sc, IWM_LMPM_CHICK,
3318 1.61 nonaka IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
3319 1.61 nonaka
3320 1.45 nonaka if (err)
3321 1.45 nonaka break;
3322 1.45 nonaka }
3323 1.45 nonaka
3324 1.45 nonaka return err;
3325 1.45 nonaka }
3326 1.1 pooka
3327 1.4 nonaka static int
3328 1.1 pooka iwm_firmware_load_chunk(struct iwm_softc *sc, uint32_t dst_addr,
3329 1.45 nonaka const uint8_t *section, uint32_t byte_cnt)
3330 1.1 pooka {
3331 1.1 pooka struct iwm_dma_info *dma = &sc->fw_dma;
3332 1.45 nonaka int err;
3333 1.1 pooka
3334 1.45 nonaka /* Copy firmware chunk into pre-allocated DMA-safe memory. */
3335 1.1 pooka memcpy(dma->vaddr, section, byte_cnt);
3336 1.45 nonaka bus_dmamap_sync(sc->sc_dmat, dma->map, 0, byte_cnt,
3337 1.45 nonaka BUS_DMASYNC_PREWRITE);
3338 1.1 pooka
3339 1.1 pooka sc->sc_fw_chunk_done = 0;
3340 1.1 pooka
3341 1.61 nonaka if (!iwm_nic_lock(sc))
3342 1.45 nonaka return EBUSY;
3343 1.45 nonaka
3344 1.1 pooka IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(IWM_FH_SRVC_CHNL),
3345 1.1 pooka IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
3346 1.1 pooka IWM_WRITE(sc, IWM_FH_SRVC_CHNL_SRAM_ADDR_REG(IWM_FH_SRVC_CHNL),
3347 1.1 pooka dst_addr);
3348 1.1 pooka IWM_WRITE(sc, IWM_FH_TFDIB_CTRL0_REG(IWM_FH_SRVC_CHNL),
3349 1.1 pooka dma->paddr & IWM_FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
3350 1.1 pooka IWM_WRITE(sc, IWM_FH_TFDIB_CTRL1_REG(IWM_FH_SRVC_CHNL),
3351 1.8 nonaka (iwm_get_dma_hi_addr(dma->paddr)
3352 1.1 pooka << IWM_FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
3353 1.1 pooka IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_BUF_STS_REG(IWM_FH_SRVC_CHNL),
3354 1.1 pooka 1 << IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
3355 1.1 pooka 1 << IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
3356 1.1 pooka IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
3357 1.1 pooka IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(IWM_FH_SRVC_CHNL),
3358 1.1 pooka IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
3359 1.1 pooka IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
3360 1.1 pooka IWM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
3361 1.8 nonaka
3362 1.1 pooka iwm_nic_unlock(sc);
3363 1.1 pooka
3364 1.45 nonaka /* Wait for this segment to load. */
3365 1.45 nonaka err = 0;
3366 1.45 nonaka while (!sc->sc_fw_chunk_done) {
3367 1.45 nonaka err = tsleep(&sc->sc_fw, 0, "iwmfw", mstohz(5000));
3368 1.45 nonaka if (err)
3369 1.1 pooka break;
3370 1.45 nonaka }
3371 1.45 nonaka if (!sc->sc_fw_chunk_done) {
3372 1.61 nonaka DPRINTF(("%s: fw chunk addr 0x%x len %d failed to load\n",
3373 1.61 nonaka DEVNAME(sc), dst_addr, byte_cnt));
3374 1.45 nonaka }
3375 1.1 pooka
3376 1.45 nonaka return err;
3377 1.1 pooka }
3378 1.1 pooka
3379 1.4 nonaka static int
3380 1.71 nonaka iwm_load_cpu_sections_7000(struct iwm_softc *sc, struct iwm_fw_sects *fws,
3381 1.71 nonaka int cpu, int *first_ucode_section)
3382 1.1 pooka {
3383 1.71 nonaka int i, err = 0;
3384 1.71 nonaka uint32_t last_read_idx = 0;
3385 1.1 pooka void *data;
3386 1.1 pooka uint32_t dlen;
3387 1.1 pooka uint32_t offset;
3388 1.1 pooka
3389 1.71 nonaka if (cpu == 1) {
3390 1.71 nonaka *first_ucode_section = 0;
3391 1.71 nonaka } else {
3392 1.71 nonaka (*first_ucode_section)++;
3393 1.71 nonaka }
3394 1.71 nonaka
3395 1.71 nonaka for (i = *first_ucode_section; i < IWM_UCODE_SECT_MAX; i++) {
3396 1.71 nonaka last_read_idx = i;
3397 1.1 pooka data = fws->fw_sect[i].fws_data;
3398 1.1 pooka dlen = fws->fw_sect[i].fws_len;
3399 1.1 pooka offset = fws->fw_sect[i].fws_devoff;
3400 1.71 nonaka
3401 1.71 nonaka /*
3402 1.71 nonaka * CPU1_CPU2_SEPARATOR_SECTION delimiter - separate between
3403 1.71 nonaka * CPU1 to CPU2.
3404 1.71 nonaka * PAGING_SEPARATOR_SECTION delimiter - separate between
3405 1.71 nonaka * CPU2 non paged to CPU2 paging sec.
3406 1.71 nonaka */
3407 1.71 nonaka if (!data || offset == IWM_CPU1_CPU2_SEPARATOR_SECTION ||
3408 1.71 nonaka offset == IWM_PAGING_SEPARATOR_SECTION)
3409 1.71 nonaka break;
3410 1.71 nonaka
3411 1.45 nonaka if (dlen > sc->sc_fwdmasegsz) {
3412 1.45 nonaka err = EFBIG;
3413 1.45 nonaka } else
3414 1.45 nonaka err = iwm_firmware_load_sect(sc, offset, data, dlen);
3415 1.45 nonaka if (err) {
3416 1.71 nonaka DPRINTF(("%s: could not load firmware chunk %d "
3417 1.71 nonaka "(error %d)\n", DEVNAME(sc), i, err));
3418 1.45 nonaka return err;
3419 1.1 pooka }
3420 1.1 pooka }
3421 1.1 pooka
3422 1.71 nonaka *first_ucode_section = last_read_idx;
3423 1.71 nonaka
3424 1.71 nonaka return 0;
3425 1.71 nonaka }
3426 1.71 nonaka
3427 1.71 nonaka static int
3428 1.71 nonaka iwm_load_firmware_7000(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
3429 1.71 nonaka {
3430 1.71 nonaka struct iwm_fw_sects *fws;
3431 1.71 nonaka int err = 0;
3432 1.71 nonaka int first_ucode_section;
3433 1.71 nonaka
3434 1.71 nonaka fws = &sc->sc_fw.fw_sects[ucode_type];
3435 1.71 nonaka
3436 1.71 nonaka DPRINTF(("%s: working with %s CPU\n", DEVNAME(sc),
3437 1.71 nonaka fws->is_dual_cpus ? "dual" : "single"));
3438 1.71 nonaka
3439 1.71 nonaka /* load to FW the binary Secured sections of CPU1 */
3440 1.71 nonaka err = iwm_load_cpu_sections_7000(sc, fws, 1, &first_ucode_section);
3441 1.71 nonaka if (err)
3442 1.71 nonaka return err;
3443 1.71 nonaka
3444 1.71 nonaka if (fws->is_dual_cpus) {
3445 1.71 nonaka /* set CPU2 header address */
3446 1.71 nonaka if (iwm_nic_lock(sc)) {
3447 1.71 nonaka iwm_write_prph(sc,
3448 1.71 nonaka IWM_LMPM_SECURE_UCODE_LOAD_CPU2_HDR_ADDR,
3449 1.71 nonaka IWM_LMPM_SECURE_CPU2_HDR_MEM_SPACE);
3450 1.71 nonaka iwm_nic_unlock(sc);
3451 1.71 nonaka }
3452 1.71 nonaka
3453 1.71 nonaka /* load to FW the binary sections of CPU2 */
3454 1.71 nonaka err = iwm_load_cpu_sections_7000(sc, fws, 2,
3455 1.71 nonaka &first_ucode_section);
3456 1.71 nonaka if (err)
3457 1.71 nonaka return err;
3458 1.71 nonaka }
3459 1.71 nonaka
3460 1.71 nonaka /* release CPU reset */
3461 1.1 pooka IWM_WRITE(sc, IWM_CSR_RESET, 0);
3462 1.1 pooka
3463 1.45 nonaka return 0;
3464 1.1 pooka }
3465 1.1 pooka
3466 1.4 nonaka static int
3467 1.45 nonaka iwm_load_cpu_sections_8000(struct iwm_softc *sc, struct iwm_fw_sects *fws,
3468 1.45 nonaka int cpu, int *first_ucode_section)
3469 1.1 pooka {
3470 1.45 nonaka int shift_param;
3471 1.45 nonaka int i, err = 0, sec_num = 0x1;
3472 1.45 nonaka uint32_t val, last_read_idx = 0;
3473 1.45 nonaka void *data;
3474 1.45 nonaka uint32_t dlen;
3475 1.45 nonaka uint32_t offset;
3476 1.1 pooka
3477 1.45 nonaka if (cpu == 1) {
3478 1.45 nonaka shift_param = 0;
3479 1.45 nonaka *first_ucode_section = 0;
3480 1.45 nonaka } else {
3481 1.45 nonaka shift_param = 16;
3482 1.45 nonaka (*first_ucode_section)++;
3483 1.45 nonaka }
3484 1.1 pooka
3485 1.45 nonaka for (i = *first_ucode_section; i < IWM_UCODE_SECT_MAX; i++) {
3486 1.45 nonaka last_read_idx = i;
3487 1.45 nonaka data = fws->fw_sect[i].fws_data;
3488 1.45 nonaka dlen = fws->fw_sect[i].fws_len;
3489 1.45 nonaka offset = fws->fw_sect[i].fws_devoff;
3490 1.1 pooka
3491 1.45 nonaka /*
3492 1.45 nonaka * CPU1_CPU2_SEPARATOR_SECTION delimiter - separate between
3493 1.45 nonaka * CPU1 to CPU2.
3494 1.45 nonaka * PAGING_SEPARATOR_SECTION delimiter - separate between
3495 1.45 nonaka * CPU2 non paged to CPU2 paging sec.
3496 1.45 nonaka */
3497 1.45 nonaka if (!data || offset == IWM_CPU1_CPU2_SEPARATOR_SECTION ||
3498 1.45 nonaka offset == IWM_PAGING_SEPARATOR_SECTION)
3499 1.45 nonaka break;
3500 1.1 pooka
3501 1.45 nonaka if (dlen > sc->sc_fwdmasegsz) {
3502 1.45 nonaka err = EFBIG;
3503 1.45 nonaka } else
3504 1.45 nonaka err = iwm_firmware_load_sect(sc, offset, data, dlen);
3505 1.45 nonaka if (err) {
3506 1.61 nonaka DPRINTF(("%s: could not load firmware chunk %d "
3507 1.61 nonaka "(error %d)\n", DEVNAME(sc), i, err));
3508 1.45 nonaka return err;
3509 1.45 nonaka }
3510 1.1 pooka
3511 1.45 nonaka /* Notify the ucode of the loaded section number and status */
3512 1.45 nonaka if (iwm_nic_lock(sc)) {
3513 1.45 nonaka val = IWM_READ(sc, IWM_FH_UCODE_LOAD_STATUS);
3514 1.45 nonaka val = val | (sec_num << shift_param);
3515 1.45 nonaka IWM_WRITE(sc, IWM_FH_UCODE_LOAD_STATUS, val);
3516 1.45 nonaka sec_num = (sec_num << 1) | 0x1;
3517 1.45 nonaka iwm_nic_unlock(sc);
3518 1.1 pooka
3519 1.45 nonaka /*
3520 1.45 nonaka * The firmware won't load correctly without this delay.
3521 1.45 nonaka */
3522 1.45 nonaka DELAY(8000);
3523 1.45 nonaka }
3524 1.45 nonaka }
3525 1.45 nonaka
3526 1.45 nonaka *first_ucode_section = last_read_idx;
3527 1.45 nonaka
3528 1.45 nonaka if (iwm_nic_lock(sc)) {
3529 1.45 nonaka if (cpu == 1)
3530 1.45 nonaka IWM_WRITE(sc, IWM_FH_UCODE_LOAD_STATUS, 0xFFFF);
3531 1.45 nonaka else
3532 1.45 nonaka IWM_WRITE(sc, IWM_FH_UCODE_LOAD_STATUS, 0xFFFFFFFF);
3533 1.45 nonaka iwm_nic_unlock(sc);
3534 1.6 nonaka }
3535 1.45 nonaka
3536 1.45 nonaka return 0;
3537 1.45 nonaka }
3538 1.45 nonaka
3539 1.45 nonaka static int
3540 1.45 nonaka iwm_load_firmware_8000(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
3541 1.45 nonaka {
3542 1.45 nonaka struct iwm_fw_sects *fws;
3543 1.45 nonaka int err = 0;
3544 1.45 nonaka int first_ucode_section;
3545 1.45 nonaka
3546 1.45 nonaka fws = &sc->sc_fw.fw_sects[ucode_type];
3547 1.45 nonaka
3548 1.45 nonaka /* configure the ucode to be ready to get the secured image */
3549 1.45 nonaka /* release CPU reset */
3550 1.61 nonaka if (iwm_nic_lock(sc)) {
3551 1.61 nonaka iwm_write_prph(sc, IWM_RELEASE_CPU_RESET,
3552 1.61 nonaka IWM_RELEASE_CPU_RESET_BIT);
3553 1.61 nonaka iwm_nic_unlock(sc);
3554 1.61 nonaka }
3555 1.45 nonaka
3556 1.45 nonaka /* load to FW the binary Secured sections of CPU1 */
3557 1.45 nonaka err = iwm_load_cpu_sections_8000(sc, fws, 1, &first_ucode_section);
3558 1.45 nonaka if (err)
3559 1.45 nonaka return err;
3560 1.45 nonaka
3561 1.45 nonaka /* load to FW the binary sections of CPU2 */
3562 1.45 nonaka return iwm_load_cpu_sections_8000(sc, fws, 2, &first_ucode_section);
3563 1.45 nonaka }
3564 1.45 nonaka
3565 1.45 nonaka static int
3566 1.45 nonaka iwm_load_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
3567 1.45 nonaka {
3568 1.45 nonaka int err, w;
3569 1.45 nonaka
3570 1.45 nonaka sc->sc_uc.uc_intr = 0;
3571 1.45 nonaka
3572 1.45 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000)
3573 1.45 nonaka err = iwm_load_firmware_8000(sc, ucode_type);
3574 1.45 nonaka else
3575 1.45 nonaka err = iwm_load_firmware_7000(sc, ucode_type);
3576 1.45 nonaka if (err)
3577 1.45 nonaka return err;
3578 1.45 nonaka
3579 1.45 nonaka /* wait for the firmware to load */
3580 1.45 nonaka for (w = 0; !sc->sc_uc.uc_intr && w < 10; w++)
3581 1.45 nonaka err = tsleep(&sc->sc_uc, 0, "iwmuc", mstohz(100));
3582 1.61 nonaka if (err || !sc->sc_uc.uc_ok) {
3583 1.61 nonaka aprint_error_dev(sc->sc_dev,
3584 1.61 nonaka "could not load firmware (error %d, ok %d)\n",
3585 1.61 nonaka err, sc->sc_uc.uc_ok);
3586 1.61 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) {
3587 1.61 nonaka aprint_error_dev(sc->sc_dev, "cpu1 status: 0x%x\n",
3588 1.61 nonaka iwm_read_prph(sc, IWM_SB_CPU_1_STATUS));
3589 1.61 nonaka aprint_error_dev(sc->sc_dev, "cpu2 status: 0x%x\n",
3590 1.61 nonaka iwm_read_prph(sc, IWM_SB_CPU_2_STATUS));
3591 1.61 nonaka }
3592 1.61 nonaka }
3593 1.45 nonaka
3594 1.45 nonaka return err;
3595 1.1 pooka }
3596 1.1 pooka
3597 1.4 nonaka static int
3598 1.45 nonaka iwm_start_fw(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
3599 1.1 pooka {
3600 1.45 nonaka int err;
3601 1.45 nonaka
3602 1.45 nonaka IWM_WRITE(sc, IWM_CSR_INT, ~0);
3603 1.45 nonaka
3604 1.45 nonaka err = iwm_nic_init(sc);
3605 1.45 nonaka if (err) {
3606 1.45 nonaka aprint_error_dev(sc->sc_dev, "Unable to init nic\n");
3607 1.45 nonaka return err;
3608 1.45 nonaka }
3609 1.45 nonaka
3610 1.45 nonaka /* make sure rfkill handshake bits are cleared */
3611 1.45 nonaka IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
3612 1.45 nonaka IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR,
3613 1.45 nonaka IWM_CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
3614 1.45 nonaka
3615 1.45 nonaka /* clear (again), then enable host interrupts */
3616 1.45 nonaka IWM_WRITE(sc, IWM_CSR_INT, ~0);
3617 1.45 nonaka iwm_enable_interrupts(sc);
3618 1.45 nonaka
3619 1.45 nonaka /* really make sure rfkill handshake bits are cleared */
3620 1.45 nonaka /* maybe we should write a few times more? just to make sure */
3621 1.45 nonaka IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
3622 1.45 nonaka IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
3623 1.45 nonaka
3624 1.45 nonaka return iwm_load_firmware(sc, ucode_type);
3625 1.1 pooka }
3626 1.1 pooka
3627 1.4 nonaka static int
3628 1.1 pooka iwm_send_tx_ant_cfg(struct iwm_softc *sc, uint8_t valid_tx_ant)
3629 1.1 pooka {
3630 1.1 pooka struct iwm_tx_ant_cfg_cmd tx_ant_cmd = {
3631 1.1 pooka .valid = htole32(valid_tx_ant),
3632 1.1 pooka };
3633 1.1 pooka
3634 1.45 nonaka return iwm_send_cmd_pdu(sc, IWM_TX_ANT_CONFIGURATION_CMD, 0,
3635 1.45 nonaka sizeof(tx_ant_cmd), &tx_ant_cmd);
3636 1.1 pooka }
3637 1.1 pooka
3638 1.4 nonaka static int
3639 1.1 pooka iwm_send_phy_cfg_cmd(struct iwm_softc *sc)
3640 1.1 pooka {
3641 1.1 pooka struct iwm_phy_cfg_cmd phy_cfg_cmd;
3642 1.1 pooka enum iwm_ucode_type ucode_type = sc->sc_uc_current;
3643 1.1 pooka
3644 1.1 pooka phy_cfg_cmd.phy_cfg = htole32(sc->sc_fw_phy_config);
3645 1.1 pooka phy_cfg_cmd.calib_control.event_trigger =
3646 1.1 pooka sc->sc_default_calib[ucode_type].event_trigger;
3647 1.1 pooka phy_cfg_cmd.calib_control.flow_trigger =
3648 1.1 pooka sc->sc_default_calib[ucode_type].flow_trigger;
3649 1.1 pooka
3650 1.1 pooka DPRINTFN(10, ("Sending Phy CFG command: 0x%x\n", phy_cfg_cmd.phy_cfg));
3651 1.45 nonaka return iwm_send_cmd_pdu(sc, IWM_PHY_CONFIGURATION_CMD, 0,
3652 1.1 pooka sizeof(phy_cfg_cmd), &phy_cfg_cmd);
3653 1.1 pooka }
3654 1.1 pooka
3655 1.4 nonaka static int
3656 1.51 nonaka iwm_load_ucode_wait_alive(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
3657 1.1 pooka {
3658 1.71 nonaka struct iwm_fw_sects *fws;
3659 1.1 pooka enum iwm_ucode_type old_type = sc->sc_uc_current;
3660 1.45 nonaka int err;
3661 1.1 pooka
3662 1.61 nonaka err = iwm_read_firmware(sc, ucode_type);
3663 1.45 nonaka if (err)
3664 1.45 nonaka return err;
3665 1.1 pooka
3666 1.1 pooka sc->sc_uc_current = ucode_type;
3667 1.45 nonaka err = iwm_start_fw(sc, ucode_type);
3668 1.45 nonaka if (err) {
3669 1.1 pooka sc->sc_uc_current = old_type;
3670 1.45 nonaka return err;
3671 1.1 pooka }
3672 1.1 pooka
3673 1.71 nonaka err = iwm_post_alive(sc);
3674 1.71 nonaka if (err)
3675 1.71 nonaka return err;
3676 1.71 nonaka
3677 1.71 nonaka fws = &sc->sc_fw.fw_sects[ucode_type];
3678 1.71 nonaka if (fws->paging_mem_size) {
3679 1.71 nonaka err = iwm_save_fw_paging(sc, fws);
3680 1.71 nonaka if (err)
3681 1.71 nonaka return err;
3682 1.71 nonaka
3683 1.71 nonaka err = iwm_send_paging_cmd(sc, fws);
3684 1.71 nonaka if (err) {
3685 1.71 nonaka iwm_free_fw_paging(sc);
3686 1.71 nonaka return err;
3687 1.71 nonaka }
3688 1.71 nonaka }
3689 1.71 nonaka
3690 1.71 nonaka return 0;
3691 1.1 pooka }
3692 1.1 pooka
3693 1.4 nonaka static int
3694 1.1 pooka iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
3695 1.1 pooka {
3696 1.45 nonaka int err;
3697 1.1 pooka
3698 1.1 pooka if ((sc->sc_flags & IWM_FLAG_RFKILL) && !justnvm) {
3699 1.3 nonaka aprint_error_dev(sc->sc_dev,
3700 1.3 nonaka "radio is disabled by hardware switch\n");
3701 1.1 pooka return EPERM;
3702 1.1 pooka }
3703 1.1 pooka
3704 1.1 pooka sc->sc_init_complete = 0;
3705 1.45 nonaka err = iwm_load_ucode_wait_alive(sc, IWM_UCODE_TYPE_INIT);
3706 1.45 nonaka if (err) {
3707 1.61 nonaka DPRINTF(("%s: failed to load init firmware\n", DEVNAME(sc)));
3708 1.45 nonaka return err;
3709 1.45 nonaka }
3710 1.1 pooka
3711 1.1 pooka if (justnvm) {
3712 1.45 nonaka err = iwm_nvm_init(sc);
3713 1.45 nonaka if (err) {
3714 1.3 nonaka aprint_error_dev(sc->sc_dev, "failed to read nvm\n");
3715 1.45 nonaka return err;
3716 1.1 pooka }
3717 1.1 pooka
3718 1.45 nonaka memcpy(&sc->sc_ic.ic_myaddr, &sc->sc_nvm.hw_addr,
3719 1.45 nonaka ETHER_ADDR_LEN);
3720 1.1 pooka return 0;
3721 1.1 pooka }
3722 1.1 pooka
3723 1.45 nonaka err = iwm_send_bt_init_conf(sc);
3724 1.45 nonaka if (err)
3725 1.45 nonaka return err;
3726 1.45 nonaka
3727 1.45 nonaka err = iwm_sf_config(sc, IWM_SF_INIT_OFF);
3728 1.45 nonaka if (err)
3729 1.45 nonaka return err;
3730 1.45 nonaka
3731 1.45 nonaka err = iwm_send_tx_ant_cfg(sc, iwm_fw_valid_tx_ant(sc));
3732 1.45 nonaka if (err)
3733 1.45 nonaka return err;
3734 1.1 pooka
3735 1.1 pooka /*
3736 1.45 nonaka * Send phy configurations command to init uCode
3737 1.45 nonaka * to start the 16.0 uCode init image internal calibrations.
3738 1.45 nonaka */
3739 1.45 nonaka err = iwm_send_phy_cfg_cmd(sc);
3740 1.45 nonaka if (err)
3741 1.45 nonaka return err;
3742 1.1 pooka
3743 1.1 pooka /*
3744 1.1 pooka * Nothing to do but wait for the init complete notification
3745 1.1 pooka * from the firmware
3746 1.1 pooka */
3747 1.45 nonaka while (!sc->sc_init_complete) {
3748 1.45 nonaka err = tsleep(&sc->sc_init_complete, 0, "iwminit", mstohz(2000));
3749 1.45 nonaka if (err)
3750 1.1 pooka break;
3751 1.45 nonaka }
3752 1.1 pooka
3753 1.45 nonaka return err;
3754 1.1 pooka }
3755 1.1 pooka
3756 1.4 nonaka static int
3757 1.1 pooka iwm_rx_addbuf(struct iwm_softc *sc, int size, int idx)
3758 1.1 pooka {
3759 1.1 pooka struct iwm_rx_ring *ring = &sc->rxq;
3760 1.1 pooka struct iwm_rx_data *data = &ring->data[idx];
3761 1.1 pooka struct mbuf *m;
3762 1.45 nonaka int err;
3763 1.1 pooka int fatal = 0;
3764 1.1 pooka
3765 1.1 pooka m = m_gethdr(M_DONTWAIT, MT_DATA);
3766 1.1 pooka if (m == NULL)
3767 1.1 pooka return ENOBUFS;
3768 1.1 pooka
3769 1.1 pooka if (size <= MCLBYTES) {
3770 1.1 pooka MCLGET(m, M_DONTWAIT);
3771 1.1 pooka } else {
3772 1.89 mlelstv MEXTMALLOC(m, size, M_DONTWAIT);
3773 1.1 pooka }
3774 1.1 pooka if ((m->m_flags & M_EXT) == 0) {
3775 1.1 pooka m_freem(m);
3776 1.1 pooka return ENOBUFS;
3777 1.1 pooka }
3778 1.1 pooka
3779 1.1 pooka if (data->m != NULL) {
3780 1.1 pooka bus_dmamap_unload(sc->sc_dmat, data->map);
3781 1.1 pooka fatal = 1;
3782 1.1 pooka }
3783 1.1 pooka
3784 1.89 mlelstv m->m_len = m->m_pkthdr.len = size;
3785 1.45 nonaka err = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
3786 1.45 nonaka BUS_DMA_READ|BUS_DMA_NOWAIT);
3787 1.45 nonaka if (err) {
3788 1.1 pooka /* XXX */
3789 1.1 pooka if (fatal)
3790 1.1 pooka panic("iwm: could not load RX mbuf");
3791 1.1 pooka m_freem(m);
3792 1.45 nonaka return err;
3793 1.1 pooka }
3794 1.1 pooka data->m = m;
3795 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0, size, BUS_DMASYNC_PREREAD);
3796 1.1 pooka
3797 1.8 nonaka /* Update RX descriptor. */
3798 1.1 pooka ring->desc[idx] = htole32(data->map->dm_segs[0].ds_addr >> 8);
3799 1.1 pooka bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
3800 1.1 pooka idx * sizeof(uint32_t), sizeof(uint32_t), BUS_DMASYNC_PREWRITE);
3801 1.1 pooka
3802 1.1 pooka return 0;
3803 1.1 pooka }
3804 1.1 pooka
3805 1.1 pooka #define IWM_RSSI_OFFSET 50
3806 1.4 nonaka static int
3807 1.45 nonaka iwm_calc_rssi(struct iwm_softc *sc, struct iwm_rx_phy_info *phy_info)
3808 1.1 pooka {
3809 1.1 pooka int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
3810 1.1 pooka uint32_t agc_a, agc_b;
3811 1.1 pooka uint32_t val;
3812 1.1 pooka
3813 1.1 pooka val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_AGC_IDX]);
3814 1.1 pooka agc_a = (val & IWM_OFDM_AGC_A_MSK) >> IWM_OFDM_AGC_A_POS;
3815 1.1 pooka agc_b = (val & IWM_OFDM_AGC_B_MSK) >> IWM_OFDM_AGC_B_POS;
3816 1.1 pooka
3817 1.1 pooka val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_RSSI_AB_IDX]);
3818 1.1 pooka rssi_a = (val & IWM_OFDM_RSSI_INBAND_A_MSK) >> IWM_OFDM_RSSI_A_POS;
3819 1.1 pooka rssi_b = (val & IWM_OFDM_RSSI_INBAND_B_MSK) >> IWM_OFDM_RSSI_B_POS;
3820 1.1 pooka
3821 1.1 pooka /*
3822 1.1 pooka * dBm = rssi dB - agc dB - constant.
3823 1.1 pooka * Higher AGC (higher radio gain) means lower signal.
3824 1.1 pooka */
3825 1.1 pooka rssi_a_dbm = rssi_a - IWM_RSSI_OFFSET - agc_a;
3826 1.1 pooka rssi_b_dbm = rssi_b - IWM_RSSI_OFFSET - agc_b;
3827 1.1 pooka max_rssi_dbm = MAX(rssi_a_dbm, rssi_b_dbm);
3828 1.1 pooka
3829 1.1 pooka DPRINTF(("Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
3830 1.1 pooka rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b));
3831 1.1 pooka
3832 1.1 pooka return max_rssi_dbm;
3833 1.1 pooka }
3834 1.1 pooka
3835 1.1 pooka /*
3836 1.45 nonaka * RSSI values are reported by the FW as positive values - need to negate
3837 1.1 pooka * to obtain their dBM. Account for missing antennas by replacing 0
3838 1.1 pooka * values by -256dBm: practically 0 power and a non-feasible 8 bit value.
3839 1.1 pooka */
3840 1.4 nonaka static int
3841 1.51 nonaka iwm_get_signal_strength(struct iwm_softc *sc, struct iwm_rx_phy_info *phy_info)
3842 1.1 pooka {
3843 1.1 pooka int energy_a, energy_b, energy_c, max_energy;
3844 1.1 pooka uint32_t val;
3845 1.1 pooka
3846 1.1 pooka val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_ENERGY_ANT_ABC_IDX]);
3847 1.1 pooka energy_a = (val & IWM_RX_INFO_ENERGY_ANT_A_MSK) >>
3848 1.1 pooka IWM_RX_INFO_ENERGY_ANT_A_POS;
3849 1.1 pooka energy_a = energy_a ? -energy_a : -256;
3850 1.1 pooka energy_b = (val & IWM_RX_INFO_ENERGY_ANT_B_MSK) >>
3851 1.1 pooka IWM_RX_INFO_ENERGY_ANT_B_POS;
3852 1.1 pooka energy_b = energy_b ? -energy_b : -256;
3853 1.1 pooka energy_c = (val & IWM_RX_INFO_ENERGY_ANT_C_MSK) >>
3854 1.1 pooka IWM_RX_INFO_ENERGY_ANT_C_POS;
3855 1.1 pooka energy_c = energy_c ? -energy_c : -256;
3856 1.1 pooka max_energy = MAX(energy_a, energy_b);
3857 1.1 pooka max_energy = MAX(max_energy, energy_c);
3858 1.1 pooka
3859 1.5 nonaka DPRINTFN(12, ("energy In A %d B %d C %d, and max %d\n",
3860 1.1 pooka energy_a, energy_b, energy_c, max_energy));
3861 1.1 pooka
3862 1.1 pooka return max_energy;
3863 1.1 pooka }
3864 1.1 pooka
3865 1.4 nonaka static void
3866 1.45 nonaka iwm_rx_rx_phy_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
3867 1.45 nonaka struct iwm_rx_data *data)
3868 1.1 pooka {
3869 1.1 pooka struct iwm_rx_phy_info *phy_info = (void *)pkt->data;
3870 1.1 pooka
3871 1.1 pooka DPRINTFN(20, ("received PHY stats\n"));
3872 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*pkt),
3873 1.1 pooka sizeof(*phy_info), BUS_DMASYNC_POSTREAD);
3874 1.1 pooka
3875 1.1 pooka memcpy(&sc->sc_last_phy_info, phy_info, sizeof(sc->sc_last_phy_info));
3876 1.1 pooka }
3877 1.1 pooka
3878 1.1 pooka /*
3879 1.1 pooka * Retrieve the average noise (in dBm) among receivers.
3880 1.1 pooka */
3881 1.4 nonaka static int
3882 1.45 nonaka iwm_get_noise(const struct iwm_statistics_rx_non_phy *stats)
3883 1.1 pooka {
3884 1.1 pooka int i, total, nbant, noise;
3885 1.1 pooka
3886 1.1 pooka total = nbant = noise = 0;
3887 1.1 pooka for (i = 0; i < 3; i++) {
3888 1.1 pooka noise = le32toh(stats->beacon_silence_rssi[i]) & 0xff;
3889 1.1 pooka if (noise) {
3890 1.1 pooka total += noise;
3891 1.1 pooka nbant++;
3892 1.1 pooka }
3893 1.1 pooka }
3894 1.1 pooka
3895 1.1 pooka /* There should be at least one antenna but check anyway. */
3896 1.1 pooka return (nbant == 0) ? -127 : (total / nbant) - 107;
3897 1.1 pooka }
3898 1.1 pooka
3899 1.4 nonaka static void
3900 1.45 nonaka iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
3901 1.45 nonaka struct iwm_rx_data *data)
3902 1.1 pooka {
3903 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
3904 1.1 pooka struct ieee80211_frame *wh;
3905 1.1 pooka struct ieee80211_node *ni;
3906 1.1 pooka struct ieee80211_channel *c = NULL;
3907 1.1 pooka struct mbuf *m;
3908 1.1 pooka struct iwm_rx_phy_info *phy_info;
3909 1.1 pooka struct iwm_rx_mpdu_res_start *rx_res;
3910 1.1 pooka int device_timestamp;
3911 1.1 pooka uint32_t len;
3912 1.1 pooka uint32_t rx_pkt_status;
3913 1.1 pooka int rssi;
3914 1.50 nonaka int s;
3915 1.1 pooka
3916 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE,
3917 1.1 pooka BUS_DMASYNC_POSTREAD);
3918 1.1 pooka
3919 1.1 pooka phy_info = &sc->sc_last_phy_info;
3920 1.1 pooka rx_res = (struct iwm_rx_mpdu_res_start *)pkt->data;
3921 1.1 pooka wh = (struct ieee80211_frame *)(pkt->data + sizeof(*rx_res));
3922 1.1 pooka len = le16toh(rx_res->byte_count);
3923 1.45 nonaka rx_pkt_status = le32toh(*(uint32_t *)(pkt->data +
3924 1.45 nonaka sizeof(*rx_res) + len));
3925 1.1 pooka
3926 1.1 pooka m = data->m;
3927 1.1 pooka m->m_data = pkt->data + sizeof(*rx_res);
3928 1.1 pooka m->m_pkthdr.len = m->m_len = len;
3929 1.1 pooka
3930 1.1 pooka if (__predict_false(phy_info->cfg_phy_cnt > 20)) {
3931 1.1 pooka DPRINTF(("dsp size out of range [0,20]: %d\n",
3932 1.1 pooka phy_info->cfg_phy_cnt));
3933 1.1 pooka return;
3934 1.1 pooka }
3935 1.1 pooka
3936 1.1 pooka if (!(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_CRC_OK) ||
3937 1.1 pooka !(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_OVERRUN_OK)) {
3938 1.1 pooka DPRINTF(("Bad CRC or FIFO: 0x%08X.\n", rx_pkt_status));
3939 1.1 pooka return; /* drop */
3940 1.1 pooka }
3941 1.1 pooka
3942 1.1 pooka device_timestamp = le32toh(phy_info->system_timestamp);
3943 1.1 pooka
3944 1.1 pooka if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_RX_ENERGY_API) {
3945 1.45 nonaka rssi = iwm_get_signal_strength(sc, phy_info);
3946 1.1 pooka } else {
3947 1.45 nonaka rssi = iwm_calc_rssi(sc, phy_info);
3948 1.1 pooka }
3949 1.1 pooka rssi = -rssi;
3950 1.1 pooka
3951 1.1 pooka if (ic->ic_state == IEEE80211_S_SCAN)
3952 1.45 nonaka iwm_fix_channel(sc, m);
3953 1.1 pooka
3954 1.1 pooka if (iwm_rx_addbuf(sc, IWM_RBUF_SIZE, sc->rxq.cur) != 0)
3955 1.1 pooka return;
3956 1.1 pooka
3957 1.42 ozaki m_set_rcvif(m, IC2IFP(ic));
3958 1.1 pooka
3959 1.45 nonaka if (le32toh(phy_info->channel) < __arraycount(ic->ic_channels))
3960 1.45 nonaka c = &ic->ic_channels[le32toh(phy_info->channel)];
3961 1.1 pooka
3962 1.50 nonaka s = splnet();
3963 1.50 nonaka
3964 1.1 pooka ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
3965 1.1 pooka if (c)
3966 1.1 pooka ni->ni_chan = c;
3967 1.1 pooka
3968 1.48 nonaka if (__predict_false(sc->sc_drvbpf != NULL)) {
3969 1.1 pooka struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap;
3970 1.1 pooka
3971 1.1 pooka tap->wr_flags = 0;
3972 1.1 pooka if (phy_info->phy_flags & htole16(IWM_PHY_INFO_FLAG_SHPREAMBLE))
3973 1.1 pooka tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
3974 1.1 pooka tap->wr_chan_freq =
3975 1.1 pooka htole16(ic->ic_channels[phy_info->channel].ic_freq);
3976 1.1 pooka tap->wr_chan_flags =
3977 1.1 pooka htole16(ic->ic_channels[phy_info->channel].ic_flags);
3978 1.1 pooka tap->wr_dbm_antsignal = (int8_t)rssi;
3979 1.1 pooka tap->wr_dbm_antnoise = (int8_t)sc->sc_noise;
3980 1.1 pooka tap->wr_tsft = phy_info->system_timestamp;
3981 1.45 nonaka if (phy_info->phy_flags &
3982 1.45 nonaka htole16(IWM_RX_RES_PHY_FLAGS_OFDM_HT)) {
3983 1.45 nonaka uint8_t mcs = (phy_info->rate_n_flags &
3984 1.61 nonaka htole32(IWM_RATE_HT_MCS_RATE_CODE_MSK |
3985 1.61 nonaka IWM_RATE_HT_MCS_NSS_MSK));
3986 1.45 nonaka tap->wr_rate = (0x80 | mcs);
3987 1.45 nonaka } else {
3988 1.45 nonaka uint8_t rate = (phy_info->rate_n_flags &
3989 1.45 nonaka htole32(IWM_RATE_LEGACY_RATE_MSK));
3990 1.45 nonaka switch (rate) {
3991 1.45 nonaka /* CCK rates. */
3992 1.45 nonaka case 10: tap->wr_rate = 2; break;
3993 1.45 nonaka case 20: tap->wr_rate = 4; break;
3994 1.45 nonaka case 55: tap->wr_rate = 11; break;
3995 1.45 nonaka case 110: tap->wr_rate = 22; break;
3996 1.45 nonaka /* OFDM rates. */
3997 1.45 nonaka case 0xd: tap->wr_rate = 12; break;
3998 1.45 nonaka case 0xf: tap->wr_rate = 18; break;
3999 1.45 nonaka case 0x5: tap->wr_rate = 24; break;
4000 1.45 nonaka case 0x7: tap->wr_rate = 36; break;
4001 1.45 nonaka case 0x9: tap->wr_rate = 48; break;
4002 1.45 nonaka case 0xb: tap->wr_rate = 72; break;
4003 1.45 nonaka case 0x1: tap->wr_rate = 96; break;
4004 1.45 nonaka case 0x3: tap->wr_rate = 108; break;
4005 1.45 nonaka /* Unknown rate: should not happen. */
4006 1.45 nonaka default: tap->wr_rate = 0;
4007 1.45 nonaka }
4008 1.1 pooka }
4009 1.1 pooka
4010 1.83 msaitoh bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m, BPF_D_IN);
4011 1.1 pooka }
4012 1.1 pooka ieee80211_input(ic, m, ni, rssi, device_timestamp);
4013 1.1 pooka ieee80211_free_node(ni);
4014 1.50 nonaka
4015 1.50 nonaka splx(s);
4016 1.1 pooka }
4017 1.1 pooka
4018 1.4 nonaka static void
4019 1.45 nonaka iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
4020 1.45 nonaka struct iwm_node *in)
4021 1.1 pooka {
4022 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
4023 1.1 pooka struct ifnet *ifp = IC2IFP(ic);
4024 1.45 nonaka struct iwm_tx_resp *tx_resp = (void *)pkt->data;
4025 1.1 pooka int status = le16toh(tx_resp->status.status) & IWM_TX_STATUS_MSK;
4026 1.1 pooka int failack = tx_resp->failure_frame;
4027 1.1 pooka
4028 1.1 pooka KASSERT(tx_resp->frame_count == 1);
4029 1.1 pooka
4030 1.1 pooka /* Update rate control statistics. */
4031 1.1 pooka in->in_amn.amn_txcnt++;
4032 1.1 pooka if (failack > 0) {
4033 1.1 pooka in->in_amn.amn_retrycnt++;
4034 1.1 pooka }
4035 1.1 pooka
4036 1.1 pooka if (status != IWM_TX_STATUS_SUCCESS &&
4037 1.1 pooka status != IWM_TX_STATUS_DIRECT_DONE)
4038 1.84 thorpej if_statinc(ifp, if_oerrors);
4039 1.1 pooka else
4040 1.84 thorpej if_statinc(ifp, if_opackets);
4041 1.1 pooka }
4042 1.1 pooka
4043 1.4 nonaka static void
4044 1.45 nonaka iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
4045 1.45 nonaka struct iwm_rx_data *data)
4046 1.1 pooka {
4047 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
4048 1.1 pooka struct ifnet *ifp = IC2IFP(ic);
4049 1.1 pooka struct iwm_cmd_header *cmd_hdr = &pkt->hdr;
4050 1.1 pooka int idx = cmd_hdr->idx;
4051 1.1 pooka int qid = cmd_hdr->qid;
4052 1.1 pooka struct iwm_tx_ring *ring = &sc->txq[qid];
4053 1.1 pooka struct iwm_tx_data *txd = &ring->data[idx];
4054 1.1 pooka struct iwm_node *in = txd->in;
4055 1.61 nonaka int s;
4056 1.61 nonaka
4057 1.61 nonaka s = splnet();
4058 1.1 pooka
4059 1.1 pooka if (txd->done) {
4060 1.2 nonaka DPRINTF(("%s: got tx interrupt that's already been handled!\n",
4061 1.2 nonaka DEVNAME(sc)));
4062 1.61 nonaka splx(s);
4063 1.1 pooka return;
4064 1.1 pooka }
4065 1.1 pooka
4066 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE,
4067 1.1 pooka BUS_DMASYNC_POSTREAD);
4068 1.1 pooka
4069 1.1 pooka sc->sc_tx_timer = 0;
4070 1.1 pooka
4071 1.45 nonaka iwm_rx_tx_cmd_single(sc, pkt, in);
4072 1.1 pooka
4073 1.1 pooka bus_dmamap_sync(sc->sc_dmat, txd->map, 0, txd->map->dm_mapsize,
4074 1.1 pooka BUS_DMASYNC_POSTWRITE);
4075 1.1 pooka bus_dmamap_unload(sc->sc_dmat, txd->map);
4076 1.1 pooka m_freem(txd->m);
4077 1.1 pooka
4078 1.1 pooka DPRINTFN(8, ("free txd %p, in %p\n", txd, txd->in));
4079 1.1 pooka KASSERT(txd->done == 0);
4080 1.1 pooka txd->done = 1;
4081 1.1 pooka KASSERT(txd->in);
4082 1.1 pooka
4083 1.1 pooka txd->m = NULL;
4084 1.1 pooka txd->in = NULL;
4085 1.1 pooka ieee80211_free_node(&in->in_ni);
4086 1.1 pooka
4087 1.1 pooka if (--ring->queued < IWM_TX_RING_LOMARK) {
4088 1.61 nonaka sc->qfullmsk &= ~(1 << qid);
4089 1.1 pooka if (sc->qfullmsk == 0 && (ifp->if_flags & IFF_OACTIVE)) {
4090 1.1 pooka ifp->if_flags &= ~IFF_OACTIVE;
4091 1.65 nonaka KASSERT(KERNEL_LOCKED_P());
4092 1.65 nonaka iwm_start(ifp);
4093 1.1 pooka }
4094 1.1 pooka }
4095 1.61 nonaka
4096 1.61 nonaka splx(s);
4097 1.1 pooka }
4098 1.1 pooka
4099 1.4 nonaka static int
4100 1.45 nonaka iwm_binding_cmd(struct iwm_softc *sc, struct iwm_node *in, uint32_t action)
4101 1.1 pooka {
4102 1.1 pooka struct iwm_binding_cmd cmd;
4103 1.45 nonaka struct iwm_phy_ctxt *phyctxt = in->in_phyctxt;
4104 1.45 nonaka int i, err;
4105 1.1 pooka uint32_t status;
4106 1.1 pooka
4107 1.1 pooka memset(&cmd, 0, sizeof(cmd));
4108 1.1 pooka
4109 1.1 pooka cmd.id_and_color
4110 1.1 pooka = htole32(IWM_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
4111 1.1 pooka cmd.action = htole32(action);
4112 1.1 pooka cmd.phy = htole32(IWM_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
4113 1.1 pooka
4114 1.1 pooka cmd.macs[0] = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
4115 1.1 pooka for (i = 1; i < IWM_MAX_MACS_IN_BINDING; i++)
4116 1.1 pooka cmd.macs[i] = htole32(IWM_FW_CTXT_INVALID);
4117 1.1 pooka
4118 1.1 pooka status = 0;
4119 1.45 nonaka err = iwm_send_cmd_pdu_status(sc, IWM_BINDING_CONTEXT_CMD,
4120 1.1 pooka sizeof(cmd), &cmd, &status);
4121 1.45 nonaka if (err == 0 && status != 0)
4122 1.45 nonaka err = EIO;
4123 1.1 pooka
4124 1.45 nonaka return err;
4125 1.1 pooka }
4126 1.1 pooka
4127 1.4 nonaka static void
4128 1.45 nonaka iwm_phy_ctxt_cmd_hdr(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt,
4129 1.45 nonaka struct iwm_phy_context_cmd *cmd, uint32_t action, uint32_t apply_time)
4130 1.1 pooka {
4131 1.1 pooka memset(cmd, 0, sizeof(struct iwm_phy_context_cmd));
4132 1.1 pooka
4133 1.1 pooka cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ctxt->id,
4134 1.1 pooka ctxt->color));
4135 1.1 pooka cmd->action = htole32(action);
4136 1.1 pooka cmd->apply_time = htole32(apply_time);
4137 1.1 pooka }
4138 1.1 pooka
4139 1.4 nonaka static void
4140 1.45 nonaka iwm_phy_ctxt_cmd_data(struct iwm_softc *sc, struct iwm_phy_context_cmd *cmd,
4141 1.45 nonaka struct ieee80211_channel *chan, uint8_t chains_static,
4142 1.45 nonaka uint8_t chains_dynamic)
4143 1.1 pooka {
4144 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
4145 1.1 pooka uint8_t active_cnt, idle_cnt;
4146 1.1 pooka
4147 1.1 pooka cmd->ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
4148 1.1 pooka IWM_PHY_BAND_24 : IWM_PHY_BAND_5;
4149 1.1 pooka
4150 1.1 pooka cmd->ci.channel = ieee80211_chan2ieee(ic, chan);
4151 1.1 pooka cmd->ci.width = IWM_PHY_VHT_CHANNEL_MODE20;
4152 1.1 pooka cmd->ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW;
4153 1.1 pooka
4154 1.1 pooka /* Set rx the chains */
4155 1.1 pooka idle_cnt = chains_static;
4156 1.1 pooka active_cnt = chains_dynamic;
4157 1.1 pooka
4158 1.45 nonaka cmd->rxchain_info = htole32(iwm_fw_valid_rx_ant(sc) <<
4159 1.45 nonaka IWM_PHY_RX_CHAIN_VALID_POS);
4160 1.1 pooka cmd->rxchain_info |= htole32(idle_cnt << IWM_PHY_RX_CHAIN_CNT_POS);
4161 1.1 pooka cmd->rxchain_info |= htole32(active_cnt <<
4162 1.1 pooka IWM_PHY_RX_CHAIN_MIMO_CNT_POS);
4163 1.1 pooka
4164 1.45 nonaka cmd->txchain_info = htole32(iwm_fw_valid_tx_ant(sc));
4165 1.1 pooka }
4166 1.1 pooka
4167 1.4 nonaka static int
4168 1.45 nonaka iwm_phy_ctxt_cmd(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt,
4169 1.45 nonaka uint8_t chains_static, uint8_t chains_dynamic, uint32_t action,
4170 1.45 nonaka uint32_t apply_time)
4171 1.1 pooka {
4172 1.1 pooka struct iwm_phy_context_cmd cmd;
4173 1.1 pooka
4174 1.45 nonaka iwm_phy_ctxt_cmd_hdr(sc, ctxt, &cmd, action, apply_time);
4175 1.1 pooka
4176 1.45 nonaka iwm_phy_ctxt_cmd_data(sc, &cmd, ctxt->channel,
4177 1.1 pooka chains_static, chains_dynamic);
4178 1.1 pooka
4179 1.45 nonaka return iwm_send_cmd_pdu(sc, IWM_PHY_CONTEXT_CMD, 0,
4180 1.1 pooka sizeof(struct iwm_phy_context_cmd), &cmd);
4181 1.1 pooka }
4182 1.1 pooka
4183 1.4 nonaka static int
4184 1.1 pooka iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
4185 1.1 pooka {
4186 1.45 nonaka struct iwm_tx_ring *ring = &sc->txq[IWM_CMD_QUEUE];
4187 1.1 pooka struct iwm_tfd *desc;
4188 1.45 nonaka struct iwm_tx_data *txdata;
4189 1.1 pooka struct iwm_device_cmd *cmd;
4190 1.1 pooka struct mbuf *m;
4191 1.1 pooka bus_addr_t paddr;
4192 1.1 pooka uint32_t addr_lo;
4193 1.45 nonaka int err = 0, i, paylen, off, s;
4194 1.1 pooka int code;
4195 1.1 pooka int async, wantresp;
4196 1.45 nonaka int group_id;
4197 1.45 nonaka size_t hdrlen, datasz;
4198 1.45 nonaka uint8_t *data;
4199 1.1 pooka
4200 1.1 pooka code = hcmd->id;
4201 1.1 pooka async = hcmd->flags & IWM_CMD_ASYNC;
4202 1.1 pooka wantresp = hcmd->flags & IWM_CMD_WANT_SKB;
4203 1.1 pooka
4204 1.1 pooka for (i = 0, paylen = 0; i < __arraycount(hcmd->len); i++) {
4205 1.1 pooka paylen += hcmd->len[i];
4206 1.1 pooka }
4207 1.1 pooka
4208 1.1 pooka /* if the command wants an answer, busy sc_cmd_resp */
4209 1.1 pooka if (wantresp) {
4210 1.1 pooka KASSERT(!async);
4211 1.45 nonaka while (sc->sc_wantresp != IWM_CMD_RESP_IDLE)
4212 1.1 pooka tsleep(&sc->sc_wantresp, 0, "iwmcmdsl", 0);
4213 1.1 pooka sc->sc_wantresp = ring->qid << 16 | ring->cur;
4214 1.1 pooka }
4215 1.1 pooka
4216 1.1 pooka /*
4217 1.1 pooka * Is the hardware still available? (after e.g. above wait).
4218 1.1 pooka */
4219 1.1 pooka s = splnet();
4220 1.1 pooka if (sc->sc_flags & IWM_FLAG_STOPPED) {
4221 1.45 nonaka err = ENXIO;
4222 1.1 pooka goto out;
4223 1.1 pooka }
4224 1.1 pooka
4225 1.1 pooka desc = &ring->desc[ring->cur];
4226 1.45 nonaka txdata = &ring->data[ring->cur];
4227 1.45 nonaka
4228 1.45 nonaka group_id = iwm_cmd_groupid(code);
4229 1.45 nonaka if (group_id != 0) {
4230 1.45 nonaka hdrlen = sizeof(cmd->hdr_wide);
4231 1.45 nonaka datasz = sizeof(cmd->data_wide);
4232 1.45 nonaka } else {
4233 1.45 nonaka hdrlen = sizeof(cmd->hdr);
4234 1.45 nonaka datasz = sizeof(cmd->data);
4235 1.45 nonaka }
4236 1.1 pooka
4237 1.45 nonaka if (paylen > datasz) {
4238 1.45 nonaka /* Command is too large to fit in pre-allocated space. */
4239 1.45 nonaka size_t totlen = hdrlen + paylen;
4240 1.45 nonaka if (paylen > IWM_MAX_CMD_PAYLOAD_SIZE) {
4241 1.45 nonaka aprint_error_dev(sc->sc_dev,
4242 1.45 nonaka "firmware command too long (%zd bytes)\n", totlen);
4243 1.45 nonaka err = EINVAL;
4244 1.1 pooka goto out;
4245 1.1 pooka }
4246 1.1 pooka m = m_gethdr(M_DONTWAIT, MT_DATA);
4247 1.1 pooka if (m == NULL) {
4248 1.45 nonaka err = ENOMEM;
4249 1.1 pooka goto out;
4250 1.1 pooka }
4251 1.1 pooka MEXTMALLOC(m, IWM_RBUF_SIZE, M_DONTWAIT);
4252 1.1 pooka if (!(m->m_flags & M_EXT)) {
4253 1.45 nonaka aprint_error_dev(sc->sc_dev,
4254 1.45 nonaka "could not get fw cmd mbuf (%zd bytes)\n", totlen);
4255 1.1 pooka m_freem(m);
4256 1.45 nonaka err = ENOMEM;
4257 1.1 pooka goto out;
4258 1.1 pooka }
4259 1.1 pooka cmd = mtod(m, struct iwm_device_cmd *);
4260 1.45 nonaka err = bus_dmamap_load(sc->sc_dmat, txdata->map, cmd,
4261 1.45 nonaka totlen, NULL, BUS_DMA_NOWAIT | BUS_DMA_WRITE);
4262 1.45 nonaka if (err) {
4263 1.45 nonaka aprint_error_dev(sc->sc_dev,
4264 1.45 nonaka "could not load fw cmd mbuf (%zd bytes)\n", totlen);
4265 1.1 pooka m_freem(m);
4266 1.1 pooka goto out;
4267 1.1 pooka }
4268 1.45 nonaka txdata->m = m;
4269 1.45 nonaka paddr = txdata->map->dm_segs[0].ds_addr;
4270 1.1 pooka } else {
4271 1.1 pooka cmd = &ring->cmd[ring->cur];
4272 1.45 nonaka paddr = txdata->cmd_paddr;
4273 1.1 pooka }
4274 1.1 pooka
4275 1.45 nonaka if (group_id != 0) {
4276 1.45 nonaka cmd->hdr_wide.opcode = iwm_cmd_opcode(code);
4277 1.45 nonaka cmd->hdr_wide.group_id = group_id;
4278 1.45 nonaka cmd->hdr_wide.qid = ring->qid;
4279 1.45 nonaka cmd->hdr_wide.idx = ring->cur;
4280 1.45 nonaka cmd->hdr_wide.length = htole16(paylen);
4281 1.45 nonaka cmd->hdr_wide.version = iwm_cmd_version(code);
4282 1.45 nonaka data = cmd->data_wide;
4283 1.45 nonaka } else {
4284 1.45 nonaka cmd->hdr.code = code;
4285 1.45 nonaka cmd->hdr.flags = 0;
4286 1.45 nonaka cmd->hdr.qid = ring->qid;
4287 1.45 nonaka cmd->hdr.idx = ring->cur;
4288 1.45 nonaka data = cmd->data;
4289 1.45 nonaka }
4290 1.1 pooka
4291 1.1 pooka for (i = 0, off = 0; i < __arraycount(hcmd->data); i++) {
4292 1.1 pooka if (hcmd->len[i] == 0)
4293 1.1 pooka continue;
4294 1.45 nonaka memcpy(data + off, hcmd->data[i], hcmd->len[i]);
4295 1.1 pooka off += hcmd->len[i];
4296 1.1 pooka }
4297 1.1 pooka KASSERT(off == paylen);
4298 1.1 pooka
4299 1.1 pooka /* lo field is not aligned */
4300 1.1 pooka addr_lo = htole32((uint32_t)paddr);
4301 1.1 pooka memcpy(&desc->tbs[0].lo, &addr_lo, sizeof(uint32_t));
4302 1.1 pooka desc->tbs[0].hi_n_len = htole16(iwm_get_dma_hi_addr(paddr)
4303 1.45 nonaka | ((hdrlen + paylen) << 4));
4304 1.1 pooka desc->num_tbs = 1;
4305 1.1 pooka
4306 1.9 nonaka DPRINTFN(8, ("iwm_send_cmd 0x%x size=%zu %s\n",
4307 1.52 nonaka code, hdrlen + paylen, async ? " (async)" : ""));
4308 1.1 pooka
4309 1.45 nonaka if (paylen > datasz) {
4310 1.61 nonaka bus_dmamap_sync(sc->sc_dmat, txdata->map, 0, hdrlen + paylen,
4311 1.61 nonaka BUS_DMASYNC_PREWRITE);
4312 1.1 pooka } else {
4313 1.1 pooka bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
4314 1.61 nonaka (uint8_t *)cmd - (uint8_t *)ring->cmd, hdrlen + paylen,
4315 1.61 nonaka BUS_DMASYNC_PREWRITE);
4316 1.1 pooka }
4317 1.1 pooka bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
4318 1.61 nonaka (uint8_t *)desc - (uint8_t *)ring->desc, sizeof(*desc),
4319 1.61 nonaka BUS_DMASYNC_PREWRITE);
4320 1.1 pooka
4321 1.59 nonaka err = iwm_set_cmd_in_flight(sc);
4322 1.59 nonaka if (err)
4323 1.1 pooka goto out;
4324 1.59 nonaka ring->queued++;
4325 1.1 pooka
4326 1.1 pooka #if 0
4327 1.1 pooka iwm_update_sched(sc, ring->qid, ring->cur, 0, 0);
4328 1.1 pooka #endif
4329 1.1 pooka DPRINTF(("sending command 0x%x qid %d, idx %d\n",
4330 1.1 pooka code, ring->qid, ring->cur));
4331 1.1 pooka
4332 1.1 pooka /* Kick command ring. */
4333 1.1 pooka ring->cur = (ring->cur + 1) % IWM_TX_RING_COUNT;
4334 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
4335 1.1 pooka
4336 1.1 pooka if (!async) {
4337 1.1 pooka int generation = sc->sc_generation;
4338 1.67 nonaka err = tsleep(desc, PCATCH, "iwmcmd", mstohz(2000));
4339 1.45 nonaka if (err == 0) {
4340 1.1 pooka /* if hardware is no longer up, return error */
4341 1.1 pooka if (generation != sc->sc_generation) {
4342 1.45 nonaka err = ENXIO;
4343 1.1 pooka } else {
4344 1.1 pooka hcmd->resp_pkt = (void *)sc->sc_cmd_resp;
4345 1.1 pooka }
4346 1.1 pooka }
4347 1.1 pooka }
4348 1.1 pooka out:
4349 1.45 nonaka if (wantresp && err) {
4350 1.1 pooka iwm_free_resp(sc, hcmd);
4351 1.1 pooka }
4352 1.1 pooka splx(s);
4353 1.1 pooka
4354 1.45 nonaka return err;
4355 1.1 pooka }
4356 1.1 pooka
4357 1.4 nonaka static int
4358 1.45 nonaka iwm_send_cmd_pdu(struct iwm_softc *sc, uint32_t id, uint32_t flags,
4359 1.45 nonaka uint16_t len, const void *data)
4360 1.1 pooka {
4361 1.1 pooka struct iwm_host_cmd cmd = {
4362 1.1 pooka .id = id,
4363 1.1 pooka .len = { len, },
4364 1.1 pooka .data = { data, },
4365 1.1 pooka .flags = flags,
4366 1.1 pooka };
4367 1.1 pooka
4368 1.1 pooka return iwm_send_cmd(sc, &cmd);
4369 1.1 pooka }
4370 1.1 pooka
4371 1.4 nonaka static int
4372 1.45 nonaka iwm_send_cmd_status(struct iwm_softc *sc, struct iwm_host_cmd *cmd,
4373 1.45 nonaka uint32_t *status)
4374 1.1 pooka {
4375 1.1 pooka struct iwm_rx_packet *pkt;
4376 1.1 pooka struct iwm_cmd_response *resp;
4377 1.45 nonaka int err, resp_len;
4378 1.1 pooka
4379 1.1 pooka KASSERT((cmd->flags & IWM_CMD_WANT_SKB) == 0);
4380 1.45 nonaka cmd->flags |= IWM_CMD_WANT_SKB;
4381 1.1 pooka
4382 1.45 nonaka err = iwm_send_cmd(sc, cmd);
4383 1.45 nonaka if (err)
4384 1.45 nonaka return err;
4385 1.1 pooka pkt = cmd->resp_pkt;
4386 1.1 pooka
4387 1.1 pooka /* Can happen if RFKILL is asserted */
4388 1.1 pooka if (!pkt) {
4389 1.45 nonaka err = 0;
4390 1.1 pooka goto out_free_resp;
4391 1.1 pooka }
4392 1.1 pooka
4393 1.1 pooka if (pkt->hdr.flags & IWM_CMD_FAILED_MSK) {
4394 1.45 nonaka err = EIO;
4395 1.1 pooka goto out_free_resp;
4396 1.1 pooka }
4397 1.1 pooka
4398 1.1 pooka resp_len = iwm_rx_packet_payload_len(pkt);
4399 1.1 pooka if (resp_len != sizeof(*resp)) {
4400 1.45 nonaka err = EIO;
4401 1.1 pooka goto out_free_resp;
4402 1.1 pooka }
4403 1.1 pooka
4404 1.1 pooka resp = (void *)pkt->data;
4405 1.1 pooka *status = le32toh(resp->status);
4406 1.1 pooka out_free_resp:
4407 1.1 pooka iwm_free_resp(sc, cmd);
4408 1.45 nonaka return err;
4409 1.1 pooka }
4410 1.1 pooka
4411 1.4 nonaka static int
4412 1.45 nonaka iwm_send_cmd_pdu_status(struct iwm_softc *sc, uint32_t id, uint16_t len,
4413 1.45 nonaka const void *data, uint32_t *status)
4414 1.1 pooka {
4415 1.1 pooka struct iwm_host_cmd cmd = {
4416 1.1 pooka .id = id,
4417 1.1 pooka .len = { len, },
4418 1.1 pooka .data = { data, },
4419 1.1 pooka };
4420 1.1 pooka
4421 1.45 nonaka return iwm_send_cmd_status(sc, &cmd, status);
4422 1.1 pooka }
4423 1.1 pooka
4424 1.4 nonaka static void
4425 1.1 pooka iwm_free_resp(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
4426 1.1 pooka {
4427 1.45 nonaka KASSERT(sc->sc_wantresp != IWM_CMD_RESP_IDLE);
4428 1.45 nonaka KASSERT((hcmd->flags & IWM_CMD_WANT_SKB) == IWM_CMD_WANT_SKB);
4429 1.45 nonaka sc->sc_wantresp = IWM_CMD_RESP_IDLE;
4430 1.1 pooka wakeup(&sc->sc_wantresp);
4431 1.1 pooka }
4432 1.1 pooka
4433 1.4 nonaka static void
4434 1.45 nonaka iwm_cmd_done(struct iwm_softc *sc, int qid, int idx)
4435 1.1 pooka {
4436 1.45 nonaka struct iwm_tx_ring *ring = &sc->txq[IWM_CMD_QUEUE];
4437 1.1 pooka struct iwm_tx_data *data;
4438 1.61 nonaka int s;
4439 1.1 pooka
4440 1.45 nonaka if (qid != IWM_CMD_QUEUE) {
4441 1.1 pooka return; /* Not a command ack. */
4442 1.1 pooka }
4443 1.1 pooka
4444 1.61 nonaka s = splnet();
4445 1.61 nonaka
4446 1.45 nonaka data = &ring->data[idx];
4447 1.1 pooka
4448 1.1 pooka if (data->m != NULL) {
4449 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0,
4450 1.1 pooka data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
4451 1.1 pooka bus_dmamap_unload(sc->sc_dmat, data->map);
4452 1.1 pooka m_freem(data->m);
4453 1.1 pooka data->m = NULL;
4454 1.1 pooka }
4455 1.45 nonaka wakeup(&ring->desc[idx]);
4456 1.59 nonaka
4457 1.59 nonaka if (((idx + ring->queued) % IWM_TX_RING_COUNT) != ring->cur) {
4458 1.89 mlelstv device_printf(sc->sc_dev,
4459 1.59 nonaka "Some HCMDs skipped?: idx=%d queued=%d cur=%d\n",
4460 1.59 nonaka idx, ring->queued, ring->cur);
4461 1.59 nonaka }
4462 1.59 nonaka
4463 1.89 mlelstv if (ring->queued == 0) {
4464 1.89 mlelstv splx(s);
4465 1.89 mlelstv device_printf(sc->sc_dev, "cmd_done with empty ring\n");
4466 1.89 mlelstv return;
4467 1.89 mlelstv }
4468 1.89 mlelstv
4469 1.59 nonaka if (--ring->queued == 0)
4470 1.59 nonaka iwm_clear_cmd_in_flight(sc);
4471 1.61 nonaka
4472 1.61 nonaka splx(s);
4473 1.1 pooka }
4474 1.1 pooka
4475 1.1 pooka #if 0
4476 1.1 pooka /*
4477 1.1 pooka * necessary only for block ack mode
4478 1.1 pooka */
4479 1.1 pooka void
4480 1.1 pooka iwm_update_sched(struct iwm_softc *sc, int qid, int idx, uint8_t sta_id,
4481 1.45 nonaka uint16_t len)
4482 1.1 pooka {
4483 1.1 pooka struct iwm_agn_scd_bc_tbl *scd_bc_tbl;
4484 1.1 pooka uint16_t w_val;
4485 1.1 pooka
4486 1.1 pooka scd_bc_tbl = sc->sched_dma.vaddr;
4487 1.1 pooka
4488 1.1 pooka len += 8; /* magic numbers came naturally from paris */
4489 1.1 pooka if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_DW_BC_TABLE)
4490 1.1 pooka len = roundup(len, 4) / 4;
4491 1.1 pooka
4492 1.1 pooka w_val = htole16(sta_id << 12 | len);
4493 1.1 pooka
4494 1.1 pooka /* Update TX scheduler. */
4495 1.1 pooka scd_bc_tbl[qid].tfd_offset[idx] = w_val;
4496 1.1 pooka bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
4497 1.1 pooka (char *)(void *)w - (char *)(void *)sc->sched_dma.vaddr,
4498 1.1 pooka sizeof(uint16_t), BUS_DMASYNC_PREWRITE);
4499 1.1 pooka
4500 1.1 pooka /* I really wonder what this is ?!? */
4501 1.1 pooka if (idx < IWM_TFD_QUEUE_SIZE_BC_DUP) {
4502 1.1 pooka scd_bc_tbl[qid].tfd_offset[IWM_TFD_QUEUE_SIZE_MAX + idx] = w_val;
4503 1.1 pooka bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
4504 1.1 pooka (char *)(void *)(w + IWM_TFD_QUEUE_SIZE_MAX) -
4505 1.1 pooka (char *)(void *)sc->sched_dma.vaddr,
4506 1.1 pooka sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
4507 1.1 pooka }
4508 1.1 pooka }
4509 1.1 pooka #endif
4510 1.1 pooka
4511 1.1 pooka /*
4512 1.1 pooka * Fill in various bit for management frames, and leave them
4513 1.1 pooka * unfilled for data frames (firmware takes care of that).
4514 1.1 pooka * Return the selected TX rate.
4515 1.1 pooka */
4516 1.4 nonaka static const struct iwm_rate *
4517 1.1 pooka iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in,
4518 1.45 nonaka struct ieee80211_frame *wh, struct iwm_tx_cmd *tx)
4519 1.1 pooka {
4520 1.24 nonaka struct ieee80211com *ic = &sc->sc_ic;
4521 1.28 nonaka struct ieee80211_node *ni = &in->in_ni;
4522 1.1 pooka const struct iwm_rate *rinfo;
4523 1.1 pooka int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
4524 1.61 nonaka int ridx, rate_flags, i, ind;
4525 1.28 nonaka int nrates = ni->ni_rates.rs_nrates;
4526 1.1 pooka
4527 1.1 pooka tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT;
4528 1.1 pooka tx->data_retry_limit = IWM_DEFAULT_TX_RETRY;
4529 1.1 pooka
4530 1.45 nonaka if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
4531 1.45 nonaka type != IEEE80211_FC0_TYPE_DATA) {
4532 1.28 nonaka /* for non-data, use the lowest supported rate */
4533 1.45 nonaka ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ?
4534 1.28 nonaka IWM_RIDX_OFDM : IWM_RIDX_CCK;
4535 1.45 nonaka tx->data_retry_limit = IWM_MGMT_DFAULT_RETRY_LIMIT;
4536 1.45 nonaka #ifndef IEEE80211_NO_HT
4537 1.45 nonaka } else if (ic->ic_fixed_mcs != -1) {
4538 1.45 nonaka ridx = sc->sc_fixed_ridx;
4539 1.45 nonaka #endif
4540 1.28 nonaka } else if (ic->ic_fixed_rate != -1) {
4541 1.28 nonaka ridx = sc->sc_fixed_ridx;
4542 1.28 nonaka } else {
4543 1.28 nonaka /* for data frames, use RS table */
4544 1.45 nonaka tx->initial_rate_index = 0;
4545 1.8 nonaka tx->tx_flags |= htole32(IWM_TX_CMD_FLG_STA_RATE);
4546 1.45 nonaka DPRINTFN(12, ("start with txrate %d\n",
4547 1.45 nonaka tx->initial_rate_index));
4548 1.45 nonaka #ifndef IEEE80211_NO_HT
4549 1.45 nonaka if (ni->ni_flags & IEEE80211_NODE_HT) {
4550 1.45 nonaka ridx = iwm_mcs2ridx[ni->ni_txmcs];
4551 1.45 nonaka return &iwm_rates[ridx];
4552 1.45 nonaka }
4553 1.45 nonaka #endif
4554 1.45 nonaka ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ?
4555 1.45 nonaka IWM_RIDX_OFDM : IWM_RIDX_CCK;
4556 1.45 nonaka for (i = 0; i < nrates; i++) {
4557 1.45 nonaka if (iwm_rates[i].rate == (ni->ni_txrate &
4558 1.45 nonaka IEEE80211_RATE_VAL)) {
4559 1.45 nonaka ridx = i;
4560 1.45 nonaka break;
4561 1.45 nonaka }
4562 1.45 nonaka }
4563 1.28 nonaka return &iwm_rates[ridx];
4564 1.1 pooka }
4565 1.1 pooka
4566 1.1 pooka rinfo = &iwm_rates[ridx];
4567 1.61 nonaka for (i = 0, ind = sc->sc_mgmt_last_antenna;
4568 1.61 nonaka i < IWM_RATE_MCS_ANT_NUM; i++) {
4569 1.61 nonaka ind = (ind + 1) % IWM_RATE_MCS_ANT_NUM;
4570 1.61 nonaka if (iwm_fw_valid_tx_ant(sc) & (1 << ind)) {
4571 1.61 nonaka sc->sc_mgmt_last_antenna = ind;
4572 1.61 nonaka break;
4573 1.61 nonaka }
4574 1.61 nonaka }
4575 1.61 nonaka rate_flags = (1 << sc->sc_mgmt_last_antenna) << IWM_RATE_MCS_ANT_POS;
4576 1.1 pooka if (IWM_RIDX_IS_CCK(ridx))
4577 1.1 pooka rate_flags |= IWM_RATE_MCS_CCK_MSK;
4578 1.45 nonaka #ifndef IEEE80211_NO_HT
4579 1.45 nonaka if ((ni->ni_flags & IEEE80211_NODE_HT) &&
4580 1.45 nonaka rinfo->ht_plcp != IWM_RATE_HT_SISO_MCS_INV_PLCP) {
4581 1.45 nonaka rate_flags |= IWM_RATE_MCS_HT_MSK;
4582 1.45 nonaka tx->rate_n_flags = htole32(rate_flags | rinfo->ht_plcp);
4583 1.45 nonaka } else
4584 1.45 nonaka #endif
4585 1.45 nonaka tx->rate_n_flags = htole32(rate_flags | rinfo->plcp);
4586 1.1 pooka
4587 1.1 pooka return rinfo;
4588 1.1 pooka }
4589 1.1 pooka
4590 1.1 pooka #define TB0_SIZE 16
4591 1.4 nonaka static int
4592 1.1 pooka iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
4593 1.1 pooka {
4594 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
4595 1.45 nonaka struct iwm_node *in = (struct iwm_node *)ni;
4596 1.1 pooka struct iwm_tx_ring *ring;
4597 1.1 pooka struct iwm_tx_data *data;
4598 1.1 pooka struct iwm_tfd *desc;
4599 1.1 pooka struct iwm_device_cmd *cmd;
4600 1.1 pooka struct iwm_tx_cmd *tx;
4601 1.1 pooka struct ieee80211_frame *wh;
4602 1.1 pooka struct ieee80211_key *k = NULL;
4603 1.1 pooka struct mbuf *m1;
4604 1.1 pooka const struct iwm_rate *rinfo;
4605 1.1 pooka uint32_t flags;
4606 1.1 pooka u_int hdrlen;
4607 1.1 pooka bus_dma_segment_t *seg;
4608 1.1 pooka uint8_t tid, type;
4609 1.45 nonaka int i, totlen, err, pad;
4610 1.1 pooka
4611 1.1 pooka wh = mtod(m, struct ieee80211_frame *);
4612 1.1 pooka hdrlen = ieee80211_anyhdrsize(wh);
4613 1.1 pooka type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
4614 1.1 pooka
4615 1.1 pooka tid = 0;
4616 1.1 pooka
4617 1.1 pooka ring = &sc->txq[ac];
4618 1.1 pooka desc = &ring->desc[ring->cur];
4619 1.1 pooka memset(desc, 0, sizeof(*desc));
4620 1.1 pooka data = &ring->data[ring->cur];
4621 1.1 pooka
4622 1.1 pooka cmd = &ring->cmd[ring->cur];
4623 1.1 pooka cmd->hdr.code = IWM_TX_CMD;
4624 1.1 pooka cmd->hdr.flags = 0;
4625 1.1 pooka cmd->hdr.qid = ring->qid;
4626 1.1 pooka cmd->hdr.idx = ring->cur;
4627 1.1 pooka
4628 1.1 pooka tx = (void *)cmd->data;
4629 1.1 pooka memset(tx, 0, sizeof(*tx));
4630 1.1 pooka
4631 1.1 pooka rinfo = iwm_tx_fill_cmd(sc, in, wh, tx);
4632 1.1 pooka
4633 1.48 nonaka if (__predict_false(sc->sc_drvbpf != NULL)) {
4634 1.1 pooka struct iwm_tx_radiotap_header *tap = &sc->sc_txtap;
4635 1.1 pooka
4636 1.1 pooka tap->wt_flags = 0;
4637 1.1 pooka tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
4638 1.1 pooka tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
4639 1.45 nonaka #ifndef IEEE80211_NO_HT
4640 1.45 nonaka if ((ni->ni_flags & IEEE80211_NODE_HT) &&
4641 1.45 nonaka !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
4642 1.45 nonaka type == IEEE80211_FC0_TYPE_DATA &&
4643 1.45 nonaka rinfo->plcp == IWM_RATE_INVM_PLCP) {
4644 1.45 nonaka tap->wt_rate = (0x80 | rinfo->ht_plcp);
4645 1.45 nonaka } else
4646 1.45 nonaka #endif
4647 1.45 nonaka tap->wt_rate = rinfo->rate;
4648 1.1 pooka tap->wt_hwqueue = ac;
4649 1.1 pooka if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4650 1.1 pooka tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
4651 1.1 pooka
4652 1.83 msaitoh bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m, BPF_D_OUT);
4653 1.1 pooka }
4654 1.1 pooka
4655 1.1 pooka /* Encrypt the frame if need be. */
4656 1.1 pooka if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
4657 1.1 pooka k = ieee80211_crypto_encap(ic, ni, m);
4658 1.1 pooka if (k == NULL) {
4659 1.1 pooka m_freem(m);
4660 1.1 pooka return ENOBUFS;
4661 1.1 pooka }
4662 1.1 pooka /* Packet header may have moved, reset our local pointer. */
4663 1.1 pooka wh = mtod(m, struct ieee80211_frame *);
4664 1.1 pooka }
4665 1.1 pooka totlen = m->m_pkthdr.len;
4666 1.1 pooka
4667 1.1 pooka flags = 0;
4668 1.1 pooka if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
4669 1.1 pooka flags |= IWM_TX_CMD_FLG_ACK;
4670 1.1 pooka }
4671 1.1 pooka
4672 1.45 nonaka if (type == IEEE80211_FC0_TYPE_DATA &&
4673 1.45 nonaka !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
4674 1.45 nonaka (totlen + IEEE80211_CRC_LEN > ic->ic_rtsthreshold ||
4675 1.45 nonaka (ic->ic_flags & IEEE80211_F_USEPROT)))
4676 1.1 pooka flags |= IWM_TX_CMD_FLG_PROT_REQUIRE;
4677 1.1 pooka
4678 1.1 pooka if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
4679 1.1 pooka type != IEEE80211_FC0_TYPE_DATA)
4680 1.45 nonaka tx->sta_id = IWM_AUX_STA_ID;
4681 1.1 pooka else
4682 1.1 pooka tx->sta_id = IWM_STATION_ID;
4683 1.1 pooka
4684 1.1 pooka if (type == IEEE80211_FC0_TYPE_MGT) {
4685 1.1 pooka uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
4686 1.1 pooka
4687 1.1 pooka if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
4688 1.1 pooka subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
4689 1.54 nonaka tx->pm_frame_timeout = htole16(IWM_PM_FRAME_ASSOC);
4690 1.1 pooka else
4691 1.54 nonaka tx->pm_frame_timeout = htole16(IWM_PM_FRAME_MGMT);
4692 1.1 pooka } else {
4693 1.54 nonaka tx->pm_frame_timeout = htole16(IWM_PM_FRAME_NONE);
4694 1.1 pooka }
4695 1.1 pooka
4696 1.8 nonaka if (hdrlen & 3) {
4697 1.8 nonaka /* First segment length must be a multiple of 4. */
4698 1.8 nonaka flags |= IWM_TX_CMD_FLG_MH_PAD;
4699 1.8 nonaka pad = 4 - (hdrlen & 3);
4700 1.8 nonaka } else
4701 1.8 nonaka pad = 0;
4702 1.1 pooka
4703 1.1 pooka tx->driver_txop = 0;
4704 1.1 pooka tx->next_frame_len = 0;
4705 1.1 pooka
4706 1.1 pooka tx->len = htole16(totlen);
4707 1.1 pooka tx->tid_tspec = tid;
4708 1.1 pooka tx->life_time = htole32(IWM_TX_CMD_LIFE_TIME_INFINITE);
4709 1.1 pooka
4710 1.1 pooka /* Set physical address of "scratch area". */
4711 1.1 pooka tx->dram_lsb_ptr = htole32(data->scratch_paddr);
4712 1.1 pooka tx->dram_msb_ptr = iwm_get_dma_hi_addr(data->scratch_paddr);
4713 1.1 pooka
4714 1.1 pooka /* Copy 802.11 header in TX command. */
4715 1.61 nonaka memcpy(tx + 1, wh, hdrlen);
4716 1.1 pooka
4717 1.1 pooka flags |= IWM_TX_CMD_FLG_BT_DIS | IWM_TX_CMD_FLG_SEQ_CTL;
4718 1.1 pooka
4719 1.1 pooka tx->sec_ctl = 0;
4720 1.1 pooka tx->tx_flags |= htole32(flags);
4721 1.1 pooka
4722 1.1 pooka /* Trim 802.11 header. */
4723 1.1 pooka m_adj(m, hdrlen);
4724 1.1 pooka
4725 1.45 nonaka err = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
4726 1.1 pooka BUS_DMA_NOWAIT | BUS_DMA_WRITE);
4727 1.45 nonaka if (err) {
4728 1.45 nonaka if (err != EFBIG) {
4729 1.3 nonaka aprint_error_dev(sc->sc_dev,
4730 1.45 nonaka "can't map mbuf (error %d)\n", err);
4731 1.1 pooka m_freem(m);
4732 1.45 nonaka return err;
4733 1.1 pooka }
4734 1.1 pooka /* Too many DMA segments, linearize mbuf. */
4735 1.1 pooka MGETHDR(m1, M_DONTWAIT, MT_DATA);
4736 1.1 pooka if (m1 == NULL) {
4737 1.1 pooka m_freem(m);
4738 1.1 pooka return ENOBUFS;
4739 1.1 pooka }
4740 1.1 pooka if (m->m_pkthdr.len > MHLEN) {
4741 1.1 pooka MCLGET(m1, M_DONTWAIT);
4742 1.1 pooka if (!(m1->m_flags & M_EXT)) {
4743 1.1 pooka m_freem(m);
4744 1.1 pooka m_freem(m1);
4745 1.1 pooka return ENOBUFS;
4746 1.1 pooka }
4747 1.1 pooka }
4748 1.1 pooka m_copydata(m, 0, m->m_pkthdr.len, mtod(m1, void *));
4749 1.1 pooka m1->m_pkthdr.len = m1->m_len = m->m_pkthdr.len;
4750 1.1 pooka m_freem(m);
4751 1.1 pooka m = m1;
4752 1.1 pooka
4753 1.45 nonaka err = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
4754 1.1 pooka BUS_DMA_NOWAIT | BUS_DMA_WRITE);
4755 1.45 nonaka if (err) {
4756 1.3 nonaka aprint_error_dev(sc->sc_dev,
4757 1.45 nonaka "can't map mbuf (error %d)\n", err);
4758 1.1 pooka m_freem(m);
4759 1.45 nonaka return err;
4760 1.1 pooka }
4761 1.1 pooka }
4762 1.1 pooka data->m = m;
4763 1.1 pooka data->in = in;
4764 1.1 pooka data->done = 0;
4765 1.1 pooka
4766 1.1 pooka DPRINTFN(8, ("sending txd %p, in %p\n", data, data->in));
4767 1.1 pooka KASSERT(data->in != NULL);
4768 1.1 pooka
4769 1.61 nonaka DPRINTFN(8, ("sending data: qid=%d idx=%d len=%d nsegs=%d type=%d "
4770 1.61 nonaka "subtype=%x tx_flags=%08x init_rateidx=%08x rate_n_flags=%08x\n",
4771 1.61 nonaka ring->qid, ring->cur, totlen, data->map->dm_nsegs, type,
4772 1.61 nonaka (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >> 4,
4773 1.61 nonaka le32toh(tx->tx_flags), le32toh(tx->initial_rate_index),
4774 1.61 nonaka le32toh(tx->rate_n_flags)));
4775 1.1 pooka
4776 1.1 pooka /* Fill TX descriptor. */
4777 1.1 pooka desc->num_tbs = 2 + data->map->dm_nsegs;
4778 1.1 pooka
4779 1.1 pooka desc->tbs[0].lo = htole32(data->cmd_paddr);
4780 1.1 pooka desc->tbs[0].hi_n_len = htole16(iwm_get_dma_hi_addr(data->cmd_paddr)) |
4781 1.1 pooka (TB0_SIZE << 4);
4782 1.1 pooka desc->tbs[1].lo = htole32(data->cmd_paddr + TB0_SIZE);
4783 1.1 pooka desc->tbs[1].hi_n_len = htole16(iwm_get_dma_hi_addr(data->cmd_paddr)) |
4784 1.1 pooka ((sizeof(struct iwm_cmd_header) + sizeof(*tx)
4785 1.1 pooka + hdrlen + pad - TB0_SIZE) << 4);
4786 1.1 pooka
4787 1.1 pooka /* Other DMA segments are for data payload. */
4788 1.1 pooka seg = data->map->dm_segs;
4789 1.1 pooka for (i = 0; i < data->map->dm_nsegs; i++, seg++) {
4790 1.1 pooka desc->tbs[i+2].lo = htole32(seg->ds_addr);
4791 1.47 nonaka desc->tbs[i+2].hi_n_len =
4792 1.1 pooka htole16(iwm_get_dma_hi_addr(seg->ds_addr))
4793 1.1 pooka | ((seg->ds_len) << 4);
4794 1.1 pooka }
4795 1.1 pooka
4796 1.89 mlelstv bus_dmamap_sync(sc->sc_dmat, data->map, 0, m->m_pkthdr.len,
4797 1.1 pooka BUS_DMASYNC_PREWRITE);
4798 1.1 pooka bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
4799 1.61 nonaka (uint8_t *)cmd - (uint8_t *)ring->cmd, sizeof(*cmd),
4800 1.61 nonaka BUS_DMASYNC_PREWRITE);
4801 1.1 pooka bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
4802 1.61 nonaka (uint8_t *)desc - (uint8_t *)ring->desc, sizeof(*desc),
4803 1.61 nonaka BUS_DMASYNC_PREWRITE);
4804 1.1 pooka
4805 1.1 pooka #if 0
4806 1.45 nonaka iwm_update_sched(sc, ring->qid, ring->cur, tx->sta_id,
4807 1.45 nonaka le16toh(tx->len));
4808 1.1 pooka #endif
4809 1.1 pooka
4810 1.1 pooka /* Kick TX ring. */
4811 1.1 pooka ring->cur = (ring->cur + 1) % IWM_TX_RING_COUNT;
4812 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
4813 1.1 pooka
4814 1.1 pooka /* Mark TX ring as full if we reach a certain threshold. */
4815 1.1 pooka if (++ring->queued > IWM_TX_RING_HIMARK) {
4816 1.1 pooka sc->qfullmsk |= 1 << ring->qid;
4817 1.1 pooka }
4818 1.1 pooka
4819 1.1 pooka return 0;
4820 1.1 pooka }
4821 1.1 pooka
4822 1.1 pooka #if 0
4823 1.1 pooka /* not necessary? */
4824 1.4 nonaka static int
4825 1.45 nonaka iwm_flush_tx_path(struct iwm_softc *sc, int tfd_msk, int sync)
4826 1.1 pooka {
4827 1.1 pooka struct iwm_tx_path_flush_cmd flush_cmd = {
4828 1.1 pooka .queues_ctl = htole32(tfd_msk),
4829 1.1 pooka .flush_ctl = htole16(IWM_DUMP_TX_FIFO_FLUSH),
4830 1.1 pooka };
4831 1.45 nonaka int err;
4832 1.1 pooka
4833 1.45 nonaka err = iwm_send_cmd_pdu(sc, IWM_TXPATH_FLUSH, sync ? 0 : IWM_CMD_ASYNC,
4834 1.1 pooka sizeof(flush_cmd), &flush_cmd);
4835 1.45 nonaka if (err)
4836 1.3 nonaka aprint_error_dev(sc->sc_dev, "Flushing tx queue failed: %d\n",
4837 1.45 nonaka err);
4838 1.45 nonaka return err;
4839 1.1 pooka }
4840 1.1 pooka #endif
4841 1.1 pooka
4842 1.45 nonaka static void
4843 1.45 nonaka iwm_led_enable(struct iwm_softc *sc)
4844 1.45 nonaka {
4845 1.45 nonaka IWM_WRITE(sc, IWM_CSR_LED_REG, IWM_CSR_LED_REG_TURN_ON);
4846 1.45 nonaka }
4847 1.45 nonaka
4848 1.45 nonaka static void
4849 1.45 nonaka iwm_led_disable(struct iwm_softc *sc)
4850 1.45 nonaka {
4851 1.45 nonaka IWM_WRITE(sc, IWM_CSR_LED_REG, IWM_CSR_LED_REG_TURN_OFF);
4852 1.45 nonaka }
4853 1.45 nonaka
4854 1.45 nonaka static int
4855 1.45 nonaka iwm_led_is_enabled(struct iwm_softc *sc)
4856 1.45 nonaka {
4857 1.45 nonaka return (IWM_READ(sc, IWM_CSR_LED_REG) == IWM_CSR_LED_REG_TURN_ON);
4858 1.45 nonaka }
4859 1.45 nonaka
4860 1.45 nonaka static void
4861 1.45 nonaka iwm_led_blink_timeout(void *arg)
4862 1.45 nonaka {
4863 1.45 nonaka struct iwm_softc *sc = arg;
4864 1.45 nonaka
4865 1.45 nonaka if (iwm_led_is_enabled(sc))
4866 1.45 nonaka iwm_led_disable(sc);
4867 1.45 nonaka else
4868 1.45 nonaka iwm_led_enable(sc);
4869 1.45 nonaka
4870 1.45 nonaka callout_schedule(&sc->sc_led_blink_to, mstohz(200));
4871 1.45 nonaka }
4872 1.45 nonaka
4873 1.45 nonaka static void
4874 1.45 nonaka iwm_led_blink_start(struct iwm_softc *sc)
4875 1.45 nonaka {
4876 1.45 nonaka callout_schedule(&sc->sc_led_blink_to, mstohz(200));
4877 1.45 nonaka }
4878 1.1 pooka
4879 1.45 nonaka static void
4880 1.45 nonaka iwm_led_blink_stop(struct iwm_softc *sc)
4881 1.45 nonaka {
4882 1.45 nonaka callout_stop(&sc->sc_led_blink_to);
4883 1.45 nonaka iwm_led_disable(sc);
4884 1.45 nonaka }
4885 1.1 pooka
4886 1.1 pooka #define IWM_POWER_KEEP_ALIVE_PERIOD_SEC 25
4887 1.1 pooka
4888 1.4 nonaka static int
4889 1.45 nonaka iwm_beacon_filter_send_cmd(struct iwm_softc *sc,
4890 1.51 nonaka struct iwm_beacon_filter_cmd *cmd)
4891 1.1 pooka {
4892 1.45 nonaka return iwm_send_cmd_pdu(sc, IWM_REPLY_BEACON_FILTERING_CMD,
4893 1.45 nonaka 0, sizeof(struct iwm_beacon_filter_cmd), cmd);
4894 1.1 pooka }
4895 1.1 pooka
4896 1.4 nonaka static void
4897 1.45 nonaka iwm_beacon_filter_set_cqm_params(struct iwm_softc *sc, struct iwm_node *in,
4898 1.45 nonaka struct iwm_beacon_filter_cmd *cmd)
4899 1.1 pooka {
4900 1.1 pooka cmd->ba_enable_beacon_abort = htole32(sc->sc_bf.ba_enabled);
4901 1.1 pooka }
4902 1.1 pooka
4903 1.4 nonaka static int
4904 1.45 nonaka iwm_update_beacon_abort(struct iwm_softc *sc, struct iwm_node *in, int enable)
4905 1.1 pooka {
4906 1.1 pooka struct iwm_beacon_filter_cmd cmd = {
4907 1.1 pooka IWM_BF_CMD_CONFIG_DEFAULTS,
4908 1.1 pooka .bf_enable_beacon_filter = htole32(1),
4909 1.1 pooka .ba_enable_beacon_abort = htole32(enable),
4910 1.1 pooka };
4911 1.1 pooka
4912 1.1 pooka if (!sc->sc_bf.bf_enabled)
4913 1.1 pooka return 0;
4914 1.1 pooka
4915 1.1 pooka sc->sc_bf.ba_enabled = enable;
4916 1.45 nonaka iwm_beacon_filter_set_cqm_params(sc, in, &cmd);
4917 1.45 nonaka return iwm_beacon_filter_send_cmd(sc, &cmd);
4918 1.1 pooka }
4919 1.1 pooka
4920 1.4 nonaka static void
4921 1.45 nonaka iwm_power_build_cmd(struct iwm_softc *sc, struct iwm_node *in,
4922 1.45 nonaka struct iwm_mac_power_cmd *cmd)
4923 1.1 pooka {
4924 1.1 pooka struct ieee80211_node *ni = &in->in_ni;
4925 1.45 nonaka int dtim_period, dtim_msec, keep_alive;
4926 1.1 pooka
4927 1.1 pooka cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id,
4928 1.1 pooka in->in_color));
4929 1.45 nonaka if (ni->ni_dtim_period)
4930 1.45 nonaka dtim_period = ni->ni_dtim_period;
4931 1.45 nonaka else
4932 1.45 nonaka dtim_period = 1;
4933 1.1 pooka
4934 1.1 pooka /*
4935 1.1 pooka * Regardless of power management state the driver must set
4936 1.1 pooka * keep alive period. FW will use it for sending keep alive NDPs
4937 1.1 pooka * immediately after association. Check that keep alive period
4938 1.45 nonaka * is at least 3 * DTIM.
4939 1.1 pooka */
4940 1.45 nonaka dtim_msec = dtim_period * ni->ni_intval;
4941 1.45 nonaka keep_alive = MAX(3 * dtim_msec, 1000 * IWM_POWER_KEEP_ALIVE_PERIOD_SEC);
4942 1.1 pooka keep_alive = roundup(keep_alive, 1000) / 1000;
4943 1.1 pooka cmd->keep_alive_seconds = htole16(keep_alive);
4944 1.45 nonaka
4945 1.45 nonaka #ifdef notyet
4946 1.45 nonaka cmd->flags = htole16(IWM_POWER_FLAGS_POWER_SAVE_ENA_MSK);
4947 1.45 nonaka cmd->rx_data_timeout = IWM_DEFAULT_PS_RX_DATA_TIMEOUT;
4948 1.45 nonaka cmd->tx_data_timeout = IWM_DEFAULT_PS_TX_DATA_TIMEOUT;
4949 1.45 nonaka #endif
4950 1.1 pooka }
4951 1.1 pooka
4952 1.4 nonaka static int
4953 1.45 nonaka iwm_power_mac_update_mode(struct iwm_softc *sc, struct iwm_node *in)
4954 1.1 pooka {
4955 1.45 nonaka int err;
4956 1.1 pooka int ba_enable;
4957 1.1 pooka struct iwm_mac_power_cmd cmd;
4958 1.1 pooka
4959 1.1 pooka memset(&cmd, 0, sizeof(cmd));
4960 1.1 pooka
4961 1.45 nonaka iwm_power_build_cmd(sc, in, &cmd);
4962 1.1 pooka
4963 1.45 nonaka err = iwm_send_cmd_pdu(sc, IWM_MAC_PM_POWER_TABLE, 0,
4964 1.45 nonaka sizeof(cmd), &cmd);
4965 1.45 nonaka if (err)
4966 1.45 nonaka return err;
4967 1.1 pooka
4968 1.1 pooka ba_enable = !!(cmd.flags &
4969 1.1 pooka htole16(IWM_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
4970 1.45 nonaka return iwm_update_beacon_abort(sc, in, ba_enable);
4971 1.1 pooka }
4972 1.1 pooka
4973 1.4 nonaka static int
4974 1.45 nonaka iwm_power_update_device(struct iwm_softc *sc)
4975 1.1 pooka {
4976 1.1 pooka struct iwm_device_power_cmd cmd = {
4977 1.45 nonaka #ifdef notyet
4978 1.1 pooka .flags = htole16(IWM_DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
4979 1.55 khorben #else
4980 1.55 khorben .flags = 0,
4981 1.45 nonaka #endif
4982 1.1 pooka };
4983 1.1 pooka
4984 1.1 pooka if (!(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
4985 1.1 pooka return 0;
4986 1.1 pooka
4987 1.1 pooka cmd.flags |= htole16(IWM_DEVICE_POWER_FLAGS_CAM_MSK);
4988 1.45 nonaka DPRINTF(("Sending device power command with flags = 0x%X\n",
4989 1.45 nonaka cmd.flags));
4990 1.1 pooka
4991 1.45 nonaka return iwm_send_cmd_pdu(sc, IWM_POWER_TABLE_CMD, 0, sizeof(cmd), &cmd);
4992 1.1 pooka }
4993 1.1 pooka
4994 1.45 nonaka #ifdef notyet
4995 1.4 nonaka static int
4996 1.45 nonaka iwm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_node *in)
4997 1.1 pooka {
4998 1.1 pooka struct iwm_beacon_filter_cmd cmd = {
4999 1.1 pooka IWM_BF_CMD_CONFIG_DEFAULTS,
5000 1.1 pooka .bf_enable_beacon_filter = htole32(1),
5001 1.1 pooka };
5002 1.45 nonaka int err;
5003 1.1 pooka
5004 1.45 nonaka iwm_beacon_filter_set_cqm_params(sc, in, &cmd);
5005 1.45 nonaka err = iwm_beacon_filter_send_cmd(sc, &cmd);
5006 1.1 pooka
5007 1.45 nonaka if (err == 0)
5008 1.1 pooka sc->sc_bf.bf_enabled = 1;
5009 1.1 pooka
5010 1.45 nonaka return err;
5011 1.1 pooka }
5012 1.45 nonaka #endif
5013 1.1 pooka
5014 1.4 nonaka static int
5015 1.45 nonaka iwm_disable_beacon_filter(struct iwm_softc *sc)
5016 1.1 pooka {
5017 1.1 pooka struct iwm_beacon_filter_cmd cmd;
5018 1.45 nonaka int err;
5019 1.1 pooka
5020 1.1 pooka memset(&cmd, 0, sizeof(cmd));
5021 1.1 pooka if ((sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_BF_UPDATED) == 0)
5022 1.1 pooka return 0;
5023 1.1 pooka
5024 1.45 nonaka err = iwm_beacon_filter_send_cmd(sc, &cmd);
5025 1.45 nonaka if (err == 0)
5026 1.1 pooka sc->sc_bf.bf_enabled = 0;
5027 1.1 pooka
5028 1.45 nonaka return err;
5029 1.1 pooka }
5030 1.1 pooka
5031 1.4 nonaka static int
5032 1.45 nonaka iwm_add_sta_cmd(struct iwm_softc *sc, struct iwm_node *in, int update)
5033 1.1 pooka {
5034 1.45 nonaka struct iwm_add_sta_cmd_v7 add_sta_cmd;
5035 1.45 nonaka int err;
5036 1.45 nonaka uint32_t status;
5037 1.1 pooka
5038 1.45 nonaka memset(&add_sta_cmd, 0, sizeof(add_sta_cmd));
5039 1.1 pooka
5040 1.45 nonaka add_sta_cmd.sta_id = IWM_STATION_ID;
5041 1.45 nonaka add_sta_cmd.mac_id_n_color
5042 1.45 nonaka = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
5043 1.45 nonaka if (!update) {
5044 1.45 nonaka int ac;
5045 1.45 nonaka for (ac = 0; ac < WME_NUM_AC; ac++) {
5046 1.45 nonaka add_sta_cmd.tfd_queue_msk |=
5047 1.45 nonaka htole32(__BIT(iwm_ac_to_tx_fifo[ac]));
5048 1.45 nonaka }
5049 1.45 nonaka IEEE80211_ADDR_COPY(&add_sta_cmd.addr, in->in_ni.ni_bssid);
5050 1.45 nonaka }
5051 1.1 pooka add_sta_cmd.add_modify = update ? 1 : 0;
5052 1.1 pooka add_sta_cmd.station_flags_msk
5053 1.1 pooka |= htole32(IWM_STA_FLG_FAT_EN_MSK | IWM_STA_FLG_MIMO_EN_MSK);
5054 1.45 nonaka add_sta_cmd.tid_disable_tx = htole16(0xffff);
5055 1.45 nonaka if (update)
5056 1.45 nonaka add_sta_cmd.modify_mask |= (IWM_STA_MODIFY_TID_DISABLE_TX);
5057 1.45 nonaka
5058 1.45 nonaka #ifndef IEEE80211_NO_HT
5059 1.45 nonaka if (in->in_ni.ni_flags & IEEE80211_NODE_HT) {
5060 1.45 nonaka add_sta_cmd.station_flags_msk
5061 1.45 nonaka |= htole32(IWM_STA_FLG_MAX_AGG_SIZE_MSK |
5062 1.45 nonaka IWM_STA_FLG_AGG_MPDU_DENS_MSK);
5063 1.45 nonaka
5064 1.45 nonaka add_sta_cmd.station_flags
5065 1.45 nonaka |= htole32(IWM_STA_FLG_MAX_AGG_SIZE_64K);
5066 1.45 nonaka switch (ic->ic_ampdu_params & IEEE80211_AMPDU_PARAM_SS) {
5067 1.45 nonaka case IEEE80211_AMPDU_PARAM_SS_2:
5068 1.45 nonaka add_sta_cmd.station_flags
5069 1.45 nonaka |= htole32(IWM_STA_FLG_AGG_MPDU_DENS_2US);
5070 1.45 nonaka break;
5071 1.45 nonaka case IEEE80211_AMPDU_PARAM_SS_4:
5072 1.45 nonaka add_sta_cmd.station_flags
5073 1.45 nonaka |= htole32(IWM_STA_FLG_AGG_MPDU_DENS_4US);
5074 1.45 nonaka break;
5075 1.45 nonaka case IEEE80211_AMPDU_PARAM_SS_8:
5076 1.45 nonaka add_sta_cmd.station_flags
5077 1.45 nonaka |= htole32(IWM_STA_FLG_AGG_MPDU_DENS_8US);
5078 1.45 nonaka break;
5079 1.45 nonaka case IEEE80211_AMPDU_PARAM_SS_16:
5080 1.45 nonaka add_sta_cmd.station_flags
5081 1.45 nonaka |= htole32(IWM_STA_FLG_AGG_MPDU_DENS_16US);
5082 1.45 nonaka break;
5083 1.45 nonaka default:
5084 1.45 nonaka break;
5085 1.45 nonaka }
5086 1.45 nonaka }
5087 1.45 nonaka #endif
5088 1.1 pooka
5089 1.1 pooka status = IWM_ADD_STA_SUCCESS;
5090 1.45 nonaka err = iwm_send_cmd_pdu_status(sc, IWM_ADD_STA, sizeof(add_sta_cmd),
5091 1.45 nonaka &add_sta_cmd, &status);
5092 1.45 nonaka if (err == 0 && status != IWM_ADD_STA_SUCCESS)
5093 1.45 nonaka err = EIO;
5094 1.1 pooka
5095 1.45 nonaka return err;
5096 1.1 pooka }
5097 1.1 pooka
5098 1.4 nonaka static int
5099 1.45 nonaka iwm_add_aux_sta(struct iwm_softc *sc)
5100 1.1 pooka {
5101 1.45 nonaka struct iwm_add_sta_cmd_v7 cmd;
5102 1.45 nonaka int err;
5103 1.45 nonaka uint32_t status;
5104 1.1 pooka
5105 1.45 nonaka err = iwm_enable_txq(sc, 0, IWM_AUX_QUEUE, IWM_TX_FIFO_MCAST);
5106 1.45 nonaka if (err)
5107 1.45 nonaka return err;
5108 1.1 pooka
5109 1.1 pooka memset(&cmd, 0, sizeof(cmd));
5110 1.45 nonaka cmd.sta_id = IWM_AUX_STA_ID;
5111 1.45 nonaka cmd.mac_id_n_color =
5112 1.45 nonaka htole32(IWM_FW_CMD_ID_AND_COLOR(IWM_MAC_INDEX_AUX, 0));
5113 1.45 nonaka cmd.tfd_queue_msk = htole32(1 << IWM_AUX_QUEUE);
5114 1.45 nonaka cmd.tid_disable_tx = htole16(0xffff);
5115 1.1 pooka
5116 1.45 nonaka status = IWM_ADD_STA_SUCCESS;
5117 1.45 nonaka err = iwm_send_cmd_pdu_status(sc, IWM_ADD_STA, sizeof(cmd), &cmd,
5118 1.45 nonaka &status);
5119 1.45 nonaka if (err == 0 && status != IWM_ADD_STA_SUCCESS)
5120 1.45 nonaka err = EIO;
5121 1.1 pooka
5122 1.45 nonaka return err;
5123 1.1 pooka }
5124 1.1 pooka
5125 1.1 pooka #define IWM_PLCP_QUIET_THRESH 1
5126 1.1 pooka #define IWM_ACTIVE_QUIET_TIME 10
5127 1.1 pooka #define LONG_OUT_TIME_PERIOD 600
5128 1.1 pooka #define SHORT_OUT_TIME_PERIOD 200
5129 1.1 pooka #define SUSPEND_TIME_PERIOD 100
5130 1.1 pooka
5131 1.4 nonaka static uint16_t
5132 1.45 nonaka iwm_scan_rx_chain(struct iwm_softc *sc)
5133 1.1 pooka {
5134 1.1 pooka uint16_t rx_chain;
5135 1.1 pooka uint8_t rx_ant;
5136 1.1 pooka
5137 1.45 nonaka rx_ant = iwm_fw_valid_rx_ant(sc);
5138 1.1 pooka rx_chain = rx_ant << IWM_PHY_RX_CHAIN_VALID_POS;
5139 1.1 pooka rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
5140 1.1 pooka rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_SEL_POS;
5141 1.1 pooka rx_chain |= 0x1 << IWM_PHY_RX_CHAIN_DRIVER_FORCE_POS;
5142 1.1 pooka return htole16(rx_chain);
5143 1.1 pooka }
5144 1.1 pooka
5145 1.4 nonaka static uint32_t
5146 1.45 nonaka iwm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck)
5147 1.1 pooka {
5148 1.1 pooka uint32_t tx_ant;
5149 1.1 pooka int i, ind;
5150 1.1 pooka
5151 1.1 pooka for (i = 0, ind = sc->sc_scan_last_antenna;
5152 1.1 pooka i < IWM_RATE_MCS_ANT_NUM; i++) {
5153 1.1 pooka ind = (ind + 1) % IWM_RATE_MCS_ANT_NUM;
5154 1.45 nonaka if (iwm_fw_valid_tx_ant(sc) & (1 << ind)) {
5155 1.1 pooka sc->sc_scan_last_antenna = ind;
5156 1.1 pooka break;
5157 1.1 pooka }
5158 1.1 pooka }
5159 1.1 pooka tx_ant = (1 << sc->sc_scan_last_antenna) << IWM_RATE_MCS_ANT_POS;
5160 1.1 pooka
5161 1.1 pooka if ((flags & IEEE80211_CHAN_2GHZ) && !no_cck)
5162 1.1 pooka return htole32(IWM_RATE_1M_PLCP | IWM_RATE_MCS_CCK_MSK |
5163 1.1 pooka tx_ant);
5164 1.1 pooka else
5165 1.1 pooka return htole32(IWM_RATE_6M_PLCP | tx_ant);
5166 1.1 pooka }
5167 1.1 pooka
5168 1.45 nonaka #ifdef notyet
5169 1.1 pooka /*
5170 1.1 pooka * If req->n_ssids > 0, it means we should do an active scan.
5171 1.1 pooka * In case of active scan w/o directed scan, we receive a zero-length SSID
5172 1.1 pooka * just to notify that this scan is active and not passive.
5173 1.1 pooka * In order to notify the FW of the number of SSIDs we wish to scan (including
5174 1.1 pooka * the zero-length one), we need to set the corresponding bits in chan->type,
5175 1.1 pooka * one for each SSID, and set the active bit (first). If the first SSID is
5176 1.1 pooka * already included in the probe template, so we need to set only
5177 1.1 pooka * req->n_ssids - 1 bits in addition to the first bit.
5178 1.1 pooka */
5179 1.4 nonaka static uint16_t
5180 1.45 nonaka iwm_get_active_dwell(struct iwm_softc *sc, int flags, int n_ssids)
5181 1.1 pooka {
5182 1.1 pooka if (flags & IEEE80211_CHAN_2GHZ)
5183 1.1 pooka return 30 + 3 * (n_ssids + 1);
5184 1.1 pooka return 20 + 2 * (n_ssids + 1);
5185 1.1 pooka }
5186 1.1 pooka
5187 1.4 nonaka static uint16_t
5188 1.45 nonaka iwm_get_passive_dwell(struct iwm_softc *sc, int flags)
5189 1.1 pooka {
5190 1.1 pooka return (flags & IEEE80211_CHAN_2GHZ) ? 100 + 20 : 100 + 10;
5191 1.1 pooka }
5192 1.45 nonaka #endif
5193 1.1 pooka
5194 1.45 nonaka static uint8_t
5195 1.45 nonaka iwm_lmac_scan_fill_channels(struct iwm_softc *sc,
5196 1.45 nonaka struct iwm_scan_channel_cfg_lmac *chan, int n_ssids)
5197 1.1 pooka {
5198 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5199 1.1 pooka struct ieee80211_channel *c;
5200 1.45 nonaka uint8_t nchan;
5201 1.1 pooka
5202 1.45 nonaka for (nchan = 0, c = &ic->ic_channels[1];
5203 1.45 nonaka c <= &ic->ic_channels[IEEE80211_CHAN_MAX] &&
5204 1.45 nonaka nchan < sc->sc_capa_n_scan_channels;
5205 1.45 nonaka c++) {
5206 1.45 nonaka if (c->ic_flags == 0)
5207 1.45 nonaka continue;
5208 1.45 nonaka
5209 1.45 nonaka chan->channel_num = htole16(ieee80211_mhz2ieee(c->ic_freq, 0));
5210 1.45 nonaka chan->iter_count = htole16(1);
5211 1.61 nonaka chan->iter_interval = htole32(0);
5212 1.45 nonaka chan->flags = htole32(IWM_UNIFIED_SCAN_CHANNEL_PARTIAL);
5213 1.61 nonaka chan->flags |= htole32(IWM_SCAN_CHANNEL_NSSIDS(n_ssids));
5214 1.61 nonaka if (!IEEE80211_IS_CHAN_PASSIVE(c) && n_ssids != 0)
5215 1.61 nonaka chan->flags |= htole32(IWM_SCAN_CHANNEL_TYPE_ACTIVE);
5216 1.45 nonaka chan++;
5217 1.45 nonaka nchan++;
5218 1.45 nonaka }
5219 1.45 nonaka
5220 1.45 nonaka return nchan;
5221 1.45 nonaka }
5222 1.45 nonaka
5223 1.45 nonaka static uint8_t
5224 1.45 nonaka iwm_umac_scan_fill_channels(struct iwm_softc *sc,
5225 1.45 nonaka struct iwm_scan_channel_cfg_umac *chan, int n_ssids)
5226 1.45 nonaka {
5227 1.45 nonaka struct ieee80211com *ic = &sc->sc_ic;
5228 1.45 nonaka struct ieee80211_channel *c;
5229 1.45 nonaka uint8_t nchan;
5230 1.1 pooka
5231 1.1 pooka for (nchan = 0, c = &ic->ic_channels[1];
5232 1.45 nonaka c <= &ic->ic_channels[IEEE80211_CHAN_MAX] &&
5233 1.45 nonaka nchan < sc->sc_capa_n_scan_channels;
5234 1.1 pooka c++) {
5235 1.45 nonaka if (c->ic_flags == 0)
5236 1.1 pooka continue;
5237 1.61 nonaka
5238 1.45 nonaka chan->channel_num = ieee80211_mhz2ieee(c->ic_freq, 0);
5239 1.45 nonaka chan->iter_count = 1;
5240 1.45 nonaka chan->iter_interval = htole16(0);
5241 1.61 nonaka chan->flags = htole32(IWM_SCAN_CHANNEL_UMAC_NSSIDS(n_ssids));
5242 1.1 pooka chan++;
5243 1.1 pooka nchan++;
5244 1.1 pooka }
5245 1.45 nonaka
5246 1.1 pooka return nchan;
5247 1.1 pooka }
5248 1.1 pooka
5249 1.45 nonaka static int
5250 1.45 nonaka iwm_fill_probe_req(struct iwm_softc *sc, struct iwm_scan_probe_req *preq)
5251 1.45 nonaka {
5252 1.45 nonaka struct ieee80211com *ic = &sc->sc_ic;
5253 1.45 nonaka struct ieee80211_frame *wh = (struct ieee80211_frame *)preq->buf;
5254 1.45 nonaka struct ieee80211_rateset *rs;
5255 1.45 nonaka size_t remain = sizeof(preq->buf);
5256 1.45 nonaka uint8_t *frm, *pos;
5257 1.45 nonaka
5258 1.45 nonaka memset(preq, 0, sizeof(*preq));
5259 1.45 nonaka
5260 1.78 christos KASSERT(ic->ic_des_esslen < sizeof(ic->ic_des_essid));
5261 1.45 nonaka if (remain < sizeof(*wh) + 2 + ic->ic_des_esslen)
5262 1.45 nonaka return ENOBUFS;
5263 1.1 pooka
5264 1.45 nonaka /*
5265 1.45 nonaka * Build a probe request frame. Most of the following code is a
5266 1.45 nonaka * copy & paste of what is done in net80211.
5267 1.45 nonaka */
5268 1.45 nonaka wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
5269 1.1 pooka IEEE80211_FC0_SUBTYPE_PROBE_REQ;
5270 1.45 nonaka wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
5271 1.45 nonaka IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr);
5272 1.45 nonaka IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
5273 1.45 nonaka IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr);
5274 1.45 nonaka *(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */
5275 1.45 nonaka *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */
5276 1.45 nonaka
5277 1.45 nonaka frm = (uint8_t *)(wh + 1);
5278 1.45 nonaka frm = ieee80211_add_ssid(frm, ic->ic_des_essid, ic->ic_des_esslen);
5279 1.45 nonaka
5280 1.45 nonaka /* Tell the firmware where the MAC header is. */
5281 1.45 nonaka preq->mac_header.offset = 0;
5282 1.45 nonaka preq->mac_header.len = htole16(frm - (uint8_t *)wh);
5283 1.45 nonaka remain -= frm - (uint8_t *)wh;
5284 1.45 nonaka
5285 1.45 nonaka /* Fill in 2GHz IEs and tell firmware where they are. */
5286 1.45 nonaka rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
5287 1.45 nonaka if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
5288 1.45 nonaka if (remain < 4 + rs->rs_nrates)
5289 1.45 nonaka return ENOBUFS;
5290 1.45 nonaka } else if (remain < 2 + rs->rs_nrates)
5291 1.45 nonaka return ENOBUFS;
5292 1.45 nonaka preq->band_data[0].offset = htole16(frm - (uint8_t *)wh);
5293 1.45 nonaka pos = frm;
5294 1.45 nonaka frm = ieee80211_add_rates(frm, rs);
5295 1.45 nonaka if (rs->rs_nrates > IEEE80211_RATE_SIZE)
5296 1.45 nonaka frm = ieee80211_add_xrates(frm, rs);
5297 1.45 nonaka preq->band_data[0].len = htole16(frm - pos);
5298 1.45 nonaka remain -= frm - pos;
5299 1.45 nonaka
5300 1.45 nonaka if (isset(sc->sc_enabled_capa,
5301 1.45 nonaka IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT)) {
5302 1.45 nonaka if (remain < 3)
5303 1.45 nonaka return ENOBUFS;
5304 1.45 nonaka *frm++ = IEEE80211_ELEMID_DSPARMS;
5305 1.45 nonaka *frm++ = 1;
5306 1.45 nonaka *frm++ = 0;
5307 1.45 nonaka remain -= 3;
5308 1.45 nonaka }
5309 1.45 nonaka
5310 1.45 nonaka if (sc->sc_nvm.sku_cap_band_52GHz_enable) {
5311 1.45 nonaka /* Fill in 5GHz IEs. */
5312 1.45 nonaka rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
5313 1.45 nonaka if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
5314 1.45 nonaka if (remain < 4 + rs->rs_nrates)
5315 1.45 nonaka return ENOBUFS;
5316 1.45 nonaka } else if (remain < 2 + rs->rs_nrates)
5317 1.45 nonaka return ENOBUFS;
5318 1.45 nonaka preq->band_data[1].offset = htole16(frm - (uint8_t *)wh);
5319 1.45 nonaka pos = frm;
5320 1.45 nonaka frm = ieee80211_add_rates(frm, rs);
5321 1.45 nonaka if (rs->rs_nrates > IEEE80211_RATE_SIZE)
5322 1.45 nonaka frm = ieee80211_add_xrates(frm, rs);
5323 1.45 nonaka preq->band_data[1].len = htole16(frm - pos);
5324 1.45 nonaka remain -= frm - pos;
5325 1.45 nonaka }
5326 1.45 nonaka
5327 1.45 nonaka #ifndef IEEE80211_NO_HT
5328 1.45 nonaka /* Send 11n IEs on both 2GHz and 5GHz bands. */
5329 1.45 nonaka preq->common_data.offset = htole16(frm - (uint8_t *)wh);
5330 1.45 nonaka pos = frm;
5331 1.45 nonaka if (ic->ic_flags & IEEE80211_F_HTON) {
5332 1.45 nonaka if (remain < 28)
5333 1.45 nonaka return ENOBUFS;
5334 1.45 nonaka frm = ieee80211_add_htcaps(frm, ic);
5335 1.45 nonaka /* XXX add WME info? */
5336 1.45 nonaka }
5337 1.45 nonaka #endif
5338 1.45 nonaka
5339 1.45 nonaka preq->common_data.len = htole16(frm - pos);
5340 1.45 nonaka
5341 1.45 nonaka return 0;
5342 1.45 nonaka }
5343 1.45 nonaka
5344 1.45 nonaka static int
5345 1.45 nonaka iwm_lmac_scan(struct iwm_softc *sc)
5346 1.45 nonaka {
5347 1.45 nonaka struct ieee80211com *ic = &sc->sc_ic;
5348 1.45 nonaka struct iwm_host_cmd hcmd = {
5349 1.45 nonaka .id = IWM_SCAN_OFFLOAD_REQUEST_CMD,
5350 1.45 nonaka .len = { 0, },
5351 1.45 nonaka .data = { NULL, },
5352 1.45 nonaka .flags = 0,
5353 1.45 nonaka };
5354 1.45 nonaka struct iwm_scan_req_lmac *req;
5355 1.45 nonaka size_t req_len;
5356 1.45 nonaka int err;
5357 1.45 nonaka
5358 1.45 nonaka DPRINTF(("%s: %s\n", DEVNAME(sc), __func__));
5359 1.45 nonaka
5360 1.45 nonaka req_len = sizeof(struct iwm_scan_req_lmac) +
5361 1.45 nonaka (sizeof(struct iwm_scan_channel_cfg_lmac) *
5362 1.45 nonaka sc->sc_capa_n_scan_channels) + sizeof(struct iwm_scan_probe_req);
5363 1.45 nonaka if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
5364 1.45 nonaka return ENOMEM;
5365 1.45 nonaka req = kmem_zalloc(req_len, KM_SLEEP);
5366 1.45 nonaka hcmd.len[0] = (uint16_t)req_len;
5367 1.45 nonaka hcmd.data[0] = (void *)req;
5368 1.45 nonaka
5369 1.45 nonaka /* These timings correspond to iwlwifi's UNASSOC scan. */
5370 1.45 nonaka req->active_dwell = 10;
5371 1.45 nonaka req->passive_dwell = 110;
5372 1.45 nonaka req->fragmented_dwell = 44;
5373 1.45 nonaka req->extended_dwell = 90;
5374 1.45 nonaka req->max_out_time = 0;
5375 1.45 nonaka req->suspend_time = 0;
5376 1.45 nonaka
5377 1.45 nonaka req->scan_prio = htole32(IWM_SCAN_PRIORITY_HIGH);
5378 1.45 nonaka req->rx_chain_select = iwm_scan_rx_chain(sc);
5379 1.45 nonaka req->iter_num = htole32(1);
5380 1.45 nonaka req->delay = 0;
5381 1.45 nonaka
5382 1.45 nonaka req->scan_flags = htole32(IWM_LMAC_SCAN_FLAG_PASS_ALL |
5383 1.45 nonaka IWM_LMAC_SCAN_FLAG_ITER_COMPLETE |
5384 1.45 nonaka IWM_LMAC_SCAN_FLAG_EXTENDED_DWELL);
5385 1.45 nonaka if (ic->ic_des_esslen == 0)
5386 1.45 nonaka req->scan_flags |= htole32(IWM_LMAC_SCAN_FLAG_PASSIVE);
5387 1.45 nonaka else
5388 1.45 nonaka req->scan_flags |= htole32(IWM_LMAC_SCAN_FLAG_PRE_CONNECTION);
5389 1.45 nonaka if (isset(sc->sc_enabled_capa,
5390 1.45 nonaka IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT))
5391 1.45 nonaka req->scan_flags |= htole32(IWM_LMAC_SCAN_FLAGS_RRM_ENABLED);
5392 1.45 nonaka
5393 1.45 nonaka req->flags = htole32(IWM_PHY_BAND_24);
5394 1.45 nonaka if (sc->sc_nvm.sku_cap_band_52GHz_enable)
5395 1.45 nonaka req->flags |= htole32(IWM_PHY_BAND_5);
5396 1.45 nonaka req->filter_flags =
5397 1.45 nonaka htole32(IWM_MAC_FILTER_ACCEPT_GRP | IWM_MAC_FILTER_IN_BEACON);
5398 1.45 nonaka
5399 1.45 nonaka /* Tx flags 2 GHz. */
5400 1.45 nonaka req->tx_cmd[0].tx_flags = htole32(IWM_TX_CMD_FLG_SEQ_CTL |
5401 1.45 nonaka IWM_TX_CMD_FLG_BT_DIS);
5402 1.45 nonaka req->tx_cmd[0].rate_n_flags =
5403 1.45 nonaka iwm_scan_rate_n_flags(sc, IEEE80211_CHAN_2GHZ, 1/*XXX*/);
5404 1.45 nonaka req->tx_cmd[0].sta_id = IWM_AUX_STA_ID;
5405 1.45 nonaka
5406 1.45 nonaka /* Tx flags 5 GHz. */
5407 1.45 nonaka req->tx_cmd[1].tx_flags = htole32(IWM_TX_CMD_FLG_SEQ_CTL |
5408 1.45 nonaka IWM_TX_CMD_FLG_BT_DIS);
5409 1.45 nonaka req->tx_cmd[1].rate_n_flags =
5410 1.45 nonaka iwm_scan_rate_n_flags(sc, IEEE80211_CHAN_5GHZ, 1/*XXX*/);
5411 1.45 nonaka req->tx_cmd[1].sta_id = IWM_AUX_STA_ID;
5412 1.45 nonaka
5413 1.45 nonaka /* Check if we're doing an active directed scan. */
5414 1.45 nonaka if (ic->ic_des_esslen != 0) {
5415 1.45 nonaka req->direct_scan[0].id = IEEE80211_ELEMID_SSID;
5416 1.45 nonaka req->direct_scan[0].len = ic->ic_des_esslen;
5417 1.45 nonaka memcpy(req->direct_scan[0].ssid, ic->ic_des_essid,
5418 1.45 nonaka ic->ic_des_esslen);
5419 1.45 nonaka }
5420 1.45 nonaka
5421 1.45 nonaka req->n_channels = iwm_lmac_scan_fill_channels(sc,
5422 1.45 nonaka (struct iwm_scan_channel_cfg_lmac *)req->data,
5423 1.45 nonaka ic->ic_des_esslen != 0);
5424 1.45 nonaka
5425 1.45 nonaka err = iwm_fill_probe_req(sc,
5426 1.45 nonaka (struct iwm_scan_probe_req *)(req->data +
5427 1.45 nonaka (sizeof(struct iwm_scan_channel_cfg_lmac) *
5428 1.45 nonaka sc->sc_capa_n_scan_channels)));
5429 1.45 nonaka if (err) {
5430 1.45 nonaka kmem_free(req, req_len);
5431 1.45 nonaka return err;
5432 1.1 pooka }
5433 1.1 pooka
5434 1.45 nonaka /* Specify the scan plan: We'll do one iteration. */
5435 1.45 nonaka req->schedule[0].iterations = 1;
5436 1.45 nonaka req->schedule[0].full_scan_mul = 1;
5437 1.1 pooka
5438 1.45 nonaka /* Disable EBS. */
5439 1.45 nonaka req->channel_opt[0].non_ebs_ratio = 1;
5440 1.45 nonaka req->channel_opt[1].non_ebs_ratio = 1;
5441 1.1 pooka
5442 1.45 nonaka err = iwm_send_cmd(sc, &hcmd);
5443 1.45 nonaka kmem_free(req, req_len);
5444 1.45 nonaka return err;
5445 1.45 nonaka }
5446 1.45 nonaka
5447 1.45 nonaka static int
5448 1.45 nonaka iwm_config_umac_scan(struct iwm_softc *sc)
5449 1.45 nonaka {
5450 1.45 nonaka struct ieee80211com *ic = &sc->sc_ic;
5451 1.45 nonaka struct iwm_scan_config *scan_config;
5452 1.45 nonaka int err, nchan;
5453 1.45 nonaka size_t cmd_size;
5454 1.45 nonaka struct ieee80211_channel *c;
5455 1.45 nonaka struct iwm_host_cmd hcmd = {
5456 1.45 nonaka .id = iwm_cmd_id(IWM_SCAN_CFG_CMD, IWM_ALWAYS_LONG_GROUP, 0),
5457 1.45 nonaka .flags = 0,
5458 1.45 nonaka };
5459 1.45 nonaka static const uint32_t rates = (IWM_SCAN_CONFIG_RATE_1M |
5460 1.45 nonaka IWM_SCAN_CONFIG_RATE_2M | IWM_SCAN_CONFIG_RATE_5M |
5461 1.45 nonaka IWM_SCAN_CONFIG_RATE_11M | IWM_SCAN_CONFIG_RATE_6M |
5462 1.45 nonaka IWM_SCAN_CONFIG_RATE_9M | IWM_SCAN_CONFIG_RATE_12M |
5463 1.45 nonaka IWM_SCAN_CONFIG_RATE_18M | IWM_SCAN_CONFIG_RATE_24M |
5464 1.45 nonaka IWM_SCAN_CONFIG_RATE_36M | IWM_SCAN_CONFIG_RATE_48M |
5465 1.45 nonaka IWM_SCAN_CONFIG_RATE_54M);
5466 1.45 nonaka
5467 1.45 nonaka cmd_size = sizeof(*scan_config) + sc->sc_capa_n_scan_channels;
5468 1.45 nonaka
5469 1.45 nonaka scan_config = kmem_zalloc(cmd_size, KM_SLEEP);
5470 1.45 nonaka scan_config->tx_chains = htole32(iwm_fw_valid_tx_ant(sc));
5471 1.45 nonaka scan_config->rx_chains = htole32(iwm_fw_valid_rx_ant(sc));
5472 1.45 nonaka scan_config->legacy_rates = htole32(rates |
5473 1.45 nonaka IWM_SCAN_CONFIG_SUPPORTED_RATE(rates));
5474 1.45 nonaka
5475 1.45 nonaka /* These timings correspond to iwlwifi's UNASSOC scan. */
5476 1.45 nonaka scan_config->dwell_active = 10;
5477 1.45 nonaka scan_config->dwell_passive = 110;
5478 1.45 nonaka scan_config->dwell_fragmented = 44;
5479 1.45 nonaka scan_config->dwell_extended = 90;
5480 1.45 nonaka scan_config->out_of_channel_time = htole32(0);
5481 1.45 nonaka scan_config->suspend_time = htole32(0);
5482 1.45 nonaka
5483 1.45 nonaka IEEE80211_ADDR_COPY(scan_config->mac_addr, sc->sc_ic.ic_myaddr);
5484 1.45 nonaka
5485 1.45 nonaka scan_config->bcast_sta_id = IWM_AUX_STA_ID;
5486 1.45 nonaka scan_config->channel_flags = IWM_CHANNEL_FLAG_EBS |
5487 1.45 nonaka IWM_CHANNEL_FLAG_ACCURATE_EBS | IWM_CHANNEL_FLAG_EBS_ADD |
5488 1.45 nonaka IWM_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE;
5489 1.45 nonaka
5490 1.45 nonaka for (c = &ic->ic_channels[1], nchan = 0;
5491 1.45 nonaka c <= &ic->ic_channels[IEEE80211_CHAN_MAX] &&
5492 1.45 nonaka nchan < sc->sc_capa_n_scan_channels; c++) {
5493 1.45 nonaka if (c->ic_flags == 0)
5494 1.45 nonaka continue;
5495 1.45 nonaka scan_config->channel_array[nchan++] =
5496 1.45 nonaka ieee80211_mhz2ieee(c->ic_freq, 0);
5497 1.1 pooka }
5498 1.1 pooka
5499 1.45 nonaka scan_config->flags = htole32(IWM_SCAN_CONFIG_FLAG_ACTIVATE |
5500 1.45 nonaka IWM_SCAN_CONFIG_FLAG_ALLOW_CHUB_REQS |
5501 1.45 nonaka IWM_SCAN_CONFIG_FLAG_SET_TX_CHAINS |
5502 1.45 nonaka IWM_SCAN_CONFIG_FLAG_SET_RX_CHAINS |
5503 1.45 nonaka IWM_SCAN_CONFIG_FLAG_SET_AUX_STA_ID |
5504 1.45 nonaka IWM_SCAN_CONFIG_FLAG_SET_ALL_TIMES |
5505 1.45 nonaka IWM_SCAN_CONFIG_FLAG_SET_LEGACY_RATES |
5506 1.45 nonaka IWM_SCAN_CONFIG_FLAG_SET_MAC_ADDR |
5507 1.45 nonaka IWM_SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS|
5508 1.45 nonaka IWM_SCAN_CONFIG_N_CHANNELS(nchan) |
5509 1.45 nonaka IWM_SCAN_CONFIG_FLAG_CLEAR_FRAGMENTED);
5510 1.45 nonaka
5511 1.45 nonaka hcmd.data[0] = scan_config;
5512 1.45 nonaka hcmd.len[0] = cmd_size;
5513 1.45 nonaka
5514 1.45 nonaka err = iwm_send_cmd(sc, &hcmd);
5515 1.45 nonaka kmem_free(scan_config, cmd_size);
5516 1.45 nonaka return err;
5517 1.1 pooka }
5518 1.1 pooka
5519 1.4 nonaka static int
5520 1.45 nonaka iwm_umac_scan(struct iwm_softc *sc)
5521 1.1 pooka {
5522 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5523 1.1 pooka struct iwm_host_cmd hcmd = {
5524 1.45 nonaka .id = iwm_cmd_id(IWM_SCAN_REQ_UMAC, IWM_ALWAYS_LONG_GROUP, 0),
5525 1.1 pooka .len = { 0, },
5526 1.45 nonaka .data = { NULL, },
5527 1.45 nonaka .flags = 0,
5528 1.1 pooka };
5529 1.45 nonaka struct iwm_scan_req_umac *req;
5530 1.45 nonaka struct iwm_scan_req_umac_tail *tail;
5531 1.45 nonaka size_t req_len;
5532 1.45 nonaka int err;
5533 1.1 pooka
5534 1.45 nonaka DPRINTF(("%s: %s\n", DEVNAME(sc), __func__));
5535 1.1 pooka
5536 1.45 nonaka req_len = sizeof(struct iwm_scan_req_umac) +
5537 1.45 nonaka (sizeof(struct iwm_scan_channel_cfg_umac) *
5538 1.45 nonaka sc->sc_capa_n_scan_channels) +
5539 1.45 nonaka sizeof(struct iwm_scan_req_umac_tail);
5540 1.45 nonaka if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
5541 1.45 nonaka return ENOMEM;
5542 1.45 nonaka req = kmem_zalloc(req_len, KM_SLEEP);
5543 1.1 pooka
5544 1.45 nonaka hcmd.len[0] = (uint16_t)req_len;
5545 1.45 nonaka hcmd.data[0] = (void *)req;
5546 1.1 pooka
5547 1.45 nonaka /* These timings correspond to iwlwifi's UNASSOC scan. */
5548 1.45 nonaka req->active_dwell = 10;
5549 1.45 nonaka req->passive_dwell = 110;
5550 1.45 nonaka req->fragmented_dwell = 44;
5551 1.45 nonaka req->extended_dwell = 90;
5552 1.45 nonaka req->max_out_time = 0;
5553 1.45 nonaka req->suspend_time = 0;
5554 1.45 nonaka
5555 1.45 nonaka req->scan_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
5556 1.45 nonaka req->ooc_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
5557 1.45 nonaka
5558 1.45 nonaka req->n_channels = iwm_umac_scan_fill_channels(sc,
5559 1.45 nonaka (struct iwm_scan_channel_cfg_umac *)req->data,
5560 1.45 nonaka ic->ic_des_esslen != 0);
5561 1.45 nonaka
5562 1.45 nonaka req->general_flags = htole32(IWM_UMAC_SCAN_GEN_FLAGS_PASS_ALL |
5563 1.45 nonaka IWM_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE |
5564 1.45 nonaka IWM_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL);
5565 1.45 nonaka
5566 1.45 nonaka tail = (struct iwm_scan_req_umac_tail *)(req->data +
5567 1.45 nonaka sizeof(struct iwm_scan_channel_cfg_umac) *
5568 1.45 nonaka sc->sc_capa_n_scan_channels);
5569 1.45 nonaka
5570 1.45 nonaka /* Check if we're doing an active directed scan. */
5571 1.45 nonaka if (ic->ic_des_esslen != 0) {
5572 1.45 nonaka tail->direct_scan[0].id = IEEE80211_ELEMID_SSID;
5573 1.45 nonaka tail->direct_scan[0].len = ic->ic_des_esslen;
5574 1.45 nonaka memcpy(tail->direct_scan[0].ssid, ic->ic_des_essid,
5575 1.45 nonaka ic->ic_des_esslen);
5576 1.45 nonaka req->general_flags |=
5577 1.45 nonaka htole32(IWM_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT);
5578 1.45 nonaka } else
5579 1.45 nonaka req->general_flags |= htole32(IWM_UMAC_SCAN_GEN_FLAGS_PASSIVE);
5580 1.1 pooka
5581 1.45 nonaka if (isset(sc->sc_enabled_capa,
5582 1.45 nonaka IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT))
5583 1.45 nonaka req->general_flags |=
5584 1.45 nonaka htole32(IWM_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED);
5585 1.1 pooka
5586 1.45 nonaka err = iwm_fill_probe_req(sc, &tail->preq);
5587 1.45 nonaka if (err) {
5588 1.45 nonaka kmem_free(req, req_len);
5589 1.45 nonaka return err;
5590 1.1 pooka }
5591 1.1 pooka
5592 1.45 nonaka /* Specify the scan plan: We'll do one iteration. */
5593 1.45 nonaka tail->schedule[0].interval = 0;
5594 1.45 nonaka tail->schedule[0].iter_count = 1;
5595 1.45 nonaka
5596 1.45 nonaka err = iwm_send_cmd(sc, &hcmd);
5597 1.45 nonaka kmem_free(req, req_len);
5598 1.45 nonaka return err;
5599 1.1 pooka }
5600 1.1 pooka
5601 1.45 nonaka static uint8_t
5602 1.45 nonaka iwm_ridx2rate(struct ieee80211_rateset *rs, int ridx)
5603 1.45 nonaka {
5604 1.45 nonaka int i;
5605 1.45 nonaka uint8_t rval;
5606 1.1 pooka
5607 1.45 nonaka for (i = 0; i < rs->rs_nrates; i++) {
5608 1.45 nonaka rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL);
5609 1.45 nonaka if (rval == iwm_rates[ridx].rate)
5610 1.45 nonaka return rs->rs_rates[i];
5611 1.45 nonaka }
5612 1.45 nonaka return 0;
5613 1.45 nonaka }
5614 1.1 pooka
5615 1.4 nonaka static void
5616 1.45 nonaka iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates,
5617 1.45 nonaka int *ofdm_rates)
5618 1.1 pooka {
5619 1.24 nonaka struct ieee80211_node *ni = &in->in_ni;
5620 1.45 nonaka struct ieee80211_rateset *rs = &ni->ni_rates;
5621 1.56 nonaka int lowest_present_ofdm = -1;
5622 1.56 nonaka int lowest_present_cck = -1;
5623 1.1 pooka uint8_t cck = 0;
5624 1.1 pooka uint8_t ofdm = 0;
5625 1.1 pooka int i;
5626 1.1 pooka
5627 1.45 nonaka if (ni->ni_chan == IEEE80211_CHAN_ANYC ||
5628 1.45 nonaka IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) {
5629 1.45 nonaka for (i = IWM_FIRST_CCK_RATE; i < IWM_FIRST_OFDM_RATE; i++) {
5630 1.45 nonaka if ((iwm_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0)
5631 1.45 nonaka continue;
5632 1.24 nonaka cck |= (1 << i);
5633 1.56 nonaka if (lowest_present_cck == -1 || lowest_present_cck > i)
5634 1.24 nonaka lowest_present_cck = i;
5635 1.24 nonaka }
5636 1.1 pooka }
5637 1.1 pooka for (i = IWM_FIRST_OFDM_RATE; i <= IWM_LAST_NON_HT_RATE; i++) {
5638 1.45 nonaka if ((iwm_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0)
5639 1.45 nonaka continue;
5640 1.45 nonaka ofdm |= (1 << (i - IWM_FIRST_OFDM_RATE));
5641 1.56 nonaka if (lowest_present_ofdm == -1 || lowest_present_ofdm > i)
5642 1.20 nonaka lowest_present_ofdm = i;
5643 1.1 pooka }
5644 1.1 pooka
5645 1.1 pooka /*
5646 1.1 pooka * Now we've got the basic rates as bitmaps in the ofdm and cck
5647 1.1 pooka * variables. This isn't sufficient though, as there might not
5648 1.1 pooka * be all the right rates in the bitmap. E.g. if the only basic
5649 1.1 pooka * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps
5650 1.1 pooka * and 6 Mbps because the 802.11-2007 standard says in 9.6:
5651 1.1 pooka *
5652 1.1 pooka * [...] a STA responding to a received frame shall transmit
5653 1.1 pooka * its Control Response frame [...] at the highest rate in the
5654 1.1 pooka * BSSBasicRateSet parameter that is less than or equal to the
5655 1.1 pooka * rate of the immediately previous frame in the frame exchange
5656 1.1 pooka * sequence ([...]) and that is of the same modulation class
5657 1.1 pooka * ([...]) as the received frame. If no rate contained in the
5658 1.1 pooka * BSSBasicRateSet parameter meets these conditions, then the
5659 1.1 pooka * control frame sent in response to a received frame shall be
5660 1.1 pooka * transmitted at the highest mandatory rate of the PHY that is
5661 1.1 pooka * less than or equal to the rate of the received frame, and
5662 1.1 pooka * that is of the same modulation class as the received frame.
5663 1.1 pooka *
5664 1.1 pooka * As a consequence, we need to add all mandatory rates that are
5665 1.1 pooka * lower than all of the basic rates to these bitmaps.
5666 1.1 pooka */
5667 1.1 pooka
5668 1.1 pooka if (IWM_RATE_24M_INDEX < lowest_present_ofdm)
5669 1.1 pooka ofdm |= IWM_RATE_BIT_MSK(24) >> IWM_FIRST_OFDM_RATE;
5670 1.1 pooka if (IWM_RATE_12M_INDEX < lowest_present_ofdm)
5671 1.1 pooka ofdm |= IWM_RATE_BIT_MSK(12) >> IWM_FIRST_OFDM_RATE;
5672 1.1 pooka /* 6M already there or needed so always add */
5673 1.1 pooka ofdm |= IWM_RATE_BIT_MSK(6) >> IWM_FIRST_OFDM_RATE;
5674 1.1 pooka
5675 1.1 pooka /*
5676 1.1 pooka * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP.
5677 1.1 pooka * Note, however:
5678 1.1 pooka * - if no CCK rates are basic, it must be ERP since there must
5679 1.1 pooka * be some basic rates at all, so they're OFDM => ERP PHY
5680 1.1 pooka * (or we're in 5 GHz, and the cck bitmap will never be used)
5681 1.1 pooka * - if 11M is a basic rate, it must be ERP as well, so add 5.5M
5682 1.1 pooka * - if 5.5M is basic, 1M and 2M are mandatory
5683 1.1 pooka * - if 2M is basic, 1M is mandatory
5684 1.1 pooka * - if 1M is basic, that's the only valid ACK rate.
5685 1.1 pooka * As a consequence, it's not as complicated as it sounds, just add
5686 1.1 pooka * any lower rates to the ACK rate bitmap.
5687 1.1 pooka */
5688 1.1 pooka if (IWM_RATE_11M_INDEX < lowest_present_cck)
5689 1.1 pooka cck |= IWM_RATE_BIT_MSK(11) >> IWM_FIRST_CCK_RATE;
5690 1.1 pooka if (IWM_RATE_5M_INDEX < lowest_present_cck)
5691 1.1 pooka cck |= IWM_RATE_BIT_MSK(5) >> IWM_FIRST_CCK_RATE;
5692 1.1 pooka if (IWM_RATE_2M_INDEX < lowest_present_cck)
5693 1.1 pooka cck |= IWM_RATE_BIT_MSK(2) >> IWM_FIRST_CCK_RATE;
5694 1.1 pooka /* 1M already there or needed so always add */
5695 1.1 pooka cck |= IWM_RATE_BIT_MSK(1) >> IWM_FIRST_CCK_RATE;
5696 1.1 pooka
5697 1.1 pooka *cck_rates = cck;
5698 1.1 pooka *ofdm_rates = ofdm;
5699 1.1 pooka }
5700 1.1 pooka
5701 1.4 nonaka static void
5702 1.45 nonaka iwm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in,
5703 1.45 nonaka struct iwm_mac_ctx_cmd *cmd, uint32_t action, int assoc)
5704 1.1 pooka {
5705 1.45 nonaka #define IWM_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */
5706 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5707 1.1 pooka struct ieee80211_node *ni = ic->ic_bss;
5708 1.1 pooka int cck_ack_rates, ofdm_ack_rates;
5709 1.1 pooka int i;
5710 1.1 pooka
5711 1.1 pooka cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id,
5712 1.1 pooka in->in_color));
5713 1.1 pooka cmd->action = htole32(action);
5714 1.1 pooka
5715 1.1 pooka cmd->mac_type = htole32(IWM_FW_MAC_TYPE_BSS_STA);
5716 1.45 nonaka cmd->tsf_id = htole32(IWM_TSF_ID_A);
5717 1.1 pooka
5718 1.1 pooka IEEE80211_ADDR_COPY(cmd->node_addr, ic->ic_myaddr);
5719 1.45 nonaka IEEE80211_ADDR_COPY(cmd->bssid_addr, ni->ni_bssid);
5720 1.45 nonaka
5721 1.45 nonaka iwm_ack_rates(sc, in, &cck_ack_rates, &ofdm_ack_rates);
5722 1.1 pooka cmd->cck_rates = htole32(cck_ack_rates);
5723 1.1 pooka cmd->ofdm_rates = htole32(ofdm_ack_rates);
5724 1.1 pooka
5725 1.1 pooka cmd->cck_short_preamble
5726 1.1 pooka = htole32((ic->ic_flags & IEEE80211_F_SHPREAMBLE)
5727 1.1 pooka ? IWM_MAC_FLG_SHORT_PREAMBLE : 0);
5728 1.1 pooka cmd->short_slot
5729 1.1 pooka = htole32((ic->ic_flags & IEEE80211_F_SHSLOT)
5730 1.1 pooka ? IWM_MAC_FLG_SHORT_SLOT : 0);
5731 1.1 pooka
5732 1.45 nonaka for (i = 0; i < WME_NUM_AC; i++) {
5733 1.45 nonaka struct wmeParams *wmep = &ic->ic_wme.wme_params[i];
5734 1.45 nonaka int txf = iwm_ac_to_tx_fifo[i];
5735 1.45 nonaka
5736 1.45 nonaka cmd->ac[txf].cw_min = htole16(IWM_EXP2(wmep->wmep_logcwmin));
5737 1.45 nonaka cmd->ac[txf].cw_max = htole16(IWM_EXP2(wmep->wmep_logcwmax));
5738 1.45 nonaka cmd->ac[txf].aifsn = wmep->wmep_aifsn;
5739 1.1 pooka cmd->ac[txf].fifos_mask = (1 << txf);
5740 1.45 nonaka cmd->ac[txf].edca_txop = htole16(wmep->wmep_txopLimit * 32);
5741 1.1 pooka }
5742 1.45 nonaka if (ni->ni_flags & IEEE80211_NODE_QOS)
5743 1.45 nonaka cmd->qos_flags |= htole32(IWM_MAC_QOS_FLG_UPDATE_EDCA);
5744 1.1 pooka
5745 1.45 nonaka #ifndef IEEE80211_NO_HT
5746 1.45 nonaka if (ni->ni_flags & IEEE80211_NODE_HT) {
5747 1.45 nonaka enum ieee80211_htprot htprot =
5748 1.45 nonaka (ni->ni_htop1 & IEEE80211_HTOP1_PROT_MASK);
5749 1.45 nonaka switch (htprot) {
5750 1.45 nonaka case IEEE80211_HTPROT_NONE:
5751 1.45 nonaka break;
5752 1.45 nonaka case IEEE80211_HTPROT_NONMEMBER:
5753 1.45 nonaka case IEEE80211_HTPROT_NONHT_MIXED:
5754 1.45 nonaka cmd->protection_flags |=
5755 1.45 nonaka htole32(IWM_MAC_PROT_FLG_HT_PROT);
5756 1.45 nonaka case IEEE80211_HTPROT_20MHZ:
5757 1.45 nonaka cmd->protection_flags |=
5758 1.45 nonaka htole32(IWM_MAC_PROT_FLG_HT_PROT |
5759 1.45 nonaka IWM_MAC_PROT_FLG_FAT_PROT);
5760 1.45 nonaka break;
5761 1.45 nonaka default:
5762 1.45 nonaka break;
5763 1.45 nonaka }
5764 1.1 pooka
5765 1.45 nonaka cmd->qos_flags |= htole32(IWM_MAC_QOS_FLG_TGN);
5766 1.1 pooka }
5767 1.45 nonaka #endif
5768 1.1 pooka
5769 1.45 nonaka if (ic->ic_flags & IEEE80211_F_USEPROT)
5770 1.45 nonaka cmd->protection_flags |= htole32(IWM_MAC_PROT_FLG_TGG_PROTECT);
5771 1.1 pooka
5772 1.45 nonaka cmd->filter_flags = htole32(IWM_MAC_FILTER_ACCEPT_GRP);
5773 1.45 nonaka #undef IWM_EXP2
5774 1.1 pooka }
5775 1.1 pooka
5776 1.45 nonaka static void
5777 1.45 nonaka iwm_mac_ctxt_cmd_fill_sta(struct iwm_softc *sc, struct iwm_node *in,
5778 1.45 nonaka struct iwm_mac_data_sta *sta, int assoc)
5779 1.1 pooka {
5780 1.45 nonaka struct ieee80211_node *ni = &in->in_ni;
5781 1.45 nonaka uint32_t dtim_off;
5782 1.45 nonaka uint64_t tsf;
5783 1.1 pooka
5784 1.45 nonaka dtim_off = ni->ni_dtim_count * ni->ni_intval * IEEE80211_DUR_TU;
5785 1.45 nonaka tsf = le64toh(ni->ni_tstamp.tsf);
5786 1.1 pooka
5787 1.45 nonaka sta->is_assoc = htole32(assoc);
5788 1.45 nonaka sta->dtim_time = htole32(ni->ni_rstamp + dtim_off);
5789 1.45 nonaka sta->dtim_tsf = htole64(tsf + dtim_off);
5790 1.45 nonaka sta->bi = htole32(ni->ni_intval);
5791 1.45 nonaka sta->bi_reciprocal = htole32(iwm_reciprocal(ni->ni_intval));
5792 1.45 nonaka sta->dtim_interval = htole32(ni->ni_intval * ni->ni_dtim_period);
5793 1.45 nonaka sta->dtim_reciprocal = htole32(iwm_reciprocal(sta->dtim_interval));
5794 1.45 nonaka sta->listen_interval = htole32(10);
5795 1.45 nonaka sta->assoc_id = htole32(ni->ni_associd);
5796 1.45 nonaka sta->assoc_beacon_arrive_time = htole32(ni->ni_rstamp);
5797 1.1 pooka }
5798 1.1 pooka
5799 1.4 nonaka static int
5800 1.45 nonaka iwm_mac_ctxt_cmd(struct iwm_softc *sc, struct iwm_node *in, uint32_t action,
5801 1.45 nonaka int assoc)
5802 1.1 pooka {
5803 1.45 nonaka struct ieee80211_node *ni = &in->in_ni;
5804 1.1 pooka struct iwm_mac_ctx_cmd cmd;
5805 1.1 pooka
5806 1.1 pooka memset(&cmd, 0, sizeof(cmd));
5807 1.1 pooka
5808 1.45 nonaka iwm_mac_ctxt_cmd_common(sc, in, &cmd, action, assoc);
5809 1.1 pooka
5810 1.45 nonaka /* Allow beacons to pass through as long as we are not associated or we
5811 1.45 nonaka * do not have dtim period information */
5812 1.45 nonaka if (!assoc || !ni->ni_associd || !ni->ni_dtim_period)
5813 1.45 nonaka cmd.filter_flags |= htole32(IWM_MAC_FILTER_IN_BEACON);
5814 1.45 nonaka else
5815 1.45 nonaka iwm_mac_ctxt_cmd_fill_sta(sc, in, &cmd.sta, assoc);
5816 1.1 pooka
5817 1.45 nonaka return iwm_send_cmd_pdu(sc, IWM_MAC_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
5818 1.1 pooka }
5819 1.1 pooka
5820 1.45 nonaka #define IWM_MISSED_BEACONS_THRESHOLD 8
5821 1.1 pooka
5822 1.1 pooka static void
5823 1.45 nonaka iwm_rx_missed_beacons_notif(struct iwm_softc *sc,
5824 1.1 pooka struct iwm_rx_packet *pkt, struct iwm_rx_data *data)
5825 1.1 pooka {
5826 1.1 pooka struct iwm_missed_beacons_notif *mb = (void *)pkt->data;
5827 1.68 nonaka int s;
5828 1.1 pooka
5829 1.1 pooka DPRINTF(("missed bcn mac_id=%u, consecutive=%u (%u, %u, %u)\n",
5830 1.1 pooka le32toh(mb->mac_id),
5831 1.1 pooka le32toh(mb->consec_missed_beacons),
5832 1.1 pooka le32toh(mb->consec_missed_beacons_since_last_rx),
5833 1.1 pooka le32toh(mb->num_recvd_beacons),
5834 1.1 pooka le32toh(mb->num_expected_beacons)));
5835 1.1 pooka
5836 1.1 pooka /*
5837 1.1 pooka * TODO: the threshold should be adjusted based on latency conditions,
5838 1.1 pooka * and/or in case of a CS flow on one of the other AP vifs.
5839 1.1 pooka */
5840 1.1 pooka if (le32toh(mb->consec_missed_beacons_since_last_rx) >
5841 1.68 nonaka IWM_MISSED_BEACONS_THRESHOLD) {
5842 1.68 nonaka s = splnet();
5843 1.1 pooka ieee80211_beacon_miss(&sc->sc_ic);
5844 1.68 nonaka splx(s);
5845 1.68 nonaka }
5846 1.1 pooka }
5847 1.1 pooka
5848 1.4 nonaka static int
5849 1.45 nonaka iwm_update_quotas(struct iwm_softc *sc, struct iwm_node *in)
5850 1.1 pooka {
5851 1.1 pooka struct iwm_time_quota_cmd cmd;
5852 1.45 nonaka int i, idx, num_active_macs, quota, quota_rem;
5853 1.1 pooka int colors[IWM_MAX_BINDINGS] = { -1, -1, -1, -1, };
5854 1.1 pooka int n_ifs[IWM_MAX_BINDINGS] = {0, };
5855 1.1 pooka uint16_t id;
5856 1.1 pooka
5857 1.1 pooka memset(&cmd, 0, sizeof(cmd));
5858 1.1 pooka
5859 1.1 pooka /* currently, PHY ID == binding ID */
5860 1.1 pooka if (in) {
5861 1.1 pooka id = in->in_phyctxt->id;
5862 1.1 pooka KASSERT(id < IWM_MAX_BINDINGS);
5863 1.1 pooka colors[id] = in->in_phyctxt->color;
5864 1.1 pooka
5865 1.1 pooka if (1)
5866 1.1 pooka n_ifs[id] = 1;
5867 1.1 pooka }
5868 1.1 pooka
5869 1.1 pooka /*
5870 1.1 pooka * The FW's scheduling session consists of
5871 1.45 nonaka * IWM_MAX_QUOTA fragments. Divide these fragments
5872 1.1 pooka * equally between all the bindings that require quota
5873 1.1 pooka */
5874 1.1 pooka num_active_macs = 0;
5875 1.1 pooka for (i = 0; i < IWM_MAX_BINDINGS; i++) {
5876 1.1 pooka cmd.quotas[i].id_and_color = htole32(IWM_FW_CTXT_INVALID);
5877 1.1 pooka num_active_macs += n_ifs[i];
5878 1.1 pooka }
5879 1.1 pooka
5880 1.1 pooka quota = 0;
5881 1.1 pooka quota_rem = 0;
5882 1.1 pooka if (num_active_macs) {
5883 1.45 nonaka quota = IWM_MAX_QUOTA / num_active_macs;
5884 1.45 nonaka quota_rem = IWM_MAX_QUOTA % num_active_macs;
5885 1.1 pooka }
5886 1.1 pooka
5887 1.1 pooka for (idx = 0, i = 0; i < IWM_MAX_BINDINGS; i++) {
5888 1.1 pooka if (colors[i] < 0)
5889 1.1 pooka continue;
5890 1.1 pooka
5891 1.1 pooka cmd.quotas[idx].id_and_color =
5892 1.1 pooka htole32(IWM_FW_CMD_ID_AND_COLOR(i, colors[i]));
5893 1.1 pooka
5894 1.1 pooka if (n_ifs[i] <= 0) {
5895 1.1 pooka cmd.quotas[idx].quota = htole32(0);
5896 1.1 pooka cmd.quotas[idx].max_duration = htole32(0);
5897 1.1 pooka } else {
5898 1.1 pooka cmd.quotas[idx].quota = htole32(quota * n_ifs[i]);
5899 1.1 pooka cmd.quotas[idx].max_duration = htole32(0);
5900 1.1 pooka }
5901 1.1 pooka idx++;
5902 1.1 pooka }
5903 1.1 pooka
5904 1.1 pooka /* Give the remainder of the session to the first binding */
5905 1.1 pooka cmd.quotas[0].quota = htole32(le32toh(cmd.quotas[0].quota) + quota_rem);
5906 1.1 pooka
5907 1.45 nonaka return iwm_send_cmd_pdu(sc, IWM_TIME_QUOTA_CMD, 0, sizeof(cmd), &cmd);
5908 1.1 pooka }
5909 1.1 pooka
5910 1.4 nonaka static int
5911 1.1 pooka iwm_auth(struct iwm_softc *sc)
5912 1.1 pooka {
5913 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5914 1.45 nonaka struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
5915 1.1 pooka uint32_t duration;
5916 1.45 nonaka int err;
5917 1.1 pooka
5918 1.45 nonaka err = iwm_sf_config(sc, IWM_SF_FULL_ON);
5919 1.45 nonaka if (err)
5920 1.45 nonaka return err;
5921 1.11 nonaka
5922 1.45 nonaka err = iwm_allow_mcast(sc);
5923 1.45 nonaka if (err)
5924 1.45 nonaka return err;
5925 1.11 nonaka
5926 1.45 nonaka sc->sc_phyctxt[0].channel = in->in_ni.ni_chan;
5927 1.45 nonaka err = iwm_phy_ctxt_cmd(sc, &sc->sc_phyctxt[0], 1, 1,
5928 1.45 nonaka IWM_FW_CTXT_ACTION_MODIFY, 0);
5929 1.45 nonaka if (err)
5930 1.45 nonaka return err;
5931 1.1 pooka in->in_phyctxt = &sc->sc_phyctxt[0];
5932 1.1 pooka
5933 1.45 nonaka err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_ADD, 0);
5934 1.45 nonaka if (err) {
5935 1.45 nonaka aprint_error_dev(sc->sc_dev,
5936 1.45 nonaka "could not add MAC context (error %d)\n", err);
5937 1.45 nonaka return err;
5938 1.1 pooka }
5939 1.1 pooka
5940 1.45 nonaka err = iwm_binding_cmd(sc, in, IWM_FW_CTXT_ACTION_ADD);
5941 1.45 nonaka if (err)
5942 1.45 nonaka return err;
5943 1.1 pooka
5944 1.45 nonaka err = iwm_add_sta_cmd(sc, in, 0);
5945 1.45 nonaka if (err)
5946 1.45 nonaka return err;
5947 1.8 nonaka
5948 1.45 nonaka err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY, 0);
5949 1.45 nonaka if (err) {
5950 1.45 nonaka aprint_error_dev(sc->sc_dev, "failed to update MAC\n");
5951 1.45 nonaka return err;
5952 1.45 nonaka }
5953 1.1 pooka
5954 1.45 nonaka /*
5955 1.45 nonaka * Prevent the FW from wandering off channel during association
5956 1.45 nonaka * by "protecting" the session with a time event.
5957 1.45 nonaka */
5958 1.45 nonaka if (in->in_ni.ni_intval)
5959 1.45 nonaka duration = in->in_ni.ni_intval * 2;
5960 1.45 nonaka else
5961 1.45 nonaka duration = IEEE80211_DUR_TU;
5962 1.45 nonaka iwm_protect_session(sc, in, duration, in->in_ni.ni_intval / 2);
5963 1.45 nonaka DELAY(100);
5964 1.1 pooka
5965 1.1 pooka return 0;
5966 1.1 pooka }
5967 1.1 pooka
5968 1.4 nonaka static int
5969 1.1 pooka iwm_assoc(struct iwm_softc *sc)
5970 1.1 pooka {
5971 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5972 1.45 nonaka struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
5973 1.45 nonaka int err;
5974 1.1 pooka
5975 1.45 nonaka err = iwm_add_sta_cmd(sc, in, 1);
5976 1.45 nonaka if (err)
5977 1.45 nonaka return err;
5978 1.1 pooka
5979 1.1 pooka return 0;
5980 1.1 pooka }
5981 1.1 pooka
5982 1.1 pooka static struct ieee80211_node *
5983 1.1 pooka iwm_node_alloc(struct ieee80211_node_table *nt)
5984 1.1 pooka {
5985 1.5 nonaka return malloc(sizeof(struct iwm_node), M_80211_NODE, M_NOWAIT | M_ZERO);
5986 1.1 pooka }
5987 1.1 pooka
5988 1.4 nonaka static void
5989 1.1 pooka iwm_calib_timeout(void *arg)
5990 1.1 pooka {
5991 1.1 pooka struct iwm_softc *sc = arg;
5992 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5993 1.45 nonaka struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
5994 1.45 nonaka #ifndef IEEE80211_NO_HT
5995 1.45 nonaka struct ieee80211_node *ni = &in->in_ni;
5996 1.45 nonaka int otxrate;
5997 1.45 nonaka #endif
5998 1.1 pooka int s;
5999 1.1 pooka
6000 1.1 pooka s = splnet();
6001 1.45 nonaka if ((ic->ic_fixed_rate == -1
6002 1.45 nonaka #ifndef IEEE80211_NO_HT
6003 1.45 nonaka || ic->ic_fixed_mcs == -1
6004 1.45 nonaka #endif
6005 1.45 nonaka ) &&
6006 1.45 nonaka ic->ic_opmode == IEEE80211_M_STA && ic->ic_bss) {
6007 1.45 nonaka #ifndef IEEE80211_NO_HT
6008 1.45 nonaka if (ni->ni_flags & IEEE80211_NODE_HT)
6009 1.45 nonaka otxrate = ni->ni_txmcs;
6010 1.45 nonaka else
6011 1.45 nonaka otxrate = ni->ni_txrate;
6012 1.45 nonaka #endif
6013 1.1 pooka ieee80211_amrr_choose(&sc->sc_amrr, &in->in_ni, &in->in_amn);
6014 1.45 nonaka
6015 1.45 nonaka #ifndef IEEE80211_NO_HT
6016 1.45 nonaka /*
6017 1.45 nonaka * If AMRR has chosen a new TX rate we must update
6018 1.45 nonaka * the firwmare's LQ rate table from process context.
6019 1.45 nonaka */
6020 1.45 nonaka if ((ni->ni_flags & IEEE80211_NODE_HT) &&
6021 1.45 nonaka otxrate != ni->ni_txmcs)
6022 1.45 nonaka softint_schedule(sc->setrates_task);
6023 1.45 nonaka else if (otxrate != ni->ni_txrate)
6024 1.45 nonaka softint_schedule(sc->setrates_task);
6025 1.45 nonaka #endif
6026 1.1 pooka }
6027 1.1 pooka splx(s);
6028 1.1 pooka
6029 1.45 nonaka callout_schedule(&sc->sc_calib_to, mstohz(500));
6030 1.1 pooka }
6031 1.1 pooka
6032 1.45 nonaka #ifndef IEEE80211_NO_HT
6033 1.4 nonaka static void
6034 1.45 nonaka iwm_setrates_task(void *arg)
6035 1.45 nonaka {
6036 1.45 nonaka struct iwm_softc *sc = arg;
6037 1.45 nonaka struct ieee80211com *ic = &sc->sc_ic;
6038 1.45 nonaka struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
6039 1.45 nonaka
6040 1.45 nonaka /* Update rates table based on new TX rate determined by AMRR. */
6041 1.45 nonaka iwm_setrates(in);
6042 1.45 nonaka }
6043 1.45 nonaka
6044 1.45 nonaka static int
6045 1.1 pooka iwm_setrates(struct iwm_node *in)
6046 1.1 pooka {
6047 1.1 pooka struct ieee80211_node *ni = &in->in_ni;
6048 1.1 pooka struct ieee80211com *ic = ni->ni_ic;
6049 1.1 pooka struct iwm_softc *sc = IC2IFP(ic)->if_softc;
6050 1.1 pooka struct iwm_lq_cmd *lq = &in->in_lq;
6051 1.45 nonaka struct ieee80211_rateset *rs = &ni->ni_rates;
6052 1.45 nonaka int i, j, ridx, ridx_min, tab = 0;
6053 1.45 nonaka #ifndef IEEE80211_NO_HT
6054 1.45 nonaka int sgi_ok;
6055 1.45 nonaka #endif
6056 1.45 nonaka struct iwm_host_cmd cmd = {
6057 1.45 nonaka .id = IWM_LQ_CMD,
6058 1.45 nonaka .len = { sizeof(in->in_lq), },
6059 1.45 nonaka };
6060 1.1 pooka
6061 1.45 nonaka memset(lq, 0, sizeof(*lq));
6062 1.45 nonaka lq->sta_id = IWM_STATION_ID;
6063 1.1 pooka
6064 1.45 nonaka if (ic->ic_flags & IEEE80211_F_USEPROT)
6065 1.45 nonaka lq->flags |= IWM_LQ_FLAG_USE_RTS_MSK;
6066 1.8 nonaka
6067 1.45 nonaka #ifndef IEEE80211_NO_HT
6068 1.45 nonaka sgi_ok = ((ni->ni_flags & IEEE80211_NODE_HT) &&
6069 1.45 nonaka (ni->ni_htcaps & IEEE80211_HTCAP_SGI20));
6070 1.45 nonaka #endif
6071 1.1 pooka
6072 1.1 pooka
6073 1.1 pooka /*
6074 1.45 nonaka * Fill the LQ rate selection table with legacy and/or HT rates
6075 1.45 nonaka * in descending order, i.e. with the node's current TX rate first.
6076 1.45 nonaka * In cases where throughput of an HT rate corresponds to a legacy
6077 1.45 nonaka * rate it makes no sense to add both. We rely on the fact that
6078 1.45 nonaka * iwm_rates is laid out such that equivalent HT/legacy rates share
6079 1.45 nonaka * the same IWM_RATE_*_INDEX value. Also, rates not applicable to
6080 1.45 nonaka * legacy/HT are assumed to be marked with an 'invalid' PLCP value.
6081 1.1 pooka */
6082 1.45 nonaka j = 0;
6083 1.45 nonaka ridx_min = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ?
6084 1.45 nonaka IWM_RIDX_OFDM : IWM_RIDX_CCK;
6085 1.45 nonaka for (ridx = IWM_RIDX_MAX; ridx >= ridx_min; ridx--) {
6086 1.45 nonaka if (j >= __arraycount(lq->rs_table))
6087 1.45 nonaka break;
6088 1.45 nonaka tab = 0;
6089 1.45 nonaka #ifndef IEEE80211_NO_HT
6090 1.45 nonaka if ((ni->ni_flags & IEEE80211_NODE_HT) &&
6091 1.45 nonaka iwm_rates[ridx].ht_plcp != IWM_RATE_HT_SISO_MCS_INV_PLCP) {
6092 1.45 nonaka for (i = ni->ni_txmcs; i >= 0; i--) {
6093 1.45 nonaka if (isclr(ni->ni_rxmcs, i))
6094 1.45 nonaka continue;
6095 1.45 nonaka if (ridx == iwm_mcs2ridx[i]) {
6096 1.45 nonaka tab = iwm_rates[ridx].ht_plcp;
6097 1.45 nonaka tab |= IWM_RATE_MCS_HT_MSK;
6098 1.45 nonaka if (sgi_ok)
6099 1.45 nonaka tab |= IWM_RATE_MCS_SGI_MSK;
6100 1.45 nonaka break;
6101 1.45 nonaka }
6102 1.45 nonaka }
6103 1.45 nonaka }
6104 1.45 nonaka #endif
6105 1.45 nonaka if (tab == 0 && iwm_rates[ridx].plcp != IWM_RATE_INVM_PLCP) {
6106 1.45 nonaka for (i = ni->ni_txrate; i >= 0; i--) {
6107 1.45 nonaka if (iwm_rates[ridx].rate == (rs->rs_rates[i] &
6108 1.45 nonaka IEEE80211_RATE_VAL)) {
6109 1.45 nonaka tab = iwm_rates[ridx].plcp;
6110 1.45 nonaka break;
6111 1.45 nonaka }
6112 1.45 nonaka }
6113 1.45 nonaka }
6114 1.1 pooka
6115 1.45 nonaka if (tab == 0)
6116 1.45 nonaka continue;
6117 1.1 pooka
6118 1.45 nonaka tab |= 1 << IWM_RATE_MCS_ANT_POS;
6119 1.1 pooka if (IWM_RIDX_IS_CCK(ridx))
6120 1.1 pooka tab |= IWM_RATE_MCS_CCK_MSK;
6121 1.1 pooka DPRINTFN(2, ("station rate %d %x\n", i, tab));
6122 1.45 nonaka lq->rs_table[j++] = htole32(tab);
6123 1.1 pooka }
6124 1.1 pooka
6125 1.45 nonaka /* Fill the rest with the lowest possible rate */
6126 1.45 nonaka i = j > 0 ? j - 1 : 0;
6127 1.45 nonaka while (j < __arraycount(lq->rs_table))
6128 1.45 nonaka lq->rs_table[j++] = lq->rs_table[i];
6129 1.45 nonaka
6130 1.45 nonaka lq->single_stream_ant_msk = IWM_ANT_A;
6131 1.45 nonaka lq->dual_stream_ant_msk = IWM_ANT_AB;
6132 1.45 nonaka
6133 1.45 nonaka lq->agg_time_limit = htole16(4000); /* 4ms */
6134 1.45 nonaka lq->agg_disable_start_th = 3;
6135 1.45 nonaka #ifdef notyet
6136 1.45 nonaka lq->agg_frame_cnt_limit = 0x3f;
6137 1.45 nonaka #else
6138 1.45 nonaka lq->agg_frame_cnt_limit = 1; /* tx agg disabled */
6139 1.45 nonaka #endif
6140 1.45 nonaka
6141 1.45 nonaka cmd.data[0] = &in->in_lq;
6142 1.45 nonaka return iwm_send_cmd(sc, &cmd);
6143 1.1 pooka }
6144 1.45 nonaka #endif
6145 1.1 pooka
6146 1.4 nonaka static int
6147 1.1 pooka iwm_media_change(struct ifnet *ifp)
6148 1.1 pooka {
6149 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
6150 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
6151 1.1 pooka uint8_t rate, ridx;
6152 1.45 nonaka int err;
6153 1.1 pooka
6154 1.45 nonaka err = ieee80211_media_change(ifp);
6155 1.45 nonaka if (err != ENETRESET)
6156 1.45 nonaka return err;
6157 1.1 pooka
6158 1.45 nonaka #ifndef IEEE80211_NO_HT
6159 1.45 nonaka if (ic->ic_fixed_mcs != -1)
6160 1.45 nonaka sc->sc_fixed_ridx = iwm_mcs2ridx[ic->ic_fixed_mcs];
6161 1.45 nonaka else
6162 1.45 nonaka #endif
6163 1.1 pooka if (ic->ic_fixed_rate != -1) {
6164 1.1 pooka rate = ic->ic_sup_rates[ic->ic_curmode].
6165 1.1 pooka rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
6166 1.1 pooka /* Map 802.11 rate to HW rate index. */
6167 1.1 pooka for (ridx = 0; ridx <= IWM_RIDX_MAX; ridx++)
6168 1.1 pooka if (iwm_rates[ridx].rate == rate)
6169 1.1 pooka break;
6170 1.1 pooka sc->sc_fixed_ridx = ridx;
6171 1.1 pooka }
6172 1.1 pooka
6173 1.1 pooka if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
6174 1.1 pooka (IFF_UP | IFF_RUNNING)) {
6175 1.1 pooka iwm_stop(ifp, 0);
6176 1.45 nonaka err = iwm_init(ifp);
6177 1.1 pooka }
6178 1.45 nonaka return err;
6179 1.1 pooka }
6180 1.1 pooka
6181 1.65 nonaka static int
6182 1.65 nonaka iwm_do_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
6183 1.1 pooka {
6184 1.65 nonaka struct ifnet *ifp = IC2IFP(ic);
6185 1.65 nonaka struct iwm_softc *sc = ifp->if_softc;
6186 1.45 nonaka enum ieee80211_state ostate = ic->ic_state;
6187 1.1 pooka struct iwm_node *in;
6188 1.45 nonaka int err;
6189 1.1 pooka
6190 1.45 nonaka DPRINTF(("switching state %s->%s\n", ieee80211_state_name[ostate],
6191 1.45 nonaka ieee80211_state_name[nstate]));
6192 1.1 pooka
6193 1.45 nonaka if (ostate == IEEE80211_S_SCAN && nstate != ostate)
6194 1.45 nonaka iwm_led_blink_stop(sc);
6195 1.45 nonaka
6196 1.45 nonaka if (ostate == IEEE80211_S_RUN && nstate != ostate)
6197 1.45 nonaka iwm_disable_beacon_filter(sc);
6198 1.45 nonaka
6199 1.45 nonaka /* Reset the device if moving out of AUTH, ASSOC, or RUN. */
6200 1.45 nonaka /* XXX Is there a way to switch states without a full reset? */
6201 1.45 nonaka if (ostate > IEEE80211_S_SCAN && nstate < ostate) {
6202 1.1 pooka /*
6203 1.45 nonaka * Upon receiving a deauth frame from AP the net80211 stack
6204 1.45 nonaka * puts the driver into AUTH state. This will fail with this
6205 1.45 nonaka * driver so bring the FSM from RUN to SCAN in this case.
6206 1.1 pooka */
6207 1.69 nonaka if (nstate != IEEE80211_S_INIT) {
6208 1.1 pooka DPRINTF(("Force transition to INIT; MGT=%d\n", arg));
6209 1.45 nonaka /* Always pass arg as -1 since we can't Tx right now. */
6210 1.45 nonaka sc->sc_newstate(ic, IEEE80211_S_INIT, -1);
6211 1.69 nonaka iwm_stop(ifp, 0);
6212 1.69 nonaka iwm_init(ifp);
6213 1.69 nonaka return 0;
6214 1.1 pooka }
6215 1.69 nonaka
6216 1.69 nonaka iwm_stop_device(sc);
6217 1.69 nonaka iwm_init_hw(sc);
6218 1.1 pooka }
6219 1.1 pooka
6220 1.1 pooka switch (nstate) {
6221 1.1 pooka case IEEE80211_S_INIT:
6222 1.1 pooka break;
6223 1.1 pooka
6224 1.1 pooka case IEEE80211_S_SCAN:
6225 1.45 nonaka if (ostate == nstate &&
6226 1.45 nonaka ISSET(sc->sc_flags, IWM_FLAG_SCANNING))
6227 1.65 nonaka return 0;
6228 1.45 nonaka if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN))
6229 1.45 nonaka err = iwm_umac_scan(sc);
6230 1.45 nonaka else
6231 1.45 nonaka err = iwm_lmac_scan(sc);
6232 1.45 nonaka if (err) {
6233 1.69 nonaka DPRINTF(("%s: could not initiate scan: %d\n",
6234 1.69 nonaka DEVNAME(sc), err));
6235 1.65 nonaka return err;
6236 1.1 pooka }
6237 1.45 nonaka SET(sc->sc_flags, IWM_FLAG_SCANNING);
6238 1.1 pooka ic->ic_state = nstate;
6239 1.45 nonaka iwm_led_blink_start(sc);
6240 1.65 nonaka return 0;
6241 1.1 pooka
6242 1.1 pooka case IEEE80211_S_AUTH:
6243 1.45 nonaka err = iwm_auth(sc);
6244 1.45 nonaka if (err) {
6245 1.2 nonaka DPRINTF(("%s: could not move to auth state: %d\n",
6246 1.45 nonaka DEVNAME(sc), err));
6247 1.65 nonaka return err;
6248 1.1 pooka }
6249 1.1 pooka break;
6250 1.1 pooka
6251 1.1 pooka case IEEE80211_S_ASSOC:
6252 1.45 nonaka err = iwm_assoc(sc);
6253 1.45 nonaka if (err) {
6254 1.2 nonaka DPRINTF(("%s: failed to associate: %d\n", DEVNAME(sc),
6255 1.45 nonaka err));
6256 1.65 nonaka return err;
6257 1.1 pooka }
6258 1.1 pooka break;
6259 1.1 pooka
6260 1.45 nonaka case IEEE80211_S_RUN:
6261 1.45 nonaka in = (struct iwm_node *)ic->ic_bss;
6262 1.45 nonaka
6263 1.45 nonaka /* We have now been assigned an associd by the AP. */
6264 1.45 nonaka err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY, 1);
6265 1.45 nonaka if (err) {
6266 1.45 nonaka aprint_error_dev(sc->sc_dev, "failed to update MAC\n");
6267 1.65 nonaka return err;
6268 1.45 nonaka }
6269 1.1 pooka
6270 1.45 nonaka err = iwm_power_update_device(sc);
6271 1.45 nonaka if (err) {
6272 1.45 nonaka aprint_error_dev(sc->sc_dev,
6273 1.45 nonaka "could send power command (error %d)\n", err);
6274 1.65 nonaka return err;
6275 1.45 nonaka }
6276 1.45 nonaka #ifdef notyet
6277 1.45 nonaka /*
6278 1.45 nonaka * Disabled for now. Default beacon filter settings
6279 1.45 nonaka * prevent net80211 from getting ERP and HT protection
6280 1.45 nonaka * updates from beacons.
6281 1.45 nonaka */
6282 1.45 nonaka err = iwm_enable_beacon_filter(sc, in);
6283 1.45 nonaka if (err) {
6284 1.45 nonaka aprint_error_dev(sc->sc_dev,
6285 1.45 nonaka "could not enable beacon filter\n");
6286 1.65 nonaka return err;
6287 1.45 nonaka }
6288 1.45 nonaka #endif
6289 1.45 nonaka err = iwm_power_mac_update_mode(sc, in);
6290 1.45 nonaka if (err) {
6291 1.45 nonaka aprint_error_dev(sc->sc_dev,
6292 1.45 nonaka "could not update MAC power (error %d)\n", err);
6293 1.65 nonaka return err;
6294 1.45 nonaka }
6295 1.1 pooka
6296 1.45 nonaka err = iwm_update_quotas(sc, in);
6297 1.45 nonaka if (err) {
6298 1.45 nonaka aprint_error_dev(sc->sc_dev,
6299 1.45 nonaka "could not update quotas (error %d)\n", err);
6300 1.65 nonaka return err;
6301 1.1 pooka }
6302 1.1 pooka
6303 1.45 nonaka ieee80211_amrr_node_init(&sc->sc_amrr, &in->in_amn);
6304 1.1 pooka
6305 1.45 nonaka /* Start at lowest available bit-rate, AMRR will raise. */
6306 1.45 nonaka in->in_ni.ni_txrate = 0;
6307 1.45 nonaka #ifndef IEEE80211_NO_HT
6308 1.45 nonaka in->in_ni.ni_txmcs = 0;
6309 1.45 nonaka iwm_setrates(in);
6310 1.45 nonaka #endif
6311 1.45 nonaka
6312 1.45 nonaka callout_schedule(&sc->sc_calib_to, mstohz(500));
6313 1.45 nonaka iwm_led_enable(sc);
6314 1.45 nonaka break;
6315 1.1 pooka
6316 1.1 pooka default:
6317 1.2 nonaka break;
6318 1.1 pooka }
6319 1.1 pooka
6320 1.65 nonaka return sc->sc_newstate(ic, nstate, arg);
6321 1.65 nonaka }
6322 1.65 nonaka
6323 1.65 nonaka static void
6324 1.65 nonaka iwm_newstate_cb(struct work *wk, void *v)
6325 1.65 nonaka {
6326 1.65 nonaka struct iwm_softc *sc = v;
6327 1.65 nonaka struct ieee80211com *ic = &sc->sc_ic;
6328 1.65 nonaka struct iwm_newstate_state *iwmns = (struct iwm_newstate_state *)wk;
6329 1.65 nonaka enum ieee80211_state nstate = iwmns->ns_nstate;
6330 1.65 nonaka int generation = iwmns->ns_generation;
6331 1.65 nonaka int arg = iwmns->ns_arg;
6332 1.65 nonaka int s;
6333 1.65 nonaka
6334 1.75 para kmem_intr_free(iwmns, sizeof(*iwmns));
6335 1.65 nonaka
6336 1.65 nonaka s = splnet();
6337 1.65 nonaka
6338 1.65 nonaka DPRINTF(("Prepare to switch state %d->%d\n", ic->ic_state, nstate));
6339 1.65 nonaka if (sc->sc_generation != generation) {
6340 1.65 nonaka DPRINTF(("newstate_cb: someone pulled the plug meanwhile\n"));
6341 1.65 nonaka if (nstate == IEEE80211_S_INIT) {
6342 1.65 nonaka DPRINTF(("newstate_cb: nstate == IEEE80211_S_INIT: "
6343 1.65 nonaka "calling sc_newstate()\n"));
6344 1.65 nonaka (void) sc->sc_newstate(ic, nstate, arg);
6345 1.65 nonaka }
6346 1.65 nonaka } else
6347 1.65 nonaka (void) iwm_do_newstate(ic, nstate, arg);
6348 1.65 nonaka
6349 1.65 nonaka splx(s);
6350 1.1 pooka }
6351 1.1 pooka
6352 1.4 nonaka static int
6353 1.1 pooka iwm_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
6354 1.1 pooka {
6355 1.1 pooka struct iwm_newstate_state *iwmns;
6356 1.1 pooka struct ifnet *ifp = IC2IFP(ic);
6357 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
6358 1.1 pooka
6359 1.1 pooka callout_stop(&sc->sc_calib_to);
6360 1.1 pooka
6361 1.5 nonaka iwmns = kmem_intr_alloc(sizeof(*iwmns), KM_NOSLEEP);
6362 1.1 pooka if (!iwmns) {
6363 1.2 nonaka DPRINTF(("%s: allocating state cb mem failed\n", DEVNAME(sc)));
6364 1.1 pooka return ENOMEM;
6365 1.1 pooka }
6366 1.1 pooka
6367 1.1 pooka iwmns->ns_nstate = nstate;
6368 1.1 pooka iwmns->ns_arg = arg;
6369 1.1 pooka iwmns->ns_generation = sc->sc_generation;
6370 1.1 pooka
6371 1.1 pooka workqueue_enqueue(sc->sc_nswq, &iwmns->ns_wk, NULL);
6372 1.1 pooka
6373 1.1 pooka return 0;
6374 1.1 pooka }
6375 1.1 pooka
6376 1.4 nonaka static void
6377 1.50 nonaka iwm_endscan(struct iwm_softc *sc)
6378 1.1 pooka {
6379 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
6380 1.61 nonaka int s;
6381 1.1 pooka
6382 1.61 nonaka DPRINTF(("%s: scan ended\n", DEVNAME(sc)));
6383 1.1 pooka
6384 1.61 nonaka s = splnet();
6385 1.61 nonaka if (ic->ic_state == IEEE80211_S_SCAN)
6386 1.61 nonaka ieee80211_end_scan(ic);
6387 1.61 nonaka splx(s);
6388 1.45 nonaka }
6389 1.45 nonaka
6390 1.45 nonaka /*
6391 1.45 nonaka * Aging and idle timeouts for the different possible scenarios
6392 1.45 nonaka * in default configuration
6393 1.45 nonaka */
6394 1.45 nonaka static const uint32_t
6395 1.45 nonaka iwm_sf_full_timeout_def[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = {
6396 1.45 nonaka {
6397 1.45 nonaka htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER_DEF),
6398 1.45 nonaka htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER_DEF)
6399 1.45 nonaka },
6400 1.45 nonaka {
6401 1.45 nonaka htole32(IWM_SF_AGG_UNICAST_AGING_TIMER_DEF),
6402 1.45 nonaka htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER_DEF)
6403 1.45 nonaka },
6404 1.45 nonaka {
6405 1.45 nonaka htole32(IWM_SF_MCAST_AGING_TIMER_DEF),
6406 1.45 nonaka htole32(IWM_SF_MCAST_IDLE_TIMER_DEF)
6407 1.45 nonaka },
6408 1.45 nonaka {
6409 1.45 nonaka htole32(IWM_SF_BA_AGING_TIMER_DEF),
6410 1.45 nonaka htole32(IWM_SF_BA_IDLE_TIMER_DEF)
6411 1.45 nonaka },
6412 1.45 nonaka {
6413 1.45 nonaka htole32(IWM_SF_TX_RE_AGING_TIMER_DEF),
6414 1.45 nonaka htole32(IWM_SF_TX_RE_IDLE_TIMER_DEF)
6415 1.45 nonaka },
6416 1.45 nonaka };
6417 1.45 nonaka
6418 1.45 nonaka /*
6419 1.45 nonaka * Aging and idle timeouts for the different possible scenarios
6420 1.45 nonaka * in single BSS MAC configuration.
6421 1.45 nonaka */
6422 1.45 nonaka static const uint32_t
6423 1.45 nonaka iwm_sf_full_timeout[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = {
6424 1.45 nonaka {
6425 1.45 nonaka htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER),
6426 1.45 nonaka htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER)
6427 1.45 nonaka },
6428 1.45 nonaka {
6429 1.45 nonaka htole32(IWM_SF_AGG_UNICAST_AGING_TIMER),
6430 1.45 nonaka htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER)
6431 1.45 nonaka },
6432 1.45 nonaka {
6433 1.45 nonaka htole32(IWM_SF_MCAST_AGING_TIMER),
6434 1.45 nonaka htole32(IWM_SF_MCAST_IDLE_TIMER)
6435 1.45 nonaka },
6436 1.45 nonaka {
6437 1.45 nonaka htole32(IWM_SF_BA_AGING_TIMER),
6438 1.45 nonaka htole32(IWM_SF_BA_IDLE_TIMER)
6439 1.45 nonaka },
6440 1.45 nonaka {
6441 1.45 nonaka htole32(IWM_SF_TX_RE_AGING_TIMER),
6442 1.45 nonaka htole32(IWM_SF_TX_RE_IDLE_TIMER)
6443 1.45 nonaka },
6444 1.45 nonaka };
6445 1.45 nonaka
6446 1.45 nonaka static void
6447 1.45 nonaka iwm_fill_sf_command(struct iwm_softc *sc, struct iwm_sf_cfg_cmd *sf_cmd,
6448 1.45 nonaka struct ieee80211_node *ni)
6449 1.45 nonaka {
6450 1.45 nonaka int i, j, watermark;
6451 1.45 nonaka
6452 1.45 nonaka sf_cmd->watermark[IWM_SF_LONG_DELAY_ON] = htole32(IWM_SF_W_MARK_SCAN);
6453 1.45 nonaka
6454 1.45 nonaka /*
6455 1.45 nonaka * If we are in association flow - check antenna configuration
6456 1.45 nonaka * capabilities of the AP station, and choose the watermark accordingly.
6457 1.45 nonaka */
6458 1.45 nonaka if (ni) {
6459 1.45 nonaka #ifndef IEEE80211_NO_HT
6460 1.45 nonaka if (ni->ni_flags & IEEE80211_NODE_HT) {
6461 1.45 nonaka #ifdef notyet
6462 1.45 nonaka if (ni->ni_rxmcs[2] != 0)
6463 1.45 nonaka watermark = IWM_SF_W_MARK_MIMO3;
6464 1.45 nonaka else if (ni->ni_rxmcs[1] != 0)
6465 1.45 nonaka watermark = IWM_SF_W_MARK_MIMO2;
6466 1.45 nonaka else
6467 1.45 nonaka #endif
6468 1.45 nonaka watermark = IWM_SF_W_MARK_SISO;
6469 1.45 nonaka } else
6470 1.45 nonaka #endif
6471 1.45 nonaka watermark = IWM_SF_W_MARK_LEGACY;
6472 1.45 nonaka /* default watermark value for unassociated mode. */
6473 1.45 nonaka } else {
6474 1.45 nonaka watermark = IWM_SF_W_MARK_MIMO2;
6475 1.45 nonaka }
6476 1.45 nonaka sf_cmd->watermark[IWM_SF_FULL_ON] = htole32(watermark);
6477 1.45 nonaka
6478 1.45 nonaka for (i = 0; i < IWM_SF_NUM_SCENARIO; i++) {
6479 1.45 nonaka for (j = 0; j < IWM_SF_NUM_TIMEOUT_TYPES; j++) {
6480 1.45 nonaka sf_cmd->long_delay_timeouts[i][j] =
6481 1.45 nonaka htole32(IWM_SF_LONG_DELAY_AGING_TIMER);
6482 1.1 pooka }
6483 1.45 nonaka }
6484 1.45 nonaka
6485 1.45 nonaka if (ni) {
6486 1.45 nonaka memcpy(sf_cmd->full_on_timeouts, iwm_sf_full_timeout,
6487 1.45 nonaka sizeof(iwm_sf_full_timeout));
6488 1.1 pooka } else {
6489 1.45 nonaka memcpy(sf_cmd->full_on_timeouts, iwm_sf_full_timeout_def,
6490 1.45 nonaka sizeof(iwm_sf_full_timeout_def));
6491 1.45 nonaka }
6492 1.45 nonaka }
6493 1.45 nonaka
6494 1.45 nonaka static int
6495 1.45 nonaka iwm_sf_config(struct iwm_softc *sc, int new_state)
6496 1.45 nonaka {
6497 1.45 nonaka struct ieee80211com *ic = &sc->sc_ic;
6498 1.45 nonaka struct iwm_sf_cfg_cmd sf_cmd = {
6499 1.45 nonaka .state = htole32(IWM_SF_FULL_ON),
6500 1.45 nonaka };
6501 1.45 nonaka
6502 1.45 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000)
6503 1.45 nonaka sf_cmd.state |= htole32(IWM_SF_CFG_DUMMY_NOTIF_OFF);
6504 1.45 nonaka
6505 1.45 nonaka switch (new_state) {
6506 1.45 nonaka case IWM_SF_UNINIT:
6507 1.45 nonaka case IWM_SF_INIT_OFF:
6508 1.45 nonaka iwm_fill_sf_command(sc, &sf_cmd, NULL);
6509 1.45 nonaka break;
6510 1.45 nonaka case IWM_SF_FULL_ON:
6511 1.45 nonaka iwm_fill_sf_command(sc, &sf_cmd, ic->ic_bss);
6512 1.45 nonaka break;
6513 1.45 nonaka default:
6514 1.45 nonaka return EINVAL;
6515 1.1 pooka }
6516 1.1 pooka
6517 1.45 nonaka return iwm_send_cmd_pdu(sc, IWM_REPLY_SF_CFG_CMD, IWM_CMD_ASYNC,
6518 1.45 nonaka sizeof(sf_cmd), &sf_cmd);
6519 1.45 nonaka }
6520 1.45 nonaka
6521 1.45 nonaka static int
6522 1.45 nonaka iwm_send_bt_init_conf(struct iwm_softc *sc)
6523 1.45 nonaka {
6524 1.45 nonaka struct iwm_bt_coex_cmd bt_cmd;
6525 1.45 nonaka
6526 1.45 nonaka bt_cmd.mode = htole32(IWM_BT_COEX_WIFI);
6527 1.45 nonaka bt_cmd.enabled_modules = htole32(IWM_BT_COEX_HIGH_BAND_RET);
6528 1.45 nonaka
6529 1.45 nonaka return iwm_send_cmd_pdu(sc, IWM_BT_CONFIG, 0, sizeof(bt_cmd), &bt_cmd);
6530 1.45 nonaka }
6531 1.45 nonaka
6532 1.60 nonaka static bool
6533 1.60 nonaka iwm_is_lar_supported(struct iwm_softc *sc)
6534 1.60 nonaka {
6535 1.60 nonaka bool nvm_lar = sc->sc_nvm.lar_enabled;
6536 1.60 nonaka bool tlv_lar = isset(sc->sc_enabled_capa,
6537 1.60 nonaka IWM_UCODE_TLV_CAPA_LAR_SUPPORT);
6538 1.60 nonaka
6539 1.60 nonaka if (iwm_lar_disable)
6540 1.60 nonaka return false;
6541 1.60 nonaka
6542 1.60 nonaka /*
6543 1.60 nonaka * Enable LAR only if it is supported by the FW (TLV) &&
6544 1.60 nonaka * enabled in the NVM
6545 1.60 nonaka */
6546 1.60 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000)
6547 1.60 nonaka return nvm_lar && tlv_lar;
6548 1.60 nonaka else
6549 1.60 nonaka return tlv_lar;
6550 1.60 nonaka }
6551 1.60 nonaka
6552 1.45 nonaka static int
6553 1.45 nonaka iwm_send_update_mcc_cmd(struct iwm_softc *sc, const char *alpha2)
6554 1.45 nonaka {
6555 1.45 nonaka struct iwm_mcc_update_cmd mcc_cmd;
6556 1.45 nonaka struct iwm_host_cmd hcmd = {
6557 1.45 nonaka .id = IWM_MCC_UPDATE_CMD,
6558 1.45 nonaka .flags = IWM_CMD_WANT_SKB,
6559 1.45 nonaka .data = { &mcc_cmd },
6560 1.45 nonaka };
6561 1.60 nonaka int err;
6562 1.45 nonaka int resp_v2 = isset(sc->sc_enabled_capa,
6563 1.45 nonaka IWM_UCODE_TLV_CAPA_LAR_SUPPORT_V2);
6564 1.60 nonaka
6565 1.60 nonaka if (!iwm_is_lar_supported(sc)) {
6566 1.60 nonaka DPRINTF(("%s: no LAR support\n", __func__));
6567 1.60 nonaka return 0;
6568 1.60 nonaka }
6569 1.45 nonaka
6570 1.45 nonaka memset(&mcc_cmd, 0, sizeof(mcc_cmd));
6571 1.45 nonaka mcc_cmd.mcc = htole16(alpha2[0] << 8 | alpha2[1]);
6572 1.71 nonaka if (isset(sc->sc_ucode_api, IWM_UCODE_TLV_API_WIFI_MCC_UPDATE) ||
6573 1.45 nonaka isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_LAR_MULTI_MCC))
6574 1.45 nonaka mcc_cmd.source_id = IWM_MCC_SOURCE_GET_CURRENT;
6575 1.45 nonaka else
6576 1.45 nonaka mcc_cmd.source_id = IWM_MCC_SOURCE_OLD_FW;
6577 1.45 nonaka
6578 1.45 nonaka if (resp_v2)
6579 1.45 nonaka hcmd.len[0] = sizeof(struct iwm_mcc_update_cmd);
6580 1.45 nonaka else
6581 1.45 nonaka hcmd.len[0] = sizeof(struct iwm_mcc_update_cmd_v1);
6582 1.45 nonaka
6583 1.45 nonaka err = iwm_send_cmd(sc, &hcmd);
6584 1.45 nonaka if (err)
6585 1.45 nonaka return err;
6586 1.45 nonaka
6587 1.45 nonaka iwm_free_resp(sc, &hcmd);
6588 1.45 nonaka
6589 1.45 nonaka return 0;
6590 1.45 nonaka }
6591 1.45 nonaka
6592 1.45 nonaka static void
6593 1.45 nonaka iwm_tt_tx_backoff(struct iwm_softc *sc, uint32_t backoff)
6594 1.45 nonaka {
6595 1.45 nonaka struct iwm_host_cmd cmd = {
6596 1.45 nonaka .id = IWM_REPLY_THERMAL_MNG_BACKOFF,
6597 1.45 nonaka .len = { sizeof(uint32_t), },
6598 1.45 nonaka .data = { &backoff, },
6599 1.45 nonaka };
6600 1.45 nonaka
6601 1.45 nonaka iwm_send_cmd(sc, &cmd);
6602 1.1 pooka }
6603 1.1 pooka
6604 1.4 nonaka static int
6605 1.1 pooka iwm_init_hw(struct iwm_softc *sc)
6606 1.1 pooka {
6607 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
6608 1.45 nonaka int err, i, ac;
6609 1.1 pooka
6610 1.45 nonaka err = iwm_start_hw(sc);
6611 1.45 nonaka if (err) {
6612 1.45 nonaka aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
6613 1.45 nonaka return err;
6614 1.45 nonaka }
6615 1.1 pooka
6616 1.45 nonaka err = iwm_run_init_mvm_ucode(sc, 0);
6617 1.45 nonaka if (err)
6618 1.45 nonaka return err;
6619 1.1 pooka
6620 1.45 nonaka /* Should stop and start HW since INIT image just loaded. */
6621 1.1 pooka iwm_stop_device(sc);
6622 1.45 nonaka err = iwm_start_hw(sc);
6623 1.45 nonaka if (err) {
6624 1.3 nonaka aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
6625 1.45 nonaka return err;
6626 1.2 nonaka }
6627 1.1 pooka
6628 1.45 nonaka /* Restart, this time with the regular firmware */
6629 1.45 nonaka err = iwm_load_ucode_wait_alive(sc, IWM_UCODE_TYPE_REGULAR);
6630 1.45 nonaka if (err) {
6631 1.61 nonaka aprint_error_dev(sc->sc_dev,
6632 1.61 nonaka "could not load firmware (error %d)\n", err);
6633 1.45 nonaka goto err;
6634 1.45 nonaka }
6635 1.45 nonaka
6636 1.45 nonaka err = iwm_send_bt_init_conf(sc);
6637 1.45 nonaka if (err) {
6638 1.45 nonaka aprint_error_dev(sc->sc_dev,
6639 1.45 nonaka "could not init bt coex (error %d)\n", err);
6640 1.45 nonaka goto err;
6641 1.1 pooka }
6642 1.1 pooka
6643 1.45 nonaka err = iwm_send_tx_ant_cfg(sc, iwm_fw_valid_tx_ant(sc));
6644 1.45 nonaka if (err) {
6645 1.45 nonaka aprint_error_dev(sc->sc_dev,
6646 1.45 nonaka "could not init tx ant config (error %d)\n", err);
6647 1.45 nonaka goto err;
6648 1.45 nonaka }
6649 1.1 pooka
6650 1.8 nonaka /* Send phy db control command and then phy db calibration*/
6651 1.45 nonaka err = iwm_send_phy_db_data(sc);
6652 1.45 nonaka if (err) {
6653 1.45 nonaka aprint_error_dev(sc->sc_dev,
6654 1.45 nonaka "could not init phy db (error %d)\n", err);
6655 1.45 nonaka goto err;
6656 1.45 nonaka }
6657 1.1 pooka
6658 1.45 nonaka err = iwm_send_phy_cfg_cmd(sc);
6659 1.45 nonaka if (err) {
6660 1.45 nonaka aprint_error_dev(sc->sc_dev,
6661 1.45 nonaka "could not send phy config (error %d)\n", err);
6662 1.45 nonaka goto err;
6663 1.45 nonaka }
6664 1.1 pooka
6665 1.1 pooka /* Add auxiliary station for scanning */
6666 1.45 nonaka err = iwm_add_aux_sta(sc);
6667 1.45 nonaka if (err) {
6668 1.45 nonaka aprint_error_dev(sc->sc_dev,
6669 1.45 nonaka "could not add aux station (error %d)\n", err);
6670 1.45 nonaka goto err;
6671 1.45 nonaka }
6672 1.1 pooka
6673 1.1 pooka for (i = 0; i < IWM_NUM_PHY_CTX; i++) {
6674 1.1 pooka /*
6675 1.1 pooka * The channel used here isn't relevant as it's
6676 1.1 pooka * going to be overwritten in the other flows.
6677 1.1 pooka * For now use the first channel we have.
6678 1.1 pooka */
6679 1.45 nonaka sc->sc_phyctxt[i].channel = &ic->ic_channels[1];
6680 1.45 nonaka err = iwm_phy_ctxt_cmd(sc, &sc->sc_phyctxt[i], 1, 1,
6681 1.45 nonaka IWM_FW_CTXT_ACTION_ADD, 0);
6682 1.45 nonaka if (err) {
6683 1.45 nonaka aprint_error_dev(sc->sc_dev,
6684 1.45 nonaka "could not add phy context %d (error %d)\n",
6685 1.45 nonaka i, err);
6686 1.45 nonaka goto err;
6687 1.45 nonaka }
6688 1.45 nonaka }
6689 1.45 nonaka
6690 1.45 nonaka /* Initialize tx backoffs to the minimum. */
6691 1.45 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000)
6692 1.45 nonaka iwm_tt_tx_backoff(sc, 0);
6693 1.45 nonaka
6694 1.45 nonaka err = iwm_power_update_device(sc);
6695 1.45 nonaka if (err) {
6696 1.45 nonaka aprint_error_dev(sc->sc_dev,
6697 1.45 nonaka "could send power command (error %d)\n", err);
6698 1.45 nonaka goto err;
6699 1.45 nonaka }
6700 1.45 nonaka
6701 1.61 nonaka err = iwm_send_update_mcc_cmd(sc, iwm_default_mcc);
6702 1.60 nonaka if (err) {
6703 1.60 nonaka aprint_error_dev(sc->sc_dev,
6704 1.60 nonaka "could not init LAR (error %d)\n", err);
6705 1.60 nonaka goto err;
6706 1.45 nonaka }
6707 1.45 nonaka
6708 1.45 nonaka if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) {
6709 1.45 nonaka err = iwm_config_umac_scan(sc);
6710 1.45 nonaka if (err) {
6711 1.45 nonaka aprint_error_dev(sc->sc_dev,
6712 1.45 nonaka "could not configure scan (error %d)\n", err);
6713 1.45 nonaka goto err;
6714 1.45 nonaka }
6715 1.45 nonaka }
6716 1.45 nonaka
6717 1.45 nonaka for (ac = 0; ac < WME_NUM_AC; ac++) {
6718 1.45 nonaka err = iwm_enable_txq(sc, IWM_STATION_ID, ac,
6719 1.45 nonaka iwm_ac_to_tx_fifo[ac]);
6720 1.45 nonaka if (err) {
6721 1.45 nonaka aprint_error_dev(sc->sc_dev,
6722 1.45 nonaka "could not enable Tx queue %d (error %d)\n",
6723 1.45 nonaka i, err);
6724 1.45 nonaka goto err;
6725 1.45 nonaka }
6726 1.1 pooka }
6727 1.1 pooka
6728 1.45 nonaka err = iwm_disable_beacon_filter(sc);
6729 1.45 nonaka if (err) {
6730 1.45 nonaka aprint_error_dev(sc->sc_dev,
6731 1.45 nonaka "could not disable beacon filter (error %d)\n", err);
6732 1.45 nonaka goto err;
6733 1.1 pooka }
6734 1.1 pooka
6735 1.1 pooka return 0;
6736 1.1 pooka
6737 1.45 nonaka err:
6738 1.1 pooka iwm_stop_device(sc);
6739 1.45 nonaka return err;
6740 1.1 pooka }
6741 1.1 pooka
6742 1.11 nonaka /* Allow multicast from our BSSID. */
6743 1.11 nonaka static int
6744 1.11 nonaka iwm_allow_mcast(struct iwm_softc *sc)
6745 1.11 nonaka {
6746 1.11 nonaka struct ieee80211com *ic = &sc->sc_ic;
6747 1.11 nonaka struct ieee80211_node *ni = ic->ic_bss;
6748 1.11 nonaka struct iwm_mcast_filter_cmd *cmd;
6749 1.11 nonaka size_t size;
6750 1.45 nonaka int err;
6751 1.11 nonaka
6752 1.11 nonaka size = roundup(sizeof(*cmd), 4);
6753 1.11 nonaka cmd = kmem_intr_zalloc(size, KM_NOSLEEP);
6754 1.11 nonaka if (cmd == NULL)
6755 1.11 nonaka return ENOMEM;
6756 1.11 nonaka cmd->filter_own = 1;
6757 1.11 nonaka cmd->port_id = 0;
6758 1.11 nonaka cmd->count = 0;
6759 1.11 nonaka cmd->pass_all = 1;
6760 1.11 nonaka IEEE80211_ADDR_COPY(cmd->bssid, ni->ni_bssid);
6761 1.11 nonaka
6762 1.45 nonaka err = iwm_send_cmd_pdu(sc, IWM_MCAST_FILTER_CMD, 0, size, cmd);
6763 1.11 nonaka kmem_intr_free(cmd, size);
6764 1.45 nonaka return err;
6765 1.11 nonaka }
6766 1.11 nonaka
6767 1.4 nonaka static int
6768 1.1 pooka iwm_init(struct ifnet *ifp)
6769 1.1 pooka {
6770 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
6771 1.45 nonaka int err;
6772 1.1 pooka
6773 1.45 nonaka if (ISSET(sc->sc_flags, IWM_FLAG_HW_INITED))
6774 1.1 pooka return 0;
6775 1.45 nonaka
6776 1.1 pooka sc->sc_generation++;
6777 1.1 pooka sc->sc_flags &= ~IWM_FLAG_STOPPED;
6778 1.1 pooka
6779 1.45 nonaka err = iwm_init_hw(sc);
6780 1.45 nonaka if (err) {
6781 1.1 pooka iwm_stop(ifp, 1);
6782 1.45 nonaka return err;
6783 1.1 pooka }
6784 1.1 pooka
6785 1.1 pooka ifp->if_flags &= ~IFF_OACTIVE;
6786 1.1 pooka ifp->if_flags |= IFF_RUNNING;
6787 1.1 pooka
6788 1.1 pooka ieee80211_begin_scan(&sc->sc_ic, 0);
6789 1.45 nonaka SET(sc->sc_flags, IWM_FLAG_HW_INITED);
6790 1.1 pooka
6791 1.1 pooka return 0;
6792 1.1 pooka }
6793 1.1 pooka
6794 1.4 nonaka static void
6795 1.1 pooka iwm_start(struct ifnet *ifp)
6796 1.1 pooka {
6797 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
6798 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
6799 1.1 pooka struct ieee80211_node *ni;
6800 1.8 nonaka struct ether_header *eh;
6801 1.1 pooka struct mbuf *m;
6802 1.1 pooka int ac;
6803 1.1 pooka
6804 1.1 pooka if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
6805 1.1 pooka return;
6806 1.1 pooka
6807 1.1 pooka for (;;) {
6808 1.1 pooka /* why isn't this done per-queue? */
6809 1.1 pooka if (sc->qfullmsk != 0) {
6810 1.1 pooka ifp->if_flags |= IFF_OACTIVE;
6811 1.1 pooka break;
6812 1.1 pooka }
6813 1.1 pooka
6814 1.1 pooka /* need to send management frames even if we're not RUNning */
6815 1.1 pooka IF_DEQUEUE(&ic->ic_mgtq, m);
6816 1.1 pooka if (m) {
6817 1.41 ozaki ni = M_GETCTX(m, struct ieee80211_node *);
6818 1.50 nonaka M_CLEARCTX(m);
6819 1.45 nonaka ac = WME_AC_BE;
6820 1.1 pooka goto sendit;
6821 1.1 pooka }
6822 1.1 pooka if (ic->ic_state != IEEE80211_S_RUN) {
6823 1.1 pooka break;
6824 1.1 pooka }
6825 1.1 pooka
6826 1.1 pooka IFQ_DEQUEUE(&ifp->if_snd, m);
6827 1.50 nonaka if (m == NULL)
6828 1.1 pooka break;
6829 1.50 nonaka
6830 1.8 nonaka if (m->m_len < sizeof (*eh) &&
6831 1.8 nonaka (m = m_pullup(m, sizeof (*eh))) == NULL) {
6832 1.84 thorpej if_statinc(ifp, if_oerrors);
6833 1.8 nonaka continue;
6834 1.8 nonaka }
6835 1.1 pooka
6836 1.1 pooka eh = mtod(m, struct ether_header *);
6837 1.1 pooka ni = ieee80211_find_txnode(ic, eh->ether_dhost);
6838 1.1 pooka if (ni == NULL) {
6839 1.1 pooka m_freem(m);
6840 1.84 thorpej if_statinc(ifp, if_oerrors);
6841 1.1 pooka continue;
6842 1.1 pooka }
6843 1.50 nonaka
6844 1.1 pooka /* classify mbuf so we can find which tx ring to use */
6845 1.1 pooka if (ieee80211_classify(ic, m, ni) != 0) {
6846 1.1 pooka m_freem(m);
6847 1.1 pooka ieee80211_free_node(ni);
6848 1.84 thorpej if_statinc(ifp, if_oerrors);
6849 1.1 pooka continue;
6850 1.1 pooka }
6851 1.1 pooka
6852 1.1 pooka /* No QoS encapsulation for EAPOL frames. */
6853 1.1 pooka ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
6854 1.1 pooka M_WME_GETAC(m) : WME_AC_BE;
6855 1.1 pooka
6856 1.83 msaitoh bpf_mtap(ifp, m, BPF_D_OUT);
6857 1.48 nonaka
6858 1.1 pooka if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
6859 1.1 pooka ieee80211_free_node(ni);
6860 1.84 thorpej if_statinc(ifp, if_oerrors);
6861 1.1 pooka continue;
6862 1.1 pooka }
6863 1.1 pooka
6864 1.1 pooka sendit:
6865 1.83 msaitoh bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT);
6866 1.48 nonaka
6867 1.1 pooka if (iwm_tx(sc, m, ni, ac) != 0) {
6868 1.1 pooka ieee80211_free_node(ni);
6869 1.84 thorpej if_statinc(ifp, if_oerrors);
6870 1.1 pooka continue;
6871 1.1 pooka }
6872 1.1 pooka
6873 1.1 pooka if (ifp->if_flags & IFF_UP) {
6874 1.1 pooka sc->sc_tx_timer = 15;
6875 1.1 pooka ifp->if_timer = 1;
6876 1.1 pooka }
6877 1.1 pooka }
6878 1.1 pooka }
6879 1.1 pooka
6880 1.4 nonaka static void
6881 1.1 pooka iwm_stop(struct ifnet *ifp, int disable)
6882 1.1 pooka {
6883 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
6884 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
6885 1.45 nonaka struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
6886 1.1 pooka
6887 1.1 pooka sc->sc_flags &= ~IWM_FLAG_HW_INITED;
6888 1.1 pooka sc->sc_flags |= IWM_FLAG_STOPPED;
6889 1.1 pooka sc->sc_generation++;
6890 1.1 pooka ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
6891 1.1 pooka
6892 1.45 nonaka if (in)
6893 1.45 nonaka in->in_phyctxt = NULL;
6894 1.45 nonaka
6895 1.1 pooka if (ic->ic_state != IEEE80211_S_INIT)
6896 1.1 pooka ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
6897 1.1 pooka
6898 1.26 nonaka callout_stop(&sc->sc_calib_to);
6899 1.45 nonaka iwm_led_blink_stop(sc);
6900 1.1 pooka ifp->if_timer = sc->sc_tx_timer = 0;
6901 1.1 pooka iwm_stop_device(sc);
6902 1.1 pooka }
6903 1.1 pooka
6904 1.4 nonaka static void
6905 1.1 pooka iwm_watchdog(struct ifnet *ifp)
6906 1.1 pooka {
6907 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
6908 1.1 pooka
6909 1.1 pooka ifp->if_timer = 0;
6910 1.1 pooka if (sc->sc_tx_timer > 0) {
6911 1.1 pooka if (--sc->sc_tx_timer == 0) {
6912 1.5 nonaka aprint_error_dev(sc->sc_dev, "device timeout\n");
6913 1.2 nonaka #ifdef IWM_DEBUG
6914 1.1 pooka iwm_nic_error(sc);
6915 1.2 nonaka #endif
6916 1.1 pooka ifp->if_flags &= ~IFF_UP;
6917 1.1 pooka iwm_stop(ifp, 1);
6918 1.84 thorpej if_statinc(ifp, if_oerrors);
6919 1.1 pooka return;
6920 1.1 pooka }
6921 1.1 pooka ifp->if_timer = 1;
6922 1.1 pooka }
6923 1.1 pooka
6924 1.1 pooka ieee80211_watchdog(&sc->sc_ic);
6925 1.1 pooka }
6926 1.1 pooka
6927 1.4 nonaka static int
6928 1.1 pooka iwm_ioctl(struct ifnet *ifp, u_long cmd, void *data)
6929 1.1 pooka {
6930 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
6931 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
6932 1.1 pooka const struct sockaddr *sa;
6933 1.45 nonaka int s, err = 0;
6934 1.1 pooka
6935 1.1 pooka s = splnet();
6936 1.1 pooka
6937 1.1 pooka switch (cmd) {
6938 1.1 pooka case SIOCSIFADDR:
6939 1.1 pooka ifp->if_flags |= IFF_UP;
6940 1.1 pooka /* FALLTHROUGH */
6941 1.1 pooka case SIOCSIFFLAGS:
6942 1.45 nonaka err = ifioctl_common(ifp, cmd, data);
6943 1.45 nonaka if (err)
6944 1.1 pooka break;
6945 1.1 pooka if (ifp->if_flags & IFF_UP) {
6946 1.1 pooka if (!(ifp->if_flags & IFF_RUNNING)) {
6947 1.45 nonaka err = iwm_init(ifp);
6948 1.45 nonaka if (err)
6949 1.1 pooka ifp->if_flags &= ~IFF_UP;
6950 1.1 pooka }
6951 1.1 pooka } else {
6952 1.1 pooka if (ifp->if_flags & IFF_RUNNING)
6953 1.1 pooka iwm_stop(ifp, 1);
6954 1.1 pooka }
6955 1.1 pooka break;
6956 1.1 pooka
6957 1.1 pooka case SIOCADDMULTI:
6958 1.1 pooka case SIOCDELMULTI:
6959 1.1 pooka sa = ifreq_getaddr(SIOCADDMULTI, (struct ifreq *)data);
6960 1.45 nonaka err = (cmd == SIOCADDMULTI) ?
6961 1.1 pooka ether_addmulti(sa, &sc->sc_ec) :
6962 1.1 pooka ether_delmulti(sa, &sc->sc_ec);
6963 1.45 nonaka if (err == ENETRESET)
6964 1.45 nonaka err = 0;
6965 1.1 pooka break;
6966 1.1 pooka
6967 1.1 pooka default:
6968 1.45 nonaka err = ieee80211_ioctl(ic, cmd, data);
6969 1.36 nonaka break;
6970 1.1 pooka }
6971 1.1 pooka
6972 1.45 nonaka if (err == ENETRESET) {
6973 1.45 nonaka err = 0;
6974 1.1 pooka if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
6975 1.1 pooka (IFF_UP | IFF_RUNNING)) {
6976 1.1 pooka iwm_stop(ifp, 0);
6977 1.45 nonaka err = iwm_init(ifp);
6978 1.1 pooka }
6979 1.1 pooka }
6980 1.1 pooka
6981 1.1 pooka splx(s);
6982 1.45 nonaka return err;
6983 1.1 pooka }
6984 1.1 pooka
6985 1.1 pooka /*
6986 1.1 pooka * Note: This structure is read from the device with IO accesses,
6987 1.1 pooka * and the reading already does the endian conversion. As it is
6988 1.1 pooka * read with uint32_t-sized accesses, any members with a different size
6989 1.1 pooka * need to be ordered correctly though!
6990 1.1 pooka */
6991 1.1 pooka struct iwm_error_event_table {
6992 1.1 pooka uint32_t valid; /* (nonzero) valid, (0) log is empty */
6993 1.1 pooka uint32_t error_id; /* type of error */
6994 1.45 nonaka uint32_t trm_hw_status0; /* TRM HW status */
6995 1.45 nonaka uint32_t trm_hw_status1; /* TRM HW status */
6996 1.1 pooka uint32_t blink2; /* branch link */
6997 1.1 pooka uint32_t ilink1; /* interrupt link */
6998 1.1 pooka uint32_t ilink2; /* interrupt link */
6999 1.1 pooka uint32_t data1; /* error-specific data */
7000 1.1 pooka uint32_t data2; /* error-specific data */
7001 1.1 pooka uint32_t data3; /* error-specific data */
7002 1.1 pooka uint32_t bcon_time; /* beacon timer */
7003 1.1 pooka uint32_t tsf_low; /* network timestamp function timer */
7004 1.1 pooka uint32_t tsf_hi; /* network timestamp function timer */
7005 1.1 pooka uint32_t gp1; /* GP1 timer register */
7006 1.1 pooka uint32_t gp2; /* GP2 timer register */
7007 1.45 nonaka uint32_t fw_rev_type; /* firmware revision type */
7008 1.45 nonaka uint32_t major; /* uCode version major */
7009 1.45 nonaka uint32_t minor; /* uCode version minor */
7010 1.1 pooka uint32_t hw_ver; /* HW Silicon version */
7011 1.1 pooka uint32_t brd_ver; /* HW board version */
7012 1.1 pooka uint32_t log_pc; /* log program counter */
7013 1.1 pooka uint32_t frame_ptr; /* frame pointer */
7014 1.1 pooka uint32_t stack_ptr; /* stack pointer */
7015 1.1 pooka uint32_t hcmd; /* last host command header */
7016 1.1 pooka uint32_t isr0; /* isr status register LMPM_NIC_ISR0:
7017 1.1 pooka * rxtx_flag */
7018 1.1 pooka uint32_t isr1; /* isr status register LMPM_NIC_ISR1:
7019 1.1 pooka * host_flag */
7020 1.1 pooka uint32_t isr2; /* isr status register LMPM_NIC_ISR2:
7021 1.1 pooka * enc_flag */
7022 1.1 pooka uint32_t isr3; /* isr status register LMPM_NIC_ISR3:
7023 1.1 pooka * time_flag */
7024 1.1 pooka uint32_t isr4; /* isr status register LMPM_NIC_ISR4:
7025 1.1 pooka * wico interrupt */
7026 1.45 nonaka uint32_t last_cmd_id; /* last HCMD id handled by the firmware */
7027 1.1 pooka uint32_t wait_event; /* wait event() caller address */
7028 1.1 pooka uint32_t l2p_control; /* L2pControlField */
7029 1.1 pooka uint32_t l2p_duration; /* L2pDurationField */
7030 1.1 pooka uint32_t l2p_mhvalid; /* L2pMhValidBits */
7031 1.1 pooka uint32_t l2p_addr_match; /* L2pAddrMatchStat */
7032 1.1 pooka uint32_t lmpm_pmg_sel; /* indicate which clocks are turned on
7033 1.1 pooka * (LMPM_PMG_SEL) */
7034 1.1 pooka uint32_t u_timestamp; /* indicate when the date and time of the
7035 1.1 pooka * compilation */
7036 1.1 pooka uint32_t flow_handler; /* FH read/write pointers, RX credit */
7037 1.45 nonaka } __packed /* LOG_ERROR_TABLE_API_S_VER_3 */;
7038 1.45 nonaka
7039 1.45 nonaka /*
7040 1.45 nonaka * UMAC error struct - relevant starting from family 8000 chip.
7041 1.45 nonaka * Note: This structure is read from the device with IO accesses,
7042 1.45 nonaka * and the reading already does the endian conversion. As it is
7043 1.45 nonaka * read with u32-sized accesses, any members with a different size
7044 1.45 nonaka * need to be ordered correctly though!
7045 1.45 nonaka */
7046 1.45 nonaka struct iwm_umac_error_event_table {
7047 1.45 nonaka uint32_t valid; /* (nonzero) valid, (0) log is empty */
7048 1.45 nonaka uint32_t error_id; /* type of error */
7049 1.45 nonaka uint32_t blink1; /* branch link */
7050 1.45 nonaka uint32_t blink2; /* branch link */
7051 1.45 nonaka uint32_t ilink1; /* interrupt link */
7052 1.45 nonaka uint32_t ilink2; /* interrupt link */
7053 1.45 nonaka uint32_t data1; /* error-specific data */
7054 1.45 nonaka uint32_t data2; /* error-specific data */
7055 1.45 nonaka uint32_t data3; /* error-specific data */
7056 1.45 nonaka uint32_t umac_major;
7057 1.45 nonaka uint32_t umac_minor;
7058 1.45 nonaka uint32_t frame_pointer; /* core register 27 */
7059 1.45 nonaka uint32_t stack_pointer; /* core register 28 */
7060 1.45 nonaka uint32_t cmd_header; /* latest host cmd sent to UMAC */
7061 1.45 nonaka uint32_t nic_isr_pref; /* ISR status register */
7062 1.1 pooka } __packed;
7063 1.1 pooka
7064 1.1 pooka #define ERROR_START_OFFSET (1 * sizeof(uint32_t))
7065 1.1 pooka #define ERROR_ELEM_SIZE (7 * sizeof(uint32_t))
7066 1.1 pooka
7067 1.4 nonaka #ifdef IWM_DEBUG
7068 1.4 nonaka static const struct {
7069 1.1 pooka const char *name;
7070 1.1 pooka uint8_t num;
7071 1.1 pooka } advanced_lookup[] = {
7072 1.1 pooka { "NMI_INTERRUPT_WDG", 0x34 },
7073 1.1 pooka { "SYSASSERT", 0x35 },
7074 1.1 pooka { "UCODE_VERSION_MISMATCH", 0x37 },
7075 1.1 pooka { "BAD_COMMAND", 0x38 },
7076 1.1 pooka { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
7077 1.1 pooka { "FATAL_ERROR", 0x3D },
7078 1.1 pooka { "NMI_TRM_HW_ERR", 0x46 },
7079 1.1 pooka { "NMI_INTERRUPT_TRM", 0x4C },
7080 1.1 pooka { "NMI_INTERRUPT_BREAK_POINT", 0x54 },
7081 1.1 pooka { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
7082 1.1 pooka { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
7083 1.1 pooka { "NMI_INTERRUPT_HOST", 0x66 },
7084 1.1 pooka { "NMI_INTERRUPT_ACTION_PT", 0x7C },
7085 1.1 pooka { "NMI_INTERRUPT_UNKNOWN", 0x84 },
7086 1.1 pooka { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
7087 1.1 pooka { "ADVANCED_SYSASSERT", 0 },
7088 1.1 pooka };
7089 1.1 pooka
7090 1.4 nonaka static const char *
7091 1.1 pooka iwm_desc_lookup(uint32_t num)
7092 1.1 pooka {
7093 1.1 pooka int i;
7094 1.1 pooka
7095 1.1 pooka for (i = 0; i < __arraycount(advanced_lookup) - 1; i++)
7096 1.1 pooka if (advanced_lookup[i].num == num)
7097 1.1 pooka return advanced_lookup[i].name;
7098 1.1 pooka
7099 1.1 pooka /* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */
7100 1.1 pooka return advanced_lookup[i].name;
7101 1.1 pooka }
7102 1.1 pooka
7103 1.1 pooka /*
7104 1.1 pooka * Support for dumping the error log seemed like a good idea ...
7105 1.1 pooka * but it's mostly hex junk and the only sensible thing is the
7106 1.1 pooka * hw/ucode revision (which we know anyway). Since it's here,
7107 1.1 pooka * I'll just leave it in, just in case e.g. the Intel guys want to
7108 1.1 pooka * help us decipher some "ADVANCED_SYSASSERT" later.
7109 1.1 pooka */
7110 1.4 nonaka static void
7111 1.1 pooka iwm_nic_error(struct iwm_softc *sc)
7112 1.1 pooka {
7113 1.45 nonaka struct iwm_error_event_table t;
7114 1.1 pooka uint32_t base;
7115 1.1 pooka
7116 1.3 nonaka aprint_error_dev(sc->sc_dev, "dumping device error log\n");
7117 1.1 pooka base = sc->sc_uc.uc_error_event_table;
7118 1.45 nonaka if (base < 0x800000) {
7119 1.3 nonaka aprint_error_dev(sc->sc_dev,
7120 1.45 nonaka "Invalid error log pointer 0x%08x\n", base);
7121 1.1 pooka return;
7122 1.1 pooka }
7123 1.1 pooka
7124 1.45 nonaka if (iwm_read_mem(sc, base, &t, sizeof(t)/sizeof(uint32_t))) {
7125 1.3 nonaka aprint_error_dev(sc->sc_dev, "reading errlog failed\n");
7126 1.1 pooka return;
7127 1.1 pooka }
7128 1.1 pooka
7129 1.45 nonaka if (!t.valid) {
7130 1.3 nonaka aprint_error_dev(sc->sc_dev, "errlog not found, skipping\n");
7131 1.1 pooka return;
7132 1.1 pooka }
7133 1.1 pooka
7134 1.45 nonaka if (ERROR_START_OFFSET <= t.valid * ERROR_ELEM_SIZE) {
7135 1.45 nonaka aprint_error_dev(sc->sc_dev, "Start Error Log Dump:\n");
7136 1.3 nonaka aprint_error_dev(sc->sc_dev, "Status: 0x%x, count: %d\n",
7137 1.45 nonaka sc->sc_flags, t.valid);
7138 1.1 pooka }
7139 1.1 pooka
7140 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | %-28s\n", t.error_id,
7141 1.45 nonaka iwm_desc_lookup(t.error_id));
7142 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | trm_hw_status0\n",
7143 1.45 nonaka t.trm_hw_status0);
7144 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | trm_hw_status1\n",
7145 1.45 nonaka t.trm_hw_status1);
7146 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | branchlink2\n", t.blink2);
7147 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | interruptlink1\n", t.ilink1);
7148 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | interruptlink2\n", t.ilink2);
7149 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | data1\n", t.data1);
7150 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | data2\n", t.data2);
7151 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | data3\n", t.data3);
7152 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | beacon time\n", t.bcon_time);
7153 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | tsf low\n", t.tsf_low);
7154 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | tsf hi\n", t.tsf_hi);
7155 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | time gp1\n", t.gp1);
7156 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | time gp2\n", t.gp2);
7157 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | uCode revision type\n",
7158 1.45 nonaka t.fw_rev_type);
7159 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | uCode version major\n",
7160 1.45 nonaka t.major);
7161 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | uCode version minor\n",
7162 1.45 nonaka t.minor);
7163 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | hw version\n", t.hw_ver);
7164 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | board version\n", t.brd_ver);
7165 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | hcmd\n", t.hcmd);
7166 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | isr0\n", t.isr0);
7167 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | isr1\n", t.isr1);
7168 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | isr2\n", t.isr2);
7169 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | isr3\n", t.isr3);
7170 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | isr4\n", t.isr4);
7171 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | last cmd Id\n", t.last_cmd_id);
7172 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | wait_event\n", t.wait_event);
7173 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | l2p_control\n", t.l2p_control);
7174 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | l2p_duration\n", t.l2p_duration);
7175 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | l2p_mhvalid\n", t.l2p_mhvalid);
7176 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | l2p_addr_match\n",
7177 1.45 nonaka t.l2p_addr_match);
7178 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | lmpm_pmg_sel\n", t.lmpm_pmg_sel);
7179 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | timestamp\n", t.u_timestamp);
7180 1.45 nonaka aprint_error_dev(sc->sc_dev, "%08X | flow_handler\n", t.flow_handler);
7181 1.45 nonaka
7182 1.45 nonaka if (sc->sc_uc.uc_umac_error_event_table)
7183 1.45 nonaka iwm_nic_umac_error(sc);
7184 1.45 nonaka }
7185 1.45 nonaka
7186 1.45 nonaka static void
7187 1.45 nonaka iwm_nic_umac_error(struct iwm_softc *sc)
7188 1.45 nonaka {
7189 1.45 nonaka struct iwm_umac_error_event_table t;
7190 1.45 nonaka uint32_t base;
7191 1.45 nonaka
7192 1.45 nonaka base = sc->sc_uc.uc_umac_error_event_table;
7193 1.45 nonaka
7194 1.45 nonaka if (base < 0x800000) {
7195 1.45 nonaka aprint_error_dev(sc->sc_dev,
7196 1.45 nonaka "Invalid error log pointer 0x%08x\n", base);
7197 1.45 nonaka return;
7198 1.45 nonaka }
7199 1.45 nonaka
7200 1.45 nonaka if (iwm_read_mem(sc, base, &t, sizeof(t)/sizeof(uint32_t))) {
7201 1.45 nonaka aprint_error_dev(sc->sc_dev, "reading errlog failed\n");
7202 1.45 nonaka return;
7203 1.45 nonaka }
7204 1.45 nonaka
7205 1.45 nonaka if (ERROR_START_OFFSET <= t.valid * ERROR_ELEM_SIZE) {
7206 1.45 nonaka aprint_error_dev(sc->sc_dev, "Start UMAC Error Log Dump:\n");
7207 1.45 nonaka aprint_error_dev(sc->sc_dev, "Status: 0x%x, count: %d\n",
7208 1.45 nonaka sc->sc_flags, t.valid);
7209 1.45 nonaka }
7210 1.45 nonaka
7211 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | %s\n", t.error_id,
7212 1.45 nonaka iwm_desc_lookup(t.error_id));
7213 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | umac branchlink1\n", t.blink1);
7214 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | umac branchlink2\n", t.blink2);
7215 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | umac interruptlink1\n",
7216 1.45 nonaka t.ilink1);
7217 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | umac interruptlink2\n",
7218 1.45 nonaka t.ilink2);
7219 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | umac data1\n", t.data1);
7220 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | umac data2\n", t.data2);
7221 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | umac data3\n", t.data3);
7222 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | umac major\n", t.umac_major);
7223 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | umac minor\n", t.umac_minor);
7224 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | frame pointer\n",
7225 1.45 nonaka t.frame_pointer);
7226 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | stack pointer\n",
7227 1.45 nonaka t.stack_pointer);
7228 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | last host cmd\n", t.cmd_header);
7229 1.45 nonaka aprint_error_dev(sc->sc_dev, "0x%08X | isr status reg\n",
7230 1.45 nonaka t.nic_isr_pref);
7231 1.1 pooka }
7232 1.2 nonaka #endif
7233 1.1 pooka
7234 1.1 pooka #define SYNC_RESP_STRUCT(_var_, _pkt_) \
7235 1.1 pooka do { \
7236 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*(_pkt_)), \
7237 1.1 pooka sizeof(*(_var_)), BUS_DMASYNC_POSTREAD); \
7238 1.1 pooka _var_ = (void *)((_pkt_)+1); \
7239 1.1 pooka } while (/*CONSTCOND*/0)
7240 1.1 pooka
7241 1.1 pooka #define SYNC_RESP_PTR(_ptr_, _len_, _pkt_) \
7242 1.1 pooka do { \
7243 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*(_pkt_)), \
7244 1.1 pooka sizeof(len), BUS_DMASYNC_POSTREAD); \
7245 1.1 pooka _ptr_ = (void *)((_pkt_)+1); \
7246 1.1 pooka } while (/*CONSTCOND*/0)
7247 1.1 pooka
7248 1.1 pooka #define ADVANCE_RXQ(sc) (sc->rxq.cur = (sc->rxq.cur + 1) % IWM_RX_RING_COUNT);
7249 1.1 pooka
7250 1.4 nonaka static void
7251 1.1 pooka iwm_notif_intr(struct iwm_softc *sc)
7252 1.1 pooka {
7253 1.1 pooka uint16_t hw;
7254 1.1 pooka
7255 1.1 pooka bus_dmamap_sync(sc->sc_dmat, sc->rxq.stat_dma.map,
7256 1.1 pooka 0, sc->rxq.stat_dma.size, BUS_DMASYNC_POSTREAD);
7257 1.1 pooka
7258 1.1 pooka hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff;
7259 1.1 pooka while (sc->rxq.cur != hw) {
7260 1.1 pooka struct iwm_rx_data *data = &sc->rxq.data[sc->rxq.cur];
7261 1.45 nonaka struct iwm_rx_packet *pkt;
7262 1.1 pooka struct iwm_cmd_response *cresp;
7263 1.45 nonaka int orig_qid, qid, idx, code;
7264 1.1 pooka
7265 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0, sizeof(*pkt),
7266 1.1 pooka BUS_DMASYNC_POSTREAD);
7267 1.1 pooka pkt = mtod(data->m, struct iwm_rx_packet *);
7268 1.1 pooka
7269 1.45 nonaka orig_qid = pkt->hdr.qid;
7270 1.45 nonaka qid = orig_qid & ~0x80;
7271 1.1 pooka idx = pkt->hdr.idx;
7272 1.1 pooka
7273 1.45 nonaka code = IWM_WIDE_ID(pkt->hdr.flags, pkt->hdr.code);
7274 1.1 pooka
7275 1.1 pooka /*
7276 1.1 pooka * randomly get these from the firmware, no idea why.
7277 1.1 pooka * they at least seem harmless, so just ignore them for now
7278 1.1 pooka */
7279 1.1 pooka if (__predict_false((pkt->hdr.code == 0 && qid == 0 && idx == 0)
7280 1.1 pooka || pkt->len_n_flags == htole32(0x55550000))) {
7281 1.1 pooka ADVANCE_RXQ(sc);
7282 1.1 pooka continue;
7283 1.1 pooka }
7284 1.1 pooka
7285 1.45 nonaka switch (code) {
7286 1.1 pooka case IWM_REPLY_RX_PHY_CMD:
7287 1.45 nonaka iwm_rx_rx_phy_cmd(sc, pkt, data);
7288 1.1 pooka break;
7289 1.1 pooka
7290 1.1 pooka case IWM_REPLY_RX_MPDU_CMD:
7291 1.45 nonaka iwm_rx_rx_mpdu(sc, pkt, data);
7292 1.1 pooka break;
7293 1.1 pooka
7294 1.1 pooka case IWM_TX_CMD:
7295 1.45 nonaka iwm_rx_tx_cmd(sc, pkt, data);
7296 1.1 pooka break;
7297 1.1 pooka
7298 1.1 pooka case IWM_MISSED_BEACONS_NOTIFICATION:
7299 1.45 nonaka iwm_rx_missed_beacons_notif(sc, pkt, data);
7300 1.1 pooka break;
7301 1.1 pooka
7302 1.45 nonaka case IWM_MFUART_LOAD_NOTIFICATION:
7303 1.45 nonaka break;
7304 1.1 pooka
7305 1.45 nonaka case IWM_ALIVE: {
7306 1.45 nonaka struct iwm_alive_resp_v1 *resp1;
7307 1.45 nonaka struct iwm_alive_resp_v2 *resp2;
7308 1.45 nonaka struct iwm_alive_resp_v3 *resp3;
7309 1.45 nonaka
7310 1.45 nonaka if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp1)) {
7311 1.45 nonaka SYNC_RESP_STRUCT(resp1, pkt);
7312 1.45 nonaka sc->sc_uc.uc_error_event_table
7313 1.45 nonaka = le32toh(resp1->error_event_table_ptr);
7314 1.45 nonaka sc->sc_uc.uc_log_event_table
7315 1.45 nonaka = le32toh(resp1->log_event_table_ptr);
7316 1.45 nonaka sc->sched_base = le32toh(resp1->scd_base_ptr);
7317 1.45 nonaka if (resp1->status == IWM_ALIVE_STATUS_OK)
7318 1.45 nonaka sc->sc_uc.uc_ok = 1;
7319 1.45 nonaka else
7320 1.45 nonaka sc->sc_uc.uc_ok = 0;
7321 1.45 nonaka }
7322 1.45 nonaka if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp2)) {
7323 1.45 nonaka SYNC_RESP_STRUCT(resp2, pkt);
7324 1.45 nonaka sc->sc_uc.uc_error_event_table
7325 1.45 nonaka = le32toh(resp2->error_event_table_ptr);
7326 1.45 nonaka sc->sc_uc.uc_log_event_table
7327 1.45 nonaka = le32toh(resp2->log_event_table_ptr);
7328 1.45 nonaka sc->sched_base = le32toh(resp2->scd_base_ptr);
7329 1.45 nonaka sc->sc_uc.uc_umac_error_event_table
7330 1.45 nonaka = le32toh(resp2->error_info_addr);
7331 1.45 nonaka if (resp2->status == IWM_ALIVE_STATUS_OK)
7332 1.45 nonaka sc->sc_uc.uc_ok = 1;
7333 1.45 nonaka else
7334 1.45 nonaka sc->sc_uc.uc_ok = 0;
7335 1.45 nonaka }
7336 1.45 nonaka if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp3)) {
7337 1.45 nonaka SYNC_RESP_STRUCT(resp3, pkt);
7338 1.45 nonaka sc->sc_uc.uc_error_event_table
7339 1.45 nonaka = le32toh(resp3->error_event_table_ptr);
7340 1.45 nonaka sc->sc_uc.uc_log_event_table
7341 1.45 nonaka = le32toh(resp3->log_event_table_ptr);
7342 1.45 nonaka sc->sched_base = le32toh(resp3->scd_base_ptr);
7343 1.45 nonaka sc->sc_uc.uc_umac_error_event_table
7344 1.45 nonaka = le32toh(resp3->error_info_addr);
7345 1.45 nonaka if (resp3->status == IWM_ALIVE_STATUS_OK)
7346 1.45 nonaka sc->sc_uc.uc_ok = 1;
7347 1.45 nonaka else
7348 1.45 nonaka sc->sc_uc.uc_ok = 0;
7349 1.45 nonaka }
7350 1.1 pooka
7351 1.1 pooka sc->sc_uc.uc_intr = 1;
7352 1.1 pooka wakeup(&sc->sc_uc);
7353 1.45 nonaka break;
7354 1.45 nonaka }
7355 1.1 pooka
7356 1.1 pooka case IWM_CALIB_RES_NOTIF_PHY_DB: {
7357 1.1 pooka struct iwm_calib_res_notif_phy_db *phy_db_notif;
7358 1.1 pooka SYNC_RESP_STRUCT(phy_db_notif, pkt);
7359 1.5 nonaka uint16_t size = le16toh(phy_db_notif->length);
7360 1.5 nonaka bus_dmamap_sync(sc->sc_dmat, data->map,
7361 1.5 nonaka sizeof(*pkt) + sizeof(*phy_db_notif),
7362 1.5 nonaka size, BUS_DMASYNC_POSTREAD);
7363 1.5 nonaka iwm_phy_db_set_section(sc, phy_db_notif, size);
7364 1.45 nonaka break;
7365 1.45 nonaka }
7366 1.1 pooka
7367 1.1 pooka case IWM_STATISTICS_NOTIFICATION: {
7368 1.1 pooka struct iwm_notif_statistics *stats;
7369 1.1 pooka SYNC_RESP_STRUCT(stats, pkt);
7370 1.1 pooka memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats));
7371 1.1 pooka sc->sc_noise = iwm_get_noise(&stats->rx.general);
7372 1.45 nonaka break;
7373 1.45 nonaka }
7374 1.1 pooka
7375 1.1 pooka case IWM_NVM_ACCESS_CMD:
7376 1.45 nonaka case IWM_MCC_UPDATE_CMD:
7377 1.1 pooka if (sc->sc_wantresp == ((qid << 16) | idx)) {
7378 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0,
7379 1.1 pooka sizeof(sc->sc_cmd_resp),
7380 1.1 pooka BUS_DMASYNC_POSTREAD);
7381 1.1 pooka memcpy(sc->sc_cmd_resp,
7382 1.1 pooka pkt, sizeof(sc->sc_cmd_resp));
7383 1.1 pooka }
7384 1.1 pooka break;
7385 1.1 pooka
7386 1.45 nonaka case IWM_MCC_CHUB_UPDATE_CMD: {
7387 1.45 nonaka struct iwm_mcc_chub_notif *notif;
7388 1.45 nonaka SYNC_RESP_STRUCT(notif, pkt);
7389 1.45 nonaka
7390 1.45 nonaka sc->sc_fw_mcc[0] = (notif->mcc & 0xff00) >> 8;
7391 1.45 nonaka sc->sc_fw_mcc[1] = notif->mcc & 0xff;
7392 1.45 nonaka sc->sc_fw_mcc[2] = '\0';
7393 1.45 nonaka break;
7394 1.45 nonaka }
7395 1.45 nonaka
7396 1.45 nonaka case IWM_DTS_MEASUREMENT_NOTIFICATION:
7397 1.61 nonaka case IWM_WIDE_ID(IWM_PHY_OPS_GROUP,
7398 1.61 nonaka IWM_DTS_MEASUREMENT_NOTIF_WIDE): {
7399 1.61 nonaka struct iwm_dts_measurement_notif_v1 *notif1;
7400 1.61 nonaka struct iwm_dts_measurement_notif_v2 *notif2;
7401 1.61 nonaka
7402 1.61 nonaka if (iwm_rx_packet_payload_len(pkt) == sizeof(*notif1)) {
7403 1.61 nonaka SYNC_RESP_STRUCT(notif1, pkt);
7404 1.61 nonaka DPRINTF(("%s: DTS temp=%d \n",
7405 1.61 nonaka DEVNAME(sc), notif1->temp));
7406 1.61 nonaka break;
7407 1.61 nonaka }
7408 1.61 nonaka if (iwm_rx_packet_payload_len(pkt) == sizeof(*notif2)) {
7409 1.61 nonaka SYNC_RESP_STRUCT(notif2, pkt);
7410 1.61 nonaka DPRINTF(("%s: DTS temp=%d \n",
7411 1.61 nonaka DEVNAME(sc), notif2->temp));
7412 1.61 nonaka break;
7413 1.61 nonaka }
7414 1.45 nonaka break;
7415 1.61 nonaka }
7416 1.45 nonaka
7417 1.1 pooka case IWM_PHY_CONFIGURATION_CMD:
7418 1.1 pooka case IWM_TX_ANT_CONFIGURATION_CMD:
7419 1.1 pooka case IWM_ADD_STA:
7420 1.1 pooka case IWM_MAC_CONTEXT_CMD:
7421 1.1 pooka case IWM_REPLY_SF_CFG_CMD:
7422 1.1 pooka case IWM_POWER_TABLE_CMD:
7423 1.1 pooka case IWM_PHY_CONTEXT_CMD:
7424 1.1 pooka case IWM_BINDING_CONTEXT_CMD:
7425 1.1 pooka case IWM_TIME_EVENT_CMD:
7426 1.1 pooka case IWM_SCAN_REQUEST_CMD:
7427 1.45 nonaka case IWM_WIDE_ID(IWM_ALWAYS_LONG_GROUP, IWM_SCAN_CFG_CMD):
7428 1.45 nonaka case IWM_WIDE_ID(IWM_ALWAYS_LONG_GROUP, IWM_SCAN_REQ_UMAC):
7429 1.61 nonaka case IWM_WIDE_ID(IWM_ALWAYS_LONG_GROUP, IWM_SCAN_ABORT_UMAC):
7430 1.45 nonaka case IWM_SCAN_OFFLOAD_REQUEST_CMD:
7431 1.61 nonaka case IWM_SCAN_OFFLOAD_ABORT_CMD:
7432 1.1 pooka case IWM_REPLY_BEACON_FILTERING_CMD:
7433 1.1 pooka case IWM_MAC_PM_POWER_TABLE:
7434 1.1 pooka case IWM_TIME_QUOTA_CMD:
7435 1.1 pooka case IWM_REMOVE_STA:
7436 1.1 pooka case IWM_TXPATH_FLUSH:
7437 1.1 pooka case IWM_LQ_CMD:
7438 1.71 nonaka case IWM_WIDE_ID(IWM_ALWAYS_LONG_GROUP, IWM_FW_PAGING_BLOCK_CMD):
7439 1.45 nonaka case IWM_BT_CONFIG:
7440 1.45 nonaka case IWM_REPLY_THERMAL_MNG_BACKOFF:
7441 1.1 pooka SYNC_RESP_STRUCT(cresp, pkt);
7442 1.1 pooka if (sc->sc_wantresp == ((qid << 16) | idx)) {
7443 1.1 pooka memcpy(sc->sc_cmd_resp,
7444 1.45 nonaka pkt, sizeof(*pkt) + sizeof(*cresp));
7445 1.1 pooka }
7446 1.1 pooka break;
7447 1.1 pooka
7448 1.1 pooka /* ignore */
7449 1.61 nonaka case IWM_PHY_DB_CMD:
7450 1.1 pooka break;
7451 1.1 pooka
7452 1.1 pooka case IWM_INIT_COMPLETE_NOTIF:
7453 1.1 pooka sc->sc_init_complete = 1;
7454 1.1 pooka wakeup(&sc->sc_init_complete);
7455 1.1 pooka break;
7456 1.1 pooka
7457 1.45 nonaka case IWM_SCAN_OFFLOAD_COMPLETE: {
7458 1.45 nonaka struct iwm_periodic_scan_complete *notif;
7459 1.45 nonaka SYNC_RESP_STRUCT(notif, pkt);
7460 1.45 nonaka break;
7461 1.45 nonaka }
7462 1.45 nonaka
7463 1.45 nonaka case IWM_SCAN_ITERATION_COMPLETE: {
7464 1.45 nonaka struct iwm_lmac_scan_complete_notif *notif;
7465 1.45 nonaka SYNC_RESP_STRUCT(notif, pkt);
7466 1.61 nonaka if (ISSET(sc->sc_flags, IWM_FLAG_SCANNING)) {
7467 1.61 nonaka CLR(sc->sc_flags, IWM_FLAG_SCANNING);
7468 1.61 nonaka iwm_endscan(sc);
7469 1.61 nonaka }
7470 1.45 nonaka break;
7471 1.45 nonaka }
7472 1.45 nonaka
7473 1.45 nonaka case IWM_SCAN_COMPLETE_UMAC: {
7474 1.45 nonaka struct iwm_umac_scan_complete *notif;
7475 1.1 pooka SYNC_RESP_STRUCT(notif, pkt);
7476 1.61 nonaka if (ISSET(sc->sc_flags, IWM_FLAG_SCANNING)) {
7477 1.61 nonaka CLR(sc->sc_flags, IWM_FLAG_SCANNING);
7478 1.61 nonaka iwm_endscan(sc);
7479 1.61 nonaka }
7480 1.45 nonaka break;
7481 1.45 nonaka }
7482 1.1 pooka
7483 1.45 nonaka case IWM_SCAN_ITERATION_COMPLETE_UMAC: {
7484 1.45 nonaka struct iwm_umac_scan_iter_complete_notif *notif;
7485 1.45 nonaka SYNC_RESP_STRUCT(notif, pkt);
7486 1.61 nonaka if (ISSET(sc->sc_flags, IWM_FLAG_SCANNING)) {
7487 1.61 nonaka CLR(sc->sc_flags, IWM_FLAG_SCANNING);
7488 1.61 nonaka iwm_endscan(sc);
7489 1.61 nonaka }
7490 1.45 nonaka break;
7491 1.45 nonaka }
7492 1.1 pooka
7493 1.1 pooka case IWM_REPLY_ERROR: {
7494 1.1 pooka struct iwm_error_resp *resp;
7495 1.1 pooka SYNC_RESP_STRUCT(resp, pkt);
7496 1.3 nonaka aprint_error_dev(sc->sc_dev,
7497 1.3 nonaka "firmware error 0x%x, cmd 0x%x\n",
7498 1.3 nonaka le32toh(resp->error_type), resp->cmd_id);
7499 1.45 nonaka break;
7500 1.45 nonaka }
7501 1.1 pooka
7502 1.1 pooka case IWM_TIME_EVENT_NOTIFICATION: {
7503 1.1 pooka struct iwm_time_event_notif *notif;
7504 1.1 pooka SYNC_RESP_STRUCT(notif, pkt);
7505 1.45 nonaka break;
7506 1.45 nonaka }
7507 1.8 nonaka
7508 1.71 nonaka case IWM_DEBUG_LOG_MSG:
7509 1.71 nonaka break;
7510 1.71 nonaka
7511 1.45 nonaka case IWM_MCAST_FILTER_CMD:
7512 1.45 nonaka break;
7513 1.1 pooka
7514 1.45 nonaka case IWM_SCD_QUEUE_CFG: {
7515 1.45 nonaka struct iwm_scd_txq_cfg_rsp *rsp;
7516 1.45 nonaka SYNC_RESP_STRUCT(rsp, pkt);
7517 1.11 nonaka break;
7518 1.45 nonaka }
7519 1.11 nonaka
7520 1.1 pooka default:
7521 1.3 nonaka aprint_error_dev(sc->sc_dev,
7522 1.45 nonaka "unhandled firmware response 0x%x 0x%x/0x%x "
7523 1.45 nonaka "rx ring %d[%d]\n",
7524 1.45 nonaka code, pkt->hdr.code, pkt->len_n_flags, qid, idx);
7525 1.1 pooka break;
7526 1.1 pooka }
7527 1.1 pooka
7528 1.1 pooka /*
7529 1.45 nonaka * uCode sets bit 0x80 when it originates the notification,
7530 1.45 nonaka * i.e. when the notification is not a direct response to a
7531 1.45 nonaka * command sent by the driver.
7532 1.45 nonaka * For example, uCode issues IWM_REPLY_RX when it sends a
7533 1.45 nonaka * received frame to the driver.
7534 1.1 pooka */
7535 1.45 nonaka if (!(orig_qid & (1 << 7))) {
7536 1.45 nonaka iwm_cmd_done(sc, qid, idx);
7537 1.1 pooka }
7538 1.1 pooka
7539 1.1 pooka ADVANCE_RXQ(sc);
7540 1.1 pooka }
7541 1.1 pooka
7542 1.1 pooka /*
7543 1.45 nonaka * Seems like the hardware gets upset unless we align the write by 8??
7544 1.1 pooka */
7545 1.1 pooka hw = (hw == 0) ? IWM_RX_RING_COUNT - 1 : hw - 1;
7546 1.1 pooka IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, hw & ~7);
7547 1.1 pooka }
7548 1.1 pooka
7549 1.61 nonaka static int
7550 1.61 nonaka iwm_intr(void *arg)
7551 1.61 nonaka {
7552 1.61 nonaka struct iwm_softc *sc = arg;
7553 1.61 nonaka
7554 1.70 nonaka /* Disable interrupts */
7555 1.61 nonaka IWM_WRITE(sc, IWM_CSR_INT_MASK, 0);
7556 1.61 nonaka
7557 1.70 nonaka softint_schedule(sc->sc_soft_ih);
7558 1.70 nonaka return 1;
7559 1.70 nonaka }
7560 1.70 nonaka
7561 1.70 nonaka static void
7562 1.70 nonaka iwm_softintr(void *arg)
7563 1.70 nonaka {
7564 1.70 nonaka struct iwm_softc *sc = arg;
7565 1.70 nonaka struct ifnet *ifp = IC2IFP(&sc->sc_ic);
7566 1.70 nonaka uint32_t r1, r2;
7567 1.70 nonaka int isperiodic = 0, s;
7568 1.70 nonaka
7569 1.63 nonaka if (__predict_true(sc->sc_flags & IWM_FLAG_USE_ICT)) {
7570 1.61 nonaka uint32_t *ict = sc->ict_dma.vaddr;
7571 1.61 nonaka int tmp;
7572 1.61 nonaka
7573 1.61 nonaka bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map,
7574 1.61 nonaka 0, sc->ict_dma.size, BUS_DMASYNC_POSTREAD);
7575 1.61 nonaka tmp = htole32(ict[sc->ict_cur]);
7576 1.70 nonaka if (tmp == 0)
7577 1.70 nonaka goto out_ena; /* Interrupt not for us. */
7578 1.61 nonaka
7579 1.61 nonaka /*
7580 1.61 nonaka * ok, there was something. keep plowing until we have all.
7581 1.61 nonaka */
7582 1.61 nonaka r1 = r2 = 0;
7583 1.61 nonaka while (tmp) {
7584 1.61 nonaka r1 |= tmp;
7585 1.61 nonaka ict[sc->ict_cur] = 0; /* Acknowledge. */
7586 1.61 nonaka sc->ict_cur = (sc->ict_cur + 1) % IWM_ICT_COUNT;
7587 1.61 nonaka tmp = htole32(ict[sc->ict_cur]);
7588 1.61 nonaka }
7589 1.61 nonaka
7590 1.62 nonaka bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map,
7591 1.62 nonaka 0, sc->ict_dma.size, BUS_DMASYNC_PREWRITE);
7592 1.62 nonaka
7593 1.61 nonaka /* this is where the fun begins. don't ask */
7594 1.61 nonaka if (r1 == 0xffffffff)
7595 1.61 nonaka r1 = 0;
7596 1.61 nonaka
7597 1.61 nonaka /* i am not expected to understand this */
7598 1.61 nonaka if (r1 & 0xc0000)
7599 1.61 nonaka r1 |= 0x8000;
7600 1.61 nonaka r1 = (0xff & r1) | ((0xff00 & r1) << 16);
7601 1.61 nonaka } else {
7602 1.61 nonaka r1 = IWM_READ(sc, IWM_CSR_INT);
7603 1.61 nonaka if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
7604 1.70 nonaka return; /* Hardware gone! */
7605 1.61 nonaka r2 = IWM_READ(sc, IWM_CSR_FH_INT_STATUS);
7606 1.61 nonaka }
7607 1.61 nonaka if (r1 == 0 && r2 == 0) {
7608 1.70 nonaka goto out_ena; /* Interrupt not for us. */
7609 1.61 nonaka }
7610 1.61 nonaka
7611 1.63 nonaka /* Acknowledge interrupts. */
7612 1.61 nonaka IWM_WRITE(sc, IWM_CSR_INT, r1 | ~sc->sc_intmask);
7613 1.63 nonaka if (__predict_false(!(sc->sc_flags & IWM_FLAG_USE_ICT)))
7614 1.63 nonaka IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, r2);
7615 1.61 nonaka
7616 1.1 pooka if (r1 & IWM_CSR_INT_BIT_SW_ERR) {
7617 1.1 pooka #ifdef IWM_DEBUG
7618 1.1 pooka int i;
7619 1.1 pooka
7620 1.1 pooka iwm_nic_error(sc);
7621 1.1 pooka
7622 1.1 pooka /* Dump driver status (TX and RX rings) while we're here. */
7623 1.1 pooka DPRINTF(("driver status:\n"));
7624 1.45 nonaka for (i = 0; i < IWM_MAX_QUEUES; i++) {
7625 1.1 pooka struct iwm_tx_ring *ring = &sc->txq[i];
7626 1.1 pooka DPRINTF((" tx ring %2d: qid=%-2d cur=%-3d "
7627 1.1 pooka "queued=%-3d\n",
7628 1.1 pooka i, ring->qid, ring->cur, ring->queued));
7629 1.1 pooka }
7630 1.1 pooka DPRINTF((" rx ring: cur=%d\n", sc->rxq.cur));
7631 1.45 nonaka DPRINTF((" 802.11 state %s\n",
7632 1.45 nonaka ieee80211_state_name[sc->sc_ic.ic_state]));
7633 1.1 pooka #endif
7634 1.1 pooka
7635 1.3 nonaka aprint_error_dev(sc->sc_dev, "fatal firmware error\n");
7636 1.50 nonaka fatal:
7637 1.68 nonaka s = splnet();
7638 1.1 pooka ifp->if_flags &= ~IFF_UP;
7639 1.1 pooka iwm_stop(ifp, 1);
7640 1.68 nonaka splx(s);
7641 1.50 nonaka /* Don't restore interrupt mask */
7642 1.50 nonaka return;
7643 1.1 pooka
7644 1.1 pooka }
7645 1.1 pooka
7646 1.1 pooka if (r1 & IWM_CSR_INT_BIT_HW_ERR) {
7647 1.3 nonaka aprint_error_dev(sc->sc_dev,
7648 1.3 nonaka "hardware error, stopping device\n");
7649 1.50 nonaka goto fatal;
7650 1.1 pooka }
7651 1.1 pooka
7652 1.1 pooka /* firmware chunk loaded */
7653 1.1 pooka if (r1 & IWM_CSR_INT_BIT_FH_TX) {
7654 1.1 pooka IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_TX_MASK);
7655 1.1 pooka sc->sc_fw_chunk_done = 1;
7656 1.1 pooka wakeup(&sc->sc_fw);
7657 1.1 pooka }
7658 1.1 pooka
7659 1.1 pooka if (r1 & IWM_CSR_INT_BIT_RF_KILL) {
7660 1.68 nonaka if (iwm_check_rfkill(sc) && (ifp->if_flags & IFF_UP))
7661 1.68 nonaka goto fatal;
7662 1.1 pooka }
7663 1.1 pooka
7664 1.1 pooka if (r1 & IWM_CSR_INT_BIT_RX_PERIODIC) {
7665 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT, IWM_CSR_INT_BIT_RX_PERIODIC);
7666 1.1 pooka if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) == 0)
7667 1.1 pooka IWM_WRITE_1(sc,
7668 1.1 pooka IWM_CSR_INT_PERIODIC_REG, IWM_CSR_INT_PERIODIC_DIS);
7669 1.1 pooka isperiodic = 1;
7670 1.1 pooka }
7671 1.1 pooka
7672 1.45 nonaka if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) ||
7673 1.45 nonaka isperiodic) {
7674 1.1 pooka IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_RX_MASK);
7675 1.1 pooka
7676 1.1 pooka iwm_notif_intr(sc);
7677 1.1 pooka
7678 1.1 pooka /* enable periodic interrupt, see above */
7679 1.45 nonaka if (r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX) &&
7680 1.45 nonaka !isperiodic)
7681 1.1 pooka IWM_WRITE_1(sc, IWM_CSR_INT_PERIODIC_REG,
7682 1.1 pooka IWM_CSR_INT_PERIODIC_ENA);
7683 1.1 pooka }
7684 1.1 pooka
7685 1.70 nonaka out_ena:
7686 1.1 pooka iwm_restore_interrupts(sc);
7687 1.1 pooka }
7688 1.1 pooka
7689 1.1 pooka /*
7690 1.1 pooka * Autoconf glue-sniffing
7691 1.1 pooka */
7692 1.1 pooka
7693 1.1 pooka static const pci_product_id_t iwm_devices[] = {
7694 1.5 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_7260_1,
7695 1.5 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_7260_2,
7696 1.5 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_3160_1,
7697 1.5 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_3160_2,
7698 1.5 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_7265_1,
7699 1.5 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_7265_2,
7700 1.45 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_3165_1,
7701 1.45 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_3165_2,
7702 1.77 mlelstv PCI_PRODUCT_INTEL_WIFI_LINK_3168,
7703 1.45 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_8260_1,
7704 1.45 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_8260_2,
7705 1.58 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_4165_1,
7706 1.58 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_4165_2,
7707 1.72 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_8265,
7708 1.1 pooka };
7709 1.1 pooka
7710 1.1 pooka static int
7711 1.4 nonaka iwm_match(device_t parent, cfdata_t match __unused, void *aux)
7712 1.1 pooka {
7713 1.1 pooka struct pci_attach_args *pa = aux;
7714 1.1 pooka
7715 1.1 pooka if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
7716 1.1 pooka return 0;
7717 1.1 pooka
7718 1.5 nonaka for (size_t i = 0; i < __arraycount(iwm_devices); i++)
7719 1.1 pooka if (PCI_PRODUCT(pa->pa_id) == iwm_devices[i])
7720 1.1 pooka return 1;
7721 1.1 pooka
7722 1.1 pooka return 0;
7723 1.1 pooka }
7724 1.1 pooka
7725 1.4 nonaka static int
7726 1.1 pooka iwm_preinit(struct iwm_softc *sc)
7727 1.1 pooka {
7728 1.45 nonaka int err;
7729 1.1 pooka
7730 1.45 nonaka err = iwm_start_hw(sc);
7731 1.45 nonaka if (err) {
7732 1.3 nonaka aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
7733 1.45 nonaka return err;
7734 1.1 pooka }
7735 1.1 pooka
7736 1.45 nonaka err = iwm_run_init_mvm_ucode(sc, 1);
7737 1.1 pooka iwm_stop_device(sc);
7738 1.45 nonaka if (err)
7739 1.45 nonaka return err;
7740 1.1 pooka
7741 1.45 nonaka aprint_normal_dev(sc->sc_dev, "hw rev 0x%x, fw ver %s, address %s\n",
7742 1.45 nonaka sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK, sc->sc_fwver,
7743 1.1 pooka ether_sprintf(sc->sc_nvm.hw_addr));
7744 1.8 nonaka
7745 1.36 nonaka return 0;
7746 1.36 nonaka }
7747 1.36 nonaka
7748 1.36 nonaka static void
7749 1.36 nonaka iwm_attach_hook(device_t dev)
7750 1.36 nonaka {
7751 1.36 nonaka struct iwm_softc *sc = device_private(dev);
7752 1.30 nonaka
7753 1.87 riastrad iwm_config_complete(sc);
7754 1.1 pooka }
7755 1.1 pooka
7756 1.4 nonaka static void
7757 1.4 nonaka iwm_attach(device_t parent, device_t self, void *aux)
7758 1.1 pooka {
7759 1.1 pooka struct iwm_softc *sc = device_private(self);
7760 1.1 pooka struct pci_attach_args *pa = aux;
7761 1.1 pooka pcireg_t reg, memtype;
7762 1.37 nonaka char intrbuf[PCI_INTRSTR_LEN];
7763 1.1 pooka const char *intrstr;
7764 1.45 nonaka int err;
7765 1.2 nonaka int txq_i;
7766 1.36 nonaka const struct sysctlnode *node;
7767 1.1 pooka
7768 1.3 nonaka sc->sc_dev = self;
7769 1.1 pooka sc->sc_pct = pa->pa_pc;
7770 1.1 pooka sc->sc_pcitag = pa->pa_tag;
7771 1.1 pooka sc->sc_dmat = pa->pa_dmat;
7772 1.5 nonaka sc->sc_pciid = pa->pa_id;
7773 1.1 pooka
7774 1.1 pooka pci_aprint_devinfo(pa, NULL);
7775 1.1 pooka
7776 1.45 nonaka if (workqueue_create(&sc->sc_nswq, "iwmns",
7777 1.45 nonaka iwm_newstate_cb, sc, PRI_NONE, IPL_NET, 0))
7778 1.45 nonaka panic("%s: could not create workqueue: newstate",
7779 1.45 nonaka device_xname(self));
7780 1.50 nonaka sc->sc_soft_ih = softint_establish(SOFTINT_NET, iwm_softintr, sc);
7781 1.50 nonaka if (sc->sc_soft_ih == NULL)
7782 1.50 nonaka panic("%s: could not establish softint", device_xname(self));
7783 1.45 nonaka
7784 1.1 pooka /*
7785 1.1 pooka * Get the offset of the PCI Express Capability Structure in PCI
7786 1.1 pooka * Configuration Space.
7787 1.1 pooka */
7788 1.45 nonaka err = pci_get_capability(sc->sc_pct, sc->sc_pcitag,
7789 1.1 pooka PCI_CAP_PCIEXPRESS, &sc->sc_cap_off, NULL);
7790 1.45 nonaka if (err == 0) {
7791 1.3 nonaka aprint_error_dev(self,
7792 1.3 nonaka "PCIe capability structure not found!\n");
7793 1.1 pooka return;
7794 1.1 pooka }
7795 1.1 pooka
7796 1.1 pooka /* Clear device-specific "PCI retry timeout" register (41h). */
7797 1.1 pooka reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
7798 1.1 pooka pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
7799 1.1 pooka
7800 1.45 nonaka /* Enable bus-mastering */
7801 1.1 pooka reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
7802 1.1 pooka reg |= PCI_COMMAND_MASTER_ENABLE;
7803 1.1 pooka pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
7804 1.1 pooka
7805 1.1 pooka memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START);
7806 1.45 nonaka err = pci_mapreg_map(pa, PCI_MAPREG_START, memtype, 0,
7807 1.1 pooka &sc->sc_st, &sc->sc_sh, NULL, &sc->sc_sz);
7808 1.45 nonaka if (err) {
7809 1.3 nonaka aprint_error_dev(self, "can't map mem space\n");
7810 1.1 pooka return;
7811 1.1 pooka }
7812 1.1 pooka
7813 1.1 pooka /* Install interrupt handler. */
7814 1.45 nonaka err = pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0);
7815 1.45 nonaka if (err) {
7816 1.37 nonaka aprint_error_dev(self, "can't allocate interrupt\n");
7817 1.1 pooka return;
7818 1.1 pooka }
7819 1.61 nonaka reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
7820 1.61 nonaka if (pci_intr_type(sc->sc_pct, sc->sc_pihp[0]) == PCI_INTR_TYPE_INTX)
7821 1.61 nonaka CLR(reg, PCI_COMMAND_INTERRUPT_DISABLE);
7822 1.61 nonaka else
7823 1.61 nonaka SET(reg, PCI_COMMAND_INTERRUPT_DISABLE);
7824 1.61 nonaka pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
7825 1.31 nonaka intrstr = pci_intr_string(sc->sc_pct, sc->sc_pihp[0], intrbuf,
7826 1.31 nonaka sizeof(intrbuf));
7827 1.49 nonaka sc->sc_ih = pci_intr_establish_xname(sc->sc_pct, sc->sc_pihp[0],
7828 1.49 nonaka IPL_NET, iwm_intr, sc, device_xname(self));
7829 1.1 pooka if (sc->sc_ih == NULL) {
7830 1.3 nonaka aprint_error_dev(self, "can't establish interrupt");
7831 1.1 pooka if (intrstr != NULL)
7832 1.3 nonaka aprint_error(" at %s", intrstr);
7833 1.3 nonaka aprint_error("\n");
7834 1.1 pooka return;
7835 1.1 pooka }
7836 1.3 nonaka aprint_normal_dev(self, "interrupting at %s\n", intrstr);
7837 1.1 pooka
7838 1.45 nonaka sc->sc_wantresp = IWM_CMD_RESP_IDLE;
7839 1.5 nonaka
7840 1.45 nonaka sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV);
7841 1.5 nonaka switch (PCI_PRODUCT(sc->sc_pciid)) {
7842 1.45 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_3160_1:
7843 1.45 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_3160_2:
7844 1.71 nonaka sc->sc_fwname = "iwlwifi-3160-17.ucode";
7845 1.45 nonaka sc->host_interrupt_operation_mode = 1;
7846 1.59 nonaka sc->apmg_wake_up_wa = 1;
7847 1.45 nonaka sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
7848 1.45 nonaka sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
7849 1.45 nonaka break;
7850 1.45 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_3165_1:
7851 1.45 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_3165_2:
7852 1.71 nonaka sc->sc_fwname = "iwlwifi-7265D-22.ucode";
7853 1.71 nonaka sc->host_interrupt_operation_mode = 0;
7854 1.71 nonaka sc->apmg_wake_up_wa = 1;
7855 1.71 nonaka sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
7856 1.71 nonaka sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
7857 1.71 nonaka break;
7858 1.71 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_3168:
7859 1.71 nonaka sc->sc_fwname = "iwlwifi-3168-22.ucode";
7860 1.45 nonaka sc->host_interrupt_operation_mode = 0;
7861 1.59 nonaka sc->apmg_wake_up_wa = 1;
7862 1.45 nonaka sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
7863 1.45 nonaka sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
7864 1.45 nonaka break;
7865 1.5 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_7260_1:
7866 1.5 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_7260_2:
7867 1.71 nonaka sc->sc_fwname = "iwlwifi-7260-17.ucode";
7868 1.17 nonaka sc->host_interrupt_operation_mode = 1;
7869 1.59 nonaka sc->apmg_wake_up_wa = 1;
7870 1.45 nonaka sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
7871 1.45 nonaka sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
7872 1.5 nonaka break;
7873 1.5 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_7265_1:
7874 1.5 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_7265_2:
7875 1.45 nonaka sc->sc_fwname = (sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK) ==
7876 1.45 nonaka IWM_CSR_HW_REV_TYPE_7265D ?
7877 1.71 nonaka "iwlwifi-7265D-22.ucode": "iwlwifi-7265-17.ucode";
7878 1.45 nonaka sc->host_interrupt_operation_mode = 0;
7879 1.59 nonaka sc->apmg_wake_up_wa = 1;
7880 1.45 nonaka sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
7881 1.45 nonaka sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
7882 1.45 nonaka break;
7883 1.45 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_8260_1:
7884 1.45 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_8260_2:
7885 1.58 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_4165_1:
7886 1.58 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_4165_2:
7887 1.71 nonaka sc->sc_fwname = "iwlwifi-8000C-22.ucode";
7888 1.71 nonaka sc->host_interrupt_operation_mode = 0;
7889 1.71 nonaka sc->apmg_wake_up_wa = 0;
7890 1.71 nonaka sc->sc_device_family = IWM_DEVICE_FAMILY_8000;
7891 1.71 nonaka sc->sc_fwdmasegsz = IWM_FWDMASEGSZ_8000;
7892 1.71 nonaka break;
7893 1.71 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_8265:
7894 1.71 nonaka sc->sc_fwname = "iwlwifi-8265-22.ucode";
7895 1.17 nonaka sc->host_interrupt_operation_mode = 0;
7896 1.59 nonaka sc->apmg_wake_up_wa = 0;
7897 1.45 nonaka sc->sc_device_family = IWM_DEVICE_FAMILY_8000;
7898 1.45 nonaka sc->sc_fwdmasegsz = IWM_FWDMASEGSZ_8000;
7899 1.5 nonaka break;
7900 1.5 nonaka default:
7901 1.5 nonaka aprint_error_dev(self, "unknown product %#x",
7902 1.5 nonaka PCI_PRODUCT(sc->sc_pciid));
7903 1.5 nonaka return;
7904 1.5 nonaka }
7905 1.5 nonaka DPRINTF(("%s: firmware=%s\n", DEVNAME(sc), sc->sc_fwname));
7906 1.2 nonaka
7907 1.2 nonaka /*
7908 1.45 nonaka * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have
7909 1.45 nonaka * changed, and now the revision step also includes bit 0-1 (no more
7910 1.45 nonaka * "dash" value). To keep hw_rev backwards compatible - we'll store it
7911 1.45 nonaka * in the old format.
7912 1.2 nonaka */
7913 1.2 nonaka
7914 1.45 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000)
7915 1.45 nonaka sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) |
7916 1.45 nonaka (IWM_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2);
7917 1.45 nonaka
7918 1.2 nonaka if (iwm_prepare_card_hw(sc) != 0) {
7919 1.3 nonaka aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
7920 1.2 nonaka return;
7921 1.2 nonaka }
7922 1.2 nonaka
7923 1.45 nonaka if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) {
7924 1.45 nonaka uint32_t hw_step;
7925 1.45 nonaka
7926 1.45 nonaka /*
7927 1.45 nonaka * In order to recognize C step the driver should read the
7928 1.45 nonaka * chip version id located at the AUX bus MISC address.
7929 1.45 nonaka */
7930 1.45 nonaka IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
7931 1.45 nonaka IWM_CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
7932 1.45 nonaka DELAY(2);
7933 1.45 nonaka
7934 1.45 nonaka err = iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
7935 1.45 nonaka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
7936 1.45 nonaka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
7937 1.45 nonaka 25000);
7938 1.45 nonaka if (!err) {
7939 1.45 nonaka aprint_error_dev(sc->sc_dev,
7940 1.45 nonaka "failed to wake up the nic\n");
7941 1.45 nonaka return;
7942 1.45 nonaka }
7943 1.45 nonaka
7944 1.45 nonaka if (iwm_nic_lock(sc)) {
7945 1.45 nonaka hw_step = iwm_read_prph(sc, IWM_WFPM_CTRL_REG);
7946 1.45 nonaka hw_step |= IWM_ENABLE_WFPM;
7947 1.45 nonaka iwm_write_prph(sc, IWM_WFPM_CTRL_REG, hw_step);
7948 1.45 nonaka hw_step = iwm_read_prph(sc, IWM_AUX_MISC_REG);
7949 1.45 nonaka hw_step = (hw_step >> IWM_HW_STEP_LOCATION_BITS) & 0xF;
7950 1.45 nonaka if (hw_step == 0x3)
7951 1.45 nonaka sc->sc_hw_rev = (sc->sc_hw_rev & 0xFFFFFFF3) |
7952 1.45 nonaka (IWM_SILICON_C_STEP << 2);
7953 1.45 nonaka iwm_nic_unlock(sc);
7954 1.45 nonaka } else {
7955 1.45 nonaka aprint_error_dev(sc->sc_dev,
7956 1.45 nonaka "failed to lock the nic\n");
7957 1.45 nonaka return;
7958 1.45 nonaka }
7959 1.45 nonaka }
7960 1.45 nonaka
7961 1.45 nonaka /*
7962 1.45 nonaka * Allocate DMA memory for firmware transfers.
7963 1.45 nonaka * Must be aligned on a 16-byte boundary.
7964 1.45 nonaka */
7965 1.45 nonaka err = iwm_dma_contig_alloc(sc->sc_dmat, &sc->fw_dma, sc->sc_fwdmasegsz,
7966 1.45 nonaka 16);
7967 1.45 nonaka if (err) {
7968 1.3 nonaka aprint_error_dev(sc->sc_dev,
7969 1.3 nonaka "could not allocate memory for firmware\n");
7970 1.2 nonaka return;
7971 1.2 nonaka }
7972 1.2 nonaka
7973 1.45 nonaka /* Allocate "Keep Warm" page, used internally by the card. */
7974 1.45 nonaka err = iwm_dma_contig_alloc(sc->sc_dmat, &sc->kw_dma, 4096, 4096);
7975 1.45 nonaka if (err) {
7976 1.3 nonaka aprint_error_dev(sc->sc_dev,
7977 1.3 nonaka "could not allocate keep warm page\n");
7978 1.2 nonaka goto fail1;
7979 1.2 nonaka }
7980 1.2 nonaka
7981 1.45 nonaka /* Allocate interrupt cause table (ICT).*/
7982 1.45 nonaka err = iwm_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma, IWM_ICT_SIZE,
7983 1.45 nonaka 1 << IWM_ICT_PADDR_SHIFT);
7984 1.45 nonaka if (err) {
7985 1.3 nonaka aprint_error_dev(sc->sc_dev, "could not allocate ICT table\n");
7986 1.2 nonaka goto fail2;
7987 1.2 nonaka }
7988 1.2 nonaka
7989 1.45 nonaka /* TX scheduler rings must be aligned on a 1KB boundary. */
7990 1.45 nonaka err = iwm_dma_contig_alloc(sc->sc_dmat, &sc->sched_dma,
7991 1.45 nonaka __arraycount(sc->txq) * sizeof(struct iwm_agn_scd_bc_tbl), 1024);
7992 1.45 nonaka if (err) {
7993 1.3 nonaka aprint_error_dev(sc->sc_dev,
7994 1.3 nonaka "could not allocate TX scheduler rings\n");
7995 1.2 nonaka goto fail3;
7996 1.2 nonaka }
7997 1.2 nonaka
7998 1.2 nonaka for (txq_i = 0; txq_i < __arraycount(sc->txq); txq_i++) {
7999 1.45 nonaka err = iwm_alloc_tx_ring(sc, &sc->txq[txq_i], txq_i);
8000 1.45 nonaka if (err) {
8001 1.3 nonaka aprint_error_dev(sc->sc_dev,
8002 1.3 nonaka "could not allocate TX ring %d\n", txq_i);
8003 1.2 nonaka goto fail4;
8004 1.2 nonaka }
8005 1.2 nonaka }
8006 1.2 nonaka
8007 1.45 nonaka err = iwm_alloc_rx_ring(sc, &sc->rxq);
8008 1.45 nonaka if (err) {
8009 1.3 nonaka aprint_error_dev(sc->sc_dev, "could not allocate RX ring\n");
8010 1.76 msaitoh goto fail5;
8011 1.2 nonaka }
8012 1.2 nonaka
8013 1.2 nonaka /* Clear pending interrupts. */
8014 1.2 nonaka IWM_WRITE(sc, IWM_CSR_INT, 0xffffffff);
8015 1.2 nonaka
8016 1.45 nonaka if ((err = sysctl_createv(&sc->sc_clog, 0, NULL, &node,
8017 1.36 nonaka 0, CTLTYPE_NODE, device_xname(sc->sc_dev),
8018 1.36 nonaka SYSCTL_DESCR("iwm per-controller controls"),
8019 1.36 nonaka NULL, 0, NULL, 0,
8020 1.36 nonaka CTL_HW, iwm_sysctl_root_num, CTL_CREATE,
8021 1.36 nonaka CTL_EOL)) != 0) {
8022 1.36 nonaka aprint_normal_dev(sc->sc_dev,
8023 1.36 nonaka "couldn't create iwm per-controller sysctl node\n");
8024 1.36 nonaka }
8025 1.45 nonaka if (err == 0) {
8026 1.36 nonaka int iwm_nodenum = node->sysctl_num;
8027 1.36 nonaka
8028 1.36 nonaka /* Reload firmware sysctl node */
8029 1.45 nonaka if ((err = sysctl_createv(&sc->sc_clog, 0, NULL, &node,
8030 1.36 nonaka CTLFLAG_READWRITE, CTLTYPE_INT, "fw_loaded",
8031 1.36 nonaka SYSCTL_DESCR("Reload firmware"),
8032 1.36 nonaka iwm_sysctl_fw_loaded_handler, 0, (void *)sc, 0,
8033 1.36 nonaka CTL_HW, iwm_sysctl_root_num, iwm_nodenum, CTL_CREATE,
8034 1.36 nonaka CTL_EOL)) != 0) {
8035 1.36 nonaka aprint_normal_dev(sc->sc_dev,
8036 1.36 nonaka "couldn't create load_fw sysctl node\n");
8037 1.36 nonaka }
8038 1.36 nonaka }
8039 1.36 nonaka
8040 1.87 riastrad callout_init(&sc->sc_calib_to, 0);
8041 1.87 riastrad callout_setfunc(&sc->sc_calib_to, iwm_calib_timeout, sc);
8042 1.87 riastrad callout_init(&sc->sc_led_blink_to, 0);
8043 1.87 riastrad callout_setfunc(&sc->sc_led_blink_to, iwm_led_blink_timeout, sc);
8044 1.87 riastrad #ifndef IEEE80211_NO_HT
8045 1.87 riastrad if (workqueue_create(&sc->sc_setratewq, "iwmsr",
8046 1.87 riastrad iwm_setrates_task, sc, PRI_NONE, IPL_NET, 0))
8047 1.87 riastrad panic("%s: could not create workqueue: setrates",
8048 1.87 riastrad device_xname(self));
8049 1.87 riastrad if (workqueue_create(&sc->sc_bawq, "iwmba",
8050 1.87 riastrad iwm_ba_task, sc, PRI_NONE, IPL_NET, 0))
8051 1.87 riastrad panic("%s: could not create workqueue: blockack",
8052 1.87 riastrad device_xname(self));
8053 1.87 riastrad if (workqueue_create(&sc->sc_htprowq, "iwmhtpro",
8054 1.87 riastrad iwm_htprot_task, sc, PRI_NONE, IPL_NET, 0))
8055 1.87 riastrad panic("%s: could not create workqueue: htprot",
8056 1.87 riastrad device_xname(self));
8057 1.87 riastrad #endif
8058 1.87 riastrad
8059 1.87 riastrad /*
8060 1.87 riastrad * We can't do normal attach before the file system is mounted
8061 1.87 riastrad * because we cannot read the MAC address without loading the
8062 1.87 riastrad * firmware from disk. So we postpone until mountroot is done.
8063 1.87 riastrad * Notably, this will require a full driver unload/load cycle
8064 1.87 riastrad * (or reboot) in case the firmware is not present when the
8065 1.87 riastrad * hook runs.
8066 1.87 riastrad */
8067 1.87 riastrad config_mountroot(self, iwm_attach_hook);
8068 1.87 riastrad
8069 1.87 riastrad return;
8070 1.87 riastrad
8071 1.87 riastrad fail5: while (--txq_i >= 0)
8072 1.87 riastrad iwm_free_tx_ring(sc, &sc->txq[txq_i]);
8073 1.87 riastrad fail4: iwm_dma_contig_free(&sc->sched_dma);
8074 1.87 riastrad fail3: if (sc->ict_dma.vaddr != NULL)
8075 1.87 riastrad iwm_dma_contig_free(&sc->ict_dma);
8076 1.87 riastrad fail2: iwm_dma_contig_free(&sc->kw_dma);
8077 1.87 riastrad fail1: iwm_dma_contig_free(&sc->fw_dma);
8078 1.87 riastrad }
8079 1.87 riastrad
8080 1.87 riastrad static int
8081 1.87 riastrad iwm_config_complete(struct iwm_softc *sc)
8082 1.87 riastrad {
8083 1.87 riastrad device_t self = sc->sc_dev;
8084 1.87 riastrad struct ieee80211com *ic = &sc->sc_ic;
8085 1.87 riastrad struct ifnet *ifp = &sc->sc_ec.ec_if;
8086 1.87 riastrad int err;
8087 1.87 riastrad
8088 1.87 riastrad KASSERT(!ISSET(sc->sc_flags, IWM_FLAG_ATTACHED));
8089 1.87 riastrad
8090 1.87 riastrad err = iwm_preinit(sc);
8091 1.87 riastrad if (err)
8092 1.87 riastrad return err;
8093 1.87 riastrad
8094 1.36 nonaka /*
8095 1.36 nonaka * Attach interface
8096 1.36 nonaka */
8097 1.36 nonaka ic->ic_ifp = ifp;
8098 1.36 nonaka ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
8099 1.36 nonaka ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
8100 1.36 nonaka ic->ic_state = IEEE80211_S_INIT;
8101 1.36 nonaka
8102 1.36 nonaka /* Set device capabilities. */
8103 1.36 nonaka ic->ic_caps =
8104 1.36 nonaka IEEE80211_C_WEP | /* WEP */
8105 1.36 nonaka IEEE80211_C_WPA | /* 802.11i */
8106 1.45 nonaka #ifdef notyet
8107 1.45 nonaka IEEE80211_C_SCANALL | /* device scans all channels at once */
8108 1.45 nonaka IEEE80211_C_SCANALLBAND | /* device scans all bands at once */
8109 1.45 nonaka #endif
8110 1.36 nonaka IEEE80211_C_SHSLOT | /* short slot time supported */
8111 1.36 nonaka IEEE80211_C_SHPREAMBLE; /* short preamble supported */
8112 1.36 nonaka
8113 1.45 nonaka #ifndef IEEE80211_NO_HT
8114 1.45 nonaka ic->ic_htcaps = IEEE80211_HTCAP_SGI20;
8115 1.45 nonaka ic->ic_htxcaps = 0;
8116 1.45 nonaka ic->ic_txbfcaps = 0;
8117 1.45 nonaka ic->ic_aselcaps = 0;
8118 1.45 nonaka ic->ic_ampdu_params = (IEEE80211_AMPDU_PARAM_SS_4 | 0x3 /* 64k */);
8119 1.45 nonaka #endif
8120 1.45 nonaka
8121 1.36 nonaka /* all hardware can do 2.4GHz band */
8122 1.36 nonaka ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
8123 1.36 nonaka ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
8124 1.36 nonaka
8125 1.87 riastrad /* not all hardware can do 5GHz band */
8126 1.87 riastrad if (sc->sc_nvm.sku_cap_band_52GHz_enable)
8127 1.87 riastrad ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a;
8128 1.87 riastrad
8129 1.87 riastrad #ifndef IEEE80211_NO_HT
8130 1.87 riastrad if (sc->sc_nvm.sku_cap_11n_enable)
8131 1.87 riastrad iwm_setup_ht_rates(sc);
8132 1.87 riastrad #endif
8133 1.87 riastrad
8134 1.36 nonaka for (int i = 0; i < __arraycount(sc->sc_phyctxt); i++) {
8135 1.36 nonaka sc->sc_phyctxt[i].id = i;
8136 1.36 nonaka }
8137 1.36 nonaka
8138 1.36 nonaka sc->sc_amrr.amrr_min_success_threshold = 1;
8139 1.36 nonaka sc->sc_amrr.amrr_max_success_threshold = 15;
8140 1.36 nonaka
8141 1.36 nonaka /* IBSS channel undefined for now. */
8142 1.36 nonaka ic->ic_ibss_chan = &ic->ic_channels[1];
8143 1.36 nonaka
8144 1.36 nonaka #if 0
8145 1.36 nonaka ic->ic_max_rssi = IWM_MAX_DBM - IWM_MIN_DBM;
8146 1.36 nonaka #endif
8147 1.36 nonaka
8148 1.36 nonaka ifp->if_softc = sc;
8149 1.36 nonaka ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
8150 1.36 nonaka ifp->if_init = iwm_init;
8151 1.36 nonaka ifp->if_stop = iwm_stop;
8152 1.36 nonaka ifp->if_ioctl = iwm_ioctl;
8153 1.36 nonaka ifp->if_start = iwm_start;
8154 1.36 nonaka ifp->if_watchdog = iwm_watchdog;
8155 1.36 nonaka IFQ_SET_READY(&ifp->if_snd);
8156 1.36 nonaka memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
8157 1.36 nonaka
8158 1.86 riastrad if_initialize(ifp);
8159 1.36 nonaka ieee80211_ifattach(ic);
8160 1.40 ozaki /* Use common softint-based if_input */
8161 1.40 ozaki ifp->if_percpuq = if_percpuq_create(ifp);
8162 1.44 ozaki if_register(ifp);
8163 1.36 nonaka
8164 1.87 riastrad ic->ic_node_alloc = iwm_node_alloc;
8165 1.87 riastrad
8166 1.87 riastrad /* Override 802.11 state transition machine. */
8167 1.87 riastrad sc->sc_newstate = ic->ic_newstate;
8168 1.87 riastrad ic->ic_newstate = iwm_newstate;
8169 1.87 riastrad
8170 1.87 riastrad /* XXX media locking needs revisiting */
8171 1.87 riastrad mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTNET);
8172 1.87 riastrad ieee80211_media_init_with_lock(ic,
8173 1.87 riastrad iwm_media_change, ieee80211_media_status, &sc->sc_media_mtx);
8174 1.87 riastrad
8175 1.87 riastrad ieee80211_announce(ic);
8176 1.87 riastrad
8177 1.87 riastrad iwm_radiotap_attach(sc);
8178 1.36 nonaka
8179 1.36 nonaka if (pmf_device_register(self, NULL, NULL))
8180 1.36 nonaka pmf_class_network_register(self, ifp);
8181 1.36 nonaka else
8182 1.36 nonaka aprint_error_dev(self, "couldn't establish power handler\n");
8183 1.36 nonaka
8184 1.87 riastrad sc->sc_flags |= IWM_FLAG_ATTACHED;
8185 1.2 nonaka
8186 1.87 riastrad return 0;
8187 1.1 pooka }
8188 1.1 pooka
8189 1.1 pooka void
8190 1.1 pooka iwm_radiotap_attach(struct iwm_softc *sc)
8191 1.1 pooka {
8192 1.47 nonaka struct ifnet *ifp = IC2IFP(&sc->sc_ic);
8193 1.1 pooka
8194 1.1 pooka bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
8195 1.1 pooka sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
8196 1.1 pooka &sc->sc_drvbpf);
8197 1.1 pooka
8198 1.1 pooka sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
8199 1.1 pooka sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
8200 1.1 pooka sc->sc_rxtap.wr_ihdr.it_present = htole32(IWM_RX_RADIOTAP_PRESENT);
8201 1.1 pooka
8202 1.1 pooka sc->sc_txtap_len = sizeof sc->sc_txtapu;
8203 1.1 pooka sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
8204 1.1 pooka sc->sc_txtap.wt_ihdr.it_present = htole32(IWM_TX_RADIOTAP_PRESENT);
8205 1.1 pooka }
8206 1.1 pooka
8207 1.1 pooka #if 0
8208 1.4 nonaka static void
8209 1.47 nonaka iwm_init_task(void *arg)
8210 1.1 pooka {
8211 1.47 nonaka struct iwm_softc *sc = arg;
8212 1.47 nonaka struct ifnet *ifp = IC2IFP(&sc->sc_ic);
8213 1.1 pooka int s;
8214 1.8 nonaka
8215 1.45 nonaka rw_enter_write(&sc->ioctl_rwl);
8216 1.1 pooka s = splnet();
8217 1.8 nonaka
8218 1.1 pooka iwm_stop(ifp, 0);
8219 1.1 pooka if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
8220 1.1 pooka iwm_init(ifp);
8221 1.1 pooka
8222 1.1 pooka splx(s);
8223 1.45 nonaka rw_exit(&sc->ioctl_rwl);
8224 1.1 pooka }
8225 1.1 pooka
8226 1.4 nonaka static void
8227 1.1 pooka iwm_wakeup(struct iwm_softc *sc)
8228 1.1 pooka {
8229 1.1 pooka pcireg_t reg;
8230 1.1 pooka
8231 1.1 pooka /* Clear device-specific "PCI retry timeout" register (41h). */
8232 1.1 pooka reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
8233 1.1 pooka pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
8234 1.1 pooka
8235 1.1 pooka iwm_init_task(sc);
8236 1.1 pooka }
8237 1.1 pooka
8238 1.4 nonaka static int
8239 1.4 nonaka iwm_activate(device_t self, enum devact act)
8240 1.1 pooka {
8241 1.4 nonaka struct iwm_softc *sc = device_private(self);
8242 1.4 nonaka struct ifnet *ifp = IC2IFP(&sc->sc_ic);
8243 1.1 pooka
8244 1.1 pooka switch (act) {
8245 1.4 nonaka case DVACT_DEACTIVATE:
8246 1.1 pooka if (ifp->if_flags & IFF_RUNNING)
8247 1.1 pooka iwm_stop(ifp, 0);
8248 1.4 nonaka return 0;
8249 1.4 nonaka default:
8250 1.4 nonaka return EOPNOTSUPP;
8251 1.1 pooka }
8252 1.1 pooka }
8253 1.1 pooka #endif
8254 1.1 pooka
8255 1.1 pooka CFATTACH_DECL_NEW(iwm, sizeof(struct iwm_softc), iwm_match, iwm_attach,
8256 1.1 pooka NULL, NULL);
8257 1.32 nonaka
8258 1.36 nonaka static int
8259 1.36 nonaka iwm_sysctl_fw_loaded_handler(SYSCTLFN_ARGS)
8260 1.36 nonaka {
8261 1.36 nonaka struct sysctlnode node;
8262 1.36 nonaka struct iwm_softc *sc;
8263 1.45 nonaka int err, t;
8264 1.36 nonaka
8265 1.36 nonaka node = *rnode;
8266 1.36 nonaka sc = node.sysctl_data;
8267 1.36 nonaka t = ISSET(sc->sc_flags, IWM_FLAG_FW_LOADED) ? 1 : 0;
8268 1.36 nonaka node.sysctl_data = &t;
8269 1.45 nonaka err = sysctl_lookup(SYSCTLFN_CALL(&node));
8270 1.45 nonaka if (err || newp == NULL)
8271 1.45 nonaka return err;
8272 1.36 nonaka
8273 1.36 nonaka if (t == 0)
8274 1.36 nonaka CLR(sc->sc_flags, IWM_FLAG_FW_LOADED);
8275 1.36 nonaka return 0;
8276 1.36 nonaka }
8277 1.36 nonaka
8278 1.32 nonaka SYSCTL_SETUP(sysctl_iwm, "sysctl iwm(4) subtree setup")
8279 1.32 nonaka {
8280 1.36 nonaka const struct sysctlnode *rnode;
8281 1.36 nonaka #ifdef IWM_DEBUG
8282 1.36 nonaka const struct sysctlnode *cnode;
8283 1.36 nonaka #endif /* IWM_DEBUG */
8284 1.32 nonaka int rc;
8285 1.32 nonaka
8286 1.32 nonaka if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
8287 1.32 nonaka CTLFLAG_PERMANENT, CTLTYPE_NODE, "iwm",
8288 1.32 nonaka SYSCTL_DESCR("iwm global controls"),
8289 1.32 nonaka NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
8290 1.32 nonaka goto err;
8291 1.32 nonaka
8292 1.36 nonaka iwm_sysctl_root_num = rnode->sysctl_num;
8293 1.36 nonaka
8294 1.36 nonaka #ifdef IWM_DEBUG
8295 1.32 nonaka /* control debugging printfs */
8296 1.32 nonaka if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
8297 1.32 nonaka CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
8298 1.32 nonaka "debug", SYSCTL_DESCR("Enable debugging output"),
8299 1.32 nonaka NULL, 0, &iwm_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
8300 1.32 nonaka goto err;
8301 1.36 nonaka #endif /* IWM_DEBUG */
8302 1.32 nonaka
8303 1.32 nonaka return;
8304 1.32 nonaka
8305 1.32 nonaka err:
8306 1.32 nonaka aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
8307 1.32 nonaka }
8308