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