xref: /freebsd/sys/dev/bwn/if_bwn.c (revision 4a4bcdc6aa3eb99948a369fe16f5cecf5828e1bb)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
5  * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org>
6  * Copyright (c) 2017 The FreeBSD Foundation
7  * All rights reserved.
8  *
9  * Portions of this software were developed by Landon Fuller
10  * under sponsorship from the FreeBSD Foundation.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
20  *    redistribution must be conditioned upon including a substantially
21  *    similar Disclaimer requirement for further binary redistribution.
22  *
23  * NO WARRANTY
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
27  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
28  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
29  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
32  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34  * THE POSSIBILITY OF SUCH DAMAGES.
35  */
36 
37 #include <sys/cdefs.h>
38 /*
39  * The Broadcom Wireless LAN controller driver.
40  */
41 
42 #include "opt_bwn.h"
43 #include "opt_wlan.h"
44 
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/gpio.h>
49 #include <sys/malloc.h>
50 #include <sys/module.h>
51 #include <sys/endian.h>
52 #include <sys/errno.h>
53 #include <sys/firmware.h>
54 #include <sys/lock.h>
55 #include <sys/mutex.h>
56 #include <machine/bus.h>
57 #include <machine/resource.h>
58 #include <sys/bus.h>
59 #include <sys/rman.h>
60 #include <sys/socket.h>
61 #include <sys/sockio.h>
62 
63 #include <net/ethernet.h>
64 #include <net/if.h>
65 #include <net/if_var.h>
66 #include <net/if_arp.h>
67 #include <net/if_dl.h>
68 #include <net/if_llc.h>
69 #include <net/if_media.h>
70 #include <net/if_types.h>
71 
72 #include <net80211/ieee80211_var.h>
73 #include <net80211/ieee80211_radiotap.h>
74 #include <net80211/ieee80211_regdomain.h>
75 #include <net80211/ieee80211_phy.h>
76 #include <net80211/ieee80211_ratectl.h>
77 
78 #include <dev/bhnd/bhnd.h>
79 #include <dev/bhnd/bhnd_ids.h>
80 
81 #include <dev/bhnd/cores/chipc/chipc.h>
82 #include <dev/bhnd/cores/pmu/bhnd_pmu.h>
83 
84 #include <dev/bwn/if_bwnreg.h>
85 #include <dev/bwn/if_bwnvar.h>
86 
87 #include <dev/bwn/if_bwn_debug.h>
88 #include <dev/bwn/if_bwn_misc.h>
89 #include <dev/bwn/if_bwn_util.h>
90 #include <dev/bwn/if_bwn_phy_common.h>
91 #include <dev/bwn/if_bwn_phy_g.h>
92 #include <dev/bwn/if_bwn_phy_lp.h>
93 #include <dev/bwn/if_bwn_phy_n.h>
94 
95 #include "bhnd_nvram_map.h"
96 
97 #include "gpio_if.h"
98 
99 static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
100     "Broadcom driver parameters");
101 
102 /*
103  * Tunable & sysctl variables.
104  */
105 
106 #ifdef BWN_DEBUG
107 static	int bwn_debug = 0;
108 SYSCTL_INT(_hw_bwn, OID_AUTO, debug, CTLFLAG_RWTUN, &bwn_debug, 0,
109     "Broadcom debugging printfs");
110 #endif
111 
112 static int	bwn_bfp = 0;		/* use "Bad Frames Preemption" */
113 SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
114     "uses Bad Frames Preemption");
115 static int	bwn_bluetooth = 1;
116 SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, &bwn_bluetooth, 0,
117     "turns on Bluetooth Coexistence");
118 static int	bwn_hwpctl = 0;
119 SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0,
120     "uses H/W power control");
121 static int	bwn_usedma = 1;
122 SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0,
123     "uses DMA");
124 TUNABLE_INT("hw.bwn.usedma", &bwn_usedma);
125 static int	bwn_wme = 1;
126 SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
127     "uses WME support");
128 
129 static void	bwn_attach_pre(struct bwn_softc *);
130 static int	bwn_attach_post(struct bwn_softc *);
131 static int	bwn_retain_bus_providers(struct bwn_softc *sc);
132 static void	bwn_release_bus_providers(struct bwn_softc *sc);
133 static void	bwn_sprom_bugfixes(device_t);
134 static int	bwn_init(struct bwn_softc *);
135 static void	bwn_parent(struct ieee80211com *);
136 static void	bwn_start(struct bwn_softc *);
137 static int	bwn_transmit(struct ieee80211com *, struct mbuf *);
138 static int	bwn_attach_core(struct bwn_mac *);
139 static int	bwn_phy_getinfo(struct bwn_mac *, int);
140 static int	bwn_chiptest(struct bwn_mac *);
141 static int	bwn_setup_channels(struct bwn_mac *, int, int);
142 static void	bwn_shm_ctlword(struct bwn_mac *, uint16_t,
143 		    uint16_t);
144 static void	bwn_addchannels(struct ieee80211_channel [], int, int *,
145 		    const struct bwn_channelinfo *, const uint8_t []);
146 static int	bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
147 		    const struct ieee80211_bpf_params *);
148 static void	bwn_updateslot(struct ieee80211com *);
149 static void	bwn_update_promisc(struct ieee80211com *);
150 static void	bwn_wme_init(struct bwn_mac *);
151 static int	bwn_wme_update(struct ieee80211com *);
152 static void	bwn_wme_clear(struct bwn_softc *);
153 static void	bwn_wme_load(struct bwn_mac *);
154 static void	bwn_wme_loadparams(struct bwn_mac *,
155 		    const struct wmeParams *, uint16_t);
156 static void	bwn_scan_start(struct ieee80211com *);
157 static void	bwn_scan_end(struct ieee80211com *);
158 static void	bwn_set_channel(struct ieee80211com *);
159 static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
160 		    const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
161 		    const uint8_t [IEEE80211_ADDR_LEN],
162 		    const uint8_t [IEEE80211_ADDR_LEN]);
163 static void	bwn_vap_delete(struct ieee80211vap *);
164 static void	bwn_stop(struct bwn_softc *);
165 static int	bwn_core_forceclk(struct bwn_mac *, bool);
166 static int	bwn_core_init(struct bwn_mac *);
167 static void	bwn_core_start(struct bwn_mac *);
168 static void	bwn_core_exit(struct bwn_mac *);
169 static void	bwn_bt_disable(struct bwn_mac *);
170 static int	bwn_chip_init(struct bwn_mac *);
171 static void	bwn_set_txretry(struct bwn_mac *, int, int);
172 static void	bwn_rate_init(struct bwn_mac *);
173 static void	bwn_set_phytxctl(struct bwn_mac *);
174 static void	bwn_spu_setdelay(struct bwn_mac *, int);
175 static void	bwn_bt_enable(struct bwn_mac *);
176 static void	bwn_set_macaddr(struct bwn_mac *);
177 static void	bwn_crypt_init(struct bwn_mac *);
178 static void	bwn_chip_exit(struct bwn_mac *);
179 static int	bwn_fw_fillinfo(struct bwn_mac *);
180 static int	bwn_fw_loaducode(struct bwn_mac *);
181 static int	bwn_gpio_init(struct bwn_mac *);
182 static int	bwn_fw_loadinitvals(struct bwn_mac *);
183 static int	bwn_phy_init(struct bwn_mac *);
184 static void	bwn_set_txantenna(struct bwn_mac *, int);
185 static void	bwn_set_opmode(struct bwn_mac *);
186 static void	bwn_rate_write(struct bwn_mac *, uint16_t, int);
187 static uint8_t	bwn_plcp_getcck(const uint8_t);
188 static uint8_t	bwn_plcp_getofdm(const uint8_t);
189 static void	bwn_pio_init(struct bwn_mac *);
190 static uint16_t	bwn_pio_idx2base(struct bwn_mac *, int);
191 static void	bwn_pio_set_txqueue(struct bwn_mac *, struct bwn_pio_txqueue *,
192 		    int);
193 static void	bwn_pio_setupqueue_rx(struct bwn_mac *,
194 		    struct bwn_pio_rxqueue *, int);
195 static void	bwn_destroy_queue_tx(struct bwn_pio_txqueue *);
196 static uint16_t	bwn_pio_read_2(struct bwn_mac *, struct bwn_pio_txqueue *,
197 		    uint16_t);
198 static void	bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *);
199 static int	bwn_pio_rx(struct bwn_pio_rxqueue *);
200 static uint8_t	bwn_pio_rxeof(struct bwn_pio_rxqueue *);
201 static void	bwn_pio_handle_txeof(struct bwn_mac *,
202 		    const struct bwn_txstatus *);
203 static uint16_t	bwn_pio_rx_read_2(struct bwn_pio_rxqueue *, uint16_t);
204 static uint32_t	bwn_pio_rx_read_4(struct bwn_pio_rxqueue *, uint16_t);
205 static void	bwn_pio_rx_write_2(struct bwn_pio_rxqueue *, uint16_t,
206 		    uint16_t);
207 static void	bwn_pio_rx_write_4(struct bwn_pio_rxqueue *, uint16_t,
208 		    uint32_t);
209 static int	bwn_pio_tx_start(struct bwn_mac *, struct ieee80211_node *,
210 		    struct mbuf **);
211 static struct bwn_pio_txqueue *bwn_pio_select(struct bwn_mac *, uint8_t);
212 static uint32_t	bwn_pio_write_multi_4(struct bwn_mac *,
213 		    struct bwn_pio_txqueue *, uint32_t, const void *, int);
214 static void	bwn_pio_write_4(struct bwn_mac *, struct bwn_pio_txqueue *,
215 		    uint16_t, uint32_t);
216 static uint16_t	bwn_pio_write_multi_2(struct bwn_mac *,
217 		    struct bwn_pio_txqueue *, uint16_t, const void *, int);
218 static uint16_t	bwn_pio_write_mbuf_2(struct bwn_mac *,
219 		    struct bwn_pio_txqueue *, uint16_t, struct mbuf *);
220 static struct bwn_pio_txqueue *bwn_pio_parse_cookie(struct bwn_mac *,
221 		    uint16_t, struct bwn_pio_txpkt **);
222 static void	bwn_dma_init(struct bwn_mac *);
223 static void	bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t);
224 static uint16_t	bwn_dma_base(int, int);
225 static void	bwn_dma_ringfree(struct bwn_dma_ring **);
226 static void	bwn_dma_32_getdesc(struct bwn_dma_ring *,
227 		    int, struct bwn_dmadesc_generic **,
228 		    struct bwn_dmadesc_meta **);
229 static void	bwn_dma_32_setdesc(struct bwn_dma_ring *,
230 		    struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
231 		    int, int);
232 static void	bwn_dma_32_start_transfer(struct bwn_dma_ring *, int);
233 static void	bwn_dma_32_suspend(struct bwn_dma_ring *);
234 static void	bwn_dma_32_resume(struct bwn_dma_ring *);
235 static int	bwn_dma_32_get_curslot(struct bwn_dma_ring *);
236 static void	bwn_dma_32_set_curslot(struct bwn_dma_ring *, int);
237 static void	bwn_dma_64_getdesc(struct bwn_dma_ring *,
238 		    int, struct bwn_dmadesc_generic **,
239 		    struct bwn_dmadesc_meta **);
240 static void	bwn_dma_64_setdesc(struct bwn_dma_ring *,
241 		    struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int,
242 		    int, int);
243 static void	bwn_dma_64_start_transfer(struct bwn_dma_ring *, int);
244 static void	bwn_dma_64_suspend(struct bwn_dma_ring *);
245 static void	bwn_dma_64_resume(struct bwn_dma_ring *);
246 static int	bwn_dma_64_get_curslot(struct bwn_dma_ring *);
247 static void	bwn_dma_64_set_curslot(struct bwn_dma_ring *, int);
248 static int	bwn_dma_allocringmemory(struct bwn_dma_ring *);
249 static void	bwn_dma_setup(struct bwn_dma_ring *);
250 static void	bwn_dma_free_ringmemory(struct bwn_dma_ring *);
251 static void	bwn_dma_cleanup(struct bwn_dma_ring *);
252 static void	bwn_dma_free_descbufs(struct bwn_dma_ring *);
253 static int	bwn_dma_tx_reset(struct bwn_mac *, uint16_t, int);
254 static void	bwn_dma_rx(struct bwn_dma_ring *);
255 static int	bwn_dma_rx_reset(struct bwn_mac *, uint16_t, int);
256 static void	bwn_dma_free_descbuf(struct bwn_dma_ring *,
257 		    struct bwn_dmadesc_meta *);
258 static void	bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *);
259 static void	bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
260 static int	bwn_dma_freeslot(struct bwn_dma_ring *);
261 static int	bwn_dma_nextslot(struct bwn_dma_ring *, int);
262 static void	bwn_dma_rxeof(struct bwn_dma_ring *, int *);
263 static int	bwn_dma_newbuf(struct bwn_dma_ring *,
264 		    struct bwn_dmadesc_generic *, struct bwn_dmadesc_meta *,
265 		    int);
266 static void	bwn_dma_buf_addr(void *, bus_dma_segment_t *, int,
267 		    bus_size_t, int);
268 static uint8_t	bwn_dma_check_redzone(struct bwn_dma_ring *, struct mbuf *);
269 static void	bwn_ratectl_tx_complete(const struct ieee80211_node *,
270 		    const struct bwn_txstatus *);
271 static void	bwn_dma_handle_txeof(struct bwn_mac *,
272 		    const struct bwn_txstatus *);
273 static int	bwn_dma_tx_start(struct bwn_mac *, struct ieee80211_node *,
274 		    struct mbuf **);
275 static int	bwn_dma_getslot(struct bwn_dma_ring *);
276 static struct bwn_dma_ring *bwn_dma_select(struct bwn_mac *,
277 		    uint8_t);
278 static int	bwn_dma_attach(struct bwn_mac *);
279 static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *,
280 		    int, int);
281 static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *,
282 		    const struct bwn_txstatus *, uint16_t, int *);
283 static void	bwn_dma_free(struct bwn_mac *);
284 static int	bwn_fw_gets(struct bwn_mac *, enum bwn_fwtype);
285 static int	bwn_fw_get(struct bwn_mac *, enum bwn_fwtype,
286 		    const char *, struct bwn_fwfile *);
287 static void	bwn_release_firmware(struct bwn_mac *);
288 static void	bwn_do_release_fw(struct bwn_fwfile *);
289 static uint16_t	bwn_fwcaps_read(struct bwn_mac *);
290 static int	bwn_fwinitvals_write(struct bwn_mac *,
291 		    const struct bwn_fwinitvals *, size_t, size_t);
292 static uint16_t	bwn_ant2phy(int);
293 static void	bwn_mac_write_bssid(struct bwn_mac *);
294 static void	bwn_mac_setfilter(struct bwn_mac *, uint16_t,
295 		    const uint8_t *);
296 static void	bwn_key_dowrite(struct bwn_mac *, uint8_t, uint8_t,
297 		    const uint8_t *, size_t, const uint8_t *);
298 static void	bwn_key_macwrite(struct bwn_mac *, uint8_t,
299 		    const uint8_t *);
300 static void	bwn_key_write(struct bwn_mac *, uint8_t, uint8_t,
301 		    const uint8_t *);
302 static void	bwn_phy_exit(struct bwn_mac *);
303 static void	bwn_core_stop(struct bwn_mac *);
304 static int	bwn_switch_band(struct bwn_softc *,
305 		    struct ieee80211_channel *);
306 static int	bwn_phy_reset(struct bwn_mac *);
307 static int	bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
308 static void	bwn_set_pretbtt(struct bwn_mac *);
309 static int	bwn_intr(void *);
310 static void	bwn_intrtask(void *, int);
311 static void	bwn_restart(struct bwn_mac *, const char *);
312 static void	bwn_intr_ucode_debug(struct bwn_mac *);
313 static void	bwn_intr_tbtt_indication(struct bwn_mac *);
314 static void	bwn_intr_atim_end(struct bwn_mac *);
315 static void	bwn_intr_beacon(struct bwn_mac *);
316 static void	bwn_intr_pmq(struct bwn_mac *);
317 static void	bwn_intr_noise(struct bwn_mac *);
318 static void	bwn_intr_txeof(struct bwn_mac *);
319 static void	bwn_hwreset(void *, int);
320 static void	bwn_handle_fwpanic(struct bwn_mac *);
321 static void	bwn_load_beacon0(struct bwn_mac *);
322 static void	bwn_load_beacon1(struct bwn_mac *);
323 static uint32_t	bwn_jssi_read(struct bwn_mac *);
324 static void	bwn_noise_gensample(struct bwn_mac *);
325 static void	bwn_handle_txeof(struct bwn_mac *,
326 		    const struct bwn_txstatus *);
327 static void	bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
328 static void	bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
329 static int	bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
330 		    struct mbuf *);
331 static int	bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
332 static int	bwn_set_txhdr(struct bwn_mac *,
333 		    struct ieee80211_node *, struct mbuf *, struct bwn_txhdr *,
334 		    uint16_t);
335 static void	bwn_plcp_genhdr(struct bwn_plcp4 *, const uint16_t,
336 		    const uint8_t);
337 static uint8_t	bwn_antenna_sanitize(struct bwn_mac *, uint8_t);
338 static uint8_t	bwn_get_fbrate(uint8_t);
339 static void	bwn_txpwr(void *, int);
340 static void	bwn_tasks(void *);
341 static void	bwn_task_15s(struct bwn_mac *);
342 static void	bwn_task_30s(struct bwn_mac *);
343 static void	bwn_task_60s(struct bwn_mac *);
344 static int	bwn_plcp_get_ofdmrate(struct bwn_mac *, struct bwn_plcp6 *,
345 		    uint8_t);
346 static int	bwn_plcp_get_cckrate(struct bwn_mac *, struct bwn_plcp6 *);
347 static void	bwn_rx_radiotap(struct bwn_mac *, struct mbuf *,
348 		    const struct bwn_rxhdr4 *, struct bwn_plcp6 *, int,
349 		    int, int);
350 static void	bwn_tsf_read(struct bwn_mac *, uint64_t *);
351 static void	bwn_set_slot_time(struct bwn_mac *, uint16_t);
352 static void	bwn_watchdog(void *);
353 static void	bwn_dma_stop(struct bwn_mac *);
354 static void	bwn_pio_stop(struct bwn_mac *);
355 static void	bwn_dma_ringstop(struct bwn_dma_ring **);
356 static int	bwn_led_attach(struct bwn_mac *);
357 static void	bwn_led_newstate(struct bwn_mac *, enum ieee80211_state);
358 static void	bwn_led_event(struct bwn_mac *, int);
359 static void	bwn_led_blink_start(struct bwn_mac *, int, int);
360 static void	bwn_led_blink_next(void *);
361 static void	bwn_led_blink_end(void *);
362 static void	bwn_rfswitch(void *);
363 static void	bwn_rf_turnon(struct bwn_mac *);
364 static void	bwn_rf_turnoff(struct bwn_mac *);
365 static void	bwn_sysctl_node(struct bwn_softc *);
366 
367 static const struct bwn_channelinfo bwn_chantable_bg = {
368 	.channels = {
369 		{ 2412,  1, 30 }, { 2417,  2, 30 }, { 2422,  3, 30 },
370 		{ 2427,  4, 30 }, { 2432,  5, 30 }, { 2437,  6, 30 },
371 		{ 2442,  7, 30 }, { 2447,  8, 30 }, { 2452,  9, 30 },
372 		{ 2457, 10, 30 }, { 2462, 11, 30 }, { 2467, 12, 30 },
373 		{ 2472, 13, 30 }, { 2484, 14, 30 } },
374 	.nchannels = 14
375 };
376 
377 static const struct bwn_channelinfo bwn_chantable_a = {
378 	.channels = {
379 		{ 5170,  34, 30 }, { 5180,  36, 30 }, { 5190,  38, 30 },
380 		{ 5200,  40, 30 }, { 5210,  42, 30 }, { 5220,  44, 30 },
381 		{ 5230,  46, 30 }, { 5240,  48, 30 }, { 5260,  52, 30 },
382 		{ 5280,  56, 30 }, { 5300,  60, 30 }, { 5320,  64, 30 },
383 		{ 5500, 100, 30 }, { 5520, 104, 30 }, { 5540, 108, 30 },
384 		{ 5560, 112, 30 }, { 5580, 116, 30 }, { 5600, 120, 30 },
385 		{ 5620, 124, 30 }, { 5640, 128, 30 }, { 5660, 132, 30 },
386 		{ 5680, 136, 30 }, { 5700, 140, 30 }, { 5745, 149, 30 },
387 		{ 5765, 153, 30 }, { 5785, 157, 30 }, { 5805, 161, 30 },
388 		{ 5825, 165, 30 }, { 5920, 184, 30 }, { 5940, 188, 30 },
389 		{ 5960, 192, 30 }, { 5980, 196, 30 }, { 6000, 200, 30 },
390 		{ 6020, 204, 30 }, { 6040, 208, 30 }, { 6060, 212, 30 },
391 		{ 6080, 216, 30 } },
392 	.nchannels = 37
393 };
394 
395 #if 0
396 static const struct bwn_channelinfo bwn_chantable_n = {
397 	.channels = {
398 		{ 5160,  32, 30 }, { 5170,  34, 30 }, { 5180,  36, 30 },
399 		{ 5190,  38, 30 }, { 5200,  40, 30 }, { 5210,  42, 30 },
400 		{ 5220,  44, 30 }, { 5230,  46, 30 }, { 5240,  48, 30 },
401 		{ 5250,  50, 30 }, { 5260,  52, 30 }, { 5270,  54, 30 },
402 		{ 5280,  56, 30 }, { 5290,  58, 30 }, { 5300,  60, 30 },
403 		{ 5310,  62, 30 }, { 5320,  64, 30 }, { 5330,  66, 30 },
404 		{ 5340,  68, 30 }, { 5350,  70, 30 }, { 5360,  72, 30 },
405 		{ 5370,  74, 30 }, { 5380,  76, 30 }, { 5390,  78, 30 },
406 		{ 5400,  80, 30 }, { 5410,  82, 30 }, { 5420,  84, 30 },
407 		{ 5430,  86, 30 }, { 5440,  88, 30 }, { 5450,  90, 30 },
408 		{ 5460,  92, 30 }, { 5470,  94, 30 }, { 5480,  96, 30 },
409 		{ 5490,  98, 30 }, { 5500, 100, 30 }, { 5510, 102, 30 },
410 		{ 5520, 104, 30 }, { 5530, 106, 30 }, { 5540, 108, 30 },
411 		{ 5550, 110, 30 }, { 5560, 112, 30 }, { 5570, 114, 30 },
412 		{ 5580, 116, 30 }, { 5590, 118, 30 }, { 5600, 120, 30 },
413 		{ 5610, 122, 30 }, { 5620, 124, 30 }, { 5630, 126, 30 },
414 		{ 5640, 128, 30 }, { 5650, 130, 30 }, { 5660, 132, 30 },
415 		{ 5670, 134, 30 }, { 5680, 136, 30 }, { 5690, 138, 30 },
416 		{ 5700, 140, 30 }, { 5710, 142, 30 }, { 5720, 144, 30 },
417 		{ 5725, 145, 30 }, { 5730, 146, 30 }, { 5735, 147, 30 },
418 		{ 5740, 148, 30 }, { 5745, 149, 30 }, { 5750, 150, 30 },
419 		{ 5755, 151, 30 }, { 5760, 152, 30 }, { 5765, 153, 30 },
420 		{ 5770, 154, 30 }, { 5775, 155, 30 }, { 5780, 156, 30 },
421 		{ 5785, 157, 30 }, { 5790, 158, 30 }, { 5795, 159, 30 },
422 		{ 5800, 160, 30 }, { 5805, 161, 30 }, { 5810, 162, 30 },
423 		{ 5815, 163, 30 }, { 5820, 164, 30 }, { 5825, 165, 30 },
424 		{ 5830, 166, 30 }, { 5840, 168, 30 }, { 5850, 170, 30 },
425 		{ 5860, 172, 30 }, { 5870, 174, 30 }, { 5880, 176, 30 },
426 		{ 5890, 178, 30 }, { 5900, 180, 30 }, { 5910, 182, 30 },
427 		{ 5920, 184, 30 }, { 5930, 186, 30 }, { 5940, 188, 30 },
428 		{ 5950, 190, 30 }, { 5960, 192, 30 }, { 5970, 194, 30 },
429 		{ 5980, 196, 30 }, { 5990, 198, 30 }, { 6000, 200, 30 },
430 		{ 6010, 202, 30 }, { 6020, 204, 30 }, { 6030, 206, 30 },
431 		{ 6040, 208, 30 }, { 6050, 210, 30 }, { 6060, 212, 30 },
432 		{ 6070, 214, 30 }, { 6080, 216, 30 }, { 6090, 218, 30 },
433 		{ 6100, 220, 30 }, { 6110, 222, 30 }, { 6120, 224, 30 },
434 		{ 6130, 226, 30 }, { 6140, 228, 30 } },
435 	.nchannels = 110
436 };
437 #endif
438 
439 #define	VENDOR_LED_ACT(vendor)				\
440 {							\
441 	.vid = PCI_VENDOR_##vendor,			\
442 	.led_act = { BWN_VENDOR_LED_ACT_##vendor }	\
443 }
444 
445 static const struct {
446 	uint16_t	vid;
447 	uint8_t		led_act[BWN_LED_MAX];
448 } bwn_vendor_led_act[] = {
449 	VENDOR_LED_ACT(HP_COMPAQ),
450 	VENDOR_LED_ACT(ASUSTEK)
451 };
452 
453 static const uint8_t bwn_default_led_act[BWN_LED_MAX] =
454 	{ BWN_VENDOR_LED_ACT_DEFAULT };
455 
456 #undef VENDOR_LED_ACT
457 
458 static const char *bwn_led_vars[] = {
459 	BHND_NVAR_LEDBH0,
460 	BHND_NVAR_LEDBH1,
461 	BHND_NVAR_LEDBH2,
462 	BHND_NVAR_LEDBH3
463 };
464 
465 static const struct {
466 	int		on_dur;
467 	int		off_dur;
468 } bwn_led_duration[109] = {
469 	[0]	= { 400, 100 },
470 	[2]	= { 150, 75 },
471 	[4]	= { 90, 45 },
472 	[11]	= { 66, 34 },
473 	[12]	= { 53, 26 },
474 	[18]	= { 42, 21 },
475 	[22]	= { 35, 17 },
476 	[24]	= { 32, 16 },
477 	[36]	= { 21, 10 },
478 	[48]	= { 16, 8 },
479 	[72]	= { 11, 5 },
480 	[96]	= { 9, 4 },
481 	[108]	= { 7, 3 }
482 };
483 
484 static const uint16_t bwn_wme_shm_offsets[] = {
485 	[0] = BWN_WME_BESTEFFORT,
486 	[1] = BWN_WME_BACKGROUND,
487 	[2] = BWN_WME_VOICE,
488 	[3] = BWN_WME_VIDEO,
489 };
490 
491 /* Supported D11 core revisions */
492 #define	BWN_DEV(_hwrev)	{{					\
493 	BHND_MATCH_CORE(BHND_MFGID_BCM, BHND_COREID_D11),	\
494 	BHND_MATCH_CORE_REV(_hwrev),				\
495 }}
496 static const struct bhnd_device bwn_devices[] = {
497 	BWN_DEV(HWREV_RANGE(5, 16)),
498 	BWN_DEV(HWREV_EQ(23)),
499 	BHND_DEVICE_END
500 };
501 
502 /* D11 quirks when bridged via a PCI host bridge core */
503 static const struct bhnd_device_quirk pci_bridge_quirks[] = {
504 	BHND_CORE_QUIRK	(HWREV_LTE(10),	BWN_QUIRK_UCODE_SLOWCLOCK_WAR),
505 	BHND_DEVICE_QUIRK_END
506 };
507 
508 /* D11 quirks when bridged via a PCMCIA host bridge core */
509 static const struct bhnd_device_quirk pcmcia_bridge_quirks[] = {
510 	BHND_CORE_QUIRK	(HWREV_ANY,	BWN_QUIRK_NODMA),
511 	BHND_DEVICE_QUIRK_END
512 };
513 
514 /* Host bridge cores for which D11 quirk flags should be applied */
515 static const struct bhnd_device bridge_devices[] = {
516 	BHND_DEVICE(BCM, PCI,		NULL, pci_bridge_quirks),
517 	BHND_DEVICE(BCM, PCMCIA,	NULL, pcmcia_bridge_quirks),
518 	BHND_DEVICE_END
519 };
520 
521 static int
bwn_probe(device_t dev)522 bwn_probe(device_t dev)
523 {
524 	const struct bhnd_device *id;
525 
526 	id = bhnd_device_lookup(dev, bwn_devices, sizeof(bwn_devices[0]));
527 	if (id == NULL)
528 		return (ENXIO);
529 
530 	bhnd_set_default_core_desc(dev);
531 	return (BUS_PROBE_DEFAULT);
532 }
533 
534 static int
bwn_attach(device_t dev)535 bwn_attach(device_t dev)
536 {
537 	struct bwn_mac		*mac;
538 	struct bwn_softc	*sc;
539 	device_t		 parent, hostb;
540 	char			 chip_name[BHND_CHIPID_MAX_NAMELEN];
541 	int			 error;
542 
543 	sc = device_get_softc(dev);
544 	sc->sc_dev = dev;
545 #ifdef BWN_DEBUG
546 	sc->sc_debug = bwn_debug;
547 #endif
548 
549 	mac = NULL;
550 
551 	/* Determine the driver quirks applicable to this device, including any
552 	 * quirks specific to the bus host bridge core (if any) */
553 	sc->sc_quirks = bhnd_device_quirks(dev, bwn_devices,
554 	    sizeof(bwn_devices[0]));
555 
556 	parent = device_get_parent(dev);
557 	if ((hostb = bhnd_bus_find_hostb_device(parent)) != NULL) {
558 		sc->sc_quirks |= bhnd_device_quirks(hostb, bridge_devices,
559 		    sizeof(bridge_devices[0]));
560 	}
561 
562 	/* DMA explicitly disabled? */
563 	if (!bwn_usedma)
564 		sc->sc_quirks |= BWN_QUIRK_NODMA;
565 
566 	/* Fetch our chip identification and board info */
567 	sc->sc_cid = *bhnd_get_chipid(dev);
568 	if ((error = bhnd_read_board_info(dev, &sc->sc_board_info))) {
569 		device_printf(sc->sc_dev, "couldn't read board info\n");
570 		return (error);
571 	}
572 
573 	/* Allocate our D11 register block and PMU state */
574 	sc->sc_mem_rid = 0;
575 	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
576 	    &sc->sc_mem_rid, RF_ACTIVE);
577 	if (sc->sc_mem_res == NULL) {
578 		device_printf(sc->sc_dev, "couldn't allocate registers\n");
579 		return (error);
580 	}
581 
582 	if ((error = bhnd_alloc_pmu(sc->sc_dev))) {
583 		bus_release_resource(sc->sc_dev, SYS_RES_MEMORY,
584 		    sc->sc_mem_rid, sc->sc_mem_res);
585 		return (error);
586 	}
587 
588 	/* Retain references to all required bus service providers */
589 	if ((error = bwn_retain_bus_providers(sc)))
590 		goto fail;
591 
592 	/* Fetch mask of available antennas */
593 	error = bhnd_nvram_getvar_uint8(sc->sc_dev, BHND_NVAR_AA2G,
594 	    &sc->sc_ant2g);
595 	if (error) {
596 		device_printf(sc->sc_dev, "error determining 2GHz antenna "
597 		    "availability from NVRAM: %d\n", error);
598 		goto fail;
599 	}
600 
601 	error = bhnd_nvram_getvar_uint8(sc->sc_dev, BHND_NVAR_AA5G,
602 	    &sc->sc_ant5g);
603 	if (error) {
604 		device_printf(sc->sc_dev, "error determining 5GHz antenna "
605 		    "availability from NVRAM: %d\n", error);
606 		goto fail;
607 	}
608 
609 	if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
610 		bwn_attach_pre(sc);
611 		bwn_sprom_bugfixes(dev);
612 		sc->sc_flags |= BWN_FLAG_ATTACHED;
613 	}
614 
615 	mac = malloc(sizeof(*mac), M_DEVBUF, M_WAITOK | M_ZERO);
616 	mac->mac_sc = sc;
617 	mac->mac_status = BWN_MAC_STATUS_UNINIT;
618 	if (bwn_bfp != 0)
619 		mac->mac_flags |= BWN_MAC_FLAG_BADFRAME_PREEMP;
620 
621 	TASK_INIT(&mac->mac_hwreset, 0, bwn_hwreset, mac);
622 	NET_TASK_INIT(&mac->mac_intrtask, 0, bwn_intrtask, mac);
623 	TASK_INIT(&mac->mac_txpower, 0, bwn_txpwr, mac);
624 
625 	error = bwn_attach_core(mac);
626 	if (error)
627 		goto fail;
628 	error = bwn_led_attach(mac);
629 	if (error)
630 		goto fail;
631 
632 	bhnd_format_chip_id(chip_name, sizeof(chip_name), sc->sc_cid.chip_id);
633 	device_printf(sc->sc_dev, "WLAN (%s rev %u sromrev %u) "
634 	    "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n",
635 	    chip_name, bhnd_get_hwrev(sc->sc_dev),
636 	    sc->sc_board_info.board_srom_rev, mac->mac_phy.analog,
637 	    mac->mac_phy.type, mac->mac_phy.rev, mac->mac_phy.rf_manuf,
638 	    mac->mac_phy.rf_ver, mac->mac_phy.rf_rev);
639 	if (mac->mac_flags & BWN_MAC_FLAG_DMA)
640 		device_printf(sc->sc_dev, "DMA (%d bits)\n", mac->mac_dmatype);
641 	else
642 		device_printf(sc->sc_dev, "PIO\n");
643 
644 #ifdef	BWN_GPL_PHY
645 	device_printf(sc->sc_dev,
646 	    "Note: compiled with BWN_GPL_PHY; includes GPLv2 code\n");
647 #endif
648 
649 	mac->mac_rid_irq = 0;
650 	mac->mac_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
651 	    &mac->mac_rid_irq, RF_ACTIVE | RF_SHAREABLE);
652 
653 	if (mac->mac_res_irq == NULL) {
654 		device_printf(sc->sc_dev, "couldn't allocate IRQ resource\n");
655 		error = ENXIO;
656 		goto fail;
657 	}
658 
659 	error = bus_setup_intr(dev, mac->mac_res_irq,
660 	    INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac,
661 	    &mac->mac_intrhand);
662 	if (error != 0) {
663 		device_printf(sc->sc_dev, "couldn't setup interrupt (%d)\n",
664 		    error);
665 		goto fail;
666 	}
667 
668 	TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list);
669 
670 	/*
671 	 * calls attach-post routine
672 	 */
673 	if ((sc->sc_flags & BWN_FLAG_ATTACHED) != 0)
674 		bwn_attach_post(sc);
675 
676 	return (0);
677 fail:
678 	if (mac != NULL && mac->mac_res_irq != NULL) {
679 		bus_release_resource(dev, SYS_RES_IRQ, mac->mac_rid_irq,
680 		    mac->mac_res_irq);
681 	}
682 
683 	free(mac, M_DEVBUF);
684 	bhnd_release_pmu(dev);
685 	bwn_release_bus_providers(sc);
686 
687 	if (sc->sc_mem_res != NULL) {
688 		bus_release_resource(sc->sc_dev, SYS_RES_MEMORY,
689 		    sc->sc_mem_rid, sc->sc_mem_res);
690 	}
691 
692 	return (error);
693 }
694 
695 static int
bwn_retain_bus_providers(struct bwn_softc * sc)696 bwn_retain_bus_providers(struct bwn_softc *sc)
697 {
698 	struct chipc_caps *ccaps;
699 
700 	sc->sc_chipc = bhnd_retain_provider(sc->sc_dev, BHND_SERVICE_CHIPC);
701 	if (sc->sc_chipc == NULL) {
702 		device_printf(sc->sc_dev, "ChipCommon device not found\n");
703 		goto failed;
704 	}
705 
706 	ccaps = BHND_CHIPC_GET_CAPS(sc->sc_chipc);
707 
708 	sc->sc_gpio = bhnd_retain_provider(sc->sc_dev, BHND_SERVICE_GPIO);
709 	if (sc->sc_gpio == NULL) {
710 		device_printf(sc->sc_dev, "GPIO device not found\n");
711 		goto failed;
712 	}
713 
714 	if (ccaps->pmu) {
715 		sc->sc_pmu = bhnd_retain_provider(sc->sc_dev, BHND_SERVICE_PMU);
716 		if (sc->sc_pmu == NULL) {
717 			device_printf(sc->sc_dev, "PMU device not found\n");
718 			goto failed;
719 		}
720 	}
721 
722 	return (0);
723 
724 failed:
725 	bwn_release_bus_providers(sc);
726 	return (ENXIO);
727 }
728 
729 static void
bwn_release_bus_providers(struct bwn_softc * sc)730 bwn_release_bus_providers(struct bwn_softc *sc)
731 {
732 #define	BWN_RELEASE_PROV(_sc, _prov, _service)	do {			\
733 	if ((_sc)-> _prov != NULL) {					\
734 		bhnd_release_provider((_sc)->sc_dev, (_sc)-> _prov,	\
735 		    (_service));					\
736 		(_sc)-> _prov = NULL;					\
737 	}								\
738 } while (0)
739 
740 	BWN_RELEASE_PROV(sc, sc_chipc, BHND_SERVICE_CHIPC);
741 	BWN_RELEASE_PROV(sc, sc_gpio, BHND_SERVICE_GPIO);
742 	BWN_RELEASE_PROV(sc, sc_pmu, BHND_SERVICE_PMU);
743 
744 #undef	BWN_RELEASE_PROV
745 }
746 
747 static int
bwn_attach_post(struct bwn_softc * sc)748 bwn_attach_post(struct bwn_softc *sc)
749 {
750 	struct ieee80211com	*ic;
751 	const char		*mac_varname;
752 	u_int			 core_unit;
753 	int			 error;
754 
755 	ic = &sc->sc_ic;
756 
757 	ic->ic_softc = sc;
758 	ic->ic_name = device_get_nameunit(sc->sc_dev);
759 	/* XXX not right but it's not used anywhere important */
760 	ic->ic_phytype = IEEE80211_T_OFDM;
761 	ic->ic_opmode = IEEE80211_M_STA;
762 	ic->ic_caps =
763 		  IEEE80211_C_STA		/* station mode supported */
764 		| IEEE80211_C_MONITOR		/* monitor mode */
765 		| IEEE80211_C_AHDEMO		/* adhoc demo mode */
766 		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
767 		| IEEE80211_C_SHSLOT		/* short slot time supported */
768 		| IEEE80211_C_WME		/* WME/WMM supported */
769 		| IEEE80211_C_WPA		/* capable of WPA1+WPA2 */
770 #if 0
771 		| IEEE80211_C_BGSCAN		/* capable of bg scanning */
772 #endif
773 		| IEEE80211_C_TXPMGT		/* capable of txpow mgt */
774 		;
775 
776 	ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;	/* s/w bmiss */
777 	ic->ic_flags_ext |= IEEE80211_FEXT_SEQNO_OFFLOAD;
778 
779 	/* Determine the NVRAM variable containing our MAC address */
780 	core_unit = bhnd_get_core_unit(sc->sc_dev);
781 	mac_varname = NULL;
782 	if (sc->sc_board_info.board_srom_rev <= 2) {
783 		if (core_unit == 0) {
784 			mac_varname = BHND_NVAR_IL0MACADDR;
785 		} else if (core_unit == 1) {
786 			mac_varname = BHND_NVAR_ET1MACADDR;
787 		}
788 	} else {
789 		if (core_unit == 0) {
790 			mac_varname = BHND_NVAR_MACADDR;
791 		}
792 	}
793 
794 	if (mac_varname == NULL) {
795 		device_printf(sc->sc_dev, "missing MAC address variable for "
796 		    "D11 core %u", core_unit);
797 		return (ENXIO);
798 	}
799 
800 	/* Read the MAC address from NVRAM */
801 	error = bhnd_nvram_getvar_array(sc->sc_dev, mac_varname, ic->ic_macaddr,
802 	    sizeof(ic->ic_macaddr), BHND_NVRAM_TYPE_UINT8_ARRAY);
803 	if (error) {
804 		device_printf(sc->sc_dev, "error reading %s: %d\n", mac_varname,
805 		    error);
806 		return (error);
807 	}
808 
809 	/* call MI attach routine. */
810 	ieee80211_ifattach(ic);
811 
812 	/* override default methods */
813 	ic->ic_raw_xmit = bwn_raw_xmit;
814 	ic->ic_updateslot = bwn_updateslot;
815 	ic->ic_update_promisc = bwn_update_promisc;
816 	ic->ic_wme.wme_update = bwn_wme_update;
817 	ic->ic_scan_start = bwn_scan_start;
818 	ic->ic_scan_end = bwn_scan_end;
819 	ic->ic_set_channel = bwn_set_channel;
820 	ic->ic_vap_create = bwn_vap_create;
821 	ic->ic_vap_delete = bwn_vap_delete;
822 	ic->ic_transmit = bwn_transmit;
823 	ic->ic_parent = bwn_parent;
824 
825 	ieee80211_radiotap_attach(ic,
826 	    &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
827 	    BWN_TX_RADIOTAP_PRESENT,
828 	    &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
829 	    BWN_RX_RADIOTAP_PRESENT);
830 
831 	bwn_sysctl_node(sc);
832 
833 	if (bootverbose)
834 		ieee80211_announce(ic);
835 	return (0);
836 }
837 
838 static void
bwn_phy_detach(struct bwn_mac * mac)839 bwn_phy_detach(struct bwn_mac *mac)
840 {
841 
842 	if (mac->mac_phy.detach != NULL)
843 		mac->mac_phy.detach(mac);
844 }
845 
846 static int
bwn_detach(device_t dev)847 bwn_detach(device_t dev)
848 {
849 	struct bwn_softc *sc = device_get_softc(dev);
850 	struct bwn_mac *mac = sc->sc_curmac;
851 	struct ieee80211com *ic = &sc->sc_ic;
852 
853 	sc->sc_flags |= BWN_FLAG_INVALID;
854 
855 	if (device_is_attached(sc->sc_dev)) {
856 		BWN_LOCK(sc);
857 		bwn_stop(sc);
858 		BWN_UNLOCK(sc);
859 		bwn_dma_free(mac);
860 		callout_drain(&sc->sc_led_blink_ch);
861 		callout_drain(&sc->sc_rfswitch_ch);
862 		callout_drain(&sc->sc_task_ch);
863 		callout_drain(&sc->sc_watchdog_ch);
864 		bwn_phy_detach(mac);
865 		ieee80211_draintask(ic, &mac->mac_hwreset);
866 		ieee80211_draintask(ic, &mac->mac_txpower);
867 		ieee80211_ifdetach(ic);
868 	}
869 	taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
870 	taskqueue_free(sc->sc_tq);
871 
872 	if (mac->mac_intrhand != NULL) {
873 		bus_teardown_intr(dev, mac->mac_res_irq, mac->mac_intrhand);
874 		mac->mac_intrhand = NULL;
875 	}
876 
877 	bhnd_release_pmu(dev);
878 	bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid,
879 	    sc->sc_mem_res);
880 	bus_release_resource(dev, SYS_RES_IRQ, mac->mac_rid_irq,
881 	    mac->mac_res_irq);
882 	mbufq_drain(&sc->sc_snd);
883 	bwn_release_firmware(mac);
884 	BWN_LOCK_DESTROY(sc);
885 
886 	bwn_release_bus_providers(sc);
887 
888 	return (0);
889 }
890 
891 static void
bwn_attach_pre(struct bwn_softc * sc)892 bwn_attach_pre(struct bwn_softc *sc)
893 {
894 
895 	BWN_LOCK_INIT(sc);
896 	TAILQ_INIT(&sc->sc_maclist);
897 	callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
898 	callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
899 	callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
900 	mbufq_init(&sc->sc_snd, ifqmaxlen);
901 	sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT,
902 		taskqueue_thread_enqueue, &sc->sc_tq);
903 	taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
904 		"%s taskq", device_get_nameunit(sc->sc_dev));
905 }
906 
907 static void
bwn_sprom_bugfixes(device_t dev)908 bwn_sprom_bugfixes(device_t dev)
909 {
910 	struct bwn_softc *sc = device_get_softc(dev);
911 
912 #define	BWN_ISDEV(_device, _subvendor, _subdevice)		\
913 	((sc->sc_board_info.board_devid == PCI_DEVID_##_device) &&	\
914 	 (sc->sc_board_info.board_vendor == PCI_VENDOR_##_subvendor) &&	\
915 	 (sc->sc_board_info.board_type == _subdevice))
916 
917 	 /* A subset of Apple Airport Extreme (BCM4306 rev 2) devices
918 	  * were programmed with a missing PACTRL boardflag */
919 	 if (sc->sc_board_info.board_vendor == PCI_VENDOR_APPLE &&
920 	     sc->sc_board_info.board_type == 0x4e &&
921 	     sc->sc_board_info.board_rev > 0x40)
922 		 sc->sc_board_info.board_flags |= BHND_BFL_PACTRL;
923 
924 	if (BWN_ISDEV(BCM4318_D11G, ASUSTEK, 0x100f) ||
925 	    BWN_ISDEV(BCM4306_D11G, DELL, 0x0003) ||
926 	    BWN_ISDEV(BCM4306_D11G, HP, 0x12f8) ||
927 	    BWN_ISDEV(BCM4306_D11G, LINKSYS, 0x0013) ||
928 	    BWN_ISDEV(BCM4306_D11G, LINKSYS, 0x0014) ||
929 	    BWN_ISDEV(BCM4306_D11G, LINKSYS, 0x0015) ||
930 	    BWN_ISDEV(BCM4306_D11G, MOTOROLA, 0x7010))
931 		sc->sc_board_info.board_flags &= ~BHND_BFL_BTCOEX;
932 #undef	BWN_ISDEV
933 }
934 
935 static void
bwn_parent(struct ieee80211com * ic)936 bwn_parent(struct ieee80211com *ic)
937 {
938 	struct bwn_softc *sc = ic->ic_softc;
939 	int startall = 0;
940 
941 	BWN_LOCK(sc);
942 	if (ic->ic_nrunning > 0) {
943 		if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) {
944 			bwn_init(sc);
945 			startall = 1;
946 		} else
947 			bwn_update_promisc(ic);
948 	} else if (sc->sc_flags & BWN_FLAG_RUNNING)
949 		bwn_stop(sc);
950 	BWN_UNLOCK(sc);
951 
952 	if (startall)
953 		ieee80211_start_all(ic);
954 }
955 
956 static int
bwn_transmit(struct ieee80211com * ic,struct mbuf * m)957 bwn_transmit(struct ieee80211com *ic, struct mbuf *m)
958 {
959 	struct bwn_softc *sc = ic->ic_softc;
960 	int error;
961 
962 	BWN_LOCK(sc);
963 	if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) {
964 		BWN_UNLOCK(sc);
965 		return (ENXIO);
966 	}
967 	error = mbufq_enqueue(&sc->sc_snd, m);
968 	if (error) {
969 		BWN_UNLOCK(sc);
970 		return (error);
971 	}
972 	bwn_start(sc);
973 	BWN_UNLOCK(sc);
974 	return (0);
975 }
976 
977 static void
bwn_start(struct bwn_softc * sc)978 bwn_start(struct bwn_softc *sc)
979 {
980 	struct bwn_mac *mac = sc->sc_curmac;
981 	struct ieee80211_frame *wh;
982 	struct ieee80211_node *ni;
983 	struct ieee80211_key *k;
984 	struct mbuf *m;
985 
986 	BWN_ASSERT_LOCKED(sc);
987 
988 	if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || mac == NULL ||
989 	    mac->mac_status < BWN_MAC_STATUS_STARTED)
990 		return;
991 
992 	while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
993 		if (bwn_tx_isfull(sc, m))
994 			break;
995 		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
996 		if (ni == NULL) {
997 			device_printf(sc->sc_dev, "unexpected NULL ni\n");
998 			m_freem(m);
999 			counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1000 			continue;
1001 		}
1002 		wh = mtod(m, struct ieee80211_frame *);
1003 		if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1004 			k = ieee80211_crypto_encap(ni, m);
1005 			if (k == NULL) {
1006 				if_inc_counter(ni->ni_vap->iv_ifp,
1007 				    IFCOUNTER_OERRORS, 1);
1008 				ieee80211_free_node(ni);
1009 				m_freem(m);
1010 				continue;
1011 			}
1012 		}
1013 		wh = NULL;	/* Catch any invalid use */
1014 		if (bwn_tx_start(sc, ni, m) != 0) {
1015 			if (ni != NULL) {
1016 				if_inc_counter(ni->ni_vap->iv_ifp,
1017 				    IFCOUNTER_OERRORS, 1);
1018 				ieee80211_free_node(ni);
1019 			}
1020 			continue;
1021 		}
1022 		sc->sc_watchdog_timer = 5;
1023 	}
1024 }
1025 
1026 static int
bwn_tx_isfull(struct bwn_softc * sc,struct mbuf * m)1027 bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
1028 {
1029 	struct bwn_dma_ring *dr;
1030 	struct bwn_mac *mac = sc->sc_curmac;
1031 	struct bwn_pio_txqueue *tq;
1032 	int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1033 
1034 	BWN_ASSERT_LOCKED(sc);
1035 
1036 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
1037 		dr = bwn_dma_select(mac, M_WME_GETAC(m));
1038 		if (dr->dr_stop == 1 ||
1039 		    bwn_dma_freeslot(dr) < BWN_TX_SLOTS_PER_FRAME) {
1040 			dr->dr_stop = 1;
1041 			goto full;
1042 		}
1043 	} else {
1044 		tq = bwn_pio_select(mac, M_WME_GETAC(m));
1045 		if (tq->tq_free == 0 || pktlen > tq->tq_size ||
1046 		    pktlen > (tq->tq_size - tq->tq_used))
1047 			goto full;
1048 	}
1049 	return (0);
1050 full:
1051 	mbufq_prepend(&sc->sc_snd, m);
1052 	return (1);
1053 }
1054 
1055 /*
1056  * @brief Queue the give frame for transmit.
1057  *
1058  * This must be called in the same lock/path as the crypto encap call
1059  * to avoid reordering issues.
1060  */
1061 static int
bwn_tx_start(struct bwn_softc * sc,struct ieee80211_node * ni,struct mbuf * m)1062 bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m)
1063 {
1064 	struct bwn_mac *mac = sc->sc_curmac;
1065 	int error;
1066 
1067 	BWN_ASSERT_LOCKED(sc);
1068 
1069 	if (m->m_pkthdr.len < IEEE80211_MIN_LEN || mac == NULL) {
1070 		m_freem(m);
1071 		return (ENXIO);
1072 	}
1073 
1074 	ieee80211_output_seqno_assign(ni, -1, m);
1075 
1076 	error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ?
1077 	    bwn_dma_tx_start(mac, ni, &m) : bwn_pio_tx_start(mac, ni, &m);
1078 	if (error) {
1079 		m_freem(m);
1080 		return (error);
1081 	}
1082 	return (0);
1083 }
1084 
1085 static int
bwn_pio_tx_start(struct bwn_mac * mac,struct ieee80211_node * ni,struct mbuf ** mp)1086 bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni,
1087     struct mbuf **mp)
1088 {
1089 	struct bwn_pio_txpkt *tp;
1090 	struct bwn_pio_txqueue *tq;
1091 	struct bwn_softc *sc = mac->mac_sc;
1092 	struct bwn_txhdr txhdr;
1093 	struct mbuf *m, *m_new;
1094 	uint32_t ctl32;
1095 	int error;
1096 	uint16_t ctl16;
1097 
1098 	BWN_ASSERT_LOCKED(sc);
1099 
1100 	/* XXX TODO send packets after DTIM */
1101 
1102 	m = *mp;
1103 	tq = bwn_pio_select(mac, M_WME_GETAC(m));
1104 	KASSERT(!TAILQ_EMPTY(&tq->tq_pktlist), ("%s: fail", __func__));
1105 	tp = TAILQ_FIRST(&tq->tq_pktlist);
1106 	tp->tp_ni = ni;
1107 	tp->tp_m = m;
1108 
1109 	error = bwn_set_txhdr(mac, ni, m, &txhdr, BWN_PIO_COOKIE(tq, tp));
1110 	if (error) {
1111 		device_printf(sc->sc_dev, "tx fail\n");
1112 		return (error);
1113 	}
1114 
1115 	TAILQ_REMOVE(&tq->tq_pktlist, tp, tp_list);
1116 	tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
1117 	tq->tq_free--;
1118 
1119 	if (bhnd_get_hwrev(sc->sc_dev) >= 8) {
1120 		/*
1121 		 * XXX please removes m_defrag(9)
1122 		 */
1123 		m_new = m_defrag(*mp, M_NOWAIT);
1124 		if (m_new == NULL) {
1125 			device_printf(sc->sc_dev,
1126 			    "%s: can't defrag TX buffer\n",
1127 			    __func__);
1128 			return (ENOBUFS);
1129 		}
1130 		*mp = m_new;
1131 		if (m_new->m_next != NULL)
1132 			device_printf(sc->sc_dev,
1133 			    "TODO: fragmented packets for PIO\n");
1134 		tp->tp_m = m_new;
1135 
1136 		/* send HEADER */
1137 		ctl32 = bwn_pio_write_multi_4(mac, tq,
1138 		    (BWN_PIO_READ_4(mac, tq, BWN_PIO8_TXCTL) |
1139 			BWN_PIO8_TXCTL_FRAMEREADY) & ~BWN_PIO8_TXCTL_EOF,
1140 		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1141 		/* send BODY */
1142 		ctl32 = bwn_pio_write_multi_4(mac, tq, ctl32,
1143 		    mtod(m_new, const void *), m_new->m_pkthdr.len);
1144 		bwn_pio_write_4(mac, tq, BWN_PIO_TXCTL,
1145 		    ctl32 | BWN_PIO8_TXCTL_EOF);
1146 	} else {
1147 		ctl16 = bwn_pio_write_multi_2(mac, tq,
1148 		    (bwn_pio_read_2(mac, tq, BWN_PIO_TXCTL) |
1149 			BWN_PIO_TXCTL_FRAMEREADY) & ~BWN_PIO_TXCTL_EOF,
1150 		    (const uint8_t *)&txhdr, BWN_HDRSIZE(mac));
1151 		ctl16 = bwn_pio_write_mbuf_2(mac, tq, ctl16, m);
1152 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL,
1153 		    ctl16 | BWN_PIO_TXCTL_EOF);
1154 	}
1155 
1156 	return (0);
1157 }
1158 
1159 static struct bwn_pio_txqueue *
bwn_pio_select(struct bwn_mac * mac,uint8_t prio)1160 bwn_pio_select(struct bwn_mac *mac, uint8_t prio)
1161 {
1162 
1163 	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
1164 		return (&mac->mac_method.pio.wme[WME_AC_BE]);
1165 
1166 	switch (prio) {
1167 	case 0:
1168 		return (&mac->mac_method.pio.wme[WME_AC_BE]);
1169 	case 1:
1170 		return (&mac->mac_method.pio.wme[WME_AC_BK]);
1171 	case 2:
1172 		return (&mac->mac_method.pio.wme[WME_AC_VI]);
1173 	case 3:
1174 		return (&mac->mac_method.pio.wme[WME_AC_VO]);
1175 	}
1176 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1177 	return (NULL);
1178 }
1179 
1180 static int
bwn_dma_tx_start(struct bwn_mac * mac,struct ieee80211_node * ni,struct mbuf ** mp)1181 bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni,
1182     struct mbuf **mp)
1183 {
1184 #define	BWN_GET_TXHDRCACHE(slot)					\
1185 	&(txhdr_cache[(slot / BWN_TX_SLOTS_PER_FRAME) * BWN_HDRSIZE(mac)])
1186 	struct bwn_dma *dma = &mac->mac_method.dma;
1187 	struct bwn_dma_ring *dr = bwn_dma_select(mac, M_WME_GETAC(*mp));
1188 	struct bwn_dmadesc_generic *desc;
1189 	struct bwn_dmadesc_meta *mt;
1190 	struct bwn_softc *sc = mac->mac_sc;
1191 	struct mbuf *m;
1192 	uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
1193 	int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
1194 
1195 	BWN_ASSERT_LOCKED(sc);
1196 	KASSERT(!dr->dr_stop, ("%s:%d: fail", __func__, __LINE__));
1197 
1198 	/* XXX send after DTIM */
1199 
1200 	m = *mp;
1201 	slot = bwn_dma_getslot(dr);
1202 	dr->getdesc(dr, slot, &desc, &mt);
1203 	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_HEADER,
1204 	    ("%s:%d: fail", __func__, __LINE__));
1205 
1206 	error = bwn_set_txhdr(dr->dr_mac, ni, m,
1207 	    (struct bwn_txhdr *)BWN_GET_TXHDRCACHE(slot),
1208 	    BWN_DMA_COOKIE(dr, slot));
1209 	if (error)
1210 		goto fail;
1211 	error = bus_dmamap_load(dr->dr_txring_dtag, mt->mt_dmap,
1212 	    BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
1213 	    &mt->mt_paddr, BUS_DMA_NOWAIT);
1214 	if (error) {
1215 		device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
1216 		    __func__, error);
1217 		goto fail;
1218 	}
1219 	bus_dmamap_sync(dr->dr_txring_dtag, mt->mt_dmap,
1220 	    BUS_DMASYNC_PREWRITE);
1221 	dr->setdesc(dr, desc, mt->mt_paddr, BWN_HDRSIZE(mac), 1, 0, 0);
1222 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1223 	    BUS_DMASYNC_PREWRITE);
1224 
1225 	slot = bwn_dma_getslot(dr);
1226 	dr->getdesc(dr, slot, &desc, &mt);
1227 	KASSERT(mt->mt_txtype == BWN_DMADESC_METATYPE_BODY &&
1228 	    mt->mt_islast == 1, ("%s:%d: fail", __func__, __LINE__));
1229 	mt->mt_m = m;
1230 	mt->mt_ni = ni;
1231 
1232 	error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
1233 	    bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1234 	if (error && error != EFBIG) {
1235 		device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
1236 		    __func__, error);
1237 		goto fail;
1238 	}
1239 	if (error) {    /* error == EFBIG */
1240 		struct mbuf *m_new;
1241 
1242 		m_new = m_defrag(m, M_NOWAIT);
1243 		if (m_new == NULL) {
1244 			device_printf(sc->sc_dev,
1245 			    "%s: can't defrag TX buffer\n",
1246 			    __func__);
1247 			error = ENOBUFS;
1248 			goto fail;
1249 		}
1250 		*mp = m = m_new;
1251 
1252 		mt->mt_m = m;
1253 		error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
1254 		    m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
1255 		if (error) {
1256 			device_printf(sc->sc_dev,
1257 			    "%s: can't load TX buffer (2) %d\n",
1258 			    __func__, error);
1259 			goto fail;
1260 		}
1261 	}
1262 	bus_dmamap_sync(dma->txbuf_dtag, mt->mt_dmap, BUS_DMASYNC_PREWRITE);
1263 	dr->setdesc(dr, desc, mt->mt_paddr, m->m_pkthdr.len, 0, 1, 1);
1264 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
1265 	    BUS_DMASYNC_PREWRITE);
1266 
1267 	/* XXX send after DTIM */
1268 
1269 	dr->start_transfer(dr, bwn_dma_nextslot(dr, slot));
1270 	return (0);
1271 fail:
1272 	dr->dr_curslot = backup[0];
1273 	dr->dr_usedslot = backup[1];
1274 	return (error);
1275 #undef BWN_GET_TXHDRCACHE
1276 }
1277 
1278 static void
bwn_watchdog(void * arg)1279 bwn_watchdog(void *arg)
1280 {
1281 	struct bwn_softc *sc = arg;
1282 
1283 	if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
1284 		device_printf(sc->sc_dev, "device timeout\n");
1285 		counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1286 	}
1287 	callout_schedule(&sc->sc_watchdog_ch, hz);
1288 }
1289 
1290 static int
bwn_attach_core(struct bwn_mac * mac)1291 bwn_attach_core(struct bwn_mac *mac)
1292 {
1293 	struct bwn_softc *sc = mac->mac_sc;
1294 	int error, have_bg = 0, have_a = 0;
1295 	uint16_t iost;
1296 
1297 	KASSERT(bhnd_get_hwrev(sc->sc_dev) >= 5,
1298 	    ("unsupported revision %d", bhnd_get_hwrev(sc->sc_dev)));
1299 
1300 	if ((error = bwn_core_forceclk(mac, true)))
1301 		return (error);
1302 
1303 	if ((error = bhnd_read_iost(sc->sc_dev, &iost))) {
1304 		device_printf(sc->sc_dev, "error reading I/O status flags: "
1305 		    "%d\n", error);
1306 		return (error);
1307 	}
1308 
1309 	have_a = (iost & BWN_IOST_HAVE_5GHZ) ? 1 : 0;
1310 	have_bg = (iost & BWN_IOST_HAVE_2GHZ) ? 1 : 0;
1311 	if (iost & BWN_IOST_DUALPHY) {
1312 		have_bg = 1;
1313 		have_a = 1;
1314 	}
1315 
1316 #if 0
1317 	device_printf(sc->sc_dev, "%s: iost=0x%04hx, have_a=%d, have_bg=%d,"
1318 	    " deviceid=0x%04x, siba_deviceid=0x%04x\n",
1319 	    __func__,
1320 	    iost,
1321 	    have_a,
1322 	    have_bg,
1323 	    sc->sc_board_info.board_devid,
1324 	    sc->sc_cid.chip_id);
1325 #endif
1326 
1327 	/*
1328 	 * Guess at whether it has A-PHY or G-PHY.
1329 	 * This is just used for resetting the core to probe things;
1330 	 * we will re-guess once it's all up and working.
1331 	 */
1332 	error = bwn_reset_core(mac, have_bg);
1333 	if (error)
1334 		goto fail;
1335 
1336 	/*
1337 	 * Determine the DMA engine type
1338 	 */
1339 	if (iost & BHND_IOST_DMA64) {
1340 		mac->mac_dmatype = BHND_DMA_ADDR_64BIT;
1341 	} else {
1342 		uint32_t tmp;
1343 		uint16_t base;
1344 
1345 		base = bwn_dma_base(0, 0);
1346 		BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL,
1347 		    BWN_DMA32_TXADDREXT_MASK);
1348 		tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL);
1349 		if (tmp & BWN_DMA32_TXADDREXT_MASK) {
1350 			mac->mac_dmatype = BHND_DMA_ADDR_32BIT;
1351 		} else {
1352 			mac->mac_dmatype = BHND_DMA_ADDR_30BIT;
1353 		}
1354 	}
1355 
1356 	/*
1357 	 * Get the PHY version.
1358 	 */
1359 	error = bwn_phy_getinfo(mac, have_bg);
1360 	if (error)
1361 		goto fail;
1362 
1363 	/*
1364 	 * This is the whitelist of devices which we "believe"
1365 	 * the SPROM PHY config from.  The rest are "guessed".
1366 	 */
1367 	if (sc->sc_board_info.board_devid != PCI_DEVID_BCM4311_D11DUAL &&
1368 	    sc->sc_board_info.board_devid != PCI_DEVID_BCM4328_D11G &&
1369 	    sc->sc_board_info.board_devid != PCI_DEVID_BCM4318_D11DUAL &&
1370 	    sc->sc_board_info.board_devid != PCI_DEVID_BCM4306_D11DUAL &&
1371 	    sc->sc_board_info.board_devid != PCI_DEVID_BCM4321_D11N &&
1372 	    sc->sc_board_info.board_devid != PCI_DEVID_BCM4322_D11N) {
1373 		have_a = have_bg = 0;
1374 		if (mac->mac_phy.type == BWN_PHYTYPE_A)
1375 			have_a = 1;
1376 		else if (mac->mac_phy.type == BWN_PHYTYPE_G ||
1377 		    mac->mac_phy.type == BWN_PHYTYPE_N ||
1378 		    mac->mac_phy.type == BWN_PHYTYPE_LP)
1379 			have_bg = 1;
1380 		else
1381 			KASSERT(0 == 1, ("%s: unknown phy type (%d)", __func__,
1382 			    mac->mac_phy.type));
1383 	}
1384 
1385 	/*
1386 	 * XXX The PHY-G support doesn't do 5GHz operation.
1387 	 */
1388 	if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
1389 	    mac->mac_phy.type != BWN_PHYTYPE_N) {
1390 		device_printf(sc->sc_dev,
1391 		    "%s: forcing 2GHz only; no dual-band support for PHY\n",
1392 		    __func__);
1393 		have_a = 0;
1394 		have_bg = 1;
1395 	}
1396 
1397 	mac->mac_phy.phy_n = NULL;
1398 
1399 	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
1400 		mac->mac_phy.attach = bwn_phy_g_attach;
1401 		mac->mac_phy.detach = bwn_phy_g_detach;
1402 		mac->mac_phy.prepare_hw = bwn_phy_g_prepare_hw;
1403 		mac->mac_phy.init_pre = bwn_phy_g_init_pre;
1404 		mac->mac_phy.init = bwn_phy_g_init;
1405 		mac->mac_phy.exit = bwn_phy_g_exit;
1406 		mac->mac_phy.phy_read = bwn_phy_g_read;
1407 		mac->mac_phy.phy_write = bwn_phy_g_write;
1408 		mac->mac_phy.rf_read = bwn_phy_g_rf_read;
1409 		mac->mac_phy.rf_write = bwn_phy_g_rf_write;
1410 		mac->mac_phy.use_hwpctl = bwn_phy_g_hwpctl;
1411 		mac->mac_phy.rf_onoff = bwn_phy_g_rf_onoff;
1412 		mac->mac_phy.switch_analog = bwn_phy_switch_analog;
1413 		mac->mac_phy.switch_channel = bwn_phy_g_switch_channel;
1414 		mac->mac_phy.get_default_chan = bwn_phy_g_get_default_chan;
1415 		mac->mac_phy.set_antenna = bwn_phy_g_set_antenna;
1416 		mac->mac_phy.set_im = bwn_phy_g_im;
1417 		mac->mac_phy.recalc_txpwr = bwn_phy_g_recalc_txpwr;
1418 		mac->mac_phy.set_txpwr = bwn_phy_g_set_txpwr;
1419 		mac->mac_phy.task_15s = bwn_phy_g_task_15s;
1420 		mac->mac_phy.task_60s = bwn_phy_g_task_60s;
1421 	} else if (mac->mac_phy.type == BWN_PHYTYPE_LP) {
1422 		mac->mac_phy.init_pre = bwn_phy_lp_init_pre;
1423 		mac->mac_phy.init = bwn_phy_lp_init;
1424 		mac->mac_phy.phy_read = bwn_phy_lp_read;
1425 		mac->mac_phy.phy_write = bwn_phy_lp_write;
1426 		mac->mac_phy.phy_maskset = bwn_phy_lp_maskset;
1427 		mac->mac_phy.rf_read = bwn_phy_lp_rf_read;
1428 		mac->mac_phy.rf_write = bwn_phy_lp_rf_write;
1429 		mac->mac_phy.rf_onoff = bwn_phy_lp_rf_onoff;
1430 		mac->mac_phy.switch_analog = bwn_phy_lp_switch_analog;
1431 		mac->mac_phy.switch_channel = bwn_phy_lp_switch_channel;
1432 		mac->mac_phy.get_default_chan = bwn_phy_lp_get_default_chan;
1433 		mac->mac_phy.set_antenna = bwn_phy_lp_set_antenna;
1434 		mac->mac_phy.task_60s = bwn_phy_lp_task_60s;
1435 	} else if (mac->mac_phy.type == BWN_PHYTYPE_N) {
1436 		mac->mac_phy.attach = bwn_phy_n_attach;
1437 		mac->mac_phy.detach = bwn_phy_n_detach;
1438 		mac->mac_phy.prepare_hw = bwn_phy_n_prepare_hw;
1439 		mac->mac_phy.init_pre = bwn_phy_n_init_pre;
1440 		mac->mac_phy.init = bwn_phy_n_init;
1441 		mac->mac_phy.exit = bwn_phy_n_exit;
1442 		mac->mac_phy.phy_read = bwn_phy_n_read;
1443 		mac->mac_phy.phy_write = bwn_phy_n_write;
1444 		mac->mac_phy.rf_read = bwn_phy_n_rf_read;
1445 		mac->mac_phy.rf_write = bwn_phy_n_rf_write;
1446 		mac->mac_phy.use_hwpctl = bwn_phy_n_hwpctl;
1447 		mac->mac_phy.rf_onoff = bwn_phy_n_rf_onoff;
1448 		mac->mac_phy.switch_analog = bwn_phy_n_switch_analog;
1449 		mac->mac_phy.switch_channel = bwn_phy_n_switch_channel;
1450 		mac->mac_phy.get_default_chan = bwn_phy_n_get_default_chan;
1451 		mac->mac_phy.set_antenna = bwn_phy_n_set_antenna;
1452 		mac->mac_phy.set_im = bwn_phy_n_im;
1453 		mac->mac_phy.recalc_txpwr = bwn_phy_n_recalc_txpwr;
1454 		mac->mac_phy.set_txpwr = bwn_phy_n_set_txpwr;
1455 		mac->mac_phy.task_15s = bwn_phy_n_task_15s;
1456 		mac->mac_phy.task_60s = bwn_phy_n_task_60s;
1457 	} else {
1458 		device_printf(sc->sc_dev, "unsupported PHY type (%d)\n",
1459 		    mac->mac_phy.type);
1460 		error = ENXIO;
1461 		goto fail;
1462 	}
1463 
1464 	mac->mac_phy.gmode = have_bg;
1465 	if (mac->mac_phy.attach != NULL) {
1466 		error = mac->mac_phy.attach(mac);
1467 		if (error) {
1468 			device_printf(sc->sc_dev, "failed\n");
1469 			goto fail;
1470 		}
1471 	}
1472 
1473 	error = bwn_reset_core(mac, have_bg);
1474 	if (error)
1475 		goto fail;
1476 
1477 	error = bwn_chiptest(mac);
1478 	if (error)
1479 		goto fail;
1480 	error = bwn_setup_channels(mac, have_bg, have_a);
1481 	if (error) {
1482 		device_printf(sc->sc_dev, "failed to setup channels\n");
1483 		goto fail;
1484 	}
1485 
1486 	if (sc->sc_curmac == NULL)
1487 		sc->sc_curmac = mac;
1488 
1489 	error = bwn_dma_attach(mac);
1490 	if (error != 0) {
1491 		device_printf(sc->sc_dev, "failed to initialize DMA\n");
1492 		goto fail;
1493 	}
1494 
1495 	mac->mac_phy.switch_analog(mac, 0);
1496 
1497 fail:
1498 	bhnd_suspend_hw(sc->sc_dev, 0);
1499 	bwn_release_firmware(mac);
1500 	return (error);
1501 }
1502 
1503 /*
1504  * Reset
1505  */
1506 int
bwn_reset_core(struct bwn_mac * mac,int g_mode)1507 bwn_reset_core(struct bwn_mac *mac, int g_mode)
1508 {
1509 	struct bwn_softc	*sc;
1510 	uint32_t		 ctl;
1511 	uint16_t		 ioctl, ioctl_mask;
1512 	int			 error;
1513 
1514 	sc = mac->mac_sc;
1515 
1516 	DPRINTF(sc, BWN_DEBUG_RESET, "%s: g_mode=%d\n", __func__, g_mode);
1517 
1518 	/* Reset core */
1519 	ioctl = (BWN_IOCTL_PHYCLOCK_ENABLE | BWN_IOCTL_PHYRESET);
1520 	if (g_mode)
1521 		ioctl |= BWN_IOCTL_SUPPORT_G;
1522 
1523 	/* XXX N-PHY only; and hard-code to 20MHz for now */
1524 	if (mac->mac_phy.type == BWN_PHYTYPE_N)
1525 		ioctl |= BWN_IOCTL_PHY_BANDWIDTH_20MHZ;
1526 
1527 	if ((error = bhnd_reset_hw(sc->sc_dev, ioctl, ioctl))) {
1528 		device_printf(sc->sc_dev, "core reset failed: %d", error);
1529 		return (error);
1530 	}
1531 
1532 	DELAY(2000);
1533 
1534 	/* Take PHY out of reset */
1535 	ioctl = BHND_IOCTL_CLK_FORCE;
1536 	ioctl_mask = BHND_IOCTL_CLK_FORCE |
1537 		     BWN_IOCTL_PHYRESET |
1538 		     BWN_IOCTL_PHYCLOCK_ENABLE;
1539 
1540 	if ((error = bhnd_write_ioctl(sc->sc_dev, ioctl, ioctl_mask))) {
1541 		device_printf(sc->sc_dev, "failed to set core ioctl flags: "
1542 		    "%d\n", error);
1543 		return (error);
1544 	}
1545 
1546 	DELAY(2000);
1547 
1548 	ioctl = BWN_IOCTL_PHYCLOCK_ENABLE;
1549 	if ((error = bhnd_write_ioctl(sc->sc_dev, ioctl, ioctl_mask))) {
1550 		device_printf(sc->sc_dev, "failed to set core ioctl flags: "
1551 		    "%d\n", error);
1552 		return (error);
1553 	}
1554 
1555 	DELAY(2000);
1556 
1557 	if (mac->mac_phy.switch_analog != NULL)
1558 		mac->mac_phy.switch_analog(mac, 1);
1559 
1560 	ctl = BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GMODE;
1561 	if (g_mode)
1562 		ctl |= BWN_MACCTL_GMODE;
1563 	BWN_WRITE_4(mac, BWN_MACCTL, ctl | BWN_MACCTL_IHR_ON);
1564 
1565 	return (0);
1566 }
1567 
1568 static int
bwn_phy_getinfo(struct bwn_mac * mac,int gmode)1569 bwn_phy_getinfo(struct bwn_mac *mac, int gmode)
1570 {
1571 	struct bwn_phy *phy = &mac->mac_phy;
1572 	struct bwn_softc *sc = mac->mac_sc;
1573 	uint32_t tmp;
1574 
1575 	/* PHY */
1576 	tmp = BWN_READ_2(mac, BWN_PHYVER);
1577 	phy->gmode = gmode;
1578 	phy->rf_on = 1;
1579 	phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
1580 	phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
1581 	phy->rev = (tmp & BWN_PHYVER_VERSION);
1582 	if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
1583 	    (phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
1584 		phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
1585 	    (phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
1586 	    (phy->type == BWN_PHYTYPE_N && phy->rev > 6) ||
1587 	    (phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
1588 		goto unsupphy;
1589 
1590 	/* RADIO */
1591 	BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1592 	tmp = BWN_READ_2(mac, BWN_RFDATALO);
1593 	BWN_WRITE_2(mac, BWN_RFCTL, BWN_RFCTL_ID);
1594 	tmp |= (uint32_t)BWN_READ_2(mac, BWN_RFDATAHI) << 16;
1595 
1596 	phy->rf_rev = (tmp & 0xf0000000) >> 28;
1597 	phy->rf_ver = (tmp & 0x0ffff000) >> 12;
1598 	phy->rf_manuf = (tmp & 0x00000fff);
1599 
1600 	/*
1601 	 * For now, just always do full init (ie, what bwn has traditionally
1602 	 * done)
1603 	 */
1604 	phy->phy_do_full_init = 1;
1605 
1606 	if (phy->rf_manuf != 0x17f)	/* 0x17f is broadcom */
1607 		goto unsupradio;
1608 	if ((phy->type == BWN_PHYTYPE_A && (phy->rf_ver != 0x2060 ||
1609 	     phy->rf_rev != 1 || phy->rf_manuf != 0x17f)) ||
1610 	    (phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
1611 	    (phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
1612 	    (phy->type == BWN_PHYTYPE_N &&
1613 	     phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
1614 	    (phy->type == BWN_PHYTYPE_LP &&
1615 	     phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
1616 		goto unsupradio;
1617 
1618 	return (0);
1619 unsupphy:
1620 	device_printf(sc->sc_dev, "unsupported PHY (type %#x, rev %#x, "
1621 	    "analog %#x)\n",
1622 	    phy->type, phy->rev, phy->analog);
1623 	return (ENXIO);
1624 unsupradio:
1625 	device_printf(sc->sc_dev, "unsupported radio (manuf %#x, ver %#x, "
1626 	    "rev %#x)\n",
1627 	    phy->rf_manuf, phy->rf_ver, phy->rf_rev);
1628 	return (ENXIO);
1629 }
1630 
1631 static int
bwn_chiptest(struct bwn_mac * mac)1632 bwn_chiptest(struct bwn_mac *mac)
1633 {
1634 #define	TESTVAL0	0x55aaaa55
1635 #define	TESTVAL1	0xaa5555aa
1636 	struct bwn_softc *sc = mac->mac_sc;
1637 	uint32_t v, backup;
1638 
1639 	BWN_LOCK(sc);
1640 
1641 	backup = bwn_shm_read_4(mac, BWN_SHARED, 0);
1642 
1643 	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL0);
1644 	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL0)
1645 		goto error;
1646 	bwn_shm_write_4(mac, BWN_SHARED, 0, TESTVAL1);
1647 	if (bwn_shm_read_4(mac, BWN_SHARED, 0) != TESTVAL1)
1648 		goto error;
1649 
1650 	bwn_shm_write_4(mac, BWN_SHARED, 0, backup);
1651 
1652 	if ((bhnd_get_hwrev(sc->sc_dev) >= 3) &&
1653 	    (bhnd_get_hwrev(sc->sc_dev) <= 10)) {
1654 		BWN_WRITE_2(mac, BWN_TSF_CFP_START, 0xaaaa);
1655 		BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0xccccbbbb);
1656 		if (BWN_READ_2(mac, BWN_TSF_CFP_START_LOW) != 0xbbbb)
1657 			goto error;
1658 		if (BWN_READ_2(mac, BWN_TSF_CFP_START_HIGH) != 0xcccc)
1659 			goto error;
1660 	}
1661 	BWN_WRITE_4(mac, BWN_TSF_CFP_START, 0);
1662 
1663 	v = BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_GMODE;
1664 	if (v != (BWN_MACCTL_GMODE | BWN_MACCTL_IHR_ON))
1665 		goto error;
1666 
1667 	BWN_UNLOCK(sc);
1668 	return (0);
1669 error:
1670 	BWN_UNLOCK(sc);
1671 	device_printf(sc->sc_dev, "failed to validate the chipaccess\n");
1672 	return (ENODEV);
1673 }
1674 
1675 static int
bwn_setup_channels(struct bwn_mac * mac,int have_bg,int have_a)1676 bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
1677 {
1678 	struct bwn_softc *sc = mac->mac_sc;
1679 	struct ieee80211com *ic = &sc->sc_ic;
1680 	uint8_t bands[IEEE80211_MODE_BYTES];
1681 
1682 	memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
1683 	ic->ic_nchans = 0;
1684 
1685 	DPRINTF(sc, BWN_DEBUG_EEPROM, "%s: called; bg=%d, a=%d\n",
1686 	    __func__,
1687 	    have_bg,
1688 	    have_a);
1689 
1690 	if (have_bg) {
1691 		memset(bands, 0, sizeof(bands));
1692 		setbit(bands, IEEE80211_MODE_11B);
1693 		setbit(bands, IEEE80211_MODE_11G);
1694 		bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1695 		    &ic->ic_nchans, &bwn_chantable_bg, bands);
1696 	}
1697 
1698 	if (have_a) {
1699 		memset(bands, 0, sizeof(bands));
1700 		setbit(bands, IEEE80211_MODE_11A);
1701 		bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
1702 		    &ic->ic_nchans, &bwn_chantable_a, bands);
1703 	}
1704 
1705 	mac->mac_phy.supports_2ghz = have_bg;
1706 	mac->mac_phy.supports_5ghz = have_a;
1707 
1708 	return (ic->ic_nchans == 0 ? ENXIO : 0);
1709 }
1710 
1711 uint32_t
bwn_shm_read_4(struct bwn_mac * mac,uint16_t way,uint16_t offset)1712 bwn_shm_read_4(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1713 {
1714 	uint32_t ret;
1715 
1716 	BWN_ASSERT_LOCKED(mac->mac_sc);
1717 
1718 	if (way == BWN_SHARED) {
1719 		KASSERT((offset & 0x0001) == 0,
1720 		    ("%s:%d warn", __func__, __LINE__));
1721 		if (offset & 0x0003) {
1722 			bwn_shm_ctlword(mac, way, offset >> 2);
1723 			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1724 			ret <<= 16;
1725 			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1726 			ret |= BWN_READ_2(mac, BWN_SHM_DATA);
1727 			goto out;
1728 		}
1729 		offset >>= 2;
1730 	}
1731 	bwn_shm_ctlword(mac, way, offset);
1732 	ret = BWN_READ_4(mac, BWN_SHM_DATA);
1733 out:
1734 	return (ret);
1735 }
1736 
1737 uint16_t
bwn_shm_read_2(struct bwn_mac * mac,uint16_t way,uint16_t offset)1738 bwn_shm_read_2(struct bwn_mac *mac, uint16_t way, uint16_t offset)
1739 {
1740 	uint16_t ret;
1741 
1742 	BWN_ASSERT_LOCKED(mac->mac_sc);
1743 
1744 	if (way == BWN_SHARED) {
1745 		KASSERT((offset & 0x0001) == 0,
1746 		    ("%s:%d warn", __func__, __LINE__));
1747 		if (offset & 0x0003) {
1748 			bwn_shm_ctlword(mac, way, offset >> 2);
1749 			ret = BWN_READ_2(mac, BWN_SHM_DATA_UNALIGNED);
1750 			goto out;
1751 		}
1752 		offset >>= 2;
1753 	}
1754 	bwn_shm_ctlword(mac, way, offset);
1755 	ret = BWN_READ_2(mac, BWN_SHM_DATA);
1756 out:
1757 
1758 	return (ret);
1759 }
1760 
1761 static void
bwn_shm_ctlword(struct bwn_mac * mac,uint16_t way,uint16_t offset)1762 bwn_shm_ctlword(struct bwn_mac *mac, uint16_t way,
1763     uint16_t offset)
1764 {
1765 	uint32_t control;
1766 
1767 	control = way;
1768 	control <<= 16;
1769 	control |= offset;
1770 	BWN_WRITE_4(mac, BWN_SHM_CONTROL, control);
1771 }
1772 
1773 void
bwn_shm_write_4(struct bwn_mac * mac,uint16_t way,uint16_t offset,uint32_t value)1774 bwn_shm_write_4(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1775     uint32_t value)
1776 {
1777 	BWN_ASSERT_LOCKED(mac->mac_sc);
1778 
1779 	if (way == BWN_SHARED) {
1780 		KASSERT((offset & 0x0001) == 0,
1781 		    ("%s:%d warn", __func__, __LINE__));
1782 		if (offset & 0x0003) {
1783 			bwn_shm_ctlword(mac, way, offset >> 2);
1784 			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED,
1785 				    (value >> 16) & 0xffff);
1786 			bwn_shm_ctlword(mac, way, (offset >> 2) + 1);
1787 			BWN_WRITE_2(mac, BWN_SHM_DATA, value & 0xffff);
1788 			return;
1789 		}
1790 		offset >>= 2;
1791 	}
1792 	bwn_shm_ctlword(mac, way, offset);
1793 	BWN_WRITE_4(mac, BWN_SHM_DATA, value);
1794 }
1795 
1796 void
bwn_shm_write_2(struct bwn_mac * mac,uint16_t way,uint16_t offset,uint16_t value)1797 bwn_shm_write_2(struct bwn_mac *mac, uint16_t way, uint16_t offset,
1798     uint16_t value)
1799 {
1800 	BWN_ASSERT_LOCKED(mac->mac_sc);
1801 
1802 	if (way == BWN_SHARED) {
1803 		KASSERT((offset & 0x0001) == 0,
1804 		    ("%s:%d warn", __func__, __LINE__));
1805 		if (offset & 0x0003) {
1806 			bwn_shm_ctlword(mac, way, offset >> 2);
1807 			BWN_WRITE_2(mac, BWN_SHM_DATA_UNALIGNED, value);
1808 			return;
1809 		}
1810 		offset >>= 2;
1811 	}
1812 	bwn_shm_ctlword(mac, way, offset);
1813 	BWN_WRITE_2(mac, BWN_SHM_DATA, value);
1814 }
1815 
1816 static void
bwn_addchannels(struct ieee80211_channel chans[],int maxchans,int * nchans,const struct bwn_channelinfo * ci,const uint8_t bands[])1817 bwn_addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
1818     const struct bwn_channelinfo *ci, const uint8_t bands[])
1819 {
1820 	int i, error;
1821 
1822 	for (i = 0, error = 0; i < ci->nchannels && error == 0; i++) {
1823 		const struct bwn_channel *hc = &ci->channels[i];
1824 
1825 		error = ieee80211_add_channel(chans, maxchans, nchans,
1826 		    hc->ieee, hc->freq, hc->maxTxPow, 0, bands);
1827 	}
1828 }
1829 
1830 static int
bwn_raw_xmit(struct ieee80211_node * ni,struct mbuf * m,const struct ieee80211_bpf_params * params)1831 bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1832 	const struct ieee80211_bpf_params *params)
1833 {
1834 	struct ieee80211com *ic = ni->ni_ic;
1835 	struct bwn_softc *sc = ic->ic_softc;
1836 	struct bwn_mac *mac = sc->sc_curmac;
1837 	int error;
1838 
1839 	if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 ||
1840 	    mac->mac_status < BWN_MAC_STATUS_STARTED) {
1841 		m_freem(m);
1842 		return (ENETDOWN);
1843 	}
1844 
1845 	BWN_LOCK(sc);
1846 	if (bwn_tx_isfull(sc, m)) {
1847 		m_freem(m);
1848 		BWN_UNLOCK(sc);
1849 		return (ENOBUFS);
1850 	}
1851 
1852 	error = bwn_tx_start(sc, ni, m);
1853 	if (error == 0)
1854 		sc->sc_watchdog_timer = 5;
1855 	BWN_UNLOCK(sc);
1856 	return (error);
1857 }
1858 
1859 /*
1860  * Callback from the 802.11 layer to update the slot time
1861  * based on the current setting.  We use it to notify the
1862  * firmware of ERP changes and the f/w takes care of things
1863  * like slot time and preamble.
1864  */
1865 static void
bwn_updateslot(struct ieee80211com * ic)1866 bwn_updateslot(struct ieee80211com *ic)
1867 {
1868 	struct bwn_softc *sc = ic->ic_softc;
1869 	struct bwn_mac *mac;
1870 
1871 	BWN_LOCK(sc);
1872 	if (sc->sc_flags & BWN_FLAG_RUNNING) {
1873 		mac = (struct bwn_mac *)sc->sc_curmac;
1874 		bwn_set_slot_time(mac, IEEE80211_GET_SLOTTIME(ic));
1875 	}
1876 	BWN_UNLOCK(sc);
1877 }
1878 
1879 /*
1880  * Callback from the 802.11 layer after a promiscuous mode change.
1881  * Note this interface does not check the operating mode as this
1882  * is an internal callback and we are expected to honor the current
1883  * state (e.g. this is used for setting the interface in promiscuous
1884  * mode when operating in hostap mode to do ACS).
1885  */
1886 static void
bwn_update_promisc(struct ieee80211com * ic)1887 bwn_update_promisc(struct ieee80211com *ic)
1888 {
1889 	struct bwn_softc *sc = ic->ic_softc;
1890 	struct bwn_mac *mac = sc->sc_curmac;
1891 
1892 	BWN_LOCK(sc);
1893 	mac = sc->sc_curmac;
1894 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
1895 		if (ic->ic_promisc > 0)
1896 			sc->sc_filters |= BWN_MACCTL_PROMISC;
1897 		else
1898 			sc->sc_filters &= ~BWN_MACCTL_PROMISC;
1899 		bwn_set_opmode(mac);
1900 	}
1901 	BWN_UNLOCK(sc);
1902 }
1903 
1904 /*
1905  * Callback from the 802.11 layer to update WME parameters.
1906  */
1907 static int
bwn_wme_update(struct ieee80211com * ic)1908 bwn_wme_update(struct ieee80211com *ic)
1909 {
1910 	struct bwn_softc *sc = ic->ic_softc;
1911 	struct bwn_mac *mac = sc->sc_curmac;
1912 	struct chanAccParams chp;
1913 	struct wmeParams *wmep;
1914 	int i;
1915 
1916 	ieee80211_wme_ic_getparams(ic, &chp);
1917 
1918 	BWN_LOCK(sc);
1919 	mac = sc->sc_curmac;
1920 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
1921 		bwn_mac_suspend(mac);
1922 		for (i = 0; i < N(sc->sc_wmeParams); i++) {
1923 			wmep = &chp.cap_wmeParams[i];
1924 			bwn_wme_loadparams(mac, wmep, bwn_wme_shm_offsets[i]);
1925 		}
1926 		bwn_mac_enable(mac);
1927 	}
1928 	BWN_UNLOCK(sc);
1929 	return (0);
1930 }
1931 
1932 static void
bwn_scan_start(struct ieee80211com * ic)1933 bwn_scan_start(struct ieee80211com *ic)
1934 {
1935 	struct bwn_softc *sc = ic->ic_softc;
1936 	struct bwn_mac *mac;
1937 
1938 	BWN_LOCK(sc);
1939 	mac = sc->sc_curmac;
1940 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
1941 		sc->sc_filters |= BWN_MACCTL_BEACON_PROMISC;
1942 		bwn_set_opmode(mac);
1943 		/* disable CFP update during scan */
1944 		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_SKIP_CFP_UPDATE);
1945 	}
1946 	BWN_UNLOCK(sc);
1947 }
1948 
1949 static void
bwn_scan_end(struct ieee80211com * ic)1950 bwn_scan_end(struct ieee80211com *ic)
1951 {
1952 	struct bwn_softc *sc = ic->ic_softc;
1953 	struct bwn_mac *mac;
1954 
1955 	BWN_LOCK(sc);
1956 	mac = sc->sc_curmac;
1957 	if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
1958 		sc->sc_filters &= ~BWN_MACCTL_BEACON_PROMISC;
1959 		bwn_set_opmode(mac);
1960 		bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_SKIP_CFP_UPDATE);
1961 	}
1962 	BWN_UNLOCK(sc);
1963 }
1964 
1965 static void
bwn_set_channel(struct ieee80211com * ic)1966 bwn_set_channel(struct ieee80211com *ic)
1967 {
1968 	struct bwn_softc *sc = ic->ic_softc;
1969 	struct bwn_mac *mac = sc->sc_curmac;
1970 	struct bwn_phy *phy = &mac->mac_phy;
1971 	int chan, error;
1972 
1973 	BWN_LOCK(sc);
1974 
1975 	error = bwn_switch_band(sc, ic->ic_curchan);
1976 	if (error)
1977 		goto fail;
1978 	bwn_mac_suspend(mac);
1979 	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
1980 	chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
1981 	if (chan != phy->chan)
1982 		bwn_switch_channel(mac, chan);
1983 
1984 	/* TX power level */
1985 	if (ic->ic_curchan->ic_maxpower != 0 &&
1986 	    ic->ic_curchan->ic_maxpower != phy->txpower) {
1987 		phy->txpower = ic->ic_curchan->ic_maxpower / 2;
1988 		bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME |
1989 		    BWN_TXPWR_IGNORE_TSSI);
1990 	}
1991 
1992 	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
1993 	if (phy->set_antenna)
1994 		phy->set_antenna(mac, BWN_ANT_DEFAULT);
1995 
1996 	if (sc->sc_rf_enabled != phy->rf_on) {
1997 		if (sc->sc_rf_enabled) {
1998 			bwn_rf_turnon(mac);
1999 			if (!(mac->mac_flags & BWN_MAC_FLAG_RADIO_ON))
2000 				device_printf(sc->sc_dev,
2001 				    "please turn on the RF switch\n");
2002 		} else
2003 			bwn_rf_turnoff(mac);
2004 	}
2005 
2006 	bwn_mac_enable(mac);
2007 
2008 fail:
2009 	BWN_UNLOCK(sc);
2010 }
2011 
2012 static struct ieee80211vap *
bwn_vap_create(struct ieee80211com * ic,const char name[IFNAMSIZ],int unit,enum ieee80211_opmode opmode,int flags,const uint8_t bssid[IEEE80211_ADDR_LEN],const uint8_t mac[IEEE80211_ADDR_LEN])2013 bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
2014     enum ieee80211_opmode opmode, int flags,
2015     const uint8_t bssid[IEEE80211_ADDR_LEN],
2016     const uint8_t mac[IEEE80211_ADDR_LEN])
2017 {
2018 	struct ieee80211vap *vap;
2019 	struct bwn_vap *bvp;
2020 
2021 	switch (opmode) {
2022 	case IEEE80211_M_HOSTAP:
2023 	case IEEE80211_M_MBSS:
2024 	case IEEE80211_M_STA:
2025 	case IEEE80211_M_WDS:
2026 	case IEEE80211_M_MONITOR:
2027 	case IEEE80211_M_IBSS:
2028 	case IEEE80211_M_AHDEMO:
2029 		break;
2030 	default:
2031 		return (NULL);
2032 	}
2033 
2034 	bvp = malloc(sizeof(struct bwn_vap), M_80211_VAP, M_WAITOK | M_ZERO);
2035 	vap = &bvp->bv_vap;
2036 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
2037 	/* override with driver methods */
2038 	bvp->bv_newstate = vap->iv_newstate;
2039 	vap->iv_newstate = bwn_newstate;
2040 
2041 	/* override max aid so sta's cannot assoc when we're out of sta id's */
2042 	vap->iv_max_aid = BWN_STAID_MAX;
2043 
2044 	ieee80211_ratectl_init(vap);
2045 
2046 	/* complete setup */
2047 	ieee80211_vap_attach(vap, ieee80211_media_change,
2048 	    ieee80211_media_status, mac);
2049 	return (vap);
2050 }
2051 
2052 static void
bwn_vap_delete(struct ieee80211vap * vap)2053 bwn_vap_delete(struct ieee80211vap *vap)
2054 {
2055 	struct bwn_vap *bvp = BWN_VAP(vap);
2056 
2057 	ieee80211_ratectl_deinit(vap);
2058 	ieee80211_vap_detach(vap);
2059 	free(bvp, M_80211_VAP);
2060 }
2061 
2062 static int
bwn_init(struct bwn_softc * sc)2063 bwn_init(struct bwn_softc *sc)
2064 {
2065 	struct bwn_mac *mac;
2066 	int error;
2067 
2068 	BWN_ASSERT_LOCKED(sc);
2069 
2070 	DPRINTF(sc, BWN_DEBUG_RESET, "%s: called\n", __func__);
2071 
2072 	bzero(sc->sc_bssid, IEEE80211_ADDR_LEN);
2073 	sc->sc_flags |= BWN_FLAG_NEED_BEACON_TP;
2074 	sc->sc_filters = 0;
2075 	bwn_wme_clear(sc);
2076 	sc->sc_beacons[0] = sc->sc_beacons[1] = 0;
2077 	sc->sc_rf_enabled = 1;
2078 
2079 	mac = sc->sc_curmac;
2080 	if (mac->mac_status == BWN_MAC_STATUS_UNINIT) {
2081 		error = bwn_core_init(mac);
2082 		if (error != 0)
2083 			return (error);
2084 	}
2085 	if (mac->mac_status == BWN_MAC_STATUS_INITED)
2086 		bwn_core_start(mac);
2087 
2088 	bwn_set_opmode(mac);
2089 	bwn_set_pretbtt(mac);
2090 	bwn_spu_setdelay(mac, 0);
2091 	bwn_set_macaddr(mac);
2092 
2093 	sc->sc_flags |= BWN_FLAG_RUNNING;
2094 	callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
2095 	callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
2096 
2097 	return (0);
2098 }
2099 
2100 static void
bwn_stop(struct bwn_softc * sc)2101 bwn_stop(struct bwn_softc *sc)
2102 {
2103 	struct bwn_mac *mac = sc->sc_curmac;
2104 
2105 	BWN_ASSERT_LOCKED(sc);
2106 
2107 	DPRINTF(sc, BWN_DEBUG_RESET, "%s: called\n", __func__);
2108 
2109 	if (mac->mac_status >= BWN_MAC_STATUS_INITED) {
2110 		/* XXX FIXME opmode not based on VAP */
2111 		bwn_set_opmode(mac);
2112 		bwn_set_macaddr(mac);
2113 	}
2114 
2115 	if (mac->mac_status >= BWN_MAC_STATUS_STARTED)
2116 		bwn_core_stop(mac);
2117 
2118 	callout_stop(&sc->sc_led_blink_ch);
2119 	sc->sc_led_blinking = 0;
2120 
2121 	bwn_core_exit(mac);
2122 	sc->sc_rf_enabled = 0;
2123 
2124 	sc->sc_flags &= ~BWN_FLAG_RUNNING;
2125 }
2126 
2127 static void
bwn_wme_clear(struct bwn_softc * sc)2128 bwn_wme_clear(struct bwn_softc *sc)
2129 {
2130 	struct wmeParams *p;
2131 	unsigned int i;
2132 
2133 	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
2134 	    ("%s:%d: fail", __func__, __LINE__));
2135 
2136 	for (i = 0; i < N(sc->sc_wmeParams); i++) {
2137 		p = &(sc->sc_wmeParams[i]);
2138 
2139 		switch (bwn_wme_shm_offsets[i]) {
2140 		case BWN_WME_VOICE:
2141 			p->wmep_txopLimit = 0;
2142 			p->wmep_aifsn = 2;
2143 			/* XXX FIXME: log2(cwmin) */
2144 			p->wmep_logcwmin =
2145 			    _IEEE80211_MASKSHIFT(0x0001, WME_PARAM_LOGCWMIN);
2146 			p->wmep_logcwmax =
2147 			    _IEEE80211_MASKSHIFT(0x0001, WME_PARAM_LOGCWMAX);
2148 			break;
2149 		case BWN_WME_VIDEO:
2150 			p->wmep_txopLimit = 0;
2151 			p->wmep_aifsn = 2;
2152 			/* XXX FIXME: log2(cwmin) */
2153 			p->wmep_logcwmin =
2154 			    _IEEE80211_MASKSHIFT(0x0001, WME_PARAM_LOGCWMIN);
2155 			p->wmep_logcwmax =
2156 			    _IEEE80211_MASKSHIFT(0x0001, WME_PARAM_LOGCWMAX);
2157 			break;
2158 		case BWN_WME_BESTEFFORT:
2159 			p->wmep_txopLimit = 0;
2160 			p->wmep_aifsn = 3;
2161 			/* XXX FIXME: log2(cwmin) */
2162 			p->wmep_logcwmin =
2163 			    _IEEE80211_MASKSHIFT(0x0001, WME_PARAM_LOGCWMIN);
2164 			p->wmep_logcwmax =
2165 			    _IEEE80211_MASKSHIFT(0x03ff, WME_PARAM_LOGCWMAX);
2166 			break;
2167 		case BWN_WME_BACKGROUND:
2168 			p->wmep_txopLimit = 0;
2169 			p->wmep_aifsn = 7;
2170 			/* XXX FIXME: log2(cwmin) */
2171 			p->wmep_logcwmin =
2172 			    _IEEE80211_MASKSHIFT(0x0001, WME_PARAM_LOGCWMIN);
2173 			p->wmep_logcwmax =
2174 			    _IEEE80211_MASKSHIFT(0x03ff, WME_PARAM_LOGCWMAX);
2175 			break;
2176 		default:
2177 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
2178 		}
2179 	}
2180 }
2181 
2182 static int
bwn_core_forceclk(struct bwn_mac * mac,bool force)2183 bwn_core_forceclk(struct bwn_mac *mac, bool force)
2184 {
2185 	struct bwn_softc	*sc;
2186 	bhnd_clock		 clock;
2187 	int			 error;
2188 
2189 	sc = mac->mac_sc;
2190 
2191 	/* On PMU equipped devices, we do not need to force the HT clock */
2192 	if (sc->sc_pmu != NULL)
2193 		return (0);
2194 
2195 	/* Issue a PMU clock request */
2196 	if (force)
2197 		clock = BHND_CLOCK_HT;
2198 	else
2199 		clock = BHND_CLOCK_DYN;
2200 
2201 	if ((error = bhnd_request_clock(sc->sc_dev, clock))) {
2202 		device_printf(sc->sc_dev, "%d clock request failed: %d\n",
2203 		    clock, error);
2204 		return (error);
2205 	}
2206 
2207 	return (0);
2208 }
2209 
2210 static int
bwn_core_init(struct bwn_mac * mac)2211 bwn_core_init(struct bwn_mac *mac)
2212 {
2213 	struct bwn_softc *sc = mac->mac_sc;
2214 	uint64_t hf;
2215 	int error;
2216 
2217 	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
2218 	    ("%s:%d: fail", __func__, __LINE__));
2219 
2220 	DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: called\n", __func__);
2221 
2222 	if ((error = bwn_core_forceclk(mac, true)))
2223 		return (error);
2224 
2225 	if (bhnd_is_hw_suspended(sc->sc_dev)) {
2226 		if ((error = bwn_reset_core(mac, mac->mac_phy.gmode)))
2227 			goto fail0;
2228 	}
2229 
2230 	mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
2231 	mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
2232 	mac->mac_phy.hwpctl = (bwn_hwpctl) ? 1 : 0;
2233 	BWN_GETTIME(mac->mac_phy.nexttime);
2234 	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
2235 	bzero(&mac->mac_stats, sizeof(mac->mac_stats));
2236 	mac->mac_stats.link_noise = -95;
2237 	mac->mac_reason_intr = 0;
2238 	bzero(mac->mac_reason, sizeof(mac->mac_reason));
2239 	mac->mac_intr_mask = BWN_INTR_MASKTEMPLATE;
2240 #ifdef BWN_DEBUG
2241 	if (sc->sc_debug & BWN_DEBUG_XMIT)
2242 		mac->mac_intr_mask &= ~BWN_INTR_PHY_TXERR;
2243 #endif
2244 	mac->mac_suspended = 1;
2245 	mac->mac_task_state = 0;
2246 	memset(&mac->mac_noise, 0, sizeof(mac->mac_noise));
2247 
2248 	mac->mac_phy.init_pre(mac);
2249 
2250 	bwn_bt_disable(mac);
2251 	if (mac->mac_phy.prepare_hw) {
2252 		error = mac->mac_phy.prepare_hw(mac);
2253 		if (error)
2254 			goto fail0;
2255 	}
2256 	DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: chip_init\n", __func__);
2257 	error = bwn_chip_init(mac);
2258 	if (error)
2259 		goto fail0;
2260 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_COREREV,
2261 	    bhnd_get_hwrev(sc->sc_dev));
2262 	hf = bwn_hf_read(mac);
2263 	if (mac->mac_phy.type == BWN_PHYTYPE_G) {
2264 		hf |= BWN_HF_GPHY_SYM_WORKAROUND;
2265 		if (sc->sc_board_info.board_flags & BHND_BFL_PACTRL)
2266 			hf |= BWN_HF_PAGAINBOOST_OFDM_ON;
2267 		if (mac->mac_phy.rev == 1)
2268 			hf |= BWN_HF_GPHY_DC_CANCELFILTER;
2269 	}
2270 	if (mac->mac_phy.rf_ver == 0x2050) {
2271 		if (mac->mac_phy.rf_rev < 6)
2272 			hf |= BWN_HF_FORCE_VCO_RECALC;
2273 		if (mac->mac_phy.rf_rev == 6)
2274 			hf |= BWN_HF_4318_TSSI;
2275 	}
2276 	if (sc->sc_board_info.board_flags & BHND_BFL_NOPLLDOWN)
2277 		hf |= BWN_HF_SLOWCLOCK_REQ_OFF;
2278 	if (sc->sc_quirks & BWN_QUIRK_UCODE_SLOWCLOCK_WAR)
2279 		hf |= BWN_HF_PCI_SLOWCLOCK_WORKAROUND;
2280 	hf &= ~BWN_HF_SKIP_CFP_UPDATE;
2281 	bwn_hf_write(mac, hf);
2282 
2283 	/* Tell the firmware about the MAC capabilities */
2284 	if (bhnd_get_hwrev(sc->sc_dev) >= 13) {
2285 		uint32_t cap;
2286 		cap = BWN_READ_4(mac, BWN_MAC_HW_CAP);
2287 		DPRINTF(sc, BWN_DEBUG_RESET,
2288 		    "%s: hw capabilities: 0x%08x\n",
2289 		    __func__, cap);
2290 		bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_MACHW_L,
2291 		    cap & 0xffff);
2292 		bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_MACHW_H,
2293 		    (cap >> 16) & 0xffff);
2294 	}
2295 
2296 	bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
2297 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
2298 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
2299 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
2300 
2301 	bwn_rate_init(mac);
2302 	bwn_set_phytxctl(mac);
2303 
2304 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MIN,
2305 	    (mac->mac_phy.type == BWN_PHYTYPE_B) ? 0x1f : 0xf);
2306 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_CONT_MAX, 0x3ff);
2307 
2308 	if (sc->sc_quirks & BWN_QUIRK_NODMA)
2309 		bwn_pio_init(mac);
2310 	else
2311 		bwn_dma_init(mac);
2312 	bwn_wme_init(mac);
2313 	bwn_spu_setdelay(mac, 1);
2314 	bwn_bt_enable(mac);
2315 
2316 	DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: powerup\n", __func__);
2317 	if (sc->sc_board_info.board_flags & BHND_BFL_NOPLLDOWN)
2318 		bwn_core_forceclk(mac, true);
2319 	else
2320 		bwn_core_forceclk(mac, false);
2321 
2322 	bwn_set_macaddr(mac);
2323 	bwn_crypt_init(mac);
2324 
2325 	/* XXX LED initializatin */
2326 
2327 	mac->mac_status = BWN_MAC_STATUS_INITED;
2328 
2329 	DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: done\n", __func__);
2330 	return (error);
2331 
2332 fail0:
2333 	bhnd_suspend_hw(sc->sc_dev, 0);
2334 	KASSERT(mac->mac_status == BWN_MAC_STATUS_UNINIT,
2335 	    ("%s:%d: fail", __func__, __LINE__));
2336 	DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: fail\n", __func__);
2337 	return (error);
2338 }
2339 
2340 static void
bwn_core_start(struct bwn_mac * mac)2341 bwn_core_start(struct bwn_mac *mac)
2342 {
2343 	struct bwn_softc *sc = mac->mac_sc;
2344 	uint32_t tmp;
2345 
2346 	KASSERT(mac->mac_status == BWN_MAC_STATUS_INITED,
2347 	    ("%s:%d: fail", __func__, __LINE__));
2348 
2349 	if (bhnd_get_hwrev(sc->sc_dev) < 5)
2350 		return;
2351 
2352 	while (1) {
2353 		tmp = BWN_READ_4(mac, BWN_XMITSTAT_0);
2354 		if (!(tmp & 0x00000001))
2355 			break;
2356 		tmp = BWN_READ_4(mac, BWN_XMITSTAT_1);
2357 	}
2358 
2359 	bwn_mac_enable(mac);
2360 	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
2361 	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
2362 
2363 	mac->mac_status = BWN_MAC_STATUS_STARTED;
2364 }
2365 
2366 static void
bwn_core_exit(struct bwn_mac * mac)2367 bwn_core_exit(struct bwn_mac *mac)
2368 {
2369 	struct bwn_softc *sc = mac->mac_sc;
2370 	uint32_t macctl;
2371 
2372 	BWN_ASSERT_LOCKED(mac->mac_sc);
2373 
2374 	KASSERT(mac->mac_status <= BWN_MAC_STATUS_INITED,
2375 	    ("%s:%d: fail", __func__, __LINE__));
2376 
2377 	if (mac->mac_status != BWN_MAC_STATUS_INITED)
2378 		return;
2379 	mac->mac_status = BWN_MAC_STATUS_UNINIT;
2380 
2381 	macctl = BWN_READ_4(mac, BWN_MACCTL);
2382 	macctl &= ~BWN_MACCTL_MCODE_RUN;
2383 	macctl |= BWN_MACCTL_MCODE_JMP0;
2384 	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
2385 
2386 	bwn_dma_stop(mac);
2387 	bwn_pio_stop(mac);
2388 	bwn_chip_exit(mac);
2389 	mac->mac_phy.switch_analog(mac, 0);
2390 	bhnd_suspend_hw(sc->sc_dev, 0);
2391 }
2392 
2393 static void
bwn_bt_disable(struct bwn_mac * mac)2394 bwn_bt_disable(struct bwn_mac *mac)
2395 {
2396 	struct bwn_softc *sc = mac->mac_sc;
2397 
2398 	(void)sc;
2399 	/* XXX do nothing yet */
2400 }
2401 
2402 static int
bwn_chip_init(struct bwn_mac * mac)2403 bwn_chip_init(struct bwn_mac *mac)
2404 {
2405 	struct bwn_softc *sc = mac->mac_sc;
2406 	struct bwn_phy *phy = &mac->mac_phy;
2407 	uint32_t macctl;
2408 	u_int delay;
2409 	int error;
2410 
2411 	macctl = BWN_MACCTL_IHR_ON | BWN_MACCTL_SHM_ON | BWN_MACCTL_STA;
2412 	if (phy->gmode)
2413 		macctl |= BWN_MACCTL_GMODE;
2414 	BWN_WRITE_4(mac, BWN_MACCTL, macctl);
2415 
2416 	error = bwn_fw_fillinfo(mac);
2417 	if (error)
2418 		return (error);
2419 	error = bwn_fw_loaducode(mac);
2420 	if (error)
2421 		return (error);
2422 
2423 	error = bwn_gpio_init(mac);
2424 	if (error)
2425 		return (error);
2426 
2427 	error = bwn_fw_loadinitvals(mac);
2428 	if (error)
2429 		return (error);
2430 
2431 	phy->switch_analog(mac, 1);
2432 	error = bwn_phy_init(mac);
2433 	if (error)
2434 		return (error);
2435 
2436 	if (phy->set_im)
2437 		phy->set_im(mac, BWN_IMMODE_NONE);
2438 	if (phy->set_antenna)
2439 		phy->set_antenna(mac, BWN_ANT_DEFAULT);
2440 	bwn_set_txantenna(mac, BWN_ANT_DEFAULT);
2441 
2442 	if (phy->type == BWN_PHYTYPE_B)
2443 		BWN_WRITE_2(mac, 0x005e, BWN_READ_2(mac, 0x005e) | 0x0004);
2444 	BWN_WRITE_4(mac, 0x0100, 0x01000000);
2445 	if (bhnd_get_hwrev(sc->sc_dev) < 5)
2446 		BWN_WRITE_4(mac, 0x010c, 0x01000000);
2447 
2448 	BWN_WRITE_4(mac, BWN_MACCTL,
2449 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_STA);
2450 	BWN_WRITE_4(mac, BWN_MACCTL,
2451 	    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_STA);
2452 	bwn_shm_write_2(mac, BWN_SHARED, 0x0074, 0x0000);
2453 
2454 	bwn_set_opmode(mac);
2455 	if (bhnd_get_hwrev(sc->sc_dev) < 3) {
2456 		BWN_WRITE_2(mac, 0x060e, 0x0000);
2457 		BWN_WRITE_2(mac, 0x0610, 0x8000);
2458 		BWN_WRITE_2(mac, 0x0604, 0x0000);
2459 		BWN_WRITE_2(mac, 0x0606, 0x0200);
2460 	} else {
2461 		BWN_WRITE_4(mac, 0x0188, 0x80000000);
2462 		BWN_WRITE_4(mac, 0x018c, 0x02000000);
2463 	}
2464 	BWN_WRITE_4(mac, BWN_INTR_REASON, 0x00004000);
2465 	BWN_WRITE_4(mac, BWN_DMA0_INTR_MASK, 0x0001dc00);
2466 	BWN_WRITE_4(mac, BWN_DMA1_INTR_MASK, 0x0000dc00);
2467 	BWN_WRITE_4(mac, BWN_DMA2_INTR_MASK, 0x0000dc00);
2468 	BWN_WRITE_4(mac, BWN_DMA3_INTR_MASK, 0x0001dc00);
2469 	BWN_WRITE_4(mac, BWN_DMA4_INTR_MASK, 0x0000dc00);
2470 	BWN_WRITE_4(mac, BWN_DMA5_INTR_MASK, 0x0000dc00);
2471 
2472 	bwn_mac_phy_clock_set(mac, true);
2473 
2474 	/* Provide the HT clock transition latency to the MAC core */
2475 	error = bhnd_get_clock_latency(sc->sc_dev, BHND_CLOCK_HT, &delay);
2476 	if (error) {
2477 		device_printf(sc->sc_dev, "failed to fetch HT clock latency: "
2478 		    "%d\n", error);
2479 		return (error);
2480 	}
2481 
2482 	if (delay > UINT16_MAX) {
2483 		device_printf(sc->sc_dev, "invalid HT clock latency: %u\n",
2484 		    delay);
2485 		return (ENXIO);
2486 	}
2487 
2488 	BWN_WRITE_2(mac, BWN_POWERUP_DELAY, delay);
2489 	return (0);
2490 }
2491 
2492 /* read hostflags */
2493 uint64_t
bwn_hf_read(struct bwn_mac * mac)2494 bwn_hf_read(struct bwn_mac *mac)
2495 {
2496 	uint64_t ret;
2497 
2498 	ret = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFHI);
2499 	ret <<= 16;
2500 	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFMI);
2501 	ret <<= 16;
2502 	ret |= bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_HFLO);
2503 	return (ret);
2504 }
2505 
2506 void
bwn_hf_write(struct bwn_mac * mac,uint64_t value)2507 bwn_hf_write(struct bwn_mac *mac, uint64_t value)
2508 {
2509 
2510 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFLO,
2511 	    (value & 0x00000000ffffull));
2512 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFMI,
2513 	    (value & 0x0000ffff0000ull) >> 16);
2514 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_HFHI,
2515 	    (value & 0xffff00000000ULL) >> 32);
2516 }
2517 
2518 static void
bwn_set_txretry(struct bwn_mac * mac,int s,int l)2519 bwn_set_txretry(struct bwn_mac *mac, int s, int l)
2520 {
2521 
2522 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_SHORT_RETRY, MIN(s, 0xf));
2523 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_SCRATCH_LONG_RETRY, MIN(l, 0xf));
2524 }
2525 
2526 static void
bwn_rate_init(struct bwn_mac * mac)2527 bwn_rate_init(struct bwn_mac *mac)
2528 {
2529 
2530 	switch (mac->mac_phy.type) {
2531 	case BWN_PHYTYPE_A:
2532 	case BWN_PHYTYPE_G:
2533 	case BWN_PHYTYPE_LP:
2534 	case BWN_PHYTYPE_N:
2535 		bwn_rate_write(mac, BWN_OFDM_RATE_6MB, 1);
2536 		bwn_rate_write(mac, BWN_OFDM_RATE_12MB, 1);
2537 		bwn_rate_write(mac, BWN_OFDM_RATE_18MB, 1);
2538 		bwn_rate_write(mac, BWN_OFDM_RATE_24MB, 1);
2539 		bwn_rate_write(mac, BWN_OFDM_RATE_36MB, 1);
2540 		bwn_rate_write(mac, BWN_OFDM_RATE_48MB, 1);
2541 		bwn_rate_write(mac, BWN_OFDM_RATE_54MB, 1);
2542 		if (mac->mac_phy.type == BWN_PHYTYPE_A)
2543 			break;
2544 		/* FALLTHROUGH */
2545 	case BWN_PHYTYPE_B:
2546 		bwn_rate_write(mac, BWN_CCK_RATE_1MB, 0);
2547 		bwn_rate_write(mac, BWN_CCK_RATE_2MB, 0);
2548 		bwn_rate_write(mac, BWN_CCK_RATE_5MB, 0);
2549 		bwn_rate_write(mac, BWN_CCK_RATE_11MB, 0);
2550 		break;
2551 	default:
2552 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
2553 	}
2554 }
2555 
2556 static void
bwn_rate_write(struct bwn_mac * mac,uint16_t rate,int ofdm)2557 bwn_rate_write(struct bwn_mac *mac, uint16_t rate, int ofdm)
2558 {
2559 	uint16_t offset;
2560 
2561 	if (ofdm) {
2562 		offset = 0x480;
2563 		offset += (bwn_plcp_getofdm(rate) & 0x000f) * 2;
2564 	} else {
2565 		offset = 0x4c0;
2566 		offset += (bwn_plcp_getcck(rate) & 0x000f) * 2;
2567 	}
2568 	bwn_shm_write_2(mac, BWN_SHARED, offset + 0x20,
2569 	    bwn_shm_read_2(mac, BWN_SHARED, offset));
2570 }
2571 
2572 static uint8_t
bwn_plcp_getcck(const uint8_t bitrate)2573 bwn_plcp_getcck(const uint8_t bitrate)
2574 {
2575 
2576 	switch (bitrate) {
2577 	case BWN_CCK_RATE_1MB:
2578 		return (0x0a);
2579 	case BWN_CCK_RATE_2MB:
2580 		return (0x14);
2581 	case BWN_CCK_RATE_5MB:
2582 		return (0x37);
2583 	case BWN_CCK_RATE_11MB:
2584 		return (0x6e);
2585 	}
2586 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
2587 	return (0);
2588 }
2589 
2590 static uint8_t
bwn_plcp_getofdm(const uint8_t bitrate)2591 bwn_plcp_getofdm(const uint8_t bitrate)
2592 {
2593 
2594 	switch (bitrate) {
2595 	case BWN_OFDM_RATE_6MB:
2596 		return (0xb);
2597 	case BWN_OFDM_RATE_9MB:
2598 		return (0xf);
2599 	case BWN_OFDM_RATE_12MB:
2600 		return (0xa);
2601 	case BWN_OFDM_RATE_18MB:
2602 		return (0xe);
2603 	case BWN_OFDM_RATE_24MB:
2604 		return (0x9);
2605 	case BWN_OFDM_RATE_36MB:
2606 		return (0xd);
2607 	case BWN_OFDM_RATE_48MB:
2608 		return (0x8);
2609 	case BWN_OFDM_RATE_54MB:
2610 		return (0xc);
2611 	}
2612 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
2613 	return (0);
2614 }
2615 
2616 static void
bwn_set_phytxctl(struct bwn_mac * mac)2617 bwn_set_phytxctl(struct bwn_mac *mac)
2618 {
2619 	uint16_t ctl;
2620 
2621 	ctl = (BWN_TX_PHY_ENC_CCK | BWN_TX_PHY_ANT01AUTO |
2622 	    BWN_TX_PHY_TXPWR);
2623 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_BEACON_PHYCTL, ctl);
2624 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, ctl);
2625 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, ctl);
2626 }
2627 
2628 static void
bwn_pio_init(struct bwn_mac * mac)2629 bwn_pio_init(struct bwn_mac *mac)
2630 {
2631 	struct bwn_pio *pio = &mac->mac_method.pio;
2632 
2633 	BWN_WRITE_4(mac, BWN_MACCTL, BWN_READ_4(mac, BWN_MACCTL)
2634 	    & ~BWN_MACCTL_BIGENDIAN);
2635 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_RX_PADOFFSET, 0);
2636 
2637 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BK], 0);
2638 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_BE], 1);
2639 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VI], 2);
2640 	bwn_pio_set_txqueue(mac, &pio->wme[WME_AC_VO], 3);
2641 	bwn_pio_set_txqueue(mac, &pio->mcast, 4);
2642 	bwn_pio_setupqueue_rx(mac, &pio->rx, 0);
2643 }
2644 
2645 static void
bwn_pio_set_txqueue(struct bwn_mac * mac,struct bwn_pio_txqueue * tq,int index)2646 bwn_pio_set_txqueue(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
2647     int index)
2648 {
2649 	struct bwn_pio_txpkt *tp;
2650 	struct bwn_softc *sc = mac->mac_sc;
2651 	unsigned int i;
2652 
2653 	tq->tq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_TXQOFFSET(mac);
2654 	tq->tq_index = index;
2655 
2656 	tq->tq_free = BWN_PIO_MAX_TXPACKETS;
2657 	if (bhnd_get_hwrev(sc->sc_dev) >= 8)
2658 		tq->tq_size = 1920;
2659 	else {
2660 		tq->tq_size = bwn_pio_read_2(mac, tq, BWN_PIO_TXQBUFSIZE);
2661 		tq->tq_size -= 80;
2662 	}
2663 
2664 	TAILQ_INIT(&tq->tq_pktlist);
2665 	for (i = 0; i < N(tq->tq_pkts); i++) {
2666 		tp = &(tq->tq_pkts[i]);
2667 		tp->tp_index = i;
2668 		tp->tp_queue = tq;
2669 		TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
2670 	}
2671 }
2672 
2673 static uint16_t
bwn_pio_idx2base(struct bwn_mac * mac,int index)2674 bwn_pio_idx2base(struct bwn_mac *mac, int index)
2675 {
2676 	struct bwn_softc *sc = mac->mac_sc;
2677 	static const uint16_t bases[] = {
2678 		BWN_PIO_BASE0,
2679 		BWN_PIO_BASE1,
2680 		BWN_PIO_BASE2,
2681 		BWN_PIO_BASE3,
2682 		BWN_PIO_BASE4,
2683 		BWN_PIO_BASE5,
2684 		BWN_PIO_BASE6,
2685 		BWN_PIO_BASE7,
2686 	};
2687 	static const uint16_t bases_rev11[] = {
2688 		BWN_PIO11_BASE0,
2689 		BWN_PIO11_BASE1,
2690 		BWN_PIO11_BASE2,
2691 		BWN_PIO11_BASE3,
2692 		BWN_PIO11_BASE4,
2693 		BWN_PIO11_BASE5,
2694 	};
2695 
2696 	if (bhnd_get_hwrev(sc->sc_dev) >= 11) {
2697 		if (index >= N(bases_rev11))
2698 			device_printf(sc->sc_dev, "%s: warning\n", __func__);
2699 		return (bases_rev11[index]);
2700 	}
2701 	if (index >= N(bases))
2702 		device_printf(sc->sc_dev, "%s: warning\n", __func__);
2703 	return (bases[index]);
2704 }
2705 
2706 static void
bwn_pio_setupqueue_rx(struct bwn_mac * mac,struct bwn_pio_rxqueue * prq,int index)2707 bwn_pio_setupqueue_rx(struct bwn_mac *mac, struct bwn_pio_rxqueue *prq,
2708     int index)
2709 {
2710 	struct bwn_softc *sc = mac->mac_sc;
2711 
2712 	prq->prq_mac = mac;
2713 	prq->prq_rev = bhnd_get_hwrev(sc->sc_dev);
2714 	prq->prq_base = bwn_pio_idx2base(mac, index) + BWN_PIO_RXQOFFSET(mac);
2715 	bwn_dma_rxdirectfifo(mac, index, 1);
2716 }
2717 
2718 static void
bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue * tq)2719 bwn_destroy_pioqueue_tx(struct bwn_pio_txqueue *tq)
2720 {
2721 	if (tq == NULL)
2722 		return;
2723 	bwn_pio_cancel_tx_packets(tq);
2724 }
2725 
2726 static void
bwn_destroy_queue_tx(struct bwn_pio_txqueue * pio)2727 bwn_destroy_queue_tx(struct bwn_pio_txqueue *pio)
2728 {
2729 
2730 	bwn_destroy_pioqueue_tx(pio);
2731 }
2732 
2733 static uint16_t
bwn_pio_read_2(struct bwn_mac * mac,struct bwn_pio_txqueue * tq,uint16_t offset)2734 bwn_pio_read_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
2735     uint16_t offset)
2736 {
2737 
2738 	return (BWN_READ_2(mac, tq->tq_base + offset));
2739 }
2740 
2741 static void
bwn_dma_rxdirectfifo(struct bwn_mac * mac,int idx,uint8_t enable)2742 bwn_dma_rxdirectfifo(struct bwn_mac *mac, int idx, uint8_t enable)
2743 {
2744 	uint32_t ctl;
2745 	uint16_t base;
2746 
2747 	base = bwn_dma_base(mac->mac_dmatype, idx);
2748 	if (mac->mac_dmatype == BHND_DMA_ADDR_64BIT) {
2749 		ctl = BWN_READ_4(mac, base + BWN_DMA64_RXCTL);
2750 		ctl &= ~BWN_DMA64_RXDIRECTFIFO;
2751 		if (enable)
2752 			ctl |= BWN_DMA64_RXDIRECTFIFO;
2753 		BWN_WRITE_4(mac, base + BWN_DMA64_RXCTL, ctl);
2754 	} else {
2755 		ctl = BWN_READ_4(mac, base + BWN_DMA32_RXCTL);
2756 		ctl &= ~BWN_DMA32_RXDIRECTFIFO;
2757 		if (enable)
2758 			ctl |= BWN_DMA32_RXDIRECTFIFO;
2759 		BWN_WRITE_4(mac, base + BWN_DMA32_RXCTL, ctl);
2760 	}
2761 }
2762 
2763 static void
bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue * tq)2764 bwn_pio_cancel_tx_packets(struct bwn_pio_txqueue *tq)
2765 {
2766 	struct bwn_pio_txpkt *tp;
2767 	unsigned int i;
2768 
2769 	for (i = 0; i < N(tq->tq_pkts); i++) {
2770 		tp = &(tq->tq_pkts[i]);
2771 		if (tp->tp_m) {
2772 			m_freem(tp->tp_m);
2773 			tp->tp_m = NULL;
2774 		}
2775 	}
2776 }
2777 
2778 static uint16_t
bwn_dma_base(int type,int controller_idx)2779 bwn_dma_base(int type, int controller_idx)
2780 {
2781 	static const uint16_t map64[] = {
2782 		BWN_DMA64_BASE0,
2783 		BWN_DMA64_BASE1,
2784 		BWN_DMA64_BASE2,
2785 		BWN_DMA64_BASE3,
2786 		BWN_DMA64_BASE4,
2787 		BWN_DMA64_BASE5,
2788 	};
2789 	static const uint16_t map32[] = {
2790 		BWN_DMA32_BASE0,
2791 		BWN_DMA32_BASE1,
2792 		BWN_DMA32_BASE2,
2793 		BWN_DMA32_BASE3,
2794 		BWN_DMA32_BASE4,
2795 		BWN_DMA32_BASE5,
2796 	};
2797 
2798 	if (type == BHND_DMA_ADDR_64BIT) {
2799 		KASSERT(controller_idx >= 0 && controller_idx < N(map64),
2800 		    ("%s:%d: fail", __func__, __LINE__));
2801 		return (map64[controller_idx]);
2802 	}
2803 	KASSERT(controller_idx >= 0 && controller_idx < N(map32),
2804 	    ("%s:%d: fail", __func__, __LINE__));
2805 	return (map32[controller_idx]);
2806 }
2807 
2808 static void
bwn_dma_init(struct bwn_mac * mac)2809 bwn_dma_init(struct bwn_mac *mac)
2810 {
2811 	struct bwn_dma *dma = &mac->mac_method.dma;
2812 
2813 	/* setup TX DMA channels. */
2814 	bwn_dma_setup(dma->wme[WME_AC_BK]);
2815 	bwn_dma_setup(dma->wme[WME_AC_BE]);
2816 	bwn_dma_setup(dma->wme[WME_AC_VI]);
2817 	bwn_dma_setup(dma->wme[WME_AC_VO]);
2818 	bwn_dma_setup(dma->mcast);
2819 	/* setup RX DMA channel. */
2820 	bwn_dma_setup(dma->rx);
2821 }
2822 
2823 static struct bwn_dma_ring *
bwn_dma_ringsetup(struct bwn_mac * mac,int controller_index,int for_tx)2824 bwn_dma_ringsetup(struct bwn_mac *mac, int controller_index,
2825     int for_tx)
2826 {
2827 	struct bwn_dma *dma = &mac->mac_method.dma;
2828 	struct bwn_dma_ring *dr;
2829 	struct bwn_dmadesc_generic *desc;
2830 	struct bwn_dmadesc_meta *mt;
2831 	struct bwn_softc *sc = mac->mac_sc;
2832 	int error, i;
2833 
2834 	dr = malloc(sizeof(*dr), M_DEVBUF, M_NOWAIT | M_ZERO);
2835 	if (dr == NULL)
2836 		goto out;
2837 	dr->dr_numslots = BWN_RXRING_SLOTS;
2838 	if (for_tx)
2839 		dr->dr_numslots = BWN_TXRING_SLOTS;
2840 
2841 	dr->dr_meta = malloc(dr->dr_numslots * sizeof(struct bwn_dmadesc_meta),
2842 	    M_DEVBUF, M_NOWAIT | M_ZERO);
2843 	if (dr->dr_meta == NULL)
2844 		goto fail0;
2845 
2846 	dr->dr_type = mac->mac_dmatype;
2847 	dr->dr_mac = mac;
2848 	dr->dr_base = bwn_dma_base(dr->dr_type, controller_index);
2849 	dr->dr_index = controller_index;
2850 	if (dr->dr_type == BHND_DMA_ADDR_64BIT) {
2851 		dr->getdesc = bwn_dma_64_getdesc;
2852 		dr->setdesc = bwn_dma_64_setdesc;
2853 		dr->start_transfer = bwn_dma_64_start_transfer;
2854 		dr->suspend = bwn_dma_64_suspend;
2855 		dr->resume = bwn_dma_64_resume;
2856 		dr->get_curslot = bwn_dma_64_get_curslot;
2857 		dr->set_curslot = bwn_dma_64_set_curslot;
2858 	} else {
2859 		dr->getdesc = bwn_dma_32_getdesc;
2860 		dr->setdesc = bwn_dma_32_setdesc;
2861 		dr->start_transfer = bwn_dma_32_start_transfer;
2862 		dr->suspend = bwn_dma_32_suspend;
2863 		dr->resume = bwn_dma_32_resume;
2864 		dr->get_curslot = bwn_dma_32_get_curslot;
2865 		dr->set_curslot = bwn_dma_32_set_curslot;
2866 	}
2867 	if (for_tx) {
2868 		dr->dr_tx = 1;
2869 		dr->dr_curslot = -1;
2870 	} else {
2871 		if (dr->dr_index == 0) {
2872 			switch (mac->mac_fw.fw_hdr_format) {
2873 			case BWN_FW_HDR_351:
2874 			case BWN_FW_HDR_410:
2875 				dr->dr_rx_bufsize =
2876 				    BWN_DMA0_RX_BUFFERSIZE_FW351;
2877 				dr->dr_frameoffset =
2878 				    BWN_DMA0_RX_FRAMEOFFSET_FW351;
2879 				break;
2880 			case BWN_FW_HDR_598:
2881 				dr->dr_rx_bufsize =
2882 				    BWN_DMA0_RX_BUFFERSIZE_FW598;
2883 				dr->dr_frameoffset =
2884 				    BWN_DMA0_RX_FRAMEOFFSET_FW598;
2885 				break;
2886 			}
2887 		} else
2888 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
2889 	}
2890 
2891 	error = bwn_dma_allocringmemory(dr);
2892 	if (error)
2893 		goto fail2;
2894 
2895 	if (for_tx) {
2896 		/*
2897 		 * Assumption: BWN_TXRING_SLOTS can be divided by
2898 		 * BWN_TX_SLOTS_PER_FRAME
2899 		 */
2900 		KASSERT(BWN_TXRING_SLOTS % BWN_TX_SLOTS_PER_FRAME == 0,
2901 		    ("%s:%d: fail", __func__, __LINE__));
2902 
2903 		dr->dr_txhdr_cache = contigmalloc(
2904 		    (dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
2905 		    BWN_MAXTXHDRSIZE, M_DEVBUF, M_ZERO,
2906 		    0, BUS_SPACE_MAXADDR, 8, 0);
2907 		if (dr->dr_txhdr_cache == NULL) {
2908 			device_printf(sc->sc_dev,
2909 			    "can't allocate TX header DMA memory\n");
2910 			goto fail1;
2911 		}
2912 
2913 		/*
2914 		 * Create TX ring DMA stuffs
2915 		 */
2916 		error = bus_dma_tag_create(dma->parent_dtag,
2917 				    BWN_ALIGN, 0,
2918 				    BUS_SPACE_MAXADDR,
2919 				    BUS_SPACE_MAXADDR,
2920 				    NULL, NULL,
2921 				    BWN_HDRSIZE(mac),
2922 				    1,
2923 				    BUS_SPACE_MAXSIZE_32BIT,
2924 				    0,
2925 				    NULL, NULL,
2926 				    &dr->dr_txring_dtag);
2927 		if (error) {
2928 			device_printf(sc->sc_dev,
2929 			    "can't create TX ring DMA tag: TODO frees\n");
2930 			goto fail2;
2931 		}
2932 
2933 		for (i = 0; i < dr->dr_numslots; i += 2) {
2934 			dr->getdesc(dr, i, &desc, &mt);
2935 
2936 			mt->mt_txtype = BWN_DMADESC_METATYPE_HEADER;
2937 			mt->mt_m = NULL;
2938 			mt->mt_ni = NULL;
2939 			mt->mt_islast = 0;
2940 			error = bus_dmamap_create(dr->dr_txring_dtag, 0,
2941 			    &mt->mt_dmap);
2942 			if (error) {
2943 				device_printf(sc->sc_dev,
2944 				     "can't create RX buf DMA map\n");
2945 				goto fail2;
2946 			}
2947 
2948 			dr->getdesc(dr, i + 1, &desc, &mt);
2949 
2950 			mt->mt_txtype = BWN_DMADESC_METATYPE_BODY;
2951 			mt->mt_m = NULL;
2952 			mt->mt_ni = NULL;
2953 			mt->mt_islast = 1;
2954 			error = bus_dmamap_create(dma->txbuf_dtag, 0,
2955 			    &mt->mt_dmap);
2956 			if (error) {
2957 				device_printf(sc->sc_dev,
2958 				     "can't create RX buf DMA map\n");
2959 				goto fail2;
2960 			}
2961 		}
2962 	} else {
2963 		error = bus_dmamap_create(dma->rxbuf_dtag, 0,
2964 		    &dr->dr_spare_dmap);
2965 		if (error) {
2966 			device_printf(sc->sc_dev,
2967 			    "can't create RX buf DMA map\n");
2968 			goto out;		/* XXX wrong! */
2969 		}
2970 
2971 		for (i = 0; i < dr->dr_numslots; i++) {
2972 			dr->getdesc(dr, i, &desc, &mt);
2973 
2974 			error = bus_dmamap_create(dma->rxbuf_dtag, 0,
2975 			    &mt->mt_dmap);
2976 			if (error) {
2977 				device_printf(sc->sc_dev,
2978 				    "can't create RX buf DMA map\n");
2979 				goto out;	/* XXX wrong! */
2980 			}
2981 			error = bwn_dma_newbuf(dr, desc, mt, 1);
2982 			if (error) {
2983 				device_printf(sc->sc_dev,
2984 				    "failed to allocate RX buf\n");
2985 				goto out;	/* XXX wrong! */
2986 			}
2987 		}
2988 
2989 		bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
2990 		    BUS_DMASYNC_PREWRITE);
2991 
2992 		dr->dr_usedslot = dr->dr_numslots;
2993 	}
2994 
2995       out:
2996 	return (dr);
2997 
2998 fail2:
2999 	free(dr->dr_txhdr_cache, M_DEVBUF);
3000 fail1:
3001 	free(dr->dr_meta, M_DEVBUF);
3002 fail0:
3003 	free(dr, M_DEVBUF);
3004 	return (NULL);
3005 }
3006 
3007 static void
bwn_dma_ringfree(struct bwn_dma_ring ** dr)3008 bwn_dma_ringfree(struct bwn_dma_ring **dr)
3009 {
3010 
3011 	if (dr == NULL)
3012 		return;
3013 
3014 	bwn_dma_free_descbufs(*dr);
3015 	bwn_dma_free_ringmemory(*dr);
3016 
3017 	free((*dr)->dr_txhdr_cache, M_DEVBUF);
3018 	free((*dr)->dr_meta, M_DEVBUF);
3019 	free(*dr, M_DEVBUF);
3020 
3021 	*dr = NULL;
3022 }
3023 
3024 static void
bwn_dma_32_getdesc(struct bwn_dma_ring * dr,int slot,struct bwn_dmadesc_generic ** gdesc,struct bwn_dmadesc_meta ** meta)3025 bwn_dma_32_getdesc(struct bwn_dma_ring *dr, int slot,
3026     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3027 {
3028 	struct bwn_dmadesc32 *desc;
3029 
3030 	*meta = &(dr->dr_meta[slot]);
3031 	desc = dr->dr_ring_descbase;
3032 	desc = &(desc[slot]);
3033 
3034 	*gdesc = (struct bwn_dmadesc_generic *)desc;
3035 }
3036 
3037 static void
bwn_dma_32_setdesc(struct bwn_dma_ring * dr,struct bwn_dmadesc_generic * desc,bus_addr_t dmaaddr,uint16_t bufsize,int start,int end,int irq)3038 bwn_dma_32_setdesc(struct bwn_dma_ring *dr,
3039     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3040     int start, int end, int irq)
3041 {
3042 	struct bwn_dmadesc32		*descbase;
3043 	struct bwn_dma			*dma;
3044 	struct bhnd_dma_translation	*dt;
3045 	uint32_t			 addr, addrext, ctl;
3046 	int				 slot;
3047 
3048 	descbase = dr->dr_ring_descbase;
3049 	dma = &dr->dr_mac->mac_method.dma;
3050 	dt = &dma->translation;
3051 
3052 	slot = (int)(&(desc->dma.dma32) - descbase);
3053 	KASSERT(slot >= 0 && slot < dr->dr_numslots,
3054 	    ("%s:%d: fail", __func__, __LINE__));
3055 
3056 	addr = (dmaaddr & dt->addr_mask) | dt->base_addr;
3057 	addrext = ((dmaaddr & dt->addrext_mask) >> dma->addrext_shift);
3058 	ctl = bufsize & BWN_DMA32_DCTL_BYTECNT;
3059 	if (slot == dr->dr_numslots - 1)
3060 		ctl |= BWN_DMA32_DCTL_DTABLEEND;
3061 	if (start)
3062 		ctl |= BWN_DMA32_DCTL_FRAMESTART;
3063 	if (end)
3064 		ctl |= BWN_DMA32_DCTL_FRAMEEND;
3065 	if (irq)
3066 		ctl |= BWN_DMA32_DCTL_IRQ;
3067 	ctl |= (addrext << BWN_DMA32_DCTL_ADDREXT_SHIFT)
3068 	    & BWN_DMA32_DCTL_ADDREXT_MASK;
3069 
3070 	desc->dma.dma32.control = htole32(ctl);
3071 	desc->dma.dma32.address = htole32(addr);
3072 }
3073 
3074 static void
bwn_dma_32_start_transfer(struct bwn_dma_ring * dr,int slot)3075 bwn_dma_32_start_transfer(struct bwn_dma_ring *dr, int slot)
3076 {
3077 
3078 	BWN_DMA_WRITE(dr, BWN_DMA32_TXINDEX,
3079 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc32)));
3080 }
3081 
3082 static void
bwn_dma_32_suspend(struct bwn_dma_ring * dr)3083 bwn_dma_32_suspend(struct bwn_dma_ring *dr)
3084 {
3085 
3086 	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3087 	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) | BWN_DMA32_TXSUSPEND);
3088 }
3089 
3090 static void
bwn_dma_32_resume(struct bwn_dma_ring * dr)3091 bwn_dma_32_resume(struct bwn_dma_ring *dr)
3092 {
3093 
3094 	BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL,
3095 	    BWN_DMA_READ(dr, BWN_DMA32_TXCTL) & ~BWN_DMA32_TXSUSPEND);
3096 }
3097 
3098 static int
bwn_dma_32_get_curslot(struct bwn_dma_ring * dr)3099 bwn_dma_32_get_curslot(struct bwn_dma_ring *dr)
3100 {
3101 	uint32_t val;
3102 
3103 	val = BWN_DMA_READ(dr, BWN_DMA32_RXSTATUS);
3104 	val &= BWN_DMA32_RXDPTR;
3105 
3106 	return (val / sizeof(struct bwn_dmadesc32));
3107 }
3108 
3109 static void
bwn_dma_32_set_curslot(struct bwn_dma_ring * dr,int slot)3110 bwn_dma_32_set_curslot(struct bwn_dma_ring *dr, int slot)
3111 {
3112 
3113 	BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX,
3114 	    (uint32_t) (slot * sizeof(struct bwn_dmadesc32)));
3115 }
3116 
3117 static void
bwn_dma_64_getdesc(struct bwn_dma_ring * dr,int slot,struct bwn_dmadesc_generic ** gdesc,struct bwn_dmadesc_meta ** meta)3118 bwn_dma_64_getdesc(struct bwn_dma_ring *dr, int slot,
3119     struct bwn_dmadesc_generic **gdesc, struct bwn_dmadesc_meta **meta)
3120 {
3121 	struct bwn_dmadesc64 *desc;
3122 
3123 	*meta = &(dr->dr_meta[slot]);
3124 	desc = dr->dr_ring_descbase;
3125 	desc = &(desc[slot]);
3126 
3127 	*gdesc = (struct bwn_dmadesc_generic *)desc;
3128 }
3129 
3130 static void
bwn_dma_64_setdesc(struct bwn_dma_ring * dr,struct bwn_dmadesc_generic * desc,bus_addr_t dmaaddr,uint16_t bufsize,int start,int end,int irq)3131 bwn_dma_64_setdesc(struct bwn_dma_ring *dr,
3132     struct bwn_dmadesc_generic *desc, bus_addr_t dmaaddr, uint16_t bufsize,
3133     int start, int end, int irq)
3134 {
3135 	struct bwn_dmadesc64		*descbase;
3136 	struct bwn_dma			*dma;
3137 	struct bhnd_dma_translation	*dt;
3138 	bhnd_addr_t			 addr;
3139 	uint32_t			 addrhi, addrlo;
3140 	uint32_t			 addrext;
3141 	uint32_t			 ctl0, ctl1;
3142 	int				 slot;
3143 
3144 	descbase = dr->dr_ring_descbase;
3145 	dma = &dr->dr_mac->mac_method.dma;
3146 	dt = &dma->translation;
3147 
3148 	slot = (int)(&(desc->dma.dma64) - descbase);
3149 	KASSERT(slot >= 0 && slot < dr->dr_numslots,
3150 	    ("%s:%d: fail", __func__, __LINE__));
3151 
3152 	addr = (dmaaddr & dt->addr_mask) | dt->base_addr;
3153 	addrhi = (addr >> 32);
3154 	addrlo = (addr & UINT32_MAX);
3155 	addrext = ((dmaaddr & dt->addrext_mask) >> dma->addrext_shift);
3156 
3157 	ctl0 = 0;
3158 	if (slot == dr->dr_numslots - 1)
3159 		ctl0 |= BWN_DMA64_DCTL0_DTABLEEND;
3160 	if (start)
3161 		ctl0 |= BWN_DMA64_DCTL0_FRAMESTART;
3162 	if (end)
3163 		ctl0 |= BWN_DMA64_DCTL0_FRAMEEND;
3164 	if (irq)
3165 		ctl0 |= BWN_DMA64_DCTL0_IRQ;
3166 
3167 	ctl1 = 0;
3168 	ctl1 |= bufsize & BWN_DMA64_DCTL1_BYTECNT;
3169 	ctl1 |= (addrext << BWN_DMA64_DCTL1_ADDREXT_SHIFT)
3170 	    & BWN_DMA64_DCTL1_ADDREXT_MASK;
3171 
3172 	desc->dma.dma64.control0 = htole32(ctl0);
3173 	desc->dma.dma64.control1 = htole32(ctl1);
3174 	desc->dma.dma64.address_low = htole32(addrlo);
3175 	desc->dma.dma64.address_high = htole32(addrhi);
3176 }
3177 
3178 static void
bwn_dma_64_start_transfer(struct bwn_dma_ring * dr,int slot)3179 bwn_dma_64_start_transfer(struct bwn_dma_ring *dr, int slot)
3180 {
3181 
3182 	BWN_DMA_WRITE(dr, BWN_DMA64_TXINDEX,
3183 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
3184 }
3185 
3186 static void
bwn_dma_64_suspend(struct bwn_dma_ring * dr)3187 bwn_dma_64_suspend(struct bwn_dma_ring *dr)
3188 {
3189 
3190 	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3191 	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) | BWN_DMA64_TXSUSPEND);
3192 }
3193 
3194 static void
bwn_dma_64_resume(struct bwn_dma_ring * dr)3195 bwn_dma_64_resume(struct bwn_dma_ring *dr)
3196 {
3197 
3198 	BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL,
3199 	    BWN_DMA_READ(dr, BWN_DMA64_TXCTL) & ~BWN_DMA64_TXSUSPEND);
3200 }
3201 
3202 static int
bwn_dma_64_get_curslot(struct bwn_dma_ring * dr)3203 bwn_dma_64_get_curslot(struct bwn_dma_ring *dr)
3204 {
3205 	uint32_t val;
3206 
3207 	val = BWN_DMA_READ(dr, BWN_DMA64_RXSTATUS);
3208 	val &= BWN_DMA64_RXSTATDPTR;
3209 
3210 	return (val / sizeof(struct bwn_dmadesc64));
3211 }
3212 
3213 static void
bwn_dma_64_set_curslot(struct bwn_dma_ring * dr,int slot)3214 bwn_dma_64_set_curslot(struct bwn_dma_ring *dr, int slot)
3215 {
3216 
3217 	BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX,
3218 	    (uint32_t)(slot * sizeof(struct bwn_dmadesc64)));
3219 }
3220 
3221 static int
bwn_dma_allocringmemory(struct bwn_dma_ring * dr)3222 bwn_dma_allocringmemory(struct bwn_dma_ring *dr)
3223 {
3224 	struct bwn_mac *mac = dr->dr_mac;
3225 	struct bwn_dma *dma = &mac->mac_method.dma;
3226 	struct bwn_softc *sc = mac->mac_sc;
3227 	int error;
3228 
3229 	error = bus_dma_tag_create(dma->parent_dtag,
3230 			    BWN_ALIGN, 0,
3231 			    BUS_SPACE_MAXADDR,
3232 			    BUS_SPACE_MAXADDR,
3233 			    NULL, NULL,
3234 			    BWN_DMA_RINGMEMSIZE,
3235 			    1,
3236 			    BUS_SPACE_MAXSIZE_32BIT,
3237 			    0,
3238 			    NULL, NULL,
3239 			    &dr->dr_ring_dtag);
3240 	if (error) {
3241 		device_printf(sc->sc_dev,
3242 		    "can't create TX ring DMA tag: TODO frees\n");
3243 		return (-1);
3244 	}
3245 
3246 	error = bus_dmamem_alloc(dr->dr_ring_dtag,
3247 	    &dr->dr_ring_descbase, BUS_DMA_WAITOK | BUS_DMA_ZERO,
3248 	    &dr->dr_ring_dmap);
3249 	if (error) {
3250 		device_printf(sc->sc_dev,
3251 		    "can't allocate DMA mem: TODO frees\n");
3252 		return (-1);
3253 	}
3254 	error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
3255 	    dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
3256 	    bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
3257 	if (error) {
3258 		device_printf(sc->sc_dev,
3259 		    "can't load DMA mem: TODO free\n");
3260 		return (-1);
3261 	}
3262 
3263 	return (0);
3264 }
3265 
3266 static void
bwn_dma_setup(struct bwn_dma_ring * dr)3267 bwn_dma_setup(struct bwn_dma_ring *dr)
3268 {
3269 	struct bwn_mac			*mac;
3270 	struct bwn_dma			*dma;
3271 	struct bhnd_dma_translation	*dt;
3272 	bhnd_addr_t			 addr, paddr;
3273 	uint32_t			 addrhi, addrlo, addrext, value;
3274 
3275 	mac = dr->dr_mac;
3276 	dma = &mac->mac_method.dma;
3277 	dt = &dma->translation;
3278 
3279 	paddr = dr->dr_ring_dmabase;
3280 	addr = (paddr & dt->addr_mask) | dt->base_addr;
3281 	addrhi = (addr >> 32);
3282 	addrlo = (addr & UINT32_MAX);
3283 	addrext = ((paddr & dt->addrext_mask) >> dma->addrext_shift);
3284 
3285 	if (dr->dr_tx) {
3286 		dr->dr_curslot = -1;
3287 
3288 		if (dr->dr_type == BHND_DMA_ADDR_64BIT) {
3289 			value = BWN_DMA64_TXENABLE;
3290 			value |= BWN_DMA64_TXPARITY_DISABLE;
3291 			value |= (addrext << BWN_DMA64_TXADDREXT_SHIFT)
3292 			    & BWN_DMA64_TXADDREXT_MASK;
3293 			BWN_DMA_WRITE(dr, BWN_DMA64_TXCTL, value);
3294 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, addrlo);
3295 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, addrhi);
3296 		} else {
3297 			value = BWN_DMA32_TXENABLE;
3298 			value |= BWN_DMA32_TXPARITY_DISABLE;
3299 			value |= (addrext << BWN_DMA32_TXADDREXT_SHIFT)
3300 			    & BWN_DMA32_TXADDREXT_MASK;
3301 			BWN_DMA_WRITE(dr, BWN_DMA32_TXCTL, value);
3302 			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, addrlo);
3303 		}
3304 		return;
3305 	}
3306 
3307 	/*
3308 	 * set for RX
3309 	 */
3310 	dr->dr_usedslot = dr->dr_numslots;
3311 
3312 	if (dr->dr_type == BHND_DMA_ADDR_64BIT) {
3313 		value = (dr->dr_frameoffset << BWN_DMA64_RXFROFF_SHIFT);
3314 		value |= BWN_DMA64_RXENABLE;
3315 		value |= BWN_DMA64_RXPARITY_DISABLE;
3316 		value |= (addrext << BWN_DMA64_RXADDREXT_SHIFT)
3317 		    & BWN_DMA64_RXADDREXT_MASK;
3318 		BWN_DMA_WRITE(dr, BWN_DMA64_RXCTL, value);
3319 		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, addrlo);
3320 		BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, addrhi);
3321 		BWN_DMA_WRITE(dr, BWN_DMA64_RXINDEX, dr->dr_numslots *
3322 		    sizeof(struct bwn_dmadesc64));
3323 	} else {
3324 		value = (dr->dr_frameoffset << BWN_DMA32_RXFROFF_SHIFT);
3325 		value |= BWN_DMA32_RXENABLE;
3326 		value |= BWN_DMA32_RXPARITY_DISABLE;
3327 		value |= (addrext << BWN_DMA32_RXADDREXT_SHIFT)
3328 		    & BWN_DMA32_RXADDREXT_MASK;
3329 		BWN_DMA_WRITE(dr, BWN_DMA32_RXCTL, value);
3330 		BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, addrlo);
3331 		BWN_DMA_WRITE(dr, BWN_DMA32_RXINDEX, dr->dr_numslots *
3332 		    sizeof(struct bwn_dmadesc32));
3333 	}
3334 }
3335 
3336 static void
bwn_dma_free_ringmemory(struct bwn_dma_ring * dr)3337 bwn_dma_free_ringmemory(struct bwn_dma_ring *dr)
3338 {
3339 
3340 	bus_dmamap_unload(dr->dr_ring_dtag, dr->dr_ring_dmap);
3341 	bus_dmamem_free(dr->dr_ring_dtag, dr->dr_ring_descbase,
3342 	    dr->dr_ring_dmap);
3343 }
3344 
3345 static void
bwn_dma_cleanup(struct bwn_dma_ring * dr)3346 bwn_dma_cleanup(struct bwn_dma_ring *dr)
3347 {
3348 
3349 	if (dr->dr_tx) {
3350 		bwn_dma_tx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
3351 		if (dr->dr_type == BHND_DMA_ADDR_64BIT) {
3352 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGLO, 0);
3353 			BWN_DMA_WRITE(dr, BWN_DMA64_TXRINGHI, 0);
3354 		} else
3355 			BWN_DMA_WRITE(dr, BWN_DMA32_TXRING, 0);
3356 	} else {
3357 		bwn_dma_rx_reset(dr->dr_mac, dr->dr_base, dr->dr_type);
3358 		if (dr->dr_type == BHND_DMA_ADDR_64BIT) {
3359 			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGLO, 0);
3360 			BWN_DMA_WRITE(dr, BWN_DMA64_RXRINGHI, 0);
3361 		} else
3362 			BWN_DMA_WRITE(dr, BWN_DMA32_RXRING, 0);
3363 	}
3364 }
3365 
3366 static void
bwn_dma_free_descbufs(struct bwn_dma_ring * dr)3367 bwn_dma_free_descbufs(struct bwn_dma_ring *dr)
3368 {
3369 	struct bwn_dmadesc_generic *desc;
3370 	struct bwn_dmadesc_meta *meta;
3371 	struct bwn_mac *mac = dr->dr_mac;
3372 	struct bwn_dma *dma = &mac->mac_method.dma;
3373 	struct bwn_softc *sc = mac->mac_sc;
3374 	int i;
3375 
3376 	if (!dr->dr_usedslot)
3377 		return;
3378 	for (i = 0; i < dr->dr_numslots; i++) {
3379 		dr->getdesc(dr, i, &desc, &meta);
3380 
3381 		if (meta->mt_m == NULL) {
3382 			if (!dr->dr_tx)
3383 				device_printf(sc->sc_dev, "%s: not TX?\n",
3384 				    __func__);
3385 			continue;
3386 		}
3387 		if (dr->dr_tx) {
3388 			if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
3389 				bus_dmamap_unload(dr->dr_txring_dtag,
3390 				    meta->mt_dmap);
3391 			else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
3392 				bus_dmamap_unload(dma->txbuf_dtag,
3393 				    meta->mt_dmap);
3394 		} else
3395 			bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
3396 		bwn_dma_free_descbuf(dr, meta);
3397 	}
3398 }
3399 
3400 static int
bwn_dma_tx_reset(struct bwn_mac * mac,uint16_t base,int type)3401 bwn_dma_tx_reset(struct bwn_mac *mac, uint16_t base,
3402     int type)
3403 {
3404 	struct bwn_softc *sc = mac->mac_sc;
3405 	uint32_t value;
3406 	int i;
3407 	uint16_t offset;
3408 
3409 	for (i = 0; i < 10; i++) {
3410 		offset = (type == BHND_DMA_ADDR_64BIT) ? BWN_DMA64_TXSTATUS :
3411 		    BWN_DMA32_TXSTATUS;
3412 		value = BWN_READ_4(mac, base + offset);
3413 		if (type == BHND_DMA_ADDR_64BIT) {
3414 			value &= BWN_DMA64_TXSTAT;
3415 			if (value == BWN_DMA64_TXSTAT_DISABLED ||
3416 			    value == BWN_DMA64_TXSTAT_IDLEWAIT ||
3417 			    value == BWN_DMA64_TXSTAT_STOPPED)
3418 				break;
3419 		} else {
3420 			value &= BWN_DMA32_TXSTATE;
3421 			if (value == BWN_DMA32_TXSTAT_DISABLED ||
3422 			    value == BWN_DMA32_TXSTAT_IDLEWAIT ||
3423 			    value == BWN_DMA32_TXSTAT_STOPPED)
3424 				break;
3425 		}
3426 		DELAY(1000);
3427 	}
3428 	offset = (type == BHND_DMA_ADDR_64BIT) ? BWN_DMA64_TXCTL :
3429 	    BWN_DMA32_TXCTL;
3430 	BWN_WRITE_4(mac, base + offset, 0);
3431 	for (i = 0; i < 10; i++) {
3432 		offset = (type == BHND_DMA_ADDR_64BIT) ? BWN_DMA64_TXSTATUS :
3433 		    BWN_DMA32_TXSTATUS;
3434 		value = BWN_READ_4(mac, base + offset);
3435 		if (type == BHND_DMA_ADDR_64BIT) {
3436 			value &= BWN_DMA64_TXSTAT;
3437 			if (value == BWN_DMA64_TXSTAT_DISABLED) {
3438 				i = -1;
3439 				break;
3440 			}
3441 		} else {
3442 			value &= BWN_DMA32_TXSTATE;
3443 			if (value == BWN_DMA32_TXSTAT_DISABLED) {
3444 				i = -1;
3445 				break;
3446 			}
3447 		}
3448 		DELAY(1000);
3449 	}
3450 	if (i != -1) {
3451 		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
3452 		return (ENODEV);
3453 	}
3454 	DELAY(1000);
3455 
3456 	return (0);
3457 }
3458 
3459 static int
bwn_dma_rx_reset(struct bwn_mac * mac,uint16_t base,int type)3460 bwn_dma_rx_reset(struct bwn_mac *mac, uint16_t base,
3461     int type)
3462 {
3463 	struct bwn_softc *sc = mac->mac_sc;
3464 	uint32_t value;
3465 	int i;
3466 	uint16_t offset;
3467 
3468 	offset = (type == BHND_DMA_ADDR_64BIT) ? BWN_DMA64_RXCTL :
3469 	    BWN_DMA32_RXCTL;
3470 	BWN_WRITE_4(mac, base + offset, 0);
3471 	for (i = 0; i < 10; i++) {
3472 		offset = (type == BHND_DMA_ADDR_64BIT) ? BWN_DMA64_RXSTATUS :
3473 		    BWN_DMA32_RXSTATUS;
3474 		value = BWN_READ_4(mac, base + offset);
3475 		if (type == BHND_DMA_ADDR_64BIT) {
3476 			value &= BWN_DMA64_RXSTAT;
3477 			if (value == BWN_DMA64_RXSTAT_DISABLED) {
3478 				i = -1;
3479 				break;
3480 			}
3481 		} else {
3482 			value &= BWN_DMA32_RXSTATE;
3483 			if (value == BWN_DMA32_RXSTAT_DISABLED) {
3484 				i = -1;
3485 				break;
3486 			}
3487 		}
3488 		DELAY(1000);
3489 	}
3490 	if (i != -1) {
3491 		device_printf(sc->sc_dev, "%s: timed out\n", __func__);
3492 		return (ENODEV);
3493 	}
3494 
3495 	return (0);
3496 }
3497 
3498 static void
bwn_dma_free_descbuf(struct bwn_dma_ring * dr,struct bwn_dmadesc_meta * meta)3499 bwn_dma_free_descbuf(struct bwn_dma_ring *dr,
3500     struct bwn_dmadesc_meta *meta)
3501 {
3502 
3503 	if (meta->mt_m != NULL) {
3504 		m_freem(meta->mt_m);
3505 		meta->mt_m = NULL;
3506 	}
3507 	if (meta->mt_ni != NULL) {
3508 		ieee80211_free_node(meta->mt_ni);
3509 		meta->mt_ni = NULL;
3510 	}
3511 }
3512 
3513 static void
bwn_dma_set_redzone(struct bwn_dma_ring * dr,struct mbuf * m)3514 bwn_dma_set_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
3515 {
3516 	struct bwn_rxhdr4 *rxhdr;
3517 	unsigned char *frame;
3518 
3519 	rxhdr = mtod(m, struct bwn_rxhdr4 *);
3520 	rxhdr->frame_len = 0;
3521 
3522 	KASSERT(dr->dr_rx_bufsize >= dr->dr_frameoffset +
3523 	    sizeof(struct bwn_plcp6) + 2,
3524 	    ("%s:%d: fail", __func__, __LINE__));
3525 	frame = mtod(m, char *) + dr->dr_frameoffset;
3526 	memset(frame, 0xff, sizeof(struct bwn_plcp6) + 2 /* padding */);
3527 }
3528 
3529 static uint8_t
bwn_dma_check_redzone(struct bwn_dma_ring * dr,struct mbuf * m)3530 bwn_dma_check_redzone(struct bwn_dma_ring *dr, struct mbuf *m)
3531 {
3532 	unsigned char *f = mtod(m, char *) + dr->dr_frameoffset;
3533 
3534 	return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7])
3535 	    == 0xff);
3536 }
3537 
3538 static void
bwn_wme_init(struct bwn_mac * mac)3539 bwn_wme_init(struct bwn_mac *mac)
3540 {
3541 
3542 	bwn_wme_load(mac);
3543 
3544 	/* enable WME support. */
3545 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_EDCF);
3546 	BWN_WRITE_2(mac, BWN_IFSCTL, BWN_READ_2(mac, BWN_IFSCTL) |
3547 	    BWN_IFSCTL_USE_EDCF);
3548 }
3549 
3550 static void
bwn_spu_setdelay(struct bwn_mac * mac,int idle)3551 bwn_spu_setdelay(struct bwn_mac *mac, int idle)
3552 {
3553 	struct bwn_softc *sc = mac->mac_sc;
3554 	struct ieee80211com *ic = &sc->sc_ic;
3555 	uint16_t delay;	/* microsec */
3556 
3557 	delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
3558 	if (ic->ic_opmode == IEEE80211_M_IBSS || idle)
3559 		delay = 500;
3560 	if ((mac->mac_phy.rf_ver == 0x2050) && (mac->mac_phy.rf_rev == 8))
3561 		delay = max(delay, (uint16_t)2400);
3562 
3563 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SPU_WAKEUP, delay);
3564 }
3565 
3566 static void
bwn_bt_enable(struct bwn_mac * mac)3567 bwn_bt_enable(struct bwn_mac *mac)
3568 {
3569 	struct bwn_softc *sc = mac->mac_sc;
3570 	uint64_t hf;
3571 
3572 	if (bwn_bluetooth == 0)
3573 		return;
3574 	if ((sc->sc_board_info.board_flags & BHND_BFL_BTCOEX) == 0)
3575 		return;
3576 	if (mac->mac_phy.type != BWN_PHYTYPE_B && !mac->mac_phy.gmode)
3577 		return;
3578 
3579 	hf = bwn_hf_read(mac);
3580 	if (sc->sc_board_info.board_flags & BHND_BFL_BTC2WIRE_ALTGPIO)
3581 		hf |= BWN_HF_BT_COEXISTALT;
3582 	else
3583 		hf |= BWN_HF_BT_COEXIST;
3584 	bwn_hf_write(mac, hf);
3585 }
3586 
3587 static void
bwn_set_macaddr(struct bwn_mac * mac)3588 bwn_set_macaddr(struct bwn_mac *mac)
3589 {
3590 
3591 	bwn_mac_write_bssid(mac);
3592 	bwn_mac_setfilter(mac, BWN_MACFILTER_SELF,
3593 	    mac->mac_sc->sc_ic.ic_macaddr);
3594 }
3595 
3596 static void
bwn_clear_keys(struct bwn_mac * mac)3597 bwn_clear_keys(struct bwn_mac *mac)
3598 {
3599 	int i;
3600 
3601 	for (i = 0; i < mac->mac_max_nr_keys; i++) {
3602 		KASSERT(i >= 0 && i < mac->mac_max_nr_keys,
3603 		    ("%s:%d: fail", __func__, __LINE__));
3604 
3605 		bwn_key_dowrite(mac, i, BWN_SEC_ALGO_NONE,
3606 		    NULL, BWN_SEC_KEYSIZE, NULL);
3607 		if ((i <= 3) && !BWN_SEC_NEWAPI(mac)) {
3608 			bwn_key_dowrite(mac, i + 4, BWN_SEC_ALGO_NONE,
3609 			    NULL, BWN_SEC_KEYSIZE, NULL);
3610 		}
3611 		mac->mac_key[i].keyconf = NULL;
3612 	}
3613 }
3614 
3615 static void
bwn_crypt_init(struct bwn_mac * mac)3616 bwn_crypt_init(struct bwn_mac *mac)
3617 {
3618 	struct bwn_softc *sc = mac->mac_sc;
3619 
3620 	mac->mac_max_nr_keys = (bhnd_get_hwrev(sc->sc_dev) >= 5) ? 58 : 20;
3621 	KASSERT(mac->mac_max_nr_keys <= N(mac->mac_key),
3622 	    ("%s:%d: fail", __func__, __LINE__));
3623 	mac->mac_ktp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_KEY_TABLEP);
3624 	mac->mac_ktp *= 2;
3625 	if (bhnd_get_hwrev(sc->sc_dev) >= 5)
3626 		BWN_WRITE_2(mac, BWN_RCMTA_COUNT, mac->mac_max_nr_keys - 8);
3627 	bwn_clear_keys(mac);
3628 }
3629 
3630 static void
bwn_chip_exit(struct bwn_mac * mac)3631 bwn_chip_exit(struct bwn_mac *mac)
3632 {
3633 	bwn_phy_exit(mac);
3634 }
3635 
3636 static int
bwn_fw_fillinfo(struct bwn_mac * mac)3637 bwn_fw_fillinfo(struct bwn_mac *mac)
3638 {
3639 	int error;
3640 
3641 	error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
3642 	if (error == 0)
3643 		return (0);
3644 	error = bwn_fw_gets(mac, BWN_FWTYPE_OPENSOURCE);
3645 	if (error == 0)
3646 		return (0);
3647 	return (error);
3648 }
3649 
3650 /**
3651  * Request that the GPIO controller tristate all pins set in @p mask, granting
3652  * the MAC core control over the pins.
3653  *
3654  * @param mac	bwn MAC state.
3655  * @param pins	If the bit position for a pin number is set to one, tristate the
3656  *		pin.
3657  */
3658 int
bwn_gpio_control(struct bwn_mac * mac,uint32_t pins)3659 bwn_gpio_control(struct bwn_mac *mac, uint32_t pins)
3660 {
3661 	struct bwn_softc	*sc;
3662 	uint32_t		 flags[32];
3663 	int			 error;
3664 
3665 	sc = mac->mac_sc;
3666 
3667 	/* Determine desired pin flags */
3668 	for (size_t pin = 0; pin < nitems(flags); pin++) {
3669 		uint32_t pinbit = (1 << pin);
3670 
3671 		if (pins & pinbit) {
3672 			/* Tristate output */
3673 			flags[pin] = GPIO_PIN_OUTPUT|GPIO_PIN_TRISTATE;
3674 		} else {
3675 			/* Leave unmodified */
3676 			flags[pin] = 0;
3677 		}
3678 	}
3679 
3680 	/* Configure all pins */
3681 	error = GPIO_PIN_CONFIG_32(sc->sc_gpio, 0, nitems(flags), flags);
3682 	if (error) {
3683 		device_printf(sc->sc_dev, "error configuring %s pin flags: "
3684 		    "%d\n", device_get_nameunit(sc->sc_gpio), error);
3685 		return (error);
3686 	}
3687 
3688 	return (0);
3689 }
3690 
3691 static int
bwn_gpio_init(struct bwn_mac * mac)3692 bwn_gpio_init(struct bwn_mac *mac)
3693 {
3694 	struct bwn_softc	*sc;
3695 	uint32_t		 pins;
3696 
3697 	sc = mac->mac_sc;
3698 
3699 	pins = 0xF;
3700 
3701 	BWN_WRITE_4(mac, BWN_MACCTL,
3702 	    BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_GPOUT_MASK);
3703 	BWN_WRITE_2(mac, BWN_GPIO_MASK,
3704 	    BWN_READ_2(mac, BWN_GPIO_MASK) | pins);
3705 
3706 	if (sc->sc_board_info.board_flags & BHND_BFL_PACTRL) {
3707 		/* MAC core is responsible for toggling PAREF via gpio9 */
3708 		BWN_WRITE_2(mac, BWN_GPIO_MASK,
3709 		    BWN_READ_2(mac, BWN_GPIO_MASK) | BHND_GPIO_BOARD_PACTRL);
3710 
3711 		pins |= BHND_GPIO_BOARD_PACTRL;
3712 	}
3713 
3714 	return (bwn_gpio_control(mac, pins));
3715 }
3716 
3717 static int
bwn_fw_loadinitvals(struct bwn_mac * mac)3718 bwn_fw_loadinitvals(struct bwn_mac *mac)
3719 {
3720 #define	GETFWOFFSET(fwp, offset)				\
3721 	((const struct bwn_fwinitvals *)((const char *)fwp.fw->data + offset))
3722 	const size_t hdr_len = sizeof(struct bwn_fwhdr);
3723 	const struct bwn_fwhdr *hdr;
3724 	struct bwn_fw *fw = &mac->mac_fw;
3725 	int error;
3726 
3727 	hdr = (const struct bwn_fwhdr *)(fw->initvals.fw->data);
3728 	error = bwn_fwinitvals_write(mac, GETFWOFFSET(fw->initvals, hdr_len),
3729 	    be32toh(hdr->size), fw->initvals.fw->datasize - hdr_len);
3730 	if (error)
3731 		return (error);
3732 	if (fw->initvals_band.fw) {
3733 		hdr = (const struct bwn_fwhdr *)(fw->initvals_band.fw->data);
3734 		error = bwn_fwinitvals_write(mac,
3735 		    GETFWOFFSET(fw->initvals_band, hdr_len),
3736 		    be32toh(hdr->size),
3737 		    fw->initvals_band.fw->datasize - hdr_len);
3738 	}
3739 	return (error);
3740 #undef GETFWOFFSET
3741 }
3742 
3743 static int
bwn_phy_init(struct bwn_mac * mac)3744 bwn_phy_init(struct bwn_mac *mac)
3745 {
3746 	struct bwn_softc *sc = mac->mac_sc;
3747 	int error;
3748 
3749 	mac->mac_phy.chan = mac->mac_phy.get_default_chan(mac);
3750 	mac->mac_phy.rf_onoff(mac, 1);
3751 	error = mac->mac_phy.init(mac);
3752 	if (error) {
3753 		device_printf(sc->sc_dev, "PHY init failed\n");
3754 		goto fail0;
3755 	}
3756 	error = bwn_switch_channel(mac,
3757 	    mac->mac_phy.get_default_chan(mac));
3758 	if (error) {
3759 		device_printf(sc->sc_dev,
3760 		    "failed to switch default channel\n");
3761 		goto fail1;
3762 	}
3763 	return (0);
3764 fail1:
3765 	if (mac->mac_phy.exit)
3766 		mac->mac_phy.exit(mac);
3767 fail0:
3768 	mac->mac_phy.rf_onoff(mac, 0);
3769 
3770 	return (error);
3771 }
3772 
3773 static void
bwn_set_txantenna(struct bwn_mac * mac,int antenna)3774 bwn_set_txantenna(struct bwn_mac *mac, int antenna)
3775 {
3776 	uint16_t ant;
3777 	uint16_t tmp;
3778 
3779 	ant = bwn_ant2phy(antenna);
3780 
3781 	/* For ACK/CTS */
3782 	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL);
3783 	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
3784 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_ACKCTS_PHYCTL, tmp);
3785 	/* For Probe Resposes */
3786 	tmp = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL);
3787 	tmp = (tmp & ~BWN_TX_PHY_ANT) | ant;
3788 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_PHYCTL, tmp);
3789 }
3790 
3791 static void
bwn_set_opmode(struct bwn_mac * mac)3792 bwn_set_opmode(struct bwn_mac *mac)
3793 {
3794 	struct bwn_softc *sc = mac->mac_sc;
3795 	struct ieee80211com *ic = &sc->sc_ic;
3796 	uint32_t ctl;
3797 	uint16_t cfp_pretbtt;
3798 
3799 	ctl = BWN_READ_4(mac, BWN_MACCTL);
3800 	ctl &= ~(BWN_MACCTL_HOSTAP | BWN_MACCTL_PASS_CTL |
3801 	    BWN_MACCTL_PASS_BADPLCP | BWN_MACCTL_PASS_BADFCS |
3802 	    BWN_MACCTL_PROMISC | BWN_MACCTL_BEACON_PROMISC);
3803 	ctl |= BWN_MACCTL_STA;
3804 
3805 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
3806 	    ic->ic_opmode == IEEE80211_M_MBSS)
3807 		ctl |= BWN_MACCTL_HOSTAP;
3808 	else if (ic->ic_opmode == IEEE80211_M_IBSS)
3809 		ctl &= ~BWN_MACCTL_STA;
3810 	ctl |= sc->sc_filters;
3811 
3812 	if (bhnd_get_hwrev(sc->sc_dev) <= 4)
3813 		ctl |= BWN_MACCTL_PROMISC;
3814 
3815 	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
3816 
3817 	cfp_pretbtt = 2;
3818 	if ((ctl & BWN_MACCTL_STA) && !(ctl & BWN_MACCTL_HOSTAP)) {
3819 		if (sc->sc_cid.chip_id == BHND_CHIPID_BCM4306 &&
3820 		    sc->sc_cid.chip_rev == 3)
3821 			cfp_pretbtt = 100;
3822 		else
3823 			cfp_pretbtt = 50;
3824 	}
3825 	BWN_WRITE_2(mac, 0x612, cfp_pretbtt);
3826 }
3827 
3828 static void
bwn_dma_ring_addr(void * arg,bus_dma_segment_t * seg,int nseg,int error)3829 bwn_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
3830 {
3831 	if (!error) {
3832 		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
3833 		*((bus_addr_t *)arg) = seg->ds_addr;
3834 	}
3835 }
3836 
3837 void
bwn_dummy_transmission(struct bwn_mac * mac,int ofdm,int paon)3838 bwn_dummy_transmission(struct bwn_mac *mac, int ofdm, int paon)
3839 {
3840 	struct bwn_phy *phy = &mac->mac_phy;
3841 	struct bwn_softc *sc = mac->mac_sc;
3842 	unsigned int i, max_loop;
3843 	uint16_t value;
3844 	uint32_t buffer[5] = {
3845 		0x00000000, 0x00d40000, 0x00000000, 0x01000000, 0x00000000
3846 	};
3847 
3848 	if (ofdm) {
3849 		max_loop = 0x1e;
3850 		buffer[0] = 0x000201cc;
3851 	} else {
3852 		max_loop = 0xfa;
3853 		buffer[0] = 0x000b846e;
3854 	}
3855 
3856 	BWN_ASSERT_LOCKED(mac->mac_sc);
3857 
3858 	for (i = 0; i < 5; i++)
3859 		bwn_ram_write(mac, i * 4, buffer[i]);
3860 
3861 	BWN_WRITE_2(mac, 0x0568, 0x0000);
3862 	BWN_WRITE_2(mac, 0x07c0,
3863 	    (bhnd_get_hwrev(sc->sc_dev) < 11) ? 0x0000 : 0x0100);
3864 
3865 	value = (ofdm ? 0x41 : 0x40);
3866 	BWN_WRITE_2(mac, 0x050c, value);
3867 
3868 	if (phy->type == BWN_PHYTYPE_N || phy->type == BWN_PHYTYPE_LP ||
3869 	    phy->type == BWN_PHYTYPE_LCN)
3870 		BWN_WRITE_2(mac, 0x0514, 0x1a02);
3871 	BWN_WRITE_2(mac, 0x0508, 0x0000);
3872 	BWN_WRITE_2(mac, 0x050a, 0x0000);
3873 	BWN_WRITE_2(mac, 0x054c, 0x0000);
3874 	BWN_WRITE_2(mac, 0x056a, 0x0014);
3875 	BWN_WRITE_2(mac, 0x0568, 0x0826);
3876 	BWN_WRITE_2(mac, 0x0500, 0x0000);
3877 
3878 	/* XXX TODO: n phy pa override? */
3879 
3880 	switch (phy->type) {
3881 	case BWN_PHYTYPE_N:
3882 	case BWN_PHYTYPE_LCN:
3883 		BWN_WRITE_2(mac, 0x0502, 0x00d0);
3884 		break;
3885 	case BWN_PHYTYPE_LP:
3886 		BWN_WRITE_2(mac, 0x0502, 0x0050);
3887 		break;
3888 	default:
3889 		BWN_WRITE_2(mac, 0x0502, 0x0030);
3890 		break;
3891 	}
3892 
3893 	/* flush */
3894 	BWN_READ_2(mac, 0x0502);
3895 
3896 	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
3897 		BWN_RF_WRITE(mac, 0x0051, 0x0017);
3898 	for (i = 0x00; i < max_loop; i++) {
3899 		value = BWN_READ_2(mac, 0x050e);
3900 		if (value & 0x0080)
3901 			break;
3902 		DELAY(10);
3903 	}
3904 	for (i = 0x00; i < 0x0a; i++) {
3905 		value = BWN_READ_2(mac, 0x050e);
3906 		if (value & 0x0400)
3907 			break;
3908 		DELAY(10);
3909 	}
3910 	for (i = 0x00; i < 0x19; i++) {
3911 		value = BWN_READ_2(mac, 0x0690);
3912 		if (!(value & 0x0100))
3913 			break;
3914 		DELAY(10);
3915 	}
3916 	if (phy->rf_ver == 0x2050 && phy->rf_rev <= 0x5)
3917 		BWN_RF_WRITE(mac, 0x0051, 0x0037);
3918 }
3919 
3920 void
bwn_ram_write(struct bwn_mac * mac,uint16_t offset,uint32_t val)3921 bwn_ram_write(struct bwn_mac *mac, uint16_t offset, uint32_t val)
3922 {
3923 	uint32_t macctl;
3924 
3925 	KASSERT(offset % 4 == 0, ("%s:%d: fail", __func__, __LINE__));
3926 
3927 	macctl = BWN_READ_4(mac, BWN_MACCTL);
3928 	if (macctl & BWN_MACCTL_BIGENDIAN)
3929 		printf("TODO: need swap\n");
3930 
3931 	BWN_WRITE_4(mac, BWN_RAM_CONTROL, offset);
3932 	BWN_BARRIER(mac, BWN_RAM_CONTROL, 4, BUS_SPACE_BARRIER_WRITE);
3933 	BWN_WRITE_4(mac, BWN_RAM_DATA, val);
3934 }
3935 
3936 void
bwn_mac_suspend(struct bwn_mac * mac)3937 bwn_mac_suspend(struct bwn_mac *mac)
3938 {
3939 	struct bwn_softc *sc = mac->mac_sc;
3940 	int i;
3941 	uint32_t tmp;
3942 
3943 	KASSERT(mac->mac_suspended >= 0,
3944 	    ("%s:%d: fail", __func__, __LINE__));
3945 
3946 	DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: suspended=%d\n",
3947 	    __func__, mac->mac_suspended);
3948 
3949 	if (mac->mac_suspended == 0) {
3950 		bwn_psctl(mac, BWN_PS_AWAKE);
3951 		BWN_WRITE_4(mac, BWN_MACCTL,
3952 			    BWN_READ_4(mac, BWN_MACCTL)
3953 			    & ~BWN_MACCTL_ON);
3954 		BWN_READ_4(mac, BWN_MACCTL);
3955 		for (i = 35; i; i--) {
3956 			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
3957 			if (tmp & BWN_INTR_MAC_SUSPENDED)
3958 				goto out;
3959 			DELAY(10);
3960 		}
3961 		for (i = 40; i; i--) {
3962 			tmp = BWN_READ_4(mac, BWN_INTR_REASON);
3963 			if (tmp & BWN_INTR_MAC_SUSPENDED)
3964 				goto out;
3965 			DELAY(1000);
3966 		}
3967 		device_printf(sc->sc_dev, "MAC suspend failed\n");
3968 	}
3969 out:
3970 	mac->mac_suspended++;
3971 }
3972 
3973 void
bwn_mac_enable(struct bwn_mac * mac)3974 bwn_mac_enable(struct bwn_mac *mac)
3975 {
3976 	struct bwn_softc *sc = mac->mac_sc;
3977 	uint16_t state;
3978 
3979 	DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: suspended=%d\n",
3980 	    __func__, mac->mac_suspended);
3981 
3982 	state = bwn_shm_read_2(mac, BWN_SHARED,
3983 	    BWN_SHARED_UCODESTAT);
3984 	if (state != BWN_SHARED_UCODESTAT_SUSPEND &&
3985 	    state != BWN_SHARED_UCODESTAT_SLEEP) {
3986 		DPRINTF(sc, BWN_DEBUG_FW,
3987 		    "%s: warn: firmware state (%d)\n",
3988 		    __func__, state);
3989 	}
3990 
3991 	mac->mac_suspended--;
3992 	KASSERT(mac->mac_suspended >= 0,
3993 	    ("%s:%d: fail", __func__, __LINE__));
3994 	if (mac->mac_suspended == 0) {
3995 		BWN_WRITE_4(mac, BWN_MACCTL,
3996 		    BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_ON);
3997 		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_MAC_SUSPENDED);
3998 		BWN_READ_4(mac, BWN_MACCTL);
3999 		BWN_READ_4(mac, BWN_INTR_REASON);
4000 		bwn_psctl(mac, 0);
4001 	}
4002 }
4003 
4004 void
bwn_psctl(struct bwn_mac * mac,uint32_t flags)4005 bwn_psctl(struct bwn_mac *mac, uint32_t flags)
4006 {
4007 	struct bwn_softc *sc = mac->mac_sc;
4008 	int i;
4009 	uint16_t ucstat;
4010 
4011 	KASSERT(!((flags & BWN_PS_ON) && (flags & BWN_PS_OFF)),
4012 	    ("%s:%d: fail", __func__, __LINE__));
4013 	KASSERT(!((flags & BWN_PS_AWAKE) && (flags & BWN_PS_ASLEEP)),
4014 	    ("%s:%d: fail", __func__, __LINE__));
4015 
4016 	/* XXX forcibly awake and hwps-off */
4017 
4018 	BWN_WRITE_4(mac, BWN_MACCTL,
4019 	    (BWN_READ_4(mac, BWN_MACCTL) | BWN_MACCTL_AWAKE) &
4020 	    ~BWN_MACCTL_HWPS);
4021 	BWN_READ_4(mac, BWN_MACCTL);
4022 	if (bhnd_get_hwrev(sc->sc_dev) >= 5) {
4023 		for (i = 0; i < 100; i++) {
4024 			ucstat = bwn_shm_read_2(mac, BWN_SHARED,
4025 			    BWN_SHARED_UCODESTAT);
4026 			if (ucstat != BWN_SHARED_UCODESTAT_SLEEP)
4027 				break;
4028 			DELAY(10);
4029 		}
4030 	}
4031 	DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: ucstat=%d\n", __func__,
4032 	    ucstat);
4033 }
4034 
4035 static int
bwn_fw_gets(struct bwn_mac * mac,enum bwn_fwtype type)4036 bwn_fw_gets(struct bwn_mac *mac, enum bwn_fwtype type)
4037 {
4038 	struct bwn_softc *sc = mac->mac_sc;
4039 	struct bwn_fw *fw = &mac->mac_fw;
4040 	const uint8_t rev = bhnd_get_hwrev(sc->sc_dev);
4041 	const char *filename;
4042 	uint16_t iost;
4043 	int error;
4044 
4045 	/* microcode */
4046 	filename = NULL;
4047 	switch (rev) {
4048 	case 42:
4049 		if (mac->mac_phy.type == BWN_PHYTYPE_AC)
4050 			filename = "ucode42";
4051 		break;
4052 	case 40:
4053 		if (mac->mac_phy.type == BWN_PHYTYPE_AC)
4054 			filename = "ucode40";
4055 		break;
4056 	case 33:
4057 		if (mac->mac_phy.type == BWN_PHYTYPE_LCN40)
4058 			filename = "ucode33_lcn40";
4059 		break;
4060 	case 30:
4061 		if (mac->mac_phy.type == BWN_PHYTYPE_N)
4062 			filename = "ucode30_mimo";
4063 		break;
4064 	case 29:
4065 		if (mac->mac_phy.type == BWN_PHYTYPE_HT)
4066 			filename = "ucode29_mimo";
4067 		break;
4068 	case 26:
4069 		if (mac->mac_phy.type == BWN_PHYTYPE_HT)
4070 			filename = "ucode26_mimo";
4071 		break;
4072 	case 28:
4073 	case 25:
4074 		if (mac->mac_phy.type == BWN_PHYTYPE_N)
4075 			filename = "ucode25_mimo";
4076 		else if (mac->mac_phy.type == BWN_PHYTYPE_LCN)
4077 			filename = "ucode25_lcn";
4078 		break;
4079 	case 24:
4080 		if (mac->mac_phy.type == BWN_PHYTYPE_LCN)
4081 			filename = "ucode24_lcn";
4082 		break;
4083 	case 23:
4084 		if (mac->mac_phy.type == BWN_PHYTYPE_N)
4085 			filename = "ucode16_mimo";
4086 		break;
4087 	case 16:
4088 	case 17:
4089 	case 18:
4090 	case 19:
4091 		if (mac->mac_phy.type == BWN_PHYTYPE_N)
4092 			filename = "ucode16_mimo";
4093 		else if (mac->mac_phy.type == BWN_PHYTYPE_LP)
4094 			filename = "ucode16_lp";
4095 		break;
4096 	case 15:
4097 		filename = "ucode15";
4098 		break;
4099 	case 14:
4100 		filename = "ucode14";
4101 		break;
4102 	case 13:
4103 		filename = "ucode13";
4104 		break;
4105 	case 12:
4106 	case 11:
4107 		filename = "ucode11";
4108 		break;
4109 	case 10:
4110 	case 9:
4111 	case 8:
4112 	case 7:
4113 	case 6:
4114 	case 5:
4115 		filename = "ucode5";
4116 		break;
4117 	default:
4118 		device_printf(sc->sc_dev, "no ucode for rev %d\n", rev);
4119 		bwn_release_firmware(mac);
4120 		return (EOPNOTSUPP);
4121 	}
4122 
4123 	device_printf(sc->sc_dev, "ucode fw: %s\n", filename);
4124 	error = bwn_fw_get(mac, type, filename, &fw->ucode);
4125 	if (error) {
4126 		bwn_release_firmware(mac);
4127 		return (error);
4128 	}
4129 
4130 	/* PCM */
4131 	KASSERT(fw->no_pcmfile == 0, ("%s:%d fail", __func__, __LINE__));
4132 	if (rev >= 5 && rev <= 10) {
4133 		error = bwn_fw_get(mac, type, "pcm5", &fw->pcm);
4134 		if (error == ENOENT)
4135 			fw->no_pcmfile = 1;
4136 		else if (error) {
4137 			bwn_release_firmware(mac);
4138 			return (error);
4139 		}
4140 	} else if (rev < 11) {
4141 		device_printf(sc->sc_dev, "no PCM for rev %d\n", rev);
4142 		bwn_release_firmware(mac);
4143 		return (EOPNOTSUPP);
4144 	}
4145 
4146 	/* initvals */
4147 	error = bhnd_read_iost(sc->sc_dev, &iost);
4148 	if (error)
4149 		goto fail1;
4150 
4151 	switch (mac->mac_phy.type) {
4152 	case BWN_PHYTYPE_A:
4153 		if (rev < 5 || rev > 10)
4154 			goto fail1;
4155 		if (iost & BWN_IOST_HAVE_2GHZ)
4156 			filename = "a0g1initvals5";
4157 		else
4158 			filename = "a0g0initvals5";
4159 		break;
4160 	case BWN_PHYTYPE_G:
4161 		if (rev >= 5 && rev <= 10)
4162 			filename = "b0g0initvals5";
4163 		else if (rev >= 13)
4164 			filename = "b0g0initvals13";
4165 		else
4166 			goto fail1;
4167 		break;
4168 	case BWN_PHYTYPE_LP:
4169 		if (rev == 13)
4170 			filename = "lp0initvals13";
4171 		else if (rev == 14)
4172 			filename = "lp0initvals14";
4173 		else if (rev >= 15)
4174 			filename = "lp0initvals15";
4175 		else
4176 			goto fail1;
4177 		break;
4178 	case BWN_PHYTYPE_N:
4179 		if (rev == 30)
4180 			filename = "n16initvals30";
4181 		else if (rev == 28 || rev == 25)
4182 			filename = "n0initvals25";
4183 		else if (rev == 24)
4184 			filename = "n0initvals24";
4185 		else if (rev == 23)
4186 			filename = "n0initvals16";
4187 		else if (rev >= 16 && rev <= 18)
4188 			filename = "n0initvals16";
4189 		else if (rev >= 11 && rev <= 12)
4190 			filename = "n0initvals11";
4191 		else
4192 			goto fail1;
4193 		break;
4194 	default:
4195 		goto fail1;
4196 	}
4197 	error = bwn_fw_get(mac, type, filename, &fw->initvals);
4198 	if (error) {
4199 		bwn_release_firmware(mac);
4200 		return (error);
4201 	}
4202 
4203 	/* bandswitch initvals */
4204 	switch (mac->mac_phy.type) {
4205 	case BWN_PHYTYPE_A:
4206 		if (rev >= 5 && rev <= 10) {
4207 			if (iost & BWN_IOST_HAVE_2GHZ)
4208 				filename = "a0g1bsinitvals5";
4209 			else
4210 				filename = "a0g0bsinitvals5";
4211 		} else if (rev >= 11)
4212 			filename = NULL;
4213 		else
4214 			goto fail1;
4215 		break;
4216 	case BWN_PHYTYPE_G:
4217 		if (rev >= 5 && rev <= 10)
4218 			filename = "b0g0bsinitvals5";
4219 		else if (rev >= 11)
4220 			filename = NULL;
4221 		else
4222 			goto fail1;
4223 		break;
4224 	case BWN_PHYTYPE_LP:
4225 		if (rev == 13)
4226 			filename = "lp0bsinitvals13";
4227 		else if (rev == 14)
4228 			filename = "lp0bsinitvals14";
4229 		else if (rev >= 15)
4230 			filename = "lp0bsinitvals15";
4231 		else
4232 			goto fail1;
4233 		break;
4234 	case BWN_PHYTYPE_N:
4235 		if (rev == 30)
4236 			filename = "n16bsinitvals30";
4237 		else if (rev == 28 || rev == 25)
4238 			filename = "n0bsinitvals25";
4239 		else if (rev == 24)
4240 			filename = "n0bsinitvals24";
4241 		else if (rev == 23)
4242 			filename = "n0bsinitvals16";
4243 		else if (rev >= 16 && rev <= 18)
4244 			filename = "n0bsinitvals16";
4245 		else if (rev >= 11 && rev <= 12)
4246 			filename = "n0bsinitvals11";
4247 		else
4248 			goto fail1;
4249 		break;
4250 	default:
4251 		device_printf(sc->sc_dev, "unknown phy (%d)\n",
4252 		    mac->mac_phy.type);
4253 		goto fail1;
4254 	}
4255 	error = bwn_fw_get(mac, type, filename, &fw->initvals_band);
4256 	if (error) {
4257 		bwn_release_firmware(mac);
4258 		return (error);
4259 	}
4260 	return (0);
4261 fail1:
4262 	device_printf(sc->sc_dev, "no INITVALS for rev %d, phy.type %d\n",
4263 	    rev, mac->mac_phy.type);
4264 	bwn_release_firmware(mac);
4265 	return (EOPNOTSUPP);
4266 }
4267 
4268 static int
bwn_fw_get(struct bwn_mac * mac,enum bwn_fwtype type,const char * name,struct bwn_fwfile * bfw)4269 bwn_fw_get(struct bwn_mac *mac, enum bwn_fwtype type,
4270     const char *name, struct bwn_fwfile *bfw)
4271 {
4272 	const struct bwn_fwhdr *hdr;
4273 	struct bwn_softc *sc = mac->mac_sc;
4274 	const struct firmware *fw;
4275 	char namebuf[64];
4276 
4277 	if (name == NULL) {
4278 		bwn_do_release_fw(bfw);
4279 		return (0);
4280 	}
4281 	if (bfw->filename != NULL) {
4282 		if (bfw->type == type && (strcmp(bfw->filename, name) == 0))
4283 			return (0);
4284 		bwn_do_release_fw(bfw);
4285 	}
4286 
4287 	snprintf(namebuf, sizeof(namebuf), "bwn%s_v4_%s%s",
4288 	    (type == BWN_FWTYPE_OPENSOURCE) ? "-open" : "",
4289 	    (mac->mac_phy.type == BWN_PHYTYPE_LP) ? "lp_" : "", name);
4290 	/* XXX Sleeping on "fwload" with the non-sleepable locks held */
4291 	fw = firmware_get(namebuf);
4292 	if (fw == NULL) {
4293 		device_printf(sc->sc_dev, "the fw file(%s) not found\n",
4294 		    namebuf);
4295 		return (ENOENT);
4296 	}
4297 	if (fw->datasize < sizeof(struct bwn_fwhdr))
4298 		goto fail;
4299 	hdr = (const struct bwn_fwhdr *)(fw->data);
4300 	switch (hdr->type) {
4301 	case BWN_FWTYPE_UCODE:
4302 	case BWN_FWTYPE_PCM:
4303 		if (be32toh(hdr->size) !=
4304 		    (fw->datasize - sizeof(struct bwn_fwhdr)))
4305 			goto fail;
4306 		/* FALLTHROUGH */
4307 	case BWN_FWTYPE_IV:
4308 		if (hdr->ver != 1)
4309 			goto fail;
4310 		break;
4311 	default:
4312 		goto fail;
4313 	}
4314 	bfw->filename = name;
4315 	bfw->fw = fw;
4316 	bfw->type = type;
4317 	return (0);
4318 fail:
4319 	device_printf(sc->sc_dev, "the fw file(%s) format error\n", namebuf);
4320 	if (fw != NULL)
4321 		firmware_put(fw, FIRMWARE_UNLOAD);
4322 	return (EPROTO);
4323 }
4324 
4325 static void
bwn_release_firmware(struct bwn_mac * mac)4326 bwn_release_firmware(struct bwn_mac *mac)
4327 {
4328 
4329 	bwn_do_release_fw(&mac->mac_fw.ucode);
4330 	bwn_do_release_fw(&mac->mac_fw.pcm);
4331 	bwn_do_release_fw(&mac->mac_fw.initvals);
4332 	bwn_do_release_fw(&mac->mac_fw.initvals_band);
4333 }
4334 
4335 static void
bwn_do_release_fw(struct bwn_fwfile * bfw)4336 bwn_do_release_fw(struct bwn_fwfile *bfw)
4337 {
4338 
4339 	if (bfw->fw != NULL)
4340 		firmware_put(bfw->fw, FIRMWARE_UNLOAD);
4341 	bfw->fw = NULL;
4342 	bfw->filename = NULL;
4343 }
4344 
4345 static int
bwn_fw_loaducode(struct bwn_mac * mac)4346 bwn_fw_loaducode(struct bwn_mac *mac)
4347 {
4348 #define	GETFWOFFSET(fwp, offset)	\
4349 	((const uint32_t *)((const char *)fwp.fw->data + offset))
4350 #define	GETFWSIZE(fwp, offset)	\
4351 	((fwp.fw->datasize - offset) / sizeof(uint32_t))
4352 	struct bwn_softc *sc = mac->mac_sc;
4353 	const uint32_t *data;
4354 	unsigned int i;
4355 	uint32_t ctl;
4356 	uint16_t date, fwcaps, time;
4357 	int error = 0;
4358 
4359 	ctl = BWN_READ_4(mac, BWN_MACCTL);
4360 	ctl |= BWN_MACCTL_MCODE_JMP0;
4361 	KASSERT(!(ctl & BWN_MACCTL_MCODE_RUN), ("%s:%d: fail", __func__,
4362 	    __LINE__));
4363 	BWN_WRITE_4(mac, BWN_MACCTL, ctl);
4364 	for (i = 0; i < 64; i++)
4365 		bwn_shm_write_2(mac, BWN_SCRATCH, i, 0);
4366 	for (i = 0; i < 4096; i += 2)
4367 		bwn_shm_write_2(mac, BWN_SHARED, i, 0);
4368 
4369 	data = GETFWOFFSET(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
4370 	bwn_shm_ctlword(mac, BWN_UCODE | BWN_SHARED_AUTOINC, 0x0000);
4371 	for (i = 0; i < GETFWSIZE(mac->mac_fw.ucode, sizeof(struct bwn_fwhdr));
4372 	     i++) {
4373 		BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
4374 		DELAY(10);
4375 	}
4376 
4377 	if (mac->mac_fw.pcm.fw) {
4378 		data = GETFWOFFSET(mac->mac_fw.pcm, sizeof(struct bwn_fwhdr));
4379 		bwn_shm_ctlword(mac, BWN_HW, 0x01ea);
4380 		BWN_WRITE_4(mac, BWN_SHM_DATA, 0x00004000);
4381 		bwn_shm_ctlword(mac, BWN_HW, 0x01eb);
4382 		for (i = 0; i < GETFWSIZE(mac->mac_fw.pcm,
4383 		    sizeof(struct bwn_fwhdr)); i++) {
4384 			BWN_WRITE_4(mac, BWN_SHM_DATA, be32toh(data[i]));
4385 			DELAY(10);
4386 		}
4387 	}
4388 
4389 	BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_ALL);
4390 	BWN_WRITE_4(mac, BWN_MACCTL,
4391 	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_JMP0) |
4392 	    BWN_MACCTL_MCODE_RUN);
4393 
4394 	for (i = 0; i < 21; i++) {
4395 		if (BWN_READ_4(mac, BWN_INTR_REASON) == BWN_INTR_MAC_SUSPENDED)
4396 			break;
4397 		if (i >= 20) {
4398 			device_printf(sc->sc_dev, "ucode timeout\n");
4399 			error = ENXIO;
4400 			goto error;
4401 		}
4402 		DELAY(50000);
4403 	}
4404 	BWN_READ_4(mac, BWN_INTR_REASON);
4405 
4406 	mac->mac_fw.rev = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_REV);
4407 	if (mac->mac_fw.rev <= 0x128) {
4408 		device_printf(sc->sc_dev, "the firmware is too old\n");
4409 		error = EOPNOTSUPP;
4410 		goto error;
4411 	}
4412 
4413 	/*
4414 	 * Determine firmware header version; needed for TX/RX packet
4415 	 * handling.
4416 	 */
4417 	if (mac->mac_fw.rev >= 598)
4418 		mac->mac_fw.fw_hdr_format = BWN_FW_HDR_598;
4419 	else if (mac->mac_fw.rev >= 410)
4420 		mac->mac_fw.fw_hdr_format = BWN_FW_HDR_410;
4421 	else
4422 		mac->mac_fw.fw_hdr_format = BWN_FW_HDR_351;
4423 
4424 	/*
4425 	 * We don't support rev 598 or later; that requires
4426 	 * another round of changes to the TX/RX descriptor
4427 	 * and status layout.
4428 	 *
4429 	 * So, complain this is the case and exit out, rather
4430 	 * than attaching and then failing.
4431 	 */
4432 #if 0
4433 	if (mac->mac_fw.fw_hdr_format == BWN_FW_HDR_598) {
4434 		device_printf(sc->sc_dev,
4435 		    "firmware is too new (>=598); not supported\n");
4436 		error = EOPNOTSUPP;
4437 		goto error;
4438 	}
4439 #endif
4440 
4441 	mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
4442 	    BWN_SHARED_UCODE_PATCH);
4443 	date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
4444 	mac->mac_fw.opensource = (date == 0xffff);
4445 	if (bwn_wme != 0)
4446 		mac->mac_flags |= BWN_MAC_FLAG_WME;
4447 	mac->mac_flags |= BWN_MAC_FLAG_HWCRYPTO;
4448 
4449 	time = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_TIME);
4450 	if (mac->mac_fw.opensource == 0) {
4451 		device_printf(sc->sc_dev,
4452 		    "firmware version (rev %u patch %u date %#x time %#x)\n",
4453 		    mac->mac_fw.rev, mac->mac_fw.patch, date, time);
4454 		if (mac->mac_fw.no_pcmfile)
4455 			device_printf(sc->sc_dev,
4456 			    "no HW crypto acceleration due to pcm5\n");
4457 	} else {
4458 		mac->mac_fw.patch = time;
4459 		fwcaps = bwn_fwcaps_read(mac);
4460 		if (!(fwcaps & BWN_FWCAPS_HWCRYPTO) || mac->mac_fw.no_pcmfile) {
4461 			device_printf(sc->sc_dev,
4462 			    "disabling HW crypto acceleration\n");
4463 			mac->mac_flags &= ~BWN_MAC_FLAG_HWCRYPTO;
4464 		}
4465 		if (!(fwcaps & BWN_FWCAPS_WME)) {
4466 			device_printf(sc->sc_dev, "disabling WME support\n");
4467 			mac->mac_flags &= ~BWN_MAC_FLAG_WME;
4468 		}
4469 	}
4470 
4471 	if (BWN_ISOLDFMT(mac))
4472 		device_printf(sc->sc_dev, "using old firmware image\n");
4473 
4474 	return (0);
4475 
4476 error:
4477 	BWN_WRITE_4(mac, BWN_MACCTL,
4478 	    (BWN_READ_4(mac, BWN_MACCTL) & ~BWN_MACCTL_MCODE_RUN) |
4479 	    BWN_MACCTL_MCODE_JMP0);
4480 
4481 	return (error);
4482 #undef GETFWSIZE
4483 #undef GETFWOFFSET
4484 }
4485 
4486 /* OpenFirmware only */
4487 static uint16_t
bwn_fwcaps_read(struct bwn_mac * mac)4488 bwn_fwcaps_read(struct bwn_mac *mac)
4489 {
4490 
4491 	KASSERT(mac->mac_fw.opensource == 1,
4492 	    ("%s:%d: fail", __func__, __LINE__));
4493 	return (bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_FWCAPS));
4494 }
4495 
4496 static int
bwn_fwinitvals_write(struct bwn_mac * mac,const struct bwn_fwinitvals * ivals,size_t count,size_t array_size)4497 bwn_fwinitvals_write(struct bwn_mac *mac, const struct bwn_fwinitvals *ivals,
4498     size_t count, size_t array_size)
4499 {
4500 #define	GET_NEXTIV16(iv)						\
4501 	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
4502 	    sizeof(uint16_t) + sizeof(uint16_t)))
4503 #define	GET_NEXTIV32(iv)						\
4504 	((const struct bwn_fwinitvals *)((const uint8_t *)(iv) +	\
4505 	    sizeof(uint16_t) + sizeof(uint32_t)))
4506 	struct bwn_softc *sc = mac->mac_sc;
4507 	const struct bwn_fwinitvals *iv;
4508 	uint16_t offset;
4509 	size_t i;
4510 	uint8_t bit32;
4511 
4512 	KASSERT(sizeof(struct bwn_fwinitvals) == 6,
4513 	    ("%s:%d: fail", __func__, __LINE__));
4514 	iv = ivals;
4515 	for (i = 0; i < count; i++) {
4516 		if (array_size < sizeof(iv->offset_size))
4517 			goto fail;
4518 		array_size -= sizeof(iv->offset_size);
4519 		offset = be16toh(iv->offset_size);
4520 		bit32 = (offset & BWN_FWINITVALS_32BIT) ? 1 : 0;
4521 		offset &= BWN_FWINITVALS_OFFSET_MASK;
4522 		if (offset >= 0x1000)
4523 			goto fail;
4524 		if (bit32) {
4525 			if (array_size < sizeof(iv->data.d32))
4526 				goto fail;
4527 			array_size -= sizeof(iv->data.d32);
4528 			BWN_WRITE_4(mac, offset, be32toh(iv->data.d32));
4529 			iv = GET_NEXTIV32(iv);
4530 		} else {
4531 			if (array_size < sizeof(iv->data.d16))
4532 				goto fail;
4533 			array_size -= sizeof(iv->data.d16);
4534 			BWN_WRITE_2(mac, offset, be16toh(iv->data.d16));
4535 
4536 			iv = GET_NEXTIV16(iv);
4537 		}
4538 	}
4539 	if (array_size != 0)
4540 		goto fail;
4541 	return (0);
4542 fail:
4543 	device_printf(sc->sc_dev, "initvals: invalid format\n");
4544 	return (EPROTO);
4545 #undef GET_NEXTIV16
4546 #undef GET_NEXTIV32
4547 }
4548 
4549 int
bwn_switch_channel(struct bwn_mac * mac,int chan)4550 bwn_switch_channel(struct bwn_mac *mac, int chan)
4551 {
4552 	struct bwn_phy *phy = &(mac->mac_phy);
4553 	struct bwn_softc *sc = mac->mac_sc;
4554 	struct ieee80211com *ic = &sc->sc_ic;
4555 	uint16_t channelcookie, savedcookie;
4556 	int error;
4557 
4558 	if (chan == 0xffff)
4559 		chan = phy->get_default_chan(mac);
4560 
4561 	channelcookie = chan;
4562 	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
4563 		channelcookie |= 0x100;
4564 	savedcookie = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_CHAN);
4565 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, channelcookie);
4566 	error = phy->switch_channel(mac, chan);
4567 	if (error)
4568 		goto fail;
4569 
4570 	mac->mac_phy.chan = chan;
4571 	DELAY(8000);
4572 	return (0);
4573 fail:
4574 	device_printf(sc->sc_dev, "failed to switch channel\n");
4575 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_CHAN, savedcookie);
4576 	return (error);
4577 }
4578 
4579 static uint16_t
bwn_ant2phy(int antenna)4580 bwn_ant2phy(int antenna)
4581 {
4582 
4583 	switch (antenna) {
4584 	case BWN_ANT0:
4585 		return (BWN_TX_PHY_ANT0);
4586 	case BWN_ANT1:
4587 		return (BWN_TX_PHY_ANT1);
4588 	case BWN_ANT2:
4589 		return (BWN_TX_PHY_ANT2);
4590 	case BWN_ANT3:
4591 		return (BWN_TX_PHY_ANT3);
4592 	case BWN_ANTAUTO:
4593 		return (BWN_TX_PHY_ANT01AUTO);
4594 	}
4595 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
4596 	return (0);
4597 }
4598 
4599 static void
bwn_wme_load(struct bwn_mac * mac)4600 bwn_wme_load(struct bwn_mac *mac)
4601 {
4602 	struct bwn_softc *sc = mac->mac_sc;
4603 	int i;
4604 
4605 	KASSERT(N(bwn_wme_shm_offsets) == N(sc->sc_wmeParams),
4606 	    ("%s:%d: fail", __func__, __LINE__));
4607 
4608 	bwn_mac_suspend(mac);
4609 	for (i = 0; i < N(sc->sc_wmeParams); i++)
4610 		bwn_wme_loadparams(mac, &(sc->sc_wmeParams[i]),
4611 		    bwn_wme_shm_offsets[i]);
4612 	bwn_mac_enable(mac);
4613 }
4614 
4615 static void
bwn_wme_loadparams(struct bwn_mac * mac,const struct wmeParams * p,uint16_t shm_offset)4616 bwn_wme_loadparams(struct bwn_mac *mac,
4617     const struct wmeParams *p, uint16_t shm_offset)
4618 {
4619 	struct bwn_softc *sc = mac->mac_sc;
4620 	uint16_t params[BWN_NR_WMEPARAMS];
4621 	int slot, tmp;
4622 	unsigned int i;
4623 
4624 	slot = BWN_READ_2(mac, BWN_RNG) &
4625 	    _IEEE80211_SHIFTMASK(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
4626 
4627 	memset(&params, 0, sizeof(params));
4628 
4629 	DPRINTF(sc, BWN_DEBUG_WME, "wmep_txopLimit %d wmep_logcwmin %d "
4630 	    "wmep_logcwmax %d wmep_aifsn %d\n", p->wmep_txopLimit,
4631 	    p->wmep_logcwmin, p->wmep_logcwmax, p->wmep_aifsn);
4632 
4633 	params[BWN_WMEPARAM_TXOP] = p->wmep_txopLimit * 32;
4634 	params[BWN_WMEPARAM_CWMIN] =
4635 	    _IEEE80211_SHIFTMASK(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
4636 	params[BWN_WMEPARAM_CWMAX] =
4637 	     _IEEE80211_SHIFTMASK(p->wmep_logcwmax, WME_PARAM_LOGCWMAX);
4638 	params[BWN_WMEPARAM_CWCUR] =
4639 	     _IEEE80211_SHIFTMASK(p->wmep_logcwmin, WME_PARAM_LOGCWMIN);
4640 	params[BWN_WMEPARAM_AIFS] = p->wmep_aifsn;
4641 	params[BWN_WMEPARAM_BSLOTS] = slot;
4642 	params[BWN_WMEPARAM_REGGAP] = slot + p->wmep_aifsn;
4643 
4644 	for (i = 0; i < N(params); i++) {
4645 		if (i == BWN_WMEPARAM_STATUS) {
4646 			tmp = bwn_shm_read_2(mac, BWN_SHARED,
4647 			    shm_offset + (i * 2));
4648 			tmp |= 0x100;
4649 			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
4650 			    tmp);
4651 		} else {
4652 			bwn_shm_write_2(mac, BWN_SHARED, shm_offset + (i * 2),
4653 			    params[i]);
4654 		}
4655 	}
4656 }
4657 
4658 static void
bwn_mac_write_bssid(struct bwn_mac * mac)4659 bwn_mac_write_bssid(struct bwn_mac *mac)
4660 {
4661 	struct bwn_softc *sc = mac->mac_sc;
4662 	uint32_t tmp;
4663 	int i;
4664 	uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
4665 
4666 	bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
4667 	memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN);
4668 	memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
4669 	    IEEE80211_ADDR_LEN);
4670 
4671 	for (i = 0; i < N(mac_bssid); i += sizeof(uint32_t)) {
4672 		tmp = (uint32_t) (mac_bssid[i + 0]);
4673 		tmp |= (uint32_t) (mac_bssid[i + 1]) << 8;
4674 		tmp |= (uint32_t) (mac_bssid[i + 2]) << 16;
4675 		tmp |= (uint32_t) (mac_bssid[i + 3]) << 24;
4676 		bwn_ram_write(mac, 0x20 + i, tmp);
4677 	}
4678 }
4679 
4680 static void
bwn_mac_setfilter(struct bwn_mac * mac,uint16_t offset,const uint8_t * macaddr)4681 bwn_mac_setfilter(struct bwn_mac *mac, uint16_t offset,
4682     const uint8_t *macaddr)
4683 {
4684 	static const uint8_t zero[IEEE80211_ADDR_LEN] = { 0 };
4685 	uint16_t data;
4686 
4687 	if (!mac)
4688 		macaddr = zero;
4689 
4690 	offset |= 0x0020;
4691 	BWN_WRITE_2(mac, BWN_MACFILTER_CONTROL, offset);
4692 
4693 	data = macaddr[0];
4694 	data |= macaddr[1] << 8;
4695 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
4696 	data = macaddr[2];
4697 	data |= macaddr[3] << 8;
4698 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
4699 	data = macaddr[4];
4700 	data |= macaddr[5] << 8;
4701 	BWN_WRITE_2(mac, BWN_MACFILTER_DATA, data);
4702 }
4703 
4704 static void
bwn_key_dowrite(struct bwn_mac * mac,uint8_t index,uint8_t algorithm,const uint8_t * key,size_t key_len,const uint8_t * mac_addr)4705 bwn_key_dowrite(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
4706     const uint8_t *key, size_t key_len, const uint8_t *mac_addr)
4707 {
4708 	uint8_t buf[BWN_SEC_KEYSIZE] = { 0, };
4709 	uint8_t per_sta_keys_start = 8;
4710 
4711 	if (BWN_SEC_NEWAPI(mac))
4712 		per_sta_keys_start = 4;
4713 
4714 	KASSERT(index < mac->mac_max_nr_keys,
4715 	    ("%s:%d: fail", __func__, __LINE__));
4716 	KASSERT(key_len <= BWN_SEC_KEYSIZE,
4717 	    ("%s:%d: fail", __func__, __LINE__));
4718 
4719 	if (index >= per_sta_keys_start)
4720 		bwn_key_macwrite(mac, index, NULL);
4721 	if (key)
4722 		memcpy(buf, key, key_len);
4723 	bwn_key_write(mac, index, algorithm, buf);
4724 	if (index >= per_sta_keys_start)
4725 		bwn_key_macwrite(mac, index, mac_addr);
4726 
4727 	mac->mac_key[index].algorithm = algorithm;
4728 }
4729 
4730 static void
bwn_key_macwrite(struct bwn_mac * mac,uint8_t index,const uint8_t * addr)4731 bwn_key_macwrite(struct bwn_mac *mac, uint8_t index, const uint8_t *addr)
4732 {
4733 	struct bwn_softc *sc = mac->mac_sc;
4734 	uint32_t addrtmp[2] = { 0, 0 };
4735 	uint8_t start = 8;
4736 
4737 	if (BWN_SEC_NEWAPI(mac))
4738 		start = 4;
4739 
4740 	KASSERT(index >= start,
4741 	    ("%s:%d: fail", __func__, __LINE__));
4742 	index -= start;
4743 
4744 	if (addr) {
4745 		addrtmp[0] = addr[0];
4746 		addrtmp[0] |= ((uint32_t) (addr[1]) << 8);
4747 		addrtmp[0] |= ((uint32_t) (addr[2]) << 16);
4748 		addrtmp[0] |= ((uint32_t) (addr[3]) << 24);
4749 		addrtmp[1] = addr[4];
4750 		addrtmp[1] |= ((uint32_t) (addr[5]) << 8);
4751 	}
4752 
4753 	if (bhnd_get_hwrev(sc->sc_dev) >= 5) {
4754 		bwn_shm_write_4(mac, BWN_RCMTA, (index * 2) + 0, addrtmp[0]);
4755 		bwn_shm_write_2(mac, BWN_RCMTA, (index * 2) + 1, addrtmp[1]);
4756 	} else {
4757 		if (index >= 8) {
4758 			bwn_shm_write_4(mac, BWN_SHARED,
4759 			    BWN_SHARED_PSM + (index * 6) + 0, addrtmp[0]);
4760 			bwn_shm_write_2(mac, BWN_SHARED,
4761 			    BWN_SHARED_PSM + (index * 6) + 4, addrtmp[1]);
4762 		}
4763 	}
4764 }
4765 
4766 static void
bwn_key_write(struct bwn_mac * mac,uint8_t index,uint8_t algorithm,const uint8_t * key)4767 bwn_key_write(struct bwn_mac *mac, uint8_t index, uint8_t algorithm,
4768     const uint8_t *key)
4769 {
4770 	unsigned int i;
4771 	uint32_t offset;
4772 	uint16_t kidx, value;
4773 
4774 	kidx = BWN_SEC_KEY2FW(mac, index);
4775 	bwn_shm_write_2(mac, BWN_SHARED,
4776 	    BWN_SHARED_KEYIDX_BLOCK + (kidx * 2), (kidx << 4) | algorithm);
4777 
4778 	offset = mac->mac_ktp + (index * BWN_SEC_KEYSIZE);
4779 	for (i = 0; i < BWN_SEC_KEYSIZE; i += 2) {
4780 		value = key[i];
4781 		value |= (uint16_t)(key[i + 1]) << 8;
4782 		bwn_shm_write_2(mac, BWN_SHARED, offset + i, value);
4783 	}
4784 }
4785 
4786 static void
bwn_phy_exit(struct bwn_mac * mac)4787 bwn_phy_exit(struct bwn_mac *mac)
4788 {
4789 
4790 	mac->mac_phy.rf_onoff(mac, 0);
4791 	if (mac->mac_phy.exit != NULL)
4792 		mac->mac_phy.exit(mac);
4793 }
4794 
4795 static void
bwn_dma_free(struct bwn_mac * mac)4796 bwn_dma_free(struct bwn_mac *mac)
4797 {
4798 	struct bwn_dma *dma;
4799 
4800 	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
4801 		return;
4802 	dma = &mac->mac_method.dma;
4803 
4804 	bwn_dma_ringfree(&dma->rx);
4805 	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
4806 	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
4807 	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
4808 	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
4809 	bwn_dma_ringfree(&dma->mcast);
4810 }
4811 
4812 static void
bwn_core_stop(struct bwn_mac * mac)4813 bwn_core_stop(struct bwn_mac *mac)
4814 {
4815 	struct bwn_softc *sc = mac->mac_sc;
4816 
4817 	BWN_ASSERT_LOCKED(sc);
4818 
4819 	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
4820 		return;
4821 
4822 	callout_stop(&sc->sc_rfswitch_ch);
4823 	callout_stop(&sc->sc_task_ch);
4824 	callout_stop(&sc->sc_watchdog_ch);
4825 	sc->sc_watchdog_timer = 0;
4826 	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
4827 	BWN_READ_4(mac, BWN_INTR_MASK);
4828 	bwn_mac_suspend(mac);
4829 
4830 	mac->mac_status = BWN_MAC_STATUS_INITED;
4831 }
4832 
4833 static int
bwn_switch_band(struct bwn_softc * sc,struct ieee80211_channel * chan)4834 bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
4835 {
4836 	struct bwn_mac *up_dev = NULL;
4837 	struct bwn_mac *down_dev;
4838 	struct bwn_mac *mac;
4839 	int err, status;
4840 	uint8_t gmode;
4841 
4842 	BWN_ASSERT_LOCKED(sc);
4843 
4844 	TAILQ_FOREACH(mac, &sc->sc_maclist, mac_list) {
4845 		if (IEEE80211_IS_CHAN_2GHZ(chan) &&
4846 		    mac->mac_phy.supports_2ghz) {
4847 			up_dev = mac;
4848 			gmode = 1;
4849 		} else if (IEEE80211_IS_CHAN_5GHZ(chan) &&
4850 		    mac->mac_phy.supports_5ghz) {
4851 			up_dev = mac;
4852 			gmode = 0;
4853 		} else {
4854 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
4855 			return (EINVAL);
4856 		}
4857 		if (up_dev != NULL)
4858 			break;
4859 	}
4860 	if (up_dev == NULL) {
4861 		device_printf(sc->sc_dev, "Could not find a device\n");
4862 		return (ENODEV);
4863 	}
4864 	if (up_dev == sc->sc_curmac && sc->sc_curmac->mac_phy.gmode == gmode)
4865 		return (0);
4866 
4867 	DPRINTF(sc, BWN_DEBUG_RF | BWN_DEBUG_PHY | BWN_DEBUG_RESET,
4868 	    "switching to %s-GHz band\n",
4869 	    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
4870 
4871 	down_dev = sc->sc_curmac;
4872 	status = down_dev->mac_status;
4873 	if (status >= BWN_MAC_STATUS_STARTED)
4874 		bwn_core_stop(down_dev);
4875 	if (status >= BWN_MAC_STATUS_INITED)
4876 		bwn_core_exit(down_dev);
4877 
4878 	if (down_dev != up_dev) {
4879 		err = bwn_phy_reset(down_dev);
4880 		if (err)
4881 			goto fail;
4882 	}
4883 
4884 	up_dev->mac_phy.gmode = gmode;
4885 	if (status >= BWN_MAC_STATUS_INITED) {
4886 		err = bwn_core_init(up_dev);
4887 		if (err) {
4888 			device_printf(sc->sc_dev,
4889 			    "fatal: failed to initialize for %s-GHz\n",
4890 			    IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
4891 			goto fail;
4892 		}
4893 	}
4894 	if (status >= BWN_MAC_STATUS_STARTED)
4895 		bwn_core_start(up_dev);
4896 	KASSERT(up_dev->mac_status == status, ("%s: fail", __func__));
4897 	sc->sc_curmac = up_dev;
4898 
4899 	return (0);
4900 fail:
4901 	sc->sc_curmac = NULL;
4902 	return (err);
4903 }
4904 
4905 static void
bwn_rf_turnon(struct bwn_mac * mac)4906 bwn_rf_turnon(struct bwn_mac *mac)
4907 {
4908 
4909 	DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: called\n", __func__);
4910 
4911 	bwn_mac_suspend(mac);
4912 	mac->mac_phy.rf_onoff(mac, 1);
4913 	mac->mac_phy.rf_on = 1;
4914 	bwn_mac_enable(mac);
4915 }
4916 
4917 static void
bwn_rf_turnoff(struct bwn_mac * mac)4918 bwn_rf_turnoff(struct bwn_mac *mac)
4919 {
4920 
4921 	DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: called\n", __func__);
4922 
4923 	bwn_mac_suspend(mac);
4924 	mac->mac_phy.rf_onoff(mac, 0);
4925 	mac->mac_phy.rf_on = 0;
4926 	bwn_mac_enable(mac);
4927 }
4928 
4929 /*
4930  * PHY reset.
4931  */
4932 static int
bwn_phy_reset(struct bwn_mac * mac)4933 bwn_phy_reset(struct bwn_mac *mac)
4934 {
4935 	struct bwn_softc	*sc;
4936 	uint16_t		 iost, mask;
4937 	int			 error;
4938 
4939 	sc = mac->mac_sc;
4940 
4941 	iost = BWN_IOCTL_PHYRESET | BHND_IOCTL_CLK_FORCE;
4942 	mask = iost | BWN_IOCTL_SUPPORT_G;
4943 
4944 	if ((error = bhnd_write_ioctl(sc->sc_dev, iost, mask)))
4945 		return (error);
4946 
4947 	DELAY(1000);
4948 
4949 	iost &= ~BHND_IOCTL_CLK_FORCE;
4950 
4951 	if ((error = bhnd_write_ioctl(sc->sc_dev, iost, mask)))
4952 		return (error);
4953 
4954 	DELAY(1000);
4955 
4956 	return (0);
4957 }
4958 
4959 static int
bwn_newstate(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)4960 bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
4961 {
4962 	struct bwn_vap *bvp = BWN_VAP(vap);
4963 	struct ieee80211com *ic= vap->iv_ic;
4964 	enum ieee80211_state ostate = vap->iv_state;
4965 	struct bwn_softc *sc = ic->ic_softc;
4966 	struct bwn_mac *mac = sc->sc_curmac;
4967 	int error;
4968 
4969 	DPRINTF(sc, BWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
4970 	    ieee80211_state_name[vap->iv_state],
4971 	    ieee80211_state_name[nstate]);
4972 
4973 	error = bvp->bv_newstate(vap, nstate, arg);
4974 	if (error != 0)
4975 		return (error);
4976 
4977 	BWN_LOCK(sc);
4978 
4979 	bwn_led_newstate(mac, nstate);
4980 
4981 	/*
4982 	 * Clear the BSSID when we stop a STA
4983 	 */
4984 	if (vap->iv_opmode == IEEE80211_M_STA) {
4985 		if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
4986 			/*
4987 			 * Clear out the BSSID.  If we reassociate to
4988 			 * the same AP, this will reinialize things
4989 			 * correctly...
4990 			 */
4991 			if (ic->ic_opmode == IEEE80211_M_STA &&
4992 			    (sc->sc_flags & BWN_FLAG_INVALID) == 0) {
4993 				memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
4994 				bwn_set_macaddr(mac);
4995 			}
4996 		}
4997 	}
4998 
4999 	if (vap->iv_opmode == IEEE80211_M_MONITOR ||
5000 	    vap->iv_opmode == IEEE80211_M_AHDEMO) {
5001 		/* XXX nothing to do? */
5002 	} else if (nstate == IEEE80211_S_RUN) {
5003 		memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
5004 		bwn_set_opmode(mac);
5005 		bwn_set_pretbtt(mac);
5006 		bwn_spu_setdelay(mac, 0);
5007 		bwn_set_macaddr(mac);
5008 	}
5009 
5010 	BWN_UNLOCK(sc);
5011 
5012 	return (error);
5013 }
5014 
5015 static void
bwn_set_pretbtt(struct bwn_mac * mac)5016 bwn_set_pretbtt(struct bwn_mac *mac)
5017 {
5018 	struct bwn_softc *sc = mac->mac_sc;
5019 	struct ieee80211com *ic = &sc->sc_ic;
5020 	uint16_t pretbtt;
5021 
5022 	if (ic->ic_opmode == IEEE80211_M_IBSS)
5023 		pretbtt = 2;
5024 	else
5025 		pretbtt = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 120 : 250;
5026 	bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PRETBTT, pretbtt);
5027 	BWN_WRITE_2(mac, BWN_TSF_CFP_PRETBTT, pretbtt);
5028 }
5029 
5030 static int
bwn_intr(void * arg)5031 bwn_intr(void *arg)
5032 {
5033 	struct bwn_mac *mac = arg;
5034 	struct bwn_softc *sc = mac->mac_sc;
5035 	uint32_t reason;
5036 
5037 	if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
5038 	    (sc->sc_flags & BWN_FLAG_INVALID))
5039 		return (FILTER_STRAY);
5040 
5041 	DPRINTF(sc, BWN_DEBUG_INTR, "%s: called\n", __func__);
5042 
5043 	reason = BWN_READ_4(mac, BWN_INTR_REASON);
5044 	if (reason == 0xffffffff)	/* shared IRQ */
5045 		return (FILTER_STRAY);
5046 	reason &= mac->mac_intr_mask;
5047 	if (reason == 0)
5048 		return (FILTER_HANDLED);
5049 	DPRINTF(sc, BWN_DEBUG_INTR, "%s: reason=0x%08x\n", __func__, reason);
5050 
5051 	mac->mac_reason[0] = BWN_READ_4(mac, BWN_DMA0_REASON) & 0x0001dc00;
5052 	mac->mac_reason[1] = BWN_READ_4(mac, BWN_DMA1_REASON) & 0x0000dc00;
5053 	mac->mac_reason[2] = BWN_READ_4(mac, BWN_DMA2_REASON) & 0x0000dc00;
5054 	mac->mac_reason[3] = BWN_READ_4(mac, BWN_DMA3_REASON) & 0x0001dc00;
5055 	mac->mac_reason[4] = BWN_READ_4(mac, BWN_DMA4_REASON) & 0x0000dc00;
5056 	BWN_WRITE_4(mac, BWN_INTR_REASON, reason);
5057 	BWN_WRITE_4(mac, BWN_DMA0_REASON, mac->mac_reason[0]);
5058 	BWN_WRITE_4(mac, BWN_DMA1_REASON, mac->mac_reason[1]);
5059 	BWN_WRITE_4(mac, BWN_DMA2_REASON, mac->mac_reason[2]);
5060 	BWN_WRITE_4(mac, BWN_DMA3_REASON, mac->mac_reason[3]);
5061 	BWN_WRITE_4(mac, BWN_DMA4_REASON, mac->mac_reason[4]);
5062 
5063 	/* Disable interrupts. */
5064 	BWN_WRITE_4(mac, BWN_INTR_MASK, 0);
5065 
5066 	mac->mac_reason_intr = reason;
5067 
5068 	BWN_BARRIER(mac, 0, 0, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
5069 
5070 	taskqueue_enqueue(sc->sc_tq, &mac->mac_intrtask);
5071 	return (FILTER_HANDLED);
5072 }
5073 
5074 static void
bwn_intrtask(void * arg,int npending)5075 bwn_intrtask(void *arg, int npending)
5076 {
5077 	struct bwn_mac *mac = arg;
5078 	struct bwn_softc *sc = mac->mac_sc;
5079 	uint32_t merged = 0;
5080 	int i, tx = 0, rx = 0;
5081 
5082 	BWN_LOCK(sc);
5083 	if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
5084 	    (sc->sc_flags & BWN_FLAG_INVALID)) {
5085 		BWN_UNLOCK(sc);
5086 		return;
5087 	}
5088 
5089 	for (i = 0; i < N(mac->mac_reason); i++)
5090 		merged |= mac->mac_reason[i];
5091 
5092 	if (mac->mac_reason_intr & BWN_INTR_MAC_TXERR)
5093 		device_printf(sc->sc_dev, "MAC trans error\n");
5094 
5095 	if (mac->mac_reason_intr & BWN_INTR_PHY_TXERR) {
5096 		DPRINTF(sc, BWN_DEBUG_INTR, "%s: PHY trans error\n", __func__);
5097 		mac->mac_phy.txerrors--;
5098 		if (mac->mac_phy.txerrors == 0) {
5099 			mac->mac_phy.txerrors = BWN_TXERROR_MAX;
5100 			bwn_restart(mac, "PHY TX errors");
5101 		}
5102 	}
5103 
5104 	if (merged & (BWN_DMAINTR_FATALMASK | BWN_DMAINTR_NONFATALMASK)) {
5105 		if (merged & BWN_DMAINTR_FATALMASK) {
5106 			device_printf(sc->sc_dev,
5107 			    "Fatal DMA error: %#x %#x %#x %#x %#x %#x\n",
5108 			    mac->mac_reason[0], mac->mac_reason[1],
5109 			    mac->mac_reason[2], mac->mac_reason[3],
5110 			    mac->mac_reason[4], mac->mac_reason[5]);
5111 			bwn_restart(mac, "DMA error");
5112 			BWN_UNLOCK(sc);
5113 			return;
5114 		}
5115 		if (merged & BWN_DMAINTR_NONFATALMASK) {
5116 			device_printf(sc->sc_dev,
5117 			    "DMA error: %#x %#x %#x %#x %#x %#x\n",
5118 			    mac->mac_reason[0], mac->mac_reason[1],
5119 			    mac->mac_reason[2], mac->mac_reason[3],
5120 			    mac->mac_reason[4], mac->mac_reason[5]);
5121 		}
5122 	}
5123 
5124 	if (mac->mac_reason_intr & BWN_INTR_UCODE_DEBUG)
5125 		bwn_intr_ucode_debug(mac);
5126 	if (mac->mac_reason_intr & BWN_INTR_TBTT_INDI)
5127 		bwn_intr_tbtt_indication(mac);
5128 	if (mac->mac_reason_intr & BWN_INTR_ATIM_END)
5129 		bwn_intr_atim_end(mac);
5130 	if (mac->mac_reason_intr & BWN_INTR_BEACON)
5131 		bwn_intr_beacon(mac);
5132 	if (mac->mac_reason_intr & BWN_INTR_PMQ)
5133 		bwn_intr_pmq(mac);
5134 	if (mac->mac_reason_intr & BWN_INTR_NOISESAMPLE_OK)
5135 		bwn_intr_noise(mac);
5136 
5137 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
5138 		if (mac->mac_reason[0] & BWN_DMAINTR_RX_DONE) {
5139 			bwn_dma_rx(mac->mac_method.dma.rx);
5140 			rx = 1;
5141 		}
5142 	} else
5143 		rx = bwn_pio_rx(&mac->mac_method.pio.rx);
5144 
5145 	KASSERT(!(mac->mac_reason[1] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
5146 	KASSERT(!(mac->mac_reason[2] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
5147 	KASSERT(!(mac->mac_reason[3] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
5148 	KASSERT(!(mac->mac_reason[4] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
5149 	KASSERT(!(mac->mac_reason[5] & BWN_DMAINTR_RX_DONE), ("%s", __func__));
5150 
5151 	if (mac->mac_reason_intr & BWN_INTR_TX_OK) {
5152 		bwn_intr_txeof(mac);
5153 		tx = 1;
5154 	}
5155 
5156 	BWN_WRITE_4(mac, BWN_INTR_MASK, mac->mac_intr_mask);
5157 
5158 	if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
5159 		int evt = BWN_LED_EVENT_NONE;
5160 
5161 		if (tx && rx) {
5162 			if (sc->sc_rx_rate > sc->sc_tx_rate)
5163 				evt = BWN_LED_EVENT_RX;
5164 			else
5165 				evt = BWN_LED_EVENT_TX;
5166 		} else if (tx) {
5167 			evt = BWN_LED_EVENT_TX;
5168 		} else if (rx) {
5169 			evt = BWN_LED_EVENT_RX;
5170 		} else if (rx == 0) {
5171 			evt = BWN_LED_EVENT_POLL;
5172 		}
5173 
5174 		if (evt != BWN_LED_EVENT_NONE)
5175 			bwn_led_event(mac, evt);
5176        }
5177 
5178 	if (mbufq_first(&sc->sc_snd) != NULL)
5179 		bwn_start(sc);
5180 
5181 	BWN_BARRIER(mac, 0, 0, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
5182 
5183 	BWN_UNLOCK(sc);
5184 }
5185 
5186 static void
bwn_restart(struct bwn_mac * mac,const char * msg)5187 bwn_restart(struct bwn_mac *mac, const char *msg)
5188 {
5189 	struct bwn_softc *sc = mac->mac_sc;
5190 	struct ieee80211com *ic = &sc->sc_ic;
5191 
5192 	if (mac->mac_status < BWN_MAC_STATUS_INITED)
5193 		return;
5194 
5195 	device_printf(sc->sc_dev, "HW reset: %s\n", msg);
5196 	ieee80211_runtask(ic, &mac->mac_hwreset);
5197 }
5198 
5199 static void
bwn_intr_ucode_debug(struct bwn_mac * mac)5200 bwn_intr_ucode_debug(struct bwn_mac *mac)
5201 {
5202 	struct bwn_softc *sc = mac->mac_sc;
5203 	uint16_t reason;
5204 
5205 	if (mac->mac_fw.opensource == 0)
5206 		return;
5207 
5208 	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG);
5209 	switch (reason) {
5210 	case BWN_DEBUGINTR_PANIC:
5211 		bwn_handle_fwpanic(mac);
5212 		break;
5213 	case BWN_DEBUGINTR_DUMP_SHM:
5214 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_SHM\n");
5215 		break;
5216 	case BWN_DEBUGINTR_DUMP_REGS:
5217 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_DUMP_REGS\n");
5218 		break;
5219 	case BWN_DEBUGINTR_MARKER:
5220 		device_printf(sc->sc_dev, "BWN_DEBUGINTR_MARKER\n");
5221 		break;
5222 	default:
5223 		device_printf(sc->sc_dev,
5224 		    "ucode debug unknown reason: %#x\n", reason);
5225 	}
5226 
5227 	bwn_shm_write_2(mac, BWN_SCRATCH, BWN_DEBUGINTR_REASON_REG,
5228 	    BWN_DEBUGINTR_ACK);
5229 }
5230 
5231 static void
bwn_intr_tbtt_indication(struct bwn_mac * mac)5232 bwn_intr_tbtt_indication(struct bwn_mac *mac)
5233 {
5234 	struct bwn_softc *sc = mac->mac_sc;
5235 	struct ieee80211com *ic = &sc->sc_ic;
5236 
5237 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
5238 		bwn_psctl(mac, 0);
5239 	if (ic->ic_opmode == IEEE80211_M_IBSS)
5240 		mac->mac_flags |= BWN_MAC_FLAG_DFQVALID;
5241 }
5242 
5243 static void
bwn_intr_atim_end(struct bwn_mac * mac)5244 bwn_intr_atim_end(struct bwn_mac *mac)
5245 {
5246 
5247 	if (mac->mac_flags & BWN_MAC_FLAG_DFQVALID) {
5248 		BWN_WRITE_4(mac, BWN_MACCMD,
5249 		    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_DFQ_VALID);
5250 		mac->mac_flags &= ~BWN_MAC_FLAG_DFQVALID;
5251 	}
5252 }
5253 
5254 static void
bwn_intr_beacon(struct bwn_mac * mac)5255 bwn_intr_beacon(struct bwn_mac *mac)
5256 {
5257 	struct bwn_softc *sc = mac->mac_sc;
5258 	struct ieee80211com *ic = &sc->sc_ic;
5259 	uint32_t cmd, beacon0, beacon1;
5260 
5261 	if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
5262 	    ic->ic_opmode == IEEE80211_M_MBSS)
5263 		return;
5264 
5265 	mac->mac_intr_mask &= ~BWN_INTR_BEACON;
5266 
5267 	cmd = BWN_READ_4(mac, BWN_MACCMD);
5268 	beacon0 = (cmd & BWN_MACCMD_BEACON0_VALID);
5269 	beacon1 = (cmd & BWN_MACCMD_BEACON1_VALID);
5270 
5271 	if (beacon0 && beacon1) {
5272 		BWN_WRITE_4(mac, BWN_INTR_REASON, BWN_INTR_BEACON);
5273 		mac->mac_intr_mask |= BWN_INTR_BEACON;
5274 		return;
5275 	}
5276 
5277 	if (sc->sc_flags & BWN_FLAG_NEED_BEACON_TP) {
5278 		sc->sc_flags &= ~BWN_FLAG_NEED_BEACON_TP;
5279 		bwn_load_beacon0(mac);
5280 		bwn_load_beacon1(mac);
5281 		cmd = BWN_READ_4(mac, BWN_MACCMD);
5282 		cmd |= BWN_MACCMD_BEACON0_VALID;
5283 		BWN_WRITE_4(mac, BWN_MACCMD, cmd);
5284 	} else {
5285 		if (!beacon0) {
5286 			bwn_load_beacon0(mac);
5287 			cmd = BWN_READ_4(mac, BWN_MACCMD);
5288 			cmd |= BWN_MACCMD_BEACON0_VALID;
5289 			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
5290 		} else if (!beacon1) {
5291 			bwn_load_beacon1(mac);
5292 			cmd = BWN_READ_4(mac, BWN_MACCMD);
5293 			cmd |= BWN_MACCMD_BEACON1_VALID;
5294 			BWN_WRITE_4(mac, BWN_MACCMD, cmd);
5295 		}
5296 	}
5297 }
5298 
5299 static void
bwn_intr_pmq(struct bwn_mac * mac)5300 bwn_intr_pmq(struct bwn_mac *mac)
5301 {
5302 	uint32_t tmp;
5303 
5304 	while (1) {
5305 		tmp = BWN_READ_4(mac, BWN_PS_STATUS);
5306 		if (!(tmp & 0x00000008))
5307 			break;
5308 	}
5309 	BWN_WRITE_2(mac, BWN_PS_STATUS, 0x0002);
5310 }
5311 
5312 static void
bwn_intr_noise(struct bwn_mac * mac)5313 bwn_intr_noise(struct bwn_mac *mac)
5314 {
5315 	struct bwn_phy_g *pg = &mac->mac_phy.phy_g;
5316 	uint16_t tmp;
5317 	uint8_t noise[4];
5318 	uint8_t i, j;
5319 	int32_t average;
5320 
5321 	if (mac->mac_phy.type != BWN_PHYTYPE_G)
5322 		return;
5323 
5324 	KASSERT(mac->mac_noise.noi_running, ("%s: fail", __func__));
5325 	*((uint32_t *)noise) = htole32(bwn_jssi_read(mac));
5326 	if (noise[0] == 0x7f || noise[1] == 0x7f || noise[2] == 0x7f ||
5327 	    noise[3] == 0x7f)
5328 		goto new;
5329 
5330 	KASSERT(mac->mac_noise.noi_nsamples < 8,
5331 	    ("%s:%d: fail", __func__, __LINE__));
5332 	i = mac->mac_noise.noi_nsamples;
5333 	noise[0] = MIN(MAX(noise[0], 0), N(pg->pg_nrssi_lt) - 1);
5334 	noise[1] = MIN(MAX(noise[1], 0), N(pg->pg_nrssi_lt) - 1);
5335 	noise[2] = MIN(MAX(noise[2], 0), N(pg->pg_nrssi_lt) - 1);
5336 	noise[3] = MIN(MAX(noise[3], 0), N(pg->pg_nrssi_lt) - 1);
5337 	mac->mac_noise.noi_samples[i][0] = pg->pg_nrssi_lt[noise[0]];
5338 	mac->mac_noise.noi_samples[i][1] = pg->pg_nrssi_lt[noise[1]];
5339 	mac->mac_noise.noi_samples[i][2] = pg->pg_nrssi_lt[noise[2]];
5340 	mac->mac_noise.noi_samples[i][3] = pg->pg_nrssi_lt[noise[3]];
5341 	mac->mac_noise.noi_nsamples++;
5342 	if (mac->mac_noise.noi_nsamples == 8) {
5343 		average = 0;
5344 		for (i = 0; i < 8; i++) {
5345 			for (j = 0; j < 4; j++)
5346 				average += mac->mac_noise.noi_samples[i][j];
5347 		}
5348 		average = (((average / 32) * 125) + 64) / 128;
5349 		tmp = (bwn_shm_read_2(mac, BWN_SHARED, 0x40c) / 128) & 0x1f;
5350 		if (tmp >= 8)
5351 			average += 2;
5352 		else
5353 			average -= 25;
5354 		average -= (tmp == 8) ? 72 : 48;
5355 
5356 		mac->mac_stats.link_noise = average;
5357 		mac->mac_noise.noi_running = 0;
5358 		return;
5359 	}
5360 new:
5361 	bwn_noise_gensample(mac);
5362 }
5363 
5364 static int
bwn_pio_rx(struct bwn_pio_rxqueue * prq)5365 bwn_pio_rx(struct bwn_pio_rxqueue *prq)
5366 {
5367 	struct bwn_mac *mac = prq->prq_mac;
5368 	struct bwn_softc *sc = mac->mac_sc;
5369 	unsigned int i;
5370 
5371 	BWN_ASSERT_LOCKED(sc);
5372 
5373 	if (mac->mac_status < BWN_MAC_STATUS_STARTED)
5374 		return (0);
5375 
5376 	for (i = 0; i < 5000; i++) {
5377 		if (bwn_pio_rxeof(prq) == 0)
5378 			break;
5379 	}
5380 	if (i >= 5000)
5381 		device_printf(sc->sc_dev, "too many RX frames in PIO mode\n");
5382 	return ((i > 0) ? 1 : 0);
5383 }
5384 
5385 static void
bwn_dma_rx(struct bwn_dma_ring * dr)5386 bwn_dma_rx(struct bwn_dma_ring *dr)
5387 {
5388 	int slot, curslot;
5389 
5390 	KASSERT(!dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
5391 	curslot = dr->get_curslot(dr);
5392 	KASSERT(curslot >= 0 && curslot < dr->dr_numslots,
5393 	    ("%s:%d: fail", __func__, __LINE__));
5394 
5395 	slot = dr->dr_curslot;
5396 	for (; slot != curslot; slot = bwn_dma_nextslot(dr, slot))
5397 		bwn_dma_rxeof(dr, &slot);
5398 
5399 	bus_dmamap_sync(dr->dr_ring_dtag, dr->dr_ring_dmap,
5400 	    BUS_DMASYNC_PREWRITE);
5401 
5402 	dr->set_curslot(dr, slot);
5403 	dr->dr_curslot = slot;
5404 }
5405 
5406 static void
bwn_intr_txeof(struct bwn_mac * mac)5407 bwn_intr_txeof(struct bwn_mac *mac)
5408 {
5409 	struct bwn_txstatus stat;
5410 	uint32_t stat0, stat1;
5411 	uint16_t tmp;
5412 
5413 	BWN_ASSERT_LOCKED(mac->mac_sc);
5414 
5415 	while (1) {
5416 		stat0 = BWN_READ_4(mac, BWN_XMITSTAT_0);
5417 		if (!(stat0 & 0x00000001))
5418 			break;
5419 		stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
5420 
5421 		DPRINTF(mac->mac_sc, BWN_DEBUG_XMIT,
5422 		    "%s: stat0=0x%08x, stat1=0x%08x\n",
5423 		    __func__,
5424 		    stat0,
5425 		    stat1);
5426 
5427 		stat.cookie = (stat0 >> 16);
5428 		stat.seq = (stat1 & 0x0000ffff);
5429 		stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
5430 		tmp = (stat0 & 0x0000ffff);
5431 		stat.framecnt = ((tmp & 0xf000) >> 12);
5432 		stat.rtscnt = ((tmp & 0x0f00) >> 8);
5433 		stat.sreason = ((tmp & 0x001c) >> 2);
5434 		stat.pm = (tmp & 0x0080) ? 1 : 0;
5435 		stat.im = (tmp & 0x0040) ? 1 : 0;
5436 		stat.ampdu = (tmp & 0x0020) ? 1 : 0;
5437 		stat.ack = (tmp & 0x0002) ? 1 : 0;
5438 
5439 		DPRINTF(mac->mac_sc, BWN_DEBUG_XMIT,
5440 		    "%s: cookie=%d, seq=%d, phystat=0x%02x, framecnt=%d, "
5441 		    "rtscnt=%d, sreason=%d, pm=%d, im=%d, ampdu=%d, ack=%d\n",
5442 		    __func__,
5443 		    stat.cookie,
5444 		    stat.seq,
5445 		    stat.phy_stat,
5446 		    stat.framecnt,
5447 		    stat.rtscnt,
5448 		    stat.sreason,
5449 		    stat.pm,
5450 		    stat.im,
5451 		    stat.ampdu,
5452 		    stat.ack);
5453 
5454 		bwn_handle_txeof(mac, &stat);
5455 	}
5456 }
5457 
5458 static void
bwn_hwreset(void * arg,int npending)5459 bwn_hwreset(void *arg, int npending)
5460 {
5461 	struct bwn_mac *mac = arg;
5462 	struct bwn_softc *sc = mac->mac_sc;
5463 	int error = 0;
5464 	int prev_status;
5465 
5466 	BWN_LOCK(sc);
5467 
5468 	prev_status = mac->mac_status;
5469 	if (prev_status >= BWN_MAC_STATUS_STARTED)
5470 		bwn_core_stop(mac);
5471 	if (prev_status >= BWN_MAC_STATUS_INITED)
5472 		bwn_core_exit(mac);
5473 
5474 	if (prev_status >= BWN_MAC_STATUS_INITED) {
5475 		error = bwn_core_init(mac);
5476 		if (error)
5477 			goto out;
5478 	}
5479 	if (prev_status >= BWN_MAC_STATUS_STARTED)
5480 		bwn_core_start(mac);
5481 out:
5482 	if (error) {
5483 		device_printf(sc->sc_dev, "%s: failed (%d)\n", __func__, error);
5484 		sc->sc_curmac = NULL;
5485 	}
5486 	BWN_UNLOCK(sc);
5487 }
5488 
5489 static void
bwn_handle_fwpanic(struct bwn_mac * mac)5490 bwn_handle_fwpanic(struct bwn_mac *mac)
5491 {
5492 	struct bwn_softc *sc = mac->mac_sc;
5493 	uint16_t reason;
5494 
5495 	reason = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_FWPANIC_REASON_REG);
5496 	device_printf(sc->sc_dev,"fw panic (%u)\n", reason);
5497 
5498 	if (reason == BWN_FWPANIC_RESTART)
5499 		bwn_restart(mac, "ucode panic");
5500 }
5501 
5502 static void
bwn_load_beacon0(struct bwn_mac * mac)5503 bwn_load_beacon0(struct bwn_mac *mac)
5504 {
5505 
5506 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5507 }
5508 
5509 static void
bwn_load_beacon1(struct bwn_mac * mac)5510 bwn_load_beacon1(struct bwn_mac *mac)
5511 {
5512 
5513 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
5514 }
5515 
5516 static uint32_t
bwn_jssi_read(struct bwn_mac * mac)5517 bwn_jssi_read(struct bwn_mac *mac)
5518 {
5519 	uint32_t val = 0;
5520 
5521 	val = bwn_shm_read_2(mac, BWN_SHARED, 0x08a);
5522 	val <<= 16;
5523 	val |= bwn_shm_read_2(mac, BWN_SHARED, 0x088);
5524 
5525 	return (val);
5526 }
5527 
5528 static void
bwn_noise_gensample(struct bwn_mac * mac)5529 bwn_noise_gensample(struct bwn_mac *mac)
5530 {
5531 	uint32_t jssi = 0x7f7f7f7f;
5532 
5533 	bwn_shm_write_2(mac, BWN_SHARED, 0x088, (jssi & 0x0000ffff));
5534 	bwn_shm_write_2(mac, BWN_SHARED, 0x08a, (jssi & 0xffff0000) >> 16);
5535 	BWN_WRITE_4(mac, BWN_MACCMD,
5536 	    BWN_READ_4(mac, BWN_MACCMD) | BWN_MACCMD_BGNOISE);
5537 }
5538 
5539 static int
bwn_dma_freeslot(struct bwn_dma_ring * dr)5540 bwn_dma_freeslot(struct bwn_dma_ring *dr)
5541 {
5542 	BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
5543 
5544 	return (dr->dr_numslots - dr->dr_usedslot);
5545 }
5546 
5547 static int
bwn_dma_nextslot(struct bwn_dma_ring * dr,int slot)5548 bwn_dma_nextslot(struct bwn_dma_ring *dr, int slot)
5549 {
5550 	BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
5551 
5552 	KASSERT(slot >= -1 && slot <= dr->dr_numslots - 1,
5553 	    ("%s:%d: fail", __func__, __LINE__));
5554 	if (slot == dr->dr_numslots - 1)
5555 		return (0);
5556 	return (slot + 1);
5557 }
5558 
5559 static void
bwn_dma_rxeof(struct bwn_dma_ring * dr,int * slot)5560 bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
5561 {
5562 	struct bwn_mac *mac = dr->dr_mac;
5563 	struct bwn_softc *sc = mac->mac_sc;
5564 	struct bwn_dma *dma = &mac->mac_method.dma;
5565 	struct bwn_dmadesc_generic *desc;
5566 	struct bwn_dmadesc_meta *meta;
5567 	struct bwn_rxhdr4 *rxhdr;
5568 	struct mbuf *m;
5569 	uint32_t macstat;
5570 	int32_t tmp;
5571 	int cnt = 0;
5572 	uint16_t len;
5573 
5574 	dr->getdesc(dr, *slot, &desc, &meta);
5575 
5576 	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap, BUS_DMASYNC_POSTREAD);
5577 	m = meta->mt_m;
5578 
5579 	if (bwn_dma_newbuf(dr, desc, meta, 0)) {
5580 		counter_u64_add(sc->sc_ic.ic_ierrors, 1);
5581 		return;
5582 	}
5583 
5584 	rxhdr = mtod(m, struct bwn_rxhdr4 *);
5585 	len = le16toh(rxhdr->frame_len);
5586 	if (len <= 0) {
5587 		counter_u64_add(sc->sc_ic.ic_ierrors, 1);
5588 		return;
5589 	}
5590 	if (bwn_dma_check_redzone(dr, m)) {
5591 		device_printf(sc->sc_dev, "redzone error.\n");
5592 		bwn_dma_set_redzone(dr, m);
5593 		bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
5594 		    BUS_DMASYNC_PREWRITE);
5595 		return;
5596 	}
5597 	if (len > dr->dr_rx_bufsize) {
5598 		tmp = len;
5599 		while (1) {
5600 			dr->getdesc(dr, *slot, &desc, &meta);
5601 			bwn_dma_set_redzone(dr, meta->mt_m);
5602 			bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
5603 			    BUS_DMASYNC_PREWRITE);
5604 			*slot = bwn_dma_nextslot(dr, *slot);
5605 			cnt++;
5606 			tmp -= dr->dr_rx_bufsize;
5607 			if (tmp <= 0)
5608 				break;
5609 		}
5610 		device_printf(sc->sc_dev, "too small buffer "
5611 		       "(len %u buffer %u dropped %d)\n",
5612 		       len, dr->dr_rx_bufsize, cnt);
5613 		return;
5614 	}
5615 
5616 	switch (mac->mac_fw.fw_hdr_format) {
5617 	case BWN_FW_HDR_351:
5618 	case BWN_FW_HDR_410:
5619 		macstat = le32toh(rxhdr->ps4.r351.mac_status);
5620 		break;
5621 	case BWN_FW_HDR_598:
5622 		macstat = le32toh(rxhdr->ps4.r598.mac_status);
5623 		break;
5624 	}
5625 
5626 	if (macstat & BWN_RX_MAC_FCSERR) {
5627 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
5628 			device_printf(sc->sc_dev, "RX drop\n");
5629 			return;
5630 		}
5631 	}
5632 
5633 	m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
5634 	m_adj(m, dr->dr_frameoffset);
5635 
5636 	bwn_rxeof(dr->dr_mac, m, rxhdr);
5637 }
5638 
5639 static void
bwn_handle_txeof(struct bwn_mac * mac,const struct bwn_txstatus * status)5640 bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
5641 {
5642 	struct bwn_softc *sc = mac->mac_sc;
5643 	struct bwn_stats *stats = &mac->mac_stats;
5644 
5645 	BWN_ASSERT_LOCKED(mac->mac_sc);
5646 
5647 	if (status->im)
5648 		device_printf(sc->sc_dev, "TODO: STATUS IM\n");
5649 	if (status->ampdu)
5650 		device_printf(sc->sc_dev, "TODO: STATUS AMPDU\n");
5651 	if (status->rtscnt) {
5652 		if (status->rtscnt == 0xf)
5653 			stats->rtsfail++;
5654 		else
5655 			stats->rts++;
5656 	}
5657 
5658 	if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
5659 		bwn_dma_handle_txeof(mac, status);
5660 	} else {
5661 		bwn_pio_handle_txeof(mac, status);
5662 	}
5663 
5664 	bwn_phy_txpower_check(mac, 0);
5665 }
5666 
5667 static uint8_t
bwn_pio_rxeof(struct bwn_pio_rxqueue * prq)5668 bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
5669 {
5670 	struct bwn_mac *mac = prq->prq_mac;
5671 	struct bwn_softc *sc = mac->mac_sc;
5672 	struct bwn_rxhdr4 rxhdr;
5673 	struct mbuf *m;
5674 	uint32_t ctl32, macstat, v32;
5675 	unsigned int i, padding;
5676 	uint16_t ctl16, len, totlen, v16;
5677 	unsigned char *mp;
5678 	char *data;
5679 
5680 	memset(&rxhdr, 0, sizeof(rxhdr));
5681 
5682 	if (prq->prq_rev >= 8) {
5683 		ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
5684 		if (!(ctl32 & BWN_PIO8_RXCTL_FRAMEREADY))
5685 			return (0);
5686 		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
5687 		    BWN_PIO8_RXCTL_FRAMEREADY);
5688 		for (i = 0; i < 10; i++) {
5689 			ctl32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXCTL);
5690 			if (ctl32 & BWN_PIO8_RXCTL_DATAREADY)
5691 				goto ready;
5692 			DELAY(10);
5693 		}
5694 	} else {
5695 		ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
5696 		if (!(ctl16 & BWN_PIO_RXCTL_FRAMEREADY))
5697 			return (0);
5698 		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL,
5699 		    BWN_PIO_RXCTL_FRAMEREADY);
5700 		for (i = 0; i < 10; i++) {
5701 			ctl16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXCTL);
5702 			if (ctl16 & BWN_PIO_RXCTL_DATAREADY)
5703 				goto ready;
5704 			DELAY(10);
5705 		}
5706 	}
5707 	device_printf(sc->sc_dev, "%s: timed out\n", __func__);
5708 	return (1);
5709 ready:
5710 	if (prq->prq_rev >= 8) {
5711 		bus_read_multi_4(sc->sc_mem_res,
5712 		    prq->prq_base + BWN_PIO8_RXDATA, (void *)&rxhdr,
5713 		    sizeof(rxhdr));
5714 	} else {
5715 		bus_read_multi_2(sc->sc_mem_res,
5716 		    prq->prq_base + BWN_PIO_RXDATA, (void *)&rxhdr,
5717 		    sizeof(rxhdr));
5718 	}
5719 	len = le16toh(rxhdr.frame_len);
5720 	if (len > 0x700) {
5721 		device_printf(sc->sc_dev, "%s: len is too big\n", __func__);
5722 		goto error;
5723 	}
5724 	if (len == 0) {
5725 		device_printf(sc->sc_dev, "%s: len is 0\n", __func__);
5726 		goto error;
5727 	}
5728 
5729 	switch (mac->mac_fw.fw_hdr_format) {
5730 	case BWN_FW_HDR_351:
5731 	case BWN_FW_HDR_410:
5732 		macstat = le32toh(rxhdr.ps4.r351.mac_status);
5733 		break;
5734 	case BWN_FW_HDR_598:
5735 		macstat = le32toh(rxhdr.ps4.r598.mac_status);
5736 		break;
5737 	}
5738 
5739 	if (macstat & BWN_RX_MAC_FCSERR) {
5740 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
5741 			device_printf(sc->sc_dev, "%s: FCS error", __func__);
5742 			goto error;
5743 		}
5744 	}
5745 
5746 	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
5747 	totlen = len + padding;
5748 	KASSERT(totlen <= MCLBYTES, ("too big..\n"));
5749 	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
5750 	if (m == NULL) {
5751 		device_printf(sc->sc_dev, "%s: out of memory", __func__);
5752 		goto error;
5753 	}
5754 	mp = mtod(m, unsigned char *);
5755 	if (prq->prq_rev >= 8) {
5756 		bus_read_multi_4(sc->sc_mem_res,
5757 		    prq->prq_base + BWN_PIO8_RXDATA, (void *)mp, (totlen & ~3));
5758 		if (totlen & 3) {
5759 			v32 = bwn_pio_rx_read_4(prq, BWN_PIO8_RXDATA);
5760 			data = &(mp[totlen - 1]);
5761 			switch (totlen & 3) {
5762 			case 3:
5763 				*data = (v32 >> 16);
5764 				data--;
5765 			case 2:
5766 				*data = (v32 >> 8);
5767 				data--;
5768 			case 1:
5769 				*data = v32;
5770 			}
5771 		}
5772 	} else {
5773 		bus_read_multi_2(sc->sc_mem_res,
5774 		    prq->prq_base + BWN_PIO_RXDATA, (void *)mp, (totlen & ~1));
5775 		if (totlen & 1) {
5776 			v16 = bwn_pio_rx_read_2(prq, BWN_PIO_RXDATA);
5777 			mp[totlen - 1] = v16;
5778 		}
5779 	}
5780 
5781 	m->m_len = m->m_pkthdr.len = totlen;
5782 
5783 	bwn_rxeof(prq->prq_mac, m, &rxhdr);
5784 
5785 	return (1);
5786 error:
5787 	if (prq->prq_rev >= 8)
5788 		bwn_pio_rx_write_4(prq, BWN_PIO8_RXCTL,
5789 		    BWN_PIO8_RXCTL_DATAREADY);
5790 	else
5791 		bwn_pio_rx_write_2(prq, BWN_PIO_RXCTL, BWN_PIO_RXCTL_DATAREADY);
5792 	return (1);
5793 }
5794 
5795 static int
bwn_dma_newbuf(struct bwn_dma_ring * dr,struct bwn_dmadesc_generic * desc,struct bwn_dmadesc_meta * meta,int init)5796 bwn_dma_newbuf(struct bwn_dma_ring *dr, struct bwn_dmadesc_generic *desc,
5797     struct bwn_dmadesc_meta *meta, int init)
5798 {
5799 	struct bwn_mac *mac = dr->dr_mac;
5800 	struct bwn_dma *dma = &mac->mac_method.dma;
5801 	struct bwn_rxhdr4 *hdr;
5802 	bus_dmamap_t map;
5803 	bus_addr_t paddr;
5804 	struct mbuf *m;
5805 	int error;
5806 
5807 	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
5808 	if (m == NULL) {
5809 		error = ENOBUFS;
5810 
5811 		/*
5812 		 * If the NIC is up and running, we need to:
5813 		 * - Clear RX buffer's header.
5814 		 * - Restore RX descriptor settings.
5815 		 */
5816 		if (init)
5817 			return (error);
5818 		else
5819 			goto back;
5820 	}
5821 	m->m_len = m->m_pkthdr.len = MCLBYTES;
5822 
5823 	bwn_dma_set_redzone(dr, m);
5824 
5825 	/*
5826 	 * Try to load RX buf into temporary DMA map
5827 	 */
5828 	error = bus_dmamap_load_mbuf(dma->rxbuf_dtag, dr->dr_spare_dmap, m,
5829 	    bwn_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
5830 	if (error) {
5831 		m_freem(m);
5832 
5833 		/*
5834 		 * See the comment above
5835 		 */
5836 		if (init)
5837 			return (error);
5838 		else
5839 			goto back;
5840 	}
5841 
5842 	if (!init)
5843 		bus_dmamap_unload(dma->rxbuf_dtag, meta->mt_dmap);
5844 	meta->mt_m = m;
5845 	meta->mt_paddr = paddr;
5846 
5847 	/*
5848 	 * Swap RX buf's DMA map with the loaded temporary one
5849 	 */
5850 	map = meta->mt_dmap;
5851 	meta->mt_dmap = dr->dr_spare_dmap;
5852 	dr->dr_spare_dmap = map;
5853 
5854 back:
5855 	/*
5856 	 * Clear RX buf header
5857 	 */
5858 	hdr = mtod(meta->mt_m, struct bwn_rxhdr4 *);
5859 	bzero(hdr, sizeof(*hdr));
5860 	bus_dmamap_sync(dma->rxbuf_dtag, meta->mt_dmap,
5861 	    BUS_DMASYNC_PREWRITE);
5862 
5863 	/*
5864 	 * Setup RX buf descriptor
5865 	 */
5866 	dr->setdesc(dr, desc, meta->mt_paddr, meta->mt_m->m_len -
5867 	    sizeof(*hdr), 0, 0, 0);
5868 	return (error);
5869 }
5870 
5871 static void
bwn_dma_buf_addr(void * arg,bus_dma_segment_t * seg,int nseg,bus_size_t mapsz __unused,int error)5872 bwn_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
5873 		 bus_size_t mapsz __unused, int error)
5874 {
5875 
5876 	if (!error) {
5877 		KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
5878 		*((bus_addr_t *)arg) = seg->ds_addr;
5879 	}
5880 }
5881 
5882 static int
bwn_hwrate2ieeerate(int rate)5883 bwn_hwrate2ieeerate(int rate)
5884 {
5885 
5886 	switch (rate) {
5887 	case BWN_CCK_RATE_1MB:
5888 		return (2);
5889 	case BWN_CCK_RATE_2MB:
5890 		return (4);
5891 	case BWN_CCK_RATE_5MB:
5892 		return (11);
5893 	case BWN_CCK_RATE_11MB:
5894 		return (22);
5895 	case BWN_OFDM_RATE_6MB:
5896 		return (12);
5897 	case BWN_OFDM_RATE_9MB:
5898 		return (18);
5899 	case BWN_OFDM_RATE_12MB:
5900 		return (24);
5901 	case BWN_OFDM_RATE_18MB:
5902 		return (36);
5903 	case BWN_OFDM_RATE_24MB:
5904 		return (48);
5905 	case BWN_OFDM_RATE_36MB:
5906 		return (72);
5907 	case BWN_OFDM_RATE_48MB:
5908 		return (96);
5909 	case BWN_OFDM_RATE_54MB:
5910 		return (108);
5911 	default:
5912 		printf("Ooops\n");
5913 		return (0);
5914 	}
5915 }
5916 
5917 /*
5918  * Post process the RX provided RSSI.
5919  *
5920  * Valid for A, B, G, LP PHYs.
5921  */
5922 static int8_t
bwn_rx_rssi_calc(struct bwn_mac * mac,uint8_t in_rssi,int ofdm,int adjust_2053,int adjust_2050)5923 bwn_rx_rssi_calc(struct bwn_mac *mac, uint8_t in_rssi,
5924     int ofdm, int adjust_2053, int adjust_2050)
5925 {
5926 	struct bwn_phy *phy = &mac->mac_phy;
5927 	struct bwn_phy_g *gphy = &phy->phy_g;
5928 	int tmp;
5929 
5930 	switch (phy->rf_ver) {
5931 	case 0x2050:
5932 		if (ofdm) {
5933 			tmp = in_rssi;
5934 			if (tmp > 127)
5935 				tmp -= 256;
5936 			tmp = tmp * 73 / 64;
5937 			if (adjust_2050)
5938 				tmp += 25;
5939 			else
5940 				tmp -= 3;
5941 		} else {
5942 			if (mac->mac_sc->sc_board_info.board_flags
5943 			    & BHND_BFL_ADCDIV) {
5944 				if (in_rssi > 63)
5945 					in_rssi = 63;
5946 				tmp = gphy->pg_nrssi_lt[in_rssi];
5947 				tmp = (31 - tmp) * -131 / 128 - 57;
5948 			} else {
5949 				tmp = in_rssi;
5950 				tmp = (31 - tmp) * -149 / 128 - 68;
5951 			}
5952 			if (phy->type == BWN_PHYTYPE_G && adjust_2050)
5953 				tmp += 25;
5954 		}
5955 		break;
5956 	case 0x2060:
5957 		if (in_rssi > 127)
5958 			tmp = in_rssi - 256;
5959 		else
5960 			tmp = in_rssi;
5961 		break;
5962 	default:
5963 		tmp = in_rssi;
5964 		tmp = (tmp - 11) * 103 / 64;
5965 		if (adjust_2053)
5966 			tmp -= 109;
5967 		else
5968 			tmp -= 83;
5969 	}
5970 
5971 	return (tmp);
5972 }
5973 
5974 static void
bwn_rxeof(struct bwn_mac * mac,struct mbuf * m,const void * _rxhdr)5975 bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
5976 {
5977 	const struct bwn_rxhdr4 *rxhdr = _rxhdr;
5978 	struct bwn_plcp6 *plcp;
5979 	struct bwn_softc *sc = mac->mac_sc;
5980 	struct ieee80211_frame_min *wh;
5981 	struct ieee80211_node *ni;
5982 	struct ieee80211com *ic = &sc->sc_ic;
5983 	uint32_t macstat;
5984 	int padding, rate, rssi = 0, noise = 0;
5985 	uint16_t phytype, phystat0, phystat3, chanstat;
5986 	unsigned char *mp = mtod(m, unsigned char *);
5987 
5988 	BWN_ASSERT_LOCKED(sc);
5989 
5990 	phystat0 = le16toh(rxhdr->phy_status0);
5991 
5992 	/*
5993 	 * XXX Note: phy_status3 doesn't exist for HT-PHY; it's only
5994 	 * used for LP-PHY.
5995 	 */
5996 	phystat3 = le16toh(rxhdr->ps3.lp.phy_status3);
5997 
5998 	switch (mac->mac_fw.fw_hdr_format) {
5999 	case BWN_FW_HDR_351:
6000 	case BWN_FW_HDR_410:
6001 		macstat = le32toh(rxhdr->ps4.r351.mac_status);
6002 		chanstat = le16toh(rxhdr->ps4.r351.channel);
6003 		break;
6004 	case BWN_FW_HDR_598:
6005 		macstat = le32toh(rxhdr->ps4.r598.mac_status);
6006 		chanstat = le16toh(rxhdr->ps4.r598.channel);
6007 		break;
6008 	}
6009 
6010 	phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
6011 
6012 	if (macstat & BWN_RX_MAC_FCSERR)
6013 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_FCS_CRC\n");
6014 	if (phystat0 & (BWN_RX_PHYST0_PLCPHCF | BWN_RX_PHYST0_PLCPFV))
6015 		device_printf(sc->sc_dev, "TODO RX: RX_FLAG_FAILED_PLCP_CRC\n");
6016 	if (macstat & BWN_RX_MAC_DECERR)
6017 		goto drop;
6018 
6019 	padding = (macstat & BWN_RX_MAC_PADDING) ? 2 : 0;
6020 	if (m->m_pkthdr.len < (sizeof(struct bwn_plcp6) + padding)) {
6021 		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
6022 		    m->m_pkthdr.len);
6023 		goto drop;
6024 	}
6025 	plcp = (struct bwn_plcp6 *)(mp + padding);
6026 	m_adj(m, sizeof(struct bwn_plcp6) + padding);
6027 	if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
6028 		device_printf(sc->sc_dev, "frame too short (length=%d)\n",
6029 		    m->m_pkthdr.len);
6030 		goto drop;
6031 	}
6032 	wh = mtod(m, struct ieee80211_frame_min *);
6033 
6034 	if (macstat & BWN_RX_MAC_DEC) {
6035 		DPRINTF(sc, BWN_DEBUG_HWCRYPTO,
6036 		    "RX decryption attempted (old %d keyidx %#x)\n",
6037 		    BWN_ISOLDFMT(mac),
6038 		    (macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
6039 	}
6040 
6041 	if (phystat0 & BWN_RX_PHYST0_OFDM)
6042 		rate = bwn_plcp_get_ofdmrate(mac, plcp,
6043 		    phytype == BWN_PHYTYPE_A);
6044 	else
6045 		rate = bwn_plcp_get_cckrate(mac, plcp);
6046 	if (rate == -1) {
6047 		if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADPLCP))
6048 			goto drop;
6049 	}
6050 	sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
6051 
6052 	/* rssi/noise */
6053 	switch (phytype) {
6054 	case BWN_PHYTYPE_A:
6055 	case BWN_PHYTYPE_B:
6056 	case BWN_PHYTYPE_G:
6057 	case BWN_PHYTYPE_LP:
6058 		rssi = bwn_rx_rssi_calc(mac, rxhdr->phy.abg.rssi,
6059 		    !! (phystat0 & BWN_RX_PHYST0_OFDM),
6060 		    !! (phystat0 & BWN_RX_PHYST0_GAINCTL),
6061 		    !! (phystat3 & BWN_RX_PHYST3_TRSTATE));
6062 		break;
6063 	case BWN_PHYTYPE_N:
6064 		/* Broadcom has code for min/avg, but always used max */
6065 		if (rxhdr->phy.n.power0 == 16 || rxhdr->phy.n.power0 == 32)
6066 			rssi = max(rxhdr->phy.n.power1, rxhdr->ps2.n.power2);
6067 		else
6068 			rssi = max(rxhdr->phy.n.power0, rxhdr->phy.n.power1);
6069 #if 0
6070 		DPRINTF(mac->mac_sc, BWN_DEBUG_RECV,
6071 		    "%s: power0=%d, power1=%d, power2=%d\n",
6072 		    __func__,
6073 		    rxhdr->phy.n.power0,
6074 		    rxhdr->phy.n.power1,
6075 		    rxhdr->ps2.n.power2);
6076 #endif
6077 		break;
6078 	default:
6079 		/* XXX TODO: implement rssi for other PHYs */
6080 		break;
6081 	}
6082 
6083 	/*
6084 	 * RSSI here is absolute, not relative to the noise floor.
6085 	 */
6086 	noise = mac->mac_stats.link_noise;
6087 	rssi = rssi - noise;
6088 
6089 	/* RX radio tap */
6090 	if (ieee80211_radiotap_active(ic))
6091 		bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
6092 	m_adj(m, -IEEE80211_CRC_LEN);
6093 
6094 	BWN_UNLOCK(sc);
6095 
6096 	ni = ieee80211_find_rxnode(ic, wh);
6097 	if (ni != NULL) {
6098 		ieee80211_input(ni, m, rssi, noise);
6099 		ieee80211_free_node(ni);
6100 	} else
6101 		ieee80211_input_all(ic, m, rssi, noise);
6102 
6103 	BWN_LOCK(sc);
6104 	return;
6105 drop:
6106 	device_printf(sc->sc_dev, "%s: dropped\n", __func__);
6107 }
6108 
6109 static void
bwn_ratectl_tx_complete(const struct ieee80211_node * ni,const struct bwn_txstatus * status)6110 bwn_ratectl_tx_complete(const struct ieee80211_node *ni,
6111     const struct bwn_txstatus *status)
6112 {
6113 	struct ieee80211_ratectl_tx_status txs;
6114 	int retrycnt = 0;
6115 
6116 	/*
6117 	 * If we don't get an ACK, then we should log the
6118 	 * full framecnt.  That may be 0 if it's a PHY
6119 	 * failure, so ensure that gets logged as some
6120 	 * retry attempt.
6121 	 */
6122 	txs.flags = IEEE80211_RATECTL_STATUS_LONG_RETRY;
6123 	if (status->ack) {
6124 		txs.status = IEEE80211_RATECTL_TX_SUCCESS;
6125 		retrycnt = status->framecnt - 1;
6126 	} else {
6127 		txs.status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED;
6128 		retrycnt = status->framecnt;
6129 		if (retrycnt == 0)
6130 			retrycnt = 1;
6131 	}
6132 	txs.long_retries = retrycnt;
6133 	ieee80211_ratectl_tx_complete(ni, &txs);
6134 }
6135 
6136 static void
bwn_dma_handle_txeof(struct bwn_mac * mac,const struct bwn_txstatus * status)6137 bwn_dma_handle_txeof(struct bwn_mac *mac,
6138     const struct bwn_txstatus *status)
6139 {
6140 	struct bwn_dma *dma = &mac->mac_method.dma;
6141 	struct bwn_dma_ring *dr;
6142 	struct bwn_dmadesc_generic *desc;
6143 	struct bwn_dmadesc_meta *meta;
6144 	struct bwn_softc *sc = mac->mac_sc;
6145 	int slot;
6146 
6147 	BWN_ASSERT_LOCKED(sc);
6148 
6149 	dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
6150 	if (dr == NULL) {
6151 		device_printf(sc->sc_dev, "failed to parse cookie\n");
6152 		return;
6153 	}
6154 	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
6155 
6156 	while (1) {
6157 		KASSERT(slot >= 0 && slot < dr->dr_numslots,
6158 		    ("%s:%d: fail", __func__, __LINE__));
6159 		dr->getdesc(dr, slot, &desc, &meta);
6160 
6161 		if (meta->mt_txtype == BWN_DMADESC_METATYPE_HEADER)
6162 			bus_dmamap_unload(dr->dr_txring_dtag, meta->mt_dmap);
6163 		else if (meta->mt_txtype == BWN_DMADESC_METATYPE_BODY)
6164 			bus_dmamap_unload(dma->txbuf_dtag, meta->mt_dmap);
6165 
6166 		if (meta->mt_islast) {
6167 			KASSERT(meta->mt_m != NULL,
6168 			    ("%s:%d: fail", __func__, __LINE__));
6169 
6170 			bwn_ratectl_tx_complete(meta->mt_ni, status);
6171 			ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0);
6172 			meta->mt_ni = NULL;
6173 			meta->mt_m = NULL;
6174 		} else
6175 			KASSERT(meta->mt_m == NULL,
6176 			    ("%s:%d: fail", __func__, __LINE__));
6177 
6178 		dr->dr_usedslot--;
6179 		if (meta->mt_islast)
6180 			break;
6181 		slot = bwn_dma_nextslot(dr, slot);
6182 	}
6183 	sc->sc_watchdog_timer = 0;
6184 	if (dr->dr_stop) {
6185 		KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
6186 		    ("%s:%d: fail", __func__, __LINE__));
6187 		dr->dr_stop = 0;
6188 	}
6189 }
6190 
6191 static void
bwn_pio_handle_txeof(struct bwn_mac * mac,const struct bwn_txstatus * status)6192 bwn_pio_handle_txeof(struct bwn_mac *mac,
6193     const struct bwn_txstatus *status)
6194 {
6195 	struct bwn_pio_txqueue *tq;
6196 	struct bwn_pio_txpkt *tp = NULL;
6197 	struct bwn_softc *sc = mac->mac_sc;
6198 
6199 	BWN_ASSERT_LOCKED(sc);
6200 
6201 	tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
6202 	if (tq == NULL)
6203 		return;
6204 
6205 	tq->tq_used -= roundup(tp->tp_m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
6206 	tq->tq_free++;
6207 
6208 	if (tp->tp_ni != NULL) {
6209 		/*
6210 		 * Do any tx complete callback.  Note this must
6211 		 * be done before releasing the node reference.
6212 		 */
6213 		bwn_ratectl_tx_complete(tp->tp_ni, status);
6214 	}
6215 	ieee80211_tx_complete(tp->tp_ni, tp->tp_m, 0);
6216 	tp->tp_ni = NULL;
6217 	tp->tp_m = NULL;
6218 	TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
6219 
6220 	sc->sc_watchdog_timer = 0;
6221 }
6222 
6223 static void
bwn_phy_txpower_check(struct bwn_mac * mac,uint32_t flags)6224 bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
6225 {
6226 	struct bwn_softc *sc = mac->mac_sc;
6227 	struct bwn_phy *phy = &mac->mac_phy;
6228 	struct ieee80211com *ic = &sc->sc_ic;
6229 	unsigned long now;
6230 	bwn_txpwr_result_t result;
6231 
6232 	BWN_GETTIME(now);
6233 
6234 	if (!(flags & BWN_TXPWR_IGNORE_TIME) && ieee80211_time_before(now, phy->nexttime))
6235 		return;
6236 	phy->nexttime = now + 2 * 1000;
6237 
6238 	if (sc->sc_board_info.board_vendor == PCI_VENDOR_BROADCOM &&
6239 	    sc->sc_board_info.board_type == BHND_BOARD_BU4306)
6240 		return;
6241 
6242 	if (phy->recalc_txpwr != NULL) {
6243 		result = phy->recalc_txpwr(mac,
6244 		    (flags & BWN_TXPWR_IGNORE_TSSI) ? 1 : 0);
6245 		if (result == BWN_TXPWR_RES_DONE)
6246 			return;
6247 		KASSERT(result == BWN_TXPWR_RES_NEED_ADJUST,
6248 		    ("%s: fail", __func__));
6249 		KASSERT(phy->set_txpwr != NULL, ("%s: fail", __func__));
6250 
6251 		ieee80211_runtask(ic, &mac->mac_txpower);
6252 	}
6253 }
6254 
6255 static uint16_t
bwn_pio_rx_read_2(struct bwn_pio_rxqueue * prq,uint16_t offset)6256 bwn_pio_rx_read_2(struct bwn_pio_rxqueue *prq, uint16_t offset)
6257 {
6258 
6259 	return (BWN_READ_2(prq->prq_mac, prq->prq_base + offset));
6260 }
6261 
6262 static uint32_t
bwn_pio_rx_read_4(struct bwn_pio_rxqueue * prq,uint16_t offset)6263 bwn_pio_rx_read_4(struct bwn_pio_rxqueue *prq, uint16_t offset)
6264 {
6265 
6266 	return (BWN_READ_4(prq->prq_mac, prq->prq_base + offset));
6267 }
6268 
6269 static void
bwn_pio_rx_write_2(struct bwn_pio_rxqueue * prq,uint16_t offset,uint16_t value)6270 bwn_pio_rx_write_2(struct bwn_pio_rxqueue *prq, uint16_t offset, uint16_t value)
6271 {
6272 
6273 	BWN_WRITE_2(prq->prq_mac, prq->prq_base + offset, value);
6274 }
6275 
6276 static void
bwn_pio_rx_write_4(struct bwn_pio_rxqueue * prq,uint16_t offset,uint32_t value)6277 bwn_pio_rx_write_4(struct bwn_pio_rxqueue *prq, uint16_t offset, uint32_t value)
6278 {
6279 
6280 	BWN_WRITE_4(prq->prq_mac, prq->prq_base + offset, value);
6281 }
6282 
6283 static int
bwn_ieeerate2hwrate(struct bwn_softc * sc,int rate)6284 bwn_ieeerate2hwrate(struct bwn_softc *sc, int rate)
6285 {
6286 
6287 	switch (rate) {
6288 	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
6289 	case 12:
6290 		return (BWN_OFDM_RATE_6MB);
6291 	case 18:
6292 		return (BWN_OFDM_RATE_9MB);
6293 	case 24:
6294 		return (BWN_OFDM_RATE_12MB);
6295 	case 36:
6296 		return (BWN_OFDM_RATE_18MB);
6297 	case 48:
6298 		return (BWN_OFDM_RATE_24MB);
6299 	case 72:
6300 		return (BWN_OFDM_RATE_36MB);
6301 	case 96:
6302 		return (BWN_OFDM_RATE_48MB);
6303 	case 108:
6304 		return (BWN_OFDM_RATE_54MB);
6305 	/* CCK rates (NB: not IEEE std, device-specific) */
6306 	case 2:
6307 		return (BWN_CCK_RATE_1MB);
6308 	case 4:
6309 		return (BWN_CCK_RATE_2MB);
6310 	case 11:
6311 		return (BWN_CCK_RATE_5MB);
6312 	case 22:
6313 		return (BWN_CCK_RATE_11MB);
6314 	}
6315 
6316 	device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
6317 	return (BWN_CCK_RATE_1MB);
6318 }
6319 
6320 static uint16_t
bwn_set_txhdr_phyctl1(struct bwn_mac * mac,uint8_t bitrate)6321 bwn_set_txhdr_phyctl1(struct bwn_mac *mac, uint8_t bitrate)
6322 {
6323 	struct bwn_phy *phy = &mac->mac_phy;
6324 	uint16_t control = 0;
6325 	uint16_t bw;
6326 
6327 	/* XXX TODO: this is for LP phy, what about N-PHY, etc? */
6328 	bw = BWN_TXH_PHY1_BW_20;
6329 
6330 	if (BWN_ISCCKRATE(bitrate) && phy->type != BWN_PHYTYPE_LP) {
6331 		control = bw;
6332 	} else {
6333 		control = bw;
6334 		/* Figure out coding rate and modulation */
6335 		/* XXX TODO: table-ize, for MCS transmit */
6336 		/* Note: this is BWN_*_RATE values */
6337 		switch (bitrate) {
6338 		case BWN_CCK_RATE_1MB:
6339 			control |= 0;
6340 			break;
6341 		case BWN_CCK_RATE_2MB:
6342 			control |= 1;
6343 			break;
6344 		case BWN_CCK_RATE_5MB:
6345 			control |= 2;
6346 			break;
6347 		case BWN_CCK_RATE_11MB:
6348 			control |= 3;
6349 			break;
6350 		case BWN_OFDM_RATE_6MB:
6351 			control |= BWN_TXH_PHY1_CRATE_1_2;
6352 			control |= BWN_TXH_PHY1_MODUL_BPSK;
6353 			break;
6354 		case BWN_OFDM_RATE_9MB:
6355 			control |= BWN_TXH_PHY1_CRATE_3_4;
6356 			control |= BWN_TXH_PHY1_MODUL_BPSK;
6357 			break;
6358 		case BWN_OFDM_RATE_12MB:
6359 			control |= BWN_TXH_PHY1_CRATE_1_2;
6360 			control |= BWN_TXH_PHY1_MODUL_QPSK;
6361 			break;
6362 		case BWN_OFDM_RATE_18MB:
6363 			control |= BWN_TXH_PHY1_CRATE_3_4;
6364 			control |= BWN_TXH_PHY1_MODUL_QPSK;
6365 			break;
6366 		case BWN_OFDM_RATE_24MB:
6367 			control |= BWN_TXH_PHY1_CRATE_1_2;
6368 			control |= BWN_TXH_PHY1_MODUL_QAM16;
6369 			break;
6370 		case BWN_OFDM_RATE_36MB:
6371 			control |= BWN_TXH_PHY1_CRATE_3_4;
6372 			control |= BWN_TXH_PHY1_MODUL_QAM16;
6373 			break;
6374 		case BWN_OFDM_RATE_48MB:
6375 			control |= BWN_TXH_PHY1_CRATE_1_2;
6376 			control |= BWN_TXH_PHY1_MODUL_QAM64;
6377 			break;
6378 		case BWN_OFDM_RATE_54MB:
6379 			control |= BWN_TXH_PHY1_CRATE_3_4;
6380 			control |= BWN_TXH_PHY1_MODUL_QAM64;
6381 			break;
6382 		default:
6383 			break;
6384 		}
6385 		control |= BWN_TXH_PHY1_MODE_SISO;
6386 	}
6387 
6388 	return control;
6389 }
6390 
6391 static int
bwn_set_txhdr(struct bwn_mac * mac,struct ieee80211_node * ni,struct mbuf * m,struct bwn_txhdr * txhdr,uint16_t cookie)6392 bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
6393     struct mbuf *m, struct bwn_txhdr *txhdr, uint16_t cookie)
6394 {
6395 	const struct bwn_phy *phy = &mac->mac_phy;
6396 	struct bwn_softc *sc = mac->mac_sc;
6397 	struct ieee80211_frame *wh;
6398 	struct ieee80211_frame *protwh;
6399 	const struct ieee80211_txparam *tp = ni->ni_txparms;
6400 	struct ieee80211vap *vap = ni->ni_vap;
6401 	struct ieee80211com *ic = &sc->sc_ic;
6402 	struct mbuf *mprot;
6403 	uint8_t *prot_ptr;
6404 	unsigned int len;
6405 	uint32_t macctl = 0;
6406 	int rts_rate, rts_rate_fb, ismcast, isshort, type;
6407 	uint16_t phyctl = 0;
6408 	uint8_t rate, rate_fb;
6409 	int fill_phy_ctl1 = 0;
6410 
6411 	wh = mtod(m, struct ieee80211_frame *);
6412 	memset(txhdr, 0, sizeof(*txhdr));
6413 
6414 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
6415 	ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
6416 	isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
6417 
6418 	if ((phy->type == BWN_PHYTYPE_N) || (phy->type == BWN_PHYTYPE_LP)
6419 	    || (phy->type == BWN_PHYTYPE_HT))
6420 		fill_phy_ctl1 = 1;
6421 
6422 	/*
6423 	 * Find TX rate
6424 	 */
6425 	if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL))
6426 		rate = rate_fb = tp->mgmtrate;
6427 	else if (ismcast)
6428 		rate = rate_fb = tp->mcastrate;
6429 	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
6430 		rate = rate_fb = tp->ucastrate;
6431 	else {
6432 		ieee80211_ratectl_rate(ni, NULL, 0);
6433 		rate = ieee80211_node_get_txrate_dot11rate(ni);
6434 		/* TODO: assign rate_fb the previous rate, if available */
6435 		rate_fb = rate;
6436 	}
6437 
6438 	sc->sc_tx_rate = rate;
6439 
6440 	/* Note: this maps the select ieee80211 rate to hardware rate */
6441 	rate = bwn_ieeerate2hwrate(sc, rate);
6442 	rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
6443 
6444 	txhdr->phyrate = (BWN_ISOFDMRATE(rate)) ? bwn_plcp_getofdm(rate) :
6445 	    bwn_plcp_getcck(rate);
6446 	bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
6447 	bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
6448 
6449 	/* XXX rate/rate_fb is the hardware rate */
6450 	if ((rate_fb == rate) ||
6451 	    (*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
6452 	    (*(u_int16_t *)wh->i_dur == htole16(0)))
6453 		txhdr->dur_fb = *(u_int16_t *)wh->i_dur;
6454 	else
6455 		txhdr->dur_fb = ieee80211_compute_duration(ic->ic_rt,
6456 		    m->m_pkthdr.len, rate, isshort);
6457 
6458 	/* XXX TX encryption */
6459 
6460 	switch (mac->mac_fw.fw_hdr_format) {
6461 	case BWN_FW_HDR_351:
6462 		bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->body.r351.plcp),
6463 		    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
6464 		break;
6465 	case BWN_FW_HDR_410:
6466 		bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->body.r410.plcp),
6467 		    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
6468 		break;
6469 	case BWN_FW_HDR_598:
6470 		bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->body.r598.plcp),
6471 		    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
6472 		break;
6473 	}
6474 
6475 	bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
6476 	    m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
6477 
6478 	txhdr->eftypes |= (BWN_ISOFDMRATE(rate_fb)) ? BWN_TX_EFT_FB_OFDM :
6479 	    BWN_TX_EFT_FB_CCK;
6480 	txhdr->chan = phy->chan;
6481 	phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
6482 	    BWN_TX_PHY_ENC_CCK;
6483 	/* XXX preamble? obey net80211 */
6484 	if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
6485 	     rate == BWN_CCK_RATE_11MB))
6486 		phyctl |= BWN_TX_PHY_SHORTPRMBL;
6487 
6488 	if (! phy->gmode)
6489 		macctl |= BWN_TX_MAC_5GHZ;
6490 
6491 	/* XXX TX antenna selection */
6492 
6493 	switch (bwn_antenna_sanitize(mac, 0)) {
6494 	case 0:
6495 		phyctl |= BWN_TX_PHY_ANT01AUTO;
6496 		break;
6497 	case 1:
6498 		phyctl |= BWN_TX_PHY_ANT0;
6499 		break;
6500 	case 2:
6501 		phyctl |= BWN_TX_PHY_ANT1;
6502 		break;
6503 	case 3:
6504 		phyctl |= BWN_TX_PHY_ANT2;
6505 		break;
6506 	case 4:
6507 		phyctl |= BWN_TX_PHY_ANT3;
6508 		break;
6509 	default:
6510 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
6511 	}
6512 
6513 	if (!ismcast)
6514 		macctl |= BWN_TX_MAC_ACK;
6515 
6516 	macctl |= (BWN_TX_MAC_HWSEQ | BWN_TX_MAC_START_MSDU);
6517 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
6518 	    m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
6519 		macctl |= BWN_TX_MAC_LONGFRAME;
6520 
6521 	if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
6522 	    ic->ic_protmode != IEEE80211_PROT_NONE) {
6523 		/* Note: don't fall back to CCK rates for 5G */
6524 		if (phy->gmode)
6525 			rts_rate = BWN_CCK_RATE_1MB;
6526 		else
6527 			rts_rate = BWN_OFDM_RATE_6MB;
6528 		rts_rate_fb = bwn_get_fbrate(rts_rate);
6529 
6530 		/* XXX 'rate' here is hardware rate now, not the net80211 rate */
6531 		mprot = ieee80211_alloc_prot(ni, m, rate, ic->ic_protmode);
6532 		if (mprot == NULL) {
6533 			if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, 1);
6534 			device_printf(sc->sc_dev,
6535 			    "could not allocate mbuf for protection mode %d\n",
6536 			    ic->ic_protmode);
6537 			return (ENOBUFS);
6538 		}
6539 
6540 		switch (mac->mac_fw.fw_hdr_format) {
6541 		case BWN_FW_HDR_351:
6542 			prot_ptr = txhdr->body.r351.rts_frame;
6543 			break;
6544 		case BWN_FW_HDR_410:
6545 			prot_ptr = txhdr->body.r410.rts_frame;
6546 			break;
6547 		case BWN_FW_HDR_598:
6548 			prot_ptr = txhdr->body.r598.rts_frame;
6549 			break;
6550 		}
6551 
6552 		bcopy(mtod(mprot, uint8_t *), prot_ptr, mprot->m_pkthdr.len);
6553 		m_freem(mprot);
6554 
6555 		if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
6556 			macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
6557 			len = sizeof(struct ieee80211_frame_cts);
6558 		} else {
6559 			macctl |= BWN_TX_MAC_SEND_RTSCTS;
6560 			len = sizeof(struct ieee80211_frame_rts);
6561 		}
6562 		len += IEEE80211_CRC_LEN;
6563 
6564 		switch (mac->mac_fw.fw_hdr_format) {
6565 		case BWN_FW_HDR_351:
6566 			bwn_plcp_genhdr((struct bwn_plcp4 *)
6567 			    &txhdr->body.r351.rts_plcp, len, rts_rate);
6568 			break;
6569 		case BWN_FW_HDR_410:
6570 			bwn_plcp_genhdr((struct bwn_plcp4 *)
6571 			    &txhdr->body.r410.rts_plcp, len, rts_rate);
6572 			break;
6573 		case BWN_FW_HDR_598:
6574 			bwn_plcp_genhdr((struct bwn_plcp4 *)
6575 			    &txhdr->body.r598.rts_plcp, len, rts_rate);
6576 			break;
6577 		}
6578 
6579 		bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
6580 		    rts_rate_fb);
6581 
6582 		switch (mac->mac_fw.fw_hdr_format) {
6583 		case BWN_FW_HDR_351:
6584 			protwh = (struct ieee80211_frame *)
6585 			    &txhdr->body.r351.rts_frame;
6586 			break;
6587 		case BWN_FW_HDR_410:
6588 			protwh = (struct ieee80211_frame *)
6589 			    &txhdr->body.r410.rts_frame;
6590 			break;
6591 		case BWN_FW_HDR_598:
6592 			protwh = (struct ieee80211_frame *)
6593 			    &txhdr->body.r598.rts_frame;
6594 			break;
6595 		}
6596 
6597 		txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
6598 
6599 		if (BWN_ISOFDMRATE(rts_rate)) {
6600 			txhdr->eftypes |= BWN_TX_EFT_RTS_OFDM;
6601 			txhdr->phyrate_rts = bwn_plcp_getofdm(rts_rate);
6602 		} else {
6603 			txhdr->eftypes |= BWN_TX_EFT_RTS_CCK;
6604 			txhdr->phyrate_rts = bwn_plcp_getcck(rts_rate);
6605 		}
6606 		txhdr->eftypes |= (BWN_ISOFDMRATE(rts_rate_fb)) ?
6607 		    BWN_TX_EFT_RTS_FBOFDM : BWN_TX_EFT_RTS_FBCCK;
6608 
6609 		if (fill_phy_ctl1) {
6610 			txhdr->phyctl_1rts = htole16(bwn_set_txhdr_phyctl1(mac, rts_rate));
6611 			txhdr->phyctl_1rtsfb = htole16(bwn_set_txhdr_phyctl1(mac, rts_rate_fb));
6612 		}
6613 	}
6614 
6615 	if (fill_phy_ctl1) {
6616 		txhdr->phyctl_1 = htole16(bwn_set_txhdr_phyctl1(mac, rate));
6617 		txhdr->phyctl_1fb = htole16(bwn_set_txhdr_phyctl1(mac, rate_fb));
6618 	}
6619 
6620 	switch (mac->mac_fw.fw_hdr_format) {
6621 	case BWN_FW_HDR_351:
6622 		txhdr->body.r351.cookie = htole16(cookie);
6623 		break;
6624 	case BWN_FW_HDR_410:
6625 		txhdr->body.r410.cookie = htole16(cookie);
6626 		break;
6627 	case BWN_FW_HDR_598:
6628 		txhdr->body.r598.cookie = htole16(cookie);
6629 		break;
6630 	}
6631 
6632 	txhdr->macctl = htole32(macctl);
6633 	txhdr->phyctl = htole16(phyctl);
6634 
6635 	/*
6636 	 * TX radio tap
6637 	 */
6638 	if (ieee80211_radiotap_active_vap(vap)) {
6639 		sc->sc_tx_th.wt_flags = 0;
6640 		if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
6641 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
6642 		if (isshort &&
6643 		    (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
6644 		     rate == BWN_CCK_RATE_11MB))
6645 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
6646 		sc->sc_tx_th.wt_rate = rate;
6647 
6648 		ieee80211_radiotap_tx(vap, m);
6649 	}
6650 
6651 	return (0);
6652 }
6653 
6654 static void
bwn_plcp_genhdr(struct bwn_plcp4 * plcp,const uint16_t octets,const uint8_t rate)6655 bwn_plcp_genhdr(struct bwn_plcp4 *plcp, const uint16_t octets,
6656     const uint8_t rate)
6657 {
6658 	uint32_t d, plen;
6659 	uint8_t *raw = plcp->o.raw;
6660 
6661 	if (BWN_ISOFDMRATE(rate)) {
6662 		d = bwn_plcp_getofdm(rate);
6663 		KASSERT(!(octets & 0xf000),
6664 		    ("%s:%d: fail", __func__, __LINE__));
6665 		d |= (octets << 5);
6666 		plcp->o.data = htole32(d);
6667 	} else {
6668 		plen = octets * 16 / rate;
6669 		if ((octets * 16 % rate) > 0) {
6670 			plen++;
6671 			if ((rate == BWN_CCK_RATE_11MB)
6672 			    && ((octets * 8 % 11) < 4)) {
6673 				raw[1] = 0x84;
6674 			} else
6675 				raw[1] = 0x04;
6676 		} else
6677 			raw[1] = 0x04;
6678 		plcp->o.data |= htole32(plen << 16);
6679 		raw[0] = bwn_plcp_getcck(rate);
6680 	}
6681 }
6682 
6683 static uint8_t
bwn_antenna_sanitize(struct bwn_mac * mac,uint8_t n)6684 bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
6685 {
6686 	struct bwn_softc *sc = mac->mac_sc;
6687 	uint8_t mask;
6688 
6689 	if (n == 0)
6690 		return (0);
6691 	if (mac->mac_phy.gmode)
6692 		mask = sc->sc_ant2g;
6693 	else
6694 		mask = sc->sc_ant5g;
6695 	if (!(mask & (1 << (n - 1))))
6696 		return (0);
6697 	return (n);
6698 }
6699 
6700 /*
6701  * Return a fallback rate for the given rate.
6702  *
6703  * Note: Don't fall back from OFDM to CCK.
6704  */
6705 static uint8_t
bwn_get_fbrate(uint8_t bitrate)6706 bwn_get_fbrate(uint8_t bitrate)
6707 {
6708 	switch (bitrate) {
6709 	/* CCK */
6710 	case BWN_CCK_RATE_1MB:
6711 		return (BWN_CCK_RATE_1MB);
6712 	case BWN_CCK_RATE_2MB:
6713 		return (BWN_CCK_RATE_1MB);
6714 	case BWN_CCK_RATE_5MB:
6715 		return (BWN_CCK_RATE_2MB);
6716 	case BWN_CCK_RATE_11MB:
6717 		return (BWN_CCK_RATE_5MB);
6718 
6719 	/* OFDM */
6720 	case BWN_OFDM_RATE_6MB:
6721 		return (BWN_OFDM_RATE_6MB);
6722 	case BWN_OFDM_RATE_9MB:
6723 		return (BWN_OFDM_RATE_6MB);
6724 	case BWN_OFDM_RATE_12MB:
6725 		return (BWN_OFDM_RATE_9MB);
6726 	case BWN_OFDM_RATE_18MB:
6727 		return (BWN_OFDM_RATE_12MB);
6728 	case BWN_OFDM_RATE_24MB:
6729 		return (BWN_OFDM_RATE_18MB);
6730 	case BWN_OFDM_RATE_36MB:
6731 		return (BWN_OFDM_RATE_24MB);
6732 	case BWN_OFDM_RATE_48MB:
6733 		return (BWN_OFDM_RATE_36MB);
6734 	case BWN_OFDM_RATE_54MB:
6735 		return (BWN_OFDM_RATE_48MB);
6736 	}
6737 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
6738 	return (0);
6739 }
6740 
6741 static uint32_t
bwn_pio_write_multi_4(struct bwn_mac * mac,struct bwn_pio_txqueue * tq,uint32_t ctl,const void * _data,int len)6742 bwn_pio_write_multi_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
6743     uint32_t ctl, const void *_data, int len)
6744 {
6745 	struct bwn_softc *sc = mac->mac_sc;
6746 	uint32_t value = 0;
6747 	const uint8_t *data = _data;
6748 
6749 	ctl |= BWN_PIO8_TXCTL_0_7 | BWN_PIO8_TXCTL_8_15 |
6750 	    BWN_PIO8_TXCTL_16_23 | BWN_PIO8_TXCTL_24_31;
6751 	bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
6752 
6753 	bus_write_multi_4(sc->sc_mem_res, tq->tq_base + BWN_PIO8_TXDATA,
6754 	    __DECONST(void *, data), (len & ~3));
6755 	if (len & 3) {
6756 		ctl &= ~(BWN_PIO8_TXCTL_8_15 | BWN_PIO8_TXCTL_16_23 |
6757 		    BWN_PIO8_TXCTL_24_31);
6758 		data = &(data[len - 1]);
6759 		switch (len & 3) {
6760 		case 3:
6761 			ctl |= BWN_PIO8_TXCTL_16_23;
6762 			value |= (uint32_t)(*data) << 16;
6763 			data--;
6764 		case 2:
6765 			ctl |= BWN_PIO8_TXCTL_8_15;
6766 			value |= (uint32_t)(*data) << 8;
6767 			data--;
6768 		case 1:
6769 			value |= (uint32_t)(*data);
6770 		}
6771 		bwn_pio_write_4(mac, tq, BWN_PIO8_TXCTL, ctl);
6772 		bwn_pio_write_4(mac, tq, BWN_PIO8_TXDATA, value);
6773 	}
6774 
6775 	return (ctl);
6776 }
6777 
6778 static void
bwn_pio_write_4(struct bwn_mac * mac,struct bwn_pio_txqueue * tq,uint16_t offset,uint32_t value)6779 bwn_pio_write_4(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
6780     uint16_t offset, uint32_t value)
6781 {
6782 
6783 	BWN_WRITE_4(mac, tq->tq_base + offset, value);
6784 }
6785 
6786 static uint16_t
bwn_pio_write_multi_2(struct bwn_mac * mac,struct bwn_pio_txqueue * tq,uint16_t ctl,const void * _data,int len)6787 bwn_pio_write_multi_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
6788     uint16_t ctl, const void *_data, int len)
6789 {
6790 	struct bwn_softc *sc = mac->mac_sc;
6791 	const uint8_t *data = _data;
6792 
6793 	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
6794 	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
6795 
6796 	bus_write_multi_2(sc->sc_mem_res, tq->tq_base + BWN_PIO_TXDATA,
6797 	    __DECONST(void *, data), (len & ~1));
6798 	if (len & 1) {
6799 		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
6800 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
6801 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data[len - 1]);
6802 	}
6803 
6804 	return (ctl);
6805 }
6806 
6807 static uint16_t
bwn_pio_write_mbuf_2(struct bwn_mac * mac,struct bwn_pio_txqueue * tq,uint16_t ctl,struct mbuf * m0)6808 bwn_pio_write_mbuf_2(struct bwn_mac *mac, struct bwn_pio_txqueue *tq,
6809     uint16_t ctl, struct mbuf *m0)
6810 {
6811 	int i, j = 0;
6812 	uint16_t data = 0;
6813 	const uint8_t *buf;
6814 	struct mbuf *m = m0;
6815 
6816 	ctl |= BWN_PIO_TXCTL_WRITELO | BWN_PIO_TXCTL_WRITEHI;
6817 	BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
6818 
6819 	for (; m != NULL; m = m->m_next) {
6820 		buf = mtod(m, const uint8_t *);
6821 		for (i = 0; i < m->m_len; i++) {
6822 			if (!((j++) % 2))
6823 				data |= buf[i];
6824 			else {
6825 				data |= (buf[i] << 8);
6826 				BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
6827 				data = 0;
6828 			}
6829 		}
6830 	}
6831 	if (m0->m_pkthdr.len % 2) {
6832 		ctl &= ~BWN_PIO_TXCTL_WRITEHI;
6833 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXCTL, ctl);
6834 		BWN_PIO_WRITE_2(mac, tq, BWN_PIO_TXDATA, data);
6835 	}
6836 
6837 	return (ctl);
6838 }
6839 
6840 static void
bwn_set_slot_time(struct bwn_mac * mac,uint16_t time)6841 bwn_set_slot_time(struct bwn_mac *mac, uint16_t time)
6842 {
6843 
6844 	/* XXX should exit if 5GHz band .. */
6845 	if (mac->mac_phy.type != BWN_PHYTYPE_G)
6846 		return;
6847 
6848 	BWN_WRITE_2(mac, 0x684, 510 + time);
6849 	/* Disabled in Linux b43, can adversely effect performance */
6850 #if 0
6851 	bwn_shm_write_2(mac, BWN_SHARED, 0x0010, time);
6852 #endif
6853 }
6854 
6855 static struct bwn_dma_ring *
bwn_dma_select(struct bwn_mac * mac,uint8_t prio)6856 bwn_dma_select(struct bwn_mac *mac, uint8_t prio)
6857 {
6858 
6859 	if ((mac->mac_flags & BWN_MAC_FLAG_WME) == 0)
6860 		return (mac->mac_method.dma.wme[WME_AC_BE]);
6861 
6862 	switch (prio) {
6863 	case 3:
6864 		return (mac->mac_method.dma.wme[WME_AC_VO]);
6865 	case 2:
6866 		return (mac->mac_method.dma.wme[WME_AC_VI]);
6867 	case 0:
6868 		return (mac->mac_method.dma.wme[WME_AC_BE]);
6869 	case 1:
6870 		return (mac->mac_method.dma.wme[WME_AC_BK]);
6871 	}
6872 	KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
6873 	return (NULL);
6874 }
6875 
6876 static int
bwn_dma_getslot(struct bwn_dma_ring * dr)6877 bwn_dma_getslot(struct bwn_dma_ring *dr)
6878 {
6879 	int slot;
6880 
6881 	BWN_ASSERT_LOCKED(dr->dr_mac->mac_sc);
6882 
6883 	KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
6884 	KASSERT(!(dr->dr_stop), ("%s:%d: fail", __func__, __LINE__));
6885 	KASSERT(bwn_dma_freeslot(dr) != 0, ("%s:%d: fail", __func__, __LINE__));
6886 
6887 	slot = bwn_dma_nextslot(dr, dr->dr_curslot);
6888 	KASSERT(!(slot & ~0x0fff), ("%s:%d: fail", __func__, __LINE__));
6889 	dr->dr_curslot = slot;
6890 	dr->dr_usedslot++;
6891 
6892 	return (slot);
6893 }
6894 
6895 static struct bwn_pio_txqueue *
bwn_pio_parse_cookie(struct bwn_mac * mac,uint16_t cookie,struct bwn_pio_txpkt ** pack)6896 bwn_pio_parse_cookie(struct bwn_mac *mac, uint16_t cookie,
6897     struct bwn_pio_txpkt **pack)
6898 {
6899 	struct bwn_pio *pio = &mac->mac_method.pio;
6900 	struct bwn_pio_txqueue *tq = NULL;
6901 	unsigned int index;
6902 
6903 	switch (cookie & 0xf000) {
6904 	case 0x1000:
6905 		tq = &pio->wme[WME_AC_BK];
6906 		break;
6907 	case 0x2000:
6908 		tq = &pio->wme[WME_AC_BE];
6909 		break;
6910 	case 0x3000:
6911 		tq = &pio->wme[WME_AC_VI];
6912 		break;
6913 	case 0x4000:
6914 		tq = &pio->wme[WME_AC_VO];
6915 		break;
6916 	case 0x5000:
6917 		tq = &pio->mcast;
6918 		break;
6919 	}
6920 	KASSERT(tq != NULL, ("%s:%d: fail", __func__, __LINE__));
6921 	if (tq == NULL)
6922 		return (NULL);
6923 	index = (cookie & 0x0fff);
6924 	KASSERT(index < N(tq->tq_pkts), ("%s:%d: fail", __func__, __LINE__));
6925 	if (index >= N(tq->tq_pkts))
6926 		return (NULL);
6927 	*pack = &tq->tq_pkts[index];
6928 	KASSERT(*pack != NULL, ("%s:%d: fail", __func__, __LINE__));
6929 	return (tq);
6930 }
6931 
6932 static void
bwn_txpwr(void * arg,int npending)6933 bwn_txpwr(void *arg, int npending)
6934 {
6935 	struct bwn_mac *mac = arg;
6936 	struct bwn_softc *sc;
6937 
6938 	if (mac == NULL)
6939 		return;
6940 
6941 	sc = mac->mac_sc;
6942 
6943 	BWN_LOCK(sc);
6944 	if (mac->mac_status >= BWN_MAC_STATUS_STARTED &&
6945 	    mac->mac_phy.set_txpwr != NULL)
6946 		mac->mac_phy.set_txpwr(mac);
6947 	BWN_UNLOCK(sc);
6948 }
6949 
6950 static void
bwn_task_15s(struct bwn_mac * mac)6951 bwn_task_15s(struct bwn_mac *mac)
6952 {
6953 	uint16_t reg;
6954 
6955 	if (mac->mac_fw.opensource) {
6956 		reg = bwn_shm_read_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG);
6957 		if (reg) {
6958 			bwn_restart(mac, "fw watchdog");
6959 			return;
6960 		}
6961 		bwn_shm_write_2(mac, BWN_SCRATCH, BWN_WATCHDOG_REG, 1);
6962 	}
6963 	if (mac->mac_phy.task_15s)
6964 		mac->mac_phy.task_15s(mac);
6965 
6966 	mac->mac_phy.txerrors = BWN_TXERROR_MAX;
6967 }
6968 
6969 static void
bwn_task_30s(struct bwn_mac * mac)6970 bwn_task_30s(struct bwn_mac *mac)
6971 {
6972 
6973 	if (mac->mac_phy.type != BWN_PHYTYPE_G || mac->mac_noise.noi_running)
6974 		return;
6975 	mac->mac_noise.noi_running = 1;
6976 	mac->mac_noise.noi_nsamples = 0;
6977 
6978 	bwn_noise_gensample(mac);
6979 }
6980 
6981 static void
bwn_task_60s(struct bwn_mac * mac)6982 bwn_task_60s(struct bwn_mac *mac)
6983 {
6984 
6985 	if (mac->mac_phy.task_60s)
6986 		mac->mac_phy.task_60s(mac);
6987 	bwn_phy_txpower_check(mac, BWN_TXPWR_IGNORE_TIME);
6988 }
6989 
6990 static void
bwn_tasks(void * arg)6991 bwn_tasks(void *arg)
6992 {
6993 	struct bwn_mac *mac = arg;
6994 	struct bwn_softc *sc = mac->mac_sc;
6995 
6996 	BWN_ASSERT_LOCKED(sc);
6997 	if (mac->mac_status != BWN_MAC_STATUS_STARTED)
6998 		return;
6999 
7000 	if (mac->mac_task_state % 4 == 0)
7001 		bwn_task_60s(mac);
7002 	if (mac->mac_task_state % 2 == 0)
7003 		bwn_task_30s(mac);
7004 	bwn_task_15s(mac);
7005 
7006 	mac->mac_task_state++;
7007 	callout_reset(&sc->sc_task_ch, hz * 15, bwn_tasks, mac);
7008 }
7009 
7010 static int
bwn_plcp_get_ofdmrate(struct bwn_mac * mac,struct bwn_plcp6 * plcp,uint8_t a)7011 bwn_plcp_get_ofdmrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp, uint8_t a)
7012 {
7013 	struct bwn_softc *sc = mac->mac_sc;
7014 
7015 	KASSERT(a == 0, ("not support APHY\n"));
7016 
7017 	switch (plcp->o.raw[0] & 0xf) {
7018 	case 0xb:
7019 		return (BWN_OFDM_RATE_6MB);
7020 	case 0xf:
7021 		return (BWN_OFDM_RATE_9MB);
7022 	case 0xa:
7023 		return (BWN_OFDM_RATE_12MB);
7024 	case 0xe:
7025 		return (BWN_OFDM_RATE_18MB);
7026 	case 0x9:
7027 		return (BWN_OFDM_RATE_24MB);
7028 	case 0xd:
7029 		return (BWN_OFDM_RATE_36MB);
7030 	case 0x8:
7031 		return (BWN_OFDM_RATE_48MB);
7032 	case 0xc:
7033 		return (BWN_OFDM_RATE_54MB);
7034 	}
7035 	device_printf(sc->sc_dev, "incorrect OFDM rate %d\n",
7036 	    plcp->o.raw[0] & 0xf);
7037 	return (-1);
7038 }
7039 
7040 static int
bwn_plcp_get_cckrate(struct bwn_mac * mac,struct bwn_plcp6 * plcp)7041 bwn_plcp_get_cckrate(struct bwn_mac *mac, struct bwn_plcp6 *plcp)
7042 {
7043 	struct bwn_softc *sc = mac->mac_sc;
7044 
7045 	switch (plcp->o.raw[0]) {
7046 	case 0x0a:
7047 		return (BWN_CCK_RATE_1MB);
7048 	case 0x14:
7049 		return (BWN_CCK_RATE_2MB);
7050 	case 0x37:
7051 		return (BWN_CCK_RATE_5MB);
7052 	case 0x6e:
7053 		return (BWN_CCK_RATE_11MB);
7054 	}
7055 	device_printf(sc->sc_dev, "incorrect CCK rate %d\n", plcp->o.raw[0]);
7056 	return (-1);
7057 }
7058 
7059 static void
bwn_rx_radiotap(struct bwn_mac * mac,struct mbuf * m,const struct bwn_rxhdr4 * rxhdr,struct bwn_plcp6 * plcp,int rate,int rssi,int noise)7060 bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
7061     const struct bwn_rxhdr4 *rxhdr, struct bwn_plcp6 *plcp, int rate,
7062     int rssi, int noise)
7063 {
7064 	struct bwn_softc *sc = mac->mac_sc;
7065 	const struct ieee80211_frame_min *wh;
7066 	uint64_t tsf;
7067 	uint16_t low_mactime_now;
7068 	uint16_t mt;
7069 
7070 	if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
7071 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7072 
7073 	wh = mtod(m, const struct ieee80211_frame_min *);
7074 	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
7075 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
7076 
7077 	bwn_tsf_read(mac, &tsf);
7078 	low_mactime_now = tsf;
7079 	tsf = tsf & ~0xffffULL;
7080 
7081 	switch (mac->mac_fw.fw_hdr_format) {
7082 	case BWN_FW_HDR_351:
7083 	case BWN_FW_HDR_410:
7084 		mt = le16toh(rxhdr->ps4.r351.mac_time);
7085 		break;
7086 	case BWN_FW_HDR_598:
7087 		mt = le16toh(rxhdr->ps4.r598.mac_time);
7088 		break;
7089 	}
7090 
7091 	tsf += mt;
7092 	if (low_mactime_now < mt)
7093 		tsf -= 0x10000;
7094 
7095 	sc->sc_rx_th.wr_tsf = tsf;
7096 	sc->sc_rx_th.wr_rate = rate;
7097 	sc->sc_rx_th.wr_antsignal = rssi;
7098 	sc->sc_rx_th.wr_antnoise = noise;
7099 }
7100 
7101 static void
bwn_tsf_read(struct bwn_mac * mac,uint64_t * tsf)7102 bwn_tsf_read(struct bwn_mac *mac, uint64_t *tsf)
7103 {
7104 	uint32_t low, high;
7105 
7106 	KASSERT(bhnd_get_hwrev(mac->mac_sc->sc_dev) >= 3,
7107 	    ("%s:%d: fail", __func__, __LINE__));
7108 
7109 	low = BWN_READ_4(mac, BWN_REV3PLUS_TSF_LOW);
7110 	high = BWN_READ_4(mac, BWN_REV3PLUS_TSF_HIGH);
7111 	*tsf = high;
7112 	*tsf <<= 32;
7113 	*tsf |= low;
7114 }
7115 
7116 static int
bwn_dma_attach(struct bwn_mac * mac)7117 bwn_dma_attach(struct bwn_mac *mac)
7118 {
7119 	struct bwn_dma			*dma;
7120 	struct bwn_softc		*sc;
7121 	struct bhnd_dma_translation	*dt, dma_translation;
7122 	bhnd_addr_t			 addrext_req;
7123 	bus_dma_tag_t			 dmat;
7124 	bus_addr_t			 lowaddr;
7125 	u_int				 addrext_shift, addr_width;
7126 	int				 error;
7127 
7128 	dma = &mac->mac_method.dma;
7129 	sc = mac->mac_sc;
7130 	dt = NULL;
7131 
7132 	if (sc->sc_quirks & BWN_QUIRK_NODMA)
7133 		return (0);
7134 
7135 	KASSERT(bhnd_get_hwrev(sc->sc_dev) >= 5, ("%s: fail", __func__));
7136 
7137 	/* Use the DMA engine's maximum host address width to determine the
7138 	 * addrext constraints, and supported device address width. */
7139 	switch (mac->mac_dmatype) {
7140 	case BHND_DMA_ADDR_30BIT:
7141 		/* 32-bit engine without addrext support */
7142 		addrext_req = 0x0;
7143 		addrext_shift = 0;
7144 
7145 		/* We can address the full 32-bit device address space */
7146 		addr_width = BHND_DMA_ADDR_32BIT;
7147 		break;
7148 
7149 	case BHND_DMA_ADDR_32BIT:
7150 		/* 32-bit engine with addrext support */
7151 		addrext_req = BWN_DMA32_ADDREXT_MASK;
7152 		addrext_shift = BWN_DMA32_ADDREXT_SHIFT;
7153 		addr_width = BHND_DMA_ADDR_32BIT;
7154 		break;
7155 
7156 	case BHND_DMA_ADDR_64BIT:
7157 		/* 64-bit engine with addrext support */
7158 		addrext_req = BWN_DMA64_ADDREXT_MASK;
7159 		addrext_shift = BWN_DMA64_ADDREXT_SHIFT;
7160 		addr_width = BHND_DMA_ADDR_64BIT;
7161 		break;
7162 
7163 	default:
7164 		device_printf(sc->sc_dev, "unsupported DMA address width: %d\n",
7165 		    mac->mac_dmatype);
7166 		return (ENXIO);
7167 	}
7168 
7169 	/* Fetch our device->host DMA translation and tag */
7170 	error = bhnd_get_dma_translation(sc->sc_dev, addr_width, 0, &dmat,
7171 	    &dma_translation);
7172 	if (error) {
7173 		device_printf(sc->sc_dev, "error fetching DMA translation: "
7174 		    "%d\n", error);
7175 		return (error);
7176 	}
7177 
7178 	/* Verify that our DMA engine's addrext constraints are compatible with
7179 	 * our DMA translation */
7180 	if (addrext_req != 0x0 &&
7181 	    (dma_translation.addrext_mask & addrext_req) != addrext_req)
7182 	{
7183 		device_printf(sc->sc_dev, "bus addrext mask %#jx incompatible "
7184 		    "with device addrext mask %#jx, disabling extended address "
7185 		    "support\n", (uintmax_t)dma_translation.addrext_mask,
7186 		    (uintmax_t)addrext_req);
7187 
7188 		addrext_req = 0x0;
7189 		addrext_shift = 0;
7190 	}
7191 
7192 	/* Apply our addrext translation constraint */
7193 	dma_translation.addrext_mask = addrext_req;
7194 
7195 	/* Initialize our DMA engine configuration */
7196 	mac->mac_flags |= BWN_MAC_FLAG_DMA;
7197 
7198 	dma->addrext_shift = addrext_shift;
7199 	dma->translation = dma_translation;
7200 
7201 	dt = &dma->translation;
7202 
7203 	/* Dermine our translation's maximum supported address */
7204 	lowaddr = MIN((dt->addr_mask | dt->addrext_mask), BUS_SPACE_MAXADDR);
7205 
7206 	/*
7207 	 * Create top level DMA tag
7208 	 */
7209 	error = bus_dma_tag_create(dmat,		/* parent */
7210 			       BWN_ALIGN, 0,		/* alignment, bounds */
7211 			       lowaddr,			/* lowaddr */
7212 			       BUS_SPACE_MAXADDR,	/* highaddr */
7213 			       NULL, NULL,		/* filter, filterarg */
7214 			       BUS_SPACE_MAXSIZE,	/* maxsize */
7215 			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
7216 			       BUS_SPACE_MAXSIZE,	/* maxsegsize */
7217 			       0,			/* flags */
7218 			       NULL, NULL,		/* lockfunc, lockarg */
7219 			       &dma->parent_dtag);
7220 	if (error) {
7221 		device_printf(sc->sc_dev, "can't create parent DMA tag\n");
7222 		return (error);
7223 	}
7224 
7225 	/*
7226 	 * Create TX/RX mbuf DMA tag
7227 	 */
7228 	error = bus_dma_tag_create(dma->parent_dtag,
7229 				1,
7230 				0,
7231 				BUS_SPACE_MAXADDR,
7232 				BUS_SPACE_MAXADDR,
7233 				NULL, NULL,
7234 				MCLBYTES,
7235 				1,
7236 				BUS_SPACE_MAXSIZE_32BIT,
7237 				0,
7238 				NULL, NULL,
7239 				&dma->rxbuf_dtag);
7240 	if (error) {
7241 		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
7242 		goto fail0;
7243 	}
7244 	error = bus_dma_tag_create(dma->parent_dtag,
7245 				1,
7246 				0,
7247 				BUS_SPACE_MAXADDR,
7248 				BUS_SPACE_MAXADDR,
7249 				NULL, NULL,
7250 				MCLBYTES,
7251 				1,
7252 				BUS_SPACE_MAXSIZE_32BIT,
7253 				0,
7254 				NULL, NULL,
7255 				&dma->txbuf_dtag);
7256 	if (error) {
7257 		device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
7258 		goto fail1;
7259 	}
7260 
7261 	dma->wme[WME_AC_BK] = bwn_dma_ringsetup(mac, 0, 1);
7262 	if (!dma->wme[WME_AC_BK])
7263 		goto fail2;
7264 
7265 	dma->wme[WME_AC_BE] = bwn_dma_ringsetup(mac, 1, 1);
7266 	if (!dma->wme[WME_AC_BE])
7267 		goto fail3;
7268 
7269 	dma->wme[WME_AC_VI] = bwn_dma_ringsetup(mac, 2, 1);
7270 	if (!dma->wme[WME_AC_VI])
7271 		goto fail4;
7272 
7273 	dma->wme[WME_AC_VO] = bwn_dma_ringsetup(mac, 3, 1);
7274 	if (!dma->wme[WME_AC_VO])
7275 		goto fail5;
7276 
7277 	dma->mcast = bwn_dma_ringsetup(mac, 4, 1);
7278 	if (!dma->mcast)
7279 		goto fail6;
7280 	dma->rx = bwn_dma_ringsetup(mac, 0, 0);
7281 	if (!dma->rx)
7282 		goto fail7;
7283 
7284 	return (error);
7285 
7286 fail7:	bwn_dma_ringfree(&dma->mcast);
7287 fail6:	bwn_dma_ringfree(&dma->wme[WME_AC_VO]);
7288 fail5:	bwn_dma_ringfree(&dma->wme[WME_AC_VI]);
7289 fail4:	bwn_dma_ringfree(&dma->wme[WME_AC_BE]);
7290 fail3:	bwn_dma_ringfree(&dma->wme[WME_AC_BK]);
7291 fail2:	bus_dma_tag_destroy(dma->txbuf_dtag);
7292 fail1:	bus_dma_tag_destroy(dma->rxbuf_dtag);
7293 fail0:	bus_dma_tag_destroy(dma->parent_dtag);
7294 	return (error);
7295 }
7296 
7297 static struct bwn_dma_ring *
bwn_dma_parse_cookie(struct bwn_mac * mac,const struct bwn_txstatus * status,uint16_t cookie,int * slot)7298 bwn_dma_parse_cookie(struct bwn_mac *mac, const struct bwn_txstatus *status,
7299     uint16_t cookie, int *slot)
7300 {
7301 	struct bwn_dma *dma = &mac->mac_method.dma;
7302 	struct bwn_dma_ring *dr;
7303 	struct bwn_softc *sc = mac->mac_sc;
7304 
7305 	BWN_ASSERT_LOCKED(mac->mac_sc);
7306 
7307 	switch (cookie & 0xf000) {
7308 	case 0x1000:
7309 		dr = dma->wme[WME_AC_BK];
7310 		break;
7311 	case 0x2000:
7312 		dr = dma->wme[WME_AC_BE];
7313 		break;
7314 	case 0x3000:
7315 		dr = dma->wme[WME_AC_VI];
7316 		break;
7317 	case 0x4000:
7318 		dr = dma->wme[WME_AC_VO];
7319 		break;
7320 	case 0x5000:
7321 		dr = dma->mcast;
7322 		break;
7323 	default:
7324 		dr = NULL;
7325 		KASSERT(0 == 1,
7326 		    ("invalid cookie value %d", cookie & 0xf000));
7327 	}
7328 	*slot = (cookie & 0x0fff);
7329 	if (*slot < 0 || *slot >= dr->dr_numslots) {
7330 		/*
7331 		 * XXX FIXME: sometimes H/W returns TX DONE events duplicately
7332 		 * that it occurs events which have same H/W sequence numbers.
7333 		 * When it's occurred just prints a WARNING msgs and ignores.
7334 		 */
7335 		KASSERT(status->seq == dma->lastseq,
7336 		    ("%s:%d: fail", __func__, __LINE__));
7337 		device_printf(sc->sc_dev,
7338 		    "out of slot ranges (0 < %d < %d)\n", *slot,
7339 		    dr->dr_numslots);
7340 		return (NULL);
7341 	}
7342 	dma->lastseq = status->seq;
7343 	return (dr);
7344 }
7345 
7346 static void
bwn_dma_stop(struct bwn_mac * mac)7347 bwn_dma_stop(struct bwn_mac *mac)
7348 {
7349 	struct bwn_dma *dma;
7350 
7351 	if ((mac->mac_flags & BWN_MAC_FLAG_DMA) == 0)
7352 		return;
7353 	dma = &mac->mac_method.dma;
7354 
7355 	bwn_dma_ringstop(&dma->rx);
7356 	bwn_dma_ringstop(&dma->wme[WME_AC_BK]);
7357 	bwn_dma_ringstop(&dma->wme[WME_AC_BE]);
7358 	bwn_dma_ringstop(&dma->wme[WME_AC_VI]);
7359 	bwn_dma_ringstop(&dma->wme[WME_AC_VO]);
7360 	bwn_dma_ringstop(&dma->mcast);
7361 }
7362 
7363 static void
bwn_dma_ringstop(struct bwn_dma_ring ** dr)7364 bwn_dma_ringstop(struct bwn_dma_ring **dr)
7365 {
7366 
7367 	if (dr == NULL)
7368 		return;
7369 
7370 	bwn_dma_cleanup(*dr);
7371 }
7372 
7373 static void
bwn_pio_stop(struct bwn_mac * mac)7374 bwn_pio_stop(struct bwn_mac *mac)
7375 {
7376 	struct bwn_pio *pio;
7377 
7378 	if (mac->mac_flags & BWN_MAC_FLAG_DMA)
7379 		return;
7380 	pio = &mac->mac_method.pio;
7381 
7382 	bwn_destroy_queue_tx(&pio->mcast);
7383 	bwn_destroy_queue_tx(&pio->wme[WME_AC_VO]);
7384 	bwn_destroy_queue_tx(&pio->wme[WME_AC_VI]);
7385 	bwn_destroy_queue_tx(&pio->wme[WME_AC_BE]);
7386 	bwn_destroy_queue_tx(&pio->wme[WME_AC_BK]);
7387 }
7388 
7389 static int
bwn_led_attach(struct bwn_mac * mac)7390 bwn_led_attach(struct bwn_mac *mac)
7391 {
7392 	struct bwn_softc *sc = mac->mac_sc;
7393 	const uint8_t *led_act = NULL;
7394 	int error;
7395 	int i;
7396 
7397 	sc->sc_led_idle = (2350 * hz) / 1000;
7398 	sc->sc_led_blink = 1;
7399 
7400 	for (i = 0; i < N(bwn_vendor_led_act); ++i) {
7401 		if (sc->sc_board_info.board_vendor ==
7402 		    bwn_vendor_led_act[i].vid) {
7403 			led_act = bwn_vendor_led_act[i].led_act;
7404 			break;
7405 		}
7406 	}
7407 	if (led_act == NULL)
7408 		led_act = bwn_default_led_act;
7409 
7410 	_Static_assert(nitems(bwn_led_vars) == BWN_LED_MAX,
7411 	    "invalid NVRAM variable name array");
7412 
7413 	for (i = 0; i < BWN_LED_MAX; ++i) {
7414 		struct bwn_led	*led;
7415 		uint8_t		 val;
7416 
7417 		led = &sc->sc_leds[i];
7418 
7419 		KASSERT(i < nitems(bwn_led_vars), ("unknown LED index"));
7420 		error = bhnd_nvram_getvar_uint8(sc->sc_dev, bwn_led_vars[i],
7421 		    &val);
7422 		if (error) {
7423 			if (error != ENOENT) {
7424 				device_printf(sc->sc_dev, "NVRAM variable %s "
7425 				    "unreadable: %d", bwn_led_vars[i], error);
7426 				return (error);
7427 			}
7428 
7429 			/* Not found; use default */
7430 			led->led_act = led_act[i];
7431 		} else {
7432 			if (val & BWN_LED_ACT_LOW)
7433 				led->led_flags |= BWN_LED_F_ACTLOW;
7434 			led->led_act = val & BWN_LED_ACT_MASK;
7435 		}
7436 		led->led_mask = (1 << i);
7437 
7438 		if (led->led_act == BWN_LED_ACT_BLINK_SLOW ||
7439 		    led->led_act == BWN_LED_ACT_BLINK_POLL ||
7440 		    led->led_act == BWN_LED_ACT_BLINK) {
7441 			led->led_flags |= BWN_LED_F_BLINK;
7442 			if (led->led_act == BWN_LED_ACT_BLINK_POLL)
7443 				led->led_flags |= BWN_LED_F_POLLABLE;
7444 			else if (led->led_act == BWN_LED_ACT_BLINK_SLOW)
7445 				led->led_flags |= BWN_LED_F_SLOW;
7446 
7447 			if (sc->sc_blink_led == NULL) {
7448 				sc->sc_blink_led = led;
7449 				if (led->led_flags & BWN_LED_F_SLOW)
7450 					BWN_LED_SLOWDOWN(sc->sc_led_idle);
7451 			}
7452 		}
7453 
7454 		DPRINTF(sc, BWN_DEBUG_LED,
7455 		    "%dth led, act %d, lowact %d\n", i,
7456 		    led->led_act, led->led_flags & BWN_LED_F_ACTLOW);
7457 	}
7458 	callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
7459 
7460 	return (0);
7461 }
7462 
7463 static __inline uint16_t
bwn_led_onoff(const struct bwn_led * led,uint16_t val,int on)7464 bwn_led_onoff(const struct bwn_led *led, uint16_t val, int on)
7465 {
7466 
7467 	if (led->led_flags & BWN_LED_F_ACTLOW)
7468 		on = !on;
7469 	if (on)
7470 		val |= led->led_mask;
7471 	else
7472 		val &= ~led->led_mask;
7473 	return val;
7474 }
7475 
7476 static void
bwn_led_newstate(struct bwn_mac * mac,enum ieee80211_state nstate)7477 bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
7478 {
7479 	struct bwn_softc *sc = mac->mac_sc;
7480 	struct ieee80211com *ic = &sc->sc_ic;
7481 	uint16_t val;
7482 	int i;
7483 
7484 	if (nstate == IEEE80211_S_INIT) {
7485 		callout_stop(&sc->sc_led_blink_ch);
7486 		sc->sc_led_blinking = 0;
7487 	}
7488 
7489 	if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0)
7490 		return;
7491 
7492 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
7493 	for (i = 0; i < BWN_LED_MAX; ++i) {
7494 		struct bwn_led *led = &sc->sc_leds[i];
7495 		int on;
7496 
7497 		if (led->led_act == BWN_LED_ACT_UNKN ||
7498 		    led->led_act == BWN_LED_ACT_NULL)
7499 			continue;
7500 
7501 		if ((led->led_flags & BWN_LED_F_BLINK) &&
7502 		    nstate != IEEE80211_S_INIT)
7503 			continue;
7504 
7505 		switch (led->led_act) {
7506 		case BWN_LED_ACT_ON:    /* Always on */
7507 			on = 1;
7508 			break;
7509 		case BWN_LED_ACT_OFF:   /* Always off */
7510 		case BWN_LED_ACT_5GHZ:  /* TODO: 11A */
7511 			on = 0;
7512 			break;
7513 		default:
7514 			on = 1;
7515 			switch (nstate) {
7516 			case IEEE80211_S_INIT:
7517 				on = 0;
7518 				break;
7519 			case IEEE80211_S_RUN:
7520 				if (led->led_act == BWN_LED_ACT_11G &&
7521 				    ic->ic_curmode != IEEE80211_MODE_11G)
7522 					on = 0;
7523 				break;
7524 			default:
7525 				if (led->led_act == BWN_LED_ACT_ASSOC)
7526 					on = 0;
7527 				break;
7528 			}
7529 			break;
7530 		}
7531 
7532 		val = bwn_led_onoff(led, val, on);
7533 	}
7534 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
7535 }
7536 
7537 static void
bwn_led_event(struct bwn_mac * mac,int event)7538 bwn_led_event(struct bwn_mac *mac, int event)
7539 {
7540 	struct bwn_softc *sc = mac->mac_sc;
7541 	struct bwn_led *led = sc->sc_blink_led;
7542 	int rate;
7543 
7544 	if (event == BWN_LED_EVENT_POLL) {
7545 		if ((led->led_flags & BWN_LED_F_POLLABLE) == 0)
7546 			return;
7547 		if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
7548 			return;
7549 	}
7550 
7551 	sc->sc_led_ticks = ticks;
7552 	if (sc->sc_led_blinking)
7553 		return;
7554 
7555 	switch (event) {
7556 	case BWN_LED_EVENT_RX:
7557 		rate = sc->sc_rx_rate;
7558 		break;
7559 	case BWN_LED_EVENT_TX:
7560 		rate = sc->sc_tx_rate;
7561 		break;
7562 	case BWN_LED_EVENT_POLL:
7563 		rate = 0;
7564 		break;
7565 	default:
7566 		panic("unknown LED event %d\n", event);
7567 		break;
7568 	}
7569 	bwn_led_blink_start(mac, bwn_led_duration[rate].on_dur,
7570 	    bwn_led_duration[rate].off_dur);
7571 }
7572 
7573 static void
bwn_led_blink_start(struct bwn_mac * mac,int on_dur,int off_dur)7574 bwn_led_blink_start(struct bwn_mac *mac, int on_dur, int off_dur)
7575 {
7576 	struct bwn_softc *sc = mac->mac_sc;
7577 	struct bwn_led *led = sc->sc_blink_led;
7578 	uint16_t val;
7579 
7580 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
7581 	val = bwn_led_onoff(led, val, 1);
7582 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
7583 
7584 	if (led->led_flags & BWN_LED_F_SLOW) {
7585 		BWN_LED_SLOWDOWN(on_dur);
7586 		BWN_LED_SLOWDOWN(off_dur);
7587 	}
7588 
7589 	sc->sc_led_blinking = 1;
7590 	sc->sc_led_blink_offdur = off_dur;
7591 
7592 	callout_reset(&sc->sc_led_blink_ch, on_dur, bwn_led_blink_next, mac);
7593 }
7594 
7595 static void
bwn_led_blink_next(void * arg)7596 bwn_led_blink_next(void *arg)
7597 {
7598 	struct bwn_mac *mac = arg;
7599 	struct bwn_softc *sc = mac->mac_sc;
7600 	uint16_t val;
7601 
7602 	val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
7603 	val = bwn_led_onoff(sc->sc_blink_led, val, 0);
7604 	BWN_WRITE_2(mac, BWN_GPIO_CONTROL, val);
7605 
7606 	callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
7607 	    bwn_led_blink_end, mac);
7608 }
7609 
7610 static void
bwn_led_blink_end(void * arg)7611 bwn_led_blink_end(void *arg)
7612 {
7613 	struct bwn_mac *mac = arg;
7614 	struct bwn_softc *sc = mac->mac_sc;
7615 
7616 	sc->sc_led_blinking = 0;
7617 }
7618 
7619 static int
bwn_suspend(device_t dev)7620 bwn_suspend(device_t dev)
7621 {
7622 	struct bwn_softc *sc = device_get_softc(dev);
7623 
7624 	BWN_LOCK(sc);
7625 	bwn_stop(sc);
7626 	BWN_UNLOCK(sc);
7627 	return (0);
7628 }
7629 
7630 static int
bwn_resume(device_t dev)7631 bwn_resume(device_t dev)
7632 {
7633 	struct bwn_softc *sc = device_get_softc(dev);
7634 	int error = EDOOFUS;
7635 
7636 	BWN_LOCK(sc);
7637 	if (sc->sc_ic.ic_nrunning > 0)
7638 		error = bwn_init(sc);
7639 	BWN_UNLOCK(sc);
7640 	if (error == 0)
7641 		ieee80211_start_all(&sc->sc_ic);
7642 	return (0);
7643 }
7644 
7645 static void
bwn_rfswitch(void * arg)7646 bwn_rfswitch(void *arg)
7647 {
7648 	struct bwn_softc *sc = arg;
7649 	struct bwn_mac *mac = sc->sc_curmac;
7650 	int cur = 0, prev = 0;
7651 
7652 	KASSERT(mac->mac_status >= BWN_MAC_STATUS_STARTED,
7653 	    ("%s: invalid MAC status %d", __func__, mac->mac_status));
7654 
7655 	if (mac->mac_phy.rev >= 3 || mac->mac_phy.type == BWN_PHYTYPE_LP
7656 	    || mac->mac_phy.type == BWN_PHYTYPE_N) {
7657 		if (!(BWN_READ_4(mac, BWN_RF_HWENABLED_HI)
7658 			& BWN_RF_HWENABLED_HI_MASK))
7659 			cur = 1;
7660 	} else {
7661 		if (BWN_READ_2(mac, BWN_RF_HWENABLED_LO)
7662 		    & BWN_RF_HWENABLED_LO_MASK)
7663 			cur = 1;
7664 	}
7665 
7666 	if (mac->mac_flags & BWN_MAC_FLAG_RADIO_ON)
7667 		prev = 1;
7668 
7669 	DPRINTF(sc, BWN_DEBUG_RESET, "%s: called; cur=%d, prev=%d\n",
7670 	    __func__, cur, prev);
7671 
7672 	if (cur != prev) {
7673 		if (cur)
7674 			mac->mac_flags |= BWN_MAC_FLAG_RADIO_ON;
7675 		else
7676 			mac->mac_flags &= ~BWN_MAC_FLAG_RADIO_ON;
7677 
7678 		device_printf(sc->sc_dev,
7679 		    "status of RF switch is changed to %s\n",
7680 		    cur ? "ON" : "OFF");
7681 		if (cur != mac->mac_phy.rf_on) {
7682 			if (cur)
7683 				bwn_rf_turnon(mac);
7684 			else
7685 				bwn_rf_turnoff(mac);
7686 		}
7687 	}
7688 
7689 	callout_schedule(&sc->sc_rfswitch_ch, hz);
7690 }
7691 
7692 static void
bwn_sysctl_node(struct bwn_softc * sc)7693 bwn_sysctl_node(struct bwn_softc *sc)
7694 {
7695 	device_t dev = sc->sc_dev;
7696 	struct bwn_mac *mac;
7697 	struct bwn_stats *stats;
7698 
7699 	/* XXX assume that count of MAC is only 1. */
7700 
7701 	if ((mac = sc->sc_curmac) == NULL)
7702 		return;
7703 	stats = &mac->mac_stats;
7704 
7705 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
7706 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
7707 	    "linknoise", CTLFLAG_RW, &stats->rts, 0, "Noise level");
7708 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
7709 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
7710 	    "rts", CTLFLAG_RW, &stats->rts, 0, "RTS");
7711 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
7712 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
7713 	    "rtsfail", CTLFLAG_RW, &stats->rtsfail, 0, "RTS failed to send");
7714 
7715 #ifdef BWN_DEBUG
7716 	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
7717 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
7718 	    "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
7719 #endif
7720 }
7721 
7722 static device_method_t bwn_methods[] = {
7723 	/* Device interface */
7724 	DEVMETHOD(device_probe,		bwn_probe),
7725 	DEVMETHOD(device_attach,	bwn_attach),
7726 	DEVMETHOD(device_detach,	bwn_detach),
7727 	DEVMETHOD(device_suspend,	bwn_suspend),
7728 	DEVMETHOD(device_resume,	bwn_resume),
7729 	DEVMETHOD_END
7730 };
7731 
7732 static driver_t bwn_driver = {
7733 	"bwn",
7734 	bwn_methods,
7735 	sizeof(struct bwn_softc)
7736 };
7737 
7738 DRIVER_MODULE(bwn, bhnd, bwn_driver, 0, 0);
7739 MODULE_DEPEND(bwn, bhnd, 1, 1, 1);
7740 MODULE_DEPEND(bwn, gpiobus, 1, 1, 1);
7741 MODULE_DEPEND(bwn, wlan, 1, 1, 1);		/* 802.11 media layer */
7742 MODULE_DEPEND(bwn, firmware, 1, 1, 1);		/* firmware support */
7743 MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);
7744 MODULE_VERSION(bwn, 1);
7745