if_iwm.c revision 1.42 1 1.42 ozaki /* $NetBSD: if_iwm.c,v 1.42 2016/06/10 13:27:14 ozaki-r Exp $ */
2 1.35 nonaka /* OpenBSD: if_iwm.c,v 1.41 2015/05/22 06:50:54 kettenis Exp */
3 1.1 pooka
4 1.1 pooka /*
5 1.1 pooka * Copyright (c) 2014 genua mbh <info (at) genua.de>
6 1.1 pooka * Copyright (c) 2014 Fixup Software Ltd.
7 1.1 pooka *
8 1.1 pooka * Permission to use, copy, modify, and distribute this software for any
9 1.1 pooka * purpose with or without fee is hereby granted, provided that the above
10 1.1 pooka * copyright notice and this permission notice appear in all copies.
11 1.1 pooka *
12 1.1 pooka * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 1.1 pooka * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 1.1 pooka * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 1.1 pooka * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 1.1 pooka * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 1.1 pooka * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 1.1 pooka * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 1.1 pooka */
20 1.1 pooka
21 1.1 pooka /*-
22 1.1 pooka * Based on BSD-licensed source modules in the Linux iwlwifi driver,
23 1.1 pooka * which were used as the reference documentation for this implementation.
24 1.1 pooka *
25 1.1 pooka * Driver version we are currently based off of is
26 1.1 pooka * Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
27 1.1 pooka *
28 1.1 pooka ***********************************************************************
29 1.1 pooka *
30 1.1 pooka * This file is provided under a dual BSD/GPLv2 license. When using or
31 1.1 pooka * redistributing this file, you may do so under either license.
32 1.1 pooka *
33 1.1 pooka * GPL LICENSE SUMMARY
34 1.1 pooka *
35 1.1 pooka * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
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.1 pooka * Intel Linux Wireless <ilw (at) linux.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 *
59 1.1 pooka * BSD LICENSE
60 1.1 pooka *
61 1.1 pooka * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
62 1.1 pooka * All rights reserved.
63 1.1 pooka *
64 1.1 pooka * Redistribution and use in source and binary forms, with or without
65 1.1 pooka * modification, are permitted provided that the following conditions
66 1.1 pooka * are met:
67 1.1 pooka *
68 1.1 pooka * * Redistributions of source code must retain the above copyright
69 1.1 pooka * notice, this list of conditions and the following disclaimer.
70 1.1 pooka * * Redistributions in binary form must reproduce the above copyright
71 1.1 pooka * notice, this list of conditions and the following disclaimer in
72 1.1 pooka * the documentation and/or other materials provided with the
73 1.1 pooka * distribution.
74 1.1 pooka * * Neither the name Intel Corporation nor the names of its
75 1.1 pooka * contributors may be used to endorse or promote products derived
76 1.1 pooka * from this software without specific prior written permission.
77 1.1 pooka *
78 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
79 1.1 pooka * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
80 1.1 pooka * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
81 1.1 pooka * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
82 1.1 pooka * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
83 1.1 pooka * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
84 1.1 pooka * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
85 1.1 pooka * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
86 1.1 pooka * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87 1.1 pooka * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
88 1.1 pooka * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89 1.1 pooka */
90 1.1 pooka
91 1.1 pooka /*-
92 1.1 pooka * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini (at) free.fr>
93 1.1 pooka *
94 1.1 pooka * Permission to use, copy, modify, and distribute this software for any
95 1.1 pooka * purpose with or without fee is hereby granted, provided that the above
96 1.1 pooka * copyright notice and this permission notice appear in all copies.
97 1.1 pooka *
98 1.1 pooka * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
99 1.1 pooka * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
100 1.1 pooka * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
101 1.1 pooka * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
102 1.1 pooka * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
103 1.1 pooka * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
104 1.1 pooka * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
105 1.1 pooka */
106 1.1 pooka
107 1.1 pooka #include <sys/cdefs.h>
108 1.42 ozaki __KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.42 2016/06/10 13:27:14 ozaki-r Exp $");
109 1.1 pooka
110 1.1 pooka #include <sys/param.h>
111 1.1 pooka #include <sys/conf.h>
112 1.1 pooka #include <sys/kernel.h>
113 1.1 pooka #include <sys/kmem.h>
114 1.1 pooka #include <sys/mbuf.h>
115 1.1 pooka #include <sys/mutex.h>
116 1.1 pooka #include <sys/proc.h>
117 1.1 pooka #include <sys/socket.h>
118 1.1 pooka #include <sys/sockio.h>
119 1.32 nonaka #include <sys/sysctl.h>
120 1.1 pooka #include <sys/systm.h>
121 1.1 pooka
122 1.1 pooka #include <sys/cpu.h>
123 1.1 pooka #include <sys/bus.h>
124 1.1 pooka #include <sys/workqueue.h>
125 1.1 pooka #include <machine/endian.h>
126 1.1 pooka #include <machine/intr.h>
127 1.1 pooka
128 1.1 pooka #include <dev/pci/pcireg.h>
129 1.1 pooka #include <dev/pci/pcivar.h>
130 1.1 pooka #include <dev/pci/pcidevs.h>
131 1.1 pooka #include <dev/firmload.h>
132 1.1 pooka
133 1.1 pooka #include <net/bpf.h>
134 1.1 pooka #include <net/if.h>
135 1.1 pooka #include <net/if_arp.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_types.h>
139 1.1 pooka #include <net/if_ether.h>
140 1.1 pooka
141 1.1 pooka #include <netinet/in.h>
142 1.1 pooka #include <netinet/in_systm.h>
143 1.1 pooka #include <netinet/ip.h>
144 1.1 pooka
145 1.1 pooka #include <net80211/ieee80211_var.h>
146 1.1 pooka #include <net80211/ieee80211_amrr.h>
147 1.1 pooka #include <net80211/ieee80211_radiotap.h>
148 1.1 pooka
149 1.1 pooka #define DEVNAME(_s) device_xname((_s)->sc_dev)
150 1.1 pooka #define IC2IFP(_ic_) ((_ic_)->ic_ifp)
151 1.1 pooka
152 1.1 pooka #define le16_to_cpup(_a_) (le16toh(*(const uint16_t *)(_a_)))
153 1.1 pooka #define le32_to_cpup(_a_) (le32toh(*(const uint32_t *)(_a_)))
154 1.1 pooka
155 1.1 pooka #ifdef IWM_DEBUG
156 1.1 pooka #define DPRINTF(x) do { if (iwm_debug > 0) printf x; } while (0)
157 1.1 pooka #define DPRINTFN(n, x) do { if (iwm_debug >= (n)) printf x; } while (0)
158 1.32 nonaka int iwm_debug = 0;
159 1.1 pooka #else
160 1.1 pooka #define DPRINTF(x) do { ; } while (0)
161 1.1 pooka #define DPRINTFN(n, x) do { ; } while (0)
162 1.1 pooka #endif
163 1.1 pooka
164 1.1 pooka #include <dev/pci/if_iwmreg.h>
165 1.1 pooka #include <dev/pci/if_iwmvar.h>
166 1.1 pooka
167 1.4 nonaka static const uint8_t iwm_nvm_channels[] = {
168 1.1 pooka /* 2.4 GHz */
169 1.1 pooka 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
170 1.1 pooka /* 5 GHz */
171 1.1 pooka 36, 40, 44 , 48, 52, 56, 60, 64,
172 1.1 pooka 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
173 1.1 pooka 149, 153, 157, 161, 165
174 1.1 pooka };
175 1.1 pooka #define IWM_NUM_2GHZ_CHANNELS 14
176 1.1 pooka
177 1.4 nonaka static const struct iwm_rate {
178 1.1 pooka uint8_t rate;
179 1.1 pooka uint8_t plcp;
180 1.1 pooka } iwm_rates[] = {
181 1.1 pooka { 2, IWM_RATE_1M_PLCP },
182 1.1 pooka { 4, IWM_RATE_2M_PLCP },
183 1.1 pooka { 11, IWM_RATE_5M_PLCP },
184 1.1 pooka { 22, IWM_RATE_11M_PLCP },
185 1.1 pooka { 12, IWM_RATE_6M_PLCP },
186 1.1 pooka { 18, IWM_RATE_9M_PLCP },
187 1.1 pooka { 24, IWM_RATE_12M_PLCP },
188 1.1 pooka { 36, IWM_RATE_18M_PLCP },
189 1.1 pooka { 48, IWM_RATE_24M_PLCP },
190 1.1 pooka { 72, IWM_RATE_36M_PLCP },
191 1.1 pooka { 96, IWM_RATE_48M_PLCP },
192 1.1 pooka { 108, IWM_RATE_54M_PLCP },
193 1.1 pooka };
194 1.1 pooka #define IWM_RIDX_CCK 0
195 1.1 pooka #define IWM_RIDX_OFDM 4
196 1.1 pooka #define IWM_RIDX_MAX (__arraycount(iwm_rates)-1)
197 1.1 pooka #define IWM_RIDX_IS_CCK(_i_) ((_i_) < IWM_RIDX_OFDM)
198 1.1 pooka #define IWM_RIDX_IS_OFDM(_i_) ((_i_) >= IWM_RIDX_OFDM)
199 1.1 pooka
200 1.1 pooka struct iwm_newstate_state {
201 1.1 pooka struct work ns_wk;
202 1.1 pooka enum ieee80211_state ns_nstate;
203 1.1 pooka int ns_arg;
204 1.1 pooka int ns_generation;
205 1.1 pooka };
206 1.1 pooka
207 1.4 nonaka static int iwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t);
208 1.4 nonaka static int iwm_firmware_store_section(struct iwm_softc *,
209 1.4 nonaka enum iwm_ucode_type, uint8_t *, size_t);
210 1.4 nonaka static int iwm_set_default_calib(struct iwm_softc *, const void *);
211 1.4 nonaka static int iwm_read_firmware(struct iwm_softc *);
212 1.4 nonaka static uint32_t iwm_read_prph(struct iwm_softc *, uint32_t);
213 1.4 nonaka static void iwm_write_prph(struct iwm_softc *, uint32_t, uint32_t);
214 1.2 nonaka #ifdef IWM_DEBUG
215 1.4 nonaka static int iwm_read_mem(struct iwm_softc *, uint32_t, void *, int);
216 1.2 nonaka #endif
217 1.4 nonaka static int iwm_write_mem(struct iwm_softc *, uint32_t, const void *, int);
218 1.4 nonaka static int iwm_write_mem32(struct iwm_softc *, uint32_t, uint32_t);
219 1.4 nonaka static int iwm_poll_bit(struct iwm_softc *, int, uint32_t, uint32_t, int);
220 1.4 nonaka static int iwm_nic_lock(struct iwm_softc *);
221 1.4 nonaka static void iwm_nic_unlock(struct iwm_softc *);
222 1.4 nonaka static void iwm_set_bits_mask_prph(struct iwm_softc *, uint32_t, uint32_t,
223 1.8 nonaka uint32_t);
224 1.4 nonaka static void iwm_set_bits_prph(struct iwm_softc *, uint32_t, uint32_t);
225 1.4 nonaka static void iwm_clear_bits_prph(struct iwm_softc *, uint32_t, uint32_t);
226 1.4 nonaka static int iwm_dma_contig_alloc(bus_dma_tag_t, struct iwm_dma_info *,
227 1.4 nonaka bus_size_t, bus_size_t);
228 1.4 nonaka static void iwm_dma_contig_free(struct iwm_dma_info *);
229 1.4 nonaka static int iwm_alloc_fwmem(struct iwm_softc *);
230 1.4 nonaka static void iwm_free_fwmem(struct iwm_softc *);
231 1.4 nonaka static int iwm_alloc_sched(struct iwm_softc *);
232 1.4 nonaka static void iwm_free_sched(struct iwm_softc *);
233 1.4 nonaka static int iwm_alloc_kw(struct iwm_softc *);
234 1.4 nonaka static void iwm_free_kw(struct iwm_softc *);
235 1.4 nonaka static int iwm_alloc_ict(struct iwm_softc *);
236 1.4 nonaka static void iwm_free_ict(struct iwm_softc *);
237 1.4 nonaka static int iwm_alloc_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
238 1.4 nonaka static void iwm_reset_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
239 1.4 nonaka static void iwm_free_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
240 1.4 nonaka static int iwm_alloc_tx_ring(struct iwm_softc *, struct iwm_tx_ring *,
241 1.4 nonaka int);
242 1.4 nonaka static void iwm_reset_tx_ring(struct iwm_softc *, struct iwm_tx_ring *);
243 1.4 nonaka static void iwm_free_tx_ring(struct iwm_softc *, struct iwm_tx_ring *);
244 1.4 nonaka static void iwm_enable_rfkill_int(struct iwm_softc *);
245 1.4 nonaka static int iwm_check_rfkill(struct iwm_softc *);
246 1.4 nonaka static void iwm_enable_interrupts(struct iwm_softc *);
247 1.4 nonaka static void iwm_restore_interrupts(struct iwm_softc *);
248 1.4 nonaka static void iwm_disable_interrupts(struct iwm_softc *);
249 1.4 nonaka static void iwm_ict_reset(struct iwm_softc *);
250 1.4 nonaka static int iwm_set_hw_ready(struct iwm_softc *);
251 1.4 nonaka static int iwm_prepare_card_hw(struct iwm_softc *);
252 1.4 nonaka static void iwm_apm_config(struct iwm_softc *);
253 1.4 nonaka static int iwm_apm_init(struct iwm_softc *);
254 1.4 nonaka static void iwm_apm_stop(struct iwm_softc *);
255 1.11 nonaka static int iwm_allow_mcast(struct iwm_softc *);
256 1.4 nonaka static int iwm_start_hw(struct iwm_softc *);
257 1.4 nonaka static void iwm_stop_device(struct iwm_softc *);
258 1.4 nonaka static void iwm_set_pwr(struct iwm_softc *);
259 1.4 nonaka static void iwm_mvm_nic_config(struct iwm_softc *);
260 1.4 nonaka static int iwm_nic_rx_init(struct iwm_softc *);
261 1.4 nonaka static int iwm_nic_tx_init(struct iwm_softc *);
262 1.4 nonaka static int iwm_nic_init(struct iwm_softc *);
263 1.4 nonaka static void iwm_enable_txq(struct iwm_softc *, int, int);
264 1.4 nonaka static int iwm_post_alive(struct iwm_softc *);
265 1.4 nonaka static int iwm_is_valid_channel(uint16_t);
266 1.4 nonaka static uint8_t iwm_ch_id_to_ch_index(uint16_t);
267 1.4 nonaka static uint16_t iwm_channel_id_to_papd(uint16_t);
268 1.4 nonaka static uint16_t iwm_channel_id_to_txp(struct iwm_softc *, uint16_t);
269 1.4 nonaka static int iwm_phy_db_get_section_data(struct iwm_softc *, uint32_t,
270 1.4 nonaka uint8_t **, uint16_t *, uint16_t);
271 1.4 nonaka static int iwm_send_phy_db_cmd(struct iwm_softc *, uint16_t, uint16_t,
272 1.4 nonaka void *);
273 1.4 nonaka static int iwm_send_phy_db_data(struct iwm_softc *);
274 1.4 nonaka static int iwm_send_phy_db_data(struct iwm_softc *);
275 1.4 nonaka static void iwm_mvm_te_v2_to_v1(const struct iwm_time_event_cmd_v2 *,
276 1.4 nonaka struct iwm_time_event_cmd_v1 *);
277 1.4 nonaka static int iwm_mvm_send_time_event_cmd(struct iwm_softc *,
278 1.4 nonaka const struct iwm_time_event_cmd_v2 *);
279 1.4 nonaka static int iwm_mvm_time_event_send_add(struct iwm_softc *,
280 1.4 nonaka struct iwm_node *, void *, struct iwm_time_event_cmd_v2 *);
281 1.4 nonaka static void iwm_mvm_protect_session(struct iwm_softc *, struct iwm_node *,
282 1.4 nonaka uint32_t, uint32_t, uint32_t);
283 1.4 nonaka static int iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, uint16_t,
284 1.4 nonaka uint16_t, uint8_t *, uint16_t *);
285 1.4 nonaka static int iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *,
286 1.4 nonaka uint16_t *);
287 1.4 nonaka static void iwm_init_channel_map(struct iwm_softc *,
288 1.4 nonaka const uint16_t * const);
289 1.4 nonaka static int iwm_parse_nvm_data(struct iwm_softc *, const uint16_t *,
290 1.4 nonaka const uint16_t *, const uint16_t *, uint8_t, uint8_t);
291 1.4 nonaka static int iwm_nvm_init(struct iwm_softc *);
292 1.4 nonaka static int iwm_firmware_load_chunk(struct iwm_softc *, uint32_t,
293 1.4 nonaka const uint8_t *, uint32_t);
294 1.4 nonaka static int iwm_load_firmware(struct iwm_softc *, enum iwm_ucode_type);
295 1.4 nonaka static int iwm_start_fw(struct iwm_softc *, enum iwm_ucode_type);
296 1.4 nonaka static int iwm_fw_alive(struct iwm_softc *, uint32_t);
297 1.4 nonaka static int iwm_send_tx_ant_cfg(struct iwm_softc *, uint8_t);
298 1.4 nonaka static int iwm_send_phy_cfg_cmd(struct iwm_softc *);
299 1.4 nonaka static int iwm_mvm_load_ucode_wait_alive(struct iwm_softc *,
300 1.4 nonaka enum iwm_ucode_type);
301 1.4 nonaka static int iwm_run_init_mvm_ucode(struct iwm_softc *, int);
302 1.4 nonaka static int iwm_rx_addbuf(struct iwm_softc *, int, int);
303 1.4 nonaka static int iwm_mvm_calc_rssi(struct iwm_softc *, struct iwm_rx_phy_info *);
304 1.4 nonaka static int iwm_mvm_get_signal_strength(struct iwm_softc *,
305 1.4 nonaka struct iwm_rx_phy_info *);
306 1.4 nonaka static void iwm_mvm_rx_rx_phy_cmd(struct iwm_softc *,
307 1.4 nonaka struct iwm_rx_packet *, struct iwm_rx_data *);
308 1.4 nonaka static int iwm_get_noise(const struct iwm_mvm_statistics_rx_non_phy *);
309 1.4 nonaka static void iwm_mvm_rx_rx_mpdu(struct iwm_softc *, struct iwm_rx_packet *,
310 1.4 nonaka struct iwm_rx_data *);
311 1.4 nonaka static void iwm_mvm_rx_tx_cmd_single(struct iwm_softc *,
312 1.4 nonaka struct iwm_rx_packet *, struct iwm_node *);
313 1.4 nonaka static void iwm_mvm_rx_tx_cmd(struct iwm_softc *, struct iwm_rx_packet *,
314 1.4 nonaka struct iwm_rx_data *);
315 1.4 nonaka static int iwm_mvm_binding_cmd(struct iwm_softc *, struct iwm_node *,
316 1.4 nonaka uint32_t);
317 1.4 nonaka static int iwm_mvm_binding_update(struct iwm_softc *, struct iwm_node *,
318 1.4 nonaka int);
319 1.4 nonaka static int iwm_mvm_binding_add_vif(struct iwm_softc *, struct iwm_node *);
320 1.4 nonaka static void iwm_mvm_phy_ctxt_cmd_hdr(struct iwm_softc *,
321 1.4 nonaka struct iwm_mvm_phy_ctxt *, struct iwm_phy_context_cmd *,
322 1.4 nonaka uint32_t, uint32_t);
323 1.4 nonaka static void iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *,
324 1.4 nonaka struct iwm_phy_context_cmd *, struct ieee80211_channel *,
325 1.4 nonaka uint8_t, uint8_t);
326 1.4 nonaka static int iwm_mvm_phy_ctxt_apply(struct iwm_softc *,
327 1.4 nonaka struct iwm_mvm_phy_ctxt *, uint8_t, uint8_t, uint32_t,
328 1.4 nonaka uint32_t);
329 1.4 nonaka static int iwm_mvm_phy_ctxt_add(struct iwm_softc *,
330 1.4 nonaka struct iwm_mvm_phy_ctxt *, struct ieee80211_channel *,
331 1.4 nonaka uint8_t, uint8_t);
332 1.4 nonaka static int iwm_mvm_phy_ctxt_changed(struct iwm_softc *,
333 1.4 nonaka struct iwm_mvm_phy_ctxt *, struct ieee80211_channel *,
334 1.4 nonaka uint8_t, uint8_t);
335 1.4 nonaka static int iwm_send_cmd(struct iwm_softc *, struct iwm_host_cmd *);
336 1.4 nonaka static int iwm_mvm_send_cmd_pdu(struct iwm_softc *, uint8_t, uint32_t,
337 1.4 nonaka uint16_t, const void *);
338 1.4 nonaka static int iwm_mvm_send_cmd_status(struct iwm_softc *,
339 1.4 nonaka struct iwm_host_cmd *, uint32_t *);
340 1.4 nonaka static int iwm_mvm_send_cmd_pdu_status(struct iwm_softc *, uint8_t,
341 1.4 nonaka uint16_t, const void *, uint32_t *);
342 1.4 nonaka static void iwm_free_resp(struct iwm_softc *, struct iwm_host_cmd *);
343 1.4 nonaka static void iwm_cmd_done(struct iwm_softc *, struct iwm_rx_packet *);
344 1.4 nonaka #if 0
345 1.4 nonaka static void iwm_update_sched(struct iwm_softc *, int, int, uint8_t,
346 1.4 nonaka uint16_t);
347 1.4 nonaka #endif
348 1.4 nonaka static const struct iwm_rate *iwm_tx_fill_cmd(struct iwm_softc *,
349 1.4 nonaka struct iwm_node *, struct ieee80211_frame *,
350 1.4 nonaka struct iwm_tx_cmd *);
351 1.4 nonaka static int iwm_tx(struct iwm_softc *, struct mbuf *,
352 1.4 nonaka struct ieee80211_node *, int);
353 1.4 nonaka static int iwm_mvm_beacon_filter_send_cmd(struct iwm_softc *,
354 1.4 nonaka struct iwm_beacon_filter_cmd *);
355 1.4 nonaka static void iwm_mvm_beacon_filter_set_cqm_params(struct iwm_softc *,
356 1.4 nonaka struct iwm_node *, struct iwm_beacon_filter_cmd *);
357 1.4 nonaka static int iwm_mvm_update_beacon_abort(struct iwm_softc *,
358 1.4 nonaka struct iwm_node *, int);
359 1.4 nonaka static void iwm_mvm_power_log(struct iwm_softc *,
360 1.4 nonaka struct iwm_mac_power_cmd *);
361 1.4 nonaka static void iwm_mvm_power_build_cmd(struct iwm_softc *, struct iwm_node *,
362 1.4 nonaka struct iwm_mac_power_cmd *);
363 1.4 nonaka static int iwm_mvm_power_mac_update_mode(struct iwm_softc *,
364 1.4 nonaka struct iwm_node *);
365 1.4 nonaka static int iwm_mvm_power_update_device(struct iwm_softc *);
366 1.4 nonaka static int iwm_mvm_enable_beacon_filter(struct iwm_softc *,
367 1.4 nonaka struct iwm_node *);
368 1.4 nonaka static int iwm_mvm_disable_beacon_filter(struct iwm_softc *,
369 1.4 nonaka struct iwm_node *);
370 1.4 nonaka static void iwm_mvm_add_sta_cmd_v6_to_v5(struct iwm_mvm_add_sta_cmd_v6 *,
371 1.4 nonaka struct iwm_mvm_add_sta_cmd_v5 *);
372 1.4 nonaka static int iwm_mvm_send_add_sta_cmd_status(struct iwm_softc *,
373 1.4 nonaka struct iwm_mvm_add_sta_cmd_v6 *, int *);
374 1.4 nonaka static int iwm_mvm_sta_send_to_fw(struct iwm_softc *, struct iwm_node *,
375 1.4 nonaka int);
376 1.4 nonaka static int iwm_mvm_add_sta(struct iwm_softc *, struct iwm_node *);
377 1.4 nonaka static int iwm_mvm_update_sta(struct iwm_softc *, struct iwm_node *);
378 1.4 nonaka static int iwm_mvm_add_int_sta_common(struct iwm_softc *,
379 1.4 nonaka struct iwm_int_sta *, const uint8_t *, uint16_t, uint16_t);
380 1.4 nonaka static int iwm_mvm_add_aux_sta(struct iwm_softc *);
381 1.4 nonaka static uint16_t iwm_mvm_scan_rx_chain(struct iwm_softc *);
382 1.4 nonaka static uint32_t iwm_mvm_scan_max_out_time(struct iwm_softc *, uint32_t, int);
383 1.4 nonaka static uint32_t iwm_mvm_scan_suspend_time(struct iwm_softc *, int);
384 1.4 nonaka static uint32_t iwm_mvm_scan_rxon_flags(struct iwm_softc *, int);
385 1.4 nonaka static uint32_t iwm_mvm_scan_rate_n_flags(struct iwm_softc *, int, int);
386 1.4 nonaka static uint16_t iwm_mvm_get_active_dwell(struct iwm_softc *, int, int);
387 1.4 nonaka static uint16_t iwm_mvm_get_passive_dwell(struct iwm_softc *, int);
388 1.4 nonaka static int iwm_mvm_scan_fill_channels(struct iwm_softc *,
389 1.4 nonaka struct iwm_scan_cmd *, int, int, int);
390 1.4 nonaka static uint16_t iwm_mvm_fill_probe_req(struct iwm_softc *,
391 1.4 nonaka struct ieee80211_frame *, const uint8_t *, int,
392 1.4 nonaka const uint8_t *, int, const uint8_t *, int, int);
393 1.4 nonaka static int iwm_mvm_scan_request(struct iwm_softc *, int, int, uint8_t *,
394 1.4 nonaka int);
395 1.4 nonaka static void iwm_mvm_ack_rates(struct iwm_softc *, struct iwm_node *, int *,
396 1.4 nonaka int *);
397 1.4 nonaka static void iwm_mvm_mac_ctxt_cmd_common(struct iwm_softc *,
398 1.4 nonaka struct iwm_node *, struct iwm_mac_ctx_cmd *, uint32_t);
399 1.4 nonaka static int iwm_mvm_mac_ctxt_send_cmd(struct iwm_softc *,
400 1.4 nonaka struct iwm_mac_ctx_cmd *);
401 1.4 nonaka static void iwm_mvm_mac_ctxt_cmd_fill_sta(struct iwm_softc *,
402 1.4 nonaka struct iwm_node *, struct iwm_mac_data_sta *, int);
403 1.4 nonaka static int iwm_mvm_mac_ctxt_cmd_station(struct iwm_softc *,
404 1.4 nonaka struct iwm_node *, uint32_t);
405 1.4 nonaka static int iwm_mvm_mac_ctx_send(struct iwm_softc *, struct iwm_node *,
406 1.4 nonaka uint32_t);
407 1.4 nonaka static int iwm_mvm_mac_ctxt_add(struct iwm_softc *, struct iwm_node *);
408 1.4 nonaka static int iwm_mvm_mac_ctxt_changed(struct iwm_softc *, struct iwm_node *);
409 1.4 nonaka static int iwm_mvm_update_quotas(struct iwm_softc *, struct iwm_node *);
410 1.4 nonaka static int iwm_auth(struct iwm_softc *);
411 1.4 nonaka static int iwm_assoc(struct iwm_softc *);
412 1.4 nonaka static int iwm_release(struct iwm_softc *, struct iwm_node *);
413 1.4 nonaka static void iwm_calib_timeout(void *);
414 1.4 nonaka static void iwm_setrates(struct iwm_node *);
415 1.4 nonaka static int iwm_media_change(struct ifnet *);
416 1.5 nonaka static void iwm_newstate_cb(struct work *, void *);
417 1.4 nonaka static int iwm_newstate(struct ieee80211com *, enum ieee80211_state, int);
418 1.5 nonaka static void iwm_endscan_cb(struct work *, void *);
419 1.4 nonaka static int iwm_init_hw(struct iwm_softc *);
420 1.4 nonaka static int iwm_init(struct ifnet *);
421 1.4 nonaka static void iwm_start(struct ifnet *);
422 1.4 nonaka static void iwm_stop(struct ifnet *, int);
423 1.4 nonaka static void iwm_watchdog(struct ifnet *);
424 1.4 nonaka static int iwm_ioctl(struct ifnet *, u_long, void *);
425 1.4 nonaka #ifdef IWM_DEBUG
426 1.4 nonaka static const char *iwm_desc_lookup(uint32_t);
427 1.4 nonaka static void iwm_nic_error(struct iwm_softc *);
428 1.4 nonaka #endif
429 1.4 nonaka static void iwm_notif_intr(struct iwm_softc *);
430 1.4 nonaka static int iwm_intr(void *);
431 1.4 nonaka static int iwm_preinit(struct iwm_softc *);
432 1.4 nonaka static void iwm_attach_hook(device_t);
433 1.4 nonaka static void iwm_attach(device_t, device_t, void *);
434 1.4 nonaka #if 0
435 1.4 nonaka static void iwm_init_task(void *);
436 1.4 nonaka static int iwm_activate(device_t, enum devact);
437 1.4 nonaka static void iwm_wakeup(struct iwm_softc *);
438 1.4 nonaka #endif
439 1.4 nonaka static void iwm_radiotap_attach(struct iwm_softc *);
440 1.36 nonaka static int iwm_sysctl_fw_loaded_handler(SYSCTLFN_PROTO);
441 1.36 nonaka
442 1.36 nonaka static int iwm_sysctl_root_num;
443 1.1 pooka
444 1.1 pooka static int
445 1.1 pooka iwm_firmload(struct iwm_softc *sc)
446 1.1 pooka {
447 1.1 pooka struct iwm_fw_info *fw = &sc->sc_fw;
448 1.1 pooka firmware_handle_t fwh;
449 1.1 pooka int error;
450 1.1 pooka
451 1.36 nonaka if (ISSET(sc->sc_flags, IWM_FLAG_FW_LOADED))
452 1.36 nonaka return 0;
453 1.36 nonaka
454 1.1 pooka /* Open firmware image. */
455 1.1 pooka if ((error = firmware_open("if_iwm", sc->sc_fwname, &fwh)) != 0) {
456 1.1 pooka aprint_error_dev(sc->sc_dev,
457 1.1 pooka "could not get firmware handle %s\n", sc->sc_fwname);
458 1.1 pooka return error;
459 1.1 pooka }
460 1.1 pooka
461 1.36 nonaka if (fw->fw_rawdata != NULL && fw->fw_rawsize > 0) {
462 1.36 nonaka kmem_free(fw->fw_rawdata, fw->fw_rawsize);
463 1.36 nonaka fw->fw_rawdata = NULL;
464 1.36 nonaka }
465 1.36 nonaka
466 1.1 pooka fw->fw_rawsize = firmware_get_size(fwh);
467 1.1 pooka /*
468 1.1 pooka * Well, this is how the Linux driver checks it ....
469 1.1 pooka */
470 1.1 pooka if (fw->fw_rawsize < sizeof(uint32_t)) {
471 1.1 pooka aprint_error_dev(sc->sc_dev,
472 1.1 pooka "firmware too short: %zd bytes\n", fw->fw_rawsize);
473 1.1 pooka error = EINVAL;
474 1.1 pooka goto out;
475 1.1 pooka }
476 1.1 pooka
477 1.1 pooka /* some sanity */
478 1.1 pooka if (fw->fw_rawsize > IWM_FWMAXSIZE) {
479 1.1 pooka aprint_error_dev(sc->sc_dev,
480 1.36 nonaka "firmware size is ridiculous: %zd bytes\n", fw->fw_rawsize);
481 1.1 pooka error = EINVAL;
482 1.1 pooka goto out;
483 1.1 pooka }
484 1.1 pooka
485 1.1 pooka /* Read the firmware. */
486 1.1 pooka fw->fw_rawdata = kmem_alloc(fw->fw_rawsize, KM_SLEEP);
487 1.1 pooka if (fw->fw_rawdata == NULL) {
488 1.1 pooka aprint_error_dev(sc->sc_dev,
489 1.1 pooka "not enough memory to stock firmware %s\n", sc->sc_fwname);
490 1.1 pooka error = ENOMEM;
491 1.1 pooka goto out;
492 1.1 pooka }
493 1.1 pooka error = firmware_read(fwh, 0, fw->fw_rawdata, fw->fw_rawsize);
494 1.1 pooka if (error) {
495 1.1 pooka aprint_error_dev(sc->sc_dev,
496 1.1 pooka "could not read firmware %s\n", sc->sc_fwname);
497 1.1 pooka goto out;
498 1.1 pooka }
499 1.1 pooka
500 1.36 nonaka SET(sc->sc_flags, IWM_FLAG_FW_LOADED);
501 1.1 pooka out:
502 1.1 pooka /* caller will release memory, if necessary */
503 1.1 pooka
504 1.1 pooka firmware_close(fwh);
505 1.1 pooka return error;
506 1.1 pooka }
507 1.1 pooka
508 1.1 pooka /*
509 1.1 pooka * just maintaining status quo.
510 1.1 pooka */
511 1.1 pooka static void
512 1.1 pooka iwm_fix_channel(struct ieee80211com *ic, struct mbuf *m)
513 1.1 pooka {
514 1.34 nonaka struct iwm_softc *sc = ic->ic_ifp->if_softc;
515 1.1 pooka struct ieee80211_frame *wh;
516 1.1 pooka uint8_t subtype;
517 1.1 pooka uint8_t *frm, *efrm;
518 1.1 pooka
519 1.1 pooka wh = mtod(m, struct ieee80211_frame *);
520 1.1 pooka
521 1.1 pooka if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
522 1.1 pooka return;
523 1.1 pooka
524 1.1 pooka subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
525 1.1 pooka
526 1.1 pooka if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
527 1.1 pooka subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP)
528 1.1 pooka return;
529 1.1 pooka
530 1.34 nonaka if (sc->sc_scanband == IEEE80211_CHAN_5GHZ) {
531 1.34 nonaka int chan = le32toh(sc->sc_last_phy_info.channel);
532 1.34 nonaka if (chan < __arraycount(ic->ic_channels))
533 1.34 nonaka ic->ic_curchan = &ic->ic_channels[chan];
534 1.34 nonaka return;
535 1.34 nonaka }
536 1.34 nonaka
537 1.1 pooka frm = (uint8_t *)(wh + 1);
538 1.1 pooka efrm = mtod(m, uint8_t *) + m->m_len;
539 1.1 pooka
540 1.1 pooka frm += 12; /* skip tstamp, bintval and capinfo fields */
541 1.1 pooka while (frm < efrm) {
542 1.1 pooka if (*frm == IEEE80211_ELEMID_DSPARMS) {
543 1.1 pooka #if IEEE80211_CHAN_MAX < 255
544 1.1 pooka if (frm[2] <= IEEE80211_CHAN_MAX)
545 1.1 pooka #endif
546 1.1 pooka ic->ic_curchan = &ic->ic_channels[frm[2]];
547 1.1 pooka }
548 1.1 pooka frm += frm[1] + 2;
549 1.1 pooka }
550 1.1 pooka }
551 1.1 pooka
552 1.1 pooka /*
553 1.1 pooka * Firmware parser.
554 1.1 pooka */
555 1.1 pooka
556 1.4 nonaka static int
557 1.1 pooka iwm_store_cscheme(struct iwm_softc *sc, uint8_t *data, size_t dlen)
558 1.1 pooka {
559 1.1 pooka struct iwm_fw_cscheme_list *l = (void *)data;
560 1.1 pooka
561 1.1 pooka if (dlen < sizeof(*l) ||
562 1.1 pooka dlen < sizeof(l->size) + l->size * sizeof(*l->cs))
563 1.1 pooka return EINVAL;
564 1.1 pooka
565 1.1 pooka /* we don't actually store anything for now, always use s/w crypto */
566 1.1 pooka
567 1.1 pooka return 0;
568 1.1 pooka }
569 1.1 pooka
570 1.4 nonaka static int
571 1.1 pooka iwm_firmware_store_section(struct iwm_softc *sc,
572 1.1 pooka enum iwm_ucode_type type, uint8_t *data, size_t dlen)
573 1.1 pooka {
574 1.1 pooka struct iwm_fw_sects *fws;
575 1.1 pooka struct iwm_fw_onesect *fwone;
576 1.1 pooka
577 1.1 pooka if (type >= IWM_UCODE_TYPE_MAX)
578 1.1 pooka return EINVAL;
579 1.1 pooka if (dlen < sizeof(uint32_t))
580 1.1 pooka return EINVAL;
581 1.1 pooka
582 1.1 pooka fws = &sc->sc_fw.fw_sects[type];
583 1.1 pooka if (fws->fw_count >= IWM_UCODE_SECT_MAX)
584 1.1 pooka return EINVAL;
585 1.1 pooka
586 1.1 pooka fwone = &fws->fw_sect[fws->fw_count];
587 1.1 pooka
588 1.1 pooka /* first 32bit are device load offset */
589 1.1 pooka memcpy(&fwone->fws_devoff, data, sizeof(uint32_t));
590 1.1 pooka
591 1.1 pooka /* rest is data */
592 1.1 pooka fwone->fws_data = data + sizeof(uint32_t);
593 1.1 pooka fwone->fws_len = dlen - sizeof(uint32_t);
594 1.1 pooka
595 1.1 pooka /* for freeing the buffer during driver unload */
596 1.1 pooka fwone->fws_alloc = data;
597 1.1 pooka fwone->fws_allocsize = dlen;
598 1.1 pooka
599 1.1 pooka fws->fw_count++;
600 1.1 pooka fws->fw_totlen += fwone->fws_len;
601 1.1 pooka
602 1.1 pooka return 0;
603 1.1 pooka }
604 1.1 pooka
605 1.1 pooka /* iwlwifi: iwl-drv.c */
606 1.1 pooka struct iwm_tlv_calib_data {
607 1.1 pooka uint32_t ucode_type;
608 1.1 pooka struct iwm_tlv_calib_ctrl calib;
609 1.1 pooka } __packed;
610 1.1 pooka
611 1.4 nonaka static int
612 1.1 pooka iwm_set_default_calib(struct iwm_softc *sc, const void *data)
613 1.1 pooka {
614 1.1 pooka const struct iwm_tlv_calib_data *def_calib = data;
615 1.1 pooka uint32_t ucode_type = le32toh(def_calib->ucode_type);
616 1.1 pooka
617 1.1 pooka if (ucode_type >= IWM_UCODE_TYPE_MAX) {
618 1.2 nonaka DPRINTF(("%s: Wrong ucode_type %u for default "
619 1.2 nonaka "calibration.\n", DEVNAME(sc), ucode_type));
620 1.1 pooka return EINVAL;
621 1.1 pooka }
622 1.1 pooka
623 1.1 pooka sc->sc_default_calib[ucode_type].flow_trigger =
624 1.1 pooka def_calib->calib.flow_trigger;
625 1.1 pooka sc->sc_default_calib[ucode_type].event_trigger =
626 1.1 pooka def_calib->calib.event_trigger;
627 1.1 pooka
628 1.1 pooka return 0;
629 1.1 pooka }
630 1.1 pooka
631 1.4 nonaka static int
632 1.1 pooka iwm_read_firmware(struct iwm_softc *sc)
633 1.1 pooka {
634 1.1 pooka struct iwm_fw_info *fw = &sc->sc_fw;
635 1.8 nonaka struct iwm_tlv_ucode_header *uhdr;
636 1.8 nonaka struct iwm_ucode_tlv tlv;
637 1.1 pooka enum iwm_ucode_tlv_type tlv_type;
638 1.1 pooka uint8_t *data;
639 1.2 nonaka int error, status;
640 1.2 nonaka size_t len;
641 1.1 pooka
642 1.1 pooka if (fw->fw_status == IWM_FW_STATUS_NONE) {
643 1.1 pooka fw->fw_status = IWM_FW_STATUS_INPROGRESS;
644 1.1 pooka } else {
645 1.1 pooka while (fw->fw_status == IWM_FW_STATUS_INPROGRESS)
646 1.1 pooka tsleep(&sc->sc_fw, 0, "iwmfwp", 0);
647 1.1 pooka }
648 1.1 pooka status = fw->fw_status;
649 1.1 pooka
650 1.1 pooka if (status == IWM_FW_STATUS_DONE)
651 1.1 pooka return 0;
652 1.1 pooka
653 1.1 pooka /*
654 1.1 pooka * Load firmware into driver memory.
655 1.1 pooka * fw_rawdata and fw_rawsize will be set.
656 1.1 pooka */
657 1.1 pooka error = iwm_firmload(sc);
658 1.1 pooka if (error != 0) {
659 1.3 nonaka aprint_error_dev(sc->sc_dev,
660 1.3 nonaka "could not read firmware %s (error %d)\n",
661 1.3 nonaka sc->sc_fwname, error);
662 1.1 pooka goto out;
663 1.1 pooka }
664 1.1 pooka
665 1.1 pooka /*
666 1.1 pooka * Parse firmware contents
667 1.1 pooka */
668 1.1 pooka
669 1.1 pooka uhdr = (void *)fw->fw_rawdata;
670 1.1 pooka if (*(uint32_t *)fw->fw_rawdata != 0
671 1.1 pooka || le32toh(uhdr->magic) != IWM_TLV_UCODE_MAGIC) {
672 1.3 nonaka aprint_error_dev(sc->sc_dev, "invalid firmware %s\n",
673 1.3 nonaka sc->sc_fwname);
674 1.1 pooka error = EINVAL;
675 1.1 pooka goto out;
676 1.1 pooka }
677 1.1 pooka
678 1.1 pooka sc->sc_fwver = le32toh(uhdr->ver);
679 1.1 pooka data = uhdr->data;
680 1.1 pooka len = fw->fw_rawsize - sizeof(*uhdr);
681 1.1 pooka
682 1.1 pooka while (len >= sizeof(tlv)) {
683 1.2 nonaka size_t tlv_len;
684 1.1 pooka void *tlv_data;
685 1.1 pooka
686 1.1 pooka memcpy(&tlv, data, sizeof(tlv));
687 1.1 pooka tlv_len = le32toh(tlv.length);
688 1.1 pooka tlv_type = le32toh(tlv.type);
689 1.1 pooka
690 1.1 pooka len -= sizeof(tlv);
691 1.1 pooka data += sizeof(tlv);
692 1.1 pooka tlv_data = data;
693 1.1 pooka
694 1.1 pooka if (len < tlv_len) {
695 1.3 nonaka aprint_error_dev(sc->sc_dev,
696 1.3 nonaka "firmware too short: %zu bytes\n", len);
697 1.1 pooka error = EINVAL;
698 1.1 pooka goto parse_out;
699 1.1 pooka }
700 1.1 pooka
701 1.1 pooka switch ((int)tlv_type) {
702 1.1 pooka case IWM_UCODE_TLV_PROBE_MAX_LEN:
703 1.1 pooka if (tlv_len < sizeof(uint32_t)) {
704 1.1 pooka error = EINVAL;
705 1.1 pooka goto parse_out;
706 1.1 pooka }
707 1.1 pooka sc->sc_capa_max_probe_len
708 1.1 pooka = le32toh(*(uint32_t *)tlv_data);
709 1.1 pooka /* limit it to something sensible */
710 1.1 pooka if (sc->sc_capa_max_probe_len > (1<<16)) {
711 1.2 nonaka DPRINTF(("%s: IWM_UCODE_TLV_PROBE_MAX_LEN "
712 1.2 nonaka "ridiculous\n", DEVNAME(sc)));
713 1.1 pooka error = EINVAL;
714 1.1 pooka goto parse_out;
715 1.1 pooka }
716 1.1 pooka break;
717 1.1 pooka case IWM_UCODE_TLV_PAN:
718 1.1 pooka if (tlv_len) {
719 1.1 pooka error = EINVAL;
720 1.1 pooka goto parse_out;
721 1.1 pooka }
722 1.1 pooka sc->sc_capaflags |= IWM_UCODE_TLV_FLAGS_PAN;
723 1.1 pooka break;
724 1.1 pooka case IWM_UCODE_TLV_FLAGS:
725 1.1 pooka if (tlv_len < sizeof(uint32_t)) {
726 1.1 pooka error = EINVAL;
727 1.1 pooka goto parse_out;
728 1.1 pooka }
729 1.1 pooka /*
730 1.1 pooka * Apparently there can be many flags, but Linux driver
731 1.1 pooka * parses only the first one, and so do we.
732 1.1 pooka *
733 1.1 pooka * XXX: why does this override IWM_UCODE_TLV_PAN?
734 1.1 pooka * Intentional or a bug? Observations from
735 1.1 pooka * current firmware file:
736 1.1 pooka * 1) TLV_PAN is parsed first
737 1.1 pooka * 2) TLV_FLAGS contains TLV_FLAGS_PAN
738 1.1 pooka * ==> this resets TLV_PAN to itself... hnnnk
739 1.1 pooka */
740 1.1 pooka sc->sc_capaflags = le32toh(*(uint32_t *)tlv_data);
741 1.1 pooka break;
742 1.1 pooka case IWM_UCODE_TLV_CSCHEME:
743 1.1 pooka if ((error = iwm_store_cscheme(sc,
744 1.1 pooka tlv_data, tlv_len)) != 0)
745 1.1 pooka goto parse_out;
746 1.1 pooka break;
747 1.1 pooka case IWM_UCODE_TLV_NUM_OF_CPU:
748 1.1 pooka if (tlv_len != sizeof(uint32_t)) {
749 1.1 pooka error = EINVAL;
750 1.1 pooka goto parse_out;
751 1.1 pooka }
752 1.1 pooka if (le32toh(*(uint32_t*)tlv_data) != 1) {
753 1.2 nonaka DPRINTF(("%s: driver supports "
754 1.2 nonaka "only TLV_NUM_OF_CPU == 1", DEVNAME(sc)));
755 1.1 pooka error = EINVAL;
756 1.1 pooka goto parse_out;
757 1.1 pooka }
758 1.1 pooka break;
759 1.1 pooka case IWM_UCODE_TLV_SEC_RT:
760 1.1 pooka if ((error = iwm_firmware_store_section(sc,
761 1.1 pooka IWM_UCODE_TYPE_REGULAR, tlv_data, tlv_len)) != 0)
762 1.1 pooka goto parse_out;
763 1.1 pooka break;
764 1.1 pooka case IWM_UCODE_TLV_SEC_INIT:
765 1.1 pooka if ((error = iwm_firmware_store_section(sc,
766 1.1 pooka IWM_UCODE_TYPE_INIT, tlv_data, tlv_len)) != 0)
767 1.1 pooka goto parse_out;
768 1.1 pooka break;
769 1.1 pooka case IWM_UCODE_TLV_SEC_WOWLAN:
770 1.1 pooka if ((error = iwm_firmware_store_section(sc,
771 1.1 pooka IWM_UCODE_TYPE_WOW, tlv_data, tlv_len)) != 0)
772 1.1 pooka goto parse_out;
773 1.1 pooka break;
774 1.1 pooka case IWM_UCODE_TLV_DEF_CALIB:
775 1.1 pooka if (tlv_len != sizeof(struct iwm_tlv_calib_data)) {
776 1.1 pooka error = EINVAL;
777 1.1 pooka goto parse_out;
778 1.1 pooka }
779 1.1 pooka if ((error = iwm_set_default_calib(sc, tlv_data)) != 0)
780 1.1 pooka goto parse_out;
781 1.1 pooka break;
782 1.1 pooka case IWM_UCODE_TLV_PHY_SKU:
783 1.1 pooka if (tlv_len != sizeof(uint32_t)) {
784 1.1 pooka error = EINVAL;
785 1.1 pooka goto parse_out;
786 1.1 pooka }
787 1.1 pooka sc->sc_fw_phy_config = le32toh(*(uint32_t *)tlv_data);
788 1.1 pooka break;
789 1.1 pooka
790 1.1 pooka case IWM_UCODE_TLV_API_CHANGES_SET:
791 1.1 pooka case IWM_UCODE_TLV_ENABLED_CAPABILITIES:
792 1.1 pooka /* ignore, not used by current driver */
793 1.1 pooka break;
794 1.1 pooka
795 1.1 pooka default:
796 1.2 nonaka DPRINTF(("%s: unknown firmware section %d, abort\n",
797 1.2 nonaka DEVNAME(sc), tlv_type));
798 1.1 pooka error = EINVAL;
799 1.1 pooka goto parse_out;
800 1.1 pooka }
801 1.1 pooka
802 1.1 pooka len -= roundup(tlv_len, 4);
803 1.1 pooka data += roundup(tlv_len, 4);
804 1.1 pooka }
805 1.1 pooka
806 1.1 pooka KASSERT(error == 0);
807 1.1 pooka
808 1.1 pooka parse_out:
809 1.1 pooka if (error) {
810 1.3 nonaka aprint_error_dev(sc->sc_dev,
811 1.3 nonaka "firmware parse error, section type %d\n", tlv_type);
812 1.1 pooka }
813 1.1 pooka
814 1.1 pooka if (!(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) {
815 1.3 nonaka aprint_error_dev(sc->sc_dev,
816 1.3 nonaka "device uses unsupported power ops\n");
817 1.1 pooka error = ENOTSUP;
818 1.1 pooka }
819 1.1 pooka
820 1.1 pooka out:
821 1.2 nonaka if (error)
822 1.2 nonaka fw->fw_status = IWM_FW_STATUS_NONE;
823 1.2 nonaka else
824 1.1 pooka fw->fw_status = IWM_FW_STATUS_DONE;
825 1.1 pooka wakeup(&sc->sc_fw);
826 1.1 pooka
827 1.27 khorben if (error && fw->fw_rawdata != NULL) {
828 1.1 pooka kmem_free(fw->fw_rawdata, fw->fw_rawsize);
829 1.1 pooka fw->fw_rawdata = NULL;
830 1.36 nonaka CLR(sc->sc_flags, IWM_FLAG_FW_LOADED);
831 1.1 pooka }
832 1.1 pooka return error;
833 1.1 pooka }
834 1.1 pooka
835 1.1 pooka /*
836 1.1 pooka * basic device access
837 1.1 pooka */
838 1.1 pooka
839 1.4 nonaka static uint32_t
840 1.1 pooka iwm_read_prph(struct iwm_softc *sc, uint32_t addr)
841 1.1 pooka {
842 1.1 pooka IWM_WRITE(sc,
843 1.1 pooka IWM_HBUS_TARG_PRPH_RADDR, ((addr & 0x000fffff) | (3 << 24)));
844 1.1 pooka IWM_BARRIER_READ_WRITE(sc);
845 1.1 pooka return IWM_READ(sc, IWM_HBUS_TARG_PRPH_RDAT);
846 1.1 pooka }
847 1.1 pooka
848 1.4 nonaka static void
849 1.1 pooka iwm_write_prph(struct iwm_softc *sc, uint32_t addr, uint32_t val)
850 1.1 pooka {
851 1.1 pooka IWM_WRITE(sc,
852 1.1 pooka IWM_HBUS_TARG_PRPH_WADDR, ((addr & 0x000fffff) | (3 << 24)));
853 1.1 pooka IWM_BARRIER_WRITE(sc);
854 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_PRPH_WDAT, val);
855 1.1 pooka }
856 1.1 pooka
857 1.4 nonaka #ifdef IWM_DEBUG
858 1.1 pooka /* iwlwifi: pcie/trans.c */
859 1.4 nonaka static int
860 1.1 pooka iwm_read_mem(struct iwm_softc *sc, uint32_t addr, void *buf, int dwords)
861 1.1 pooka {
862 1.1 pooka int offs, ret = 0;
863 1.1 pooka uint32_t *vals = buf;
864 1.1 pooka
865 1.1 pooka if (iwm_nic_lock(sc)) {
866 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_MEM_RADDR, addr);
867 1.1 pooka for (offs = 0; offs < dwords; offs++)
868 1.1 pooka vals[offs] = IWM_READ(sc, IWM_HBUS_TARG_MEM_RDAT);
869 1.1 pooka iwm_nic_unlock(sc);
870 1.1 pooka } else {
871 1.1 pooka ret = EBUSY;
872 1.1 pooka }
873 1.1 pooka return ret;
874 1.1 pooka }
875 1.4 nonaka #endif
876 1.1 pooka
877 1.1 pooka /* iwlwifi: pcie/trans.c */
878 1.4 nonaka static int
879 1.1 pooka iwm_write_mem(struct iwm_softc *sc, uint32_t addr, const void *buf, int dwords)
880 1.1 pooka {
881 1.5 nonaka int offs;
882 1.1 pooka const uint32_t *vals = buf;
883 1.1 pooka
884 1.1 pooka if (iwm_nic_lock(sc)) {
885 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WADDR, addr);
886 1.1 pooka /* WADDR auto-increments */
887 1.1 pooka for (offs = 0; offs < dwords; offs++) {
888 1.1 pooka uint32_t val = vals ? vals[offs] : 0;
889 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WDAT, val);
890 1.1 pooka }
891 1.1 pooka iwm_nic_unlock(sc);
892 1.1 pooka } else {
893 1.2 nonaka DPRINTF(("%s: write_mem failed\n", DEVNAME(sc)));
894 1.2 nonaka return EBUSY;
895 1.1 pooka }
896 1.2 nonaka return 0;
897 1.1 pooka }
898 1.1 pooka
899 1.4 nonaka static int
900 1.1 pooka iwm_write_mem32(struct iwm_softc *sc, uint32_t addr, uint32_t val)
901 1.1 pooka {
902 1.1 pooka return iwm_write_mem(sc, addr, &val, 1);
903 1.1 pooka }
904 1.1 pooka
905 1.4 nonaka static int
906 1.1 pooka iwm_poll_bit(struct iwm_softc *sc, int reg,
907 1.1 pooka uint32_t bits, uint32_t mask, int timo)
908 1.1 pooka {
909 1.1 pooka for (;;) {
910 1.1 pooka if ((IWM_READ(sc, reg) & mask) == (bits & mask)) {
911 1.1 pooka return 1;
912 1.1 pooka }
913 1.1 pooka if (timo < 10) {
914 1.1 pooka return 0;
915 1.1 pooka }
916 1.1 pooka timo -= 10;
917 1.1 pooka DELAY(10);
918 1.1 pooka }
919 1.1 pooka }
920 1.1 pooka
921 1.4 nonaka static int
922 1.1 pooka iwm_nic_lock(struct iwm_softc *sc)
923 1.1 pooka {
924 1.1 pooka int rv = 0;
925 1.1 pooka
926 1.1 pooka IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
927 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
928 1.1 pooka
929 1.1 pooka if (iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
930 1.1 pooka IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
931 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
932 1.1 pooka | IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP, 15000)) {
933 1.38 ozaki rv = 1;
934 1.1 pooka } else {
935 1.1 pooka /* jolt */
936 1.1 pooka IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_FORCE_NMI);
937 1.1 pooka }
938 1.1 pooka
939 1.1 pooka return rv;
940 1.1 pooka }
941 1.1 pooka
942 1.4 nonaka static void
943 1.1 pooka iwm_nic_unlock(struct iwm_softc *sc)
944 1.1 pooka {
945 1.1 pooka IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
946 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
947 1.1 pooka }
948 1.1 pooka
949 1.4 nonaka static void
950 1.1 pooka iwm_set_bits_mask_prph(struct iwm_softc *sc,
951 1.1 pooka uint32_t reg, uint32_t bits, uint32_t mask)
952 1.1 pooka {
953 1.1 pooka uint32_t val;
954 1.1 pooka
955 1.1 pooka /* XXX: no error path? */
956 1.1 pooka if (iwm_nic_lock(sc)) {
957 1.1 pooka val = iwm_read_prph(sc, reg) & mask;
958 1.1 pooka val |= bits;
959 1.1 pooka iwm_write_prph(sc, reg, val);
960 1.1 pooka iwm_nic_unlock(sc);
961 1.1 pooka }
962 1.1 pooka }
963 1.1 pooka
964 1.4 nonaka static void
965 1.1 pooka iwm_set_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits)
966 1.1 pooka {
967 1.1 pooka iwm_set_bits_mask_prph(sc, reg, bits, ~0);
968 1.1 pooka }
969 1.1 pooka
970 1.4 nonaka static void
971 1.1 pooka iwm_clear_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits)
972 1.1 pooka {
973 1.1 pooka iwm_set_bits_mask_prph(sc, reg, 0, ~bits);
974 1.1 pooka }
975 1.1 pooka
976 1.1 pooka /*
977 1.1 pooka * DMA resource routines
978 1.1 pooka */
979 1.1 pooka
980 1.4 nonaka static int
981 1.1 pooka iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
982 1.1 pooka bus_size_t size, bus_size_t alignment)
983 1.1 pooka {
984 1.1 pooka int nsegs, error;
985 1.1 pooka void *va;
986 1.1 pooka
987 1.1 pooka dma->tag = tag;
988 1.1 pooka dma->size = size;
989 1.1 pooka
990 1.1 pooka error = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT,
991 1.1 pooka &dma->map);
992 1.1 pooka if (error != 0)
993 1.1 pooka goto fail;
994 1.1 pooka
995 1.1 pooka error = bus_dmamem_alloc(tag, size, alignment, 0, &dma->seg, 1, &nsegs,
996 1.1 pooka BUS_DMA_NOWAIT);
997 1.1 pooka if (error != 0)
998 1.1 pooka goto fail;
999 1.1 pooka
1000 1.1 pooka error = bus_dmamem_map(tag, &dma->seg, 1, size, &va,
1001 1.1 pooka BUS_DMA_NOWAIT);
1002 1.1 pooka if (error != 0)
1003 1.1 pooka goto fail;
1004 1.1 pooka dma->vaddr = va;
1005 1.1 pooka
1006 1.1 pooka error = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
1007 1.1 pooka BUS_DMA_NOWAIT);
1008 1.1 pooka if (error != 0)
1009 1.1 pooka goto fail;
1010 1.1 pooka
1011 1.1 pooka memset(dma->vaddr, 0, size);
1012 1.1 pooka bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
1013 1.1 pooka dma->paddr = dma->map->dm_segs[0].ds_addr;
1014 1.1 pooka
1015 1.1 pooka return 0;
1016 1.1 pooka
1017 1.1 pooka fail: iwm_dma_contig_free(dma);
1018 1.1 pooka return error;
1019 1.1 pooka }
1020 1.1 pooka
1021 1.4 nonaka static void
1022 1.1 pooka iwm_dma_contig_free(struct iwm_dma_info *dma)
1023 1.1 pooka {
1024 1.1 pooka if (dma->map != NULL) {
1025 1.1 pooka if (dma->vaddr != NULL) {
1026 1.1 pooka bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,
1027 1.1 pooka BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1028 1.1 pooka bus_dmamap_unload(dma->tag, dma->map);
1029 1.1 pooka bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size);
1030 1.1 pooka bus_dmamem_free(dma->tag, &dma->seg, 1);
1031 1.1 pooka dma->vaddr = NULL;
1032 1.1 pooka }
1033 1.1 pooka bus_dmamap_destroy(dma->tag, dma->map);
1034 1.1 pooka dma->map = NULL;
1035 1.1 pooka }
1036 1.1 pooka }
1037 1.1 pooka
1038 1.1 pooka /* fwmem is used to load firmware onto the card */
1039 1.4 nonaka static int
1040 1.1 pooka iwm_alloc_fwmem(struct iwm_softc *sc)
1041 1.1 pooka {
1042 1.1 pooka /* Must be aligned on a 16-byte boundary. */
1043 1.1 pooka return iwm_dma_contig_alloc(sc->sc_dmat, &sc->fw_dma,
1044 1.1 pooka sc->sc_fwdmasegsz, 16);
1045 1.1 pooka }
1046 1.1 pooka
1047 1.4 nonaka static void
1048 1.1 pooka iwm_free_fwmem(struct iwm_softc *sc)
1049 1.1 pooka {
1050 1.1 pooka iwm_dma_contig_free(&sc->fw_dma);
1051 1.1 pooka }
1052 1.1 pooka
1053 1.1 pooka /* tx scheduler rings. not used? */
1054 1.4 nonaka static int
1055 1.1 pooka iwm_alloc_sched(struct iwm_softc *sc)
1056 1.1 pooka {
1057 1.1 pooka int rv;
1058 1.1 pooka
1059 1.1 pooka /* TX scheduler rings must be aligned on a 1KB boundary. */
1060 1.1 pooka rv = iwm_dma_contig_alloc(sc->sc_dmat, &sc->sched_dma,
1061 1.1 pooka __arraycount(sc->txq) * sizeof(struct iwm_agn_scd_bc_tbl), 1024);
1062 1.1 pooka return rv;
1063 1.1 pooka }
1064 1.1 pooka
1065 1.4 nonaka static void
1066 1.1 pooka iwm_free_sched(struct iwm_softc *sc)
1067 1.1 pooka {
1068 1.1 pooka iwm_dma_contig_free(&sc->sched_dma);
1069 1.1 pooka }
1070 1.1 pooka
1071 1.1 pooka /* keep-warm page is used internally by the card. see iwl-fh.h for more info */
1072 1.4 nonaka static int
1073 1.1 pooka iwm_alloc_kw(struct iwm_softc *sc)
1074 1.1 pooka {
1075 1.1 pooka return iwm_dma_contig_alloc(sc->sc_dmat, &sc->kw_dma, 4096, 4096);
1076 1.1 pooka }
1077 1.1 pooka
1078 1.4 nonaka static void
1079 1.1 pooka iwm_free_kw(struct iwm_softc *sc)
1080 1.1 pooka {
1081 1.1 pooka iwm_dma_contig_free(&sc->kw_dma);
1082 1.1 pooka }
1083 1.1 pooka
1084 1.1 pooka /* interrupt cause table */
1085 1.4 nonaka static int
1086 1.1 pooka iwm_alloc_ict(struct iwm_softc *sc)
1087 1.1 pooka {
1088 1.1 pooka return iwm_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma,
1089 1.1 pooka IWM_ICT_SIZE, 1<<IWM_ICT_PADDR_SHIFT);
1090 1.1 pooka }
1091 1.1 pooka
1092 1.4 nonaka static void
1093 1.1 pooka iwm_free_ict(struct iwm_softc *sc)
1094 1.1 pooka {
1095 1.1 pooka iwm_dma_contig_free(&sc->ict_dma);
1096 1.1 pooka }
1097 1.1 pooka
1098 1.4 nonaka static int
1099 1.1 pooka iwm_alloc_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
1100 1.1 pooka {
1101 1.1 pooka bus_size_t size;
1102 1.1 pooka int i, error;
1103 1.1 pooka
1104 1.1 pooka ring->cur = 0;
1105 1.1 pooka
1106 1.1 pooka /* Allocate RX descriptors (256-byte aligned). */
1107 1.1 pooka size = IWM_RX_RING_COUNT * sizeof(uint32_t);
1108 1.1 pooka error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256);
1109 1.1 pooka if (error != 0) {
1110 1.3 nonaka aprint_error_dev(sc->sc_dev,
1111 1.3 nonaka "could not allocate RX ring DMA memory\n");
1112 1.1 pooka goto fail;
1113 1.1 pooka }
1114 1.1 pooka ring->desc = ring->desc_dma.vaddr;
1115 1.1 pooka
1116 1.1 pooka /* Allocate RX status area (16-byte aligned). */
1117 1.1 pooka error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma,
1118 1.1 pooka sizeof(*ring->stat), 16);
1119 1.1 pooka if (error != 0) {
1120 1.3 nonaka aprint_error_dev(sc->sc_dev,
1121 1.3 nonaka "could not allocate RX status DMA memory\n");
1122 1.1 pooka goto fail;
1123 1.1 pooka }
1124 1.1 pooka ring->stat = ring->stat_dma.vaddr;
1125 1.1 pooka
1126 1.1 pooka /*
1127 1.1 pooka * Allocate and map RX buffers.
1128 1.1 pooka */
1129 1.1 pooka for (i = 0; i < IWM_RX_RING_COUNT; i++) {
1130 1.1 pooka struct iwm_rx_data *data = &ring->data[i];
1131 1.1 pooka
1132 1.1 pooka memset(data, 0, sizeof(*data));
1133 1.1 pooka error = bus_dmamap_create(sc->sc_dmat, IWM_RBUF_SIZE, 1,
1134 1.1 pooka IWM_RBUF_SIZE, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
1135 1.1 pooka &data->map);
1136 1.1 pooka if (error != 0) {
1137 1.3 nonaka aprint_error_dev(sc->sc_dev,
1138 1.3 nonaka "could not create RX buf DMA map\n");
1139 1.1 pooka goto fail;
1140 1.1 pooka }
1141 1.1 pooka
1142 1.1 pooka if ((error = iwm_rx_addbuf(sc, IWM_RBUF_SIZE, i)) != 0) {
1143 1.1 pooka goto fail;
1144 1.1 pooka }
1145 1.1 pooka }
1146 1.1 pooka return 0;
1147 1.1 pooka
1148 1.1 pooka fail: iwm_free_rx_ring(sc, ring);
1149 1.1 pooka return error;
1150 1.1 pooka }
1151 1.1 pooka
1152 1.4 nonaka static void
1153 1.1 pooka iwm_reset_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
1154 1.1 pooka {
1155 1.1 pooka int ntries;
1156 1.1 pooka
1157 1.1 pooka if (iwm_nic_lock(sc)) {
1158 1.1 pooka IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
1159 1.1 pooka for (ntries = 0; ntries < 1000; ntries++) {
1160 1.1 pooka if (IWM_READ(sc, IWM_FH_MEM_RSSR_RX_STATUS_REG) &
1161 1.1 pooka IWM_FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE)
1162 1.1 pooka break;
1163 1.1 pooka DELAY(10);
1164 1.1 pooka }
1165 1.1 pooka iwm_nic_unlock(sc);
1166 1.1 pooka }
1167 1.1 pooka ring->cur = 0;
1168 1.1 pooka }
1169 1.1 pooka
1170 1.4 nonaka static void
1171 1.1 pooka iwm_free_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
1172 1.1 pooka {
1173 1.1 pooka int i;
1174 1.1 pooka
1175 1.1 pooka iwm_dma_contig_free(&ring->desc_dma);
1176 1.1 pooka iwm_dma_contig_free(&ring->stat_dma);
1177 1.1 pooka
1178 1.1 pooka for (i = 0; i < IWM_RX_RING_COUNT; i++) {
1179 1.1 pooka struct iwm_rx_data *data = &ring->data[i];
1180 1.1 pooka
1181 1.1 pooka if (data->m != NULL) {
1182 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1183 1.1 pooka data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
1184 1.1 pooka bus_dmamap_unload(sc->sc_dmat, data->map);
1185 1.1 pooka m_freem(data->m);
1186 1.1 pooka }
1187 1.1 pooka if (data->map != NULL)
1188 1.1 pooka bus_dmamap_destroy(sc->sc_dmat, data->map);
1189 1.1 pooka }
1190 1.1 pooka }
1191 1.1 pooka
1192 1.4 nonaka static int
1193 1.1 pooka iwm_alloc_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring, int qid)
1194 1.1 pooka {
1195 1.1 pooka bus_addr_t paddr;
1196 1.1 pooka bus_size_t size;
1197 1.1 pooka int i, error;
1198 1.1 pooka
1199 1.1 pooka ring->qid = qid;
1200 1.1 pooka ring->queued = 0;
1201 1.1 pooka ring->cur = 0;
1202 1.1 pooka
1203 1.1 pooka /* Allocate TX descriptors (256-byte aligned). */
1204 1.1 pooka size = IWM_TX_RING_COUNT * sizeof (struct iwm_tfd);
1205 1.1 pooka error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256);
1206 1.1 pooka if (error != 0) {
1207 1.3 nonaka aprint_error_dev(sc->sc_dev,
1208 1.3 nonaka "could not allocate TX ring DMA memory\n");
1209 1.1 pooka goto fail;
1210 1.1 pooka }
1211 1.1 pooka ring->desc = ring->desc_dma.vaddr;
1212 1.1 pooka
1213 1.1 pooka /*
1214 1.1 pooka * We only use rings 0 through 9 (4 EDCA + cmd) so there is no need
1215 1.1 pooka * to allocate commands space for other rings.
1216 1.1 pooka */
1217 1.1 pooka if (qid > IWM_MVM_CMD_QUEUE)
1218 1.1 pooka return 0;
1219 1.1 pooka
1220 1.1 pooka size = IWM_TX_RING_COUNT * sizeof(struct iwm_device_cmd);
1221 1.1 pooka error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma, size, 4);
1222 1.1 pooka if (error != 0) {
1223 1.3 nonaka aprint_error_dev(sc->sc_dev,
1224 1.3 nonaka "could not allocate TX cmd DMA memory\n");
1225 1.1 pooka goto fail;
1226 1.1 pooka }
1227 1.1 pooka ring->cmd = ring->cmd_dma.vaddr;
1228 1.1 pooka
1229 1.1 pooka paddr = ring->cmd_dma.paddr;
1230 1.1 pooka for (i = 0; i < IWM_TX_RING_COUNT; i++) {
1231 1.1 pooka struct iwm_tx_data *data = &ring->data[i];
1232 1.1 pooka
1233 1.1 pooka data->cmd_paddr = paddr;
1234 1.1 pooka data->scratch_paddr = paddr + sizeof(struct iwm_cmd_header)
1235 1.1 pooka + offsetof(struct iwm_tx_cmd, scratch);
1236 1.1 pooka paddr += sizeof(struct iwm_device_cmd);
1237 1.1 pooka
1238 1.5 nonaka error = bus_dmamap_create(sc->sc_dmat, IWM_RBUF_SIZE,
1239 1.35 nonaka IWM_NUM_OF_TBS - 2, IWM_RBUF_SIZE, 0, BUS_DMA_NOWAIT,
1240 1.5 nonaka &data->map);
1241 1.1 pooka if (error != 0) {
1242 1.3 nonaka aprint_error_dev(sc->sc_dev,
1243 1.3 nonaka "could not create TX buf DMA map\n");
1244 1.1 pooka goto fail;
1245 1.1 pooka }
1246 1.1 pooka }
1247 1.1 pooka KASSERT(paddr == ring->cmd_dma.paddr + size);
1248 1.1 pooka return 0;
1249 1.1 pooka
1250 1.1 pooka fail: iwm_free_tx_ring(sc, ring);
1251 1.1 pooka return error;
1252 1.1 pooka }
1253 1.1 pooka
1254 1.4 nonaka static void
1255 1.1 pooka iwm_reset_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring)
1256 1.1 pooka {
1257 1.1 pooka int i;
1258 1.1 pooka
1259 1.1 pooka for (i = 0; i < IWM_TX_RING_COUNT; i++) {
1260 1.1 pooka struct iwm_tx_data *data = &ring->data[i];
1261 1.1 pooka
1262 1.1 pooka if (data->m != NULL) {
1263 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1264 1.1 pooka data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1265 1.1 pooka bus_dmamap_unload(sc->sc_dmat, data->map);
1266 1.1 pooka m_freem(data->m);
1267 1.1 pooka data->m = NULL;
1268 1.1 pooka }
1269 1.1 pooka }
1270 1.1 pooka /* Clear TX descriptors. */
1271 1.1 pooka memset(ring->desc, 0, ring->desc_dma.size);
1272 1.1 pooka bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0,
1273 1.1 pooka ring->desc_dma.size, BUS_DMASYNC_PREWRITE);
1274 1.1 pooka sc->qfullmsk &= ~(1 << ring->qid);
1275 1.1 pooka ring->queued = 0;
1276 1.1 pooka ring->cur = 0;
1277 1.1 pooka }
1278 1.1 pooka
1279 1.4 nonaka static void
1280 1.1 pooka iwm_free_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring)
1281 1.1 pooka {
1282 1.1 pooka int i;
1283 1.1 pooka
1284 1.1 pooka iwm_dma_contig_free(&ring->desc_dma);
1285 1.1 pooka iwm_dma_contig_free(&ring->cmd_dma);
1286 1.1 pooka
1287 1.1 pooka for (i = 0; i < IWM_TX_RING_COUNT; i++) {
1288 1.1 pooka struct iwm_tx_data *data = &ring->data[i];
1289 1.1 pooka
1290 1.1 pooka if (data->m != NULL) {
1291 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1292 1.1 pooka data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1293 1.1 pooka bus_dmamap_unload(sc->sc_dmat, data->map);
1294 1.1 pooka m_freem(data->m);
1295 1.1 pooka }
1296 1.1 pooka if (data->map != NULL)
1297 1.1 pooka bus_dmamap_destroy(sc->sc_dmat, data->map);
1298 1.1 pooka }
1299 1.1 pooka }
1300 1.1 pooka
1301 1.1 pooka /*
1302 1.1 pooka * High-level hardware frobbing routines
1303 1.1 pooka */
1304 1.1 pooka
1305 1.4 nonaka static void
1306 1.1 pooka iwm_enable_rfkill_int(struct iwm_softc *sc)
1307 1.1 pooka {
1308 1.1 pooka sc->sc_intmask = IWM_CSR_INT_BIT_RF_KILL;
1309 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
1310 1.1 pooka }
1311 1.1 pooka
1312 1.4 nonaka static int
1313 1.1 pooka iwm_check_rfkill(struct iwm_softc *sc)
1314 1.1 pooka {
1315 1.1 pooka uint32_t v;
1316 1.1 pooka int s;
1317 1.1 pooka int rv;
1318 1.8 nonaka
1319 1.1 pooka s = splnet();
1320 1.1 pooka
1321 1.1 pooka /*
1322 1.1 pooka * "documentation" is not really helpful here:
1323 1.1 pooka * 27: HW_RF_KILL_SW
1324 1.1 pooka * Indicates state of (platform's) hardware RF-Kill switch
1325 1.1 pooka *
1326 1.1 pooka * But apparently when it's off, it's on ...
1327 1.1 pooka */
1328 1.1 pooka v = IWM_READ(sc, IWM_CSR_GP_CNTRL);
1329 1.1 pooka rv = (v & IWM_CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) == 0;
1330 1.1 pooka if (rv) {
1331 1.1 pooka sc->sc_flags |= IWM_FLAG_RFKILL;
1332 1.1 pooka } else {
1333 1.1 pooka sc->sc_flags &= ~IWM_FLAG_RFKILL;
1334 1.1 pooka }
1335 1.1 pooka
1336 1.1 pooka splx(s);
1337 1.1 pooka return rv;
1338 1.1 pooka }
1339 1.1 pooka
1340 1.4 nonaka static void
1341 1.1 pooka iwm_enable_interrupts(struct iwm_softc *sc)
1342 1.1 pooka {
1343 1.1 pooka sc->sc_intmask = IWM_CSR_INI_SET_MASK;
1344 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
1345 1.1 pooka }
1346 1.1 pooka
1347 1.4 nonaka static void
1348 1.1 pooka iwm_restore_interrupts(struct iwm_softc *sc)
1349 1.1 pooka {
1350 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
1351 1.1 pooka }
1352 1.1 pooka
1353 1.4 nonaka static void
1354 1.1 pooka iwm_disable_interrupts(struct iwm_softc *sc)
1355 1.1 pooka {
1356 1.1 pooka int s = splnet();
1357 1.1 pooka
1358 1.1 pooka /* disable interrupts */
1359 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT_MASK, 0);
1360 1.1 pooka
1361 1.1 pooka /* acknowledge all interrupts */
1362 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT, ~0);
1363 1.1 pooka IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, ~0);
1364 1.1 pooka
1365 1.1 pooka splx(s);
1366 1.1 pooka }
1367 1.1 pooka
1368 1.4 nonaka static void
1369 1.1 pooka iwm_ict_reset(struct iwm_softc *sc)
1370 1.1 pooka {
1371 1.1 pooka iwm_disable_interrupts(sc);
1372 1.1 pooka
1373 1.1 pooka /* Reset ICT table. */
1374 1.1 pooka memset(sc->ict_dma.vaddr, 0, IWM_ICT_SIZE);
1375 1.1 pooka sc->ict_cur = 0;
1376 1.1 pooka
1377 1.1 pooka /* Set physical address of ICT table (4KB aligned). */
1378 1.1 pooka IWM_WRITE(sc, IWM_CSR_DRAM_INT_TBL_REG,
1379 1.1 pooka IWM_CSR_DRAM_INT_TBL_ENABLE
1380 1.1 pooka | IWM_CSR_DRAM_INIT_TBL_WRAP_CHECK
1381 1.1 pooka | sc->ict_dma.paddr >> IWM_ICT_PADDR_SHIFT);
1382 1.1 pooka
1383 1.1 pooka /* Switch to ICT interrupt mode in driver. */
1384 1.1 pooka sc->sc_flags |= IWM_FLAG_USE_ICT;
1385 1.1 pooka
1386 1.1 pooka /* Re-enable interrupts. */
1387 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT, ~0);
1388 1.1 pooka iwm_enable_interrupts(sc);
1389 1.1 pooka }
1390 1.1 pooka
1391 1.1 pooka #define IWM_HW_READY_TIMEOUT 50
1392 1.4 nonaka static int
1393 1.1 pooka iwm_set_hw_ready(struct iwm_softc *sc)
1394 1.1 pooka {
1395 1.1 pooka IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
1396 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
1397 1.1 pooka
1398 1.8 nonaka return iwm_poll_bit(sc, IWM_CSR_HW_IF_CONFIG_REG,
1399 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
1400 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
1401 1.1 pooka IWM_HW_READY_TIMEOUT);
1402 1.1 pooka }
1403 1.1 pooka #undef IWM_HW_READY_TIMEOUT
1404 1.1 pooka
1405 1.4 nonaka static int
1406 1.1 pooka iwm_prepare_card_hw(struct iwm_softc *sc)
1407 1.1 pooka {
1408 1.1 pooka int rv = 0;
1409 1.1 pooka int t = 0;
1410 1.1 pooka
1411 1.10 nonaka if (iwm_set_hw_ready(sc))
1412 1.1 pooka goto out;
1413 1.1 pooka
1414 1.1 pooka /* If HW is not ready, prepare the conditions to check again */
1415 1.1 pooka IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
1416 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_PREPARE);
1417 1.1 pooka
1418 1.1 pooka do {
1419 1.1 pooka if (iwm_set_hw_ready(sc))
1420 1.1 pooka goto out;
1421 1.1 pooka DELAY(200);
1422 1.1 pooka t += 200;
1423 1.1 pooka } while (t < 150000);
1424 1.1 pooka
1425 1.1 pooka rv = ETIMEDOUT;
1426 1.1 pooka
1427 1.1 pooka out:
1428 1.1 pooka return rv;
1429 1.1 pooka }
1430 1.1 pooka
1431 1.4 nonaka static void
1432 1.1 pooka iwm_apm_config(struct iwm_softc *sc)
1433 1.1 pooka {
1434 1.1 pooka pcireg_t reg;
1435 1.1 pooka
1436 1.1 pooka reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
1437 1.1 pooka sc->sc_cap_off + PCIE_LCSR);
1438 1.1 pooka if (reg & PCIE_LCSR_ASPM_L1) {
1439 1.1 pooka /* Um the Linux driver prints "Disabling L0S for this one ... */
1440 1.1 pooka IWM_SETBITS(sc, IWM_CSR_GIO_REG,
1441 1.1 pooka IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
1442 1.1 pooka } else {
1443 1.1 pooka /* ... and "Enabling" here */
1444 1.1 pooka IWM_CLRBITS(sc, IWM_CSR_GIO_REG,
1445 1.1 pooka IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
1446 1.1 pooka }
1447 1.1 pooka }
1448 1.1 pooka
1449 1.1 pooka /*
1450 1.1 pooka * Start up NIC's basic functionality after it has been reset
1451 1.1 pooka * (e.g. after platform boot, or shutdown via iwm_pcie_apm_stop())
1452 1.1 pooka * NOTE: This does not load uCode nor start the embedded processor
1453 1.1 pooka */
1454 1.4 nonaka static int
1455 1.1 pooka iwm_apm_init(struct iwm_softc *sc)
1456 1.1 pooka {
1457 1.1 pooka int error = 0;
1458 1.1 pooka
1459 1.1 pooka DPRINTF(("iwm apm start\n"));
1460 1.1 pooka
1461 1.1 pooka /* Disable L0S exit timer (platform NMI Work/Around) */
1462 1.1 pooka IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS,
1463 1.1 pooka IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
1464 1.1 pooka
1465 1.1 pooka /*
1466 1.1 pooka * Disable L0s without affecting L1;
1467 1.1 pooka * don't wait for ICH L0s (ICH bug W/A)
1468 1.1 pooka */
1469 1.1 pooka IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS,
1470 1.1 pooka IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
1471 1.1 pooka
1472 1.1 pooka /* Set FH wait threshold to maximum (HW error during stress W/A) */
1473 1.1 pooka IWM_SETBITS(sc, IWM_CSR_DBG_HPET_MEM_REG, IWM_CSR_DBG_HPET_MEM_REG_VAL);
1474 1.1 pooka
1475 1.1 pooka /*
1476 1.1 pooka * Enable HAP INTA (interrupt from management bus) to
1477 1.1 pooka * wake device's PCI Express link L1a -> L0s
1478 1.1 pooka */
1479 1.1 pooka IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
1480 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
1481 1.1 pooka
1482 1.1 pooka iwm_apm_config(sc);
1483 1.1 pooka
1484 1.1 pooka #if 0 /* not for 7k */
1485 1.1 pooka /* Configure analog phase-lock-loop before activating to D0A */
1486 1.1 pooka if (trans->cfg->base_params->pll_cfg_val)
1487 1.1 pooka IWM_SETBITS(trans, IWM_CSR_ANA_PLL_CFG,
1488 1.1 pooka trans->cfg->base_params->pll_cfg_val);
1489 1.1 pooka #endif
1490 1.1 pooka
1491 1.1 pooka /*
1492 1.1 pooka * Set "initialization complete" bit to move adapter from
1493 1.1 pooka * D0U* --> D0A* (powered-up active) state.
1494 1.1 pooka */
1495 1.1 pooka IWM_SETBITS(sc, IWM_CSR_GP_CNTRL, IWM_CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
1496 1.1 pooka
1497 1.1 pooka /*
1498 1.1 pooka * Wait for clock stabilization; once stabilized, access to
1499 1.1 pooka * device-internal resources is supported, e.g. iwm_write_prph()
1500 1.1 pooka * and accesses to uCode SRAM.
1501 1.1 pooka */
1502 1.1 pooka if (!iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
1503 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
1504 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000)) {
1505 1.3 nonaka aprint_error_dev(sc->sc_dev,
1506 1.3 nonaka "timeout waiting for clock stabilization\n");
1507 1.1 pooka goto out;
1508 1.1 pooka }
1509 1.1 pooka
1510 1.17 nonaka if (sc->host_interrupt_operation_mode) {
1511 1.17 nonaka /*
1512 1.17 nonaka * This is a bit of an abuse - This is needed for 7260 / 3160
1513 1.17 nonaka * only check host_interrupt_operation_mode even if this is
1514 1.17 nonaka * not related to host_interrupt_operation_mode.
1515 1.17 nonaka *
1516 1.17 nonaka * Enable the oscillator to count wake up time for L1 exit. This
1517 1.17 nonaka * consumes slightly more power (100uA) - but allows to be sure
1518 1.17 nonaka * that we wake up from L1 on time.
1519 1.17 nonaka *
1520 1.17 nonaka * This looks weird: read twice the same register, discard the
1521 1.17 nonaka * value, set a bit, and yet again, read that same register
1522 1.17 nonaka * just to discard the value. But that's the way the hardware
1523 1.17 nonaka * seems to like it.
1524 1.17 nonaka */
1525 1.17 nonaka iwm_read_prph(sc, IWM_OSC_CLK);
1526 1.17 nonaka iwm_read_prph(sc, IWM_OSC_CLK);
1527 1.17 nonaka iwm_set_bits_prph(sc, IWM_OSC_CLK, IWM_OSC_CLK_FORCE_CONTROL);
1528 1.17 nonaka iwm_read_prph(sc, IWM_OSC_CLK);
1529 1.17 nonaka iwm_read_prph(sc, IWM_OSC_CLK);
1530 1.17 nonaka }
1531 1.1 pooka
1532 1.1 pooka /*
1533 1.1 pooka * Enable DMA clock and wait for it to stabilize.
1534 1.1 pooka *
1535 1.1 pooka * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
1536 1.1 pooka * do not disable clocks. This preserves any hardware bits already
1537 1.1 pooka * set by default in "CLK_CTRL_REG" after reset.
1538 1.1 pooka */
1539 1.1 pooka iwm_write_prph(sc, IWM_APMG_CLK_EN_REG, IWM_APMG_CLK_VAL_DMA_CLK_RQT);
1540 1.1 pooka //kpause("iwmapm", 0, mstohz(20), NULL);
1541 1.1 pooka DELAY(20);
1542 1.1 pooka
1543 1.1 pooka /* Disable L1-Active */
1544 1.1 pooka iwm_set_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
1545 1.1 pooka IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
1546 1.1 pooka
1547 1.1 pooka /* Clear the interrupt in APMG if the NIC is in RFKILL */
1548 1.1 pooka iwm_write_prph(sc, IWM_APMG_RTC_INT_STT_REG,
1549 1.1 pooka IWM_APMG_RTC_INT_STT_RFKILL);
1550 1.1 pooka
1551 1.1 pooka out:
1552 1.1 pooka if (error)
1553 1.3 nonaka aprint_error_dev(sc->sc_dev, "apm init error %d\n", error);
1554 1.1 pooka return error;
1555 1.1 pooka }
1556 1.1 pooka
1557 1.1 pooka /* iwlwifi/pcie/trans.c */
1558 1.4 nonaka static void
1559 1.1 pooka iwm_apm_stop(struct iwm_softc *sc)
1560 1.1 pooka {
1561 1.1 pooka /* stop device's busmaster DMA activity */
1562 1.1 pooka IWM_SETBITS(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_STOP_MASTER);
1563 1.1 pooka
1564 1.1 pooka if (!iwm_poll_bit(sc, IWM_CSR_RESET,
1565 1.1 pooka IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED,
1566 1.1 pooka IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED, 100))
1567 1.3 nonaka aprint_error_dev(sc->sc_dev, "timeout waiting for master\n");
1568 1.3 nonaka DPRINTF(("iwm apm stop\n"));
1569 1.1 pooka }
1570 1.1 pooka
1571 1.1 pooka /* iwlwifi pcie/trans.c */
1572 1.4 nonaka static int
1573 1.1 pooka iwm_start_hw(struct iwm_softc *sc)
1574 1.1 pooka {
1575 1.1 pooka int error;
1576 1.1 pooka
1577 1.1 pooka if ((error = iwm_prepare_card_hw(sc)) != 0)
1578 1.1 pooka return error;
1579 1.1 pooka
1580 1.8 nonaka /* Reset the entire device */
1581 1.1 pooka IWM_WRITE(sc, IWM_CSR_RESET,
1582 1.1 pooka IWM_CSR_RESET_REG_FLAG_SW_RESET |
1583 1.1 pooka IWM_CSR_RESET_REG_FLAG_NEVO_RESET);
1584 1.1 pooka DELAY(10);
1585 1.1 pooka
1586 1.1 pooka if ((error = iwm_apm_init(sc)) != 0)
1587 1.1 pooka return error;
1588 1.1 pooka
1589 1.1 pooka iwm_enable_rfkill_int(sc);
1590 1.1 pooka iwm_check_rfkill(sc);
1591 1.1 pooka
1592 1.1 pooka return 0;
1593 1.1 pooka }
1594 1.1 pooka
1595 1.1 pooka /* iwlwifi pcie/trans.c */
1596 1.1 pooka
1597 1.4 nonaka static void
1598 1.1 pooka iwm_stop_device(struct iwm_softc *sc)
1599 1.1 pooka {
1600 1.1 pooka int chnl, ntries;
1601 1.1 pooka int qid;
1602 1.1 pooka
1603 1.1 pooka /* tell the device to stop sending interrupts */
1604 1.1 pooka iwm_disable_interrupts(sc);
1605 1.1 pooka
1606 1.1 pooka /* device going down, Stop using ICT table */
1607 1.1 pooka sc->sc_flags &= ~IWM_FLAG_USE_ICT;
1608 1.1 pooka
1609 1.1 pooka /* stop tx and rx. tx and rx bits, as usual, are from if_iwn */
1610 1.1 pooka
1611 1.1 pooka iwm_write_prph(sc, IWM_SCD_TXFACT, 0);
1612 1.1 pooka
1613 1.1 pooka /* Stop all DMA channels. */
1614 1.1 pooka if (iwm_nic_lock(sc)) {
1615 1.1 pooka for (chnl = 0; chnl < IWM_FH_TCSR_CHNL_NUM; chnl++) {
1616 1.1 pooka IWM_WRITE(sc,
1617 1.1 pooka IWM_FH_TCSR_CHNL_TX_CONFIG_REG(chnl), 0);
1618 1.1 pooka for (ntries = 0; ntries < 200; ntries++) {
1619 1.1 pooka uint32_t r;
1620 1.1 pooka
1621 1.1 pooka r = IWM_READ(sc, IWM_FH_TSSR_TX_STATUS_REG);
1622 1.1 pooka if (r & IWM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(
1623 1.1 pooka chnl))
1624 1.1 pooka break;
1625 1.1 pooka DELAY(20);
1626 1.1 pooka }
1627 1.1 pooka }
1628 1.1 pooka iwm_nic_unlock(sc);
1629 1.1 pooka }
1630 1.1 pooka
1631 1.1 pooka /* Stop RX ring. */
1632 1.1 pooka iwm_reset_rx_ring(sc, &sc->rxq);
1633 1.1 pooka
1634 1.1 pooka /* Reset all TX rings. */
1635 1.1 pooka for (qid = 0; qid < __arraycount(sc->txq); qid++)
1636 1.1 pooka iwm_reset_tx_ring(sc, &sc->txq[qid]);
1637 1.1 pooka
1638 1.1 pooka /*
1639 1.1 pooka * Power-down device's busmaster DMA clocks
1640 1.1 pooka */
1641 1.1 pooka iwm_write_prph(sc, IWM_APMG_CLK_DIS_REG, IWM_APMG_CLK_VAL_DMA_CLK_RQT);
1642 1.1 pooka DELAY(5);
1643 1.1 pooka
1644 1.1 pooka /* Make sure (redundant) we've released our request to stay awake */
1645 1.1 pooka IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
1646 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1647 1.1 pooka
1648 1.1 pooka /* Stop the device, and put it in low power state */
1649 1.1 pooka iwm_apm_stop(sc);
1650 1.1 pooka
1651 1.8 nonaka /* Upon stop, the APM issues an interrupt if HW RF kill is set.
1652 1.8 nonaka * Clean again the interrupt here
1653 1.8 nonaka */
1654 1.1 pooka iwm_disable_interrupts(sc);
1655 1.1 pooka /* stop and reset the on-board processor */
1656 1.1 pooka IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_NEVO_RESET);
1657 1.1 pooka
1658 1.1 pooka /*
1659 1.1 pooka * Even if we stop the HW, we still want the RF kill
1660 1.1 pooka * interrupt
1661 1.1 pooka */
1662 1.1 pooka iwm_enable_rfkill_int(sc);
1663 1.1 pooka iwm_check_rfkill(sc);
1664 1.1 pooka }
1665 1.1 pooka
1666 1.1 pooka /* iwlwifi pcie/trans.c (always main power) */
1667 1.4 nonaka static void
1668 1.1 pooka iwm_set_pwr(struct iwm_softc *sc)
1669 1.1 pooka {
1670 1.1 pooka iwm_set_bits_mask_prph(sc, IWM_APMG_PS_CTRL_REG,
1671 1.1 pooka IWM_APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, ~IWM_APMG_PS_CTRL_MSK_PWR_SRC);
1672 1.1 pooka }
1673 1.1 pooka
1674 1.1 pooka /* iwlwifi: mvm/ops.c */
1675 1.4 nonaka static void
1676 1.1 pooka iwm_mvm_nic_config(struct iwm_softc *sc)
1677 1.1 pooka {
1678 1.1 pooka uint8_t radio_cfg_type, radio_cfg_step, radio_cfg_dash;
1679 1.1 pooka uint32_t reg_val = 0;
1680 1.1 pooka
1681 1.1 pooka radio_cfg_type = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_TYPE) >>
1682 1.1 pooka IWM_FW_PHY_CFG_RADIO_TYPE_POS;
1683 1.1 pooka radio_cfg_step = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_STEP) >>
1684 1.1 pooka IWM_FW_PHY_CFG_RADIO_STEP_POS;
1685 1.1 pooka radio_cfg_dash = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_DASH) >>
1686 1.1 pooka IWM_FW_PHY_CFG_RADIO_DASH_POS;
1687 1.1 pooka
1688 1.1 pooka /* SKU control */
1689 1.1 pooka reg_val |= IWM_CSR_HW_REV_STEP(sc->sc_hw_rev) <<
1690 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_POS_MAC_STEP;
1691 1.1 pooka reg_val |= IWM_CSR_HW_REV_DASH(sc->sc_hw_rev) <<
1692 1.1 pooka IWM_CSR_HW_IF_CONFIG_REG_POS_MAC_DASH;
1693 1.1 pooka
1694 1.1 pooka /* radio configuration */
1695 1.1 pooka reg_val |= radio_cfg_type << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE;
1696 1.1 pooka reg_val |= radio_cfg_step << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_STEP;
1697 1.1 pooka reg_val |= radio_cfg_dash << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_DASH;
1698 1.1 pooka
1699 1.1 pooka IWM_WRITE(sc, IWM_CSR_HW_IF_CONFIG_REG, reg_val);
1700 1.1 pooka
1701 1.8 nonaka DPRINTF(("Radio type=0x%x-0x%x-0x%x\n", radio_cfg_type,
1702 1.8 nonaka radio_cfg_step, radio_cfg_dash));
1703 1.1 pooka
1704 1.1 pooka /*
1705 1.1 pooka * W/A : NIC is stuck in a reset state after Early PCIe power off
1706 1.1 pooka * (PCIe power is lost before PERST# is asserted), causing ME FW
1707 1.1 pooka * to lose ownership and not being able to obtain it back.
1708 1.1 pooka */
1709 1.1 pooka iwm_set_bits_mask_prph(sc, IWM_APMG_PS_CTRL_REG,
1710 1.1 pooka IWM_APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
1711 1.1 pooka ~IWM_APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
1712 1.1 pooka }
1713 1.1 pooka
1714 1.4 nonaka static int
1715 1.1 pooka iwm_nic_rx_init(struct iwm_softc *sc)
1716 1.1 pooka {
1717 1.1 pooka if (!iwm_nic_lock(sc))
1718 1.1 pooka return EBUSY;
1719 1.1 pooka
1720 1.1 pooka /*
1721 1.1 pooka * Initialize RX ring. This is from the iwn driver.
1722 1.1 pooka */
1723 1.1 pooka memset(sc->rxq.stat, 0, sizeof(*sc->rxq.stat));
1724 1.1 pooka
1725 1.1 pooka /* stop DMA */
1726 1.1 pooka IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
1727 1.1 pooka IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_RBDCB_WPTR, 0);
1728 1.1 pooka IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ, 0);
1729 1.1 pooka IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_RDPTR, 0);
1730 1.1 pooka IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
1731 1.1 pooka
1732 1.1 pooka /* Set physical address of RX ring (256-byte aligned). */
1733 1.1 pooka IWM_WRITE(sc,
1734 1.1 pooka IWM_FH_RSCSR_CHNL0_RBDCB_BASE_REG, sc->rxq.desc_dma.paddr >> 8);
1735 1.1 pooka
1736 1.1 pooka /* Set physical address of RX status (16-byte aligned). */
1737 1.1 pooka IWM_WRITE(sc,
1738 1.1 pooka IWM_FH_RSCSR_CHNL0_STTS_WPTR_REG, sc->rxq.stat_dma.paddr >> 4);
1739 1.1 pooka
1740 1.1 pooka /* Enable RX. */
1741 1.1 pooka /*
1742 1.1 pooka * Note: Linux driver also sets this:
1743 1.1 pooka * (IWM_RX_RB_TIMEOUT << IWM_FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS) |
1744 1.1 pooka *
1745 1.1 pooka * It causes weird behavior. YMMV.
1746 1.1 pooka */
1747 1.1 pooka IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG,
1748 1.1 pooka IWM_FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
1749 1.1 pooka IWM_FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | /* HW bug */
1750 1.1 pooka IWM_FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
1751 1.1 pooka IWM_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K |
1752 1.1 pooka IWM_RX_QUEUE_SIZE_LOG << IWM_FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS);
1753 1.1 pooka
1754 1.1 pooka IWM_WRITE_1(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_TIMEOUT_DEF);
1755 1.17 nonaka
1756 1.17 nonaka /* W/A for interrupt coalescing bug in 7260 and 3160 */
1757 1.17 nonaka if (sc->host_interrupt_operation_mode)
1758 1.17 nonaka IWM_SETBITS(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_OPER_MODE);
1759 1.1 pooka
1760 1.1 pooka /*
1761 1.1 pooka * Thus sayeth el jefe (iwlwifi) via a comment:
1762 1.1 pooka *
1763 1.1 pooka * This value should initially be 0 (before preparing any
1764 1.38 ozaki * RBs), should be 8 after preparing the first 8 RBs (for example)
1765 1.1 pooka */
1766 1.1 pooka IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, 8);
1767 1.1 pooka
1768 1.1 pooka iwm_nic_unlock(sc);
1769 1.1 pooka
1770 1.1 pooka return 0;
1771 1.1 pooka }
1772 1.1 pooka
1773 1.4 nonaka static int
1774 1.1 pooka iwm_nic_tx_init(struct iwm_softc *sc)
1775 1.1 pooka {
1776 1.1 pooka int qid;
1777 1.1 pooka
1778 1.1 pooka if (!iwm_nic_lock(sc))
1779 1.1 pooka return EBUSY;
1780 1.1 pooka
1781 1.1 pooka /* Deactivate TX scheduler. */
1782 1.1 pooka iwm_write_prph(sc, IWM_SCD_TXFACT, 0);
1783 1.1 pooka
1784 1.1 pooka /* Set physical address of "keep warm" page (16-byte aligned). */
1785 1.1 pooka IWM_WRITE(sc, IWM_FH_KW_MEM_ADDR_REG, sc->kw_dma.paddr >> 4);
1786 1.1 pooka
1787 1.1 pooka /* Initialize TX rings. */
1788 1.1 pooka for (qid = 0; qid < __arraycount(sc->txq); qid++) {
1789 1.1 pooka struct iwm_tx_ring *txq = &sc->txq[qid];
1790 1.1 pooka
1791 1.1 pooka /* Set physical address of TX ring (256-byte aligned). */
1792 1.1 pooka IWM_WRITE(sc, IWM_FH_MEM_CBBC_QUEUE(qid),
1793 1.1 pooka txq->desc_dma.paddr >> 8);
1794 1.9 nonaka DPRINTF(("loading ring %d descriptors (%p) at %"PRIxMAX"\n",
1795 1.9 nonaka qid, txq->desc, (uintmax_t)(txq->desc_dma.paddr >> 8)));
1796 1.1 pooka }
1797 1.1 pooka iwm_nic_unlock(sc);
1798 1.1 pooka
1799 1.1 pooka return 0;
1800 1.1 pooka }
1801 1.1 pooka
1802 1.4 nonaka static int
1803 1.1 pooka iwm_nic_init(struct iwm_softc *sc)
1804 1.1 pooka {
1805 1.1 pooka int error;
1806 1.1 pooka
1807 1.1 pooka iwm_apm_init(sc);
1808 1.1 pooka iwm_set_pwr(sc);
1809 1.1 pooka
1810 1.1 pooka iwm_mvm_nic_config(sc);
1811 1.1 pooka
1812 1.1 pooka if ((error = iwm_nic_rx_init(sc)) != 0)
1813 1.1 pooka return error;
1814 1.1 pooka
1815 1.1 pooka /*
1816 1.1 pooka * Ditto for TX, from iwn
1817 1.1 pooka */
1818 1.1 pooka if ((error = iwm_nic_tx_init(sc)) != 0)
1819 1.1 pooka return error;
1820 1.1 pooka
1821 1.1 pooka DPRINTF(("shadow registers enabled\n"));
1822 1.1 pooka IWM_SETBITS(sc, IWM_CSR_MAC_SHADOW_REG_CTRL, 0x800fffff);
1823 1.1 pooka
1824 1.8 nonaka return 0;
1825 1.1 pooka }
1826 1.1 pooka
1827 1.7 nonaka #if 0
1828 1.1 pooka enum iwm_mvm_tx_fifo {
1829 1.1 pooka IWM_MVM_TX_FIFO_BK = 0,
1830 1.1 pooka IWM_MVM_TX_FIFO_BE,
1831 1.1 pooka IWM_MVM_TX_FIFO_VI,
1832 1.1 pooka IWM_MVM_TX_FIFO_VO,
1833 1.1 pooka IWM_MVM_TX_FIFO_MCAST = 5,
1834 1.1 pooka };
1835 1.1 pooka
1836 1.4 nonaka static const uint8_t iwm_mvm_ac_to_tx_fifo[] = {
1837 1.8 nonaka IWM_MVM_TX_FIFO_VO,
1838 1.8 nonaka IWM_MVM_TX_FIFO_VI,
1839 1.8 nonaka IWM_MVM_TX_FIFO_BE,
1840 1.8 nonaka IWM_MVM_TX_FIFO_BK,
1841 1.1 pooka };
1842 1.7 nonaka #endif
1843 1.1 pooka
1844 1.4 nonaka static void
1845 1.1 pooka iwm_enable_txq(struct iwm_softc *sc, int qid, int fifo)
1846 1.1 pooka {
1847 1.1 pooka if (!iwm_nic_lock(sc)) {
1848 1.2 nonaka DPRINTF(("%s: cannot enable txq %d\n", DEVNAME(sc), qid));
1849 1.2 nonaka return; /* XXX return EBUSY */
1850 1.1 pooka }
1851 1.1 pooka
1852 1.1 pooka /* unactivate before configuration */
1853 1.1 pooka iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
1854 1.1 pooka (0 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE)
1855 1.1 pooka | (1 << IWM_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
1856 1.1 pooka
1857 1.1 pooka if (qid != IWM_MVM_CMD_QUEUE) {
1858 1.1 pooka iwm_set_bits_prph(sc, IWM_SCD_QUEUECHAIN_SEL, (1 << qid));
1859 1.1 pooka }
1860 1.1 pooka
1861 1.1 pooka iwm_clear_bits_prph(sc, IWM_SCD_AGGR_SEL, (1 << qid));
1862 1.1 pooka
1863 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, qid << 8 | 0);
1864 1.1 pooka iwm_write_prph(sc, IWM_SCD_QUEUE_RDPTR(qid), 0);
1865 1.1 pooka
1866 1.1 pooka iwm_write_mem32(sc, sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid), 0);
1867 1.1 pooka /* Set scheduler window size and frame limit. */
1868 1.1 pooka iwm_write_mem32(sc,
1869 1.1 pooka sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid) +
1870 1.1 pooka sizeof(uint32_t),
1871 1.1 pooka ((IWM_FRAME_LIMIT << IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
1872 1.1 pooka IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
1873 1.1 pooka ((IWM_FRAME_LIMIT << IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
1874 1.1 pooka IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
1875 1.1 pooka
1876 1.1 pooka iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
1877 1.1 pooka (1 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
1878 1.1 pooka (fifo << IWM_SCD_QUEUE_STTS_REG_POS_TXF) |
1879 1.1 pooka (1 << IWM_SCD_QUEUE_STTS_REG_POS_WSL) |
1880 1.1 pooka IWM_SCD_QUEUE_STTS_REG_MSK);
1881 1.1 pooka
1882 1.1 pooka iwm_nic_unlock(sc);
1883 1.1 pooka
1884 1.1 pooka DPRINTF(("enabled txq %d FIFO %d\n", qid, fifo));
1885 1.1 pooka }
1886 1.1 pooka
1887 1.4 nonaka static int
1888 1.1 pooka iwm_post_alive(struct iwm_softc *sc)
1889 1.1 pooka {
1890 1.1 pooka int nwords;
1891 1.1 pooka int error, chnl;
1892 1.1 pooka
1893 1.1 pooka if (!iwm_nic_lock(sc))
1894 1.1 pooka return EBUSY;
1895 1.1 pooka
1896 1.1 pooka if (sc->sched_base != iwm_read_prph(sc, IWM_SCD_SRAM_BASE_ADDR)) {
1897 1.5 nonaka DPRINTF(("%s: sched addr mismatch\n", DEVNAME(sc)));
1898 1.1 pooka error = EINVAL;
1899 1.1 pooka goto out;
1900 1.1 pooka }
1901 1.1 pooka
1902 1.1 pooka iwm_ict_reset(sc);
1903 1.1 pooka
1904 1.1 pooka /* Clear TX scheduler state in SRAM. */
1905 1.1 pooka nwords = (IWM_SCD_TRANS_TBL_MEM_UPPER_BOUND -
1906 1.1 pooka IWM_SCD_CONTEXT_MEM_LOWER_BOUND)
1907 1.1 pooka / sizeof(uint32_t);
1908 1.1 pooka error = iwm_write_mem(sc,
1909 1.1 pooka sc->sched_base + IWM_SCD_CONTEXT_MEM_LOWER_BOUND,
1910 1.1 pooka NULL, nwords);
1911 1.1 pooka if (error)
1912 1.1 pooka goto out;
1913 1.1 pooka
1914 1.1 pooka /* Set physical address of TX scheduler rings (1KB aligned). */
1915 1.1 pooka iwm_write_prph(sc, IWM_SCD_DRAM_BASE_ADDR, sc->sched_dma.paddr >> 10);
1916 1.1 pooka
1917 1.1 pooka iwm_write_prph(sc, IWM_SCD_CHAINEXT_EN, 0);
1918 1.1 pooka
1919 1.1 pooka /* enable command channel */
1920 1.1 pooka iwm_enable_txq(sc, IWM_MVM_CMD_QUEUE, 7);
1921 1.1 pooka
1922 1.1 pooka iwm_write_prph(sc, IWM_SCD_TXFACT, 0xff);
1923 1.1 pooka
1924 1.1 pooka /* Enable DMA channels. */
1925 1.1 pooka for (chnl = 0; chnl < IWM_FH_TCSR_CHNL_NUM; chnl++) {
1926 1.1 pooka IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(chnl),
1927 1.1 pooka IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
1928 1.1 pooka IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
1929 1.1 pooka }
1930 1.1 pooka
1931 1.1 pooka IWM_SETBITS(sc, IWM_FH_TX_CHICKEN_BITS_REG,
1932 1.1 pooka IWM_FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
1933 1.1 pooka
1934 1.8 nonaka /* Enable L1-Active */
1935 1.1 pooka iwm_clear_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
1936 1.1 pooka IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
1937 1.1 pooka
1938 1.1 pooka out:
1939 1.38 ozaki iwm_nic_unlock(sc);
1940 1.1 pooka return error;
1941 1.1 pooka }
1942 1.1 pooka
1943 1.1 pooka /*
1944 1.1 pooka * PHY db
1945 1.1 pooka * iwlwifi/iwl-phy-db.c
1946 1.1 pooka */
1947 1.1 pooka
1948 1.1 pooka /*
1949 1.1 pooka * BEGIN iwl-phy-db.c
1950 1.1 pooka */
1951 1.1 pooka
1952 1.1 pooka enum iwm_phy_db_section_type {
1953 1.1 pooka IWM_PHY_DB_CFG = 1,
1954 1.1 pooka IWM_PHY_DB_CALIB_NCH,
1955 1.1 pooka IWM_PHY_DB_UNUSED,
1956 1.1 pooka IWM_PHY_DB_CALIB_CHG_PAPD,
1957 1.1 pooka IWM_PHY_DB_CALIB_CHG_TXP,
1958 1.1 pooka IWM_PHY_DB_MAX
1959 1.1 pooka };
1960 1.1 pooka
1961 1.1 pooka #define IWM_PHY_DB_CMD 0x6c /* TEMP API - The actual is 0x8c */
1962 1.1 pooka
1963 1.1 pooka /*
1964 1.1 pooka * phy db - configure operational ucode
1965 1.1 pooka */
1966 1.1 pooka struct iwm_phy_db_cmd {
1967 1.1 pooka uint16_t type;
1968 1.1 pooka uint16_t length;
1969 1.1 pooka uint8_t data[];
1970 1.1 pooka } __packed;
1971 1.1 pooka
1972 1.1 pooka /* for parsing of tx power channel group data that comes from the firmware*/
1973 1.1 pooka struct iwm_phy_db_chg_txp {
1974 1.1 pooka uint32_t space;
1975 1.1 pooka uint16_t max_channel_idx;
1976 1.1 pooka } __packed;
1977 1.1 pooka
1978 1.1 pooka /*
1979 1.1 pooka * phy db - Receive phy db chunk after calibrations
1980 1.1 pooka */
1981 1.1 pooka struct iwm_calib_res_notif_phy_db {
1982 1.1 pooka uint16_t type;
1983 1.1 pooka uint16_t length;
1984 1.1 pooka uint8_t data[];
1985 1.1 pooka } __packed;
1986 1.1 pooka
1987 1.1 pooka /*
1988 1.1 pooka * get phy db section: returns a pointer to a phy db section specified by
1989 1.1 pooka * type and channel group id.
1990 1.1 pooka */
1991 1.1 pooka static struct iwm_phy_db_entry *
1992 1.1 pooka iwm_phy_db_get_section(struct iwm_softc *sc,
1993 1.1 pooka enum iwm_phy_db_section_type type, uint16_t chg_id)
1994 1.1 pooka {
1995 1.1 pooka struct iwm_phy_db *phy_db = &sc->sc_phy_db;
1996 1.1 pooka
1997 1.1 pooka if (type >= IWM_PHY_DB_MAX)
1998 1.1 pooka return NULL;
1999 1.1 pooka
2000 1.1 pooka switch (type) {
2001 1.1 pooka case IWM_PHY_DB_CFG:
2002 1.1 pooka return &phy_db->cfg;
2003 1.1 pooka case IWM_PHY_DB_CALIB_NCH:
2004 1.1 pooka return &phy_db->calib_nch;
2005 1.1 pooka case IWM_PHY_DB_CALIB_CHG_PAPD:
2006 1.1 pooka if (chg_id >= IWM_NUM_PAPD_CH_GROUPS)
2007 1.1 pooka return NULL;
2008 1.1 pooka return &phy_db->calib_ch_group_papd[chg_id];
2009 1.1 pooka case IWM_PHY_DB_CALIB_CHG_TXP:
2010 1.1 pooka if (chg_id >= IWM_NUM_TXP_CH_GROUPS)
2011 1.1 pooka return NULL;
2012 1.1 pooka return &phy_db->calib_ch_group_txp[chg_id];
2013 1.1 pooka default:
2014 1.1 pooka return NULL;
2015 1.1 pooka }
2016 1.1 pooka return NULL;
2017 1.1 pooka }
2018 1.1 pooka
2019 1.1 pooka static int
2020 1.1 pooka iwm_phy_db_set_section(struct iwm_softc *sc,
2021 1.5 nonaka struct iwm_calib_res_notif_phy_db *phy_db_notif, uint16_t size)
2022 1.1 pooka {
2023 1.1 pooka enum iwm_phy_db_section_type type = le16toh(phy_db_notif->type);
2024 1.1 pooka struct iwm_phy_db_entry *entry;
2025 1.1 pooka uint16_t chg_id = 0;
2026 1.1 pooka
2027 1.1 pooka if (type == IWM_PHY_DB_CALIB_CHG_PAPD ||
2028 1.1 pooka type == IWM_PHY_DB_CALIB_CHG_TXP)
2029 1.1 pooka chg_id = le16toh(*(uint16_t *)phy_db_notif->data);
2030 1.1 pooka
2031 1.1 pooka entry = iwm_phy_db_get_section(sc, type, chg_id);
2032 1.1 pooka if (!entry)
2033 1.1 pooka return EINVAL;
2034 1.1 pooka
2035 1.1 pooka if (entry->data)
2036 1.5 nonaka kmem_intr_free(entry->data, entry->size);
2037 1.5 nonaka entry->data = kmem_intr_alloc(size, KM_NOSLEEP);
2038 1.1 pooka if (!entry->data) {
2039 1.1 pooka entry->size = 0;
2040 1.1 pooka return ENOMEM;
2041 1.1 pooka }
2042 1.1 pooka memcpy(entry->data, phy_db_notif->data, size);
2043 1.1 pooka entry->size = size;
2044 1.1 pooka
2045 1.5 nonaka DPRINTFN(10, ("%s(%d): [PHYDB]SET: Type %d, Size: %d, data: %p\n",
2046 1.1 pooka __func__, __LINE__, type, size, entry->data));
2047 1.1 pooka
2048 1.1 pooka return 0;
2049 1.1 pooka }
2050 1.1 pooka
2051 1.4 nonaka static int
2052 1.1 pooka iwm_is_valid_channel(uint16_t ch_id)
2053 1.1 pooka {
2054 1.1 pooka if (ch_id <= 14 ||
2055 1.1 pooka (36 <= ch_id && ch_id <= 64 && ch_id % 4 == 0) ||
2056 1.1 pooka (100 <= ch_id && ch_id <= 140 && ch_id % 4 == 0) ||
2057 1.1 pooka (145 <= ch_id && ch_id <= 165 && ch_id % 4 == 1))
2058 1.1 pooka return 1;
2059 1.1 pooka return 0;
2060 1.1 pooka }
2061 1.1 pooka
2062 1.4 nonaka static uint8_t
2063 1.1 pooka iwm_ch_id_to_ch_index(uint16_t ch_id)
2064 1.1 pooka {
2065 1.1 pooka if (!iwm_is_valid_channel(ch_id))
2066 1.1 pooka return 0xff;
2067 1.1 pooka
2068 1.1 pooka if (ch_id <= 14)
2069 1.1 pooka return ch_id - 1;
2070 1.1 pooka if (ch_id <= 64)
2071 1.1 pooka return (ch_id + 20) / 4;
2072 1.1 pooka if (ch_id <= 140)
2073 1.1 pooka return (ch_id - 12) / 4;
2074 1.1 pooka return (ch_id - 13) / 4;
2075 1.1 pooka }
2076 1.1 pooka
2077 1.1 pooka
2078 1.4 nonaka static uint16_t
2079 1.1 pooka iwm_channel_id_to_papd(uint16_t ch_id)
2080 1.1 pooka {
2081 1.1 pooka if (!iwm_is_valid_channel(ch_id))
2082 1.1 pooka return 0xff;
2083 1.1 pooka
2084 1.1 pooka if (1 <= ch_id && ch_id <= 14)
2085 1.1 pooka return 0;
2086 1.1 pooka if (36 <= ch_id && ch_id <= 64)
2087 1.1 pooka return 1;
2088 1.1 pooka if (100 <= ch_id && ch_id <= 140)
2089 1.1 pooka return 2;
2090 1.1 pooka return 3;
2091 1.1 pooka }
2092 1.1 pooka
2093 1.4 nonaka static uint16_t
2094 1.1 pooka iwm_channel_id_to_txp(struct iwm_softc *sc, uint16_t ch_id)
2095 1.1 pooka {
2096 1.1 pooka struct iwm_phy_db *phy_db = &sc->sc_phy_db;
2097 1.1 pooka struct iwm_phy_db_chg_txp *txp_chg;
2098 1.1 pooka int i;
2099 1.1 pooka uint8_t ch_index = iwm_ch_id_to_ch_index(ch_id);
2100 1.1 pooka
2101 1.1 pooka if (ch_index == 0xff)
2102 1.1 pooka return 0xff;
2103 1.1 pooka
2104 1.1 pooka for (i = 0; i < IWM_NUM_TXP_CH_GROUPS; i++) {
2105 1.1 pooka txp_chg = (void *)phy_db->calib_ch_group_txp[i].data;
2106 1.1 pooka if (!txp_chg)
2107 1.1 pooka return 0xff;
2108 1.1 pooka /*
2109 1.1 pooka * Looking for the first channel group that its max channel is
2110 1.1 pooka * higher then wanted channel.
2111 1.1 pooka */
2112 1.1 pooka if (le16toh(txp_chg->max_channel_idx) >= ch_index)
2113 1.1 pooka return i;
2114 1.1 pooka }
2115 1.1 pooka return 0xff;
2116 1.1 pooka }
2117 1.1 pooka
2118 1.4 nonaka static int
2119 1.1 pooka iwm_phy_db_get_section_data(struct iwm_softc *sc,
2120 1.1 pooka uint32_t type, uint8_t **data, uint16_t *size, uint16_t ch_id)
2121 1.1 pooka {
2122 1.1 pooka struct iwm_phy_db_entry *entry;
2123 1.1 pooka uint16_t ch_group_id = 0;
2124 1.1 pooka
2125 1.1 pooka /* find wanted channel group */
2126 1.1 pooka if (type == IWM_PHY_DB_CALIB_CHG_PAPD)
2127 1.1 pooka ch_group_id = iwm_channel_id_to_papd(ch_id);
2128 1.1 pooka else if (type == IWM_PHY_DB_CALIB_CHG_TXP)
2129 1.1 pooka ch_group_id = iwm_channel_id_to_txp(sc, ch_id);
2130 1.1 pooka
2131 1.1 pooka entry = iwm_phy_db_get_section(sc, type, ch_group_id);
2132 1.1 pooka if (!entry)
2133 1.1 pooka return EINVAL;
2134 1.1 pooka
2135 1.1 pooka *data = entry->data;
2136 1.1 pooka *size = entry->size;
2137 1.1 pooka
2138 1.1 pooka DPRINTFN(10, ("%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
2139 1.1 pooka __func__, __LINE__, type, *size));
2140 1.1 pooka
2141 1.1 pooka return 0;
2142 1.1 pooka }
2143 1.1 pooka
2144 1.4 nonaka static int
2145 1.1 pooka iwm_send_phy_db_cmd(struct iwm_softc *sc, uint16_t type,
2146 1.1 pooka uint16_t length, void *data)
2147 1.1 pooka {
2148 1.1 pooka struct iwm_phy_db_cmd phy_db_cmd;
2149 1.1 pooka struct iwm_host_cmd cmd = {
2150 1.1 pooka .id = IWM_PHY_DB_CMD,
2151 1.1 pooka .flags = IWM_CMD_SYNC,
2152 1.1 pooka };
2153 1.1 pooka
2154 1.5 nonaka DPRINTFN(10, ("Sending PHY-DB hcmd of type %d, of length %d\n",
2155 1.5 nonaka type, length));
2156 1.1 pooka
2157 1.1 pooka /* Set phy db cmd variables */
2158 1.1 pooka phy_db_cmd.type = le16toh(type);
2159 1.1 pooka phy_db_cmd.length = le16toh(length);
2160 1.1 pooka
2161 1.1 pooka /* Set hcmd variables */
2162 1.1 pooka cmd.data[0] = &phy_db_cmd;
2163 1.1 pooka cmd.len[0] = sizeof(struct iwm_phy_db_cmd);
2164 1.1 pooka cmd.data[1] = data;
2165 1.1 pooka cmd.len[1] = length;
2166 1.1 pooka cmd.dataflags[1] = IWM_HCMD_DFL_NOCOPY;
2167 1.1 pooka
2168 1.1 pooka return iwm_send_cmd(sc, &cmd);
2169 1.1 pooka }
2170 1.1 pooka
2171 1.1 pooka static int
2172 1.1 pooka iwm_phy_db_send_all_channel_groups(struct iwm_softc *sc,
2173 1.1 pooka enum iwm_phy_db_section_type type, uint8_t max_ch_groups)
2174 1.1 pooka {
2175 1.1 pooka uint16_t i;
2176 1.1 pooka int err;
2177 1.1 pooka struct iwm_phy_db_entry *entry;
2178 1.1 pooka
2179 1.1 pooka /* Send all the channel-specific groups to operational fw */
2180 1.1 pooka for (i = 0; i < max_ch_groups; i++) {
2181 1.1 pooka entry = iwm_phy_db_get_section(sc, type, i);
2182 1.1 pooka if (!entry)
2183 1.1 pooka return EINVAL;
2184 1.1 pooka
2185 1.1 pooka if (!entry->size)
2186 1.1 pooka continue;
2187 1.1 pooka
2188 1.1 pooka /* Send the requested PHY DB section */
2189 1.1 pooka err = iwm_send_phy_db_cmd(sc, type, entry->size, entry->data);
2190 1.1 pooka if (err) {
2191 1.2 nonaka DPRINTF(("%s: Can't SEND phy_db section %d (%d), "
2192 1.2 nonaka "err %d\n", DEVNAME(sc), type, i, err));
2193 1.1 pooka return err;
2194 1.1 pooka }
2195 1.1 pooka
2196 1.1 pooka DPRINTFN(10, ("Sent PHY_DB HCMD, type = %d num = %d\n", type, i));
2197 1.1 pooka }
2198 1.1 pooka
2199 1.1 pooka return 0;
2200 1.1 pooka }
2201 1.1 pooka
2202 1.4 nonaka static int
2203 1.1 pooka iwm_send_phy_db_data(struct iwm_softc *sc)
2204 1.1 pooka {
2205 1.1 pooka uint8_t *data = NULL;
2206 1.1 pooka uint16_t size = 0;
2207 1.1 pooka int err;
2208 1.1 pooka
2209 1.1 pooka DPRINTF(("Sending phy db data and configuration to runtime image\n"));
2210 1.1 pooka
2211 1.1 pooka /* Send PHY DB CFG section */
2212 1.1 pooka err = iwm_phy_db_get_section_data(sc, IWM_PHY_DB_CFG, &data, &size, 0);
2213 1.1 pooka if (err) {
2214 1.2 nonaka DPRINTF(("%s: Cannot get Phy DB cfg section, %d\n",
2215 1.2 nonaka DEVNAME(sc), err));
2216 1.1 pooka return err;
2217 1.1 pooka }
2218 1.1 pooka
2219 1.1 pooka err = iwm_send_phy_db_cmd(sc, IWM_PHY_DB_CFG, size, data);
2220 1.1 pooka if (err) {
2221 1.2 nonaka DPRINTF(("%s: Cannot send HCMD of Phy DB cfg section, %d\n",
2222 1.2 nonaka DEVNAME(sc), err));
2223 1.1 pooka return err;
2224 1.1 pooka }
2225 1.1 pooka
2226 1.1 pooka err = iwm_phy_db_get_section_data(sc, IWM_PHY_DB_CALIB_NCH,
2227 1.1 pooka &data, &size, 0);
2228 1.1 pooka if (err) {
2229 1.2 nonaka DPRINTF(("%s: Cannot get Phy DB non specific channel section, "
2230 1.2 nonaka "%d\n", DEVNAME(sc), err));
2231 1.1 pooka return err;
2232 1.1 pooka }
2233 1.1 pooka
2234 1.1 pooka err = iwm_send_phy_db_cmd(sc, IWM_PHY_DB_CALIB_NCH, size, data);
2235 1.1 pooka if (err) {
2236 1.2 nonaka DPRINTF(("%s: Cannot send HCMD of Phy DB non specific channel "
2237 1.2 nonaka "sect, %d\n", DEVNAME(sc), err));
2238 1.1 pooka return err;
2239 1.1 pooka }
2240 1.1 pooka
2241 1.1 pooka /* Send all the TXP channel specific data */
2242 1.1 pooka err = iwm_phy_db_send_all_channel_groups(sc,
2243 1.1 pooka IWM_PHY_DB_CALIB_CHG_PAPD, IWM_NUM_PAPD_CH_GROUPS);
2244 1.1 pooka if (err) {
2245 1.2 nonaka DPRINTF(("%s: Cannot send channel specific PAPD groups, %d\n",
2246 1.2 nonaka DEVNAME(sc), err));
2247 1.1 pooka return err;
2248 1.1 pooka }
2249 1.1 pooka
2250 1.1 pooka /* Send all the TXP channel specific data */
2251 1.1 pooka err = iwm_phy_db_send_all_channel_groups(sc,
2252 1.1 pooka IWM_PHY_DB_CALIB_CHG_TXP, IWM_NUM_TXP_CH_GROUPS);
2253 1.1 pooka if (err) {
2254 1.2 nonaka DPRINTF(("%s: Cannot send channel specific TX power groups, "
2255 1.2 nonaka "%d\n", DEVNAME(sc), err));
2256 1.1 pooka return err;
2257 1.1 pooka }
2258 1.1 pooka
2259 1.1 pooka DPRINTF(("Finished sending phy db non channel data\n"));
2260 1.1 pooka return 0;
2261 1.1 pooka }
2262 1.1 pooka
2263 1.1 pooka /*
2264 1.1 pooka * END iwl-phy-db.c
2265 1.1 pooka */
2266 1.1 pooka
2267 1.1 pooka /*
2268 1.1 pooka * BEGIN iwlwifi/mvm/time-event.c
2269 1.1 pooka */
2270 1.1 pooka
2271 1.1 pooka /*
2272 1.1 pooka * For the high priority TE use a time event type that has similar priority to
2273 1.1 pooka * the FW's action scan priority.
2274 1.1 pooka */
2275 1.1 pooka #define IWM_MVM_ROC_TE_TYPE_NORMAL IWM_TE_P2P_DEVICE_DISCOVERABLE
2276 1.1 pooka #define IWM_MVM_ROC_TE_TYPE_MGMT_TX IWM_TE_P2P_CLIENT_ASSOC
2277 1.1 pooka
2278 1.1 pooka /* used to convert from time event API v2 to v1 */
2279 1.1 pooka #define IWM_TE_V2_DEP_POLICY_MSK (IWM_TE_V2_DEP_OTHER | IWM_TE_V2_DEP_TSF |\
2280 1.1 pooka IWM_TE_V2_EVENT_SOCIOPATHIC)
2281 1.1 pooka static inline uint16_t
2282 1.1 pooka iwm_te_v2_get_notify(uint16_t policy)
2283 1.1 pooka {
2284 1.1 pooka return le16toh(policy) & IWM_TE_V2_NOTIF_MSK;
2285 1.1 pooka }
2286 1.1 pooka
2287 1.1 pooka static inline uint16_t
2288 1.1 pooka iwm_te_v2_get_dep_policy(uint16_t policy)
2289 1.1 pooka {
2290 1.1 pooka return (le16toh(policy) & IWM_TE_V2_DEP_POLICY_MSK) >>
2291 1.1 pooka IWM_TE_V2_PLACEMENT_POS;
2292 1.1 pooka }
2293 1.1 pooka
2294 1.1 pooka static inline uint16_t
2295 1.1 pooka iwm_te_v2_get_absence(uint16_t policy)
2296 1.1 pooka {
2297 1.1 pooka return (le16toh(policy) & IWM_TE_V2_ABSENCE) >> IWM_TE_V2_ABSENCE_POS;
2298 1.1 pooka }
2299 1.1 pooka
2300 1.4 nonaka static void
2301 1.1 pooka iwm_mvm_te_v2_to_v1(const struct iwm_time_event_cmd_v2 *cmd_v2,
2302 1.1 pooka struct iwm_time_event_cmd_v1 *cmd_v1)
2303 1.1 pooka {
2304 1.1 pooka cmd_v1->id_and_color = cmd_v2->id_and_color;
2305 1.1 pooka cmd_v1->action = cmd_v2->action;
2306 1.1 pooka cmd_v1->id = cmd_v2->id;
2307 1.1 pooka cmd_v1->apply_time = cmd_v2->apply_time;
2308 1.1 pooka cmd_v1->max_delay = cmd_v2->max_delay;
2309 1.1 pooka cmd_v1->depends_on = cmd_v2->depends_on;
2310 1.1 pooka cmd_v1->interval = cmd_v2->interval;
2311 1.1 pooka cmd_v1->duration = cmd_v2->duration;
2312 1.1 pooka if (cmd_v2->repeat == IWM_TE_V2_REPEAT_ENDLESS)
2313 1.1 pooka cmd_v1->repeat = htole32(IWM_TE_V1_REPEAT_ENDLESS);
2314 1.1 pooka else
2315 1.1 pooka cmd_v1->repeat = htole32(cmd_v2->repeat);
2316 1.1 pooka cmd_v1->max_frags = htole32(cmd_v2->max_frags);
2317 1.1 pooka cmd_v1->interval_reciprocal = 0; /* unused */
2318 1.1 pooka
2319 1.1 pooka cmd_v1->dep_policy = htole32(iwm_te_v2_get_dep_policy(cmd_v2->policy));
2320 1.1 pooka cmd_v1->is_present = htole32(!iwm_te_v2_get_absence(cmd_v2->policy));
2321 1.1 pooka cmd_v1->notify = htole32(iwm_te_v2_get_notify(cmd_v2->policy));
2322 1.1 pooka }
2323 1.1 pooka
2324 1.4 nonaka static int
2325 1.1 pooka iwm_mvm_send_time_event_cmd(struct iwm_softc *sc,
2326 1.1 pooka const struct iwm_time_event_cmd_v2 *cmd)
2327 1.1 pooka {
2328 1.1 pooka struct iwm_time_event_cmd_v1 cmd_v1;
2329 1.1 pooka
2330 1.1 pooka if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_TIME_EVENT_API_V2)
2331 1.1 pooka return iwm_mvm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD,
2332 1.1 pooka IWM_CMD_SYNC, sizeof(*cmd), cmd);
2333 1.1 pooka
2334 1.1 pooka iwm_mvm_te_v2_to_v1(cmd, &cmd_v1);
2335 1.1 pooka return iwm_mvm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, IWM_CMD_SYNC,
2336 1.1 pooka sizeof(cmd_v1), &cmd_v1);
2337 1.1 pooka }
2338 1.1 pooka
2339 1.4 nonaka static int
2340 1.1 pooka iwm_mvm_time_event_send_add(struct iwm_softc *sc, struct iwm_node *in,
2341 1.1 pooka void *te_data, struct iwm_time_event_cmd_v2 *te_cmd)
2342 1.1 pooka {
2343 1.1 pooka int ret;
2344 1.1 pooka
2345 1.1 pooka DPRINTF(("Add new TE, duration %d TU\n", le32toh(te_cmd->duration)));
2346 1.1 pooka
2347 1.1 pooka ret = iwm_mvm_send_time_event_cmd(sc, te_cmd);
2348 1.1 pooka if (ret) {
2349 1.2 nonaka DPRINTF(("%s: Couldn't send IWM_TIME_EVENT_CMD: %d\n",
2350 1.2 nonaka DEVNAME(sc), ret));
2351 1.1 pooka }
2352 1.1 pooka
2353 1.1 pooka return ret;
2354 1.1 pooka }
2355 1.1 pooka
2356 1.4 nonaka static void
2357 1.1 pooka iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_node *in,
2358 1.1 pooka uint32_t duration, uint32_t min_duration, uint32_t max_delay)
2359 1.1 pooka {
2360 1.1 pooka struct iwm_time_event_cmd_v2 time_cmd;
2361 1.1 pooka
2362 1.1 pooka memset(&time_cmd, 0, sizeof(time_cmd));
2363 1.1 pooka
2364 1.1 pooka time_cmd.action = htole32(IWM_FW_CTXT_ACTION_ADD);
2365 1.1 pooka time_cmd.id_and_color =
2366 1.1 pooka htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
2367 1.1 pooka time_cmd.id = htole32(IWM_TE_BSS_STA_AGGRESSIVE_ASSOC);
2368 1.1 pooka
2369 1.1 pooka time_cmd.apply_time = htole32(iwm_read_prph(sc,
2370 1.1 pooka IWM_DEVICE_SYSTEM_TIME_REG));
2371 1.1 pooka
2372 1.1 pooka time_cmd.max_frags = IWM_TE_V2_FRAG_NONE;
2373 1.1 pooka time_cmd.max_delay = htole32(max_delay);
2374 1.1 pooka /* TODO: why do we need to interval = bi if it is not periodic? */
2375 1.1 pooka time_cmd.interval = htole32(1);
2376 1.1 pooka time_cmd.duration = htole32(duration);
2377 1.1 pooka time_cmd.repeat = 1;
2378 1.1 pooka time_cmd.policy
2379 1.1 pooka = htole32(IWM_TE_V2_NOTIF_HOST_EVENT_START |
2380 1.1 pooka IWM_TE_V2_NOTIF_HOST_EVENT_END);
2381 1.1 pooka
2382 1.1 pooka iwm_mvm_time_event_send_add(sc, in, /*te_data*/NULL, &time_cmd);
2383 1.1 pooka }
2384 1.1 pooka
2385 1.1 pooka /*
2386 1.1 pooka * END iwlwifi/mvm/time-event.c
2387 1.1 pooka */
2388 1.1 pooka
2389 1.1 pooka /*
2390 1.1 pooka * NVM read access and content parsing. We do not support
2391 1.1 pooka * external NVM or writing NVM.
2392 1.1 pooka * iwlwifi/mvm/nvm.c
2393 1.1 pooka */
2394 1.1 pooka
2395 1.1 pooka /* list of NVM sections we are allowed/need to read */
2396 1.4 nonaka static const int nvm_to_read[] = {
2397 1.1 pooka IWM_NVM_SECTION_TYPE_HW,
2398 1.1 pooka IWM_NVM_SECTION_TYPE_SW,
2399 1.1 pooka IWM_NVM_SECTION_TYPE_CALIBRATION,
2400 1.1 pooka IWM_NVM_SECTION_TYPE_PRODUCTION,
2401 1.1 pooka };
2402 1.1 pooka
2403 1.1 pooka /* Default NVM size to read */
2404 1.1 pooka #define IWM_NVM_DEFAULT_CHUNK_SIZE (2*1024)
2405 1.1 pooka #define IWM_MAX_NVM_SECTION_SIZE 7000
2406 1.1 pooka
2407 1.1 pooka #define IWM_NVM_WRITE_OPCODE 1
2408 1.1 pooka #define IWM_NVM_READ_OPCODE 0
2409 1.1 pooka
2410 1.4 nonaka static int
2411 1.1 pooka iwm_nvm_read_chunk(struct iwm_softc *sc, uint16_t section,
2412 1.1 pooka uint16_t offset, uint16_t length, uint8_t *data, uint16_t *len)
2413 1.1 pooka {
2414 1.1 pooka offset = 0;
2415 1.1 pooka struct iwm_nvm_access_cmd nvm_access_cmd = {
2416 1.1 pooka .offset = htole16(offset),
2417 1.1 pooka .length = htole16(length),
2418 1.1 pooka .type = htole16(section),
2419 1.1 pooka .op_code = IWM_NVM_READ_OPCODE,
2420 1.1 pooka };
2421 1.1 pooka struct iwm_nvm_access_resp *nvm_resp;
2422 1.1 pooka struct iwm_rx_packet *pkt;
2423 1.1 pooka struct iwm_host_cmd cmd = {
2424 1.1 pooka .id = IWM_NVM_ACCESS_CMD,
2425 1.1 pooka .flags = IWM_CMD_SYNC | IWM_CMD_WANT_SKB |
2426 1.1 pooka IWM_CMD_SEND_IN_RFKILL,
2427 1.1 pooka .data = { &nvm_access_cmd, },
2428 1.1 pooka };
2429 1.1 pooka int ret, bytes_read, offset_read;
2430 1.1 pooka uint8_t *resp_data;
2431 1.1 pooka
2432 1.1 pooka cmd.len[0] = sizeof(struct iwm_nvm_access_cmd);
2433 1.1 pooka
2434 1.1 pooka ret = iwm_send_cmd(sc, &cmd);
2435 1.1 pooka if (ret)
2436 1.1 pooka return ret;
2437 1.1 pooka
2438 1.1 pooka pkt = cmd.resp_pkt;
2439 1.1 pooka if (pkt->hdr.flags & IWM_CMD_FAILED_MSK) {
2440 1.2 nonaka DPRINTF(("%s: Bad return from IWM_NVM_ACCES_COMMAND (0x%08X)\n",
2441 1.2 nonaka DEVNAME(sc), pkt->hdr.flags));
2442 1.1 pooka ret = EIO;
2443 1.1 pooka goto exit;
2444 1.1 pooka }
2445 1.1 pooka
2446 1.1 pooka /* Extract NVM response */
2447 1.1 pooka nvm_resp = (void *)pkt->data;
2448 1.1 pooka
2449 1.1 pooka ret = le16toh(nvm_resp->status);
2450 1.1 pooka bytes_read = le16toh(nvm_resp->length);
2451 1.1 pooka offset_read = le16toh(nvm_resp->offset);
2452 1.1 pooka resp_data = nvm_resp->data;
2453 1.1 pooka if (ret) {
2454 1.2 nonaka DPRINTF(("%s: NVM access command failed with status %d\n",
2455 1.2 nonaka DEVNAME(sc), ret));
2456 1.1 pooka ret = EINVAL;
2457 1.1 pooka goto exit;
2458 1.1 pooka }
2459 1.1 pooka
2460 1.1 pooka if (offset_read != offset) {
2461 1.2 nonaka DPRINTF(("%s: NVM ACCESS response with invalid offset %d\n",
2462 1.2 nonaka DEVNAME(sc), offset_read));
2463 1.1 pooka ret = EINVAL;
2464 1.1 pooka goto exit;
2465 1.1 pooka }
2466 1.1 pooka
2467 1.1 pooka memcpy(data + offset, resp_data, bytes_read);
2468 1.1 pooka *len = bytes_read;
2469 1.1 pooka
2470 1.1 pooka exit:
2471 1.1 pooka iwm_free_resp(sc, &cmd);
2472 1.1 pooka return ret;
2473 1.1 pooka }
2474 1.1 pooka
2475 1.1 pooka /*
2476 1.1 pooka * Reads an NVM section completely.
2477 1.1 pooka * NICs prior to 7000 family doesn't have a real NVM, but just read
2478 1.1 pooka * section 0 which is the EEPROM. Because the EEPROM reading is unlimited
2479 1.1 pooka * by uCode, we need to manually check in this case that we don't
2480 1.1 pooka * overflow and try to read more than the EEPROM size.
2481 1.1 pooka * For 7000 family NICs, we supply the maximal size we can read, and
2482 1.1 pooka * the uCode fills the response with as much data as we can,
2483 1.1 pooka * without overflowing, so no check is needed.
2484 1.1 pooka */
2485 1.4 nonaka static int
2486 1.1 pooka iwm_nvm_read_section(struct iwm_softc *sc,
2487 1.1 pooka uint16_t section, uint8_t *data, uint16_t *len)
2488 1.1 pooka {
2489 1.1 pooka uint16_t length, seglen;
2490 1.1 pooka int error;
2491 1.1 pooka
2492 1.1 pooka /* Set nvm section read length */
2493 1.1 pooka length = seglen = IWM_NVM_DEFAULT_CHUNK_SIZE;
2494 1.1 pooka *len = 0;
2495 1.1 pooka
2496 1.1 pooka /* Read the NVM until exhausted (reading less than requested) */
2497 1.1 pooka while (seglen == length) {
2498 1.1 pooka error = iwm_nvm_read_chunk(sc,
2499 1.1 pooka section, *len, length, data, &seglen);
2500 1.1 pooka if (error) {
2501 1.3 nonaka aprint_error_dev(sc->sc_dev,
2502 1.3 nonaka "Cannot read NVM from section %d offset %d, "
2503 1.3 nonaka "length %d\n", section, *len, length);
2504 1.1 pooka return error;
2505 1.1 pooka }
2506 1.1 pooka *len += seglen;
2507 1.1 pooka }
2508 1.1 pooka
2509 1.1 pooka DPRINTFN(4, ("NVM section %d read completed\n", section));
2510 1.1 pooka return 0;
2511 1.1 pooka }
2512 1.1 pooka
2513 1.1 pooka /*
2514 1.1 pooka * BEGIN IWM_NVM_PARSE
2515 1.1 pooka */
2516 1.1 pooka
2517 1.1 pooka /* iwlwifi/iwl-nvm-parse.c */
2518 1.1 pooka
2519 1.1 pooka /* NVM offsets (in words) definitions */
2520 1.1 pooka enum wkp_nvm_offsets {
2521 1.1 pooka /* NVM HW-Section offset (in words) definitions */
2522 1.1 pooka IWM_HW_ADDR = 0x15,
2523 1.1 pooka
2524 1.1 pooka /* NVM SW-Section offset (in words) definitions */
2525 1.1 pooka IWM_NVM_SW_SECTION = 0x1C0,
2526 1.1 pooka IWM_NVM_VERSION = 0,
2527 1.1 pooka IWM_RADIO_CFG = 1,
2528 1.1 pooka IWM_SKU = 2,
2529 1.1 pooka IWM_N_HW_ADDRS = 3,
2530 1.1 pooka IWM_NVM_CHANNELS = 0x1E0 - IWM_NVM_SW_SECTION,
2531 1.1 pooka
2532 1.1 pooka /* NVM calibration section offset (in words) definitions */
2533 1.1 pooka IWM_NVM_CALIB_SECTION = 0x2B8,
2534 1.1 pooka IWM_XTAL_CALIB = 0x316 - IWM_NVM_CALIB_SECTION
2535 1.1 pooka };
2536 1.1 pooka
2537 1.1 pooka /* SKU Capabilities (actual values from NVM definition) */
2538 1.1 pooka enum nvm_sku_bits {
2539 1.1 pooka IWM_NVM_SKU_CAP_BAND_24GHZ = (1 << 0),
2540 1.1 pooka IWM_NVM_SKU_CAP_BAND_52GHZ = (1 << 1),
2541 1.1 pooka IWM_NVM_SKU_CAP_11N_ENABLE = (1 << 2),
2542 1.1 pooka IWM_NVM_SKU_CAP_11AC_ENABLE = (1 << 3),
2543 1.1 pooka };
2544 1.1 pooka
2545 1.1 pooka /* radio config bits (actual values from NVM definition) */
2546 1.1 pooka #define IWM_NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
2547 1.1 pooka #define IWM_NVM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */
2548 1.1 pooka #define IWM_NVM_RF_CFG_TYPE_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */
2549 1.1 pooka #define IWM_NVM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */
2550 1.1 pooka #define IWM_NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
2551 1.1 pooka #define IWM_NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
2552 1.1 pooka
2553 1.1 pooka #define DEFAULT_MAX_TX_POWER 16
2554 1.1 pooka
2555 1.1 pooka /**
2556 1.1 pooka * enum iwm_nvm_channel_flags - channel flags in NVM
2557 1.1 pooka * @IWM_NVM_CHANNEL_VALID: channel is usable for this SKU/geo
2558 1.1 pooka * @IWM_NVM_CHANNEL_IBSS: usable as an IBSS channel
2559 1.1 pooka * @IWM_NVM_CHANNEL_ACTIVE: active scanning allowed
2560 1.1 pooka * @IWM_NVM_CHANNEL_RADAR: radar detection required
2561 1.1 pooka * @IWM_NVM_CHANNEL_DFS: dynamic freq selection candidate
2562 1.1 pooka * @IWM_NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
2563 1.1 pooka * @IWM_NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
2564 1.1 pooka * @IWM_NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
2565 1.1 pooka * @IWM_NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
2566 1.1 pooka */
2567 1.1 pooka enum iwm_nvm_channel_flags {
2568 1.1 pooka IWM_NVM_CHANNEL_VALID = (1 << 0),
2569 1.1 pooka IWM_NVM_CHANNEL_IBSS = (1 << 1),
2570 1.1 pooka IWM_NVM_CHANNEL_ACTIVE = (1 << 3),
2571 1.1 pooka IWM_NVM_CHANNEL_RADAR = (1 << 4),
2572 1.1 pooka IWM_NVM_CHANNEL_DFS = (1 << 7),
2573 1.1 pooka IWM_NVM_CHANNEL_WIDE = (1 << 8),
2574 1.1 pooka IWM_NVM_CHANNEL_40MHZ = (1 << 9),
2575 1.1 pooka IWM_NVM_CHANNEL_80MHZ = (1 << 10),
2576 1.1 pooka IWM_NVM_CHANNEL_160MHZ = (1 << 11),
2577 1.1 pooka };
2578 1.1 pooka
2579 1.4 nonaka static void
2580 1.1 pooka iwm_init_channel_map(struct iwm_softc *sc, const uint16_t * const nvm_ch_flags)
2581 1.1 pooka {
2582 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
2583 1.1 pooka struct iwm_nvm_data *data = &sc->sc_nvm;
2584 1.1 pooka int ch_idx;
2585 1.1 pooka struct ieee80211_channel *channel;
2586 1.1 pooka uint16_t ch_flags;
2587 1.1 pooka int is_5ghz;
2588 1.1 pooka int flags, hw_value;
2589 1.1 pooka
2590 1.1 pooka for (ch_idx = 0; ch_idx < __arraycount(iwm_nvm_channels); ch_idx++) {
2591 1.1 pooka ch_flags = le16_to_cpup(nvm_ch_flags + ch_idx);
2592 1.1 pooka
2593 1.1 pooka if (ch_idx >= IWM_NUM_2GHZ_CHANNELS &&
2594 1.1 pooka !data->sku_cap_band_52GHz_enable)
2595 1.1 pooka ch_flags &= ~IWM_NVM_CHANNEL_VALID;
2596 1.1 pooka
2597 1.1 pooka if (!(ch_flags & IWM_NVM_CHANNEL_VALID)) {
2598 1.1 pooka DPRINTF(("Ch. %d Flags %x [%sGHz] - No traffic\n",
2599 1.1 pooka iwm_nvm_channels[ch_idx],
2600 1.1 pooka ch_flags,
2601 1.1 pooka (ch_idx >= IWM_NUM_2GHZ_CHANNELS) ?
2602 1.1 pooka "5.2" : "2.4"));
2603 1.1 pooka continue;
2604 1.1 pooka }
2605 1.1 pooka
2606 1.1 pooka hw_value = iwm_nvm_channels[ch_idx];
2607 1.1 pooka channel = &ic->ic_channels[hw_value];
2608 1.1 pooka
2609 1.1 pooka is_5ghz = ch_idx >= IWM_NUM_2GHZ_CHANNELS;
2610 1.1 pooka if (!is_5ghz) {
2611 1.1 pooka flags = IEEE80211_CHAN_2GHZ;
2612 1.1 pooka channel->ic_flags
2613 1.1 pooka = IEEE80211_CHAN_CCK
2614 1.1 pooka | IEEE80211_CHAN_OFDM
2615 1.1 pooka | IEEE80211_CHAN_DYN
2616 1.1 pooka | IEEE80211_CHAN_2GHZ;
2617 1.1 pooka } else {
2618 1.1 pooka flags = IEEE80211_CHAN_5GHZ;
2619 1.1 pooka channel->ic_flags =
2620 1.1 pooka IEEE80211_CHAN_A;
2621 1.1 pooka }
2622 1.1 pooka channel->ic_freq = ieee80211_ieee2mhz(hw_value, flags);
2623 1.1 pooka
2624 1.1 pooka if (!(ch_flags & IWM_NVM_CHANNEL_ACTIVE))
2625 1.1 pooka channel->ic_flags |= IEEE80211_CHAN_PASSIVE;
2626 1.1 pooka }
2627 1.1 pooka }
2628 1.1 pooka
2629 1.4 nonaka static int
2630 1.1 pooka iwm_parse_nvm_data(struct iwm_softc *sc,
2631 1.1 pooka const uint16_t *nvm_hw, const uint16_t *nvm_sw,
2632 1.1 pooka const uint16_t *nvm_calib, uint8_t tx_chains, uint8_t rx_chains)
2633 1.1 pooka {
2634 1.1 pooka struct iwm_nvm_data *data = &sc->sc_nvm;
2635 1.1 pooka uint8_t hw_addr[ETHER_ADDR_LEN];
2636 1.1 pooka uint16_t radio_cfg, sku;
2637 1.1 pooka
2638 1.1 pooka data->nvm_version = le16_to_cpup(nvm_sw + IWM_NVM_VERSION);
2639 1.1 pooka
2640 1.1 pooka radio_cfg = le16_to_cpup(nvm_sw + IWM_RADIO_CFG);
2641 1.1 pooka data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK(radio_cfg);
2642 1.1 pooka data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK(radio_cfg);
2643 1.1 pooka data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK(radio_cfg);
2644 1.1 pooka data->radio_cfg_pnum = IWM_NVM_RF_CFG_PNUM_MSK(radio_cfg);
2645 1.1 pooka data->valid_tx_ant = IWM_NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
2646 1.1 pooka data->valid_rx_ant = IWM_NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
2647 1.1 pooka
2648 1.1 pooka sku = le16_to_cpup(nvm_sw + IWM_SKU);
2649 1.1 pooka data->sku_cap_band_24GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_24GHZ;
2650 1.1 pooka data->sku_cap_band_52GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_52GHZ;
2651 1.1 pooka data->sku_cap_11n_enable = 0;
2652 1.1 pooka
2653 1.1 pooka if (!data->valid_tx_ant || !data->valid_rx_ant) {
2654 1.5 nonaka DPRINTF(("%s: invalid antennas (0x%x, 0x%x)\n", DEVNAME(sc),
2655 1.5 nonaka data->valid_tx_ant, data->valid_rx_ant));
2656 1.1 pooka return EINVAL;
2657 1.1 pooka }
2658 1.1 pooka
2659 1.1 pooka data->n_hw_addrs = le16_to_cpup(nvm_sw + IWM_N_HW_ADDRS);
2660 1.1 pooka
2661 1.1 pooka data->xtal_calib[0] = *(nvm_calib + IWM_XTAL_CALIB);
2662 1.1 pooka data->xtal_calib[1] = *(nvm_calib + IWM_XTAL_CALIB + 1);
2663 1.1 pooka
2664 1.1 pooka /* The byte order is little endian 16 bit, meaning 214365 */
2665 1.1 pooka memcpy(hw_addr, nvm_hw + IWM_HW_ADDR, ETHER_ADDR_LEN);
2666 1.1 pooka data->hw_addr[0] = hw_addr[1];
2667 1.1 pooka data->hw_addr[1] = hw_addr[0];
2668 1.1 pooka data->hw_addr[2] = hw_addr[3];
2669 1.1 pooka data->hw_addr[3] = hw_addr[2];
2670 1.1 pooka data->hw_addr[4] = hw_addr[5];
2671 1.1 pooka data->hw_addr[5] = hw_addr[4];
2672 1.1 pooka
2673 1.1 pooka iwm_init_channel_map(sc, &nvm_sw[IWM_NVM_CHANNELS]);
2674 1.1 pooka data->calib_version = 255; /* TODO:
2675 1.1 pooka this value will prevent some checks from
2676 1.1 pooka failing, we need to check if this
2677 1.1 pooka field is still needed, and if it does,
2678 1.1 pooka where is it in the NVM */
2679 1.1 pooka
2680 1.1 pooka return 0;
2681 1.1 pooka }
2682 1.1 pooka
2683 1.1 pooka /*
2684 1.1 pooka * END NVM PARSE
2685 1.1 pooka */
2686 1.1 pooka
2687 1.1 pooka struct iwm_nvm_section {
2688 1.8 nonaka uint16_t length;
2689 1.8 nonaka const uint8_t *data;
2690 1.1 pooka };
2691 1.1 pooka
2692 1.1 pooka #define IWM_FW_VALID_TX_ANT(sc) \
2693 1.1 pooka ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_TX_CHAIN) \
2694 1.1 pooka >> IWM_FW_PHY_CFG_TX_CHAIN_POS)
2695 1.1 pooka #define IWM_FW_VALID_RX_ANT(sc) \
2696 1.1 pooka ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RX_CHAIN) \
2697 1.1 pooka >> IWM_FW_PHY_CFG_RX_CHAIN_POS)
2698 1.1 pooka
2699 1.1 pooka static int
2700 1.1 pooka iwm_parse_nvm_sections(struct iwm_softc *sc, struct iwm_nvm_section *sections)
2701 1.1 pooka {
2702 1.1 pooka const uint16_t *hw, *sw, *calib;
2703 1.1 pooka
2704 1.1 pooka /* Checking for required sections */
2705 1.1 pooka if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
2706 1.1 pooka !sections[IWM_NVM_SECTION_TYPE_HW].data) {
2707 1.2 nonaka DPRINTF(("%s: Can't parse empty NVM sections\n", DEVNAME(sc)));
2708 1.1 pooka return ENOENT;
2709 1.1 pooka }
2710 1.1 pooka
2711 1.1 pooka hw = (const uint16_t *)sections[IWM_NVM_SECTION_TYPE_HW].data;
2712 1.1 pooka sw = (const uint16_t *)sections[IWM_NVM_SECTION_TYPE_SW].data;
2713 1.1 pooka calib = (const uint16_t *)sections[IWM_NVM_SECTION_TYPE_CALIBRATION].data;
2714 1.1 pooka return iwm_parse_nvm_data(sc, hw, sw, calib,
2715 1.1 pooka IWM_FW_VALID_TX_ANT(sc), IWM_FW_VALID_RX_ANT(sc));
2716 1.1 pooka }
2717 1.1 pooka
2718 1.4 nonaka static int
2719 1.1 pooka iwm_nvm_init(struct iwm_softc *sc)
2720 1.1 pooka {
2721 1.1 pooka struct iwm_nvm_section nvm_sections[IWM_NVM_NUM_OF_SECTIONS];
2722 1.1 pooka int i, section, error;
2723 1.1 pooka uint16_t len;
2724 1.1 pooka uint8_t *nvm_buffer, *temp;
2725 1.1 pooka
2726 1.1 pooka /* Read From FW NVM */
2727 1.1 pooka DPRINTF(("Read NVM\n"));
2728 1.1 pooka
2729 1.1 pooka /* TODO: find correct NVM max size for a section */
2730 1.1 pooka nvm_buffer = kmem_alloc(IWM_OTP_LOW_IMAGE_SIZE, KM_SLEEP);
2731 1.1 pooka for (i = 0; i < __arraycount(nvm_to_read); i++) {
2732 1.1 pooka section = nvm_to_read[i];
2733 1.1 pooka KASSERT(section <= __arraycount(nvm_sections));
2734 1.1 pooka
2735 1.1 pooka error = iwm_nvm_read_section(sc, section, nvm_buffer, &len);
2736 1.1 pooka if (error)
2737 1.1 pooka break;
2738 1.1 pooka
2739 1.1 pooka temp = kmem_alloc(len, KM_SLEEP);
2740 1.1 pooka memcpy(temp, nvm_buffer, len);
2741 1.1 pooka nvm_sections[section].data = temp;
2742 1.1 pooka nvm_sections[section].length = len;
2743 1.1 pooka }
2744 1.1 pooka kmem_free(nvm_buffer, IWM_OTP_LOW_IMAGE_SIZE);
2745 1.1 pooka if (error)
2746 1.1 pooka return error;
2747 1.1 pooka
2748 1.1 pooka return iwm_parse_nvm_sections(sc, nvm_sections);
2749 1.1 pooka }
2750 1.1 pooka
2751 1.1 pooka /*
2752 1.1 pooka * Firmware loading gunk. This is kind of a weird hybrid between the
2753 1.1 pooka * iwn driver and the Linux iwlwifi driver.
2754 1.1 pooka */
2755 1.1 pooka
2756 1.4 nonaka static int
2757 1.1 pooka iwm_firmware_load_chunk(struct iwm_softc *sc, uint32_t dst_addr,
2758 1.1 pooka const uint8_t *section, uint32_t byte_cnt)
2759 1.1 pooka {
2760 1.1 pooka struct iwm_dma_info *dma = &sc->fw_dma;
2761 1.1 pooka int error;
2762 1.1 pooka
2763 1.1 pooka /* Copy firmware section into pre-allocated DMA-safe memory. */
2764 1.1 pooka memcpy(dma->vaddr, section, byte_cnt);
2765 1.1 pooka bus_dmamap_sync(sc->sc_dmat,
2766 1.1 pooka dma->map, 0, byte_cnt, BUS_DMASYNC_PREWRITE);
2767 1.1 pooka
2768 1.1 pooka if (!iwm_nic_lock(sc))
2769 1.1 pooka return EBUSY;
2770 1.1 pooka
2771 1.1 pooka sc->sc_fw_chunk_done = 0;
2772 1.1 pooka
2773 1.1 pooka IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(IWM_FH_SRVC_CHNL),
2774 1.1 pooka IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
2775 1.1 pooka IWM_WRITE(sc, IWM_FH_SRVC_CHNL_SRAM_ADDR_REG(IWM_FH_SRVC_CHNL),
2776 1.1 pooka dst_addr);
2777 1.1 pooka IWM_WRITE(sc, IWM_FH_TFDIB_CTRL0_REG(IWM_FH_SRVC_CHNL),
2778 1.1 pooka dma->paddr & IWM_FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
2779 1.1 pooka IWM_WRITE(sc, IWM_FH_TFDIB_CTRL1_REG(IWM_FH_SRVC_CHNL),
2780 1.8 nonaka (iwm_get_dma_hi_addr(dma->paddr)
2781 1.1 pooka << IWM_FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
2782 1.1 pooka IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_BUF_STS_REG(IWM_FH_SRVC_CHNL),
2783 1.1 pooka 1 << IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
2784 1.1 pooka 1 << IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
2785 1.1 pooka IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
2786 1.1 pooka IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(IWM_FH_SRVC_CHNL),
2787 1.1 pooka IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
2788 1.1 pooka IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
2789 1.1 pooka IWM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
2790 1.8 nonaka
2791 1.1 pooka iwm_nic_unlock(sc);
2792 1.1 pooka
2793 1.1 pooka /* wait 1s for this segment to load */
2794 1.1 pooka while (!sc->sc_fw_chunk_done)
2795 1.1 pooka if ((error = tsleep(&sc->sc_fw, 0, "iwmfw", hz)) != 0)
2796 1.1 pooka break;
2797 1.1 pooka
2798 1.8 nonaka return error;
2799 1.1 pooka }
2800 1.1 pooka
2801 1.4 nonaka static int
2802 1.1 pooka iwm_load_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
2803 1.1 pooka {
2804 1.1 pooka struct iwm_fw_sects *fws;
2805 1.1 pooka int error, i, w;
2806 1.1 pooka void *data;
2807 1.1 pooka uint32_t dlen;
2808 1.1 pooka uint32_t offset;
2809 1.1 pooka
2810 1.1 pooka sc->sc_uc.uc_intr = 0;
2811 1.1 pooka
2812 1.1 pooka fws = &sc->sc_fw.fw_sects[ucode_type];
2813 1.1 pooka for (i = 0; i < fws->fw_count; i++) {
2814 1.1 pooka data = fws->fw_sect[i].fws_data;
2815 1.1 pooka dlen = fws->fw_sect[i].fws_len;
2816 1.1 pooka offset = fws->fw_sect[i].fws_devoff;
2817 1.1 pooka DPRINTF(("LOAD FIRMWARE type %d offset %u len %d\n",
2818 1.1 pooka ucode_type, offset, dlen));
2819 1.1 pooka error = iwm_firmware_load_chunk(sc, offset, data, dlen);
2820 1.1 pooka if (error) {
2821 1.5 nonaka DPRINTF(("iwm_firmware_load_chunk() chunk %u of %u "
2822 1.5 nonaka "returned error %02d\n", i, fws->fw_count, error));
2823 1.1 pooka return error;
2824 1.1 pooka }
2825 1.1 pooka }
2826 1.1 pooka
2827 1.1 pooka /* wait for the firmware to load */
2828 1.1 pooka IWM_WRITE(sc, IWM_CSR_RESET, 0);
2829 1.1 pooka
2830 1.1 pooka for (w = 0; !sc->sc_uc.uc_intr && w < 10; w++) {
2831 1.1 pooka error = tsleep(&sc->sc_uc, 0, "iwmuc", hz/10);
2832 1.1 pooka }
2833 1.1 pooka
2834 1.1 pooka return error;
2835 1.1 pooka }
2836 1.1 pooka
2837 1.1 pooka /* iwlwifi: pcie/trans.c */
2838 1.4 nonaka static int
2839 1.1 pooka iwm_start_fw(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
2840 1.1 pooka {
2841 1.1 pooka int error;
2842 1.1 pooka
2843 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT, ~0);
2844 1.1 pooka
2845 1.1 pooka if ((error = iwm_nic_init(sc)) != 0) {
2846 1.3 nonaka aprint_error_dev(sc->sc_dev, "Unable to init nic\n");
2847 1.1 pooka return error;
2848 1.1 pooka }
2849 1.1 pooka
2850 1.1 pooka /* make sure rfkill handshake bits are cleared */
2851 1.1 pooka IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
2852 1.1 pooka IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR,
2853 1.1 pooka IWM_CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
2854 1.1 pooka
2855 1.1 pooka /* clear (again), then enable host interrupts */
2856 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT, ~0);
2857 1.1 pooka iwm_enable_interrupts(sc);
2858 1.1 pooka
2859 1.1 pooka /* really make sure rfkill handshake bits are cleared */
2860 1.1 pooka /* maybe we should write a few times more? just to make sure */
2861 1.1 pooka IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
2862 1.1 pooka IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
2863 1.1 pooka
2864 1.1 pooka /* Load the given image to the HW */
2865 1.6 nonaka error = iwm_load_firmware(sc, ucode_type);
2866 1.6 nonaka if (error) {
2867 1.6 nonaka aprint_error_dev(sc->sc_dev, "failed to load firmware: %d\n",
2868 1.6 nonaka error);
2869 1.6 nonaka }
2870 1.6 nonaka return error;
2871 1.1 pooka }
2872 1.1 pooka
2873 1.4 nonaka static int
2874 1.1 pooka iwm_fw_alive(struct iwm_softc *sc, uint32_t sched_base)
2875 1.1 pooka {
2876 1.1 pooka return iwm_post_alive(sc);
2877 1.1 pooka }
2878 1.1 pooka
2879 1.4 nonaka static int
2880 1.1 pooka iwm_send_tx_ant_cfg(struct iwm_softc *sc, uint8_t valid_tx_ant)
2881 1.1 pooka {
2882 1.1 pooka struct iwm_tx_ant_cfg_cmd tx_ant_cmd = {
2883 1.1 pooka .valid = htole32(valid_tx_ant),
2884 1.1 pooka };
2885 1.1 pooka
2886 1.1 pooka return iwm_mvm_send_cmd_pdu(sc, IWM_TX_ANT_CONFIGURATION_CMD,
2887 1.1 pooka IWM_CMD_SYNC, sizeof(tx_ant_cmd), &tx_ant_cmd);
2888 1.1 pooka }
2889 1.1 pooka
2890 1.1 pooka /* iwlwifi: mvm/fw.c */
2891 1.4 nonaka static int
2892 1.1 pooka iwm_send_phy_cfg_cmd(struct iwm_softc *sc)
2893 1.1 pooka {
2894 1.1 pooka struct iwm_phy_cfg_cmd phy_cfg_cmd;
2895 1.1 pooka enum iwm_ucode_type ucode_type = sc->sc_uc_current;
2896 1.1 pooka
2897 1.1 pooka /* Set parameters */
2898 1.1 pooka phy_cfg_cmd.phy_cfg = htole32(sc->sc_fw_phy_config);
2899 1.1 pooka phy_cfg_cmd.calib_control.event_trigger =
2900 1.1 pooka sc->sc_default_calib[ucode_type].event_trigger;
2901 1.1 pooka phy_cfg_cmd.calib_control.flow_trigger =
2902 1.1 pooka sc->sc_default_calib[ucode_type].flow_trigger;
2903 1.1 pooka
2904 1.1 pooka DPRINTFN(10, ("Sending Phy CFG command: 0x%x\n", phy_cfg_cmd.phy_cfg));
2905 1.1 pooka return iwm_mvm_send_cmd_pdu(sc, IWM_PHY_CONFIGURATION_CMD, IWM_CMD_SYNC,
2906 1.1 pooka sizeof(phy_cfg_cmd), &phy_cfg_cmd);
2907 1.1 pooka }
2908 1.1 pooka
2909 1.4 nonaka static int
2910 1.1 pooka iwm_mvm_load_ucode_wait_alive(struct iwm_softc *sc,
2911 1.1 pooka enum iwm_ucode_type ucode_type)
2912 1.1 pooka {
2913 1.1 pooka enum iwm_ucode_type old_type = sc->sc_uc_current;
2914 1.1 pooka int error;
2915 1.1 pooka
2916 1.1 pooka if ((error = iwm_read_firmware(sc)) != 0)
2917 1.1 pooka return error;
2918 1.1 pooka
2919 1.1 pooka sc->sc_uc_current = ucode_type;
2920 1.8 nonaka error = iwm_start_fw(sc, ucode_type);
2921 1.1 pooka if (error) {
2922 1.1 pooka sc->sc_uc_current = old_type;
2923 1.1 pooka return error;
2924 1.1 pooka }
2925 1.1 pooka
2926 1.1 pooka return iwm_fw_alive(sc, sc->sched_base);
2927 1.1 pooka }
2928 1.1 pooka
2929 1.1 pooka /*
2930 1.1 pooka * mvm misc bits
2931 1.1 pooka */
2932 1.1 pooka
2933 1.1 pooka /*
2934 1.1 pooka * follows iwlwifi/fw.c
2935 1.1 pooka */
2936 1.4 nonaka static int
2937 1.1 pooka iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
2938 1.1 pooka {
2939 1.1 pooka int error;
2940 1.1 pooka
2941 1.1 pooka /* do not operate with rfkill switch turned on */
2942 1.1 pooka if ((sc->sc_flags & IWM_FLAG_RFKILL) && !justnvm) {
2943 1.3 nonaka aprint_error_dev(sc->sc_dev,
2944 1.3 nonaka "radio is disabled by hardware switch\n");
2945 1.1 pooka return EPERM;
2946 1.1 pooka }
2947 1.1 pooka
2948 1.1 pooka sc->sc_init_complete = 0;
2949 1.8 nonaka if ((error = iwm_mvm_load_ucode_wait_alive(sc,
2950 1.1 pooka IWM_UCODE_TYPE_INIT)) != 0)
2951 1.1 pooka return error;
2952 1.1 pooka
2953 1.1 pooka if (justnvm) {
2954 1.1 pooka if ((error = iwm_nvm_init(sc)) != 0) {
2955 1.3 nonaka aprint_error_dev(sc->sc_dev, "failed to read nvm\n");
2956 1.1 pooka return error;
2957 1.1 pooka }
2958 1.1 pooka memcpy(&sc->sc_ic.ic_myaddr,
2959 1.1 pooka &sc->sc_nvm.hw_addr, ETHER_ADDR_LEN);
2960 1.1 pooka
2961 1.1 pooka sc->sc_scan_cmd_len = sizeof(struct iwm_scan_cmd)
2962 1.1 pooka + sc->sc_capa_max_probe_len
2963 1.1 pooka + IWM_MAX_NUM_SCAN_CHANNELS
2964 1.1 pooka * sizeof(struct iwm_scan_channel);
2965 1.1 pooka sc->sc_scan_cmd = kmem_alloc(sc->sc_scan_cmd_len, KM_SLEEP);
2966 1.1 pooka
2967 1.1 pooka return 0;
2968 1.1 pooka }
2969 1.1 pooka
2970 1.1 pooka /* Send TX valid antennas before triggering calibrations */
2971 1.1 pooka if ((error = iwm_send_tx_ant_cfg(sc, IWM_FW_VALID_TX_ANT(sc))) != 0)
2972 1.1 pooka return error;
2973 1.1 pooka
2974 1.1 pooka /*
2975 1.1 pooka * Send phy configurations command to init uCode
2976 1.1 pooka * to start the 16.0 uCode init image internal calibrations.
2977 1.1 pooka */
2978 1.1 pooka if ((error = iwm_send_phy_cfg_cmd(sc)) != 0 ) {
2979 1.2 nonaka DPRINTF(("%s: failed to run internal calibration: %d\n",
2980 1.2 nonaka DEVNAME(sc), error));
2981 1.1 pooka return error;
2982 1.1 pooka }
2983 1.1 pooka
2984 1.1 pooka /*
2985 1.1 pooka * Nothing to do but wait for the init complete notification
2986 1.1 pooka * from the firmware
2987 1.1 pooka */
2988 1.1 pooka while (!sc->sc_init_complete)
2989 1.1 pooka if ((error = tsleep(&sc->sc_init_complete,
2990 1.1 pooka 0, "iwminit", 2*hz)) != 0)
2991 1.1 pooka break;
2992 1.1 pooka
2993 1.1 pooka return error;
2994 1.1 pooka }
2995 1.1 pooka
2996 1.1 pooka /*
2997 1.1 pooka * receive side
2998 1.1 pooka */
2999 1.1 pooka
3000 1.1 pooka /* (re)stock rx ring, called at init-time and at runtime */
3001 1.4 nonaka static int
3002 1.1 pooka iwm_rx_addbuf(struct iwm_softc *sc, int size, int idx)
3003 1.1 pooka {
3004 1.1 pooka struct iwm_rx_ring *ring = &sc->rxq;
3005 1.1 pooka struct iwm_rx_data *data = &ring->data[idx];
3006 1.1 pooka struct mbuf *m;
3007 1.1 pooka int error;
3008 1.1 pooka int fatal = 0;
3009 1.1 pooka
3010 1.1 pooka m = m_gethdr(M_DONTWAIT, MT_DATA);
3011 1.1 pooka if (m == NULL)
3012 1.1 pooka return ENOBUFS;
3013 1.1 pooka
3014 1.1 pooka if (size <= MCLBYTES) {
3015 1.1 pooka MCLGET(m, M_DONTWAIT);
3016 1.1 pooka } else {
3017 1.1 pooka MEXTMALLOC(m, IWM_RBUF_SIZE, M_DONTWAIT);
3018 1.1 pooka }
3019 1.1 pooka if ((m->m_flags & M_EXT) == 0) {
3020 1.1 pooka m_freem(m);
3021 1.1 pooka return ENOBUFS;
3022 1.1 pooka }
3023 1.1 pooka
3024 1.1 pooka if (data->m != NULL) {
3025 1.1 pooka bus_dmamap_unload(sc->sc_dmat, data->map);
3026 1.1 pooka fatal = 1;
3027 1.1 pooka }
3028 1.1 pooka
3029 1.1 pooka m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
3030 1.1 pooka if ((error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
3031 1.1 pooka BUS_DMA_READ|BUS_DMA_NOWAIT)) != 0) {
3032 1.1 pooka /* XXX */
3033 1.1 pooka if (fatal)
3034 1.1 pooka panic("iwm: could not load RX mbuf");
3035 1.1 pooka m_freem(m);
3036 1.1 pooka return error;
3037 1.1 pooka }
3038 1.1 pooka data->m = m;
3039 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0, size, BUS_DMASYNC_PREREAD);
3040 1.1 pooka
3041 1.8 nonaka /* Update RX descriptor. */
3042 1.1 pooka ring->desc[idx] = htole32(data->map->dm_segs[0].ds_addr >> 8);
3043 1.1 pooka bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
3044 1.1 pooka idx * sizeof(uint32_t), sizeof(uint32_t), BUS_DMASYNC_PREWRITE);
3045 1.1 pooka
3046 1.1 pooka return 0;
3047 1.1 pooka }
3048 1.1 pooka
3049 1.1 pooka /* iwlwifi: mvm/rx.c */
3050 1.1 pooka #define IWM_RSSI_OFFSET 50
3051 1.4 nonaka static int
3052 1.1 pooka iwm_mvm_calc_rssi(struct iwm_softc *sc, struct iwm_rx_phy_info *phy_info)
3053 1.1 pooka {
3054 1.1 pooka int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
3055 1.1 pooka uint32_t agc_a, agc_b;
3056 1.1 pooka uint32_t val;
3057 1.1 pooka
3058 1.1 pooka val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_AGC_IDX]);
3059 1.1 pooka agc_a = (val & IWM_OFDM_AGC_A_MSK) >> IWM_OFDM_AGC_A_POS;
3060 1.1 pooka agc_b = (val & IWM_OFDM_AGC_B_MSK) >> IWM_OFDM_AGC_B_POS;
3061 1.1 pooka
3062 1.1 pooka val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_RSSI_AB_IDX]);
3063 1.1 pooka rssi_a = (val & IWM_OFDM_RSSI_INBAND_A_MSK) >> IWM_OFDM_RSSI_A_POS;
3064 1.1 pooka rssi_b = (val & IWM_OFDM_RSSI_INBAND_B_MSK) >> IWM_OFDM_RSSI_B_POS;
3065 1.1 pooka
3066 1.1 pooka /*
3067 1.1 pooka * dBm = rssi dB - agc dB - constant.
3068 1.1 pooka * Higher AGC (higher radio gain) means lower signal.
3069 1.1 pooka */
3070 1.1 pooka rssi_a_dbm = rssi_a - IWM_RSSI_OFFSET - agc_a;
3071 1.1 pooka rssi_b_dbm = rssi_b - IWM_RSSI_OFFSET - agc_b;
3072 1.1 pooka max_rssi_dbm = MAX(rssi_a_dbm, rssi_b_dbm);
3073 1.1 pooka
3074 1.1 pooka DPRINTF(("Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
3075 1.1 pooka rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b));
3076 1.1 pooka
3077 1.1 pooka return max_rssi_dbm;
3078 1.1 pooka }
3079 1.1 pooka
3080 1.1 pooka /* iwlwifi: mvm/rx.c */
3081 1.1 pooka /*
3082 1.1 pooka * iwm_mvm_get_signal_strength - use new rx PHY INFO API
3083 1.1 pooka * values are reported by the fw as positive values - need to negate
3084 1.1 pooka * to obtain their dBM. Account for missing antennas by replacing 0
3085 1.1 pooka * values by -256dBm: practically 0 power and a non-feasible 8 bit value.
3086 1.1 pooka */
3087 1.4 nonaka static int
3088 1.5 nonaka iwm_mvm_get_signal_strength(struct iwm_softc *sc,
3089 1.5 nonaka struct iwm_rx_phy_info *phy_info)
3090 1.1 pooka {
3091 1.1 pooka int energy_a, energy_b, energy_c, max_energy;
3092 1.1 pooka uint32_t val;
3093 1.1 pooka
3094 1.1 pooka val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_ENERGY_ANT_ABC_IDX]);
3095 1.1 pooka energy_a = (val & IWM_RX_INFO_ENERGY_ANT_A_MSK) >>
3096 1.1 pooka IWM_RX_INFO_ENERGY_ANT_A_POS;
3097 1.1 pooka energy_a = energy_a ? -energy_a : -256;
3098 1.1 pooka energy_b = (val & IWM_RX_INFO_ENERGY_ANT_B_MSK) >>
3099 1.1 pooka IWM_RX_INFO_ENERGY_ANT_B_POS;
3100 1.1 pooka energy_b = energy_b ? -energy_b : -256;
3101 1.1 pooka energy_c = (val & IWM_RX_INFO_ENERGY_ANT_C_MSK) >>
3102 1.1 pooka IWM_RX_INFO_ENERGY_ANT_C_POS;
3103 1.1 pooka energy_c = energy_c ? -energy_c : -256;
3104 1.1 pooka max_energy = MAX(energy_a, energy_b);
3105 1.1 pooka max_energy = MAX(max_energy, energy_c);
3106 1.1 pooka
3107 1.5 nonaka DPRINTFN(12, ("energy In A %d B %d C %d, and max %d\n",
3108 1.1 pooka energy_a, energy_b, energy_c, max_energy));
3109 1.1 pooka
3110 1.1 pooka return max_energy;
3111 1.1 pooka }
3112 1.1 pooka
3113 1.4 nonaka static void
3114 1.1 pooka iwm_mvm_rx_rx_phy_cmd(struct iwm_softc *sc,
3115 1.1 pooka struct iwm_rx_packet *pkt, struct iwm_rx_data *data)
3116 1.1 pooka {
3117 1.1 pooka struct iwm_rx_phy_info *phy_info = (void *)pkt->data;
3118 1.1 pooka
3119 1.1 pooka DPRINTFN(20, ("received PHY stats\n"));
3120 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*pkt),
3121 1.1 pooka sizeof(*phy_info), BUS_DMASYNC_POSTREAD);
3122 1.1 pooka
3123 1.1 pooka memcpy(&sc->sc_last_phy_info, phy_info, sizeof(sc->sc_last_phy_info));
3124 1.1 pooka }
3125 1.1 pooka
3126 1.1 pooka /*
3127 1.1 pooka * Retrieve the average noise (in dBm) among receivers.
3128 1.1 pooka */
3129 1.4 nonaka static int
3130 1.1 pooka iwm_get_noise(const struct iwm_mvm_statistics_rx_non_phy *stats)
3131 1.1 pooka {
3132 1.1 pooka int i, total, nbant, noise;
3133 1.1 pooka
3134 1.1 pooka total = nbant = noise = 0;
3135 1.1 pooka for (i = 0; i < 3; i++) {
3136 1.1 pooka noise = le32toh(stats->beacon_silence_rssi[i]) & 0xff;
3137 1.1 pooka if (noise) {
3138 1.1 pooka total += noise;
3139 1.1 pooka nbant++;
3140 1.1 pooka }
3141 1.1 pooka }
3142 1.1 pooka
3143 1.1 pooka /* There should be at least one antenna but check anyway. */
3144 1.1 pooka return (nbant == 0) ? -127 : (total / nbant) - 107;
3145 1.1 pooka }
3146 1.1 pooka
3147 1.1 pooka /*
3148 1.1 pooka * iwm_mvm_rx_rx_mpdu - IWM_REPLY_RX_MPDU_CMD handler
3149 1.1 pooka *
3150 1.1 pooka * Handles the actual data of the Rx packet from the fw
3151 1.1 pooka */
3152 1.4 nonaka static void
3153 1.1 pooka iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc,
3154 1.1 pooka struct iwm_rx_packet *pkt, struct iwm_rx_data *data)
3155 1.1 pooka {
3156 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
3157 1.1 pooka struct ieee80211_frame *wh;
3158 1.1 pooka struct ieee80211_node *ni;
3159 1.1 pooka struct ieee80211_channel *c = NULL;
3160 1.1 pooka struct mbuf *m;
3161 1.1 pooka struct iwm_rx_phy_info *phy_info;
3162 1.1 pooka struct iwm_rx_mpdu_res_start *rx_res;
3163 1.1 pooka int device_timestamp;
3164 1.1 pooka uint32_t len;
3165 1.1 pooka uint32_t rx_pkt_status;
3166 1.1 pooka int rssi;
3167 1.1 pooka
3168 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE,
3169 1.1 pooka BUS_DMASYNC_POSTREAD);
3170 1.1 pooka
3171 1.1 pooka phy_info = &sc->sc_last_phy_info;
3172 1.1 pooka rx_res = (struct iwm_rx_mpdu_res_start *)pkt->data;
3173 1.1 pooka wh = (struct ieee80211_frame *)(pkt->data + sizeof(*rx_res));
3174 1.1 pooka len = le16toh(rx_res->byte_count);
3175 1.1 pooka rx_pkt_status = le32toh(*(uint32_t *)(pkt->data + sizeof(*rx_res) + len));
3176 1.1 pooka
3177 1.1 pooka m = data->m;
3178 1.1 pooka m->m_data = pkt->data + sizeof(*rx_res);
3179 1.1 pooka m->m_pkthdr.len = m->m_len = len;
3180 1.1 pooka
3181 1.1 pooka if (__predict_false(phy_info->cfg_phy_cnt > 20)) {
3182 1.1 pooka DPRINTF(("dsp size out of range [0,20]: %d\n",
3183 1.1 pooka phy_info->cfg_phy_cnt));
3184 1.1 pooka return;
3185 1.1 pooka }
3186 1.1 pooka
3187 1.1 pooka if (!(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_CRC_OK) ||
3188 1.1 pooka !(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_OVERRUN_OK)) {
3189 1.1 pooka DPRINTF(("Bad CRC or FIFO: 0x%08X.\n", rx_pkt_status));
3190 1.1 pooka return; /* drop */
3191 1.1 pooka }
3192 1.1 pooka
3193 1.1 pooka device_timestamp = le32toh(phy_info->system_timestamp);
3194 1.1 pooka
3195 1.1 pooka if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_RX_ENERGY_API) {
3196 1.1 pooka rssi = iwm_mvm_get_signal_strength(sc, phy_info);
3197 1.1 pooka } else {
3198 1.1 pooka rssi = iwm_mvm_calc_rssi(sc, phy_info);
3199 1.1 pooka }
3200 1.1 pooka rssi = -rssi;
3201 1.1 pooka
3202 1.1 pooka if (ic->ic_state == IEEE80211_S_SCAN)
3203 1.1 pooka iwm_fix_channel(ic, m);
3204 1.1 pooka
3205 1.1 pooka /* replenish ring for the buffer we're going to feed to the sharks */
3206 1.1 pooka if (iwm_rx_addbuf(sc, IWM_RBUF_SIZE, sc->rxq.cur) != 0)
3207 1.1 pooka return;
3208 1.1 pooka
3209 1.42 ozaki m_set_rcvif(m, IC2IFP(ic));
3210 1.1 pooka
3211 1.1 pooka if (sc->sc_scanband == IEEE80211_CHAN_5GHZ) {
3212 1.1 pooka if (le32toh(phy_info->channel) < __arraycount(ic->ic_channels))
3213 1.1 pooka c = &ic->ic_channels[le32toh(phy_info->channel)];
3214 1.1 pooka }
3215 1.1 pooka
3216 1.1 pooka ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
3217 1.1 pooka if (c)
3218 1.1 pooka ni->ni_chan = c;
3219 1.1 pooka
3220 1.1 pooka if (sc->sc_drvbpf != NULL) {
3221 1.1 pooka struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap;
3222 1.1 pooka
3223 1.1 pooka tap->wr_flags = 0;
3224 1.1 pooka if (phy_info->phy_flags & htole16(IWM_PHY_INFO_FLAG_SHPREAMBLE))
3225 1.1 pooka tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
3226 1.1 pooka tap->wr_chan_freq =
3227 1.1 pooka htole16(ic->ic_channels[phy_info->channel].ic_freq);
3228 1.1 pooka tap->wr_chan_flags =
3229 1.1 pooka htole16(ic->ic_channels[phy_info->channel].ic_flags);
3230 1.1 pooka tap->wr_dbm_antsignal = (int8_t)rssi;
3231 1.1 pooka tap->wr_dbm_antnoise = (int8_t)sc->sc_noise;
3232 1.1 pooka tap->wr_tsft = phy_info->system_timestamp;
3233 1.1 pooka switch (phy_info->rate) {
3234 1.1 pooka /* CCK rates. */
3235 1.1 pooka case 10: tap->wr_rate = 2; break;
3236 1.1 pooka case 20: tap->wr_rate = 4; break;
3237 1.1 pooka case 55: tap->wr_rate = 11; break;
3238 1.1 pooka case 110: tap->wr_rate = 22; break;
3239 1.1 pooka /* OFDM rates. */
3240 1.1 pooka case 0xd: tap->wr_rate = 12; break;
3241 1.1 pooka case 0xf: tap->wr_rate = 18; break;
3242 1.1 pooka case 0x5: tap->wr_rate = 24; break;
3243 1.1 pooka case 0x7: tap->wr_rate = 36; break;
3244 1.1 pooka case 0x9: tap->wr_rate = 48; break;
3245 1.1 pooka case 0xb: tap->wr_rate = 72; break;
3246 1.1 pooka case 0x1: tap->wr_rate = 96; break;
3247 1.1 pooka case 0x3: tap->wr_rate = 108; break;
3248 1.1 pooka /* Unknown rate: should not happen. */
3249 1.1 pooka default: tap->wr_rate = 0;
3250 1.1 pooka }
3251 1.1 pooka
3252 1.1 pooka bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
3253 1.1 pooka }
3254 1.1 pooka ieee80211_input(ic, m, ni, rssi, device_timestamp);
3255 1.1 pooka ieee80211_free_node(ni);
3256 1.1 pooka }
3257 1.1 pooka
3258 1.4 nonaka static void
3259 1.1 pooka iwm_mvm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
3260 1.1 pooka struct iwm_node *in)
3261 1.1 pooka {
3262 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
3263 1.1 pooka struct ifnet *ifp = IC2IFP(ic);
3264 1.1 pooka struct iwm_mvm_tx_resp *tx_resp = (void *)pkt->data;
3265 1.1 pooka int status = le16toh(tx_resp->status.status) & IWM_TX_STATUS_MSK;
3266 1.1 pooka int failack = tx_resp->failure_frame;
3267 1.1 pooka
3268 1.1 pooka KASSERT(tx_resp->frame_count == 1);
3269 1.1 pooka
3270 1.1 pooka /* Update rate control statistics. */
3271 1.1 pooka in->in_amn.amn_txcnt++;
3272 1.1 pooka if (failack > 0) {
3273 1.1 pooka in->in_amn.amn_retrycnt++;
3274 1.1 pooka }
3275 1.1 pooka
3276 1.1 pooka if (status != IWM_TX_STATUS_SUCCESS &&
3277 1.1 pooka status != IWM_TX_STATUS_DIRECT_DONE)
3278 1.1 pooka ifp->if_oerrors++;
3279 1.1 pooka else
3280 1.1 pooka ifp->if_opackets++;
3281 1.1 pooka }
3282 1.1 pooka
3283 1.4 nonaka static void
3284 1.8 nonaka iwm_mvm_rx_tx_cmd(struct iwm_softc *sc,
3285 1.1 pooka struct iwm_rx_packet *pkt, struct iwm_rx_data *data)
3286 1.1 pooka {
3287 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
3288 1.1 pooka struct ifnet *ifp = IC2IFP(ic);
3289 1.1 pooka struct iwm_cmd_header *cmd_hdr = &pkt->hdr;
3290 1.1 pooka int idx = cmd_hdr->idx;
3291 1.1 pooka int qid = cmd_hdr->qid;
3292 1.1 pooka struct iwm_tx_ring *ring = &sc->txq[qid];
3293 1.1 pooka struct iwm_tx_data *txd = &ring->data[idx];
3294 1.1 pooka struct iwm_node *in = txd->in;
3295 1.1 pooka
3296 1.1 pooka if (txd->done) {
3297 1.2 nonaka DPRINTF(("%s: got tx interrupt that's already been handled!\n",
3298 1.2 nonaka DEVNAME(sc)));
3299 1.1 pooka return;
3300 1.1 pooka }
3301 1.1 pooka
3302 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE,
3303 1.1 pooka BUS_DMASYNC_POSTREAD);
3304 1.1 pooka
3305 1.1 pooka sc->sc_tx_timer = 0;
3306 1.1 pooka
3307 1.1 pooka iwm_mvm_rx_tx_cmd_single(sc, pkt, in);
3308 1.1 pooka
3309 1.1 pooka /* Unmap and free mbuf. */
3310 1.1 pooka bus_dmamap_sync(sc->sc_dmat, txd->map, 0, txd->map->dm_mapsize,
3311 1.1 pooka BUS_DMASYNC_POSTWRITE);
3312 1.1 pooka bus_dmamap_unload(sc->sc_dmat, txd->map);
3313 1.1 pooka m_freem(txd->m);
3314 1.1 pooka
3315 1.1 pooka DPRINTFN(8, ("free txd %p, in %p\n", txd, txd->in));
3316 1.1 pooka KASSERT(txd->done == 0);
3317 1.1 pooka txd->done = 1;
3318 1.1 pooka KASSERT(txd->in);
3319 1.1 pooka
3320 1.1 pooka txd->m = NULL;
3321 1.1 pooka txd->in = NULL;
3322 1.1 pooka ieee80211_free_node(&in->in_ni);
3323 1.1 pooka
3324 1.1 pooka if (--ring->queued < IWM_TX_RING_LOMARK) {
3325 1.1 pooka sc->qfullmsk &= ~(1 << ring->qid);
3326 1.1 pooka if (sc->qfullmsk == 0 && (ifp->if_flags & IFF_OACTIVE)) {
3327 1.1 pooka ifp->if_flags &= ~IFF_OACTIVE;
3328 1.1 pooka /*
3329 1.1 pooka * Well, we're in interrupt context, but then again
3330 1.1 pooka * I guess net80211 does all sorts of stunts in
3331 1.1 pooka * interrupt context, so maybe this is no biggie.
3332 1.1 pooka */
3333 1.1 pooka (*ifp->if_start)(ifp);
3334 1.1 pooka }
3335 1.1 pooka }
3336 1.1 pooka }
3337 1.1 pooka
3338 1.1 pooka /*
3339 1.1 pooka * BEGIN iwlwifi/mvm/binding.c
3340 1.1 pooka */
3341 1.1 pooka
3342 1.4 nonaka static int
3343 1.1 pooka iwm_mvm_binding_cmd(struct iwm_softc *sc, struct iwm_node *in, uint32_t action)
3344 1.1 pooka {
3345 1.1 pooka struct iwm_binding_cmd cmd;
3346 1.1 pooka struct iwm_mvm_phy_ctxt *phyctxt = in->in_phyctxt;
3347 1.1 pooka int i, ret;
3348 1.1 pooka uint32_t status;
3349 1.1 pooka
3350 1.1 pooka memset(&cmd, 0, sizeof(cmd));
3351 1.1 pooka
3352 1.1 pooka cmd.id_and_color
3353 1.1 pooka = htole32(IWM_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
3354 1.1 pooka cmd.action = htole32(action);
3355 1.1 pooka cmd.phy = htole32(IWM_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
3356 1.1 pooka
3357 1.1 pooka cmd.macs[0] = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
3358 1.1 pooka for (i = 1; i < IWM_MAX_MACS_IN_BINDING; i++)
3359 1.1 pooka cmd.macs[i] = htole32(IWM_FW_CTXT_INVALID);
3360 1.1 pooka
3361 1.1 pooka status = 0;
3362 1.1 pooka ret = iwm_mvm_send_cmd_pdu_status(sc, IWM_BINDING_CONTEXT_CMD,
3363 1.1 pooka sizeof(cmd), &cmd, &status);
3364 1.1 pooka if (ret) {
3365 1.2 nonaka DPRINTF(("%s: Failed to send binding (action:%d): %d\n",
3366 1.2 nonaka DEVNAME(sc), action, ret));
3367 1.1 pooka return ret;
3368 1.1 pooka }
3369 1.1 pooka
3370 1.1 pooka if (status) {
3371 1.2 nonaka DPRINTF(("%s: Binding command failed: %u\n", DEVNAME(sc),
3372 1.2 nonaka status));
3373 1.1 pooka ret = EIO;
3374 1.1 pooka }
3375 1.1 pooka
3376 1.1 pooka return ret;
3377 1.1 pooka }
3378 1.1 pooka
3379 1.4 nonaka static int
3380 1.1 pooka iwm_mvm_binding_update(struct iwm_softc *sc, struct iwm_node *in, int add)
3381 1.1 pooka {
3382 1.1 pooka return iwm_mvm_binding_cmd(sc, in, IWM_FW_CTXT_ACTION_ADD);
3383 1.1 pooka }
3384 1.1 pooka
3385 1.4 nonaka static int
3386 1.1 pooka iwm_mvm_binding_add_vif(struct iwm_softc *sc, struct iwm_node *in)
3387 1.1 pooka {
3388 1.1 pooka return iwm_mvm_binding_update(sc, in, IWM_FW_CTXT_ACTION_ADD);
3389 1.1 pooka }
3390 1.1 pooka
3391 1.1 pooka /*
3392 1.1 pooka * END iwlwifi/mvm/binding.c
3393 1.1 pooka */
3394 1.1 pooka
3395 1.1 pooka /*
3396 1.1 pooka * BEGIN iwlwifi/mvm/phy-ctxt.c
3397 1.1 pooka */
3398 1.1 pooka
3399 1.1 pooka /*
3400 1.1 pooka * Construct the generic fields of the PHY context command
3401 1.1 pooka */
3402 1.4 nonaka static void
3403 1.1 pooka iwm_mvm_phy_ctxt_cmd_hdr(struct iwm_softc *sc, struct iwm_mvm_phy_ctxt *ctxt,
3404 1.1 pooka struct iwm_phy_context_cmd *cmd, uint32_t action, uint32_t apply_time)
3405 1.1 pooka {
3406 1.1 pooka memset(cmd, 0, sizeof(struct iwm_phy_context_cmd));
3407 1.1 pooka
3408 1.1 pooka cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ctxt->id,
3409 1.1 pooka ctxt->color));
3410 1.1 pooka cmd->action = htole32(action);
3411 1.1 pooka cmd->apply_time = htole32(apply_time);
3412 1.1 pooka }
3413 1.1 pooka
3414 1.1 pooka /*
3415 1.1 pooka * Add the phy configuration to the PHY context command
3416 1.1 pooka */
3417 1.4 nonaka static void
3418 1.1 pooka iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *sc,
3419 1.1 pooka struct iwm_phy_context_cmd *cmd, struct ieee80211_channel *chan,
3420 1.1 pooka uint8_t chains_static, uint8_t chains_dynamic)
3421 1.1 pooka {
3422 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
3423 1.1 pooka uint8_t active_cnt, idle_cnt;
3424 1.1 pooka
3425 1.1 pooka cmd->ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
3426 1.1 pooka IWM_PHY_BAND_24 : IWM_PHY_BAND_5;
3427 1.1 pooka
3428 1.1 pooka cmd->ci.channel = ieee80211_chan2ieee(ic, chan);
3429 1.1 pooka cmd->ci.width = IWM_PHY_VHT_CHANNEL_MODE20;
3430 1.1 pooka cmd->ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW;
3431 1.1 pooka
3432 1.1 pooka /* Set rx the chains */
3433 1.1 pooka idle_cnt = chains_static;
3434 1.1 pooka active_cnt = chains_dynamic;
3435 1.1 pooka
3436 1.1 pooka cmd->rxchain_info = htole32(IWM_FW_VALID_RX_ANT(sc) <<
3437 1.1 pooka IWM_PHY_RX_CHAIN_VALID_POS);
3438 1.1 pooka cmd->rxchain_info |= htole32(idle_cnt << IWM_PHY_RX_CHAIN_CNT_POS);
3439 1.1 pooka cmd->rxchain_info |= htole32(active_cnt <<
3440 1.1 pooka IWM_PHY_RX_CHAIN_MIMO_CNT_POS);
3441 1.1 pooka
3442 1.1 pooka cmd->txchain_info = htole32(IWM_FW_VALID_TX_ANT(sc));
3443 1.1 pooka }
3444 1.1 pooka
3445 1.1 pooka /*
3446 1.1 pooka * Send a command
3447 1.1 pooka * only if something in the configuration changed: in case that this is the
3448 1.1 pooka * first time that the phy configuration is applied or in case that the phy
3449 1.1 pooka * configuration changed from the previous apply.
3450 1.1 pooka */
3451 1.4 nonaka static int
3452 1.1 pooka iwm_mvm_phy_ctxt_apply(struct iwm_softc *sc,
3453 1.1 pooka struct iwm_mvm_phy_ctxt *ctxt,
3454 1.1 pooka uint8_t chains_static, uint8_t chains_dynamic,
3455 1.1 pooka uint32_t action, uint32_t apply_time)
3456 1.1 pooka {
3457 1.1 pooka struct iwm_phy_context_cmd cmd;
3458 1.1 pooka int ret;
3459 1.1 pooka
3460 1.1 pooka /* Set the command header fields */
3461 1.1 pooka iwm_mvm_phy_ctxt_cmd_hdr(sc, ctxt, &cmd, action, apply_time);
3462 1.1 pooka
3463 1.1 pooka /* Set the command data */
3464 1.1 pooka iwm_mvm_phy_ctxt_cmd_data(sc, &cmd, ctxt->channel,
3465 1.1 pooka chains_static, chains_dynamic);
3466 1.1 pooka
3467 1.1 pooka ret = iwm_mvm_send_cmd_pdu(sc, IWM_PHY_CONTEXT_CMD, IWM_CMD_SYNC,
3468 1.1 pooka sizeof(struct iwm_phy_context_cmd), &cmd);
3469 1.1 pooka if (ret) {
3470 1.1 pooka DPRINTF(("PHY ctxt cmd error. ret=%d\n", ret));
3471 1.1 pooka }
3472 1.1 pooka return ret;
3473 1.1 pooka }
3474 1.1 pooka
3475 1.1 pooka /*
3476 1.1 pooka * Send a command to add a PHY context based on the current HW configuration.
3477 1.1 pooka */
3478 1.4 nonaka static int
3479 1.1 pooka iwm_mvm_phy_ctxt_add(struct iwm_softc *sc, struct iwm_mvm_phy_ctxt *ctxt,
3480 1.1 pooka struct ieee80211_channel *chan,
3481 1.1 pooka uint8_t chains_static, uint8_t chains_dynamic)
3482 1.1 pooka {
3483 1.1 pooka ctxt->channel = chan;
3484 1.1 pooka return iwm_mvm_phy_ctxt_apply(sc, ctxt,
3485 1.1 pooka chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_ADD, 0);
3486 1.1 pooka }
3487 1.1 pooka
3488 1.1 pooka /*
3489 1.1 pooka * Send a command to modify the PHY context based on the current HW
3490 1.1 pooka * configuration. Note that the function does not check that the configuration
3491 1.1 pooka * changed.
3492 1.1 pooka */
3493 1.4 nonaka static int
3494 1.1 pooka iwm_mvm_phy_ctxt_changed(struct iwm_softc *sc,
3495 1.1 pooka struct iwm_mvm_phy_ctxt *ctxt, struct ieee80211_channel *chan,
3496 1.1 pooka uint8_t chains_static, uint8_t chains_dynamic)
3497 1.1 pooka {
3498 1.1 pooka ctxt->channel = chan;
3499 1.1 pooka return iwm_mvm_phy_ctxt_apply(sc, ctxt,
3500 1.1 pooka chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_MODIFY, 0);
3501 1.1 pooka }
3502 1.1 pooka
3503 1.8 nonaka /*
3504 1.1 pooka * END iwlwifi/mvm/phy-ctxt.c
3505 1.1 pooka */
3506 1.1 pooka
3507 1.1 pooka /*
3508 1.1 pooka * transmit side
3509 1.1 pooka */
3510 1.1 pooka
3511 1.1 pooka /*
3512 1.1 pooka * Send a command to the firmware. We try to implement the Linux
3513 1.1 pooka * driver interface for the routine.
3514 1.1 pooka * mostly from if_iwn (iwn_cmd()).
3515 1.1 pooka *
3516 1.1 pooka * For now, we always copy the first part and map the second one (if it exists).
3517 1.1 pooka */
3518 1.4 nonaka static int
3519 1.1 pooka iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
3520 1.1 pooka {
3521 1.1 pooka struct iwm_tx_ring *ring = &sc->txq[IWM_MVM_CMD_QUEUE];
3522 1.1 pooka struct iwm_tfd *desc;
3523 1.1 pooka struct iwm_tx_data *data;
3524 1.1 pooka struct iwm_device_cmd *cmd;
3525 1.1 pooka struct mbuf *m;
3526 1.1 pooka bus_addr_t paddr;
3527 1.1 pooka uint32_t addr_lo;
3528 1.19 nonaka int error = 0, i, paylen, off, s;
3529 1.1 pooka int code;
3530 1.1 pooka int async, wantresp;
3531 1.1 pooka
3532 1.1 pooka code = hcmd->id;
3533 1.1 pooka async = hcmd->flags & IWM_CMD_ASYNC;
3534 1.1 pooka wantresp = hcmd->flags & IWM_CMD_WANT_SKB;
3535 1.1 pooka
3536 1.1 pooka for (i = 0, paylen = 0; i < __arraycount(hcmd->len); i++) {
3537 1.1 pooka paylen += hcmd->len[i];
3538 1.1 pooka }
3539 1.1 pooka
3540 1.1 pooka /* if the command wants an answer, busy sc_cmd_resp */
3541 1.1 pooka if (wantresp) {
3542 1.1 pooka KASSERT(!async);
3543 1.1 pooka while (sc->sc_wantresp != -1)
3544 1.1 pooka tsleep(&sc->sc_wantresp, 0, "iwmcmdsl", 0);
3545 1.1 pooka sc->sc_wantresp = ring->qid << 16 | ring->cur;
3546 1.1 pooka DPRINTFN(12, ("wantresp is %x\n", sc->sc_wantresp));
3547 1.1 pooka }
3548 1.1 pooka
3549 1.1 pooka /*
3550 1.1 pooka * Is the hardware still available? (after e.g. above wait).
3551 1.1 pooka */
3552 1.1 pooka s = splnet();
3553 1.1 pooka if (sc->sc_flags & IWM_FLAG_STOPPED) {
3554 1.1 pooka error = ENXIO;
3555 1.1 pooka goto out;
3556 1.1 pooka }
3557 1.1 pooka
3558 1.1 pooka desc = &ring->desc[ring->cur];
3559 1.1 pooka data = &ring->data[ring->cur];
3560 1.1 pooka
3561 1.1 pooka if (paylen > sizeof(cmd->data)) {
3562 1.1 pooka /* Command is too large */
3563 1.1 pooka if (sizeof(cmd->hdr) + paylen > IWM_RBUF_SIZE) {
3564 1.1 pooka error = EINVAL;
3565 1.1 pooka goto out;
3566 1.1 pooka }
3567 1.1 pooka m = m_gethdr(M_DONTWAIT, MT_DATA);
3568 1.1 pooka if (m == NULL) {
3569 1.1 pooka error = ENOMEM;
3570 1.1 pooka goto out;
3571 1.1 pooka }
3572 1.1 pooka MEXTMALLOC(m, IWM_RBUF_SIZE, M_DONTWAIT);
3573 1.1 pooka if (!(m->m_flags & M_EXT)) {
3574 1.1 pooka m_freem(m);
3575 1.1 pooka error = ENOMEM;
3576 1.1 pooka goto out;
3577 1.1 pooka }
3578 1.1 pooka cmd = mtod(m, struct iwm_device_cmd *);
3579 1.1 pooka error = bus_dmamap_load(sc->sc_dmat, data->map, cmd,
3580 1.5 nonaka IWM_RBUF_SIZE, NULL, BUS_DMA_NOWAIT | BUS_DMA_WRITE);
3581 1.1 pooka if (error != 0) {
3582 1.1 pooka m_freem(m);
3583 1.1 pooka goto out;
3584 1.1 pooka }
3585 1.1 pooka data->m = m;
3586 1.1 pooka paddr = data->map->dm_segs[0].ds_addr;
3587 1.1 pooka } else {
3588 1.1 pooka cmd = &ring->cmd[ring->cur];
3589 1.1 pooka paddr = data->cmd_paddr;
3590 1.1 pooka }
3591 1.1 pooka
3592 1.1 pooka cmd->hdr.code = code;
3593 1.1 pooka cmd->hdr.flags = 0;
3594 1.1 pooka cmd->hdr.qid = ring->qid;
3595 1.1 pooka cmd->hdr.idx = ring->cur;
3596 1.1 pooka
3597 1.1 pooka for (i = 0, off = 0; i < __arraycount(hcmd->data); i++) {
3598 1.1 pooka if (hcmd->len[i] == 0)
3599 1.1 pooka continue;
3600 1.1 pooka memcpy(cmd->data + off, hcmd->data[i], hcmd->len[i]);
3601 1.1 pooka off += hcmd->len[i];
3602 1.1 pooka }
3603 1.1 pooka KASSERT(off == paylen);
3604 1.1 pooka
3605 1.1 pooka /* lo field is not aligned */
3606 1.1 pooka addr_lo = htole32((uint32_t)paddr);
3607 1.1 pooka memcpy(&desc->tbs[0].lo, &addr_lo, sizeof(uint32_t));
3608 1.1 pooka desc->tbs[0].hi_n_len = htole16(iwm_get_dma_hi_addr(paddr)
3609 1.1 pooka | ((sizeof(cmd->hdr) + paylen) << 4));
3610 1.1 pooka desc->num_tbs = 1;
3611 1.1 pooka
3612 1.9 nonaka DPRINTFN(8, ("iwm_send_cmd 0x%x size=%zu %s\n",
3613 1.5 nonaka code, sizeof(cmd->hdr) + paylen, async ? " (async)" : ""));
3614 1.1 pooka
3615 1.5 nonaka if (paylen > sizeof(cmd->data)) {
3616 1.5 nonaka bus_dmamap_sync(sc->sc_dmat, data->map, 0,
3617 1.5 nonaka sizeof(cmd->hdr) + paylen, BUS_DMASYNC_PREWRITE);
3618 1.1 pooka } else {
3619 1.1 pooka bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
3620 1.1 pooka (char *)(void *)cmd - (char *)(void *)ring->cmd_dma.vaddr,
3621 1.5 nonaka sizeof(cmd->hdr) + paylen, BUS_DMASYNC_PREWRITE);
3622 1.1 pooka }
3623 1.1 pooka bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
3624 1.1 pooka (char *)(void *)desc - (char *)(void *)ring->desc_dma.vaddr,
3625 1.1 pooka sizeof (*desc), BUS_DMASYNC_PREWRITE);
3626 1.1 pooka
3627 1.1 pooka IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
3628 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
3629 1.1 pooka if (!iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
3630 1.1 pooka IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
3631 1.1 pooka (IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
3632 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000)) {
3633 1.2 nonaka DPRINTF(("%s: acquiring device failed\n", DEVNAME(sc)));
3634 1.1 pooka error = EBUSY;
3635 1.1 pooka goto out;
3636 1.1 pooka }
3637 1.1 pooka
3638 1.1 pooka #if 0
3639 1.1 pooka iwm_update_sched(sc, ring->qid, ring->cur, 0, 0);
3640 1.1 pooka #endif
3641 1.1 pooka DPRINTF(("sending command 0x%x qid %d, idx %d\n",
3642 1.1 pooka code, ring->qid, ring->cur));
3643 1.1 pooka
3644 1.1 pooka /* Kick command ring. */
3645 1.1 pooka ring->cur = (ring->cur + 1) % IWM_TX_RING_COUNT;
3646 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
3647 1.1 pooka
3648 1.1 pooka if (!async) {
3649 1.1 pooka /* m..m-mmyy-mmyyyy-mym-ym m-my generation */
3650 1.1 pooka int generation = sc->sc_generation;
3651 1.1 pooka error = tsleep(desc, PCATCH, "iwmcmd", hz);
3652 1.1 pooka if (error == 0) {
3653 1.1 pooka /* if hardware is no longer up, return error */
3654 1.1 pooka if (generation != sc->sc_generation) {
3655 1.1 pooka error = ENXIO;
3656 1.1 pooka } else {
3657 1.1 pooka hcmd->resp_pkt = (void *)sc->sc_cmd_resp;
3658 1.1 pooka }
3659 1.1 pooka }
3660 1.1 pooka }
3661 1.1 pooka out:
3662 1.1 pooka if (wantresp && error != 0) {
3663 1.1 pooka iwm_free_resp(sc, hcmd);
3664 1.1 pooka }
3665 1.1 pooka splx(s);
3666 1.1 pooka
3667 1.1 pooka return error;
3668 1.1 pooka }
3669 1.1 pooka
3670 1.1 pooka /* iwlwifi: mvm/utils.c */
3671 1.4 nonaka static int
3672 1.1 pooka iwm_mvm_send_cmd_pdu(struct iwm_softc *sc, uint8_t id,
3673 1.1 pooka uint32_t flags, uint16_t len, const void *data)
3674 1.1 pooka {
3675 1.1 pooka struct iwm_host_cmd cmd = {
3676 1.1 pooka .id = id,
3677 1.1 pooka .len = { len, },
3678 1.1 pooka .data = { data, },
3679 1.1 pooka .flags = flags,
3680 1.1 pooka };
3681 1.1 pooka
3682 1.1 pooka return iwm_send_cmd(sc, &cmd);
3683 1.1 pooka }
3684 1.1 pooka
3685 1.1 pooka /* iwlwifi: mvm/utils.c */
3686 1.4 nonaka static int
3687 1.1 pooka iwm_mvm_send_cmd_status(struct iwm_softc *sc,
3688 1.1 pooka struct iwm_host_cmd *cmd, uint32_t *status)
3689 1.1 pooka {
3690 1.1 pooka struct iwm_rx_packet *pkt;
3691 1.1 pooka struct iwm_cmd_response *resp;
3692 1.1 pooka int error, resp_len;
3693 1.1 pooka
3694 1.1 pooka //lockdep_assert_held(&mvm->mutex);
3695 1.1 pooka
3696 1.1 pooka KASSERT((cmd->flags & IWM_CMD_WANT_SKB) == 0);
3697 1.1 pooka cmd->flags |= IWM_CMD_SYNC | IWM_CMD_WANT_SKB;
3698 1.1 pooka
3699 1.1 pooka if ((error = iwm_send_cmd(sc, cmd)) != 0)
3700 1.1 pooka return error;
3701 1.1 pooka pkt = cmd->resp_pkt;
3702 1.1 pooka
3703 1.1 pooka /* Can happen if RFKILL is asserted */
3704 1.1 pooka if (!pkt) {
3705 1.1 pooka error = 0;
3706 1.1 pooka goto out_free_resp;
3707 1.1 pooka }
3708 1.1 pooka
3709 1.1 pooka if (pkt->hdr.flags & IWM_CMD_FAILED_MSK) {
3710 1.1 pooka error = EIO;
3711 1.1 pooka goto out_free_resp;
3712 1.1 pooka }
3713 1.1 pooka
3714 1.1 pooka resp_len = iwm_rx_packet_payload_len(pkt);
3715 1.1 pooka if (resp_len != sizeof(*resp)) {
3716 1.1 pooka error = EIO;
3717 1.1 pooka goto out_free_resp;
3718 1.1 pooka }
3719 1.1 pooka
3720 1.1 pooka resp = (void *)pkt->data;
3721 1.1 pooka *status = le32toh(resp->status);
3722 1.1 pooka out_free_resp:
3723 1.1 pooka iwm_free_resp(sc, cmd);
3724 1.1 pooka return error;
3725 1.1 pooka }
3726 1.1 pooka
3727 1.1 pooka /* iwlwifi/mvm/utils.c */
3728 1.4 nonaka static int
3729 1.1 pooka iwm_mvm_send_cmd_pdu_status(struct iwm_softc *sc, uint8_t id,
3730 1.1 pooka uint16_t len, const void *data, uint32_t *status)
3731 1.1 pooka {
3732 1.1 pooka struct iwm_host_cmd cmd = {
3733 1.1 pooka .id = id,
3734 1.1 pooka .len = { len, },
3735 1.1 pooka .data = { data, },
3736 1.1 pooka };
3737 1.1 pooka
3738 1.1 pooka return iwm_mvm_send_cmd_status(sc, &cmd, status);
3739 1.1 pooka }
3740 1.1 pooka
3741 1.4 nonaka static void
3742 1.1 pooka iwm_free_resp(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
3743 1.1 pooka {
3744 1.1 pooka KASSERT(sc->sc_wantresp != -1);
3745 1.1 pooka KASSERT((hcmd->flags & (IWM_CMD_WANT_SKB|IWM_CMD_SYNC))
3746 1.1 pooka == (IWM_CMD_WANT_SKB|IWM_CMD_SYNC));
3747 1.1 pooka sc->sc_wantresp = -1;
3748 1.1 pooka wakeup(&sc->sc_wantresp);
3749 1.1 pooka }
3750 1.1 pooka
3751 1.1 pooka /*
3752 1.1 pooka * Process a "command done" firmware notification. This is where we wakeup
3753 1.1 pooka * processes waiting for a synchronous command completion.
3754 1.1 pooka * from if_iwn
3755 1.1 pooka */
3756 1.4 nonaka static void
3757 1.1 pooka iwm_cmd_done(struct iwm_softc *sc, struct iwm_rx_packet *pkt)
3758 1.1 pooka {
3759 1.1 pooka struct iwm_tx_ring *ring = &sc->txq[IWM_MVM_CMD_QUEUE];
3760 1.1 pooka struct iwm_tx_data *data;
3761 1.1 pooka
3762 1.1 pooka if (pkt->hdr.qid != IWM_MVM_CMD_QUEUE) {
3763 1.1 pooka return; /* Not a command ack. */
3764 1.1 pooka }
3765 1.1 pooka
3766 1.1 pooka data = &ring->data[pkt->hdr.idx];
3767 1.1 pooka
3768 1.1 pooka /* If the command was mapped in an mbuf, free it. */
3769 1.1 pooka if (data->m != NULL) {
3770 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0,
3771 1.1 pooka data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
3772 1.1 pooka bus_dmamap_unload(sc->sc_dmat, data->map);
3773 1.1 pooka m_freem(data->m);
3774 1.1 pooka data->m = NULL;
3775 1.1 pooka }
3776 1.1 pooka wakeup(&ring->desc[pkt->hdr.idx]);
3777 1.1 pooka }
3778 1.1 pooka
3779 1.1 pooka #if 0
3780 1.1 pooka /*
3781 1.1 pooka * necessary only for block ack mode
3782 1.1 pooka */
3783 1.1 pooka void
3784 1.1 pooka iwm_update_sched(struct iwm_softc *sc, int qid, int idx, uint8_t sta_id,
3785 1.1 pooka uint16_t len)
3786 1.1 pooka {
3787 1.1 pooka struct iwm_agn_scd_bc_tbl *scd_bc_tbl;
3788 1.1 pooka uint16_t w_val;
3789 1.1 pooka
3790 1.1 pooka scd_bc_tbl = sc->sched_dma.vaddr;
3791 1.1 pooka
3792 1.1 pooka len += 8; /* magic numbers came naturally from paris */
3793 1.1 pooka if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_DW_BC_TABLE)
3794 1.1 pooka len = roundup(len, 4) / 4;
3795 1.1 pooka
3796 1.1 pooka w_val = htole16(sta_id << 12 | len);
3797 1.1 pooka
3798 1.1 pooka /* Update TX scheduler. */
3799 1.1 pooka scd_bc_tbl[qid].tfd_offset[idx] = w_val;
3800 1.1 pooka bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
3801 1.1 pooka (char *)(void *)w - (char *)(void *)sc->sched_dma.vaddr,
3802 1.1 pooka sizeof(uint16_t), BUS_DMASYNC_PREWRITE);
3803 1.1 pooka
3804 1.1 pooka /* I really wonder what this is ?!? */
3805 1.1 pooka if (idx < IWM_TFD_QUEUE_SIZE_BC_DUP) {
3806 1.1 pooka scd_bc_tbl[qid].tfd_offset[IWM_TFD_QUEUE_SIZE_MAX + idx] = w_val;
3807 1.1 pooka bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
3808 1.1 pooka (char *)(void *)(w + IWM_TFD_QUEUE_SIZE_MAX) -
3809 1.1 pooka (char *)(void *)sc->sched_dma.vaddr,
3810 1.1 pooka sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
3811 1.1 pooka }
3812 1.1 pooka }
3813 1.1 pooka #endif
3814 1.1 pooka
3815 1.1 pooka /*
3816 1.1 pooka * Fill in various bit for management frames, and leave them
3817 1.1 pooka * unfilled for data frames (firmware takes care of that).
3818 1.1 pooka * Return the selected TX rate.
3819 1.1 pooka */
3820 1.4 nonaka static const struct iwm_rate *
3821 1.1 pooka iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in,
3822 1.1 pooka struct ieee80211_frame *wh, struct iwm_tx_cmd *tx)
3823 1.1 pooka {
3824 1.24 nonaka struct ieee80211com *ic = &sc->sc_ic;
3825 1.28 nonaka struct ieee80211_node *ni = &in->in_ni;
3826 1.1 pooka const struct iwm_rate *rinfo;
3827 1.1 pooka int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
3828 1.1 pooka int ridx, rate_flags;
3829 1.28 nonaka int nrates = ni->ni_rates.rs_nrates;
3830 1.1 pooka
3831 1.1 pooka tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT;
3832 1.1 pooka tx->data_retry_limit = IWM_DEFAULT_TX_RETRY;
3833 1.1 pooka
3834 1.28 nonaka if (type != IEEE80211_FC0_TYPE_DATA) {
3835 1.28 nonaka /* for non-data, use the lowest supported rate */
3836 1.28 nonaka ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
3837 1.28 nonaka IWM_RIDX_OFDM : IWM_RIDX_CCK;
3838 1.28 nonaka } else if (ic->ic_fixed_rate != -1) {
3839 1.28 nonaka ridx = sc->sc_fixed_ridx;
3840 1.28 nonaka } else {
3841 1.28 nonaka /* for data frames, use RS table */
3842 1.28 nonaka tx->initial_rate_index = (nrates - 1) - ni->ni_txrate;
3843 1.8 nonaka tx->tx_flags |= htole32(IWM_TX_CMD_FLG_STA_RATE);
3844 1.1 pooka DPRINTFN(12, ("start with txrate %d\n", tx->initial_rate_index));
3845 1.28 nonaka ridx = in->in_ridx[ni->ni_txrate];
3846 1.28 nonaka return &iwm_rates[ridx];
3847 1.1 pooka }
3848 1.1 pooka
3849 1.1 pooka rinfo = &iwm_rates[ridx];
3850 1.1 pooka rate_flags = 1 << IWM_RATE_MCS_ANT_POS;
3851 1.1 pooka if (IWM_RIDX_IS_CCK(ridx))
3852 1.1 pooka rate_flags |= IWM_RATE_MCS_CCK_MSK;
3853 1.1 pooka tx->rate_n_flags = htole32(rate_flags | rinfo->plcp);
3854 1.1 pooka
3855 1.1 pooka return rinfo;
3856 1.1 pooka }
3857 1.1 pooka
3858 1.1 pooka #define TB0_SIZE 16
3859 1.4 nonaka static int
3860 1.1 pooka iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
3861 1.1 pooka {
3862 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
3863 1.1 pooka struct iwm_node *in = (void *)ni;
3864 1.1 pooka struct iwm_tx_ring *ring;
3865 1.1 pooka struct iwm_tx_data *data;
3866 1.1 pooka struct iwm_tfd *desc;
3867 1.1 pooka struct iwm_device_cmd *cmd;
3868 1.1 pooka struct iwm_tx_cmd *tx;
3869 1.1 pooka struct ieee80211_frame *wh;
3870 1.1 pooka struct ieee80211_key *k = NULL;
3871 1.1 pooka struct mbuf *m1;
3872 1.1 pooka const struct iwm_rate *rinfo;
3873 1.1 pooka uint32_t flags;
3874 1.1 pooka u_int hdrlen;
3875 1.1 pooka bus_dma_segment_t *seg;
3876 1.1 pooka uint8_t tid, type;
3877 1.1 pooka int i, totlen, error, pad;
3878 1.1 pooka int hdrlen2;
3879 1.1 pooka
3880 1.1 pooka wh = mtod(m, struct ieee80211_frame *);
3881 1.1 pooka hdrlen = ieee80211_anyhdrsize(wh);
3882 1.1 pooka type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
3883 1.1 pooka
3884 1.1 pooka hdrlen2 = (ieee80211_has_qos(wh)) ?
3885 1.1 pooka sizeof (struct ieee80211_qosframe) :
3886 1.1 pooka sizeof (struct ieee80211_frame);
3887 1.1 pooka
3888 1.1 pooka if (hdrlen != hdrlen2)
3889 1.2 nonaka DPRINTF(("%s: hdrlen error (%d != %d)\n",
3890 1.2 nonaka DEVNAME(sc), hdrlen, hdrlen2));
3891 1.1 pooka
3892 1.1 pooka tid = 0;
3893 1.1 pooka
3894 1.1 pooka ring = &sc->txq[ac];
3895 1.1 pooka desc = &ring->desc[ring->cur];
3896 1.1 pooka memset(desc, 0, sizeof(*desc));
3897 1.1 pooka data = &ring->data[ring->cur];
3898 1.1 pooka
3899 1.1 pooka /* Fill out iwm_tx_cmd to send to the firmware */
3900 1.1 pooka cmd = &ring->cmd[ring->cur];
3901 1.1 pooka cmd->hdr.code = IWM_TX_CMD;
3902 1.1 pooka cmd->hdr.flags = 0;
3903 1.1 pooka cmd->hdr.qid = ring->qid;
3904 1.1 pooka cmd->hdr.idx = ring->cur;
3905 1.1 pooka
3906 1.1 pooka tx = (void *)cmd->data;
3907 1.1 pooka memset(tx, 0, sizeof(*tx));
3908 1.1 pooka
3909 1.1 pooka rinfo = iwm_tx_fill_cmd(sc, in, wh, tx);
3910 1.1 pooka
3911 1.1 pooka if (sc->sc_drvbpf != NULL) {
3912 1.1 pooka struct iwm_tx_radiotap_header *tap = &sc->sc_txtap;
3913 1.1 pooka
3914 1.1 pooka tap->wt_flags = 0;
3915 1.1 pooka tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
3916 1.1 pooka tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
3917 1.1 pooka tap->wt_rate = rinfo->rate;
3918 1.1 pooka tap->wt_hwqueue = ac;
3919 1.1 pooka if (wh->i_fc[1] & IEEE80211_FC1_WEP)
3920 1.1 pooka tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
3921 1.1 pooka
3922 1.1 pooka bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m);
3923 1.1 pooka }
3924 1.1 pooka
3925 1.1 pooka /* Encrypt the frame if need be. */
3926 1.1 pooka if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
3927 1.1 pooka k = ieee80211_crypto_encap(ic, ni, m);
3928 1.1 pooka if (k == NULL) {
3929 1.1 pooka m_freem(m);
3930 1.1 pooka return ENOBUFS;
3931 1.1 pooka }
3932 1.1 pooka /* Packet header may have moved, reset our local pointer. */
3933 1.1 pooka wh = mtod(m, struct ieee80211_frame *);
3934 1.1 pooka }
3935 1.1 pooka totlen = m->m_pkthdr.len;
3936 1.1 pooka
3937 1.1 pooka flags = 0;
3938 1.1 pooka if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
3939 1.1 pooka flags |= IWM_TX_CMD_FLG_ACK;
3940 1.1 pooka }
3941 1.1 pooka
3942 1.1 pooka if (type != IEEE80211_FC0_TYPE_DATA
3943 1.1 pooka && (totlen + IEEE80211_CRC_LEN > ic->ic_rtsthreshold)
3944 1.1 pooka && !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
3945 1.1 pooka flags |= IWM_TX_CMD_FLG_PROT_REQUIRE;
3946 1.1 pooka }
3947 1.1 pooka
3948 1.1 pooka if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
3949 1.1 pooka type != IEEE80211_FC0_TYPE_DATA)
3950 1.1 pooka tx->sta_id = sc->sc_aux_sta.sta_id;
3951 1.1 pooka else
3952 1.1 pooka tx->sta_id = IWM_STATION_ID;
3953 1.1 pooka
3954 1.1 pooka if (type == IEEE80211_FC0_TYPE_MGT) {
3955 1.1 pooka uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
3956 1.1 pooka
3957 1.1 pooka if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
3958 1.1 pooka subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
3959 1.1 pooka tx->pm_frame_timeout = htole16(3);
3960 1.1 pooka else
3961 1.1 pooka tx->pm_frame_timeout = htole16(2);
3962 1.1 pooka } else {
3963 1.1 pooka tx->pm_frame_timeout = htole16(0);
3964 1.1 pooka }
3965 1.1 pooka
3966 1.8 nonaka if (hdrlen & 3) {
3967 1.8 nonaka /* First segment length must be a multiple of 4. */
3968 1.8 nonaka flags |= IWM_TX_CMD_FLG_MH_PAD;
3969 1.8 nonaka pad = 4 - (hdrlen & 3);
3970 1.8 nonaka } else
3971 1.8 nonaka pad = 0;
3972 1.1 pooka
3973 1.1 pooka tx->driver_txop = 0;
3974 1.1 pooka tx->next_frame_len = 0;
3975 1.1 pooka
3976 1.1 pooka tx->len = htole16(totlen);
3977 1.1 pooka tx->tid_tspec = tid;
3978 1.1 pooka tx->life_time = htole32(IWM_TX_CMD_LIFE_TIME_INFINITE);
3979 1.1 pooka
3980 1.1 pooka /* Set physical address of "scratch area". */
3981 1.1 pooka tx->dram_lsb_ptr = htole32(data->scratch_paddr);
3982 1.1 pooka tx->dram_msb_ptr = iwm_get_dma_hi_addr(data->scratch_paddr);
3983 1.1 pooka
3984 1.1 pooka /* Copy 802.11 header in TX command. */
3985 1.1 pooka memcpy(((uint8_t *)tx) + sizeof(*tx), wh, hdrlen);
3986 1.1 pooka
3987 1.1 pooka flags |= IWM_TX_CMD_FLG_BT_DIS | IWM_TX_CMD_FLG_SEQ_CTL;
3988 1.1 pooka
3989 1.1 pooka tx->sec_ctl = 0;
3990 1.1 pooka tx->tx_flags |= htole32(flags);
3991 1.1 pooka
3992 1.1 pooka /* Trim 802.11 header. */
3993 1.1 pooka m_adj(m, hdrlen);
3994 1.1 pooka
3995 1.1 pooka error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
3996 1.1 pooka BUS_DMA_NOWAIT | BUS_DMA_WRITE);
3997 1.1 pooka if (error != 0) {
3998 1.1 pooka if (error != EFBIG) {
3999 1.3 nonaka aprint_error_dev(sc->sc_dev,
4000 1.3 nonaka "can't map mbuf (error %d)\n", error);
4001 1.1 pooka m_freem(m);
4002 1.1 pooka return error;
4003 1.1 pooka }
4004 1.1 pooka /* Too many DMA segments, linearize mbuf. */
4005 1.1 pooka MGETHDR(m1, M_DONTWAIT, MT_DATA);
4006 1.1 pooka if (m1 == NULL) {
4007 1.1 pooka m_freem(m);
4008 1.1 pooka return ENOBUFS;
4009 1.1 pooka }
4010 1.1 pooka if (m->m_pkthdr.len > MHLEN) {
4011 1.1 pooka MCLGET(m1, M_DONTWAIT);
4012 1.1 pooka if (!(m1->m_flags & M_EXT)) {
4013 1.1 pooka m_freem(m);
4014 1.1 pooka m_freem(m1);
4015 1.1 pooka return ENOBUFS;
4016 1.1 pooka }
4017 1.1 pooka }
4018 1.1 pooka m_copydata(m, 0, m->m_pkthdr.len, mtod(m1, void *));
4019 1.1 pooka m1->m_pkthdr.len = m1->m_len = m->m_pkthdr.len;
4020 1.1 pooka m_freem(m);
4021 1.1 pooka m = m1;
4022 1.1 pooka
4023 1.1 pooka error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
4024 1.1 pooka BUS_DMA_NOWAIT | BUS_DMA_WRITE);
4025 1.1 pooka if (error != 0) {
4026 1.3 nonaka aprint_error_dev(sc->sc_dev,
4027 1.3 nonaka "can't map mbuf (error %d)\n", error);
4028 1.1 pooka m_freem(m);
4029 1.1 pooka return error;
4030 1.1 pooka }
4031 1.1 pooka }
4032 1.1 pooka data->m = m;
4033 1.1 pooka data->in = in;
4034 1.1 pooka data->done = 0;
4035 1.1 pooka
4036 1.1 pooka DPRINTFN(8, ("sending txd %p, in %p\n", data, data->in));
4037 1.1 pooka KASSERT(data->in != NULL);
4038 1.1 pooka
4039 1.1 pooka DPRINTFN(8, ("sending data: qid=%d idx=%d len=%d nsegs=%d\n",
4040 1.1 pooka ring->qid, ring->cur, totlen, data->map->dm_nsegs));
4041 1.1 pooka
4042 1.1 pooka /* Fill TX descriptor. */
4043 1.1 pooka desc->num_tbs = 2 + data->map->dm_nsegs;
4044 1.1 pooka
4045 1.1 pooka desc->tbs[0].lo = htole32(data->cmd_paddr);
4046 1.1 pooka desc->tbs[0].hi_n_len = htole16(iwm_get_dma_hi_addr(data->cmd_paddr)) |
4047 1.1 pooka (TB0_SIZE << 4);
4048 1.1 pooka desc->tbs[1].lo = htole32(data->cmd_paddr + TB0_SIZE);
4049 1.1 pooka desc->tbs[1].hi_n_len = htole16(iwm_get_dma_hi_addr(data->cmd_paddr)) |
4050 1.1 pooka ((sizeof(struct iwm_cmd_header) + sizeof(*tx)
4051 1.1 pooka + hdrlen + pad - TB0_SIZE) << 4);
4052 1.1 pooka
4053 1.1 pooka /* Other DMA segments are for data payload. */
4054 1.1 pooka seg = data->map->dm_segs;
4055 1.1 pooka for (i = 0; i < data->map->dm_nsegs; i++, seg++) {
4056 1.1 pooka desc->tbs[i+2].lo = htole32(seg->ds_addr);
4057 1.1 pooka desc->tbs[i+2].hi_n_len = \
4058 1.1 pooka htole16(iwm_get_dma_hi_addr(seg->ds_addr))
4059 1.1 pooka | ((seg->ds_len) << 4);
4060 1.1 pooka }
4061 1.1 pooka
4062 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
4063 1.1 pooka BUS_DMASYNC_PREWRITE);
4064 1.1 pooka bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
4065 1.1 pooka (char *)(void *)cmd - (char *)(void *)ring->cmd_dma.vaddr,
4066 1.1 pooka sizeof (*cmd), BUS_DMASYNC_PREWRITE);
4067 1.1 pooka bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
4068 1.1 pooka (char *)(void *)desc - (char *)(void *)ring->desc_dma.vaddr,
4069 1.1 pooka sizeof (*desc), BUS_DMASYNC_PREWRITE);
4070 1.1 pooka
4071 1.1 pooka #if 0
4072 1.1 pooka iwm_update_sched(sc, ring->qid, ring->cur, tx->sta_id, le16toh(tx->len));
4073 1.1 pooka #endif
4074 1.1 pooka
4075 1.1 pooka /* Kick TX ring. */
4076 1.1 pooka ring->cur = (ring->cur + 1) % IWM_TX_RING_COUNT;
4077 1.1 pooka IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
4078 1.1 pooka
4079 1.1 pooka /* Mark TX ring as full if we reach a certain threshold. */
4080 1.1 pooka if (++ring->queued > IWM_TX_RING_HIMARK) {
4081 1.1 pooka sc->qfullmsk |= 1 << ring->qid;
4082 1.1 pooka }
4083 1.1 pooka
4084 1.1 pooka return 0;
4085 1.1 pooka }
4086 1.1 pooka
4087 1.1 pooka #if 0
4088 1.1 pooka /* not necessary? */
4089 1.4 nonaka static int
4090 1.1 pooka iwm_mvm_flush_tx_path(struct iwm_softc *sc, int tfd_msk, int sync)
4091 1.1 pooka {
4092 1.1 pooka struct iwm_tx_path_flush_cmd flush_cmd = {
4093 1.1 pooka .queues_ctl = htole32(tfd_msk),
4094 1.1 pooka .flush_ctl = htole16(IWM_DUMP_TX_FIFO_FLUSH),
4095 1.1 pooka };
4096 1.1 pooka int ret;
4097 1.1 pooka
4098 1.1 pooka ret = iwm_mvm_send_cmd_pdu(sc, IWM_TXPATH_FLUSH,
4099 1.1 pooka sync ? IWM_CMD_SYNC : IWM_CMD_ASYNC,
4100 1.1 pooka sizeof(flush_cmd), &flush_cmd);
4101 1.1 pooka if (ret)
4102 1.3 nonaka aprint_error_dev(sc->sc_dev, "Flushing tx queue failed: %d\n",
4103 1.3 nonaka ret);
4104 1.1 pooka return ret;
4105 1.1 pooka }
4106 1.1 pooka #endif
4107 1.1 pooka
4108 1.1 pooka
4109 1.1 pooka /*
4110 1.1 pooka * BEGIN mvm/power.c
4111 1.1 pooka */
4112 1.1 pooka
4113 1.1 pooka #define IWM_POWER_KEEP_ALIVE_PERIOD_SEC 25
4114 1.1 pooka
4115 1.4 nonaka static int
4116 1.1 pooka iwm_mvm_beacon_filter_send_cmd(struct iwm_softc *sc,
4117 1.1 pooka struct iwm_beacon_filter_cmd *cmd)
4118 1.1 pooka {
4119 1.1 pooka int ret;
4120 1.1 pooka
4121 1.1 pooka ret = iwm_mvm_send_cmd_pdu(sc, IWM_REPLY_BEACON_FILTERING_CMD,
4122 1.1 pooka IWM_CMD_SYNC, sizeof(struct iwm_beacon_filter_cmd), cmd);
4123 1.1 pooka
4124 1.1 pooka if (!ret) {
4125 1.1 pooka DPRINTF(("ba_enable_beacon_abort is: %d\n",
4126 1.1 pooka le32toh(cmd->ba_enable_beacon_abort)));
4127 1.1 pooka DPRINTF(("ba_escape_timer is: %d\n",
4128 1.1 pooka le32toh(cmd->ba_escape_timer)));
4129 1.1 pooka DPRINTF(("bf_debug_flag is: %d\n",
4130 1.1 pooka le32toh(cmd->bf_debug_flag)));
4131 1.1 pooka DPRINTF(("bf_enable_beacon_filter is: %d\n",
4132 1.1 pooka le32toh(cmd->bf_enable_beacon_filter)));
4133 1.1 pooka DPRINTF(("bf_energy_delta is: %d\n",
4134 1.1 pooka le32toh(cmd->bf_energy_delta)));
4135 1.1 pooka DPRINTF(("bf_escape_timer is: %d\n",
4136 1.1 pooka le32toh(cmd->bf_escape_timer)));
4137 1.1 pooka DPRINTF(("bf_roaming_energy_delta is: %d\n",
4138 1.1 pooka le32toh(cmd->bf_roaming_energy_delta)));
4139 1.1 pooka DPRINTF(("bf_roaming_state is: %d\n",
4140 1.1 pooka le32toh(cmd->bf_roaming_state)));
4141 1.1 pooka DPRINTF(("bf_temp_threshold is: %d\n",
4142 1.1 pooka le32toh(cmd->bf_temp_threshold)));
4143 1.1 pooka DPRINTF(("bf_temp_fast_filter is: %d\n",
4144 1.1 pooka le32toh(cmd->bf_temp_fast_filter)));
4145 1.1 pooka DPRINTF(("bf_temp_slow_filter is: %d\n",
4146 1.1 pooka le32toh(cmd->bf_temp_slow_filter)));
4147 1.1 pooka }
4148 1.1 pooka return ret;
4149 1.1 pooka }
4150 1.1 pooka
4151 1.4 nonaka static void
4152 1.1 pooka iwm_mvm_beacon_filter_set_cqm_params(struct iwm_softc *sc,
4153 1.1 pooka struct iwm_node *in, struct iwm_beacon_filter_cmd *cmd)
4154 1.1 pooka {
4155 1.1 pooka cmd->ba_enable_beacon_abort = htole32(sc->sc_bf.ba_enabled);
4156 1.1 pooka }
4157 1.1 pooka
4158 1.4 nonaka static int
4159 1.1 pooka iwm_mvm_update_beacon_abort(struct iwm_softc *sc, struct iwm_node *in,
4160 1.1 pooka int enable)
4161 1.1 pooka {
4162 1.1 pooka struct iwm_beacon_filter_cmd cmd = {
4163 1.1 pooka IWM_BF_CMD_CONFIG_DEFAULTS,
4164 1.1 pooka .bf_enable_beacon_filter = htole32(1),
4165 1.1 pooka .ba_enable_beacon_abort = htole32(enable),
4166 1.1 pooka };
4167 1.1 pooka
4168 1.1 pooka if (!sc->sc_bf.bf_enabled)
4169 1.1 pooka return 0;
4170 1.1 pooka
4171 1.1 pooka sc->sc_bf.ba_enabled = enable;
4172 1.1 pooka iwm_mvm_beacon_filter_set_cqm_params(sc, in, &cmd);
4173 1.1 pooka return iwm_mvm_beacon_filter_send_cmd(sc, &cmd);
4174 1.1 pooka }
4175 1.1 pooka
4176 1.4 nonaka static void
4177 1.1 pooka iwm_mvm_power_log(struct iwm_softc *sc, struct iwm_mac_power_cmd *cmd)
4178 1.1 pooka {
4179 1.1 pooka DPRINTF(("Sending power table command on mac id 0x%X for "
4180 1.1 pooka "power level %d, flags = 0x%X\n",
4181 1.1 pooka cmd->id_and_color, IWM_POWER_SCHEME_CAM, le16toh(cmd->flags)));
4182 1.1 pooka DPRINTF(("Keep alive = %u sec\n", le16toh(cmd->keep_alive_seconds)));
4183 1.1 pooka
4184 1.1 pooka if (!(cmd->flags & htole16(IWM_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK))) {
4185 1.1 pooka DPRINTF(("Disable power management\n"));
4186 1.1 pooka return;
4187 1.1 pooka }
4188 1.1 pooka KASSERT(0);
4189 1.1 pooka
4190 1.1 pooka #if 0
4191 1.1 pooka DPRINTF(mvm, "Rx timeout = %u usec\n",
4192 1.1 pooka le32_to_cpu(cmd->rx_data_timeout));
4193 1.1 pooka DPRINTF(mvm, "Tx timeout = %u usec\n",
4194 1.1 pooka le32_to_cpu(cmd->tx_data_timeout));
4195 1.1 pooka if (cmd->flags & cpu_to_le16(IWM_POWER_FLAGS_SKIP_OVER_DTIM_MSK))
4196 1.1 pooka DPRINTF(mvm, "DTIM periods to skip = %u\n",
4197 1.1 pooka cmd->skip_dtim_periods);
4198 1.1 pooka if (cmd->flags & cpu_to_le16(IWM_POWER_FLAGS_LPRX_ENA_MSK))
4199 1.1 pooka DPRINTF(mvm, "LP RX RSSI threshold = %u\n",
4200 1.1 pooka cmd->lprx_rssi_threshold);
4201 1.1 pooka if (cmd->flags & cpu_to_le16(IWM_POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
4202 1.1 pooka DPRINTF(mvm, "uAPSD enabled\n");
4203 1.1 pooka DPRINTF(mvm, "Rx timeout (uAPSD) = %u usec\n",
4204 1.1 pooka le32_to_cpu(cmd->rx_data_timeout_uapsd));
4205 1.1 pooka DPRINTF(mvm, "Tx timeout (uAPSD) = %u usec\n",
4206 1.1 pooka le32_to_cpu(cmd->tx_data_timeout_uapsd));
4207 1.1 pooka DPRINTF(mvm, "QNDP TID = %d\n", cmd->qndp_tid);
4208 1.1 pooka DPRINTF(mvm, "ACs flags = 0x%x\n", cmd->uapsd_ac_flags);
4209 1.1 pooka DPRINTF(mvm, "Max SP = %d\n", cmd->uapsd_max_sp);
4210 1.1 pooka }
4211 1.1 pooka #endif
4212 1.1 pooka }
4213 1.1 pooka
4214 1.4 nonaka static void
4215 1.1 pooka iwm_mvm_power_build_cmd(struct iwm_softc *sc, struct iwm_node *in,
4216 1.1 pooka struct iwm_mac_power_cmd *cmd)
4217 1.1 pooka {
4218 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
4219 1.1 pooka struct ieee80211_node *ni = &in->in_ni;
4220 1.1 pooka int dtimper, dtimper_msec;
4221 1.1 pooka int keep_alive;
4222 1.1 pooka
4223 1.1 pooka cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id,
4224 1.1 pooka in->in_color));
4225 1.1 pooka dtimper = ic->ic_dtim_period ?: 1;
4226 1.1 pooka
4227 1.1 pooka /*
4228 1.1 pooka * Regardless of power management state the driver must set
4229 1.1 pooka * keep alive period. FW will use it for sending keep alive NDPs
4230 1.1 pooka * immediately after association. Check that keep alive period
4231 1.1 pooka * is at least 3 * DTIM
4232 1.1 pooka */
4233 1.1 pooka dtimper_msec = dtimper * ni->ni_intval;
4234 1.1 pooka keep_alive
4235 1.1 pooka = MAX(3 * dtimper_msec, 1000 * IWM_POWER_KEEP_ALIVE_PERIOD_SEC);
4236 1.1 pooka keep_alive = roundup(keep_alive, 1000) / 1000;
4237 1.1 pooka cmd->keep_alive_seconds = htole16(keep_alive);
4238 1.1 pooka }
4239 1.1 pooka
4240 1.4 nonaka static int
4241 1.1 pooka iwm_mvm_power_mac_update_mode(struct iwm_softc *sc, struct iwm_node *in)
4242 1.1 pooka {
4243 1.1 pooka int ret;
4244 1.1 pooka int ba_enable;
4245 1.1 pooka struct iwm_mac_power_cmd cmd;
4246 1.1 pooka
4247 1.1 pooka memset(&cmd, 0, sizeof(cmd));
4248 1.1 pooka
4249 1.1 pooka iwm_mvm_power_build_cmd(sc, in, &cmd);
4250 1.1 pooka iwm_mvm_power_log(sc, &cmd);
4251 1.1 pooka
4252 1.1 pooka if ((ret = iwm_mvm_send_cmd_pdu(sc, IWM_MAC_PM_POWER_TABLE,
4253 1.1 pooka IWM_CMD_SYNC, sizeof(cmd), &cmd)) != 0)
4254 1.1 pooka return ret;
4255 1.1 pooka
4256 1.1 pooka ba_enable = !!(cmd.flags &
4257 1.1 pooka htole16(IWM_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
4258 1.1 pooka return iwm_mvm_update_beacon_abort(sc, in, ba_enable);
4259 1.1 pooka }
4260 1.1 pooka
4261 1.4 nonaka static int
4262 1.1 pooka iwm_mvm_power_update_device(struct iwm_softc *sc)
4263 1.1 pooka {
4264 1.1 pooka struct iwm_device_power_cmd cmd = {
4265 1.1 pooka .flags = htole16(IWM_DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
4266 1.1 pooka };
4267 1.1 pooka
4268 1.1 pooka if (!(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
4269 1.1 pooka return 0;
4270 1.1 pooka
4271 1.1 pooka cmd.flags |= htole16(IWM_DEVICE_POWER_FLAGS_CAM_MSK);
4272 1.1 pooka DPRINTF(("Sending device power command with flags = 0x%X\n", cmd.flags));
4273 1.1 pooka
4274 1.1 pooka return iwm_mvm_send_cmd_pdu(sc,
4275 1.1 pooka IWM_POWER_TABLE_CMD, IWM_CMD_SYNC, sizeof(cmd), &cmd);
4276 1.1 pooka }
4277 1.1 pooka
4278 1.4 nonaka static int
4279 1.1 pooka iwm_mvm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_node *in)
4280 1.1 pooka {
4281 1.1 pooka struct iwm_beacon_filter_cmd cmd = {
4282 1.1 pooka IWM_BF_CMD_CONFIG_DEFAULTS,
4283 1.1 pooka .bf_enable_beacon_filter = htole32(1),
4284 1.1 pooka };
4285 1.1 pooka int ret;
4286 1.1 pooka
4287 1.1 pooka iwm_mvm_beacon_filter_set_cqm_params(sc, in, &cmd);
4288 1.1 pooka ret = iwm_mvm_beacon_filter_send_cmd(sc, &cmd);
4289 1.1 pooka
4290 1.1 pooka if (ret == 0)
4291 1.1 pooka sc->sc_bf.bf_enabled = 1;
4292 1.1 pooka
4293 1.1 pooka return ret;
4294 1.1 pooka }
4295 1.1 pooka
4296 1.4 nonaka static int
4297 1.1 pooka iwm_mvm_disable_beacon_filter(struct iwm_softc *sc, struct iwm_node *in)
4298 1.1 pooka {
4299 1.1 pooka struct iwm_beacon_filter_cmd cmd;
4300 1.1 pooka int ret;
4301 1.1 pooka
4302 1.1 pooka memset(&cmd, 0, sizeof(cmd));
4303 1.1 pooka if ((sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_BF_UPDATED) == 0)
4304 1.1 pooka return 0;
4305 1.1 pooka
4306 1.1 pooka ret = iwm_mvm_beacon_filter_send_cmd(sc, &cmd);
4307 1.1 pooka if (ret == 0)
4308 1.1 pooka sc->sc_bf.bf_enabled = 0;
4309 1.1 pooka
4310 1.1 pooka return ret;
4311 1.1 pooka }
4312 1.1 pooka
4313 1.1 pooka #if 0
4314 1.4 nonaka static int
4315 1.1 pooka iwm_mvm_update_beacon_filter(struct iwm_softc *sc, struct iwm_node *in)
4316 1.1 pooka {
4317 1.1 pooka if (!sc->sc_bf.bf_enabled)
4318 1.1 pooka return 0;
4319 1.1 pooka
4320 1.1 pooka return iwm_mvm_enable_beacon_filter(sc, in);
4321 1.1 pooka }
4322 1.1 pooka #endif
4323 1.1 pooka
4324 1.1 pooka /*
4325 1.1 pooka * END mvm/power.c
4326 1.1 pooka */
4327 1.1 pooka
4328 1.1 pooka /*
4329 1.1 pooka * BEGIN mvm/sta.c
4330 1.1 pooka */
4331 1.1 pooka
4332 1.4 nonaka static void
4333 1.1 pooka iwm_mvm_add_sta_cmd_v6_to_v5(struct iwm_mvm_add_sta_cmd_v6 *cmd_v6,
4334 1.1 pooka struct iwm_mvm_add_sta_cmd_v5 *cmd_v5)
4335 1.1 pooka {
4336 1.1 pooka memset(cmd_v5, 0, sizeof(*cmd_v5));
4337 1.1 pooka
4338 1.1 pooka cmd_v5->add_modify = cmd_v6->add_modify;
4339 1.1 pooka cmd_v5->tid_disable_tx = cmd_v6->tid_disable_tx;
4340 1.1 pooka cmd_v5->mac_id_n_color = cmd_v6->mac_id_n_color;
4341 1.1 pooka memcpy(cmd_v5->addr, cmd_v6->addr, ETHER_ADDR_LEN);
4342 1.1 pooka cmd_v5->sta_id = cmd_v6->sta_id;
4343 1.1 pooka cmd_v5->modify_mask = cmd_v6->modify_mask;
4344 1.1 pooka cmd_v5->station_flags = cmd_v6->station_flags;
4345 1.1 pooka cmd_v5->station_flags_msk = cmd_v6->station_flags_msk;
4346 1.1 pooka cmd_v5->add_immediate_ba_tid = cmd_v6->add_immediate_ba_tid;
4347 1.1 pooka cmd_v5->remove_immediate_ba_tid = cmd_v6->remove_immediate_ba_tid;
4348 1.1 pooka cmd_v5->add_immediate_ba_ssn = cmd_v6->add_immediate_ba_ssn;
4349 1.1 pooka cmd_v5->sleep_tx_count = cmd_v6->sleep_tx_count;
4350 1.1 pooka cmd_v5->sleep_state_flags = cmd_v6->sleep_state_flags;
4351 1.1 pooka cmd_v5->assoc_id = cmd_v6->assoc_id;
4352 1.1 pooka cmd_v5->beamform_flags = cmd_v6->beamform_flags;
4353 1.1 pooka cmd_v5->tfd_queue_msk = cmd_v6->tfd_queue_msk;
4354 1.1 pooka }
4355 1.1 pooka
4356 1.4 nonaka static int
4357 1.1 pooka iwm_mvm_send_add_sta_cmd_status(struct iwm_softc *sc,
4358 1.1 pooka struct iwm_mvm_add_sta_cmd_v6 *cmd, int *status)
4359 1.1 pooka {
4360 1.1 pooka struct iwm_mvm_add_sta_cmd_v5 cmd_v5;
4361 1.1 pooka
4362 1.1 pooka if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_STA_KEY_CMD) {
4363 1.1 pooka return iwm_mvm_send_cmd_pdu_status(sc, IWM_ADD_STA,
4364 1.1 pooka sizeof(*cmd), cmd, status);
4365 1.1 pooka }
4366 1.1 pooka
4367 1.1 pooka iwm_mvm_add_sta_cmd_v6_to_v5(cmd, &cmd_v5);
4368 1.1 pooka
4369 1.1 pooka return iwm_mvm_send_cmd_pdu_status(sc, IWM_ADD_STA, sizeof(cmd_v5),
4370 1.1 pooka &cmd_v5, status);
4371 1.1 pooka }
4372 1.1 pooka
4373 1.1 pooka /* send station add/update command to firmware */
4374 1.4 nonaka static int
4375 1.1 pooka iwm_mvm_sta_send_to_fw(struct iwm_softc *sc, struct iwm_node *in, int update)
4376 1.1 pooka {
4377 1.1 pooka struct iwm_mvm_add_sta_cmd_v6 add_sta_cmd;
4378 1.1 pooka int ret;
4379 1.1 pooka uint32_t status;
4380 1.1 pooka
4381 1.1 pooka memset(&add_sta_cmd, 0, sizeof(add_sta_cmd));
4382 1.1 pooka
4383 1.1 pooka add_sta_cmd.sta_id = IWM_STATION_ID;
4384 1.1 pooka add_sta_cmd.mac_id_n_color
4385 1.1 pooka = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
4386 1.1 pooka if (!update) {
4387 1.1 pooka add_sta_cmd.tfd_queue_msk = htole32(0xf);
4388 1.1 pooka IEEE80211_ADDR_COPY(&add_sta_cmd.addr, in->in_ni.ni_bssid);
4389 1.1 pooka }
4390 1.1 pooka add_sta_cmd.add_modify = update ? 1 : 0;
4391 1.1 pooka add_sta_cmd.station_flags_msk
4392 1.1 pooka |= htole32(IWM_STA_FLG_FAT_EN_MSK | IWM_STA_FLG_MIMO_EN_MSK);
4393 1.1 pooka
4394 1.1 pooka status = IWM_ADD_STA_SUCCESS;
4395 1.1 pooka ret = iwm_mvm_send_add_sta_cmd_status(sc, &add_sta_cmd, &status);
4396 1.1 pooka if (ret)
4397 1.1 pooka return ret;
4398 1.1 pooka
4399 1.1 pooka switch (status) {
4400 1.1 pooka case IWM_ADD_STA_SUCCESS:
4401 1.1 pooka break;
4402 1.1 pooka default:
4403 1.1 pooka ret = EIO;
4404 1.1 pooka DPRINTF(("IWM_ADD_STA failed\n"));
4405 1.1 pooka break;
4406 1.1 pooka }
4407 1.1 pooka
4408 1.1 pooka return ret;
4409 1.1 pooka }
4410 1.1 pooka
4411 1.4 nonaka static int
4412 1.1 pooka iwm_mvm_add_sta(struct iwm_softc *sc, struct iwm_node *in)
4413 1.1 pooka {
4414 1.1 pooka int ret;
4415 1.1 pooka
4416 1.1 pooka ret = iwm_mvm_sta_send_to_fw(sc, in, 0);
4417 1.1 pooka if (ret)
4418 1.1 pooka return ret;
4419 1.1 pooka
4420 1.1 pooka return 0;
4421 1.1 pooka }
4422 1.1 pooka
4423 1.4 nonaka static int
4424 1.1 pooka iwm_mvm_update_sta(struct iwm_softc *sc, struct iwm_node *in)
4425 1.1 pooka {
4426 1.1 pooka return iwm_mvm_sta_send_to_fw(sc, in, 1);
4427 1.1 pooka }
4428 1.1 pooka
4429 1.4 nonaka static int
4430 1.1 pooka iwm_mvm_add_int_sta_common(struct iwm_softc *sc, struct iwm_int_sta *sta,
4431 1.1 pooka const uint8_t *addr, uint16_t mac_id, uint16_t color)
4432 1.1 pooka {
4433 1.1 pooka struct iwm_mvm_add_sta_cmd_v6 cmd;
4434 1.1 pooka int ret;
4435 1.1 pooka uint32_t status;
4436 1.1 pooka
4437 1.1 pooka memset(&cmd, 0, sizeof(cmd));
4438 1.1 pooka cmd.sta_id = sta->sta_id;
4439 1.1 pooka cmd.mac_id_n_color = htole32(IWM_FW_CMD_ID_AND_COLOR(mac_id, color));
4440 1.1 pooka
4441 1.1 pooka cmd.tfd_queue_msk = htole32(sta->tfd_queue_msk);
4442 1.1 pooka
4443 1.1 pooka if (addr)
4444 1.1 pooka memcpy(cmd.addr, addr, ETHER_ADDR_LEN);
4445 1.1 pooka
4446 1.1 pooka ret = iwm_mvm_send_add_sta_cmd_status(sc, &cmd, &status);
4447 1.1 pooka if (ret)
4448 1.1 pooka return ret;
4449 1.1 pooka
4450 1.1 pooka switch (status) {
4451 1.1 pooka case IWM_ADD_STA_SUCCESS:
4452 1.1 pooka DPRINTF(("Internal station added.\n"));
4453 1.1 pooka return 0;
4454 1.1 pooka default:
4455 1.2 nonaka DPRINTF(("%s: Add internal station failed, status=0x%x\n",
4456 1.2 nonaka DEVNAME(sc), status));
4457 1.1 pooka ret = EIO;
4458 1.1 pooka break;
4459 1.1 pooka }
4460 1.1 pooka return ret;
4461 1.1 pooka }
4462 1.1 pooka
4463 1.4 nonaka static int
4464 1.1 pooka iwm_mvm_add_aux_sta(struct iwm_softc *sc)
4465 1.1 pooka {
4466 1.1 pooka int ret;
4467 1.1 pooka
4468 1.1 pooka sc->sc_aux_sta.sta_id = 3;
4469 1.1 pooka sc->sc_aux_sta.tfd_queue_msk = 0;
4470 1.1 pooka
4471 1.1 pooka ret = iwm_mvm_add_int_sta_common(sc,
4472 1.1 pooka &sc->sc_aux_sta, NULL, IWM_MAC_INDEX_AUX, 0);
4473 1.1 pooka
4474 1.1 pooka if (ret)
4475 1.1 pooka memset(&sc->sc_aux_sta, 0, sizeof(sc->sc_aux_sta));
4476 1.1 pooka return ret;
4477 1.1 pooka }
4478 1.1 pooka
4479 1.1 pooka /*
4480 1.1 pooka * END mvm/sta.c
4481 1.1 pooka */
4482 1.1 pooka
4483 1.1 pooka /*
4484 1.1 pooka * BEGIN mvm/scan.c
4485 1.1 pooka */
4486 1.1 pooka
4487 1.1 pooka #define IWM_PLCP_QUIET_THRESH 1
4488 1.1 pooka #define IWM_ACTIVE_QUIET_TIME 10
4489 1.1 pooka #define LONG_OUT_TIME_PERIOD 600
4490 1.1 pooka #define SHORT_OUT_TIME_PERIOD 200
4491 1.1 pooka #define SUSPEND_TIME_PERIOD 100
4492 1.1 pooka
4493 1.4 nonaka static uint16_t
4494 1.1 pooka iwm_mvm_scan_rx_chain(struct iwm_softc *sc)
4495 1.1 pooka {
4496 1.1 pooka uint16_t rx_chain;
4497 1.1 pooka uint8_t rx_ant;
4498 1.1 pooka
4499 1.1 pooka rx_ant = IWM_FW_VALID_RX_ANT(sc);
4500 1.1 pooka rx_chain = rx_ant << IWM_PHY_RX_CHAIN_VALID_POS;
4501 1.1 pooka rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
4502 1.1 pooka rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_SEL_POS;
4503 1.1 pooka rx_chain |= 0x1 << IWM_PHY_RX_CHAIN_DRIVER_FORCE_POS;
4504 1.1 pooka return htole16(rx_chain);
4505 1.1 pooka }
4506 1.1 pooka
4507 1.1 pooka #define ieee80211_tu_to_usec(a) (1024*(a))
4508 1.1 pooka
4509 1.4 nonaka static uint32_t
4510 1.1 pooka iwm_mvm_scan_max_out_time(struct iwm_softc *sc, uint32_t flags, int is_assoc)
4511 1.1 pooka {
4512 1.1 pooka if (!is_assoc)
4513 1.1 pooka return 0;
4514 1.1 pooka if (flags & 0x1)
4515 1.1 pooka return htole32(ieee80211_tu_to_usec(SHORT_OUT_TIME_PERIOD));
4516 1.1 pooka return htole32(ieee80211_tu_to_usec(LONG_OUT_TIME_PERIOD));
4517 1.1 pooka }
4518 1.1 pooka
4519 1.4 nonaka static uint32_t
4520 1.1 pooka iwm_mvm_scan_suspend_time(struct iwm_softc *sc, int is_assoc)
4521 1.1 pooka {
4522 1.1 pooka if (!is_assoc)
4523 1.1 pooka return 0;
4524 1.1 pooka return htole32(ieee80211_tu_to_usec(SUSPEND_TIME_PERIOD));
4525 1.1 pooka }
4526 1.1 pooka
4527 1.4 nonaka static uint32_t
4528 1.1 pooka iwm_mvm_scan_rxon_flags(struct iwm_softc *sc, int flags)
4529 1.1 pooka {
4530 1.1 pooka if (flags & IEEE80211_CHAN_2GHZ)
4531 1.1 pooka return htole32(IWM_PHY_BAND_24);
4532 1.1 pooka else
4533 1.1 pooka return htole32(IWM_PHY_BAND_5);
4534 1.1 pooka }
4535 1.1 pooka
4536 1.4 nonaka static uint32_t
4537 1.1 pooka iwm_mvm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck)
4538 1.1 pooka {
4539 1.1 pooka uint32_t tx_ant;
4540 1.1 pooka int i, ind;
4541 1.1 pooka
4542 1.1 pooka for (i = 0, ind = sc->sc_scan_last_antenna;
4543 1.1 pooka i < IWM_RATE_MCS_ANT_NUM; i++) {
4544 1.1 pooka ind = (ind + 1) % IWM_RATE_MCS_ANT_NUM;
4545 1.1 pooka if (IWM_FW_VALID_TX_ANT(sc) & (1 << ind)) {
4546 1.1 pooka sc->sc_scan_last_antenna = ind;
4547 1.1 pooka break;
4548 1.1 pooka }
4549 1.1 pooka }
4550 1.1 pooka tx_ant = (1 << sc->sc_scan_last_antenna) << IWM_RATE_MCS_ANT_POS;
4551 1.1 pooka
4552 1.1 pooka if ((flags & IEEE80211_CHAN_2GHZ) && !no_cck)
4553 1.1 pooka return htole32(IWM_RATE_1M_PLCP | IWM_RATE_MCS_CCK_MSK |
4554 1.1 pooka tx_ant);
4555 1.1 pooka else
4556 1.1 pooka return htole32(IWM_RATE_6M_PLCP | tx_ant);
4557 1.1 pooka }
4558 1.1 pooka
4559 1.1 pooka /*
4560 1.1 pooka * If req->n_ssids > 0, it means we should do an active scan.
4561 1.1 pooka * In case of active scan w/o directed scan, we receive a zero-length SSID
4562 1.1 pooka * just to notify that this scan is active and not passive.
4563 1.1 pooka * In order to notify the FW of the number of SSIDs we wish to scan (including
4564 1.1 pooka * the zero-length one), we need to set the corresponding bits in chan->type,
4565 1.1 pooka * one for each SSID, and set the active bit (first). If the first SSID is
4566 1.1 pooka * already included in the probe template, so we need to set only
4567 1.1 pooka * req->n_ssids - 1 bits in addition to the first bit.
4568 1.1 pooka */
4569 1.4 nonaka static uint16_t
4570 1.1 pooka iwm_mvm_get_active_dwell(struct iwm_softc *sc, int flags, int n_ssids)
4571 1.1 pooka {
4572 1.1 pooka if (flags & IEEE80211_CHAN_2GHZ)
4573 1.1 pooka return 30 + 3 * (n_ssids + 1);
4574 1.1 pooka return 20 + 2 * (n_ssids + 1);
4575 1.1 pooka }
4576 1.1 pooka
4577 1.4 nonaka static uint16_t
4578 1.1 pooka iwm_mvm_get_passive_dwell(struct iwm_softc *sc, int flags)
4579 1.1 pooka {
4580 1.1 pooka return (flags & IEEE80211_CHAN_2GHZ) ? 100 + 20 : 100 + 10;
4581 1.1 pooka }
4582 1.1 pooka
4583 1.4 nonaka static int
4584 1.1 pooka iwm_mvm_scan_fill_channels(struct iwm_softc *sc, struct iwm_scan_cmd *cmd,
4585 1.1 pooka int flags, int n_ssids, int basic_ssid)
4586 1.1 pooka {
4587 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
4588 1.1 pooka uint16_t passive_dwell = iwm_mvm_get_passive_dwell(sc, flags);
4589 1.1 pooka uint16_t active_dwell = iwm_mvm_get_active_dwell(sc, flags, n_ssids);
4590 1.1 pooka struct iwm_scan_channel *chan = (struct iwm_scan_channel *)
4591 1.1 pooka (cmd->data + le16toh(cmd->tx_cmd.len));
4592 1.1 pooka int type = (1 << n_ssids) - 1;
4593 1.1 pooka struct ieee80211_channel *c;
4594 1.1 pooka int nchan;
4595 1.1 pooka
4596 1.1 pooka if (!basic_ssid)
4597 1.1 pooka type |= (1 << n_ssids);
4598 1.1 pooka
4599 1.1 pooka for (nchan = 0, c = &ic->ic_channels[1];
4600 1.1 pooka c <= &ic->ic_channels[IEEE80211_CHAN_MAX];
4601 1.1 pooka c++) {
4602 1.1 pooka if ((c->ic_flags & flags) != flags)
4603 1.1 pooka continue;
4604 1.1 pooka
4605 1.1 pooka chan->channel = htole16(ieee80211_mhz2ieee(c->ic_freq, flags));
4606 1.1 pooka chan->type = htole32(type);
4607 1.1 pooka if (c->ic_flags & IEEE80211_CHAN_PASSIVE)
4608 1.1 pooka chan->type &= htole32(~IWM_SCAN_CHANNEL_TYPE_ACTIVE);
4609 1.1 pooka chan->active_dwell = htole16(active_dwell);
4610 1.1 pooka chan->passive_dwell = htole16(passive_dwell);
4611 1.1 pooka chan->iteration_count = htole16(1);
4612 1.1 pooka chan++;
4613 1.1 pooka nchan++;
4614 1.1 pooka }
4615 1.1 pooka if (nchan == 0)
4616 1.2 nonaka DPRINTF(("%s: NO CHANNEL!\n", DEVNAME(sc)));
4617 1.1 pooka return nchan;
4618 1.1 pooka }
4619 1.1 pooka
4620 1.1 pooka /*
4621 1.1 pooka * Fill in probe request with the following parameters:
4622 1.1 pooka * TA is our vif HW address, which mac80211 ensures we have.
4623 1.1 pooka * Packet is broadcasted, so this is both SA and DA.
4624 1.1 pooka * The probe request IE is made out of two: first comes the most prioritized
4625 1.1 pooka * SSID if a directed scan is requested. Second comes whatever extra
4626 1.1 pooka * information was given to us as the scan request IE.
4627 1.1 pooka */
4628 1.4 nonaka static uint16_t
4629 1.1 pooka iwm_mvm_fill_probe_req(struct iwm_softc *sc, struct ieee80211_frame *frame,
4630 1.1 pooka const uint8_t *ta, int n_ssids, const uint8_t *ssid, int ssid_len,
4631 1.1 pooka const uint8_t *ie, int ie_len, int left)
4632 1.1 pooka {
4633 1.1 pooka int len = 0;
4634 1.1 pooka uint8_t *pos = NULL;
4635 1.1 pooka
4636 1.1 pooka /* Make sure there is enough space for the probe request,
4637 1.1 pooka * two mandatory IEs and the data */
4638 1.1 pooka left -= sizeof(*frame);
4639 1.1 pooka if (left < 0)
4640 1.1 pooka return 0;
4641 1.1 pooka
4642 1.1 pooka frame->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
4643 1.1 pooka IEEE80211_FC0_SUBTYPE_PROBE_REQ;
4644 1.1 pooka frame->i_fc[1] = IEEE80211_FC1_DIR_NODS;
4645 1.1 pooka IEEE80211_ADDR_COPY(frame->i_addr1, etherbroadcastaddr);
4646 1.1 pooka memcpy(frame->i_addr2, ta, ETHER_ADDR_LEN);
4647 1.1 pooka IEEE80211_ADDR_COPY(frame->i_addr3, etherbroadcastaddr);
4648 1.1 pooka
4649 1.1 pooka len += sizeof(*frame);
4650 1.1 pooka CTASSERT(sizeof(*frame) == 24);
4651 1.1 pooka
4652 1.1 pooka /* for passive scans, no need to fill anything */
4653 1.1 pooka if (n_ssids == 0)
4654 1.1 pooka return (uint16_t)len;
4655 1.1 pooka
4656 1.1 pooka /* points to the payload of the request */
4657 1.1 pooka pos = (uint8_t *)frame + sizeof(*frame);
4658 1.1 pooka
4659 1.1 pooka /* fill in our SSID IE */
4660 1.1 pooka left -= ssid_len + 2;
4661 1.1 pooka if (left < 0)
4662 1.1 pooka return 0;
4663 1.1 pooka *pos++ = IEEE80211_ELEMID_SSID;
4664 1.1 pooka *pos++ = ssid_len;
4665 1.1 pooka if (ssid && ssid_len) { /* ssid_len may be == 0 even if ssid is valid */
4666 1.1 pooka memcpy(pos, ssid, ssid_len);
4667 1.1 pooka pos += ssid_len;
4668 1.1 pooka }
4669 1.1 pooka
4670 1.1 pooka len += ssid_len + 2;
4671 1.1 pooka
4672 1.1 pooka if (left < ie_len)
4673 1.1 pooka return len;
4674 1.1 pooka
4675 1.1 pooka if (ie && ie_len) {
4676 1.1 pooka memcpy(pos, ie, ie_len);
4677 1.1 pooka len += ie_len;
4678 1.1 pooka }
4679 1.1 pooka
4680 1.1 pooka return (uint16_t)len;
4681 1.1 pooka }
4682 1.1 pooka
4683 1.4 nonaka static int
4684 1.1 pooka iwm_mvm_scan_request(struct iwm_softc *sc, int flags,
4685 1.1 pooka int n_ssids, uint8_t *ssid, int ssid_len)
4686 1.1 pooka {
4687 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
4688 1.1 pooka struct iwm_host_cmd hcmd = {
4689 1.1 pooka .id = IWM_SCAN_REQUEST_CMD,
4690 1.1 pooka .len = { 0, },
4691 1.1 pooka .data = { sc->sc_scan_cmd, },
4692 1.1 pooka .flags = IWM_CMD_SYNC,
4693 1.1 pooka .dataflags = { IWM_HCMD_DFL_NOCOPY, },
4694 1.1 pooka };
4695 1.1 pooka struct iwm_scan_cmd *cmd = sc->sc_scan_cmd;
4696 1.1 pooka int is_assoc = 0;
4697 1.1 pooka int ret;
4698 1.1 pooka uint32_t status;
4699 1.1 pooka int basic_ssid = !(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_NO_BASIC_SSID);
4700 1.1 pooka
4701 1.1 pooka //lockdep_assert_held(&mvm->mutex);
4702 1.1 pooka
4703 1.1 pooka sc->sc_scanband = flags & (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ);
4704 1.1 pooka
4705 1.1 pooka DPRINTF(("Handling ieee80211 scan request\n"));
4706 1.1 pooka memset(cmd, 0, sc->sc_scan_cmd_len);
4707 1.1 pooka
4708 1.1 pooka cmd->quiet_time = htole16(IWM_ACTIVE_QUIET_TIME);
4709 1.1 pooka cmd->quiet_plcp_th = htole16(IWM_PLCP_QUIET_THRESH);
4710 1.1 pooka cmd->rxchain_sel_flags = iwm_mvm_scan_rx_chain(sc);
4711 1.1 pooka cmd->max_out_time = iwm_mvm_scan_max_out_time(sc, 0, is_assoc);
4712 1.1 pooka cmd->suspend_time = iwm_mvm_scan_suspend_time(sc, is_assoc);
4713 1.1 pooka cmd->rxon_flags = iwm_mvm_scan_rxon_flags(sc, flags);
4714 1.1 pooka cmd->filter_flags = htole32(IWM_MAC_FILTER_ACCEPT_GRP |
4715 1.1 pooka IWM_MAC_FILTER_IN_BEACON);
4716 1.1 pooka
4717 1.1 pooka cmd->type = htole32(IWM_SCAN_TYPE_FORCED);
4718 1.1 pooka cmd->repeats = htole32(1);
4719 1.1 pooka
4720 1.1 pooka /*
4721 1.1 pooka * If the user asked for passive scan, don't change to active scan if
4722 1.1 pooka * you see any activity on the channel - remain passive.
4723 1.1 pooka */
4724 1.1 pooka if (n_ssids > 0) {
4725 1.1 pooka cmd->passive2active = htole16(1);
4726 1.1 pooka cmd->scan_flags |= IWM_SCAN_FLAGS_PASSIVE2ACTIVE;
4727 1.1 pooka #if 0
4728 1.1 pooka if (basic_ssid) {
4729 1.1 pooka ssid = req->ssids[0].ssid;
4730 1.1 pooka ssid_len = req->ssids[0].ssid_len;
4731 1.1 pooka }
4732 1.1 pooka #endif
4733 1.1 pooka } else {
4734 1.1 pooka cmd->passive2active = 0;
4735 1.1 pooka cmd->scan_flags &= ~IWM_SCAN_FLAGS_PASSIVE2ACTIVE;
4736 1.1 pooka }
4737 1.1 pooka
4738 1.1 pooka cmd->tx_cmd.tx_flags = htole32(IWM_TX_CMD_FLG_SEQ_CTL |
4739 1.1 pooka IWM_TX_CMD_FLG_BT_DIS);
4740 1.1 pooka cmd->tx_cmd.sta_id = sc->sc_aux_sta.sta_id;
4741 1.1 pooka cmd->tx_cmd.life_time = htole32(IWM_TX_CMD_LIFE_TIME_INFINITE);
4742 1.1 pooka cmd->tx_cmd.rate_n_flags = iwm_mvm_scan_rate_n_flags(sc, flags, 1/*XXX*/);
4743 1.1 pooka
4744 1.1 pooka cmd->tx_cmd.len = htole16(iwm_mvm_fill_probe_req(sc,
4745 1.1 pooka (struct ieee80211_frame *)cmd->data,
4746 1.1 pooka ic->ic_myaddr, n_ssids, ssid, ssid_len,
4747 1.1 pooka NULL, 0, sc->sc_capa_max_probe_len));
4748 1.1 pooka
4749 1.1 pooka cmd->channel_count
4750 1.1 pooka = iwm_mvm_scan_fill_channels(sc, cmd, flags, n_ssids, basic_ssid);
4751 1.1 pooka
4752 1.1 pooka cmd->len = htole16(sizeof(struct iwm_scan_cmd) +
4753 1.1 pooka le16toh(cmd->tx_cmd.len) +
4754 1.1 pooka (cmd->channel_count * sizeof(struct iwm_scan_channel)));
4755 1.1 pooka hcmd.len[0] = le16toh(cmd->len);
4756 1.1 pooka
4757 1.1 pooka status = IWM_SCAN_RESPONSE_OK;
4758 1.1 pooka ret = iwm_mvm_send_cmd_status(sc, &hcmd, &status);
4759 1.1 pooka if (!ret && status == IWM_SCAN_RESPONSE_OK) {
4760 1.1 pooka DPRINTF(("Scan request was sent successfully\n"));
4761 1.1 pooka } else {
4762 1.1 pooka /*
4763 1.1 pooka * If the scan failed, it usually means that the FW was unable
4764 1.1 pooka * to allocate the time events. Warn on it, but maybe we
4765 1.1 pooka * should try to send the command again with different params.
4766 1.1 pooka */
4767 1.1 pooka sc->sc_scanband = 0;
4768 1.1 pooka ret = EIO;
4769 1.1 pooka }
4770 1.1 pooka return ret;
4771 1.1 pooka }
4772 1.1 pooka
4773 1.1 pooka /*
4774 1.1 pooka * END mvm/scan.c
4775 1.1 pooka */
4776 1.1 pooka
4777 1.1 pooka /*
4778 1.1 pooka * BEGIN mvm/mac-ctxt.c
4779 1.1 pooka */
4780 1.1 pooka
4781 1.4 nonaka static void
4782 1.1 pooka iwm_mvm_ack_rates(struct iwm_softc *sc, struct iwm_node *in,
4783 1.1 pooka int *cck_rates, int *ofdm_rates)
4784 1.1 pooka {
4785 1.24 nonaka struct ieee80211_node *ni = &in->in_ni;
4786 1.1 pooka int lowest_present_ofdm = 100;
4787 1.1 pooka int lowest_present_cck = 100;
4788 1.1 pooka uint8_t cck = 0;
4789 1.1 pooka uint8_t ofdm = 0;
4790 1.1 pooka int i;
4791 1.1 pooka
4792 1.24 nonaka if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) {
4793 1.24 nonaka for (i = 0; i <= IWM_LAST_CCK_RATE; i++) {
4794 1.24 nonaka cck |= (1 << i);
4795 1.24 nonaka if (lowest_present_cck > i)
4796 1.24 nonaka lowest_present_cck = i;
4797 1.24 nonaka }
4798 1.1 pooka }
4799 1.1 pooka for (i = IWM_FIRST_OFDM_RATE; i <= IWM_LAST_NON_HT_RATE; i++) {
4800 1.1 pooka int adj = i - IWM_FIRST_OFDM_RATE;
4801 1.1 pooka ofdm |= (1 << adj);
4802 1.20 nonaka if (lowest_present_ofdm > i)
4803 1.20 nonaka lowest_present_ofdm = i;
4804 1.1 pooka }
4805 1.1 pooka
4806 1.1 pooka /*
4807 1.1 pooka * Now we've got the basic rates as bitmaps in the ofdm and cck
4808 1.1 pooka * variables. This isn't sufficient though, as there might not
4809 1.1 pooka * be all the right rates in the bitmap. E.g. if the only basic
4810 1.1 pooka * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps
4811 1.1 pooka * and 6 Mbps because the 802.11-2007 standard says in 9.6:
4812 1.1 pooka *
4813 1.1 pooka * [...] a STA responding to a received frame shall transmit
4814 1.1 pooka * its Control Response frame [...] at the highest rate in the
4815 1.1 pooka * BSSBasicRateSet parameter that is less than or equal to the
4816 1.1 pooka * rate of the immediately previous frame in the frame exchange
4817 1.1 pooka * sequence ([...]) and that is of the same modulation class
4818 1.1 pooka * ([...]) as the received frame. If no rate contained in the
4819 1.1 pooka * BSSBasicRateSet parameter meets these conditions, then the
4820 1.1 pooka * control frame sent in response to a received frame shall be
4821 1.1 pooka * transmitted at the highest mandatory rate of the PHY that is
4822 1.1 pooka * less than or equal to the rate of the received frame, and
4823 1.1 pooka * that is of the same modulation class as the received frame.
4824 1.1 pooka *
4825 1.1 pooka * As a consequence, we need to add all mandatory rates that are
4826 1.1 pooka * lower than all of the basic rates to these bitmaps.
4827 1.1 pooka */
4828 1.1 pooka
4829 1.1 pooka if (IWM_RATE_24M_INDEX < lowest_present_ofdm)
4830 1.1 pooka ofdm |= IWM_RATE_BIT_MSK(24) >> IWM_FIRST_OFDM_RATE;
4831 1.1 pooka if (IWM_RATE_12M_INDEX < lowest_present_ofdm)
4832 1.1 pooka ofdm |= IWM_RATE_BIT_MSK(12) >> IWM_FIRST_OFDM_RATE;
4833 1.1 pooka /* 6M already there or needed so always add */
4834 1.1 pooka ofdm |= IWM_RATE_BIT_MSK(6) >> IWM_FIRST_OFDM_RATE;
4835 1.1 pooka
4836 1.1 pooka /*
4837 1.1 pooka * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP.
4838 1.1 pooka * Note, however:
4839 1.1 pooka * - if no CCK rates are basic, it must be ERP since there must
4840 1.1 pooka * be some basic rates at all, so they're OFDM => ERP PHY
4841 1.1 pooka * (or we're in 5 GHz, and the cck bitmap will never be used)
4842 1.1 pooka * - if 11M is a basic rate, it must be ERP as well, so add 5.5M
4843 1.1 pooka * - if 5.5M is basic, 1M and 2M are mandatory
4844 1.1 pooka * - if 2M is basic, 1M is mandatory
4845 1.1 pooka * - if 1M is basic, that's the only valid ACK rate.
4846 1.1 pooka * As a consequence, it's not as complicated as it sounds, just add
4847 1.1 pooka * any lower rates to the ACK rate bitmap.
4848 1.1 pooka */
4849 1.1 pooka if (IWM_RATE_11M_INDEX < lowest_present_cck)
4850 1.1 pooka cck |= IWM_RATE_BIT_MSK(11) >> IWM_FIRST_CCK_RATE;
4851 1.1 pooka if (IWM_RATE_5M_INDEX < lowest_present_cck)
4852 1.1 pooka cck |= IWM_RATE_BIT_MSK(5) >> IWM_FIRST_CCK_RATE;
4853 1.1 pooka if (IWM_RATE_2M_INDEX < lowest_present_cck)
4854 1.1 pooka cck |= IWM_RATE_BIT_MSK(2) >> IWM_FIRST_CCK_RATE;
4855 1.1 pooka /* 1M already there or needed so always add */
4856 1.1 pooka cck |= IWM_RATE_BIT_MSK(1) >> IWM_FIRST_CCK_RATE;
4857 1.1 pooka
4858 1.1 pooka *cck_rates = cck;
4859 1.1 pooka *ofdm_rates = ofdm;
4860 1.1 pooka }
4861 1.1 pooka
4862 1.4 nonaka static void
4863 1.1 pooka iwm_mvm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in,
4864 1.1 pooka struct iwm_mac_ctx_cmd *cmd, uint32_t action)
4865 1.1 pooka {
4866 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
4867 1.1 pooka struct ieee80211_node *ni = ic->ic_bss;
4868 1.1 pooka int cck_ack_rates, ofdm_ack_rates;
4869 1.1 pooka int i;
4870 1.1 pooka
4871 1.1 pooka cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id,
4872 1.1 pooka in->in_color));
4873 1.1 pooka cmd->action = htole32(action);
4874 1.1 pooka
4875 1.1 pooka cmd->mac_type = htole32(IWM_FW_MAC_TYPE_BSS_STA);
4876 1.1 pooka cmd->tsf_id = htole32(in->in_tsfid);
4877 1.1 pooka
4878 1.1 pooka IEEE80211_ADDR_COPY(cmd->node_addr, ic->ic_myaddr);
4879 1.1 pooka if (in->in_assoc) {
4880 1.1 pooka IEEE80211_ADDR_COPY(cmd->bssid_addr, ni->ni_bssid);
4881 1.1 pooka } else {
4882 1.1 pooka memset(cmd->bssid_addr, 0, sizeof(cmd->bssid_addr));
4883 1.1 pooka }
4884 1.1 pooka iwm_mvm_ack_rates(sc, in, &cck_ack_rates, &ofdm_ack_rates);
4885 1.1 pooka cmd->cck_rates = htole32(cck_ack_rates);
4886 1.1 pooka cmd->ofdm_rates = htole32(ofdm_ack_rates);
4887 1.1 pooka
4888 1.1 pooka cmd->cck_short_preamble
4889 1.1 pooka = htole32((ic->ic_flags & IEEE80211_F_SHPREAMBLE)
4890 1.1 pooka ? IWM_MAC_FLG_SHORT_PREAMBLE : 0);
4891 1.1 pooka cmd->short_slot
4892 1.1 pooka = htole32((ic->ic_flags & IEEE80211_F_SHSLOT)
4893 1.1 pooka ? IWM_MAC_FLG_SHORT_SLOT : 0);
4894 1.1 pooka
4895 1.1 pooka for (i = 0; i < IWM_AC_NUM+1; i++) {
4896 1.1 pooka int txf = i;
4897 1.1 pooka
4898 1.1 pooka cmd->ac[txf].cw_min = htole16(0x0f);
4899 1.1 pooka cmd->ac[txf].cw_max = htole16(0x3f);
4900 1.1 pooka cmd->ac[txf].aifsn = 1;
4901 1.1 pooka cmd->ac[txf].fifos_mask = (1 << txf);
4902 1.1 pooka cmd->ac[txf].edca_txop = 0;
4903 1.1 pooka }
4904 1.1 pooka
4905 1.23 nonaka if (ic->ic_flags & IEEE80211_F_USEPROT)
4906 1.23 nonaka cmd->protection_flags |= htole32(IWM_MAC_PROT_FLG_TGG_PROTECT);
4907 1.1 pooka
4908 1.1 pooka cmd->filter_flags = htole32(IWM_MAC_FILTER_ACCEPT_GRP);
4909 1.1 pooka }
4910 1.1 pooka
4911 1.4 nonaka static int
4912 1.1 pooka iwm_mvm_mac_ctxt_send_cmd(struct iwm_softc *sc, struct iwm_mac_ctx_cmd *cmd)
4913 1.1 pooka {
4914 1.1 pooka int ret = iwm_mvm_send_cmd_pdu(sc, IWM_MAC_CONTEXT_CMD, IWM_CMD_SYNC,
4915 1.1 pooka sizeof(*cmd), cmd);
4916 1.1 pooka if (ret)
4917 1.2 nonaka DPRINTF(("%s: Failed to send MAC context (action:%d): %d\n",
4918 1.2 nonaka DEVNAME(sc), le32toh(cmd->action), ret));
4919 1.1 pooka return ret;
4920 1.1 pooka }
4921 1.1 pooka
4922 1.1 pooka /*
4923 1.1 pooka * Fill the specific data for mac context of type station or p2p client
4924 1.1 pooka */
4925 1.4 nonaka static void
4926 1.1 pooka iwm_mvm_mac_ctxt_cmd_fill_sta(struct iwm_softc *sc, struct iwm_node *in,
4927 1.1 pooka struct iwm_mac_data_sta *ctxt_sta, int force_assoc_off)
4928 1.1 pooka {
4929 1.1 pooka struct ieee80211_node *ni = &in->in_ni;
4930 1.1 pooka unsigned dtim_period, dtim_count;
4931 1.1 pooka
4932 1.1 pooka dtim_period = ni->ni_dtim_period;
4933 1.1 pooka dtim_count = ni->ni_dtim_count;
4934 1.1 pooka
4935 1.1 pooka /* We need the dtim_period to set the MAC as associated */
4936 1.1 pooka if (in->in_assoc && dtim_period && !force_assoc_off) {
4937 1.1 pooka uint64_t tsf;
4938 1.1 pooka uint32_t dtim_offs;
4939 1.1 pooka
4940 1.1 pooka /*
4941 1.1 pooka * The DTIM count counts down, so when it is N that means N
4942 1.1 pooka * more beacon intervals happen until the DTIM TBTT. Therefore
4943 1.1 pooka * add this to the current time. If that ends up being in the
4944 1.1 pooka * future, the firmware will handle it.
4945 1.1 pooka *
4946 1.1 pooka * Also note that the system_timestamp (which we get here as
4947 1.1 pooka * "sync_device_ts") and TSF timestamp aren't at exactly the
4948 1.1 pooka * same offset in the frame -- the TSF is at the first symbol
4949 1.1 pooka * of the TSF, the system timestamp is at signal acquisition
4950 1.1 pooka * time. This means there's an offset between them of at most
4951 1.1 pooka * a few hundred microseconds (24 * 8 bits + PLCP time gives
4952 1.1 pooka * 384us in the longest case), this is currently not relevant
4953 1.1 pooka * as the firmware wakes up around 2ms before the TBTT.
4954 1.1 pooka */
4955 1.1 pooka dtim_offs = dtim_count * ni->ni_intval;
4956 1.1 pooka /* convert TU to usecs */
4957 1.1 pooka dtim_offs *= 1024;
4958 1.1 pooka
4959 1.1 pooka tsf = ni->ni_tstamp.tsf;
4960 1.1 pooka
4961 1.1 pooka ctxt_sta->dtim_tsf = htole64(tsf + dtim_offs);
4962 1.1 pooka ctxt_sta->dtim_time = htole64(ni->ni_rstamp + dtim_offs);
4963 1.1 pooka
4964 1.1 pooka DPRINTF(("DTIM TBTT is 0x%llx/0x%x, offset %d\n",
4965 1.1 pooka (long long)le64toh(ctxt_sta->dtim_tsf),
4966 1.1 pooka le32toh(ctxt_sta->dtim_time), dtim_offs));
4967 1.1 pooka
4968 1.1 pooka ctxt_sta->is_assoc = htole32(1);
4969 1.1 pooka } else {
4970 1.1 pooka ctxt_sta->is_assoc = htole32(0);
4971 1.1 pooka }
4972 1.1 pooka
4973 1.1 pooka ctxt_sta->bi = htole32(ni->ni_intval);
4974 1.1 pooka ctxt_sta->bi_reciprocal = htole32(iwm_mvm_reciprocal(ni->ni_intval));
4975 1.1 pooka ctxt_sta->dtim_interval = htole32(ni->ni_intval * dtim_period);
4976 1.1 pooka ctxt_sta->dtim_reciprocal =
4977 1.1 pooka htole32(iwm_mvm_reciprocal(ni->ni_intval * dtim_period));
4978 1.1 pooka
4979 1.1 pooka /* 10 = CONN_MAX_LISTEN_INTERVAL */
4980 1.1 pooka ctxt_sta->listen_interval = htole32(10);
4981 1.1 pooka ctxt_sta->assoc_id = htole32(ni->ni_associd);
4982 1.1 pooka }
4983 1.1 pooka
4984 1.4 nonaka static int
4985 1.1 pooka iwm_mvm_mac_ctxt_cmd_station(struct iwm_softc *sc, struct iwm_node *in,
4986 1.1 pooka uint32_t action)
4987 1.1 pooka {
4988 1.1 pooka struct iwm_mac_ctx_cmd cmd;
4989 1.1 pooka
4990 1.1 pooka memset(&cmd, 0, sizeof(cmd));
4991 1.1 pooka
4992 1.1 pooka /* Fill the common data for all mac context types */
4993 1.1 pooka iwm_mvm_mac_ctxt_cmd_common(sc, in, &cmd, action);
4994 1.1 pooka
4995 1.25 nonaka /* Allow beacons to pass through as long as we are not associated,or we
4996 1.25 nonaka * do not have dtim period information */
4997 1.25 nonaka if (!in->in_assoc || !sc->sc_ic.ic_dtim_period)
4998 1.1 pooka cmd.filter_flags |= htole32(IWM_MAC_FILTER_IN_BEACON);
4999 1.1 pooka else
5000 1.1 pooka cmd.filter_flags &= ~htole32(IWM_MAC_FILTER_IN_BEACON);
5001 1.1 pooka
5002 1.1 pooka /* Fill the data specific for station mode */
5003 1.1 pooka iwm_mvm_mac_ctxt_cmd_fill_sta(sc, in,
5004 1.1 pooka &cmd.sta, action == IWM_FW_CTXT_ACTION_ADD);
5005 1.1 pooka
5006 1.1 pooka return iwm_mvm_mac_ctxt_send_cmd(sc, &cmd);
5007 1.1 pooka }
5008 1.1 pooka
5009 1.4 nonaka static int
5010 1.1 pooka iwm_mvm_mac_ctx_send(struct iwm_softc *sc, struct iwm_node *in, uint32_t action)
5011 1.1 pooka {
5012 1.1 pooka return iwm_mvm_mac_ctxt_cmd_station(sc, in, action);
5013 1.1 pooka }
5014 1.1 pooka
5015 1.4 nonaka static int
5016 1.1 pooka iwm_mvm_mac_ctxt_add(struct iwm_softc *sc, struct iwm_node *in)
5017 1.1 pooka {
5018 1.1 pooka int ret;
5019 1.1 pooka
5020 1.1 pooka ret = iwm_mvm_mac_ctx_send(sc, in, IWM_FW_CTXT_ACTION_ADD);
5021 1.1 pooka if (ret)
5022 1.1 pooka return ret;
5023 1.1 pooka
5024 1.1 pooka return 0;
5025 1.1 pooka }
5026 1.1 pooka
5027 1.4 nonaka static int
5028 1.1 pooka iwm_mvm_mac_ctxt_changed(struct iwm_softc *sc, struct iwm_node *in)
5029 1.1 pooka {
5030 1.1 pooka return iwm_mvm_mac_ctx_send(sc, in, IWM_FW_CTXT_ACTION_MODIFY);
5031 1.1 pooka }
5032 1.1 pooka
5033 1.1 pooka #if 0
5034 1.4 nonaka static int
5035 1.1 pooka iwm_mvm_mac_ctxt_remove(struct iwm_softc *sc, struct iwm_node *in)
5036 1.1 pooka {
5037 1.1 pooka struct iwm_mac_ctx_cmd cmd;
5038 1.1 pooka int ret;
5039 1.1 pooka
5040 1.1 pooka if (!in->in_uploaded) {
5041 1.1 pooka print("%s: attempt to remove !uploaded node %p", DEVNAME(sc), in);
5042 1.1 pooka return EIO;
5043 1.1 pooka }
5044 1.1 pooka
5045 1.1 pooka memset(&cmd, 0, sizeof(cmd));
5046 1.1 pooka
5047 1.1 pooka cmd.id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id,
5048 1.1 pooka in->in_color));
5049 1.1 pooka cmd.action = htole32(IWM_FW_CTXT_ACTION_REMOVE);
5050 1.1 pooka
5051 1.1 pooka ret = iwm_mvm_send_cmd_pdu(sc,
5052 1.1 pooka IWM_MAC_CONTEXT_CMD, IWM_CMD_SYNC, sizeof(cmd), &cmd);
5053 1.1 pooka if (ret) {
5054 1.3 nonaka aprint_error_dev(sc->sc_dev,
5055 1.3 nonaka "Failed to remove MAC context: %d\n", ret);
5056 1.1 pooka return ret;
5057 1.1 pooka }
5058 1.1 pooka in->in_uploaded = 0;
5059 1.1 pooka
5060 1.1 pooka return 0;
5061 1.1 pooka }
5062 1.1 pooka #endif
5063 1.1 pooka
5064 1.1 pooka #define IWM_MVM_MISSED_BEACONS_THRESHOLD 8
5065 1.1 pooka
5066 1.1 pooka static void
5067 1.1 pooka iwm_mvm_rx_missed_beacons_notif(struct iwm_softc *sc,
5068 1.1 pooka struct iwm_rx_packet *pkt, struct iwm_rx_data *data)
5069 1.1 pooka {
5070 1.1 pooka struct iwm_missed_beacons_notif *mb = (void *)pkt->data;
5071 1.1 pooka
5072 1.1 pooka DPRINTF(("missed bcn mac_id=%u, consecutive=%u (%u, %u, %u)\n",
5073 1.1 pooka le32toh(mb->mac_id),
5074 1.1 pooka le32toh(mb->consec_missed_beacons),
5075 1.1 pooka le32toh(mb->consec_missed_beacons_since_last_rx),
5076 1.1 pooka le32toh(mb->num_recvd_beacons),
5077 1.1 pooka le32toh(mb->num_expected_beacons)));
5078 1.1 pooka
5079 1.1 pooka /*
5080 1.1 pooka * TODO: the threshold should be adjusted based on latency conditions,
5081 1.1 pooka * and/or in case of a CS flow on one of the other AP vifs.
5082 1.1 pooka */
5083 1.1 pooka if (le32toh(mb->consec_missed_beacons_since_last_rx) >
5084 1.1 pooka IWM_MVM_MISSED_BEACONS_THRESHOLD)
5085 1.1 pooka ieee80211_beacon_miss(&sc->sc_ic);
5086 1.1 pooka }
5087 1.1 pooka
5088 1.1 pooka /*
5089 1.1 pooka * END mvm/mac-ctxt.c
5090 1.1 pooka */
5091 1.1 pooka
5092 1.1 pooka /*
5093 1.1 pooka * BEGIN mvm/quota.c
5094 1.1 pooka */
5095 1.1 pooka
5096 1.4 nonaka static int
5097 1.1 pooka iwm_mvm_update_quotas(struct iwm_softc *sc, struct iwm_node *in)
5098 1.1 pooka {
5099 1.1 pooka struct iwm_time_quota_cmd cmd;
5100 1.1 pooka int i, idx, ret, num_active_macs, quota, quota_rem;
5101 1.1 pooka int colors[IWM_MAX_BINDINGS] = { -1, -1, -1, -1, };
5102 1.1 pooka int n_ifs[IWM_MAX_BINDINGS] = {0, };
5103 1.1 pooka uint16_t id;
5104 1.1 pooka
5105 1.1 pooka memset(&cmd, 0, sizeof(cmd));
5106 1.1 pooka
5107 1.1 pooka /* currently, PHY ID == binding ID */
5108 1.1 pooka if (in) {
5109 1.1 pooka id = in->in_phyctxt->id;
5110 1.1 pooka KASSERT(id < IWM_MAX_BINDINGS);
5111 1.1 pooka colors[id] = in->in_phyctxt->color;
5112 1.1 pooka
5113 1.1 pooka if (1)
5114 1.1 pooka n_ifs[id] = 1;
5115 1.1 pooka }
5116 1.1 pooka
5117 1.1 pooka /*
5118 1.1 pooka * The FW's scheduling session consists of
5119 1.1 pooka * IWM_MVM_MAX_QUOTA fragments. Divide these fragments
5120 1.1 pooka * equally between all the bindings that require quota
5121 1.1 pooka */
5122 1.1 pooka num_active_macs = 0;
5123 1.1 pooka for (i = 0; i < IWM_MAX_BINDINGS; i++) {
5124 1.1 pooka cmd.quotas[i].id_and_color = htole32(IWM_FW_CTXT_INVALID);
5125 1.1 pooka num_active_macs += n_ifs[i];
5126 1.1 pooka }
5127 1.1 pooka
5128 1.1 pooka quota = 0;
5129 1.1 pooka quota_rem = 0;
5130 1.1 pooka if (num_active_macs) {
5131 1.1 pooka quota = IWM_MVM_MAX_QUOTA / num_active_macs;
5132 1.1 pooka quota_rem = IWM_MVM_MAX_QUOTA % num_active_macs;
5133 1.1 pooka }
5134 1.1 pooka
5135 1.1 pooka for (idx = 0, i = 0; i < IWM_MAX_BINDINGS; i++) {
5136 1.1 pooka if (colors[i] < 0)
5137 1.1 pooka continue;
5138 1.1 pooka
5139 1.1 pooka cmd.quotas[idx].id_and_color =
5140 1.1 pooka htole32(IWM_FW_CMD_ID_AND_COLOR(i, colors[i]));
5141 1.1 pooka
5142 1.1 pooka if (n_ifs[i] <= 0) {
5143 1.1 pooka cmd.quotas[idx].quota = htole32(0);
5144 1.1 pooka cmd.quotas[idx].max_duration = htole32(0);
5145 1.1 pooka } else {
5146 1.1 pooka cmd.quotas[idx].quota = htole32(quota * n_ifs[i]);
5147 1.1 pooka cmd.quotas[idx].max_duration = htole32(0);
5148 1.1 pooka }
5149 1.1 pooka idx++;
5150 1.1 pooka }
5151 1.1 pooka
5152 1.1 pooka /* Give the remainder of the session to the first binding */
5153 1.1 pooka cmd.quotas[0].quota = htole32(le32toh(cmd.quotas[0].quota) + quota_rem);
5154 1.1 pooka
5155 1.1 pooka ret = iwm_mvm_send_cmd_pdu(sc, IWM_TIME_QUOTA_CMD, IWM_CMD_SYNC,
5156 1.1 pooka sizeof(cmd), &cmd);
5157 1.1 pooka if (ret)
5158 1.2 nonaka DPRINTF(("%s: Failed to send quota: %d\n", DEVNAME(sc), ret));
5159 1.1 pooka return ret;
5160 1.1 pooka }
5161 1.1 pooka
5162 1.1 pooka /*
5163 1.1 pooka * END mvm/quota.c
5164 1.1 pooka */
5165 1.1 pooka
5166 1.1 pooka /*
5167 1.1 pooka * aieee80211 routines
5168 1.1 pooka */
5169 1.1 pooka
5170 1.1 pooka /*
5171 1.1 pooka * Change to AUTH state in 80211 state machine. Roughly matches what
5172 1.1 pooka * Linux does in bss_info_changed().
5173 1.1 pooka */
5174 1.4 nonaka static int
5175 1.1 pooka iwm_auth(struct iwm_softc *sc)
5176 1.1 pooka {
5177 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5178 1.1 pooka struct iwm_node *in = (void *)ic->ic_bss;
5179 1.1 pooka uint32_t duration;
5180 1.1 pooka uint32_t min_duration;
5181 1.1 pooka int error;
5182 1.1 pooka
5183 1.1 pooka in->in_assoc = 0;
5184 1.11 nonaka
5185 1.11 nonaka if ((error = iwm_allow_mcast(sc)) != 0)
5186 1.11 nonaka return error;
5187 1.11 nonaka
5188 1.1 pooka if ((error = iwm_mvm_mac_ctxt_add(sc, in)) != 0) {
5189 1.2 nonaka DPRINTF(("%s: failed to add MAC\n", DEVNAME(sc)));
5190 1.1 pooka return error;
5191 1.1 pooka }
5192 1.1 pooka
5193 1.1 pooka if ((error = iwm_mvm_phy_ctxt_changed(sc, &sc->sc_phyctxt[0],
5194 1.1 pooka in->in_ni.ni_chan, 1, 1)) != 0) {
5195 1.2 nonaka DPRINTF(("%s: failed add phy ctxt\n", DEVNAME(sc)));
5196 1.1 pooka return error;
5197 1.1 pooka }
5198 1.1 pooka in->in_phyctxt = &sc->sc_phyctxt[0];
5199 1.1 pooka
5200 1.1 pooka if ((error = iwm_mvm_binding_add_vif(sc, in)) != 0) {
5201 1.2 nonaka DPRINTF(("%s: binding cmd\n", DEVNAME(sc)));
5202 1.1 pooka return error;
5203 1.1 pooka }
5204 1.1 pooka
5205 1.1 pooka if ((error = iwm_mvm_add_sta(sc, in)) != 0) {
5206 1.2 nonaka DPRINTF(("%s: failed to add MAC\n", DEVNAME(sc)));
5207 1.1 pooka return error;
5208 1.1 pooka }
5209 1.1 pooka
5210 1.1 pooka /* a bit superfluous? */
5211 1.1 pooka while (sc->sc_auth_prot)
5212 1.1 pooka tsleep(&sc->sc_auth_prot, 0, "iwmauth", 0);
5213 1.1 pooka sc->sc_auth_prot = 1;
5214 1.8 nonaka
5215 1.1 pooka duration = min(IWM_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS,
5216 1.1 pooka 200 + in->in_ni.ni_intval);
5217 1.1 pooka min_duration = min(IWM_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS,
5218 1.1 pooka 100 + in->in_ni.ni_intval);
5219 1.1 pooka iwm_mvm_protect_session(sc, in, duration, min_duration, 500);
5220 1.1 pooka
5221 1.1 pooka while (sc->sc_auth_prot != 2) {
5222 1.1 pooka /*
5223 1.1 pooka * well, meh, but if the kernel is sleeping for half a
5224 1.1 pooka * second, we have bigger problems
5225 1.1 pooka */
5226 1.1 pooka if (sc->sc_auth_prot == 0) {
5227 1.2 nonaka DPRINTF(("%s: missed auth window!\n", DEVNAME(sc)));
5228 1.1 pooka return ETIMEDOUT;
5229 1.1 pooka } else if (sc->sc_auth_prot == -1) {
5230 1.2 nonaka DPRINTF(("%s: no time event, denied!\n", DEVNAME(sc)));
5231 1.1 pooka sc->sc_auth_prot = 0;
5232 1.1 pooka return EAUTH;
5233 1.1 pooka }
5234 1.1 pooka tsleep(&sc->sc_auth_prot, 0, "iwmau2", 0);
5235 1.1 pooka }
5236 1.1 pooka
5237 1.1 pooka return 0;
5238 1.1 pooka }
5239 1.1 pooka
5240 1.4 nonaka static int
5241 1.1 pooka iwm_assoc(struct iwm_softc *sc)
5242 1.1 pooka {
5243 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5244 1.1 pooka struct iwm_node *in = (void *)ic->ic_bss;
5245 1.1 pooka int error;
5246 1.1 pooka
5247 1.1 pooka if ((error = iwm_mvm_update_sta(sc, in)) != 0) {
5248 1.2 nonaka DPRINTF(("%s: failed to update STA\n", DEVNAME(sc)));
5249 1.1 pooka return error;
5250 1.1 pooka }
5251 1.1 pooka
5252 1.1 pooka in->in_assoc = 1;
5253 1.1 pooka if ((error = iwm_mvm_mac_ctxt_changed(sc, in)) != 0) {
5254 1.2 nonaka DPRINTF(("%s: failed to update MAC\n", DEVNAME(sc)));
5255 1.1 pooka return error;
5256 1.1 pooka }
5257 1.1 pooka
5258 1.1 pooka return 0;
5259 1.1 pooka }
5260 1.1 pooka
5261 1.4 nonaka static int
5262 1.1 pooka iwm_release(struct iwm_softc *sc, struct iwm_node *in)
5263 1.1 pooka {
5264 1.1 pooka /*
5265 1.1 pooka * Ok, so *technically* the proper set of calls for going
5266 1.1 pooka * from RUN back to SCAN is:
5267 1.1 pooka *
5268 1.1 pooka * iwm_mvm_power_mac_disable(sc, in);
5269 1.1 pooka * iwm_mvm_mac_ctxt_changed(sc, in);
5270 1.1 pooka * iwm_mvm_rm_sta(sc, in);
5271 1.1 pooka * iwm_mvm_update_quotas(sc, NULL);
5272 1.1 pooka * iwm_mvm_mac_ctxt_changed(sc, in);
5273 1.1 pooka * iwm_mvm_binding_remove_vif(sc, in);
5274 1.1 pooka * iwm_mvm_mac_ctxt_remove(sc, in);
5275 1.1 pooka *
5276 1.1 pooka * However, that freezes the device not matter which permutations
5277 1.1 pooka * and modifications are attempted. Obviously, this driver is missing
5278 1.1 pooka * something since it works in the Linux driver, but figuring out what
5279 1.1 pooka * is missing is a little more complicated. Now, since we're going
5280 1.1 pooka * back to nothing anyway, we'll just do a complete device reset.
5281 1.1 pooka * Up your's, device!
5282 1.1 pooka */
5283 1.1 pooka //iwm_mvm_flush_tx_path(sc, 0xf, 1);
5284 1.1 pooka iwm_stop_device(sc);
5285 1.1 pooka iwm_init_hw(sc);
5286 1.1 pooka if (in)
5287 1.1 pooka in->in_assoc = 0;
5288 1.1 pooka return 0;
5289 1.1 pooka
5290 1.1 pooka #if 0
5291 1.1 pooka int error;
5292 1.1 pooka
5293 1.1 pooka iwm_mvm_power_mac_disable(sc, in);
5294 1.1 pooka
5295 1.1 pooka if ((error = iwm_mvm_mac_ctxt_changed(sc, in)) != 0) {
5296 1.3 nonaka aprint_error_dev(sc->sc_dev, "mac ctxt change fail 1 %d\n",
5297 1.3 nonaka error);
5298 1.1 pooka return error;
5299 1.1 pooka }
5300 1.1 pooka
5301 1.1 pooka if ((error = iwm_mvm_rm_sta(sc, in)) != 0) {
5302 1.3 nonaka aprint_error_dev(sc->sc_dev, "sta remove fail %d\n", error);
5303 1.1 pooka return error;
5304 1.1 pooka }
5305 1.1 pooka error = iwm_mvm_rm_sta(sc, in);
5306 1.1 pooka in->in_assoc = 0;
5307 1.1 pooka iwm_mvm_update_quotas(sc, NULL);
5308 1.1 pooka if ((error = iwm_mvm_mac_ctxt_changed(sc, in)) != 0) {
5309 1.3 nonaka aprint_error_dev(sc->sc_dev, "mac ctxt change fail 2 %d\n",
5310 1.3 nonaka error);
5311 1.1 pooka return error;
5312 1.1 pooka }
5313 1.1 pooka iwm_mvm_binding_remove_vif(sc, in);
5314 1.1 pooka
5315 1.1 pooka iwm_mvm_mac_ctxt_remove(sc, in);
5316 1.1 pooka
5317 1.1 pooka return error;
5318 1.1 pooka #endif
5319 1.1 pooka }
5320 1.1 pooka
5321 1.1 pooka
5322 1.1 pooka static struct ieee80211_node *
5323 1.1 pooka iwm_node_alloc(struct ieee80211_node_table *nt)
5324 1.1 pooka {
5325 1.5 nonaka return malloc(sizeof(struct iwm_node), M_80211_NODE, M_NOWAIT | M_ZERO);
5326 1.1 pooka }
5327 1.1 pooka
5328 1.4 nonaka static void
5329 1.1 pooka iwm_calib_timeout(void *arg)
5330 1.1 pooka {
5331 1.1 pooka struct iwm_softc *sc = arg;
5332 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5333 1.1 pooka int s;
5334 1.1 pooka
5335 1.1 pooka s = splnet();
5336 1.1 pooka if (ic->ic_fixed_rate == -1
5337 1.1 pooka && ic->ic_opmode == IEEE80211_M_STA
5338 1.1 pooka && ic->ic_bss) {
5339 1.1 pooka struct iwm_node *in = (void *)ic->ic_bss;
5340 1.1 pooka ieee80211_amrr_choose(&sc->sc_amrr, &in->in_ni, &in->in_amn);
5341 1.1 pooka }
5342 1.1 pooka splx(s);
5343 1.1 pooka
5344 1.1 pooka callout_schedule(&sc->sc_calib_to, hz/2);
5345 1.1 pooka }
5346 1.1 pooka
5347 1.4 nonaka static void
5348 1.1 pooka iwm_setrates(struct iwm_node *in)
5349 1.1 pooka {
5350 1.1 pooka struct ieee80211_node *ni = &in->in_ni;
5351 1.1 pooka struct ieee80211com *ic = ni->ni_ic;
5352 1.1 pooka struct iwm_softc *sc = IC2IFP(ic)->if_softc;
5353 1.1 pooka struct iwm_lq_cmd *lq = &in->in_lq;
5354 1.1 pooka int nrates = ni->ni_rates.rs_nrates;
5355 1.1 pooka int i, ridx, tab = 0;
5356 1.1 pooka int txant = 0;
5357 1.1 pooka
5358 1.14 christos if (nrates > __arraycount(lq->rs_table) ||
5359 1.14 christos nrates > IEEE80211_RATE_MAXSIZE) {
5360 1.2 nonaka DPRINTF(("%s: node supports %d rates, driver handles only "
5361 1.2 nonaka "%zu\n", DEVNAME(sc), nrates, __arraycount(lq->rs_table)));
5362 1.1 pooka return;
5363 1.1 pooka }
5364 1.1 pooka
5365 1.1 pooka /* first figure out which rates we should support */
5366 1.1 pooka memset(&in->in_ridx, -1, sizeof(in->in_ridx));
5367 1.1 pooka for (i = 0; i < nrates; i++) {
5368 1.1 pooka int rate = ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL;
5369 1.8 nonaka
5370 1.1 pooka /* Map 802.11 rate to HW rate index. */
5371 1.1 pooka for (ridx = 0; ridx <= IWM_RIDX_MAX; ridx++)
5372 1.1 pooka if (iwm_rates[ridx].rate == rate)
5373 1.1 pooka break;
5374 1.1 pooka if (ridx > IWM_RIDX_MAX)
5375 1.2 nonaka DPRINTF(("%s: WARNING: device rate for %d not found!\n",
5376 1.2 nonaka DEVNAME(sc), rate));
5377 1.13 nonaka else
5378 1.12 nonaka in->in_ridx[i] = ridx;
5379 1.1 pooka }
5380 1.1 pooka
5381 1.1 pooka /* then construct a lq_cmd based on those */
5382 1.1 pooka memset(lq, 0, sizeof(*lq));
5383 1.1 pooka lq->sta_id = IWM_STATION_ID;
5384 1.1 pooka
5385 1.1 pooka /*
5386 1.1 pooka * are these used? (we don't do SISO or MIMO)
5387 1.1 pooka * need to set them to non-zero, though, or we get an error.
5388 1.1 pooka */
5389 1.1 pooka lq->single_stream_ant_msk = 1;
5390 1.1 pooka lq->dual_stream_ant_msk = 1;
5391 1.1 pooka
5392 1.1 pooka /*
5393 1.1 pooka * Build the actual rate selection table.
5394 1.1 pooka * The lowest bits are the rates. Additionally,
5395 1.1 pooka * CCK needs bit 9 to be set. The rest of the bits
5396 1.1 pooka * we add to the table select the tx antenna
5397 1.1 pooka * Note that we add the rates in the highest rate first
5398 1.1 pooka * (opposite of ni_rates).
5399 1.1 pooka */
5400 1.1 pooka for (i = 0; i < nrates; i++) {
5401 1.1 pooka int nextant;
5402 1.1 pooka
5403 1.1 pooka if (txant == 0)
5404 1.1 pooka txant = IWM_FW_VALID_TX_ANT(sc);
5405 1.1 pooka nextant = 1<<(ffs(txant)-1);
5406 1.1 pooka txant &= ~nextant;
5407 1.1 pooka
5408 1.1 pooka ridx = in->in_ridx[(nrates-1)-i];
5409 1.1 pooka tab = iwm_rates[ridx].plcp;
5410 1.1 pooka tab |= nextant << IWM_RATE_MCS_ANT_POS;
5411 1.1 pooka if (IWM_RIDX_IS_CCK(ridx))
5412 1.1 pooka tab |= IWM_RATE_MCS_CCK_MSK;
5413 1.1 pooka DPRINTFN(2, ("station rate %d %x\n", i, tab));
5414 1.1 pooka lq->rs_table[i] = htole32(tab);
5415 1.1 pooka }
5416 1.1 pooka /* then fill the rest with the lowest possible rate */
5417 1.1 pooka for (i = nrates; i < __arraycount(lq->rs_table); i++) {
5418 1.1 pooka KASSERT(tab != 0);
5419 1.1 pooka lq->rs_table[i] = htole32(tab);
5420 1.1 pooka }
5421 1.1 pooka
5422 1.1 pooka /* init amrr */
5423 1.1 pooka ieee80211_amrr_node_init(&sc->sc_amrr, &in->in_amn);
5424 1.18 nonaka /* Start at lowest available bit-rate, AMRR will raise. */
5425 1.18 nonaka ni->ni_txrate = 0;
5426 1.1 pooka }
5427 1.1 pooka
5428 1.4 nonaka static int
5429 1.1 pooka iwm_media_change(struct ifnet *ifp)
5430 1.1 pooka {
5431 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
5432 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5433 1.1 pooka uint8_t rate, ridx;
5434 1.1 pooka int error;
5435 1.1 pooka
5436 1.1 pooka error = ieee80211_media_change(ifp);
5437 1.1 pooka if (error != ENETRESET)
5438 1.1 pooka return error;
5439 1.1 pooka
5440 1.1 pooka if (ic->ic_fixed_rate != -1) {
5441 1.1 pooka rate = ic->ic_sup_rates[ic->ic_curmode].
5442 1.1 pooka rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
5443 1.1 pooka /* Map 802.11 rate to HW rate index. */
5444 1.1 pooka for (ridx = 0; ridx <= IWM_RIDX_MAX; ridx++)
5445 1.1 pooka if (iwm_rates[ridx].rate == rate)
5446 1.1 pooka break;
5447 1.1 pooka sc->sc_fixed_ridx = ridx;
5448 1.1 pooka }
5449 1.1 pooka
5450 1.1 pooka if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
5451 1.1 pooka (IFF_UP | IFF_RUNNING)) {
5452 1.1 pooka iwm_stop(ifp, 0);
5453 1.1 pooka error = iwm_init(ifp);
5454 1.1 pooka }
5455 1.1 pooka return error;
5456 1.1 pooka }
5457 1.1 pooka
5458 1.4 nonaka static void
5459 1.5 nonaka iwm_newstate_cb(struct work *wk, void *v)
5460 1.1 pooka {
5461 1.5 nonaka struct iwm_softc *sc = v;
5462 1.5 nonaka struct ieee80211com *ic = &sc->sc_ic;
5463 1.1 pooka struct iwm_newstate_state *iwmns = (void *)wk;
5464 1.1 pooka enum ieee80211_state nstate = iwmns->ns_nstate;
5465 1.1 pooka int generation = iwmns->ns_generation;
5466 1.1 pooka struct iwm_node *in;
5467 1.1 pooka int arg = iwmns->ns_arg;
5468 1.1 pooka int error;
5469 1.1 pooka
5470 1.1 pooka kmem_free(iwmns, sizeof(*iwmns));
5471 1.1 pooka
5472 1.1 pooka DPRINTF(("Prepare to switch state %d->%d\n", ic->ic_state, nstate));
5473 1.1 pooka if (sc->sc_generation != generation) {
5474 1.1 pooka DPRINTF(("newstate_cb: someone pulled the plug meanwhile\n"));
5475 1.1 pooka if (nstate == IEEE80211_S_INIT) {
5476 1.1 pooka DPRINTF(("newstate_cb: nstate == IEEE80211_S_INIT: calling sc_newstate()\n"));
5477 1.1 pooka sc->sc_newstate(ic, nstate, arg);
5478 1.1 pooka }
5479 1.1 pooka return;
5480 1.1 pooka }
5481 1.1 pooka
5482 1.1 pooka DPRINTF(("switching state %d->%d\n", ic->ic_state, nstate));
5483 1.1 pooka
5484 1.1 pooka /* disable beacon filtering if we're hopping out of RUN */
5485 1.1 pooka if (ic->ic_state == IEEE80211_S_RUN && nstate != ic->ic_state) {
5486 1.1 pooka iwm_mvm_disable_beacon_filter(sc, (void *)ic->ic_bss);
5487 1.1 pooka
5488 1.1 pooka if (((in = (void *)ic->ic_bss) != NULL))
5489 1.1 pooka in->in_assoc = 0;
5490 1.1 pooka iwm_release(sc, NULL);
5491 1.1 pooka
5492 1.1 pooka /*
5493 1.1 pooka * It's impossible to directly go RUN->SCAN. If we iwm_release()
5494 1.1 pooka * above then the card will be completely reinitialized,
5495 1.1 pooka * so the driver must do everything necessary to bring the card
5496 1.1 pooka * from INIT to SCAN.
5497 1.1 pooka *
5498 1.1 pooka * Additionally, upon receiving deauth frame from AP,
5499 1.1 pooka * OpenBSD 802.11 stack puts the driver in IEEE80211_S_AUTH
5500 1.1 pooka * state. This will also fail with this driver, so bring the FSM
5501 1.1 pooka * from IEEE80211_S_RUN to IEEE80211_S_SCAN in this case as well.
5502 1.1 pooka */
5503 1.1 pooka if (nstate == IEEE80211_S_SCAN ||
5504 1.1 pooka nstate == IEEE80211_S_AUTH ||
5505 1.1 pooka nstate == IEEE80211_S_ASSOC) {
5506 1.1 pooka DPRINTF(("Force transition to INIT; MGT=%d\n", arg));
5507 1.1 pooka sc->sc_newstate(ic, IEEE80211_S_INIT, arg);
5508 1.1 pooka DPRINTF(("Going INIT->SCAN\n"));
5509 1.1 pooka nstate = IEEE80211_S_SCAN;
5510 1.1 pooka }
5511 1.1 pooka }
5512 1.1 pooka
5513 1.1 pooka switch (nstate) {
5514 1.1 pooka case IEEE80211_S_INIT:
5515 1.1 pooka sc->sc_scanband = 0;
5516 1.1 pooka break;
5517 1.1 pooka
5518 1.1 pooka case IEEE80211_S_SCAN:
5519 1.2 nonaka if (sc->sc_scanband)
5520 1.1 pooka break;
5521 1.1 pooka
5522 1.1 pooka if ((error = iwm_mvm_scan_request(sc, IEEE80211_CHAN_2GHZ,
5523 1.1 pooka ic->ic_des_esslen != 0,
5524 1.1 pooka ic->ic_des_essid, ic->ic_des_esslen)) != 0) {
5525 1.8 nonaka DPRINTF(("%s: could not initiate scan\n", DEVNAME(sc)));
5526 1.1 pooka return;
5527 1.1 pooka }
5528 1.1 pooka ic->ic_state = nstate;
5529 1.1 pooka return;
5530 1.1 pooka
5531 1.1 pooka case IEEE80211_S_AUTH:
5532 1.1 pooka if ((error = iwm_auth(sc)) != 0) {
5533 1.2 nonaka DPRINTF(("%s: could not move to auth state: %d\n",
5534 1.2 nonaka DEVNAME(sc), error));
5535 1.1 pooka return;
5536 1.1 pooka }
5537 1.1 pooka
5538 1.1 pooka break;
5539 1.1 pooka
5540 1.1 pooka case IEEE80211_S_ASSOC:
5541 1.1 pooka if ((error = iwm_assoc(sc)) != 0) {
5542 1.2 nonaka DPRINTF(("%s: failed to associate: %d\n", DEVNAME(sc),
5543 1.2 nonaka error));
5544 1.1 pooka return;
5545 1.1 pooka }
5546 1.1 pooka break;
5547 1.1 pooka
5548 1.1 pooka case IEEE80211_S_RUN: {
5549 1.1 pooka struct iwm_host_cmd cmd = {
5550 1.1 pooka .id = IWM_LQ_CMD,
5551 1.1 pooka .len = { sizeof(in->in_lq), },
5552 1.1 pooka .flags = IWM_CMD_SYNC,
5553 1.1 pooka };
5554 1.1 pooka
5555 1.1 pooka in = (struct iwm_node *)ic->ic_bss;
5556 1.1 pooka iwm_mvm_power_mac_update_mode(sc, in);
5557 1.1 pooka iwm_mvm_enable_beacon_filter(sc, in);
5558 1.1 pooka iwm_mvm_update_quotas(sc, in);
5559 1.1 pooka iwm_setrates(in);
5560 1.1 pooka
5561 1.1 pooka cmd.data[0] = &in->in_lq;
5562 1.1 pooka if ((error = iwm_send_cmd(sc, &cmd)) != 0) {
5563 1.2 nonaka DPRINTF(("%s: IWM_LQ_CMD failed\n", DEVNAME(sc)));
5564 1.1 pooka }
5565 1.1 pooka
5566 1.1 pooka callout_schedule(&sc->sc_calib_to, hz/2);
5567 1.1 pooka
5568 1.1 pooka break; }
5569 1.1 pooka
5570 1.1 pooka default:
5571 1.5 nonaka DPRINTF(("%s: unsupported state %d\n", DEVNAME(sc), nstate));
5572 1.2 nonaka break;
5573 1.1 pooka }
5574 1.1 pooka
5575 1.1 pooka sc->sc_newstate(ic, nstate, arg);
5576 1.1 pooka }
5577 1.1 pooka
5578 1.4 nonaka static int
5579 1.1 pooka iwm_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
5580 1.1 pooka {
5581 1.1 pooka struct iwm_newstate_state *iwmns;
5582 1.1 pooka struct ifnet *ifp = IC2IFP(ic);
5583 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
5584 1.1 pooka
5585 1.1 pooka callout_stop(&sc->sc_calib_to);
5586 1.1 pooka
5587 1.5 nonaka iwmns = kmem_intr_alloc(sizeof(*iwmns), KM_NOSLEEP);
5588 1.1 pooka if (!iwmns) {
5589 1.2 nonaka DPRINTF(("%s: allocating state cb mem failed\n", DEVNAME(sc)));
5590 1.1 pooka return ENOMEM;
5591 1.1 pooka }
5592 1.1 pooka
5593 1.1 pooka iwmns->ns_nstate = nstate;
5594 1.1 pooka iwmns->ns_arg = arg;
5595 1.1 pooka iwmns->ns_generation = sc->sc_generation;
5596 1.1 pooka
5597 1.1 pooka workqueue_enqueue(sc->sc_nswq, &iwmns->ns_wk, NULL);
5598 1.1 pooka
5599 1.1 pooka return 0;
5600 1.1 pooka }
5601 1.1 pooka
5602 1.4 nonaka static void
5603 1.5 nonaka iwm_endscan_cb(struct work *work __unused, void *arg)
5604 1.1 pooka {
5605 1.1 pooka struct iwm_softc *sc = arg;
5606 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5607 1.1 pooka int done;
5608 1.1 pooka
5609 1.1 pooka DPRINTF(("scan ended\n"));
5610 1.1 pooka
5611 1.29 nonaka if (sc->sc_scanband == IEEE80211_CHAN_2GHZ &&
5612 1.29 nonaka sc->sc_nvm.sku_cap_band_52GHz_enable) {
5613 1.1 pooka int error;
5614 1.1 pooka done = 0;
5615 1.1 pooka if ((error = iwm_mvm_scan_request(sc,
5616 1.1 pooka IEEE80211_CHAN_5GHZ, ic->ic_des_esslen != 0,
5617 1.1 pooka ic->ic_des_essid, ic->ic_des_esslen)) != 0) {
5618 1.3 nonaka DPRINTF(("%s: could not initiate scan\n", DEVNAME(sc)));
5619 1.1 pooka done = 1;
5620 1.1 pooka }
5621 1.1 pooka } else {
5622 1.1 pooka done = 1;
5623 1.1 pooka }
5624 1.1 pooka
5625 1.1 pooka if (done) {
5626 1.1 pooka if (!sc->sc_scanband) {
5627 1.1 pooka ieee80211_cancel_scan(ic);
5628 1.1 pooka } else {
5629 1.1 pooka ieee80211_end_scan(ic);
5630 1.1 pooka }
5631 1.1 pooka sc->sc_scanband = 0;
5632 1.1 pooka }
5633 1.1 pooka }
5634 1.1 pooka
5635 1.4 nonaka static int
5636 1.1 pooka iwm_init_hw(struct iwm_softc *sc)
5637 1.1 pooka {
5638 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5639 1.1 pooka int error, i, qid;
5640 1.1 pooka
5641 1.2 nonaka if ((error = iwm_preinit(sc)) != 0)
5642 1.1 pooka return error;
5643 1.1 pooka
5644 1.1 pooka if ((error = iwm_start_hw(sc)) != 0)
5645 1.1 pooka return error;
5646 1.1 pooka
5647 1.1 pooka if ((error = iwm_run_init_mvm_ucode(sc, 0)) != 0) {
5648 1.1 pooka return error;
5649 1.1 pooka }
5650 1.1 pooka
5651 1.1 pooka /*
5652 1.1 pooka * should stop and start HW since that INIT
5653 1.1 pooka * image just loaded
5654 1.1 pooka */
5655 1.1 pooka iwm_stop_device(sc);
5656 1.2 nonaka if ((error = iwm_start_hw(sc)) != 0) {
5657 1.3 nonaka aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
5658 1.1 pooka return error;
5659 1.2 nonaka }
5660 1.1 pooka
5661 1.1 pooka /* omstart, this time with the regular firmware */
5662 1.1 pooka error = iwm_mvm_load_ucode_wait_alive(sc, IWM_UCODE_TYPE_REGULAR);
5663 1.1 pooka if (error) {
5664 1.3 nonaka aprint_error_dev(sc->sc_dev, "could not load firmware\n");
5665 1.1 pooka goto error;
5666 1.1 pooka }
5667 1.1 pooka
5668 1.8 nonaka if ((error = iwm_send_tx_ant_cfg(sc, IWM_FW_VALID_TX_ANT(sc))) != 0)
5669 1.8 nonaka goto error;
5670 1.1 pooka
5671 1.8 nonaka /* Send phy db control command and then phy db calibration*/
5672 1.8 nonaka if ((error = iwm_send_phy_db_data(sc)) != 0)
5673 1.8 nonaka goto error;
5674 1.1 pooka
5675 1.8 nonaka if ((error = iwm_send_phy_cfg_cmd(sc)) != 0)
5676 1.8 nonaka goto error;
5677 1.1 pooka
5678 1.1 pooka /* Add auxiliary station for scanning */
5679 1.1 pooka if ((error = iwm_mvm_add_aux_sta(sc)) != 0)
5680 1.1 pooka goto error;
5681 1.1 pooka
5682 1.1 pooka for (i = 0; i < IWM_NUM_PHY_CTX; i++) {
5683 1.1 pooka /*
5684 1.1 pooka * The channel used here isn't relevant as it's
5685 1.1 pooka * going to be overwritten in the other flows.
5686 1.1 pooka * For now use the first channel we have.
5687 1.1 pooka */
5688 1.1 pooka if ((error = iwm_mvm_phy_ctxt_add(sc,
5689 1.1 pooka &sc->sc_phyctxt[i], &ic->ic_channels[1], 1, 1)) != 0)
5690 1.1 pooka goto error;
5691 1.1 pooka }
5692 1.1 pooka
5693 1.8 nonaka error = iwm_mvm_power_update_device(sc);
5694 1.8 nonaka if (error)
5695 1.8 nonaka goto error;
5696 1.1 pooka
5697 1.1 pooka /* Mark TX rings as active. */
5698 1.1 pooka for (qid = 0; qid < 4; qid++) {
5699 1.1 pooka iwm_enable_txq(sc, qid, qid);
5700 1.1 pooka }
5701 1.1 pooka
5702 1.1 pooka return 0;
5703 1.1 pooka
5704 1.1 pooka error:
5705 1.1 pooka iwm_stop_device(sc);
5706 1.1 pooka return error;
5707 1.1 pooka }
5708 1.1 pooka
5709 1.11 nonaka /* Allow multicast from our BSSID. */
5710 1.11 nonaka static int
5711 1.11 nonaka iwm_allow_mcast(struct iwm_softc *sc)
5712 1.11 nonaka {
5713 1.11 nonaka struct ieee80211com *ic = &sc->sc_ic;
5714 1.11 nonaka struct ieee80211_node *ni = ic->ic_bss;
5715 1.11 nonaka struct iwm_mcast_filter_cmd *cmd;
5716 1.11 nonaka size_t size;
5717 1.11 nonaka int error;
5718 1.11 nonaka
5719 1.11 nonaka size = roundup(sizeof(*cmd), 4);
5720 1.11 nonaka cmd = kmem_intr_zalloc(size, KM_NOSLEEP);
5721 1.11 nonaka if (cmd == NULL)
5722 1.11 nonaka return ENOMEM;
5723 1.11 nonaka cmd->filter_own = 1;
5724 1.11 nonaka cmd->port_id = 0;
5725 1.11 nonaka cmd->count = 0;
5726 1.11 nonaka cmd->pass_all = 1;
5727 1.11 nonaka IEEE80211_ADDR_COPY(cmd->bssid, ni->ni_bssid);
5728 1.11 nonaka
5729 1.11 nonaka error = iwm_mvm_send_cmd_pdu(sc, IWM_MCAST_FILTER_CMD,
5730 1.11 nonaka IWM_CMD_SYNC, size, cmd);
5731 1.11 nonaka kmem_intr_free(cmd, size);
5732 1.11 nonaka return error;
5733 1.11 nonaka }
5734 1.11 nonaka
5735 1.1 pooka /*
5736 1.1 pooka * ifnet interfaces
5737 1.1 pooka */
5738 1.1 pooka
5739 1.4 nonaka static int
5740 1.1 pooka iwm_init(struct ifnet *ifp)
5741 1.1 pooka {
5742 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
5743 1.1 pooka int error;
5744 1.1 pooka
5745 1.1 pooka if (sc->sc_flags & IWM_FLAG_HW_INITED) {
5746 1.1 pooka return 0;
5747 1.1 pooka }
5748 1.1 pooka sc->sc_generation++;
5749 1.1 pooka sc->sc_flags &= ~IWM_FLAG_STOPPED;
5750 1.1 pooka
5751 1.1 pooka if ((error = iwm_init_hw(sc)) != 0) {
5752 1.1 pooka iwm_stop(ifp, 1);
5753 1.1 pooka return error;
5754 1.1 pooka }
5755 1.1 pooka
5756 1.1 pooka /*
5757 1.38 ozaki * Ok, firmware loaded and we are jogging
5758 1.1 pooka */
5759 1.1 pooka
5760 1.1 pooka ifp->if_flags &= ~IFF_OACTIVE;
5761 1.1 pooka ifp->if_flags |= IFF_RUNNING;
5762 1.1 pooka
5763 1.1 pooka ieee80211_begin_scan(&sc->sc_ic, 0);
5764 1.1 pooka sc->sc_flags |= IWM_FLAG_HW_INITED;
5765 1.1 pooka
5766 1.1 pooka return 0;
5767 1.1 pooka }
5768 1.1 pooka
5769 1.1 pooka /*
5770 1.1 pooka * Dequeue packets from sendq and call send.
5771 1.1 pooka * mostly from iwn
5772 1.1 pooka */
5773 1.4 nonaka static void
5774 1.1 pooka iwm_start(struct ifnet *ifp)
5775 1.1 pooka {
5776 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
5777 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5778 1.1 pooka struct ieee80211_node *ni;
5779 1.8 nonaka struct ether_header *eh;
5780 1.1 pooka struct mbuf *m;
5781 1.1 pooka int ac;
5782 1.1 pooka
5783 1.1 pooka if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
5784 1.1 pooka return;
5785 1.1 pooka
5786 1.1 pooka for (;;) {
5787 1.1 pooka /* why isn't this done per-queue? */
5788 1.1 pooka if (sc->qfullmsk != 0) {
5789 1.1 pooka ifp->if_flags |= IFF_OACTIVE;
5790 1.1 pooka break;
5791 1.1 pooka }
5792 1.1 pooka
5793 1.1 pooka /* need to send management frames even if we're not RUNning */
5794 1.1 pooka IF_DEQUEUE(&ic->ic_mgtq, m);
5795 1.1 pooka if (m) {
5796 1.41 ozaki ni = M_GETCTX(m, struct ieee80211_node *);
5797 1.1 pooka ac = 0;
5798 1.1 pooka goto sendit;
5799 1.1 pooka }
5800 1.1 pooka if (ic->ic_state != IEEE80211_S_RUN) {
5801 1.1 pooka break;
5802 1.1 pooka }
5803 1.1 pooka
5804 1.1 pooka IFQ_DEQUEUE(&ifp->if_snd, m);
5805 1.1 pooka if (!m)
5806 1.1 pooka break;
5807 1.8 nonaka if (m->m_len < sizeof (*eh) &&
5808 1.8 nonaka (m = m_pullup(m, sizeof (*eh))) == NULL) {
5809 1.8 nonaka ifp->if_oerrors++;
5810 1.8 nonaka continue;
5811 1.8 nonaka }
5812 1.1 pooka if (ifp->if_bpf != NULL)
5813 1.1 pooka bpf_mtap(ifp, m);
5814 1.1 pooka
5815 1.1 pooka eh = mtod(m, struct ether_header *);
5816 1.1 pooka ni = ieee80211_find_txnode(ic, eh->ether_dhost);
5817 1.1 pooka if (ni == NULL) {
5818 1.1 pooka m_freem(m);
5819 1.1 pooka ifp->if_oerrors++;
5820 1.1 pooka continue;
5821 1.1 pooka }
5822 1.1 pooka /* classify mbuf so we can find which tx ring to use */
5823 1.1 pooka if (ieee80211_classify(ic, m, ni) != 0) {
5824 1.1 pooka m_freem(m);
5825 1.1 pooka ieee80211_free_node(ni);
5826 1.1 pooka ifp->if_oerrors++;
5827 1.1 pooka continue;
5828 1.1 pooka }
5829 1.1 pooka
5830 1.1 pooka /* No QoS encapsulation for EAPOL frames. */
5831 1.1 pooka ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
5832 1.1 pooka M_WME_GETAC(m) : WME_AC_BE;
5833 1.1 pooka
5834 1.1 pooka if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
5835 1.1 pooka ieee80211_free_node(ni);
5836 1.1 pooka ifp->if_oerrors++;
5837 1.1 pooka continue;
5838 1.1 pooka }
5839 1.1 pooka
5840 1.1 pooka sendit:
5841 1.1 pooka if (ic->ic_rawbpf != NULL)
5842 1.1 pooka bpf_mtap3(ic->ic_rawbpf, m);
5843 1.1 pooka if (iwm_tx(sc, m, ni, ac) != 0) {
5844 1.1 pooka ieee80211_free_node(ni);
5845 1.1 pooka ifp->if_oerrors++;
5846 1.1 pooka continue;
5847 1.1 pooka }
5848 1.1 pooka
5849 1.1 pooka if (ifp->if_flags & IFF_UP) {
5850 1.1 pooka sc->sc_tx_timer = 15;
5851 1.1 pooka ifp->if_timer = 1;
5852 1.1 pooka }
5853 1.1 pooka }
5854 1.1 pooka
5855 1.1 pooka return;
5856 1.1 pooka }
5857 1.1 pooka
5858 1.4 nonaka static void
5859 1.1 pooka iwm_stop(struct ifnet *ifp, int disable)
5860 1.1 pooka {
5861 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
5862 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5863 1.1 pooka
5864 1.1 pooka sc->sc_flags &= ~IWM_FLAG_HW_INITED;
5865 1.1 pooka sc->sc_flags |= IWM_FLAG_STOPPED;
5866 1.1 pooka sc->sc_generation++;
5867 1.1 pooka sc->sc_scanband = 0;
5868 1.1 pooka sc->sc_auth_prot = 0;
5869 1.1 pooka ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
5870 1.1 pooka
5871 1.1 pooka if (ic->ic_state != IEEE80211_S_INIT)
5872 1.1 pooka ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
5873 1.1 pooka
5874 1.26 nonaka callout_stop(&sc->sc_calib_to);
5875 1.1 pooka ifp->if_timer = sc->sc_tx_timer = 0;
5876 1.1 pooka iwm_stop_device(sc);
5877 1.1 pooka }
5878 1.1 pooka
5879 1.4 nonaka static void
5880 1.1 pooka iwm_watchdog(struct ifnet *ifp)
5881 1.1 pooka {
5882 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
5883 1.1 pooka
5884 1.1 pooka ifp->if_timer = 0;
5885 1.1 pooka if (sc->sc_tx_timer > 0) {
5886 1.1 pooka if (--sc->sc_tx_timer == 0) {
5887 1.5 nonaka aprint_error_dev(sc->sc_dev, "device timeout\n");
5888 1.2 nonaka #ifdef IWM_DEBUG
5889 1.1 pooka iwm_nic_error(sc);
5890 1.2 nonaka #endif
5891 1.1 pooka ifp->if_flags &= ~IFF_UP;
5892 1.1 pooka iwm_stop(ifp, 1);
5893 1.1 pooka ifp->if_oerrors++;
5894 1.1 pooka return;
5895 1.1 pooka }
5896 1.1 pooka ifp->if_timer = 1;
5897 1.1 pooka }
5898 1.1 pooka
5899 1.1 pooka ieee80211_watchdog(&sc->sc_ic);
5900 1.1 pooka }
5901 1.1 pooka
5902 1.4 nonaka static int
5903 1.1 pooka iwm_ioctl(struct ifnet *ifp, u_long cmd, void *data)
5904 1.1 pooka {
5905 1.1 pooka struct iwm_softc *sc = ifp->if_softc;
5906 1.1 pooka struct ieee80211com *ic = &sc->sc_ic;
5907 1.1 pooka const struct sockaddr *sa;
5908 1.1 pooka int s, error = 0;
5909 1.1 pooka
5910 1.1 pooka s = splnet();
5911 1.1 pooka
5912 1.1 pooka switch (cmd) {
5913 1.1 pooka case SIOCSIFADDR:
5914 1.1 pooka ifp->if_flags |= IFF_UP;
5915 1.1 pooka /* FALLTHROUGH */
5916 1.1 pooka case SIOCSIFFLAGS:
5917 1.1 pooka if ((error = ifioctl_common(ifp, cmd, data)) != 0)
5918 1.1 pooka break;
5919 1.1 pooka if (ifp->if_flags & IFF_UP) {
5920 1.1 pooka if (!(ifp->if_flags & IFF_RUNNING)) {
5921 1.1 pooka if ((error = iwm_init(ifp)) != 0)
5922 1.1 pooka ifp->if_flags &= ~IFF_UP;
5923 1.1 pooka }
5924 1.1 pooka } else {
5925 1.1 pooka if (ifp->if_flags & IFF_RUNNING)
5926 1.1 pooka iwm_stop(ifp, 1);
5927 1.1 pooka }
5928 1.1 pooka break;
5929 1.1 pooka
5930 1.1 pooka case SIOCADDMULTI:
5931 1.1 pooka case SIOCDELMULTI:
5932 1.36 nonaka if (!ISSET(sc->sc_flags, IWM_FLAG_ATTACHED)) {
5933 1.36 nonaka error = ENXIO;
5934 1.36 nonaka break;
5935 1.36 nonaka }
5936 1.1 pooka sa = ifreq_getaddr(SIOCADDMULTI, (struct ifreq *)data);
5937 1.1 pooka error = (cmd == SIOCADDMULTI) ?
5938 1.1 pooka ether_addmulti(sa, &sc->sc_ec) :
5939 1.1 pooka ether_delmulti(sa, &sc->sc_ec);
5940 1.1 pooka if (error == ENETRESET)
5941 1.1 pooka error = 0;
5942 1.1 pooka break;
5943 1.1 pooka
5944 1.1 pooka default:
5945 1.36 nonaka if (!ISSET(sc->sc_flags, IWM_FLAG_ATTACHED)) {
5946 1.36 nonaka error = ether_ioctl(ifp, cmd, data);
5947 1.36 nonaka break;
5948 1.36 nonaka }
5949 1.1 pooka error = ieee80211_ioctl(ic, cmd, data);
5950 1.36 nonaka break;
5951 1.1 pooka }
5952 1.1 pooka
5953 1.1 pooka if (error == ENETRESET) {
5954 1.1 pooka error = 0;
5955 1.1 pooka if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
5956 1.1 pooka (IFF_UP | IFF_RUNNING)) {
5957 1.1 pooka iwm_stop(ifp, 0);
5958 1.1 pooka error = iwm_init(ifp);
5959 1.1 pooka }
5960 1.1 pooka }
5961 1.1 pooka
5962 1.1 pooka splx(s);
5963 1.1 pooka return error;
5964 1.1 pooka }
5965 1.1 pooka
5966 1.1 pooka /*
5967 1.1 pooka * The interrupt side of things
5968 1.1 pooka */
5969 1.1 pooka
5970 1.1 pooka /*
5971 1.1 pooka * error dumping routines are from iwlwifi/mvm/utils.c
5972 1.1 pooka */
5973 1.1 pooka
5974 1.1 pooka /*
5975 1.1 pooka * Note: This structure is read from the device with IO accesses,
5976 1.1 pooka * and the reading already does the endian conversion. As it is
5977 1.1 pooka * read with uint32_t-sized accesses, any members with a different size
5978 1.1 pooka * need to be ordered correctly though!
5979 1.1 pooka */
5980 1.1 pooka struct iwm_error_event_table {
5981 1.1 pooka uint32_t valid; /* (nonzero) valid, (0) log is empty */
5982 1.1 pooka uint32_t error_id; /* type of error */
5983 1.1 pooka uint32_t pc; /* program counter */
5984 1.1 pooka uint32_t blink1; /* branch link */
5985 1.1 pooka uint32_t blink2; /* branch link */
5986 1.1 pooka uint32_t ilink1; /* interrupt link */
5987 1.1 pooka uint32_t ilink2; /* interrupt link */
5988 1.1 pooka uint32_t data1; /* error-specific data */
5989 1.1 pooka uint32_t data2; /* error-specific data */
5990 1.1 pooka uint32_t data3; /* error-specific data */
5991 1.1 pooka uint32_t bcon_time; /* beacon timer */
5992 1.1 pooka uint32_t tsf_low; /* network timestamp function timer */
5993 1.1 pooka uint32_t tsf_hi; /* network timestamp function timer */
5994 1.1 pooka uint32_t gp1; /* GP1 timer register */
5995 1.1 pooka uint32_t gp2; /* GP2 timer register */
5996 1.1 pooka uint32_t gp3; /* GP3 timer register */
5997 1.1 pooka uint32_t ucode_ver; /* uCode version */
5998 1.1 pooka uint32_t hw_ver; /* HW Silicon version */
5999 1.1 pooka uint32_t brd_ver; /* HW board version */
6000 1.1 pooka uint32_t log_pc; /* log program counter */
6001 1.1 pooka uint32_t frame_ptr; /* frame pointer */
6002 1.1 pooka uint32_t stack_ptr; /* stack pointer */
6003 1.1 pooka uint32_t hcmd; /* last host command header */
6004 1.1 pooka uint32_t isr0; /* isr status register LMPM_NIC_ISR0:
6005 1.1 pooka * rxtx_flag */
6006 1.1 pooka uint32_t isr1; /* isr status register LMPM_NIC_ISR1:
6007 1.1 pooka * host_flag */
6008 1.1 pooka uint32_t isr2; /* isr status register LMPM_NIC_ISR2:
6009 1.1 pooka * enc_flag */
6010 1.1 pooka uint32_t isr3; /* isr status register LMPM_NIC_ISR3:
6011 1.1 pooka * time_flag */
6012 1.1 pooka uint32_t isr4; /* isr status register LMPM_NIC_ISR4:
6013 1.1 pooka * wico interrupt */
6014 1.1 pooka uint32_t isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
6015 1.1 pooka uint32_t wait_event; /* wait event() caller address */
6016 1.1 pooka uint32_t l2p_control; /* L2pControlField */
6017 1.1 pooka uint32_t l2p_duration; /* L2pDurationField */
6018 1.1 pooka uint32_t l2p_mhvalid; /* L2pMhValidBits */
6019 1.1 pooka uint32_t l2p_addr_match; /* L2pAddrMatchStat */
6020 1.1 pooka uint32_t lmpm_pmg_sel; /* indicate which clocks are turned on
6021 1.1 pooka * (LMPM_PMG_SEL) */
6022 1.1 pooka uint32_t u_timestamp; /* indicate when the date and time of the
6023 1.1 pooka * compilation */
6024 1.1 pooka uint32_t flow_handler; /* FH read/write pointers, RX credit */
6025 1.1 pooka } __packed;
6026 1.1 pooka
6027 1.1 pooka #define ERROR_START_OFFSET (1 * sizeof(uint32_t))
6028 1.1 pooka #define ERROR_ELEM_SIZE (7 * sizeof(uint32_t))
6029 1.1 pooka
6030 1.4 nonaka #ifdef IWM_DEBUG
6031 1.4 nonaka static const struct {
6032 1.1 pooka const char *name;
6033 1.1 pooka uint8_t num;
6034 1.1 pooka } advanced_lookup[] = {
6035 1.1 pooka { "NMI_INTERRUPT_WDG", 0x34 },
6036 1.1 pooka { "SYSASSERT", 0x35 },
6037 1.1 pooka { "UCODE_VERSION_MISMATCH", 0x37 },
6038 1.1 pooka { "BAD_COMMAND", 0x38 },
6039 1.1 pooka { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
6040 1.1 pooka { "FATAL_ERROR", 0x3D },
6041 1.1 pooka { "NMI_TRM_HW_ERR", 0x46 },
6042 1.1 pooka { "NMI_INTERRUPT_TRM", 0x4C },
6043 1.1 pooka { "NMI_INTERRUPT_BREAK_POINT", 0x54 },
6044 1.1 pooka { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
6045 1.1 pooka { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
6046 1.1 pooka { "NMI_INTERRUPT_HOST", 0x66 },
6047 1.1 pooka { "NMI_INTERRUPT_ACTION_PT", 0x7C },
6048 1.1 pooka { "NMI_INTERRUPT_UNKNOWN", 0x84 },
6049 1.1 pooka { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
6050 1.1 pooka { "ADVANCED_SYSASSERT", 0 },
6051 1.1 pooka };
6052 1.1 pooka
6053 1.4 nonaka static const char *
6054 1.1 pooka iwm_desc_lookup(uint32_t num)
6055 1.1 pooka {
6056 1.1 pooka int i;
6057 1.1 pooka
6058 1.1 pooka for (i = 0; i < __arraycount(advanced_lookup) - 1; i++)
6059 1.1 pooka if (advanced_lookup[i].num == num)
6060 1.1 pooka return advanced_lookup[i].name;
6061 1.1 pooka
6062 1.1 pooka /* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */
6063 1.1 pooka return advanced_lookup[i].name;
6064 1.1 pooka }
6065 1.1 pooka
6066 1.1 pooka /*
6067 1.1 pooka * Support for dumping the error log seemed like a good idea ...
6068 1.1 pooka * but it's mostly hex junk and the only sensible thing is the
6069 1.1 pooka * hw/ucode revision (which we know anyway). Since it's here,
6070 1.1 pooka * I'll just leave it in, just in case e.g. the Intel guys want to
6071 1.1 pooka * help us decipher some "ADVANCED_SYSASSERT" later.
6072 1.1 pooka */
6073 1.4 nonaka static void
6074 1.1 pooka iwm_nic_error(struct iwm_softc *sc)
6075 1.1 pooka {
6076 1.1 pooka struct iwm_error_event_table table;
6077 1.1 pooka uint32_t base;
6078 1.1 pooka
6079 1.3 nonaka aprint_error_dev(sc->sc_dev, "dumping device error log\n");
6080 1.1 pooka base = sc->sc_uc.uc_error_event_table;
6081 1.1 pooka if (base < 0x800000 || base >= 0x80C000) {
6082 1.3 nonaka aprint_error_dev(sc->sc_dev,
6083 1.3 nonaka "Not valid error log pointer 0x%08x\n", base);
6084 1.1 pooka return;
6085 1.1 pooka }
6086 1.1 pooka
6087 1.1 pooka if (iwm_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t)) != 0) {
6088 1.3 nonaka aprint_error_dev(sc->sc_dev, "reading errlog failed\n");
6089 1.1 pooka return;
6090 1.1 pooka }
6091 1.1 pooka
6092 1.1 pooka if (!table.valid) {
6093 1.3 nonaka aprint_error_dev(sc->sc_dev, "errlog not found, skipping\n");
6094 1.1 pooka return;
6095 1.1 pooka }
6096 1.1 pooka
6097 1.1 pooka if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
6098 1.3 nonaka aprint_error_dev(sc->sc_dev, "Start IWL Error Log Dump:\n");
6099 1.3 nonaka aprint_error_dev(sc->sc_dev, "Status: 0x%x, count: %d\n",
6100 1.1 pooka sc->sc_flags, table.valid);
6101 1.1 pooka }
6102 1.1 pooka
6103 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | %-28s\n", table.error_id,
6104 1.1 pooka iwm_desc_lookup(table.error_id));
6105 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | uPc\n", table.pc);
6106 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | branchlink1\n", table.blink1);
6107 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | branchlink2\n", table.blink2);
6108 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | interruptlink1\n", table.ilink1);
6109 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | interruptlink2\n", table.ilink2);
6110 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | data1\n", table.data1);
6111 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | data2\n", table.data2);
6112 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | data3\n", table.data3);
6113 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | beacon time\n", table.bcon_time);
6114 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | tsf low\n", table.tsf_low);
6115 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | tsf hi\n", table.tsf_hi);
6116 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | time gp1\n", table.gp1);
6117 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | time gp2\n", table.gp2);
6118 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | time gp3\n", table.gp3);
6119 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | uCode version\n", table.ucode_ver);
6120 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | hw version\n", table.hw_ver);
6121 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | board version\n", table.brd_ver);
6122 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | hcmd\n", table.hcmd);
6123 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | isr0\n", table.isr0);
6124 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | isr1\n", table.isr1);
6125 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | isr2\n", table.isr2);
6126 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | isr3\n", table.isr3);
6127 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | isr4\n", table.isr4);
6128 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | isr_pref\n", table.isr_pref);
6129 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | wait_event\n", table.wait_event);
6130 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | l2p_control\n", table.l2p_control);
6131 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | l2p_duration\n",
6132 1.3 nonaka table.l2p_duration);
6133 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | l2p_mhvalid\n", table.l2p_mhvalid);
6134 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | l2p_addr_match\n",
6135 1.3 nonaka table.l2p_addr_match);
6136 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | lmpm_pmg_sel\n",
6137 1.3 nonaka table.lmpm_pmg_sel);
6138 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | timestamp\n", table.u_timestamp);
6139 1.3 nonaka aprint_error_dev(sc->sc_dev, "%08X | flow_handler\n",
6140 1.3 nonaka table.flow_handler);
6141 1.1 pooka }
6142 1.2 nonaka #endif
6143 1.1 pooka
6144 1.1 pooka #define SYNC_RESP_STRUCT(_var_, _pkt_) \
6145 1.1 pooka do { \
6146 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*(_pkt_)), \
6147 1.1 pooka sizeof(*(_var_)), BUS_DMASYNC_POSTREAD); \
6148 1.1 pooka _var_ = (void *)((_pkt_)+1); \
6149 1.1 pooka } while (/*CONSTCOND*/0)
6150 1.1 pooka
6151 1.1 pooka #define SYNC_RESP_PTR(_ptr_, _len_, _pkt_) \
6152 1.1 pooka do { \
6153 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*(_pkt_)), \
6154 1.1 pooka sizeof(len), BUS_DMASYNC_POSTREAD); \
6155 1.1 pooka _ptr_ = (void *)((_pkt_)+1); \
6156 1.1 pooka } while (/*CONSTCOND*/0)
6157 1.1 pooka
6158 1.1 pooka #define ADVANCE_RXQ(sc) (sc->rxq.cur = (sc->rxq.cur + 1) % IWM_RX_RING_COUNT);
6159 1.1 pooka
6160 1.1 pooka /*
6161 1.1 pooka * Process an IWM_CSR_INT_BIT_FH_RX or IWM_CSR_INT_BIT_SW_RX interrupt.
6162 1.1 pooka * Basic structure from if_iwn
6163 1.1 pooka */
6164 1.4 nonaka static void
6165 1.1 pooka iwm_notif_intr(struct iwm_softc *sc)
6166 1.1 pooka {
6167 1.1 pooka uint16_t hw;
6168 1.1 pooka
6169 1.1 pooka bus_dmamap_sync(sc->sc_dmat, sc->rxq.stat_dma.map,
6170 1.1 pooka 0, sc->rxq.stat_dma.size, BUS_DMASYNC_POSTREAD);
6171 1.1 pooka
6172 1.1 pooka hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff;
6173 1.1 pooka while (sc->rxq.cur != hw) {
6174 1.1 pooka struct iwm_rx_data *data = &sc->rxq.data[sc->rxq.cur];
6175 1.5 nonaka struct iwm_rx_packet *pkt, tmppkt;
6176 1.1 pooka struct iwm_cmd_response *cresp;
6177 1.1 pooka int qid, idx;
6178 1.1 pooka
6179 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0, sizeof(*pkt),
6180 1.1 pooka BUS_DMASYNC_POSTREAD);
6181 1.1 pooka pkt = mtod(data->m, struct iwm_rx_packet *);
6182 1.1 pooka
6183 1.1 pooka qid = pkt->hdr.qid & ~0x80;
6184 1.1 pooka idx = pkt->hdr.idx;
6185 1.1 pooka
6186 1.1 pooka DPRINTFN(12, ("rx packet qid=%d idx=%d flags=%x type=%x %d %d\n",
6187 1.1 pooka pkt->hdr.qid & ~0x80, pkt->hdr.idx, pkt->hdr.flags,
6188 1.1 pooka pkt->hdr.code, sc->rxq.cur, hw));
6189 1.1 pooka
6190 1.1 pooka /*
6191 1.1 pooka * randomly get these from the firmware, no idea why.
6192 1.1 pooka * they at least seem harmless, so just ignore them for now
6193 1.1 pooka */
6194 1.1 pooka if (__predict_false((pkt->hdr.code == 0 && qid == 0 && idx == 0)
6195 1.1 pooka || pkt->len_n_flags == htole32(0x55550000))) {
6196 1.1 pooka ADVANCE_RXQ(sc);
6197 1.1 pooka continue;
6198 1.1 pooka }
6199 1.1 pooka
6200 1.1 pooka switch (pkt->hdr.code) {
6201 1.1 pooka case IWM_REPLY_RX_PHY_CMD:
6202 1.1 pooka iwm_mvm_rx_rx_phy_cmd(sc, pkt, data);
6203 1.1 pooka break;
6204 1.1 pooka
6205 1.1 pooka case IWM_REPLY_RX_MPDU_CMD:
6206 1.5 nonaka tmppkt = *pkt; // XXX m is freed by ieee80211_input()
6207 1.1 pooka iwm_mvm_rx_rx_mpdu(sc, pkt, data);
6208 1.5 nonaka pkt = &tmppkt;
6209 1.1 pooka break;
6210 1.1 pooka
6211 1.1 pooka case IWM_TX_CMD:
6212 1.1 pooka iwm_mvm_rx_tx_cmd(sc, pkt, data);
6213 1.1 pooka break;
6214 1.1 pooka
6215 1.1 pooka case IWM_MISSED_BEACONS_NOTIFICATION:
6216 1.1 pooka iwm_mvm_rx_missed_beacons_notif(sc, pkt, data);
6217 1.1 pooka break;
6218 1.1 pooka
6219 1.1 pooka case IWM_MVM_ALIVE: {
6220 1.1 pooka struct iwm_mvm_alive_resp *resp;
6221 1.1 pooka SYNC_RESP_STRUCT(resp, pkt);
6222 1.1 pooka
6223 1.1 pooka sc->sc_uc.uc_error_event_table
6224 1.1 pooka = le32toh(resp->error_event_table_ptr);
6225 1.1 pooka sc->sc_uc.uc_log_event_table
6226 1.1 pooka = le32toh(resp->log_event_table_ptr);
6227 1.1 pooka sc->sched_base = le32toh(resp->scd_base_ptr);
6228 1.1 pooka sc->sc_uc.uc_ok = resp->status == IWM_ALIVE_STATUS_OK;
6229 1.1 pooka
6230 1.1 pooka sc->sc_uc.uc_intr = 1;
6231 1.1 pooka wakeup(&sc->sc_uc);
6232 1.1 pooka break; }
6233 1.1 pooka
6234 1.1 pooka case IWM_CALIB_RES_NOTIF_PHY_DB: {
6235 1.1 pooka struct iwm_calib_res_notif_phy_db *phy_db_notif;
6236 1.1 pooka SYNC_RESP_STRUCT(phy_db_notif, pkt);
6237 1.1 pooka
6238 1.5 nonaka uint16_t size = le16toh(phy_db_notif->length);
6239 1.5 nonaka bus_dmamap_sync(sc->sc_dmat, data->map,
6240 1.5 nonaka sizeof(*pkt) + sizeof(*phy_db_notif),
6241 1.5 nonaka size, BUS_DMASYNC_POSTREAD);
6242 1.5 nonaka iwm_phy_db_set_section(sc, phy_db_notif, size);
6243 1.1 pooka
6244 1.1 pooka break; }
6245 1.1 pooka
6246 1.1 pooka case IWM_STATISTICS_NOTIFICATION: {
6247 1.1 pooka struct iwm_notif_statistics *stats;
6248 1.1 pooka SYNC_RESP_STRUCT(stats, pkt);
6249 1.1 pooka memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats));
6250 1.1 pooka sc->sc_noise = iwm_get_noise(&stats->rx.general);
6251 1.1 pooka break; }
6252 1.1 pooka
6253 1.1 pooka case IWM_NVM_ACCESS_CMD:
6254 1.1 pooka if (sc->sc_wantresp == ((qid << 16) | idx)) {
6255 1.1 pooka bus_dmamap_sync(sc->sc_dmat, data->map, 0,
6256 1.1 pooka sizeof(sc->sc_cmd_resp),
6257 1.1 pooka BUS_DMASYNC_POSTREAD);
6258 1.1 pooka memcpy(sc->sc_cmd_resp,
6259 1.1 pooka pkt, sizeof(sc->sc_cmd_resp));
6260 1.1 pooka }
6261 1.1 pooka break;
6262 1.1 pooka
6263 1.1 pooka case IWM_PHY_CONFIGURATION_CMD:
6264 1.1 pooka case IWM_TX_ANT_CONFIGURATION_CMD:
6265 1.1 pooka case IWM_ADD_STA:
6266 1.1 pooka case IWM_MAC_CONTEXT_CMD:
6267 1.1 pooka case IWM_REPLY_SF_CFG_CMD:
6268 1.1 pooka case IWM_POWER_TABLE_CMD:
6269 1.1 pooka case IWM_PHY_CONTEXT_CMD:
6270 1.1 pooka case IWM_BINDING_CONTEXT_CMD:
6271 1.1 pooka case IWM_TIME_EVENT_CMD:
6272 1.1 pooka case IWM_SCAN_REQUEST_CMD:
6273 1.1 pooka case IWM_REPLY_BEACON_FILTERING_CMD:
6274 1.1 pooka case IWM_MAC_PM_POWER_TABLE:
6275 1.1 pooka case IWM_TIME_QUOTA_CMD:
6276 1.1 pooka case IWM_REMOVE_STA:
6277 1.1 pooka case IWM_TXPATH_FLUSH:
6278 1.1 pooka case IWM_LQ_CMD:
6279 1.1 pooka SYNC_RESP_STRUCT(cresp, pkt);
6280 1.1 pooka if (sc->sc_wantresp == ((qid << 16) | idx)) {
6281 1.1 pooka memcpy(sc->sc_cmd_resp,
6282 1.1 pooka pkt, sizeof(*pkt)+sizeof(*cresp));
6283 1.1 pooka }
6284 1.1 pooka break;
6285 1.1 pooka
6286 1.1 pooka /* ignore */
6287 1.1 pooka case 0x6c: /* IWM_PHY_DB_CMD, no idea why it's not in fw-api.h */
6288 1.1 pooka break;
6289 1.1 pooka
6290 1.1 pooka case IWM_INIT_COMPLETE_NOTIF:
6291 1.1 pooka sc->sc_init_complete = 1;
6292 1.1 pooka wakeup(&sc->sc_init_complete);
6293 1.1 pooka break;
6294 1.1 pooka
6295 1.1 pooka case IWM_SCAN_COMPLETE_NOTIFICATION: {
6296 1.1 pooka struct iwm_scan_complete_notif *notif;
6297 1.1 pooka SYNC_RESP_STRUCT(notif, pkt);
6298 1.1 pooka
6299 1.1 pooka workqueue_enqueue(sc->sc_eswq, &sc->sc_eswk, NULL);
6300 1.1 pooka break; }
6301 1.1 pooka
6302 1.1 pooka case IWM_REPLY_ERROR: {
6303 1.1 pooka struct iwm_error_resp *resp;
6304 1.1 pooka SYNC_RESP_STRUCT(resp, pkt);
6305 1.1 pooka
6306 1.3 nonaka aprint_error_dev(sc->sc_dev,
6307 1.3 nonaka "firmware error 0x%x, cmd 0x%x\n",
6308 1.3 nonaka le32toh(resp->error_type), resp->cmd_id);
6309 1.1 pooka break; }
6310 1.1 pooka
6311 1.1 pooka case IWM_TIME_EVENT_NOTIFICATION: {
6312 1.1 pooka struct iwm_time_event_notif *notif;
6313 1.1 pooka SYNC_RESP_STRUCT(notif, pkt);
6314 1.8 nonaka
6315 1.1 pooka if (notif->status) {
6316 1.1 pooka if (le32toh(notif->action) &
6317 1.1 pooka IWM_TE_V2_NOTIF_HOST_EVENT_START)
6318 1.1 pooka sc->sc_auth_prot = 2;
6319 1.1 pooka else
6320 1.1 pooka sc->sc_auth_prot = 0;
6321 1.1 pooka } else {
6322 1.1 pooka sc->sc_auth_prot = -1;
6323 1.1 pooka }
6324 1.1 pooka wakeup(&sc->sc_auth_prot);
6325 1.1 pooka break; }
6326 1.1 pooka
6327 1.11 nonaka case IWM_MCAST_FILTER_CMD:
6328 1.11 nonaka break;
6329 1.11 nonaka
6330 1.1 pooka default:
6331 1.3 nonaka aprint_error_dev(sc->sc_dev,
6332 1.15 nonaka "code %02x frame %d/%d %x UNHANDLED "
6333 1.15 nonaka "(this should not happen)\n",
6334 1.15 nonaka pkt->hdr.code, qid, idx, pkt->len_n_flags);
6335 1.1 pooka break;
6336 1.1 pooka }
6337 1.1 pooka
6338 1.1 pooka /*
6339 1.1 pooka * Why test bit 0x80? The Linux driver:
6340 1.1 pooka *
6341 1.1 pooka * There is one exception: uCode sets bit 15 when it
6342 1.1 pooka * originates the response/notification, i.e. when the
6343 1.1 pooka * response/notification is not a direct response to a
6344 1.1 pooka * command sent by the driver. For example, uCode issues
6345 1.1 pooka * IWM_REPLY_RX when it sends a received frame to the driver;
6346 1.1 pooka * it is not a direct response to any driver command.
6347 1.1 pooka *
6348 1.1 pooka * Ok, so since when is 7 == 15? Well, the Linux driver
6349 1.1 pooka * uses a slightly different format for pkt->hdr, and "qid"
6350 1.1 pooka * is actually the upper byte of a two-byte field.
6351 1.1 pooka */
6352 1.1 pooka if (!(pkt->hdr.qid & (1 << 7))) {
6353 1.1 pooka iwm_cmd_done(sc, pkt);
6354 1.1 pooka }
6355 1.1 pooka
6356 1.1 pooka ADVANCE_RXQ(sc);
6357 1.1 pooka }
6358 1.1 pooka
6359 1.1 pooka IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
6360 1.1 pooka IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
6361 1.1 pooka
6362 1.1 pooka /*
6363 1.1 pooka * Tell the firmware what we have processed.
6364 1.1 pooka * Seems like the hardware gets upset unless we align
6365 1.1 pooka * the write by 8??
6366 1.1 pooka */
6367 1.1 pooka hw = (hw == 0) ? IWM_RX_RING_COUNT - 1 : hw - 1;
6368 1.1 pooka IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, hw & ~7);
6369 1.1 pooka }
6370 1.1 pooka
6371 1.4 nonaka static int
6372 1.1 pooka iwm_intr(void *arg)
6373 1.1 pooka {
6374 1.1 pooka struct iwm_softc *sc = arg;
6375 1.1 pooka struct ifnet *ifp = IC2IFP(&sc->sc_ic);
6376 1.1 pooka int handled = 0;
6377 1.1 pooka int r1, r2, rv = 0;
6378 1.1 pooka int isperiodic = 0;
6379 1.1 pooka
6380 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT_MASK, 0);
6381 1.1 pooka
6382 1.1 pooka if (sc->sc_flags & IWM_FLAG_USE_ICT) {
6383 1.1 pooka uint32_t *ict = sc->ict_dma.vaddr;
6384 1.1 pooka int tmp;
6385 1.1 pooka
6386 1.1 pooka tmp = htole32(ict[sc->ict_cur]);
6387 1.1 pooka if (!tmp)
6388 1.1 pooka goto out_ena;
6389 1.1 pooka
6390 1.1 pooka /*
6391 1.1 pooka * ok, there was something. keep plowing until we have all.
6392 1.1 pooka */
6393 1.1 pooka r1 = r2 = 0;
6394 1.1 pooka while (tmp) {
6395 1.1 pooka r1 |= tmp;
6396 1.1 pooka ict[sc->ict_cur] = 0;
6397 1.1 pooka sc->ict_cur = (sc->ict_cur+1) % IWM_ICT_COUNT;
6398 1.1 pooka tmp = htole32(ict[sc->ict_cur]);
6399 1.1 pooka }
6400 1.1 pooka
6401 1.1 pooka /* this is where the fun begins. don't ask */
6402 1.1 pooka if (r1 == 0xffffffff)
6403 1.1 pooka r1 = 0;
6404 1.1 pooka
6405 1.1 pooka /* i am not expected to understand this */
6406 1.1 pooka if (r1 & 0xc0000)
6407 1.1 pooka r1 |= 0x8000;
6408 1.1 pooka r1 = (0xff & r1) | ((0xff00 & r1) << 16);
6409 1.1 pooka } else {
6410 1.1 pooka r1 = IWM_READ(sc, IWM_CSR_INT);
6411 1.1 pooka /* "hardware gone" (where, fishing?) */
6412 1.1 pooka if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
6413 1.1 pooka goto out;
6414 1.1 pooka r2 = IWM_READ(sc, IWM_CSR_FH_INT_STATUS);
6415 1.1 pooka }
6416 1.1 pooka if (r1 == 0 && r2 == 0) {
6417 1.1 pooka goto out_ena;
6418 1.1 pooka }
6419 1.1 pooka
6420 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT, r1 | ~sc->sc_intmask);
6421 1.1 pooka
6422 1.1 pooka /* ignored */
6423 1.1 pooka handled |= (r1 & (IWM_CSR_INT_BIT_ALIVE /*| IWM_CSR_INT_BIT_SCD*/));
6424 1.1 pooka
6425 1.1 pooka if (r1 & IWM_CSR_INT_BIT_SW_ERR) {
6426 1.1 pooka #ifdef IWM_DEBUG
6427 1.1 pooka int i;
6428 1.1 pooka
6429 1.1 pooka iwm_nic_error(sc);
6430 1.1 pooka
6431 1.1 pooka /* Dump driver status (TX and RX rings) while we're here. */
6432 1.1 pooka DPRINTF(("driver status:\n"));
6433 1.1 pooka for (i = 0; i < IWM_MVM_MAX_QUEUES; i++) {
6434 1.1 pooka struct iwm_tx_ring *ring = &sc->txq[i];
6435 1.1 pooka DPRINTF((" tx ring %2d: qid=%-2d cur=%-3d "
6436 1.1 pooka "queued=%-3d\n",
6437 1.1 pooka i, ring->qid, ring->cur, ring->queued));
6438 1.1 pooka }
6439 1.1 pooka DPRINTF((" rx ring: cur=%d\n", sc->rxq.cur));
6440 1.1 pooka DPRINTF((" 802.11 state %d\n", sc->sc_ic.ic_state));
6441 1.1 pooka #endif
6442 1.1 pooka
6443 1.3 nonaka aprint_error_dev(sc->sc_dev, "fatal firmware error\n");
6444 1.1 pooka ifp->if_flags &= ~IFF_UP;
6445 1.1 pooka iwm_stop(ifp, 1);
6446 1.1 pooka rv = 1;
6447 1.1 pooka goto out;
6448 1.1 pooka
6449 1.1 pooka }
6450 1.1 pooka
6451 1.1 pooka if (r1 & IWM_CSR_INT_BIT_HW_ERR) {
6452 1.1 pooka handled |= IWM_CSR_INT_BIT_HW_ERR;
6453 1.3 nonaka aprint_error_dev(sc->sc_dev,
6454 1.3 nonaka "hardware error, stopping device\n");
6455 1.1 pooka ifp->if_flags &= ~IFF_UP;
6456 1.1 pooka iwm_stop(ifp, 1);
6457 1.1 pooka rv = 1;
6458 1.1 pooka goto out;
6459 1.1 pooka }
6460 1.1 pooka
6461 1.1 pooka /* firmware chunk loaded */
6462 1.1 pooka if (r1 & IWM_CSR_INT_BIT_FH_TX) {
6463 1.1 pooka IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_TX_MASK);
6464 1.1 pooka handled |= IWM_CSR_INT_BIT_FH_TX;
6465 1.1 pooka
6466 1.1 pooka sc->sc_fw_chunk_done = 1;
6467 1.1 pooka wakeup(&sc->sc_fw);
6468 1.1 pooka }
6469 1.1 pooka
6470 1.1 pooka if (r1 & IWM_CSR_INT_BIT_RF_KILL) {
6471 1.1 pooka handled |= IWM_CSR_INT_BIT_RF_KILL;
6472 1.1 pooka if (iwm_check_rfkill(sc) && (ifp->if_flags & IFF_UP)) {
6473 1.2 nonaka DPRINTF(("%s: rfkill switch, disabling interface\n",
6474 1.2 nonaka DEVNAME(sc)));
6475 1.1 pooka ifp->if_flags &= ~IFF_UP;
6476 1.1 pooka iwm_stop(ifp, 1);
6477 1.1 pooka }
6478 1.1 pooka }
6479 1.1 pooka
6480 1.1 pooka /*
6481 1.1 pooka * The Linux driver uses periodic interrupts to avoid races.
6482 1.1 pooka * We cargo-cult like it's going out of fashion.
6483 1.1 pooka */
6484 1.1 pooka if (r1 & IWM_CSR_INT_BIT_RX_PERIODIC) {
6485 1.1 pooka handled |= IWM_CSR_INT_BIT_RX_PERIODIC;
6486 1.1 pooka IWM_WRITE(sc, IWM_CSR_INT, IWM_CSR_INT_BIT_RX_PERIODIC);
6487 1.1 pooka if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) == 0)
6488 1.1 pooka IWM_WRITE_1(sc,
6489 1.1 pooka IWM_CSR_INT_PERIODIC_REG, IWM_CSR_INT_PERIODIC_DIS);
6490 1.1 pooka isperiodic = 1;
6491 1.1 pooka }
6492 1.1 pooka
6493 1.1 pooka if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) || isperiodic) {
6494 1.1 pooka handled |= (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX);
6495 1.1 pooka IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_RX_MASK);
6496 1.1 pooka
6497 1.1 pooka iwm_notif_intr(sc);
6498 1.1 pooka
6499 1.1 pooka /* enable periodic interrupt, see above */
6500 1.1 pooka if (r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX) && !isperiodic)
6501 1.1 pooka IWM_WRITE_1(sc, IWM_CSR_INT_PERIODIC_REG,
6502 1.1 pooka IWM_CSR_INT_PERIODIC_ENA);
6503 1.1 pooka }
6504 1.1 pooka
6505 1.1 pooka if (__predict_false(r1 & ~handled))
6506 1.2 nonaka DPRINTF(("%s: unhandled interrupts: %x\n", DEVNAME(sc), r1));
6507 1.1 pooka rv = 1;
6508 1.1 pooka
6509 1.1 pooka out_ena:
6510 1.1 pooka iwm_restore_interrupts(sc);
6511 1.1 pooka out:
6512 1.1 pooka return rv;
6513 1.1 pooka }
6514 1.1 pooka
6515 1.1 pooka /*
6516 1.1 pooka * Autoconf glue-sniffing
6517 1.1 pooka */
6518 1.1 pooka
6519 1.1 pooka static const pci_product_id_t iwm_devices[] = {
6520 1.5 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_7260_1,
6521 1.5 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_7260_2,
6522 1.5 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_3160_1,
6523 1.5 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_3160_2,
6524 1.5 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_7265_1,
6525 1.5 nonaka PCI_PRODUCT_INTEL_WIFI_LINK_7265_2,
6526 1.1 pooka };
6527 1.1 pooka
6528 1.1 pooka static int
6529 1.4 nonaka iwm_match(device_t parent, cfdata_t match __unused, void *aux)
6530 1.1 pooka {
6531 1.1 pooka struct pci_attach_args *pa = aux;
6532 1.1 pooka
6533 1.1 pooka if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
6534 1.1 pooka return 0;
6535 1.1 pooka
6536 1.5 nonaka for (size_t i = 0; i < __arraycount(iwm_devices); i++)
6537 1.1 pooka if (PCI_PRODUCT(pa->pa_id) == iwm_devices[i])
6538 1.1 pooka return 1;
6539 1.1 pooka
6540 1.1 pooka return 0;
6541 1.1 pooka }
6542 1.1 pooka
6543 1.4 nonaka static int
6544 1.1 pooka iwm_preinit(struct iwm_softc *sc)
6545 1.1 pooka {
6546 1.36 nonaka struct ieee80211com *ic = &sc->sc_ic;
6547 1.1 pooka int error;
6548 1.1 pooka
6549 1.2 nonaka if (sc->sc_flags & IWM_FLAG_ATTACHED)
6550 1.2 nonaka return 0;
6551 1.1 pooka
6552 1.2 nonaka if ((error = iwm_start_hw(sc)) != 0) {
6553 1.3 nonaka aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
6554 1.1 pooka return error;
6555 1.1 pooka }
6556 1.1 pooka
6557 1.2 nonaka error = iwm_run_init_mvm_ucode(sc, 1);
6558 1.1 pooka iwm_stop_device(sc);
6559 1.36 nonaka if (error)
6560 1.36 nonaka return error;
6561 1.1 pooka
6562 1.2 nonaka sc->sc_flags |= IWM_FLAG_ATTACHED;
6563 1.1 pooka
6564 1.3 nonaka aprint_normal_dev(sc->sc_dev,
6565 1.3 nonaka "hw rev: 0x%x, fw ver %d.%d (API ver %d), address %s\n",
6566 1.3 nonaka sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK,
6567 1.1 pooka IWM_UCODE_MAJOR(sc->sc_fwver),
6568 1.1 pooka IWM_UCODE_MINOR(sc->sc_fwver),
6569 1.1 pooka IWM_UCODE_API(sc->sc_fwver),
6570 1.1 pooka ether_sprintf(sc->sc_nvm.hw_addr));
6571 1.8 nonaka
6572 1.29 nonaka /* not all hardware can do 5GHz band */
6573 1.29 nonaka if (sc->sc_nvm.sku_cap_band_52GHz_enable)
6574 1.29 nonaka ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a;
6575 1.1 pooka
6576 1.1 pooka ieee80211_ifattach(ic);
6577 1.1 pooka
6578 1.1 pooka ic->ic_node_alloc = iwm_node_alloc;
6579 1.1 pooka
6580 1.1 pooka /* Override 802.11 state transition machine. */
6581 1.1 pooka sc->sc_newstate = ic->ic_newstate;
6582 1.1 pooka ic->ic_newstate = iwm_newstate;
6583 1.1 pooka ieee80211_media_init(ic, iwm_media_change, ieee80211_media_status);
6584 1.1 pooka ieee80211_announce(ic);
6585 1.1 pooka
6586 1.1 pooka iwm_radiotap_attach(sc);
6587 1.1 pooka
6588 1.36 nonaka return 0;
6589 1.36 nonaka }
6590 1.36 nonaka
6591 1.36 nonaka static void
6592 1.36 nonaka iwm_attach_hook(device_t dev)
6593 1.36 nonaka {
6594 1.36 nonaka struct iwm_softc *sc = device_private(dev);
6595 1.30 nonaka
6596 1.36 nonaka iwm_preinit(sc);
6597 1.1 pooka }
6598 1.1 pooka
6599 1.4 nonaka static void
6600 1.4 nonaka iwm_attach(device_t parent, device_t self, void *aux)
6601 1.1 pooka {
6602 1.1 pooka struct iwm_softc *sc = device_private(self);
6603 1.1 pooka struct pci_attach_args *pa = aux;
6604 1.36 nonaka struct ieee80211com *ic = &sc->sc_ic;
6605 1.36 nonaka struct ifnet *ifp = &sc->sc_ec.ec_if;
6606 1.1 pooka pcireg_t reg, memtype;
6607 1.37 nonaka char intrbuf[PCI_INTRSTR_LEN];
6608 1.1 pooka const char *intrstr;
6609 1.1 pooka int error;
6610 1.2 nonaka int txq_i;
6611 1.36 nonaka const struct sysctlnode *node;
6612 1.1 pooka
6613 1.3 nonaka sc->sc_dev = self;
6614 1.1 pooka sc->sc_pct = pa->pa_pc;
6615 1.1 pooka sc->sc_pcitag = pa->pa_tag;
6616 1.1 pooka sc->sc_dmat = pa->pa_dmat;
6617 1.5 nonaka sc->sc_pciid = pa->pa_id;
6618 1.1 pooka
6619 1.1 pooka pci_aprint_devinfo(pa, NULL);
6620 1.1 pooka
6621 1.1 pooka /*
6622 1.1 pooka * Get the offset of the PCI Express Capability Structure in PCI
6623 1.1 pooka * Configuration Space.
6624 1.1 pooka */
6625 1.1 pooka error = pci_get_capability(sc->sc_pct, sc->sc_pcitag,
6626 1.1 pooka PCI_CAP_PCIEXPRESS, &sc->sc_cap_off, NULL);
6627 1.1 pooka if (error == 0) {
6628 1.3 nonaka aprint_error_dev(self,
6629 1.3 nonaka "PCIe capability structure not found!\n");
6630 1.1 pooka return;
6631 1.1 pooka }
6632 1.1 pooka
6633 1.1 pooka /* Clear device-specific "PCI retry timeout" register (41h). */
6634 1.1 pooka reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
6635 1.1 pooka pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
6636 1.1 pooka
6637 1.1 pooka /* Enable bus-mastering and hardware bug workaround. */
6638 1.1 pooka reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
6639 1.1 pooka reg |= PCI_COMMAND_MASTER_ENABLE;
6640 1.1 pooka /* if !MSI */
6641 1.1 pooka if (reg & PCI_COMMAND_INTERRUPT_DISABLE) {
6642 1.1 pooka reg &= ~PCI_COMMAND_INTERRUPT_DISABLE;
6643 1.1 pooka }
6644 1.1 pooka pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
6645 1.1 pooka
6646 1.1 pooka memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START);
6647 1.1 pooka error = pci_mapreg_map(pa, PCI_MAPREG_START, memtype, 0,
6648 1.1 pooka &sc->sc_st, &sc->sc_sh, NULL, &sc->sc_sz);
6649 1.1 pooka if (error != 0) {
6650 1.3 nonaka aprint_error_dev(self, "can't map mem space\n");
6651 1.1 pooka return;
6652 1.1 pooka }
6653 1.1 pooka
6654 1.1 pooka /* Install interrupt handler. */
6655 1.37 nonaka error = pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0);
6656 1.31 nonaka if (error != 0) {
6657 1.37 nonaka aprint_error_dev(self, "can't allocate interrupt\n");
6658 1.1 pooka return;
6659 1.1 pooka }
6660 1.31 nonaka intrstr = pci_intr_string(sc->sc_pct, sc->sc_pihp[0], intrbuf,
6661 1.31 nonaka sizeof(intrbuf));
6662 1.33 knakahar sc->sc_ih = pci_intr_establish(sc->sc_pct, sc->sc_pihp[0], IPL_NET,
6663 1.33 knakahar iwm_intr, sc);
6664 1.1 pooka if (sc->sc_ih == NULL) {
6665 1.3 nonaka aprint_error_dev(self, "can't establish interrupt");
6666 1.1 pooka if (intrstr != NULL)
6667 1.3 nonaka aprint_error(" at %s", intrstr);
6668 1.3 nonaka aprint_error("\n");
6669 1.1 pooka return;
6670 1.1 pooka }
6671 1.3 nonaka aprint_normal_dev(self, "interrupting at %s\n", intrstr);
6672 1.1 pooka
6673 1.5 nonaka sc->sc_wantresp = -1;
6674 1.5 nonaka
6675 1.5 nonaka switch (PCI_PRODUCT(sc->sc_pciid)) {
6676 1.5 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_7260_1:
6677 1.5 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_7260_2:
6678 1.5 nonaka sc->sc_fwname = "iwlwifi-7260-9.ucode";
6679 1.17 nonaka sc->host_interrupt_operation_mode = 1;
6680 1.5 nonaka break;
6681 1.5 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_3160_1:
6682 1.5 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_3160_2:
6683 1.5 nonaka sc->sc_fwname = "iwlwifi-3160-9.ucode";
6684 1.17 nonaka sc->host_interrupt_operation_mode = 1;
6685 1.5 nonaka break;
6686 1.5 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_7265_1:
6687 1.5 nonaka case PCI_PRODUCT_INTEL_WIFI_LINK_7265_2:
6688 1.5 nonaka sc->sc_fwname = "iwlwifi-7265-9.ucode";
6689 1.17 nonaka sc->host_interrupt_operation_mode = 0;
6690 1.5 nonaka break;
6691 1.5 nonaka default:
6692 1.5 nonaka aprint_error_dev(self, "unknown product %#x",
6693 1.5 nonaka PCI_PRODUCT(sc->sc_pciid));
6694 1.5 nonaka return;
6695 1.5 nonaka }
6696 1.5 nonaka DPRINTF(("%s: firmware=%s\n", DEVNAME(sc), sc->sc_fwname));
6697 1.2 nonaka sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
6698 1.2 nonaka
6699 1.2 nonaka /*
6700 1.2 nonaka * We now start fiddling with the hardware
6701 1.2 nonaka */
6702 1.2 nonaka
6703 1.2 nonaka sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV);
6704 1.2 nonaka if (iwm_prepare_card_hw(sc) != 0) {
6705 1.3 nonaka aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
6706 1.2 nonaka return;
6707 1.2 nonaka }
6708 1.2 nonaka
6709 1.2 nonaka /* Allocate DMA memory for firmware transfers. */
6710 1.2 nonaka if ((error = iwm_alloc_fwmem(sc)) != 0) {
6711 1.3 nonaka aprint_error_dev(sc->sc_dev,
6712 1.3 nonaka "could not allocate memory for firmware\n");
6713 1.2 nonaka return;
6714 1.2 nonaka }
6715 1.2 nonaka
6716 1.2 nonaka /* Allocate "Keep Warm" page. */
6717 1.2 nonaka if ((error = iwm_alloc_kw(sc)) != 0) {
6718 1.3 nonaka aprint_error_dev(sc->sc_dev,
6719 1.3 nonaka "could not allocate keep warm page\n");
6720 1.2 nonaka goto fail1;
6721 1.2 nonaka }
6722 1.2 nonaka
6723 1.2 nonaka /* We use ICT interrupts */
6724 1.2 nonaka if ((error = iwm_alloc_ict(sc)) != 0) {
6725 1.3 nonaka aprint_error_dev(sc->sc_dev, "could not allocate ICT table\n");
6726 1.2 nonaka goto fail2;
6727 1.2 nonaka }
6728 1.2 nonaka
6729 1.2 nonaka /* Allocate TX scheduler "rings". */
6730 1.2 nonaka if ((error = iwm_alloc_sched(sc)) != 0) {
6731 1.3 nonaka aprint_error_dev(sc->sc_dev,
6732 1.3 nonaka "could not allocate TX scheduler rings\n");
6733 1.2 nonaka goto fail3;
6734 1.2 nonaka }
6735 1.2 nonaka
6736 1.2 nonaka /* Allocate TX rings */
6737 1.2 nonaka for (txq_i = 0; txq_i < __arraycount(sc->txq); txq_i++) {
6738 1.2 nonaka if ((error = iwm_alloc_tx_ring(sc,
6739 1.2 nonaka &sc->txq[txq_i], txq_i)) != 0) {
6740 1.3 nonaka aprint_error_dev(sc->sc_dev,
6741 1.3 nonaka "could not allocate TX ring %d\n", txq_i);
6742 1.2 nonaka goto fail4;
6743 1.2 nonaka }
6744 1.2 nonaka }
6745 1.2 nonaka
6746 1.2 nonaka /* Allocate RX ring. */
6747 1.2 nonaka if ((error = iwm_alloc_rx_ring(sc, &sc->rxq)) != 0) {
6748 1.3 nonaka aprint_error_dev(sc->sc_dev, "could not allocate RX ring\n");
6749 1.2 nonaka goto fail4;
6750 1.2 nonaka }
6751 1.2 nonaka
6752 1.2 nonaka workqueue_create(&sc->sc_eswq, "iwmes",
6753 1.5 nonaka iwm_endscan_cb, sc, PRI_NONE, IPL_NET, 0);
6754 1.2 nonaka workqueue_create(&sc->sc_nswq, "iwmns",
6755 1.5 nonaka iwm_newstate_cb, sc, PRI_NONE, IPL_NET, 0);
6756 1.2 nonaka
6757 1.2 nonaka /* Clear pending interrupts. */
6758 1.2 nonaka IWM_WRITE(sc, IWM_CSR_INT, 0xffffffff);
6759 1.2 nonaka
6760 1.36 nonaka if ((error = sysctl_createv(&sc->sc_clog, 0, NULL, &node,
6761 1.36 nonaka 0, CTLTYPE_NODE, device_xname(sc->sc_dev),
6762 1.36 nonaka SYSCTL_DESCR("iwm per-controller controls"),
6763 1.36 nonaka NULL, 0, NULL, 0,
6764 1.36 nonaka CTL_HW, iwm_sysctl_root_num, CTL_CREATE,
6765 1.36 nonaka CTL_EOL)) != 0) {
6766 1.36 nonaka aprint_normal_dev(sc->sc_dev,
6767 1.36 nonaka "couldn't create iwm per-controller sysctl node\n");
6768 1.36 nonaka }
6769 1.36 nonaka if (error == 0) {
6770 1.36 nonaka int iwm_nodenum = node->sysctl_num;
6771 1.36 nonaka
6772 1.36 nonaka /* Reload firmware sysctl node */
6773 1.36 nonaka if ((error = sysctl_createv(&sc->sc_clog, 0, NULL, &node,
6774 1.36 nonaka CTLFLAG_READWRITE, CTLTYPE_INT, "fw_loaded",
6775 1.36 nonaka SYSCTL_DESCR("Reload firmware"),
6776 1.36 nonaka iwm_sysctl_fw_loaded_handler, 0, (void *)sc, 0,
6777 1.36 nonaka CTL_HW, iwm_sysctl_root_num, iwm_nodenum, CTL_CREATE,
6778 1.36 nonaka CTL_EOL)) != 0) {
6779 1.36 nonaka aprint_normal_dev(sc->sc_dev,
6780 1.36 nonaka "couldn't create load_fw sysctl node\n");
6781 1.36 nonaka }
6782 1.36 nonaka }
6783 1.36 nonaka
6784 1.36 nonaka /*
6785 1.36 nonaka * Attach interface
6786 1.36 nonaka */
6787 1.36 nonaka ic->ic_ifp = ifp;
6788 1.36 nonaka ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
6789 1.36 nonaka ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
6790 1.36 nonaka ic->ic_state = IEEE80211_S_INIT;
6791 1.36 nonaka
6792 1.36 nonaka /* Set device capabilities. */
6793 1.36 nonaka ic->ic_caps =
6794 1.36 nonaka IEEE80211_C_WEP | /* WEP */
6795 1.36 nonaka IEEE80211_C_WPA | /* 802.11i */
6796 1.36 nonaka IEEE80211_C_SHSLOT | /* short slot time supported */
6797 1.36 nonaka IEEE80211_C_SHPREAMBLE; /* short preamble supported */
6798 1.36 nonaka
6799 1.36 nonaka /* all hardware can do 2.4GHz band */
6800 1.36 nonaka ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
6801 1.36 nonaka ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
6802 1.36 nonaka
6803 1.36 nonaka for (int i = 0; i < __arraycount(sc->sc_phyctxt); i++) {
6804 1.36 nonaka sc->sc_phyctxt[i].id = i;
6805 1.36 nonaka }
6806 1.36 nonaka
6807 1.36 nonaka sc->sc_amrr.amrr_min_success_threshold = 1;
6808 1.36 nonaka sc->sc_amrr.amrr_max_success_threshold = 15;
6809 1.36 nonaka
6810 1.36 nonaka /* IBSS channel undefined for now. */
6811 1.36 nonaka ic->ic_ibss_chan = &ic->ic_channels[1];
6812 1.36 nonaka
6813 1.36 nonaka #if 0
6814 1.36 nonaka /* Max RSSI */
6815 1.36 nonaka ic->ic_max_rssi = IWM_MAX_DBM - IWM_MIN_DBM;
6816 1.36 nonaka #endif
6817 1.36 nonaka
6818 1.36 nonaka ifp->if_softc = sc;
6819 1.36 nonaka ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
6820 1.36 nonaka ifp->if_init = iwm_init;
6821 1.36 nonaka ifp->if_stop = iwm_stop;
6822 1.36 nonaka ifp->if_ioctl = iwm_ioctl;
6823 1.36 nonaka ifp->if_start = iwm_start;
6824 1.36 nonaka ifp->if_watchdog = iwm_watchdog;
6825 1.36 nonaka IFQ_SET_READY(&ifp->if_snd);
6826 1.36 nonaka memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
6827 1.36 nonaka
6828 1.36 nonaka if_initialize(ifp);
6829 1.36 nonaka #if 0
6830 1.36 nonaka ieee80211_ifattach(ic);
6831 1.36 nonaka #else
6832 1.36 nonaka ether_ifattach(ifp, ic->ic_myaddr); /* XXX */
6833 1.36 nonaka #endif
6834 1.36 nonaka if_register(ifp);
6835 1.40 ozaki /* Use common softint-based if_input */
6836 1.40 ozaki ifp->if_percpuq = if_percpuq_create(ifp);
6837 1.36 nonaka
6838 1.36 nonaka callout_init(&sc->sc_calib_to, 0);
6839 1.36 nonaka callout_setfunc(&sc->sc_calib_to, iwm_calib_timeout, sc);
6840 1.36 nonaka
6841 1.36 nonaka //task_set(&sc->init_task, iwm_init_task, sc);
6842 1.36 nonaka
6843 1.36 nonaka if (pmf_device_register(self, NULL, NULL))
6844 1.36 nonaka pmf_class_network_register(self, ifp);
6845 1.36 nonaka else
6846 1.36 nonaka aprint_error_dev(self, "couldn't establish power handler\n");
6847 1.36 nonaka
6848 1.1 pooka /*
6849 1.1 pooka * We can't do normal attach before the file system is mounted
6850 1.1 pooka * because we cannot read the MAC address without loading the
6851 1.1 pooka * firmware from disk. So we postpone until mountroot is done.
6852 1.1 pooka * Notably, this will require a full driver unload/load cycle
6853 1.1 pooka * (or reboot) in case the firmware is not present when the
6854 1.1 pooka * hook runs.
6855 1.1 pooka */
6856 1.1 pooka config_mountroot(self, iwm_attach_hook);
6857 1.2 nonaka
6858 1.2 nonaka return;
6859 1.2 nonaka
6860 1.2 nonaka /* Free allocated memory if something failed during attachment. */
6861 1.2 nonaka fail4: while (--txq_i >= 0)
6862 1.2 nonaka iwm_free_tx_ring(sc, &sc->txq[txq_i]);
6863 1.2 nonaka iwm_free_sched(sc);
6864 1.2 nonaka fail3: if (sc->ict_dma.vaddr != NULL)
6865 1.2 nonaka iwm_free_ict(sc);
6866 1.2 nonaka fail2: iwm_free_kw(sc);
6867 1.2 nonaka fail1: iwm_free_fwmem(sc);
6868 1.1 pooka }
6869 1.1 pooka
6870 1.1 pooka /*
6871 1.1 pooka * Attach the interface to 802.11 radiotap.
6872 1.1 pooka */
6873 1.1 pooka void
6874 1.1 pooka iwm_radiotap_attach(struct iwm_softc *sc)
6875 1.1 pooka {
6876 1.1 pooka struct ifnet *ifp = sc->sc_ic.ic_ifp;
6877 1.1 pooka
6878 1.1 pooka bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
6879 1.1 pooka sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
6880 1.1 pooka &sc->sc_drvbpf);
6881 1.1 pooka
6882 1.1 pooka sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
6883 1.1 pooka sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
6884 1.1 pooka sc->sc_rxtap.wr_ihdr.it_present = htole32(IWM_RX_RADIOTAP_PRESENT);
6885 1.1 pooka
6886 1.1 pooka sc->sc_txtap_len = sizeof sc->sc_txtapu;
6887 1.1 pooka sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
6888 1.1 pooka sc->sc_txtap.wt_ihdr.it_present = htole32(IWM_TX_RADIOTAP_PRESENT);
6889 1.1 pooka }
6890 1.1 pooka
6891 1.1 pooka #if 0
6892 1.4 nonaka static void
6893 1.1 pooka iwm_init_task(void *arg1)
6894 1.1 pooka {
6895 1.1 pooka struct iwm_softc *sc = arg1;
6896 1.1 pooka struct ifnet *ifp = &sc->sc_ic.ic_if;
6897 1.1 pooka int s;
6898 1.8 nonaka
6899 1.1 pooka s = splnet();
6900 1.1 pooka while (sc->sc_flags & IWM_FLAG_BUSY)
6901 1.1 pooka tsleep(&sc->sc_flags, 0, "iwmpwr", 0);
6902 1.1 pooka sc->sc_flags |= IWM_FLAG_BUSY;
6903 1.8 nonaka
6904 1.1 pooka iwm_stop(ifp, 0);
6905 1.1 pooka if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
6906 1.1 pooka iwm_init(ifp);
6907 1.1 pooka
6908 1.1 pooka sc->sc_flags &= ~IWM_FLAG_BUSY;
6909 1.1 pooka wakeup(&sc->sc_flags);
6910 1.1 pooka splx(s);
6911 1.1 pooka }
6912 1.1 pooka
6913 1.4 nonaka static void
6914 1.1 pooka iwm_wakeup(struct iwm_softc *sc)
6915 1.1 pooka {
6916 1.1 pooka pcireg_t reg;
6917 1.1 pooka
6918 1.1 pooka /* Clear device-specific "PCI retry timeout" register (41h). */
6919 1.1 pooka reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
6920 1.1 pooka pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
6921 1.1 pooka
6922 1.1 pooka iwm_init_task(sc);
6923 1.1 pooka }
6924 1.1 pooka
6925 1.4 nonaka static int
6926 1.4 nonaka iwm_activate(device_t self, enum devact act)
6927 1.1 pooka {
6928 1.4 nonaka struct iwm_softc *sc = device_private(self);
6929 1.4 nonaka struct ifnet *ifp = IC2IFP(&sc->sc_ic);
6930 1.1 pooka
6931 1.1 pooka switch (act) {
6932 1.4 nonaka case DVACT_DEACTIVATE:
6933 1.1 pooka if (ifp->if_flags & IFF_RUNNING)
6934 1.1 pooka iwm_stop(ifp, 0);
6935 1.4 nonaka return 0;
6936 1.4 nonaka default:
6937 1.4 nonaka return EOPNOTSUPP;
6938 1.1 pooka }
6939 1.1 pooka }
6940 1.1 pooka #endif
6941 1.1 pooka
6942 1.1 pooka CFATTACH_DECL_NEW(iwm, sizeof(struct iwm_softc), iwm_match, iwm_attach,
6943 1.1 pooka NULL, NULL);
6944 1.32 nonaka
6945 1.36 nonaka static int
6946 1.36 nonaka iwm_sysctl_fw_loaded_handler(SYSCTLFN_ARGS)
6947 1.36 nonaka {
6948 1.36 nonaka struct sysctlnode node;
6949 1.36 nonaka struct iwm_softc *sc;
6950 1.36 nonaka int error, t;
6951 1.36 nonaka
6952 1.36 nonaka node = *rnode;
6953 1.36 nonaka sc = node.sysctl_data;
6954 1.36 nonaka t = ISSET(sc->sc_flags, IWM_FLAG_FW_LOADED) ? 1 : 0;
6955 1.36 nonaka node.sysctl_data = &t;
6956 1.36 nonaka error = sysctl_lookup(SYSCTLFN_CALL(&node));
6957 1.36 nonaka if (error || newp == NULL)
6958 1.36 nonaka return error;
6959 1.36 nonaka
6960 1.36 nonaka if (t == 0)
6961 1.36 nonaka CLR(sc->sc_flags, IWM_FLAG_FW_LOADED);
6962 1.36 nonaka return 0;
6963 1.36 nonaka }
6964 1.36 nonaka
6965 1.32 nonaka SYSCTL_SETUP(sysctl_iwm, "sysctl iwm(4) subtree setup")
6966 1.32 nonaka {
6967 1.36 nonaka const struct sysctlnode *rnode;
6968 1.36 nonaka #ifdef IWM_DEBUG
6969 1.36 nonaka const struct sysctlnode *cnode;
6970 1.36 nonaka #endif /* IWM_DEBUG */
6971 1.32 nonaka int rc;
6972 1.32 nonaka
6973 1.32 nonaka if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
6974 1.32 nonaka CTLFLAG_PERMANENT, CTLTYPE_NODE, "iwm",
6975 1.32 nonaka SYSCTL_DESCR("iwm global controls"),
6976 1.32 nonaka NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
6977 1.32 nonaka goto err;
6978 1.32 nonaka
6979 1.36 nonaka iwm_sysctl_root_num = rnode->sysctl_num;
6980 1.36 nonaka
6981 1.36 nonaka #ifdef IWM_DEBUG
6982 1.32 nonaka /* control debugging printfs */
6983 1.32 nonaka if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
6984 1.32 nonaka CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
6985 1.32 nonaka "debug", SYSCTL_DESCR("Enable debugging output"),
6986 1.32 nonaka NULL, 0, &iwm_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
6987 1.32 nonaka goto err;
6988 1.36 nonaka #endif /* IWM_DEBUG */
6989 1.32 nonaka
6990 1.32 nonaka return;
6991 1.32 nonaka
6992 1.32 nonaka err:
6993 1.32 nonaka aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
6994 1.32 nonaka }
6995