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