bwi.c revision 1.53
1/*	$OpenBSD: bwi.c,v 1.53 2007/09/30 22:12:43 mglocker Exp $	*/
2
3/*
4 * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
5 *
6 * This code is derived from software contributed to The DragonFly Project
7 * by Sepherosa Ziehau <sepherosa@gmail.com>
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in
17 *    the documentation and/or other materials provided with the
18 *    distribution.
19 * 3. Neither the name of The DragonFly Project nor the names of its
20 *    contributors may be used to endorse or promote products derived
21 *    from this software without specific, prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
27 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.1 2007/09/08 06:15:54 sephe Exp $
37 */
38
39#include "bpfilter.h"
40
41#include <sys/cdefs.h>
42#include <sys/param.h>
43#include <sys/types.h>
44
45#include <sys/device.h>
46#include <sys/kernel.h>
47#include <sys/malloc.h>
48#include <sys/mbuf.h>
49#include <sys/proc.h>
50#include <sys/socket.h>
51#include <sys/sockio.h>
52#include <sys/systm.h>
53
54#include <machine/bus.h>
55#include <machine/endian.h>
56#include <machine/intr.h>
57
58#include <net/if.h>
59#include <net/if_dl.h>
60#include <net/if_media.h>
61
62#if NBPFILTER > 0
63#include <net/bpf.h>
64#endif
65
66#include <netinet/in.h>
67#include <netinet/in_systm.h>
68#include <netinet/if_ether.h>
69
70#include <net80211/ieee80211_var.h>
71#include <net80211/ieee80211_amrr.h>
72#include <net80211/ieee80211_radiotap.h>
73
74#include <dev/ic/bwireg.h>
75#include <dev/ic/bwivar.h>
76
77#define BWI_DEBUG
78
79#ifdef BWI_DEBUG
80int bwi_debug = 1;
81#define DPRINTF(l, x...)	do { if ((l) <= bwi_debug) printf(x); } while (0)
82#else
83#define DPRINTF(l, x...)
84#endif
85
86/* XXX temporary porting goop */
87#define KKASSERT(cond) if (!(cond)) panic("KKASSERT: %s in %s", #cond, __func__)
88#undef KASSERT
89#define KASSERT(cond, complaint) if (!(cond)) panic complaint
90
91#include <dev/pci/pcireg.h>
92#include <dev/pci/pcivar.h>
93#include <dev/pci/pcidevs.h>
94
95/*
96 * Contention window (slots).
97 */
98#define IEEE80211_CW_MAX	1023	/* aCWmax */
99#define IEEE80211_CW_MIN_0	31	/* DS/CCK aCWmin, ERP aCWmin(0) */
100#define IEEE80211_CW_MIN_1	15	/* OFDM aCWmin, ERP aCWmin(1) */
101
102#define __unused __attribute__((__unused__))
103
104/* XXX end porting goop */
105
106/* MAC */
107struct bwi_retry_lim {
108	uint16_t	shretry;
109	uint16_t	shretry_fb;
110	uint16_t	lgretry;
111	uint16_t	lgretry_fb;
112};
113
114struct bwi_clock_freq {
115	u_int		clkfreq_min;
116	u_int		clkfreq_max;
117};
118
119/* XXX does not belong here */
120struct ieee80211_ds_plcp_hdr {
121	uint8_t		i_signal;
122	uint8_t		i_service;
123	uint16_t	i_length;
124	uint16_t	i_crc;
125} __packed;
126
127void		 bwi_tmplt_write_4(struct bwi_mac *, uint32_t, uint32_t);
128void		 bwi_hostflags_write(struct bwi_mac *, uint64_t);
129uint64_t	 bwi_hostflags_read(struct bwi_mac *);
130uint16_t	 bwi_memobj_read_2(struct bwi_mac *, uint16_t, uint16_t);
131uint32_t	 bwi_memobj_read_4(struct bwi_mac *, uint16_t, uint16_t);
132void		 bwi_memobj_write_2(struct bwi_mac *, uint16_t, uint16_t,
133		     uint16_t);
134void		 bwi_memobj_write_4(struct bwi_mac *, uint16_t, uint16_t,
135		     uint32_t);
136int		 bwi_mac_lateattach(struct bwi_mac *);
137int		 bwi_mac_init(struct bwi_mac *);
138void		 bwi_mac_reset(struct bwi_mac *, int);
139void		 bwi_mac_set_tpctl_11bg(struct bwi_mac *,
140		     const struct bwi_tpctl *);
141int		 bwi_mac_test(struct bwi_mac *);
142void		 bwi_mac_setup_tpctl(struct bwi_mac *);
143void		 bwi_mac_dummy_xmit(struct bwi_mac *);
144void		 bwi_mac_init_tpctl_11bg(struct bwi_mac *);
145void		 bwi_mac_detach(struct bwi_mac *);
146int		 bwi_get_firmware(const char *, const uint8_t *, size_t,
147		     size_t *, size_t *);
148int		 bwi_fwimage_is_valid(struct bwi_softc *, uint8_t *,
149		    size_t fw_len, char *, uint8_t);
150int		 bwi_mac_fw_alloc(struct bwi_mac *);
151void		 bwi_mac_fw_free(struct bwi_mac *);
152int		 bwi_mac_fw_load(struct bwi_mac *);
153int		 bwi_mac_gpio_init(struct bwi_mac *);
154int		 bwi_mac_gpio_fini(struct bwi_mac *);
155int		 bwi_mac_fw_load_iv(struct bwi_mac *, uint8_t *, size_t);
156int		 bwi_mac_fw_init(struct bwi_mac *);
157void		 bwi_mac_opmode_init(struct bwi_mac *);
158void		 bwi_mac_hostflags_init(struct bwi_mac *);
159void		 bwi_mac_bss_param_init(struct bwi_mac *);
160void		 bwi_mac_set_retry_lim(struct bwi_mac *,
161		     const struct bwi_retry_lim *);
162void		 bwi_mac_set_ackrates(struct bwi_mac *,
163		     const struct ieee80211_rateset *);
164int		 bwi_mac_start(struct bwi_mac *);
165int		 bwi_mac_stop(struct bwi_mac *);
166int		 bwi_mac_config_ps(struct bwi_mac *);
167void		 bwi_mac_reset_hwkeys(struct bwi_mac *);
168void		 bwi_mac_shutdown(struct bwi_mac *);
169int		 bwi_mac_get_property(struct bwi_mac *);
170void		 bwi_mac_updateslot(struct bwi_mac *, int);
171int		 bwi_mac_attach(struct bwi_softc *, int, uint8_t);
172void		 bwi_mac_balance_atten(int *, int *);
173void		 bwi_mac_adjust_tpctl(struct bwi_mac *, int, int);
174void		 bwi_mac_calibrate_txpower(struct bwi_mac *);
175void		 bwi_mac_lock(struct bwi_mac *);
176void		 bwi_mac_unlock(struct bwi_mac *);
177void		 bwi_mac_set_promisc(struct bwi_mac *, int);
178void		 bwi_phy_write(struct bwi_mac *, uint16_t, uint16_t);
179uint16_t	 bwi_phy_read(struct bwi_mac *, uint16_t);
180int		 bwi_phy_attach(struct bwi_mac *);
181void		 bwi_phy_set_bbp_atten(struct bwi_mac *, uint16_t);
182int		 bwi_phy_calibrate(struct bwi_mac *);
183void		 bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
184void		 bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
185void		 bwi_nrssi_write(struct bwi_mac *, uint16_t, int16_t);
186int16_t		 bwi_nrssi_read(struct bwi_mac *, uint16_t);
187void		 bwi_phy_init_11a(struct bwi_mac *);
188void		 bwi_phy_init_11g(struct bwi_mac *);
189void		 bwi_phy_init_11b_rev2(struct bwi_mac *);
190void		 bwi_phy_init_11b_rev4(struct bwi_mac *);
191void		 bwi_phy_init_11b_rev5(struct bwi_mac *);
192void		 bwi_phy_init_11b_rev6(struct bwi_mac *);
193void		 bwi_phy_config_11g(struct bwi_mac *);
194void		 bwi_phy_config_agc(struct bwi_mac *);
195void		 bwi_set_gains(struct bwi_mac *, const struct bwi_gains *);
196void		 bwi_phy_clear_state(struct bwi_phy *);
197int16_t		 bwi_nrssi_11g(struct bwi_mac *);
198struct bwi_rf_lo
199		*bwi_get_rf_lo(struct bwi_mac *, uint16_t, uint16_t);
200int		 bwi_rf_lo_isused(struct bwi_mac *, const struct bwi_rf_lo *);
201void		 bwi_rf_write(struct bwi_mac *, uint16_t, uint16_t);
202uint16_t	 bwi_rf_read(struct bwi_mac *, uint16_t);
203int		 bwi_rf_attach(struct bwi_mac *);
204void		 bwi_rf_set_chan(struct bwi_mac *, u_int, int);
205void		 bwi_rf_get_gains(struct bwi_mac *);
206void		 bwi_rf_init(struct bwi_mac *);
207void		 bwi_rf_off_11a(struct bwi_mac *);
208void		 bwi_rf_off_11bg(struct bwi_mac *);
209void		 bwi_rf_off_11g_rev5(struct bwi_mac *);
210void		 bwi_rf_work_around(struct bwi_mac *, u_int);
211struct bwi_rf_lo
212		*bwi_rf_lo_find(struct bwi_mac *, const struct bwi_tpctl *);
213void		 bwi_rf_lo_adjust(struct bwi_mac *, const struct bwi_tpctl *);
214void		 bwi_rf_lo_write(struct bwi_mac *, const struct bwi_rf_lo *);
215int		 bwi_rf_gain_max_reached(struct bwi_mac *, int);
216uint16_t	 bwi_bitswap4(uint16_t);
217uint16_t	 bwi_phy812_value(struct bwi_mac *, uint16_t);
218void		 bwi_rf_init_bcm2050(struct bwi_mac *);
219uint16_t	 bwi_rf_calibval(struct bwi_mac *);
220int32_t		 _bwi_adjust_devide(int32_t, int32_t);
221int		 bwi_rf_calc_txpower(int8_t *, uint8_t, const int16_t[]);
222int		 bwi_rf_map_txpower(struct bwi_mac *);
223void		 bwi_rf_lo_update(struct bwi_mac *);
224uint32_t	 bwi_rf_lo_devi_measure(struct bwi_mac *, uint16_t);
225uint16_t	 bwi_rf_get_tp_ctrl2(struct bwi_mac *);
226uint8_t		 _bwi_rf_lo_update(struct bwi_mac *, uint16_t);
227void		 bwi_rf_lo_measure(struct bwi_mac *,
228		     const struct bwi_rf_lo *, struct bwi_rf_lo *, uint8_t);
229void		 bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *);
230void		 bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *);
231void		 bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *);
232void		 bwi_rf_off_11a(struct bwi_mac *);
233void		 bwi_rf_off_11bg(struct bwi_mac *);
234void		 bwi_rf_off_11g_rev5(struct bwi_mac *);
235int		 bwi_rf_attach(struct bwi_mac *);
236int		 bwi_rf_map_txpower(struct bwi_mac *);
237void		 bwi_rf_lo_adjust(struct bwi_mac *, const struct bwi_tpctl *);
238void		 bwi_rf_set_chan(struct bwi_mac *, u_int, int);
239void		 bwi_rf_get_gains(struct bwi_mac *);
240void		 bwi_rf_init(struct bwi_mac *);
241void		 bwi_rf_init_bcm2050(struct bwi_mac *);
242void		 bwi_rf_init_sw_nrssi_table(struct bwi_mac *);
243void		 bwi_rf_init_hw_nrssi_table(struct bwi_mac *, uint16_t);
244void		 bwi_rf_set_nrssi_thr_11b(struct bwi_mac *);
245int32_t		 _nrssi_threshold(const struct bwi_rf *, int32_t);
246void		 bwi_rf_set_nrssi_thr_11g(struct bwi_mac *);
247void		 bwi_rf_clear_tssi(struct bwi_mac *);
248void		 bwi_rf_clear_state(struct bwi_rf *);
249void		 bwi_rf_on_11a(struct bwi_mac *);
250void		 bwi_rf_on_11bg(struct bwi_mac *);
251void		 bwi_rf_set_ant_mode(struct bwi_mac *, int);
252int		 bwi_rf_get_latest_tssi(struct bwi_mac *, int8_t[], uint16_t);
253int		 bwi_rf_tssi2dbm(struct bwi_mac *, int8_t, int8_t *);
254uint16_t	 bwi_read_sprom(struct bwi_softc *, uint16_t);
255void		 bwi_setup_desc32(struct bwi_softc *, struct bwi_desc32 *, int,
256		     int, bus_addr_t, int, int);
257void		 bwi_power_on(struct bwi_softc *, int);
258int		 bwi_power_off(struct bwi_softc *, int);
259int		 bwi_regwin_switch(struct bwi_softc *, struct bwi_regwin *,
260		     struct bwi_regwin **);
261int		 bwi_regwin_select(struct bwi_softc *, int);
262void		 bwi_regwin_info(struct bwi_softc *, uint16_t *, uint8_t *);
263int		 bwi_bbp_attach(struct bwi_softc *);
264int		 bwi_bus_init(struct bwi_softc *, struct bwi_mac *);
265void		 bwi_get_card_flags(struct bwi_softc *);
266void		 bwi_get_eaddr(struct bwi_softc *, uint16_t, uint8_t *);
267void		 bwi_get_clock_freq(struct bwi_softc *,
268		     struct bwi_clock_freq *);
269int		 bwi_set_clock_mode(struct bwi_softc *, enum bwi_clock_mode);
270int		 bwi_set_clock_delay(struct bwi_softc *);
271int		 bwi_init(struct ifnet *);
272int		 bwi_ioctl(struct ifnet *, u_long, caddr_t);
273void		 bwi_start(struct ifnet *);
274void		 bwi_watchdog(struct ifnet *);
275int		 bwi_stop(struct bwi_softc *);
276int		 bwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
277int		 bwi_media_change(struct ifnet *);
278void		 bwi_iter_func(void *, struct ieee80211_node *);
279void		 bwi_amrr_timeout(void *);
280void		 bwi_newassoc(struct ieee80211com *, struct ieee80211_node *,
281		     int);
282int		 bwi_dma_alloc(struct bwi_softc *);
283void		 bwi_dma_free(struct bwi_softc *);
284int		 bwi_dma_ring_alloc(struct bwi_softc *,
285		     struct bwi_ring_data *, bus_size_t, uint32_t);
286int		 bwi_dma_txstats_alloc(struct bwi_softc *, uint32_t,
287		     bus_size_t);
288void		 bwi_dma_txstats_free(struct bwi_softc *);
289int		 bwi_dma_mbuf_create(struct bwi_softc *);
290void		 bwi_dma_mbuf_destroy(struct bwi_softc *, int, int);
291void		 bwi_enable_intrs(struct bwi_softc *, uint32_t);
292void		 bwi_disable_intrs(struct bwi_softc *, uint32_t);
293int		 bwi_init_tx_ring32(struct bwi_softc *, int);
294void		 bwi_init_rxdesc_ring32(struct bwi_softc *, uint32_t,
295		     bus_addr_t, int, int);
296int		 bwi_init_rx_ring32(struct bwi_softc *);
297int		 bwi_init_txstats32(struct bwi_softc *);
298void		 bwi_setup_rx_desc32(struct bwi_softc *, int, bus_addr_t, int);
299void		 bwi_setup_tx_desc32(struct bwi_softc *, struct bwi_ring_data *,
300		     int, bus_addr_t, int);
301int		 bwi_init_tx_ring64(struct bwi_softc *, int);
302int		 bwi_init_rx_ring64(struct bwi_softc *);
303int		 bwi_init_txstats64(struct bwi_softc *);
304void		 bwi_setup_rx_desc64(struct bwi_softc *, int, bus_addr_t, int);
305void		 bwi_setup_tx_desc64(struct bwi_softc *, struct bwi_ring_data *,
306		     int, bus_addr_t, int);
307int		 bwi_newbuf(struct bwi_softc *, int, int);
308void		 bwi_set_addr_filter(struct bwi_softc *, uint16_t,
309		     const uint8_t *);
310int		 bwi_set_chan(struct bwi_softc *, u_int8_t);
311void		 bwi_next_scan(void *);
312void		 bwi_rxeof(struct bwi_softc *, int);
313void		 bwi_rxeof32(struct bwi_softc *);
314void		 bwi_rxeof64(struct bwi_softc *);
315void		 bwi_reset_rx_ring32(struct bwi_softc *, uint32_t);
316void		 bwi_free_txstats32(struct bwi_softc *);
317void		 bwi_free_rx_ring32(struct bwi_softc *);
318void		 bwi_free_tx_ring32(struct bwi_softc *, int);
319void		 bwi_free_txstats64(struct bwi_softc *);
320void		 bwi_free_rx_ring64(struct bwi_softc *);
321void		 bwi_free_tx_ring64(struct bwi_softc *, int);
322uint8_t		 bwi_rate2plcp(uint8_t); /* XXX belongs to 802.11 */
323void		 bwi_ofdm_plcp_header(uint32_t *, int, uint8_t);
324void		 bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *, int,
325		     uint8_t);
326void		 bwi_plcp_header(void *, int, uint8_t);
327int		 bwi_encap(struct bwi_softc *, int, struct mbuf *,
328		     struct ieee80211_node *);
329void		 bwi_start_tx32(struct bwi_softc *, uint32_t, int);
330void		 bwi_start_tx64(struct bwi_softc *, uint32_t, int);
331void		 bwi_txeof_status32(struct bwi_softc *);
332void		 bwi_txeof_status64(struct bwi_softc *);
333void		 _bwi_txeof(struct bwi_softc *, uint16_t);
334void		 bwi_txeof_status(struct bwi_softc *, int);
335void		 bwi_txeof(struct bwi_softc *);
336int		 bwi_bbp_power_on(struct bwi_softc *, enum bwi_clock_mode);
337void		 bwi_bbp_power_off(struct bwi_softc *);
338int		 bwi_get_pwron_delay(struct bwi_softc *sc);
339int		 bwi_bus_attach(struct bwi_softc *);
340const char 	*bwi_regwin_name(const struct bwi_regwin *);
341int		 bwi_regwin_is_enabled(struct bwi_softc *, struct bwi_regwin *);
342uint32_t	 bwi_regwin_disable_bits(struct bwi_softc *);
343void		 bwi_regwin_enable(struct bwi_softc *, struct bwi_regwin *,
344		     uint32_t);
345void		 bwi_regwin_disable(struct bwi_softc *, struct bwi_regwin *,
346		     uint32_t);
347void		 bwi_set_bssid(struct bwi_softc *, const uint8_t *);
348void		 bwi_updateslot(struct ieee80211com *);
349void		 bwi_calibrate(void *);
350u_int8_t	 bwi_ack_rate(struct ieee80211_node *, u_int8_t);
351u_int16_t	 bwi_txtime(struct ieee80211com *, struct ieee80211_node *,
352		     u_int, u_int8_t, uint32_t);
353enum bwi_modtype	 bwi_rate2modtype(u_int8_t);
354
355
356static const uint8_t bwi_sup_macrev[] = { 2, 4, 5, 6, 7, 9, 10 };
357
358#define SUP_BPHY(num)	{ .rev = num, .init = bwi_phy_init_11b_rev##num }
359
360static const struct {
361	uint8_t	rev;
362	void	(*init)(struct bwi_mac *);
363} bwi_sup_bphy[] = {
364	SUP_BPHY(2),
365	SUP_BPHY(4),
366	SUP_BPHY(5),
367	SUP_BPHY(6)
368};
369
370#undef SUP_BPHY
371
372#define BWI_PHYTBL_WRSSI	0x1000
373#define BWI_PHYTBL_NOISE_SCALE	0x1400
374#define BWI_PHYTBL_NOISE	0x1800
375#define BWI_PHYTBL_ROTOR	0x2000
376#define BWI_PHYTBL_DELAY	0x2400
377#define BWI_PHYTBL_RSSI		0x4000
378#define BWI_PHYTBL_SIGMA_SQ	0x5000
379#define BWI_PHYTBL_WRSSI_REV1	0x5400
380#define BWI_PHYTBL_FREQ		0x5800
381
382static const uint16_t	bwi_phy_freq_11g_rev1[] =
383	{ BWI_PHY_FREQ_11G_REV1 };
384static const uint16_t	bwi_phy_noise_11g_rev1[] =
385	{ BWI_PHY_NOISE_11G_REV1 };
386static const uint16_t	bwi_phy_noise_11g[] =
387	{ BWI_PHY_NOISE_11G };
388static const uint32_t	bwi_phy_rotor_11g_rev1[] =
389	{ BWI_PHY_ROTOR_11G_REV1 };
390static const uint16_t	bwi_phy_noise_scale_11g_rev2[] =
391	{ BWI_PHY_NOISE_SCALE_11G_REV2 };
392static const uint16_t	bwi_phy_noise_scale_11g_rev7[] =
393	{ BWI_PHY_NOISE_SCALE_11G_REV7 };
394static const uint16_t	bwi_phy_noise_scale_11g[] =
395	{ BWI_PHY_NOISE_SCALE_11G };
396static const uint16_t	bwi_phy_sigma_sq_11g_rev2[] =
397	{ BWI_PHY_SIGMA_SQ_11G_REV2 };
398static const uint16_t	bwi_phy_sigma_sq_11g_rev7[] =
399	{ BWI_PHY_SIGMA_SQ_11G_REV7 };
400static const uint32_t	bwi_phy_delay_11g_rev1[] =
401	{ BWI_PHY_DELAY_11G_REV1 };
402
403/* RF */
404#define RF_LO_WRITE(mac, lo)	bwi_rf_lo_write((mac), (lo))
405
406#define BWI_RF_2GHZ_CHAN(chan) \
407	(ieee80211_ieee2mhz((chan), IEEE80211_CHAN_2GHZ) - 2400)
408
409#define BWI_DEFAULT_IDLE_TSSI	52
410
411struct rf_saveregs {
412	uint16_t	phy_15;
413	uint16_t	phy_2a;
414	uint16_t	phy_35;
415	uint16_t	phy_60;
416	uint16_t	phy_429;
417	uint16_t	phy_802;
418	uint16_t	phy_811;
419	uint16_t	phy_812;
420	uint16_t	phy_814;
421	uint16_t	phy_815;
422
423	uint16_t	rf_43;
424	uint16_t	rf_52;
425	uint16_t	rf_7a;
426};
427
428#define SAVE_RF_REG(mac, regs, n)	(regs)->rf_##n = RF_READ((mac), 0x##n)
429#define RESTORE_RF_REG(mac, regs, n)	RF_WRITE((mac), 0x##n, (regs)->rf_##n)
430
431#define SAVE_PHY_REG(mac, regs, n)	(regs)->phy_##n = PHY_READ((mac), 0x##n)
432#define RESTORE_PHY_REG(mac, regs, n)	PHY_WRITE((mac), 0x##n, (regs)->phy_##n)
433
434static const int8_t	bwi_txpower_map_11b[BWI_TSSI_MAX] =
435	{ BWI_TXPOWER_MAP_11B };
436static const int8_t	bwi_txpower_map_11g[BWI_TSSI_MAX] =
437	{ BWI_TXPOWER_MAP_11G };
438
439/* IF_BWI */
440
441struct bwi_myaddr_bssid {
442	uint8_t		myaddr[IEEE80211_ADDR_LEN];
443	uint8_t		bssid[IEEE80211_ADDR_LEN];
444} __packed;
445
446#define IEEE80211_DS_PLCP_SERVICE_LOCKED	0x04
447#define IEEE80211_DS_PLCL_SERVICE_PBCC		0x08
448#define IEEE80211_DS_PLCP_SERVICE_LENEXT5	0x20
449#define IEEE80211_DS_PLCP_SERVICE_LENEXT6	0x40
450#define IEEE80211_DS_PLCP_SERVICE_LENEXT7	0x80
451
452struct cfdriver bwi_cd = {
453	NULL, "bwi", DV_IFNET
454};
455
456static const struct {
457	uint16_t	did_min;
458	uint16_t	did_max;
459	uint16_t	bbp_id;
460} bwi_bbpid_map[] = {
461	{ 0x4301, 0x4301, 0x4301 },
462	{ 0x4305, 0x4307, 0x4307 },
463	{ 0x4403, 0x4403, 0x4402 },
464	{ 0x4610, 0x4615, 0x4610 },
465	{ 0x4710, 0x4715, 0x4710 },
466	{ 0x4720, 0x4725, 0x4309 }
467};
468
469static const struct {
470	uint16_t	bbp_id;
471	int		nregwin;
472} bwi_regwin_count[] = {
473	{ 0x4301, 5 },
474	{ 0x4306, 6 },
475	{ 0x4307, 5 },
476	{ 0x4310, 8 },
477	{ 0x4401, 3 },
478	{ 0x4402, 3 },
479	{ 0x4610, 9 },
480	{ 0x4704, 9 },
481	{ 0x4710, 9 },
482	{ 0x5365, 7 }
483};
484
485#define CLKSRC(src) 				\
486[BWI_CLKSRC_ ## src] = {			\
487	.freq_min = BWI_CLKSRC_ ##src## _FMIN,	\
488	.freq_max = BWI_CLKSRC_ ##src## _FMAX	\
489}
490
491static const struct {
492	u_int	freq_min;
493	u_int	freq_max;
494} bwi_clkfreq[BWI_CLKSRC_MAX] = {
495	CLKSRC(LP_OSC),
496	CLKSRC(CS_OSC),
497	CLKSRC(PCI)
498};
499
500#undef CLKSRC
501
502static const uint8_t bwi_zero_addr[IEEE80211_ADDR_LEN];
503
504
505enum bwi_modtype {
506	IEEE80211_MODTYPE_DS	= 0,	/* DS/CCK modulation */
507	IEEE80211_MODTYPE_PBCC	= 1,	/* PBCC modulation */
508	IEEE80211_MODTYPE_OFDM	= 2	/* OFDM modulation */
509};
510#define IEEE80211_MODTYPE_CCK   IEEE80211_MODTYPE_DS
511
512/* CODE */
513
514int
515bwi_intr(void *xsc)
516{
517	struct bwi_softc *sc = xsc;
518	struct ifnet *ifp = &sc->sc_ic.ic_if;
519	uint32_t intr_status;
520	uint32_t txrx_intr_status[BWI_TXRX_NRING];
521	int i, txrx_error;
522
523	if ((ifp->if_flags & IFF_RUNNING) == 0)
524		return (0);
525
526	/*
527	 * Get interrupt status
528	 */
529	intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
530	if (intr_status == 0xffffffff)	/* Not for us */
531		return (0);
532
533	intr_status &= CSR_READ_4(sc, BWI_MAC_INTR_MASK);
534	if (intr_status == 0)		/* Nothing is interesting */
535		return (0);
536
537	DPRINTF(2, "%s: intr status 0x%08x\n",
538	    sc->sc_dev.dv_xname, intr_status);
539
540	txrx_error = 0;
541
542	for (i = 0; i < BWI_TXRX_NRING; ++i) {
543		uint32_t mask;
544
545		if (BWI_TXRX_IS_RX(i))
546			mask = BWI_TXRX_RX_INTRS;
547		else
548			mask = BWI_TXRX_TX_INTRS;
549
550		txrx_intr_status[i] =
551		    CSR_READ_4(sc, BWI_TXRX_INTR_STATUS(i)) & mask;
552
553		if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) {
554			DPRINTF(1, "%s: intr fatal TX/RX (%d) error 0x%08x\n",
555			    sc->sc_dev.dv_xname, i, txrx_intr_status[i]);
556			txrx_error = 1;
557		}
558	}
559
560	/*
561	 * Acknowledge interrupt
562	 */
563	CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, intr_status);
564
565	for (i = 0; i < BWI_TXRX_NRING; ++i)
566		CSR_WRITE_4(sc, BWI_TXRX_INTR_STATUS(i), txrx_intr_status[i]);
567
568	/* Disable all interrupts */
569	bwi_disable_intrs(sc, BWI_ALL_INTRS);
570
571	if (intr_status & BWI_INTR_PHY_TXERR)
572		DPRINTF(1, "%s: intr PHY TX error\n", sc->sc_dev.dv_xname);
573
574	if (txrx_error) {
575		/* TODO: reset device */
576	}
577
578	if (intr_status & BWI_INTR_TBTT) {
579		KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
580		bwi_mac_config_ps((struct bwi_mac *)sc->sc_cur_regwin);
581	}
582
583	if (intr_status & BWI_INTR_EO_ATIM)
584		DPRINTF(1, "%s: EO_ATIM\n", sc->sc_dev.dv_xname);
585
586	if (intr_status & BWI_INTR_PMQ) {
587		for (;;) {
588			if ((CSR_READ_4(sc, BWI_MAC_PS_STATUS) & 0x8) == 0)
589				break;
590		}
591		CSR_WRITE_2(sc, BWI_MAC_PS_STATUS, 0x2);
592	}
593
594	if (intr_status & BWI_INTR_NOISE)
595		DPRINTF(1, "%s: intr noise\n", sc->sc_dev.dv_xname);
596
597	if (txrx_intr_status[0] & BWI_TXRX_INTR_RX)
598		sc->sc_rxeof(sc);
599
600	if (txrx_intr_status[3] & BWI_TXRX_INTR_RX)
601		sc->sc_txeof_status(sc);
602
603	if (intr_status & BWI_INTR_TX_DONE)
604		bwi_txeof(sc);
605
606	/* TODO: LED */
607
608	/* Re-enable interrupts */
609	bwi_enable_intrs(sc, BWI_INIT_INTRS);
610
611	return (1);
612}
613
614int
615bwi_attach(struct bwi_softc *sc)
616{
617	struct ieee80211com *ic = &sc->sc_ic;
618	struct ifnet *ifp = &ic->ic_if;
619	struct bwi_mac *mac;
620	struct bwi_phy *phy;
621	int i, error;
622
623	printf("\n");
624
625	/* AMRR rate control */
626	sc->sc_amrr.amrr_min_success_threshold = 1;
627	sc->sc_amrr.amrr_max_success_threshold = 15;
628	timeout_set(&sc->sc_amrr_ch, bwi_amrr_timeout, sc);
629
630	timeout_set(&sc->sc_scan_ch, bwi_next_scan, sc);
631	timeout_set(&sc->sc_calib_ch, bwi_calibrate, sc);
632
633	bwi_power_on(sc, 1);
634
635	error = bwi_bbp_attach(sc);
636	if (error)
637		goto fail;
638
639	error = bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
640	if (error)
641		goto fail;
642
643	if (BWI_REGWIN_EXIST(&sc->sc_com_regwin)) {
644		error = bwi_set_clock_delay(sc);
645		if (error)
646			goto fail;
647
648		error = bwi_set_clock_mode(sc, BWI_CLOCK_MODE_FAST);
649		if (error)
650			goto fail;
651
652		error = bwi_get_pwron_delay(sc);
653		if (error)
654			goto fail;
655	}
656
657	error = bwi_bus_attach(sc);
658	if (error)
659		goto fail;
660
661	bwi_get_card_flags(sc);
662
663	/* TODO: LED */
664
665	for (i = 0; i < sc->sc_nmac; ++i) {
666		struct bwi_regwin *old;
667
668		mac = &sc->sc_mac[i];
669		error = bwi_regwin_switch(sc, &mac->mac_regwin, &old);
670		if (error)
671			goto fail;
672
673		error = bwi_mac_lateattach(mac);
674		if (error)
675			goto fail;
676
677		error = bwi_regwin_switch(sc, old, NULL);
678		if (error)
679			goto fail;
680	}
681
682	/*
683	 * XXX First MAC is known to exist
684	 * TODO2
685	 */
686	mac = &sc->sc_mac[0];
687	phy = &mac->mac_phy;
688
689	bwi_bbp_power_off(sc);
690
691	error = bwi_dma_alloc(sc);
692	if (error)
693		goto fail;
694
695	/* setup interface */
696	ifp->if_softc = sc;
697	ifp->if_init = bwi_init;
698	ifp->if_ioctl = bwi_ioctl;
699	ifp->if_start = bwi_start;
700	ifp->if_watchdog = bwi_watchdog;
701	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
702	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
703	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
704	IFQ_SET_READY(&ifp->if_snd);
705
706	/* Get locale */
707	sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO),
708	    BWI_SPROM_CARD_INFO_LOCALE);
709	DPRINTF(1, "%s: locale: %d\n", sc->sc_dev.dv_xname, sc->sc_locale);
710
711	/*
712	 * Setup ratesets, phytype, channels and get MAC address
713	 */
714	if (phy->phy_mode == IEEE80211_MODE_11B ||
715	    phy->phy_mode == IEEE80211_MODE_11G) {
716	    	uint16_t chan_flags;
717
718		ic->ic_sup_rates[IEEE80211_MODE_11B] =
719		    ieee80211_std_rateset_11b;
720
721		if (phy->phy_mode == IEEE80211_MODE_11B) {
722			chan_flags = IEEE80211_CHAN_B;
723			ic->ic_phytype = IEEE80211_T_DS;
724		} else {
725			chan_flags = IEEE80211_CHAN_CCK |
726			    IEEE80211_CHAN_OFDM |
727			    IEEE80211_CHAN_DYN |
728			    IEEE80211_CHAN_2GHZ;
729			ic->ic_phytype = IEEE80211_T_OFDM;
730			ic->ic_sup_rates[IEEE80211_MODE_11G] =
731			    ieee80211_std_rateset_11g;
732		}
733
734		/* XXX depend on locale */
735		for (i = 1; i <= 14; ++i) {
736			ic->ic_channels[i].ic_freq =
737				ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
738			ic->ic_channels[i].ic_flags = chan_flags;
739		}
740
741		bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, ic->ic_myaddr);
742		if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)) {
743			bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, ic->ic_myaddr);
744			if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)) {
745				DPRINTF(1, "%s: invalid MAC address: %s\n",
746				    sc->sc_dev.dv_xname,
747				    ether_sprintf(ic->ic_myaddr));
748			}
749		}
750	} else if (phy->phy_mode == IEEE80211_MODE_11A) {
751		/* TODO: 11A */
752		error = ENXIO;
753		goto fail;
754	} else
755		panic("unknown phymode %d\n", phy->phy_mode);
756
757	sc->sc_fw_version = BWI_FW_VERSION3;
758	sc->sc_dwell_time = 200;
759
760	ic->ic_caps = IEEE80211_C_SHSLOT |
761	    IEEE80211_C_SHPREAMBLE |
762	    IEEE80211_C_WEP |
763	    IEEE80211_C_MONITOR;
764	ic->ic_state = IEEE80211_S_INIT;
765	ic->ic_opmode = IEEE80211_M_STA;
766
767	ic->ic_updateslot = bwi_updateslot;
768
769	if_attach(ifp);
770	ieee80211_ifattach(ifp);
771
772	sc->sc_newstate = ic->ic_newstate;
773	ic->ic_newstate = bwi_newstate;
774	ic->ic_newassoc = bwi_newassoc;
775
776	ieee80211_media_init(ifp, bwi_media_change, ieee80211_media_status);
777
778	if (error) {
779		ieee80211_ifdetach(ifp);
780		goto fail;
781	}
782
783#if NBPFILTER > 0
784	bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
785	    sizeof(struct ieee80211_frame) + 64);
786
787	sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
788	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
789	sc->sc_rxtap.wr_ihdr.it_present = htole32(BWI_RX_RADIOTAP_PRESENT);
790
791	sc->sc_txtap_len = sizeof(sc->sc_txtapu);
792	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
793	sc->sc_txtap.wt_ihdr.it_present = htole32(BWI_TX_RADIOTAP_PRESENT);
794#endif
795
796	return (0);
797fail:
798	return (error);
799}
800
801int
802bwi_detach(void *arg)
803{
804	struct bwi_softc *sc = arg;
805	struct ifnet *ifp = &sc->sc_ic.ic_if;
806	int i;
807
808	bwi_stop(sc);
809	ieee80211_ifdetach(ifp);
810	if_detach(ifp);
811
812	for (i = 0; i < sc->sc_nmac; ++i)
813		bwi_mac_detach(&sc->sc_mac[i]);
814
815	bwi_dma_free(sc);
816
817	return (0);
818}
819
820void
821bwi_tmplt_write_4(struct bwi_mac *mac, uint32_t ofs, uint32_t val)
822{
823	struct bwi_softc *sc = mac->mac_sc;
824
825	if (mac->mac_flags & BWI_MAC_F_BSWAP)
826		val = swap32(val);
827
828	CSR_WRITE_4(sc, BWI_MAC_TMPLT_CTRL, ofs);
829	CSR_WRITE_4(sc, BWI_MAC_TMPLT_DATA, val);
830}
831
832void
833bwi_hostflags_write(struct bwi_mac *mac, uint64_t flags)
834{
835	uint64_t val;
836
837	val = flags & 0xffff;
838	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO, val);
839
840	val = (flags >> 16) & 0xffff;
841	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI, val);
842
843	/* HI has unclear meaning, so leave it as it is */
844}
845
846uint64_t
847bwi_hostflags_read(struct bwi_mac *mac)
848{
849	uint64_t flags, val;
850
851	/* HI has unclear meaning, so don't touch it */
852	flags = 0;
853
854	val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI);
855	flags |= val << 16;
856
857	val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO);
858	flags |= val;
859
860	return (flags);
861}
862
863uint16_t
864bwi_memobj_read_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0)
865{
866	struct bwi_softc *sc = mac->mac_sc;
867	uint32_t data_reg;
868	int ofs;
869
870	data_reg = BWI_MOBJ_DATA;
871	ofs = ofs0 / 4;
872
873	if (ofs0 % 4 != 0)
874		data_reg = BWI_MOBJ_DATA_UNALIGN;
875
876	CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
877	return (CSR_READ_2(sc, data_reg));
878}
879
880uint32_t
881bwi_memobj_read_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0)
882{
883	struct bwi_softc *sc = mac->mac_sc;
884	int ofs;
885
886	ofs = ofs0 / 4;
887	if (ofs0 % 4 != 0) {
888		uint32_t ret;
889
890		CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
891		ret = CSR_READ_2(sc, BWI_MOBJ_DATA_UNALIGN);
892		ret <<= 16;
893
894		CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
895		    BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1));
896		ret |= CSR_READ_2(sc, BWI_MOBJ_DATA);
897
898		return (ret);
899	} else {
900		CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
901		return (CSR_READ_4(sc, BWI_MOBJ_DATA));
902	}
903}
904
905void
906bwi_memobj_write_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0,
907    uint16_t v)
908{
909	struct bwi_softc *sc = mac->mac_sc;
910	uint32_t data_reg;
911	int ofs;
912
913	data_reg = BWI_MOBJ_DATA;
914	ofs = ofs0 / 4;
915
916	if (ofs0 % 4 != 0)
917		data_reg = BWI_MOBJ_DATA_UNALIGN;
918
919	CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
920	CSR_WRITE_2(sc, data_reg, v);
921}
922
923void
924bwi_memobj_write_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0,
925    uint32_t v)
926{
927	struct bwi_softc *sc = mac->mac_sc;
928	int ofs;
929
930	ofs = ofs0 / 4;
931	if (ofs0 % 4 != 0) {
932		CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
933		CSR_WRITE_2(sc, BWI_MOBJ_DATA_UNALIGN, v >> 16);
934		CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
935		    BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1));
936		CSR_WRITE_2(sc, BWI_MOBJ_DATA, v & 0xffff);
937	} else {
938		CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
939		CSR_WRITE_4(sc, BWI_MOBJ_DATA, v);
940	}
941}
942
943int
944bwi_mac_lateattach(struct bwi_mac *mac)
945{
946	int error;
947
948	if (mac->mac_rev >= 5)
949		CSR_READ_4(mac->mac_sc, BWI_STATE_HI); /* dummy read */
950
951	bwi_mac_reset(mac, 1);
952
953	error = bwi_phy_attach(mac);
954	if (error)
955		return (error);
956
957	error = bwi_rf_attach(mac);
958	if (error)
959		return (error);
960
961	/* Link 11B/G PHY, unlink 11A PHY */
962	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A)
963		bwi_mac_reset(mac, 0);
964	else
965		bwi_mac_reset(mac, 1);
966
967	error = bwi_mac_test(mac);
968	if (error)
969		return (error);
970
971	error = bwi_mac_get_property(mac);
972	if (error)
973		return (error);
974
975	error = bwi_rf_map_txpower(mac);
976	if (error)
977		return (error);
978
979	bwi_rf_off(mac);
980	CSR_WRITE_2(mac->mac_sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC);
981	bwi_regwin_disable(mac->mac_sc, &mac->mac_regwin, 0);
982
983	return (0);
984}
985
986int
987bwi_mac_init(struct bwi_mac *mac)
988{
989	struct bwi_softc *sc = mac->mac_sc;
990	int error, i;
991
992	/* Clear MAC/PHY/RF states */
993	bwi_mac_setup_tpctl(mac);
994	bwi_rf_clear_state(&mac->mac_rf);
995	bwi_phy_clear_state(&mac->mac_phy);
996
997	/* Enable MAC and linked it to PHY */
998	if (!bwi_regwin_is_enabled(sc, &mac->mac_regwin))
999		bwi_mac_reset(mac, 1);
1000
1001	/* Initialize backplane */
1002	error = bwi_bus_init(sc, mac);
1003	if (error)
1004		return (error);
1005
1006	/* XXX work around for hardware bugs? */
1007	if (sc->sc_bus_regwin.rw_rev <= 5 &&
1008	    sc->sc_bus_regwin.rw_type != BWI_REGWIN_T_BUSPCIE) {
1009		CSR_SETBITS_4(sc, BWI_CONF_LO,
1010		__SHIFTIN(BWI_CONF_LO_SERVTO, BWI_CONF_LO_SERVTO_MASK) |
1011		__SHIFTIN(BWI_CONF_LO_REQTO, BWI_CONF_LO_REQTO_MASK));
1012	}
1013
1014	/* Calibrate PHY */
1015	error = bwi_phy_calibrate(mac);
1016	if (error) {
1017		printf("%s: PHY calibrate failed\n", sc->sc_dev.dv_xname);
1018		return (error);
1019	}
1020
1021	/* Prepare to initialize firmware */
1022	CSR_WRITE_4(sc, BWI_MAC_STATUS,
1023	    BWI_MAC_STATUS_UCODE_JUMP0 |
1024	    BWI_MAC_STATUS_IHREN);
1025
1026	/*
1027	 * Load and initialize firmwares
1028	 */
1029	error = bwi_mac_fw_alloc(mac);
1030	if (error)
1031		return (error);
1032
1033	error = bwi_mac_fw_load(mac);
1034	if (error)
1035		return (error);
1036
1037	error = bwi_mac_gpio_init(mac);
1038	if (error)
1039		return (error);
1040
1041	error = bwi_mac_fw_init(mac);
1042	if (error)
1043		return (error);
1044
1045	/*
1046	 * Turn on RF
1047	 */
1048	bwi_rf_on(mac);
1049
1050	/* TODO: LED, hardware rf enabled is only related to LED setting */
1051
1052	/*
1053	 * Initialize PHY
1054	 */
1055	CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
1056	bwi_phy_init(mac);
1057
1058	/* TODO: interference mitigation */
1059
1060	/*
1061	 * Setup antenna mode
1062	 */
1063	bwi_rf_set_ant_mode(mac, mac->mac_rf.rf_ant_mode);
1064
1065	/*
1066	 * Initialize operation mode (RX configuration)
1067	 */
1068	bwi_mac_opmode_init(mac);
1069
1070	/* XXX what's these */
1071	if (mac->mac_rev < 3) {
1072		CSR_WRITE_2(sc, 0x60e, 0);
1073		CSR_WRITE_2(sc, 0x610, 0x8000);
1074		CSR_WRITE_2(sc, 0x604, 0);
1075		CSR_WRITE_2(sc, 0x606, 0x200);
1076	} else {
1077		CSR_WRITE_4(sc, 0x188, 0x80000000);
1078		CSR_WRITE_4(sc, 0x18c, 0x2000000);
1079	}
1080
1081	/*
1082	 * Initialize TX/RX interrupts' mask
1083	 */
1084	CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_TIMER1);
1085	for (i = 0; i < BWI_TXRX_NRING; ++i) {
1086		uint32_t intrs;
1087
1088		if (BWI_TXRX_IS_RX(i))
1089			intrs = BWI_TXRX_RX_INTRS;
1090		else
1091			intrs = BWI_TXRX_TX_INTRS;
1092		CSR_WRITE_4(sc, BWI_TXRX_INTR_MASK(i), intrs);
1093	}
1094
1095	/* XXX what's this */
1096	CSR_SETBITS_4(sc, BWI_STATE_LO, 0x100000);
1097
1098	/* Setup MAC power up delay */
1099	CSR_WRITE_2(sc, BWI_MAC_POWERUP_DELAY, sc->sc_pwron_delay);
1100
1101	/* Set MAC regwin revision */
1102	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_MACREV, mac->mac_rev);
1103
1104	/*
1105	 * Initialize host flags
1106	 */
1107	bwi_mac_hostflags_init(mac);
1108
1109	/*
1110	 * Initialize BSS parameters
1111	 */
1112	bwi_mac_bss_param_init(mac);
1113
1114	/*
1115	 * Initialize TX rings
1116	 */
1117	for (i = 0; i < BWI_TX_NRING; ++i) {
1118		error = sc->sc_init_tx_ring(sc, i);
1119		if (error) {
1120			printf("%s: can't initialize %dth TX ring\n",
1121			    sc->sc_dev.dv_xname, i);
1122			return (error);
1123		}
1124	}
1125
1126	/*
1127	 * Initialize RX ring
1128	 */
1129	error = sc->sc_init_rx_ring(sc);
1130	if (error) {
1131		DPRINTF(1, "can't initialize RX ring\n");
1132		return (error);
1133	}
1134
1135	/*
1136	 * Initialize TX stats if the current MAC uses that
1137	 */
1138	if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) {
1139		error = sc->sc_init_txstats(sc);
1140		if (error) {
1141			DPRINTF(1, "%s: can't initialize TX stats ring\n",
1142			    sc->sc_dev.dv_xname);
1143			return (error);
1144		}
1145	}
1146
1147	/* XXX what's these */
1148	CSR_WRITE_2(sc, 0x612, 0x50);	/* Force Pre-TBTT to 80? */
1149	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x416, 0x50);
1150	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x414, 0x1f4);
1151
1152	mac->mac_flags |= BWI_MAC_F_INITED;
1153
1154	return (0);
1155}
1156
1157void
1158bwi_mac_reset(struct bwi_mac *mac, int link_phy)
1159{
1160	struct bwi_softc *sc = mac->mac_sc;
1161	uint32_t flags, state_lo, status;
1162
1163	flags = BWI_STATE_LO_FLAG_PHYRST | BWI_STATE_LO_FLAG_PHYCLKEN;
1164	if (link_phy)
1165		flags |= BWI_STATE_LO_FLAG_PHYLNK;
1166	bwi_regwin_enable(sc, &mac->mac_regwin, flags);
1167	DELAY(2000);
1168
1169	state_lo = CSR_READ_4(sc, BWI_STATE_LO);
1170	state_lo |= BWI_STATE_LO_GATED_CLOCK;
1171	state_lo &= ~__SHIFTIN(BWI_STATE_LO_FLAG_PHYRST,
1172			       BWI_STATE_LO_FLAGS_MASK);
1173	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
1174	/* Flush pending bus write */
1175	CSR_READ_4(sc, BWI_STATE_LO);
1176	DELAY(1000);
1177
1178	state_lo &= ~BWI_STATE_LO_GATED_CLOCK;
1179	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
1180	/* Flush pending bus write */
1181	CSR_READ_4(sc, BWI_STATE_LO);
1182	DELAY(1000);
1183
1184	CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
1185
1186	status = CSR_READ_4(sc, BWI_MAC_STATUS);
1187	status |= BWI_MAC_STATUS_IHREN;
1188	if (link_phy)
1189		status |= BWI_MAC_STATUS_PHYLNK;
1190	else
1191		status &= ~BWI_MAC_STATUS_PHYLNK;
1192	CSR_WRITE_4(sc, BWI_MAC_STATUS, status);
1193
1194	if (link_phy) {
1195		DPRINTF(1, "%s: PHY is linked\n", sc->sc_dev.dv_xname);
1196		mac->mac_phy.phy_flags |= BWI_PHY_F_LINKED;
1197	} else {
1198		DPRINTF(1, "%s: PHY is unlinked\n", sc->sc_dev.dv_xname);
1199		mac->mac_phy.phy_flags &= ~BWI_PHY_F_LINKED;
1200	}
1201}
1202
1203void
1204bwi_mac_set_tpctl_11bg(struct bwi_mac *mac, const struct bwi_tpctl *new_tpctl)
1205{
1206	struct bwi_rf *rf = &mac->mac_rf;
1207	struct bwi_tpctl *tpctl = &mac->mac_tpctl;
1208
1209	if (new_tpctl != NULL) {
1210		KKASSERT(new_tpctl->bbp_atten <= BWI_BBP_ATTEN_MAX);
1211		KKASSERT(new_tpctl->rf_atten <=
1212		    (rf->rf_rev < 6 ? BWI_RF_ATTEN_MAX0
1213		    : BWI_RF_ATTEN_MAX1));
1214		KKASSERT(new_tpctl->tp_ctrl1 <= BWI_TPCTL1_MAX);
1215
1216		tpctl->bbp_atten = new_tpctl->bbp_atten;
1217		tpctl->rf_atten = new_tpctl->rf_atten;
1218		tpctl->tp_ctrl1 = new_tpctl->tp_ctrl1;
1219	}
1220
1221	/* Set BBP attenuation */
1222	bwi_phy_set_bbp_atten(mac, tpctl->bbp_atten);
1223
1224	/* Set RF attenuation */
1225	RF_WRITE(mac, BWI_RFR_ATTEN, tpctl->rf_atten);
1226	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RF_ATTEN,
1227	    tpctl->rf_atten);
1228
1229	/* Set TX power */
1230	if (rf->rf_type == BWI_RF_T_BCM2050) {
1231		RF_FILT_SETBITS(mac, BWI_RFR_TXPWR, ~BWI_RFR_TXPWR1_MASK,
1232		    __SHIFTIN(tpctl->tp_ctrl1, BWI_RFR_TXPWR1_MASK));
1233	}
1234
1235	/* Adjust RF Local Oscillator */
1236	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
1237		bwi_rf_lo_adjust(mac, tpctl);
1238}
1239
1240int
1241bwi_mac_test(struct bwi_mac *mac)
1242{
1243	struct bwi_softc *sc = mac->mac_sc;
1244	uint32_t orig_val, val;
1245
1246#define TEST_VAL1	0xaa5555aa
1247#define TEST_VAL2	0x55aaaa55
1248	/* Save it for later restoring */
1249	orig_val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
1250
1251	/* Test 1 */
1252	MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL1);
1253	val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
1254	if (val != TEST_VAL1) {
1255		DPRINTF(1, "%s: TEST1 failed\n", sc->sc_dev.dv_xname);
1256		return (ENXIO);
1257	}
1258
1259	/* Test 2 */
1260	MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL2);
1261	val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
1262	if (val != TEST_VAL2) {
1263		DPRINTF(1, "%s: TEST2 failed\n", sc->sc_dev.dv_xname);
1264		return (ENXIO);
1265	}
1266
1267	/* Restore to the original value */
1268	MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, orig_val);
1269
1270	val = CSR_READ_4(sc, BWI_MAC_STATUS);
1271	if ((val & ~BWI_MAC_STATUS_PHYLNK) != BWI_MAC_STATUS_IHREN) {
1272		DPRINTF(1, "%s: %s failed, MAC status 0x%08x\n",
1273		    sc->sc_dev.dv_xname, __func__, val);
1274		return (ENXIO);
1275	}
1276
1277	val = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
1278	if (val != 0) {
1279		DPRINTF(1, "%s: %s failed, intr status %08x\n",
1280		    sc->sc_dev.dv_xname, __func__, val);
1281		return (ENXIO);
1282	}
1283#undef TEST_VAL2
1284#undef TEST_VAL1
1285
1286	return (0);
1287}
1288
1289void
1290bwi_mac_setup_tpctl(struct bwi_mac *mac)
1291{
1292	struct bwi_softc *sc = mac->mac_sc;
1293	struct bwi_rf *rf = &mac->mac_rf;
1294	struct bwi_phy *phy = &mac->mac_phy;
1295	struct bwi_tpctl *tpctl = &mac->mac_tpctl;
1296
1297	/* Calc BBP attenuation */
1298	if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev < 6)
1299		tpctl->bbp_atten = 0;
1300	else
1301		tpctl->bbp_atten = 2;
1302
1303	/* Calc TX power CTRL1?? */
1304	tpctl->tp_ctrl1 = 0;
1305	if (rf->rf_type == BWI_RF_T_BCM2050) {
1306		if (rf->rf_rev == 1)
1307			tpctl->tp_ctrl1 = 3;
1308		else if (rf->rf_rev < 6)
1309			tpctl->tp_ctrl1 = 2;
1310		else if (rf->rf_rev == 8)
1311			tpctl->tp_ctrl1 = 1;
1312	}
1313
1314	/* Empty TX power CTRL2?? */
1315	tpctl->tp_ctrl2 = 0xffff;
1316
1317	/*
1318	 * Calc RF attenuation
1319	 */
1320	if (phy->phy_mode == IEEE80211_MODE_11A) {
1321		tpctl->rf_atten = 0x60;
1322		goto back;
1323	}
1324
1325	if (BWI_IS_BRCM_BCM4309G(sc) && sc->sc_pci_revid < 0x51) {
1326		tpctl->rf_atten = sc->sc_pci_revid < 0x43 ? 2 : 3;
1327		goto back;
1328	}
1329
1330	tpctl->rf_atten = 5;
1331
1332	if (rf->rf_type != BWI_RF_T_BCM2050) {
1333		if (rf->rf_type == BWI_RF_T_BCM2053 && rf->rf_rev == 1)
1334			tpctl->rf_atten = 6;
1335		goto back;
1336	}
1337
1338	/*
1339	 * NB: If we reaches here and the card is BRCM_BCM4309G,
1340	 *     then the card's PCI revision must >= 0x51
1341	 */
1342
1343	/* BCM2050 RF */
1344	switch (rf->rf_rev) {
1345	case 1:
1346		if (phy->phy_mode == IEEE80211_MODE_11G) {
1347			if (BWI_IS_BRCM_BCM4309G(sc) || BWI_IS_BRCM_BU4306(sc))
1348				tpctl->rf_atten = 3;
1349			else
1350				tpctl->rf_atten = 1;
1351		} else {
1352			if (BWI_IS_BRCM_BCM4309G(sc))
1353				tpctl->rf_atten = 7;
1354			else
1355				tpctl->rf_atten = 6;
1356		}
1357		break;
1358	case 2:
1359		if (phy->phy_mode == IEEE80211_MODE_11G) {
1360			/*
1361			 * NOTE: Order of following conditions is critical
1362			 */
1363			if (BWI_IS_BRCM_BCM4309G(sc))
1364				tpctl->rf_atten = 3;
1365			else if (BWI_IS_BRCM_BU4306(sc))
1366				tpctl->rf_atten = 5;
1367			else if (sc->sc_bbp_id == BWI_BBPID_BCM4320)
1368				tpctl->rf_atten = 4;
1369			else
1370				tpctl->rf_atten = 3;
1371		} else {
1372			tpctl->rf_atten = 6;
1373		}
1374		break;
1375	case 4:
1376	case 5:
1377		tpctl->rf_atten = 1;
1378		break;
1379	case 8:
1380		tpctl->rf_atten = 0x1a;
1381		break;
1382	}
1383back:
1384	DPRINTF(1, "%s: bbp atten: %u, rf atten: %u, ctrl1: %u, ctrl2: %u\n",
1385	    sc->sc_dev.dv_xname, tpctl->bbp_atten, tpctl->rf_atten,
1386	    tpctl->tp_ctrl1, tpctl->tp_ctrl2);
1387}
1388
1389void
1390bwi_mac_dummy_xmit(struct bwi_mac *mac)
1391{
1392#define PACKET_LEN	5
1393	struct bwi_softc *sc = mac->mac_sc;
1394	struct bwi_rf *rf = &mac->mac_rf;
1395	const uint32_t *packet;
1396	uint16_t val_50c;
1397	int wait_max, i;
1398
1399	static const uint32_t	packet_11a[PACKET_LEN] =
1400	    { 0x000201cc, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
1401	static const uint32_t	packet_11bg[PACKET_LEN] =
1402	    { 0x000b846e, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
1403
1404	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) {
1405		wait_max = 30;
1406		packet = packet_11a;
1407		val_50c = 1;
1408	} else {
1409		wait_max = 250;
1410		packet = packet_11bg;
1411		val_50c = 0;
1412	}
1413
1414	for (i = 0; i < PACKET_LEN; ++i)
1415		TMPLT_WRITE_4(mac, i * 4, packet[i]);
1416
1417	CSR_READ_4(sc, BWI_MAC_STATUS);	/* dummy read */
1418
1419	CSR_WRITE_2(sc, 0x568, 0);
1420	CSR_WRITE_2(sc, 0x7c0, 0);
1421	CSR_WRITE_2(sc, 0x50c, val_50c);
1422	CSR_WRITE_2(sc, 0x508, 0);
1423	CSR_WRITE_2(sc, 0x50a, 0);
1424	CSR_WRITE_2(sc, 0x54c, 0);
1425	CSR_WRITE_2(sc, 0x56a, 0x14);
1426	CSR_WRITE_2(sc, 0x568, 0x826);
1427	CSR_WRITE_2(sc, 0x500, 0);
1428	CSR_WRITE_2(sc, 0x502, 0x30);
1429
1430	if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5)
1431		RF_WRITE(mac, 0x51, 0x17);
1432
1433	for (i = 0; i < wait_max; ++i) {
1434		if (CSR_READ_2(sc, 0x50e) & 0x80)
1435			break;
1436		DELAY(10);
1437	}
1438	for (i = 0; i < 10; ++i) {
1439		if (CSR_READ_2(sc, 0x50e) & 0x400)
1440			break;
1441		DELAY(10);
1442	}
1443	for (i = 0; i < 10; ++i) {
1444		if ((CSR_READ_2(sc, 0x690) & 0x100) == 0)
1445			break;
1446		DELAY(10);
1447	}
1448
1449	if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5)
1450		RF_WRITE(mac, 0x51, 0x37);
1451#undef PACKET_LEN
1452}
1453
1454void
1455bwi_mac_init_tpctl_11bg(struct bwi_mac *mac)
1456{
1457	struct bwi_softc *sc = mac->mac_sc;
1458	struct bwi_phy *phy = &mac->mac_phy;
1459	struct bwi_rf *rf = &mac->mac_rf;
1460	struct bwi_tpctl tpctl_orig;
1461	int restore_tpctl = 0;
1462
1463	KKASSERT(phy->phy_mode != IEEE80211_MODE_11A);
1464
1465	if (BWI_IS_BRCM_BU4306(sc))
1466		return;
1467
1468	PHY_WRITE(mac, 0x28, 0x8018);
1469	CSR_CLRBITS_2(sc, BWI_BBP_ATTEN, 0x20);
1470
1471	if (phy->phy_mode == IEEE80211_MODE_11G) {
1472		if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
1473			return;
1474		PHY_WRITE(mac, 0x47a, 0xc111);
1475	}
1476	if (mac->mac_flags & BWI_MAC_F_TPCTL_INITED)
1477		return;
1478
1479	if (phy->phy_mode == IEEE80211_MODE_11B && phy->phy_rev >= 2 &&
1480	    rf->rf_type == BWI_RF_T_BCM2050) {
1481		RF_SETBITS(mac, 0x76, 0x84);
1482	} else {
1483		struct bwi_tpctl tpctl;
1484
1485		/* Backup original TX power control variables */
1486		bcopy(&mac->mac_tpctl, &tpctl_orig, sizeof(tpctl_orig));
1487		restore_tpctl = 1;
1488
1489		bcopy(&mac->mac_tpctl, &tpctl, sizeof(tpctl));
1490		tpctl.bbp_atten = 11;
1491		tpctl.tp_ctrl1 = 0;
1492#ifdef notyet
1493		if (rf->rf_rev >= 6 && rf->rf_rev <= 8)
1494			tpctl.rf_atten = 31;
1495		else
1496#endif
1497			tpctl.rf_atten = 9;
1498
1499		bwi_mac_set_tpctl_11bg(mac, &tpctl);
1500	}
1501
1502	bwi_mac_dummy_xmit(mac);
1503
1504	mac->mac_flags |= BWI_MAC_F_TPCTL_INITED;
1505	rf->rf_base_tssi = PHY_READ(mac, 0x29);
1506	DPRINTF(1, "%s: base tssi %d\n", sc->sc_dev.dv_xname, rf->rf_base_tssi);
1507
1508	if (abs(rf->rf_base_tssi - rf->rf_idle_tssi) >= 20) {
1509		printf("%s: base tssi measure failed\n", sc->sc_dev.dv_xname);
1510		mac->mac_flags |= BWI_MAC_F_TPCTL_ERROR;
1511	}
1512
1513	if (restore_tpctl)
1514		bwi_mac_set_tpctl_11bg(mac, &tpctl_orig);
1515	else
1516		RF_CLRBITS(mac, 0x76, 0x84);
1517
1518	bwi_rf_clear_tssi(mac);
1519}
1520
1521void
1522bwi_mac_detach(struct bwi_mac *mac)
1523{
1524	bwi_mac_fw_free(mac);
1525}
1526
1527int
1528bwi_get_firmware(const char *name, const uint8_t *ucode, size_t size_ucode,
1529    size_t *size, size_t *offset)
1530{
1531	int i, nfiles, off = 0, ret = 1;
1532	struct fwheader *h;
1533
1534	if ((h = malloc(sizeof(struct fwheader), M_DEVBUF, M_NOWAIT)) == NULL)
1535		return (ret);
1536
1537	/* get number of firmware files */
1538	bcopy(ucode, &nfiles, sizeof(nfiles));
1539	nfiles = ntohl(nfiles);
1540	off += sizeof(nfiles);
1541
1542	/* parse header and search the firmware */
1543	for (i = 0; i < nfiles && off < size_ucode; i++) {
1544		bzero(h, sizeof(struct fwheader));
1545		bcopy(ucode + off, h, sizeof(struct fwheader));
1546		off += sizeof(struct fwheader);
1547
1548		if (strcmp(name, h->filename) == 0) {
1549			ret = 0;
1550			*size = ntohl(h->filesize);
1551			*offset = ntohl(h->fileoffset);
1552			break;
1553		}
1554	}
1555
1556	free(h, M_DEVBUF);
1557
1558	return (ret);
1559}
1560
1561int
1562bwi_fwimage_is_valid(struct bwi_softc *sc, uint8_t *fw, size_t fw_len,
1563    char *fw_name, uint8_t fw_type)
1564{
1565	const struct bwi_fwhdr *hdr;
1566
1567	if (fw_len < sizeof(*hdr)) {
1568		printf("%s: invalid firmware (%s): invalid size %u\n",
1569		    sc->sc_dev.dv_xname, fw_name, fw_len);
1570		return (1);
1571	}
1572
1573	hdr = (const struct bwi_fwhdr *)fw;
1574
1575	if (fw_type != BWI_FW_T_IV) {
1576		/*
1577		 * Don't verify IV's size, it has different meaning
1578		 */
1579		if (betoh32(hdr->fw_size) != fw_len - sizeof(*hdr)) {
1580			printf("%s: invalid firmware (%s): size mismatch, "
1581			    "fw %u, real %u\n",
1582			    sc->sc_dev.dv_xname,
1583			    fw_name,
1584			    betoh32(hdr->fw_size),
1585			    fw_len - sizeof(*hdr));
1586			return (1);
1587		}
1588	}
1589
1590	if (hdr->fw_type != fw_type) {
1591		printf("%s: invalid firmware (%s): type mismatch, "
1592		    "fw \'%c\', target \'%c\'\n",
1593		    sc->sc_dev.dv_xname, fw_name, hdr->fw_type, fw_type);
1594		return (1);
1595	}
1596
1597	if (hdr->fw_gen != BWI_FW_GEN_1) {
1598		printf("%s: invalid firmware (%s): wrong generation, "
1599		    "fw %d, target %d\n",
1600		    sc->sc_dev.dv_xname, fw_name, hdr->fw_gen, BWI_FW_GEN_1);
1601		return (1);
1602	}
1603
1604	return (0);
1605}
1606
1607int
1608bwi_mac_fw_alloc(struct bwi_mac *mac)
1609{
1610	struct bwi_softc *sc = mac->mac_sc;
1611	char fwname[64];
1612	int idx, error;
1613
1614	if (mac->mac_ucode == NULL) {
1615		snprintf(fwname, sizeof(fwname), "ucode%d.fw",
1616		    mac->mac_rev >= 5 ? 5 : mac->mac_rev);
1617
1618		error = loadfirmware(fwname, &mac->mac_ucode,
1619		    &mac->mac_ucode_size);
1620		if (error != 0) {
1621			printf("%s: error %d, could not read firmware %s!\n",
1622			    sc->sc_dev.dv_xname, error, fwname);
1623			return (ENOMEM);
1624		}
1625		DPRINTF(1, "%s: loaded firmware file %s\n",
1626		    sc->sc_dev.dv_xname, fwname);
1627
1628		if (bwi_fwimage_is_valid(sc, mac->mac_ucode,
1629		    mac->mac_ucode_size, fwname, BWI_FW_T_UCODE))
1630			return (EINVAL);
1631	}
1632
1633	if (mac->mac_pcm == NULL) {
1634		snprintf(fwname, sizeof(fwname), "pcm%d.fw",
1635		    mac->mac_rev < 5 ? 4 : 5);
1636
1637		error = loadfirmware(fwname, &mac->mac_pcm,
1638		    &mac->mac_pcm_size);
1639		if (error != 0) {
1640			printf("%s: error %d, could not read firmware %s!\n",
1641			    sc->sc_dev.dv_xname, error, fwname);
1642			return (ENOMEM);
1643		}
1644		DPRINTF(1, "%s: loaded firmware file %s\n",
1645		    sc->sc_dev.dv_xname, fwname);
1646
1647		if (bwi_fwimage_is_valid(sc, mac->mac_pcm,
1648		    mac->mac_pcm_size, fwname, BWI_FW_T_PCM))
1649			return (EINVAL);
1650	}
1651
1652	if (mac->mac_iv == NULL) {
1653		/* TODO: 11A */
1654		if (mac->mac_rev == 2 || mac->mac_rev == 4) {
1655			idx = 2;
1656		} else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) {
1657			idx = 5;
1658		} else {
1659			DPRINTF(1, "%s: no suitable IV for MAC rev %d\n",
1660			    sc->sc_dev.dv_xname, mac->mac_rev);
1661			return (ENODEV);
1662		}
1663
1664		snprintf(fwname, sizeof(fwname), "b0g0initvals%d.fw", idx);
1665
1666		error = loadfirmware(fwname, &mac->mac_iv,
1667		    &mac->mac_iv_size);
1668		if (error != 0) {
1669			printf("%s: error %d, could not read firmware %s!\n",
1670			    sc->sc_dev.dv_xname, error, fwname);
1671			return (ENOMEM);
1672		}
1673		DPRINTF(1, "%s: loaded firmware file %s\n",
1674		    sc->sc_dev.dv_xname, fwname);
1675
1676		if (bwi_fwimage_is_valid(sc, mac->mac_iv,
1677		    mac->mac_iv_size, fwname, BWI_FW_T_IV))
1678			return (EINVAL);
1679	}
1680
1681	if (mac->mac_iv_ext == NULL) {
1682		/* TODO: 11A */
1683		if (mac->mac_rev == 2 || mac->mac_rev == 4 ||
1684		    mac->mac_rev >= 11) {
1685			/* No extended IV */
1686			goto back;
1687		} else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) {
1688			idx = 5;
1689		} else {
1690			printf("%s: no suitable ExtIV for MAC rev %d\n",
1691			    sc->sc_dev.dv_xname, mac->mac_rev);
1692			return (ENODEV);
1693		}
1694
1695		snprintf(fwname, sizeof(fwname), "b0g0bsinitvals%d.fw", idx);
1696
1697		error = loadfirmware(fwname, &mac->mac_iv_ext,
1698		    &mac->mac_iv_ext_size);
1699		if (error != 0) {
1700			printf("%s: error %d, could not read firmware %s!\n",
1701			    sc->sc_dev.dv_xname, error, fwname);
1702			return (ENOMEM);
1703		}
1704		DPRINTF(1, "%s: loaded firmware file %s\n",
1705		    sc->sc_dev.dv_xname, fwname);
1706
1707		if (bwi_fwimage_is_valid(sc, mac->mac_iv_ext,
1708		    mac->mac_iv_ext_size, fwname, BWI_FW_T_IV))
1709			return (EINVAL);
1710	}
1711
1712back:
1713	return (0);
1714}
1715
1716void
1717bwi_mac_fw_free(struct bwi_mac *mac)
1718{
1719	if (mac->mac_ucode != NULL) {
1720		free(mac->mac_ucode, M_DEVBUF);
1721		mac->mac_ucode = NULL;
1722	}
1723
1724	if (mac->mac_pcm != NULL) {
1725		free(mac->mac_pcm, M_DEVBUF);
1726		mac->mac_pcm = NULL;
1727	}
1728
1729	if (mac->mac_iv != NULL) {
1730		free(mac->mac_iv, M_DEVBUF);
1731		mac->mac_iv = NULL;
1732	}
1733
1734	if (mac->mac_iv_ext != NULL) {
1735		free(mac->mac_iv_ext, M_DEVBUF);
1736		mac->mac_iv_ext = NULL;
1737	}
1738}
1739
1740int
1741bwi_mac_fw_load(struct bwi_mac *mac)
1742{
1743	struct bwi_softc *sc = mac->mac_sc;
1744	uint16_t fw_rev;
1745	const uint32_t *fw;
1746	int fw_len, i, error = 0;
1747
1748	/*
1749	 * Load FW image
1750	 */
1751	fw = (const uint32_t *)(mac->mac_ucode + BWI_FWHDR_SZ);
1752	fw_len = (mac->mac_ucode_size - BWI_FWHDR_SZ) / sizeof(uint32_t);
1753
1754	CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1755	    BWI_MOBJ_CTRL_VAL(BWI_FW_UCODE_MOBJ | BWI_WR_MOBJ_AUTOINC, 0));
1756	for (i = 0; i < fw_len; ++i) {
1757		CSR_WRITE_4(sc, BWI_MOBJ_DATA, betoh32(fw[i]));
1758		DELAY(10);
1759	}
1760
1761	/*
1762	 * Load PCM image
1763	 */
1764	fw = (const uint32_t *)(mac->mac_pcm + BWI_FWHDR_SZ);
1765	fw_len = (mac->mac_pcm_size - BWI_FWHDR_SZ) / sizeof(uint32_t);
1766
1767	CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1768	    BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01ea));
1769	CSR_WRITE_4(sc, BWI_MOBJ_DATA, 0x4000);
1770
1771	CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1772	    BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01eb));
1773	for (i = 0; i < fw_len; ++i) {
1774		CSR_WRITE_4(sc, BWI_MOBJ_DATA, betoh32(fw[i]));
1775		DELAY(10);
1776	}
1777
1778	CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_ALL_INTRS);
1779	CSR_WRITE_4(sc, BWI_MAC_STATUS,
1780	    BWI_MAC_STATUS_UCODE_START |
1781	    BWI_MAC_STATUS_IHREN |
1782	    BWI_MAC_STATUS_INFRA);
1783
1784#define NRETRY	200
1785	for (i = 0; i < NRETRY; ++i) {
1786		uint32_t intr_status;
1787
1788		intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
1789		if (intr_status == BWI_INTR_READY)
1790			break;
1791		DELAY(10);
1792	}
1793	if (i == NRETRY) {
1794		DPRINTF(1, "%s: firmware (fw & pcm) loading timed out\n",
1795		    sc->sc_dev.dv_xname);
1796		error = ETIMEDOUT;
1797		goto out;
1798	}
1799#undef NRETRY
1800
1801	CSR_READ_4(sc, BWI_MAC_INTR_STATUS);	/* dummy read */
1802
1803	fw_rev = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWREV);
1804	if (fw_rev > BWI_FW_VERSION3_REVMAX) {
1805		DPRINTF(1, "%s: firmware version 4 is not supported yet\n",
1806		    sc->sc_dev.dv_xname);
1807		error = ENODEV;
1808		goto out;
1809	}
1810
1811	DPRINTF(1, "%s: firmware rev 0x%04x, patch level 0x%04x\n",
1812	    sc->sc_dev.dv_xname, fw_rev,
1813	    MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV));
1814
1815out:
1816	return (error);
1817}
1818
1819int
1820bwi_mac_gpio_init(struct bwi_mac *mac)
1821{
1822	struct bwi_softc *sc = mac->mac_sc;
1823	struct bwi_regwin *old, *gpio_rw;
1824	uint32_t filt, bits;
1825	int error;
1826
1827	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_GPOSEL_MASK);
1828	/* TODO: LED */
1829
1830	CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0xf);
1831
1832	filt = 0x1f;
1833	bits = 0xf;
1834	if (sc->sc_bbp_id == BWI_BBPID_BCM4301) {
1835		filt |= 0x60;
1836		bits |= 0x60;
1837	}
1838	if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) {
1839		CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0x200);
1840		filt |= 0x200;
1841		bits |= 0x200;
1842	}
1843
1844	gpio_rw = BWI_GPIO_REGWIN(sc);
1845	error = bwi_regwin_switch(sc, gpio_rw, &old);
1846	if (error)
1847		return (error);
1848
1849	CSR_FILT_SETBITS_4(sc, BWI_GPIO_CTRL, filt, bits);
1850
1851	return (bwi_regwin_switch(sc, old, NULL));
1852}
1853
1854int
1855bwi_mac_gpio_fini(struct bwi_mac *mac)
1856{
1857	struct bwi_softc *sc = mac->mac_sc;
1858	struct bwi_regwin *old, *gpio_rw;
1859	int error;
1860
1861	gpio_rw = BWI_GPIO_REGWIN(sc);
1862	error = bwi_regwin_switch(sc, gpio_rw, &old);
1863	if (error)
1864		return (error);
1865
1866	CSR_WRITE_4(sc, BWI_GPIO_CTRL, 0);
1867
1868	return (bwi_regwin_switch(sc, old, NULL));
1869}
1870
1871int
1872bwi_mac_fw_load_iv(struct bwi_mac *mac, uint8_t *fw, size_t fw_len)
1873{
1874	struct bwi_softc *sc = mac->mac_sc;
1875	const struct bwi_fwhdr *hdr;
1876	const struct bwi_fw_iv *iv;
1877	int n, i, iv_img_size;
1878
1879	/* Get the number of IVs in the IV image */
1880	hdr = (const struct bwi_fwhdr *)fw;
1881	n = betoh32(hdr->fw_iv_cnt);
1882	DPRINTF(1, "%s: IV count %d\n", sc->sc_dev.dv_xname, n);
1883
1884	/* Calculate the IV image size, for later sanity check */
1885	iv_img_size = fw_len - sizeof(*hdr);
1886
1887	/* Locate the first IV */
1888	iv = (const struct bwi_fw_iv *)(fw + sizeof(*hdr));
1889
1890	for (i = 0; i < n; ++i) {
1891		uint16_t iv_ofs, ofs;
1892		int sz = 0;
1893
1894		if (iv_img_size < sizeof(iv->iv_ofs)) {
1895			printf("%s: invalid IV image, ofs\n",
1896			    sc->sc_dev.dv_xname);
1897			return (EINVAL);
1898		}
1899		iv_img_size -= sizeof(iv->iv_ofs);
1900		sz += sizeof(iv->iv_ofs);
1901
1902		iv_ofs = betoh16(iv->iv_ofs);
1903
1904		ofs = __SHIFTOUT(iv_ofs, BWI_FW_IV_OFS_MASK);
1905		if (ofs >= 0x1000) {
1906			printf("%s: invalid ofs (0x%04x) for %dth iv\n",
1907			    sc->sc_dev.dv_xname, ofs, i);
1908			return (EINVAL);
1909		}
1910
1911		if (iv_ofs & BWI_FW_IV_IS_32BIT) {
1912			uint32_t val32;
1913
1914			if (iv_img_size < sizeof(iv->iv_val.val32)) {
1915				printf("%s: invalid IV image, val32\n",
1916				    sc->sc_dev.dv_xname);
1917				return (EINVAL);
1918			}
1919			iv_img_size -= sizeof(iv->iv_val.val32);
1920			sz += sizeof(iv->iv_val.val32);
1921
1922			val32 = betoh32(iv->iv_val.val32);
1923			CSR_WRITE_4(sc, ofs, val32);
1924		} else {
1925			uint16_t val16;
1926
1927			if (iv_img_size < sizeof(iv->iv_val.val16)) {
1928				printf("%s: invalid IV image, val16\n",
1929				    sc->sc_dev.dv_xname);
1930				return (EINVAL);
1931			}
1932			iv_img_size -= sizeof(iv->iv_val.val16);
1933			sz += sizeof(iv->iv_val.val16);
1934
1935			val16 = betoh16(iv->iv_val.val16);
1936			CSR_WRITE_2(sc, ofs, val16);
1937		}
1938
1939		iv = (const struct bwi_fw_iv *)((const uint8_t *)iv + sz);
1940	}
1941
1942	if (iv_img_size != 0) {
1943		printf("%s: invalid IV image, size left %d\n",
1944		    sc->sc_dev.dv_xname, iv_img_size);
1945		return (EINVAL);
1946	}
1947
1948	return (0);
1949}
1950
1951int
1952bwi_mac_fw_init(struct bwi_mac *mac)
1953{
1954	struct bwi_softc *sc = mac->mac_sc;
1955	int error;
1956
1957	error = bwi_mac_fw_load_iv(mac, mac->mac_iv, mac->mac_iv_size);
1958	if (error) {
1959		printf("%s: load IV failed\n", sc->sc_dev.dv_xname);
1960		return (error);
1961	}
1962
1963	if (mac->mac_iv_ext != NULL) {
1964		error = bwi_mac_fw_load_iv(mac, mac->mac_iv_ext,
1965		    mac->mac_iv_ext_size);
1966		if (error)
1967			printf("%s: load ExtIV failed\n", sc->sc_dev.dv_xname);
1968	}
1969
1970	return (error);
1971}
1972
1973void
1974bwi_mac_opmode_init(struct bwi_mac *mac)
1975{
1976	struct bwi_softc *sc = mac->mac_sc;
1977	struct ieee80211com *ic = &sc->sc_ic;
1978	uint32_t mac_status;
1979	uint16_t pre_tbtt;
1980
1981	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA);
1982	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA);
1983	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN);
1984
1985	/* Set probe resp timeout to infinite */
1986	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 0);
1987
1988	/*
1989	 * TODO: factor out following part
1990	 */
1991
1992	mac_status = CSR_READ_4(sc, BWI_MAC_STATUS);
1993	mac_status &= ~(BWI_MAC_STATUS_OPMODE_HOSTAP |
1994	    BWI_MAC_STATUS_PASS_CTL |
1995	    BWI_MAC_STATUS_PASS_BADPLCP |
1996	    BWI_MAC_STATUS_PASS_BADFCS |
1997	    BWI_MAC_STATUS_PROMISC);
1998	mac_status |= BWI_MAC_STATUS_INFRA;
1999
2000	/* Always turn on PROMISC on old hardware */
2001	if (mac->mac_rev < 5)
2002		mac_status |= BWI_MAC_STATUS_PROMISC;
2003
2004	switch (ic->ic_opmode) {
2005	case IEEE80211_M_IBSS:
2006		mac_status &= ~BWI_MAC_STATUS_INFRA;
2007		break;
2008	case IEEE80211_M_HOSTAP:
2009		mac_status |= BWI_MAC_STATUS_OPMODE_HOSTAP;
2010		break;
2011	case IEEE80211_M_MONITOR:
2012#if 0
2013		/* Do you want data from your microwave oven? */
2014		mac_status |= BWI_MAC_STATUS_PASS_CTL |
2015			      BWI_MAC_STATUS_PASS_BADPLCP |
2016			      BWI_MAC_STATUS_PASS_BADFCS;
2017#else
2018		mac_status |= BWI_MAC_STATUS_PASS_CTL;
2019#endif
2020		/* Promisc? */
2021		break;
2022	default:
2023		break;
2024	}
2025
2026	if (ic->ic_if.if_flags & IFF_PROMISC)
2027		mac_status |= BWI_MAC_STATUS_PROMISC;
2028
2029	CSR_WRITE_4(sc, BWI_MAC_STATUS, mac_status);
2030
2031	if (ic->ic_opmode != IEEE80211_M_IBSS &&
2032	    ic->ic_opmode != IEEE80211_M_HOSTAP) {
2033		if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_rev == 3)
2034			pre_tbtt = 100;
2035		else
2036			pre_tbtt = 50;
2037	} else
2038		pre_tbtt = 2;
2039	CSR_WRITE_2(sc, BWI_MAC_PRE_TBTT, pre_tbtt);
2040}
2041
2042void
2043bwi_mac_hostflags_init(struct bwi_mac *mac)
2044{
2045	struct bwi_softc *sc = mac->mac_sc;
2046	struct bwi_phy *phy = &mac->mac_phy;
2047	struct bwi_rf *rf = &mac->mac_rf;
2048	uint64_t host_flags;
2049
2050	if (phy->phy_mode == IEEE80211_MODE_11A)
2051		return;
2052
2053	host_flags = HFLAGS_READ(mac);
2054	host_flags |= BWI_HFLAG_SYM_WA;
2055
2056	if (phy->phy_mode == IEEE80211_MODE_11G) {
2057		if (phy->phy_rev == 1)
2058			host_flags |= BWI_HFLAG_GDC_WA;
2059		if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
2060			host_flags |= BWI_HFLAG_OFDM_PA;
2061	} else if (phy->phy_mode == IEEE80211_MODE_11B) {
2062		if (phy->phy_rev >= 2 && rf->rf_type == BWI_RF_T_BCM2050)
2063			host_flags &= ~BWI_HFLAG_GDC_WA;
2064	} else {
2065		panic("unknown PHY mode %u\n", phy->phy_mode);
2066	}
2067
2068	HFLAGS_WRITE(mac, host_flags);
2069}
2070
2071void
2072bwi_mac_bss_param_init(struct bwi_mac *mac)
2073{
2074	struct bwi_softc *sc = mac->mac_sc;
2075	struct bwi_phy *phy = &mac->mac_phy;
2076	struct bwi_retry_lim lim;
2077	uint16_t cw_min;
2078
2079	/*
2080	 * Set short/long retry limits
2081	 */
2082	bzero(&lim, sizeof(lim));
2083	lim.shretry = BWI_SHRETRY;
2084	lim.shretry_fb = BWI_SHRETRY_FB;
2085	lim.lgretry = BWI_LGRETRY;
2086	lim.lgretry_fb = BWI_LGRETRY_FB;
2087	bwi_mac_set_retry_lim(mac, &lim);
2088
2089	/*
2090	 * Implicitly prevent firmware from sending probe response
2091	 * by setting its "probe response timeout" to 1us.
2092	 */
2093	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 1);
2094
2095	/*
2096	 * XXX MAC level acknowledge and CW min/max should depend
2097	 * on the char rateset of the IBSS/BSS to join.
2098	 */
2099
2100	/*
2101	 * Set MAC level acknowledge rates
2102	 */
2103	bwi_mac_set_ackrates(mac, &sc->sc_ic.ic_sup_rates[phy->phy_mode]);
2104
2105	/*
2106	 * Set CW min
2107	 */
2108	if (phy->phy_mode == IEEE80211_MODE_11B)
2109		cw_min = IEEE80211_CW_MIN_0;
2110	else
2111		cw_min = IEEE80211_CW_MIN_1;
2112	MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMIN, cw_min);
2113
2114	/*
2115	 * Set CW max
2116	 */
2117	MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMAX,
2118	    IEEE80211_CW_MAX);
2119}
2120
2121void
2122bwi_mac_set_retry_lim(struct bwi_mac *mac, const struct bwi_retry_lim *lim)
2123{
2124	/* Short/Long retry limit */
2125	MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_SHRETRY,
2126	    lim->shretry);
2127	MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_LGRETRY,
2128	    lim->lgretry);
2129
2130	/* Short/Long retry fallback limit */
2131	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SHRETRY_FB,
2132	    lim->shretry_fb);
2133	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_LGRETEY_FB,
2134	    lim->lgretry_fb);
2135}
2136
2137void
2138bwi_mac_set_ackrates(struct bwi_mac *mac, const struct ieee80211_rateset *rs)
2139{
2140	DPRINTF(1, "%s\n", __func__);
2141
2142	int i;
2143
2144	/* XXX not standard conforming */
2145	for (i = 0; i < rs->rs_nrates; ++i) {
2146		enum bwi_modtype modtype;
2147		uint16_t ofs;
2148
2149		modtype = bwi_rate2modtype(rs->rs_rates[i]);
2150		switch (modtype) {
2151		case IEEE80211_MODTYPE_DS:
2152			ofs = 0x4c0;
2153			break;
2154		case IEEE80211_MODTYPE_OFDM:
2155			ofs = 0x480;
2156			break;
2157		default:
2158			panic("unsupported modtype %u\n", modtype);
2159		}
2160		ofs += (bwi_rate2plcp(rs->rs_rates[i]) & 0xf) * 2;
2161
2162		MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, ofs + 0x20,
2163			     MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs));
2164	}
2165}
2166
2167int
2168bwi_mac_start(struct bwi_mac *mac)
2169{
2170	struct bwi_softc *sc = mac->mac_sc;
2171
2172	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE);
2173	CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_READY);
2174
2175	/* Flush pending bus writes */
2176	CSR_READ_4(sc, BWI_MAC_STATUS);
2177	CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
2178
2179	return (bwi_mac_config_ps(mac));
2180}
2181
2182int
2183bwi_mac_stop(struct bwi_mac *mac)
2184{
2185	struct bwi_softc *sc = mac->mac_sc;
2186	int error, i;
2187
2188	error = bwi_mac_config_ps(mac);
2189	if (error)
2190		return (error);
2191
2192	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE);
2193
2194	/* Flush pending bus write */
2195	CSR_READ_4(sc, BWI_MAC_STATUS);
2196
2197#define NRETRY	10000
2198	for (i = 0; i < NRETRY; ++i) {
2199		if (CSR_READ_4(sc, BWI_MAC_INTR_STATUS) & BWI_INTR_READY)
2200			break;
2201		DELAY(1);
2202	}
2203	if (i == NRETRY) {
2204		DPRINTF(1, "%s: can't stop MAC\n", sc->sc_dev.dv_xname);
2205		return (ETIMEDOUT);
2206	}
2207#undef NRETRY
2208
2209	return (0);
2210}
2211
2212int
2213bwi_mac_config_ps(struct bwi_mac *mac)
2214{
2215	struct bwi_softc *sc = mac->mac_sc;
2216	uint32_t status;
2217
2218	status = CSR_READ_4(sc, BWI_MAC_STATUS);
2219
2220	status &= ~BWI_MAC_STATUS_HW_PS;
2221	status |= BWI_MAC_STATUS_WAKEUP;
2222	CSR_WRITE_4(sc, BWI_MAC_STATUS, status);
2223
2224	/* Flush pending bus write */
2225	CSR_READ_4(sc, BWI_MAC_STATUS);
2226
2227	if (mac->mac_rev >= 5) {
2228		int i;
2229
2230#define NRETRY	100
2231		for (i = 0; i < NRETRY; ++i) {
2232			if (MOBJ_READ_2(mac, BWI_COMM_MOBJ,
2233			    BWI_COMM_MOBJ_UCODE_STATE) != BWI_UCODE_STATE_PS)
2234				break;
2235			DELAY(10);
2236		}
2237		if (i == NRETRY) {
2238			DPRINTF(1, "%s: config PS failed\n",
2239			    sc->sc_dev.dv_xname);
2240			return (ETIMEDOUT);
2241		}
2242#undef NRETRY
2243	}
2244	return (0);
2245}
2246
2247void
2248bwi_mac_reset_hwkeys(struct bwi_mac *mac)
2249{
2250	/* TODO: firmware crypto */
2251	MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_KEYTABLE_OFS);
2252}
2253
2254void
2255bwi_mac_shutdown(struct bwi_mac *mac)
2256{
2257	struct bwi_softc *sc = mac->mac_sc;
2258	int i;
2259
2260	if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS)
2261		sc->sc_free_txstats(sc);
2262
2263	sc->sc_free_rx_ring(sc);
2264
2265	for (i = 0; i < BWI_TX_NRING; ++i)
2266		sc->sc_free_tx_ring(sc, i);
2267
2268	bwi_rf_off(mac);
2269
2270	/* TODO: LED */
2271
2272	bwi_mac_gpio_fini(mac);
2273
2274	bwi_rf_off(mac); /* XXX again */
2275	CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC);
2276	bwi_regwin_disable(sc, &mac->mac_regwin, 0);
2277
2278	mac->mac_flags &= ~BWI_MAC_F_INITED;
2279}
2280
2281int
2282bwi_mac_get_property(struct bwi_mac *mac)
2283{
2284	struct bwi_softc *sc = mac->mac_sc;
2285	enum bwi_bus_space old_bus_space;
2286	uint32_t val;
2287
2288	/*
2289	 * Byte swap
2290	 */
2291	val = CSR_READ_4(sc, BWI_MAC_STATUS);
2292	if (val & BWI_MAC_STATUS_BSWAP) {
2293		DPRINTF(1, "%s: need byte swap\n", sc->sc_dev.dv_xname);
2294		mac->mac_flags |= BWI_MAC_F_BSWAP;
2295	}
2296
2297	/*
2298	 * DMA address space
2299	 */
2300	old_bus_space = sc->sc_bus_space;
2301
2302	val = CSR_READ_4(sc, BWI_STATE_HI);
2303	if (__SHIFTOUT(val, BWI_STATE_HI_FLAGS_MASK) &
2304	    BWI_STATE_HI_FLAG_64BIT) {
2305		/* 64bit address */
2306		sc->sc_bus_space = BWI_BUS_SPACE_64BIT;
2307		DPRINTF(1, "%s: 64bit bus space\n", sc->sc_dev.dv_xname);
2308	} else {
2309		uint32_t txrx_reg = BWI_TXRX_CTRL_BASE + BWI_TX32_CTRL;
2310
2311		CSR_WRITE_4(sc, txrx_reg, BWI_TXRX32_CTRL_ADDRHI_MASK);
2312		if (CSR_READ_4(sc, txrx_reg) & BWI_TXRX32_CTRL_ADDRHI_MASK) {
2313			/* 32bit address */
2314			sc->sc_bus_space = BWI_BUS_SPACE_32BIT;
2315			DPRINTF(1, "%s: 32bit bus space\n",
2316			    sc->sc_dev.dv_xname);
2317		} else {
2318			/* 30bit address */
2319			sc->sc_bus_space = BWI_BUS_SPACE_30BIT;
2320			DPRINTF(1, "%s: 30bit bus space\n",
2321			    sc->sc_dev.dv_xname);
2322		}
2323	}
2324
2325	if (old_bus_space != 0 && old_bus_space != sc->sc_bus_space) {
2326		printf("%s: MACs bus space mismatch!\n", sc->sc_dev.dv_xname);
2327		return (ENXIO);
2328	}
2329
2330	return (0);
2331}
2332
2333#define IEEE80211_DUR_SLOT	20	/* DS/CCK slottime, ERP long slottime */
2334#define IEEE80211_DUR_SHSLOT	9	/* ERP short slottime */
2335
2336void
2337bwi_mac_updateslot(struct bwi_mac *mac, int shslot)
2338{
2339	DPRINTF(1, "%s\n", __func__);
2340
2341	uint16_t slot_time;
2342
2343	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B)
2344		return;
2345
2346	if (shslot)
2347		slot_time = IEEE80211_DUR_SHSLOT;
2348	else
2349		slot_time = IEEE80211_DUR_SLOT;
2350
2351	CSR_WRITE_2(mac->mac_sc, BWI_MAC_SLOTTIME,
2352		    slot_time + BWI_MAC_SLOTTIME_ADJUST);
2353	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SLOTTIME, slot_time);
2354}
2355
2356int
2357bwi_mac_attach(struct bwi_softc *sc, int id, uint8_t rev)
2358{
2359	struct bwi_mac *mac;
2360	int i;
2361
2362	KKASSERT(sc->sc_nmac <= BWI_MAC_MAX && sc->sc_nmac >= 0);
2363
2364	if (sc->sc_nmac == BWI_MAC_MAX) {
2365		DPRINTF(1, "%s: too many MACs\n", sc->sc_dev.dv_xname);
2366		return (0);
2367	}
2368
2369	/*
2370	 * More than one MAC is only supported by BCM4309
2371	 */
2372	if (sc->sc_nmac != 0 &&
2373	    sc->sc_pci_did != PCI_PRODUCT_BROADCOM_BCM4309) {
2374		DPRINTF(1, "%s: ignore second MAC\n", sc->sc_dev.dv_xname);
2375		return (0);
2376	}
2377
2378	mac = &sc->sc_mac[sc->sc_nmac];
2379
2380	/* XXX will this happen? */
2381	if (BWI_REGWIN_EXIST(&mac->mac_regwin)) {
2382		printf("%s: %dth MAC already attached\n",
2383		    sc->sc_dev.dv_xname, sc->sc_nmac);
2384		return (0);
2385	}
2386
2387	/*
2388	 * Test whether the revision of this MAC is supported
2389	 */
2390#define N(arr)	(int)(sizeof(arr) / sizeof(arr[0]))
2391	for (i = 0; i < N(bwi_sup_macrev); ++i) {
2392		if (bwi_sup_macrev[i] == rev)
2393			break;
2394	}
2395	if (i == N(bwi_sup_macrev)) {
2396		DPRINTF(1, "%s: MAC rev %u is not supported\n",
2397		    sc->sc_dev.dv_xname, rev);
2398		return (ENXIO);
2399	}
2400#undef N
2401
2402	BWI_CREATE_MAC(mac, sc, id, rev);
2403	sc->sc_nmac++;
2404
2405	if (mac->mac_rev < 5) {
2406		mac->mac_flags |= BWI_MAC_F_HAS_TXSTATS;
2407		DPRINTF(1, "%s: has TX stats\n", sc->sc_dev.dv_xname);
2408	}
2409
2410	return (0);
2411}
2412
2413void
2414bwi_mac_balance_atten(int *bbp_atten0, int *rf_atten0)
2415{
2416	int bbp_atten, rf_atten, rf_atten_lim = -1;
2417
2418	bbp_atten = *bbp_atten0;
2419	rf_atten = *rf_atten0;
2420
2421	/*
2422	 * RF attenuation affects TX power BWI_RF_ATTEN_FACTOR times
2423	 * as much as BBP attenuation, so we try our best to keep RF
2424	 * attenuation within range.  BBP attenuation will be clamped
2425	 * later if it is out of range during balancing.
2426	 *
2427	 * BWI_RF_ATTEN_MAX0 is used as RF attenuation upper limit.
2428	 */
2429
2430	/*
2431	 * Use BBP attenuation to balance RF attenuation
2432	 */
2433	if (rf_atten < 0)
2434		rf_atten_lim = 0;
2435	else if (rf_atten > BWI_RF_ATTEN_MAX0)
2436		rf_atten_lim = BWI_RF_ATTEN_MAX0;
2437
2438	if (rf_atten_lim >= 0) {
2439		bbp_atten += (BWI_RF_ATTEN_FACTOR * (rf_atten - rf_atten_lim));
2440		rf_atten = rf_atten_lim;
2441	}
2442
2443	/*
2444	 * If possible, use RF attenuation to balance BBP attenuation
2445	 * NOTE: RF attenuation is still kept within range.
2446	 */
2447	while (rf_atten < BWI_RF_ATTEN_MAX0 && bbp_atten > BWI_BBP_ATTEN_MAX) {
2448		bbp_atten -= BWI_RF_ATTEN_FACTOR;
2449		++rf_atten;
2450	}
2451	while (rf_atten > 0 && bbp_atten < 0) {
2452		bbp_atten += BWI_RF_ATTEN_FACTOR;
2453		--rf_atten;
2454	}
2455
2456	/* RF attenuation MUST be within range */
2457	KKASSERT(rf_atten >= 0 && rf_atten <= BWI_RF_ATTEN_MAX0);
2458
2459	/*
2460	 * Clamp BBP attenuation
2461	 */
2462	if (bbp_atten < 0)
2463		bbp_atten = 0;
2464	else if (bbp_atten > BWI_BBP_ATTEN_MAX)
2465		bbp_atten = BWI_BBP_ATTEN_MAX;
2466
2467	*rf_atten0 = rf_atten;
2468	*bbp_atten0 = bbp_atten;
2469}
2470
2471void
2472bwi_mac_adjust_tpctl(struct bwi_mac *mac, int rf_atten_adj, int bbp_atten_adj)
2473{
2474	struct bwi_softc *sc = mac->mac_sc;
2475	struct bwi_rf *rf = &mac->mac_rf;
2476	struct bwi_tpctl tpctl;
2477	int bbp_atten, rf_atten, tp_ctrl1;
2478
2479	bcopy(&mac->mac_tpctl, &tpctl, sizeof(tpctl));
2480
2481	/* NOTE: Use signed value to do calulation */
2482	bbp_atten = tpctl.bbp_atten;
2483	rf_atten = tpctl.rf_atten;
2484	tp_ctrl1 = tpctl.tp_ctrl1;
2485
2486	bbp_atten += bbp_atten_adj;
2487	rf_atten += rf_atten_adj;
2488
2489	bwi_mac_balance_atten(&bbp_atten, &rf_atten);
2490
2491	if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 2) {
2492		if (rf_atten <= 1) {
2493			if (tp_ctrl1 == 0) {
2494				tp_ctrl1 = 3;
2495				bbp_atten += 2;
2496				rf_atten += 2;
2497			} else if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) {
2498				bbp_atten +=
2499				(BWI_RF_ATTEN_FACTOR * (rf_atten - 2));
2500				rf_atten = 2;
2501			}
2502		} else if (rf_atten > 4 && tp_ctrl1 != 0) {
2503			tp_ctrl1 = 0;
2504			if (bbp_atten < 3) {
2505				bbp_atten += 2;
2506				rf_atten -= 3;
2507			} else {
2508				bbp_atten -= 2;
2509				rf_atten -= 2;
2510			}
2511		}
2512		bwi_mac_balance_atten(&bbp_atten, &rf_atten);
2513	}
2514
2515	tpctl.bbp_atten = bbp_atten;
2516	tpctl.rf_atten = rf_atten;
2517	tpctl.tp_ctrl1 = tp_ctrl1;
2518
2519	bwi_mac_lock(mac);
2520	bwi_mac_set_tpctl_11bg(mac, &tpctl);
2521	bwi_mac_unlock(mac);
2522}
2523
2524/*
2525 * http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower
2526 */
2527void
2528bwi_mac_calibrate_txpower(struct bwi_mac *mac)
2529{
2530	struct bwi_softc *sc = mac->mac_sc;
2531	struct bwi_rf *rf = &mac->mac_rf;
2532	int8_t tssi[4], tssi_avg, cur_txpwr;
2533	int error, i, ofdm_tssi;
2534	int txpwr_diff, rf_atten_adj, bbp_atten_adj;
2535
2536	if (mac->mac_flags & BWI_MAC_F_TPCTL_ERROR) {
2537		DPRINTF(1, "%s: tpctl error happened, can't set txpower\n",
2538		    sc->sc_dev.dv_xname);
2539		return;
2540	}
2541
2542	if (BWI_IS_BRCM_BU4306(sc)) {
2543		DPRINTF(1, "%s: BU4306, can't set txpower\n",
2544		    sc->sc_dev.dv_xname);
2545		return;
2546	}
2547
2548	/*
2549	 * Save latest TSSI and reset the related memory objects
2550	 */
2551	ofdm_tssi = 0;
2552	error = bwi_rf_get_latest_tssi(mac, tssi, BWI_COMM_MOBJ_TSSI_DS);
2553	if (error) {
2554		DPRINTF(1, "%s: no DS tssi\n", sc->sc_dev.dv_xname);
2555
2556		if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B)
2557			return;
2558
2559		error = bwi_rf_get_latest_tssi(mac, tssi,
2560		    BWI_COMM_MOBJ_TSSI_OFDM);
2561		if (error) {
2562			DPRINTF(1, "%s: no OFDM tssi\n", sc->sc_dev.dv_xname);
2563			return;
2564		}
2565
2566		for (i = 0; i < 4; ++i) {
2567			tssi[i] += 0x20;
2568			tssi[i] &= 0x3f;
2569		}
2570		ofdm_tssi = 1;
2571	}
2572	bwi_rf_clear_tssi(mac);
2573
2574	DPRINTF(1, "%s: tssi0 %d, tssi1 %d, tssi2 %d, tssi3 %d\n",
2575	    sc->sc_dev.dv_xname, tssi[0], tssi[1], tssi[2], tssi[3]);
2576
2577	/*
2578	 * Calculate RF/BBP attenuation adjustment based on
2579	 * the difference between desired TX power and sampled
2580	 * TX power.
2581	 */
2582	/* +8 == "each incremented by 1/2" */
2583	tssi_avg = (tssi[0] + tssi[1] + tssi[2] + tssi[3] + 8) / 4;
2584	if (ofdm_tssi && (HFLAGS_READ(mac) & BWI_HFLAG_PWR_BOOST_DS))
2585		tssi_avg -= 13;
2586
2587	DPRINTF(1, "%s: tssi avg %d\n", sc->sc_dev.dv_xname, tssi_avg);
2588
2589	error = bwi_rf_tssi2dbm(mac, tssi_avg, &cur_txpwr);
2590	if (error)
2591		return;
2592	DPRINTF(1, "%s: current txpower %d\n", sc->sc_dev.dv_xname, cur_txpwr);
2593
2594	txpwr_diff = rf->rf_txpower_max - cur_txpwr; /* XXX ni_txpower */
2595
2596	rf_atten_adj = -howmany(txpwr_diff, 8);
2597	bbp_atten_adj = -(txpwr_diff / 2) -
2598	    (BWI_RF_ATTEN_FACTOR * rf_atten_adj);
2599
2600	if (rf_atten_adj == 0 && bbp_atten_adj == 0) {
2601		DPRINTF(1, "%s: no need to adjust RF/BBP attenuation\n",
2602		    sc->sc_dev.dv_xname);
2603		/* TODO: LO */
2604		return;
2605	}
2606
2607	DPRINTF(1, "%s: rf atten adjust %d, bbp atten adjust %d\n",
2608	    sc->sc_dev.dv_xname, rf_atten_adj, bbp_atten_adj);
2609	bwi_mac_adjust_tpctl(mac, rf_atten_adj, bbp_atten_adj);
2610	/* TODO: LO */
2611}
2612
2613void
2614bwi_mac_lock(struct bwi_mac *mac)
2615{
2616	struct bwi_softc *sc = mac->mac_sc;
2617	struct ieee80211com *ic = &sc->sc_ic;
2618
2619	KKASSERT((mac->mac_flags & BWI_MAC_F_LOCKED) == 0);
2620
2621	if (mac->mac_rev < 3)
2622		bwi_mac_stop(mac);
2623	else if (ic->ic_opmode != IEEE80211_M_HOSTAP)
2624		bwi_mac_config_ps(mac);
2625
2626	CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK);
2627
2628	/* Flush pending bus write */
2629	CSR_READ_4(sc, BWI_MAC_STATUS);
2630	DELAY(10);
2631
2632	mac->mac_flags |= BWI_MAC_F_LOCKED;
2633}
2634
2635void
2636bwi_mac_unlock(struct bwi_mac *mac)
2637{
2638	struct bwi_softc *sc = mac->mac_sc;
2639	struct ieee80211com *ic = &sc->sc_ic;
2640
2641	KKASSERT(mac->mac_flags & BWI_MAC_F_LOCKED);
2642
2643	CSR_READ_2(sc, BWI_PHYINFO); /* dummy read */
2644
2645	CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK);
2646
2647	if (mac->mac_rev < 3)
2648		bwi_mac_start(mac);
2649	else if (ic->ic_opmode != IEEE80211_M_HOSTAP)
2650		bwi_mac_config_ps(mac);
2651
2652	mac->mac_flags &= ~BWI_MAC_F_LOCKED;
2653}
2654
2655void
2656bwi_mac_set_promisc(struct bwi_mac *mac, int promisc)
2657{
2658	struct bwi_softc *sc = mac->mac_sc;
2659
2660	if (mac->mac_rev < 5) /* Promisc is always on */
2661		return;
2662
2663	if (promisc)
2664		CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC);
2665	else
2666		CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC);
2667}
2668
2669/* BWIPHY */
2670
2671void
2672bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
2673{
2674	struct bwi_softc *sc = mac->mac_sc;
2675
2676	/* TODO: 11A */
2677	CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
2678	CSR_WRITE_2(sc, BWI_PHY_DATA, data);
2679}
2680
2681uint16_t
2682bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
2683{
2684	struct bwi_softc *sc = mac->mac_sc;
2685
2686	/* TODO: 11A */
2687	CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
2688	return (CSR_READ_2(sc, BWI_PHY_DATA));
2689}
2690
2691int
2692bwi_phy_attach(struct bwi_mac *mac)
2693{
2694	struct bwi_softc *sc = mac->mac_sc;
2695	struct bwi_phy *phy = &mac->mac_phy;
2696	uint8_t phyrev, phytype, phyver;
2697	uint16_t val;
2698	int i;
2699
2700	/* Get PHY type/revision/version */
2701	val = CSR_READ_2(sc, BWI_PHYINFO);
2702	phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK);
2703	phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK);
2704	phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK);
2705	DPRINTF(1, "%s: PHY type %d, rev %d, ver %d\n",
2706	    sc->sc_dev.dv_xname, phytype, phyrev, phyver);
2707
2708	/*
2709	 * Verify whether the revision of the PHY type is supported
2710	 * Convert PHY type to ieee80211_phymode
2711	 */
2712	switch (phytype) {
2713	case BWI_PHYINFO_TYPE_11A:
2714		if (phyrev >= 4) {
2715			DPRINTF(1, "%s: unsupported 11A PHY, rev %u\n",
2716			    sc->sc_dev.dv_xname, phyrev);
2717			return (ENXIO);
2718		}
2719		phy->phy_init = bwi_phy_init_11a;
2720		phy->phy_mode = IEEE80211_MODE_11A;
2721		phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A;
2722		phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A;
2723		phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A;
2724		break;
2725	case BWI_PHYINFO_TYPE_11B:
2726#define N(arr)	(int)(sizeof(arr) / sizeof(arr[0]))
2727		for (i = 0; i < N(bwi_sup_bphy); ++i) {
2728			if (phyrev == bwi_sup_bphy[i].rev) {
2729				phy->phy_init = bwi_sup_bphy[i].init;
2730				break;
2731			}
2732		}
2733		if (i == N(bwi_sup_bphy)) {
2734			DPRINTF(1, "%s: unsupported 11B PHY, rev %u\n",
2735			    sc->sc_dev.dv_xname, phyrev);
2736			return (ENXIO);
2737		}
2738#undef N
2739		phy->phy_mode = IEEE80211_MODE_11B;
2740		break;
2741	case BWI_PHYINFO_TYPE_11G:
2742		if (phyrev > 8) {
2743			DPRINTF(1, "%s: unsupported 11G PHY, rev %u\n",
2744			    sc->sc_dev.dv_xname, phyrev);
2745			return (ENXIO);
2746		}
2747		phy->phy_init = bwi_phy_init_11g;
2748		phy->phy_mode = IEEE80211_MODE_11G;
2749		phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G;
2750		phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G;
2751		phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G;
2752		break;
2753	default:
2754		DPRINTF(1, "%s: unsupported PHY type %d\n",
2755		    sc->sc_dev.dv_xname, phytype);
2756		return (ENXIO);
2757	}
2758	phy->phy_rev = phyrev;
2759	phy->phy_version = phyver;
2760
2761	return (0);
2762}
2763
2764void
2765bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten)
2766{
2767	struct bwi_phy *phy = &mac->mac_phy;
2768	uint16_t mask = 0x000f;
2769
2770	if (phy->phy_version == 0) {
2771		CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask,
2772				   __SHIFTIN(bbp_atten, mask));
2773	} else {
2774		if (phy->phy_version > 1)
2775			mask <<= 2;
2776		else
2777			mask <<= 3;
2778		PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask,
2779				 __SHIFTIN(bbp_atten, mask));
2780	}
2781}
2782
2783int
2784bwi_phy_calibrate(struct bwi_mac *mac)
2785{
2786	struct bwi_phy *phy = &mac->mac_phy;
2787
2788	/* Dummy read */
2789	CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS);
2790
2791	/* Don't re-init */
2792	if (phy->phy_flags & BWI_PHY_F_CALIBRATED)
2793		return (0);
2794
2795	if (phy->phy_mode == IEEE80211_MODE_11G && phy->phy_rev == 1) {
2796		bwi_mac_reset(mac, 0);
2797		bwi_phy_init_11g(mac);
2798		bwi_mac_reset(mac, 1);
2799	}
2800
2801	phy->phy_flags |= BWI_PHY_F_CALIBRATED;
2802
2803	return (0);
2804}
2805
2806void
2807bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data)
2808{
2809	struct bwi_phy *phy = &mac->mac_phy;
2810
2811	KKASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0);
2812	PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
2813	PHY_WRITE(mac, phy->phy_tbl_data_lo, data);
2814}
2815
2816void
2817bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data)
2818{
2819	struct bwi_phy *phy = &mac->mac_phy;
2820
2821	KKASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 &&
2822	    phy->phy_tbl_ctrl != 0);
2823
2824	PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
2825	PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16);
2826	PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff);
2827}
2828
2829void
2830bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data)
2831{
2832	PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
2833	PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data);
2834}
2835
2836int16_t
2837bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs)
2838{
2839	PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
2840	return ((int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA));
2841}
2842
2843void
2844bwi_phy_init_11a(struct bwi_mac *mac)
2845{
2846	/* TODO: 11A */
2847}
2848
2849void
2850bwi_phy_init_11g(struct bwi_mac *mac)
2851{
2852	struct bwi_softc *sc = mac->mac_sc;
2853	struct bwi_phy *phy = &mac->mac_phy;
2854	struct bwi_rf *rf = &mac->mac_rf;
2855	const struct bwi_tpctl *tpctl = &mac->mac_tpctl;
2856
2857	if (phy->phy_rev == 1)
2858		bwi_phy_init_11b_rev5(mac);
2859	else
2860		bwi_phy_init_11b_rev6(mac);
2861
2862	if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED))
2863		bwi_phy_config_11g(mac);
2864
2865	if (phy->phy_rev >= 2) {
2866		PHY_WRITE(mac, 0x814, 0);
2867		PHY_WRITE(mac, 0x815, 0);
2868
2869		if (phy->phy_rev == 2) {
2870			PHY_WRITE(mac, 0x811, 0);
2871			PHY_WRITE(mac, 0x15, 0xc0);
2872		} else if (phy->phy_rev > 5) {
2873			PHY_WRITE(mac, 0x811, 0x400);
2874			PHY_WRITE(mac, 0x15, 0xc0);
2875		}
2876	}
2877
2878	if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) {
2879		uint16_t val;
2880
2881		val = PHY_READ(mac, 0x400) & 0xff;
2882		if (val == 3 || val == 5) {
2883			PHY_WRITE(mac, 0x4c2, 0x1816);
2884			PHY_WRITE(mac, 0x4c3, 0x8006);
2885			if (val == 5) {
2886				PHY_FILT_SETBITS(mac, 0x4cc,
2887						 0xff, 0x1f00);
2888			}
2889		}
2890	}
2891
2892	if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) ||
2893	    phy->phy_rev >= 2)
2894		PHY_WRITE(mac, 0x47e, 0x78);
2895
2896	if (rf->rf_rev == 8) {
2897		PHY_SETBITS(mac, 0x801, 0x80);
2898		PHY_SETBITS(mac, 0x43e, 0x4);
2899	}
2900
2901	if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED))
2902		bwi_rf_get_gains(mac);
2903
2904	if (rf->rf_rev != 8)
2905		bwi_rf_init(mac);
2906
2907	if (tpctl->tp_ctrl2 == 0xffff) {
2908		bwi_rf_lo_update(mac);
2909	} else {
2910		if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) {
2911			RF_WRITE(mac, 0x52,
2912			    (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2);
2913		} else {
2914			RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl1);
2915		}
2916
2917		if (phy->phy_rev >= 6) {
2918			PHY_FILT_SETBITS(mac, 0x36, 0xfff,
2919			    tpctl->tp_ctrl2 << 12);
2920		}
2921
2922		if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
2923			PHY_WRITE(mac, 0x2e, 0x8075);
2924		else
2925			PHY_WRITE(mac, 0x2e, 0x807f);
2926
2927		if (phy->phy_rev < 2)
2928			PHY_WRITE(mac, 0x2f, 0x101);
2929		else
2930			PHY_WRITE(mac, 0x2f, 0x202);
2931	}
2932
2933	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
2934		bwi_rf_lo_adjust(mac, tpctl);
2935		PHY_WRITE(mac, 0x80f, 0x8078);
2936	}
2937
2938	if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
2939		bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */);
2940		bwi_rf_set_nrssi_thr(mac);
2941	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
2942		if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI) {
2943			KKASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI);
2944			bwi_rf_calc_nrssi_slope(mac);
2945		} else {
2946			KKASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI);
2947			bwi_rf_set_nrssi_thr(mac);
2948		}
2949	}
2950
2951	if (rf->rf_rev == 8)
2952		PHY_WRITE(mac, 0x805, 0x3230);
2953
2954	bwi_mac_init_tpctl_11bg(mac);
2955
2956	if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_pkg == 2) {
2957		PHY_CLRBITS(mac, 0x429, 0x4000);
2958		PHY_CLRBITS(mac, 0x4c3, 0x8000);
2959	}
2960}
2961
2962void
2963bwi_phy_init_11b_rev2(struct bwi_mac *mac)
2964{
2965	struct bwi_softc *sc;
2966
2967	sc = mac->mac_sc;
2968
2969	/* TODO: 11B */
2970	DPRINTF(1, "%s: %s is not implemented yet\n",
2971	    sc->sc_dev.dv_xname, __func__);
2972}
2973
2974void
2975bwi_phy_init_11b_rev4(struct bwi_mac *mac)
2976{
2977	struct bwi_softc *sc;
2978
2979	sc = mac->mac_sc;
2980
2981	/* TODO: 11B */
2982	DPRINTF(1, "%s: %s is not implemented yet\n",
2983	    sc->sc_dev.dv_xname, __func__);
2984}
2985
2986void
2987bwi_phy_init_11b_rev5(struct bwi_mac *mac)
2988{
2989	struct bwi_softc *sc = mac->mac_sc;
2990	struct bwi_rf *rf = &mac->mac_rf;
2991	struct bwi_phy *phy = &mac->mac_phy;
2992	u_int orig_chan;
2993
2994	if (phy->phy_version == 1)
2995		RF_SETBITS(mac, 0x7a, 0x50);
2996
2997	if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM &&
2998	    sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) {
2999		uint16_t ofs, val;
3000
3001		val = 0x2120;
3002		for (ofs = 0xa8; ofs < 0xc7; ++ofs) {
3003			PHY_WRITE(mac, ofs, val);
3004			val += 0x202;
3005		}
3006	}
3007
3008	PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700);
3009
3010	if (rf->rf_type == BWI_RF_T_BCM2050)
3011		PHY_WRITE(mac, 0x38, 0x667);
3012
3013	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
3014		if (rf->rf_type == BWI_RF_T_BCM2050) {
3015			RF_SETBITS(mac, 0x7a, 0x20);
3016			RF_SETBITS(mac, 0x51, 0x4);
3017		}
3018
3019		CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0);
3020
3021		PHY_SETBITS(mac, 0x802, 0x100);
3022		PHY_SETBITS(mac, 0x42b, 0x2000);
3023		PHY_WRITE(mac, 0x1c, 0x186a);
3024
3025		PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900);
3026		PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64);
3027		PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa);
3028	}
3029
3030	/* TODO: bad_frame_preempt? */
3031
3032	if (phy->phy_version == 1) {
3033	    	PHY_WRITE(mac, 0x26, 0xce00);
3034		PHY_WRITE(mac, 0x21, 0x3763);
3035		PHY_WRITE(mac, 0x22, 0x1bc3);
3036		PHY_WRITE(mac, 0x23, 0x6f9);
3037		PHY_WRITE(mac, 0x24, 0x37e);
3038	} else
3039		PHY_WRITE(mac, 0x26, 0xcc00);
3040	PHY_WRITE(mac, 0x30, 0xc6);
3041
3042	CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
3043
3044	if (phy->phy_version == 1)
3045		PHY_WRITE(mac, 0x20, 0x3e1c);
3046	else
3047		PHY_WRITE(mac, 0x20, 0x301c);
3048
3049	if (phy->phy_version == 0)
3050		CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
3051
3052	/* Force to channel 7 */
3053	orig_chan = rf->rf_curchan;
3054	bwi_rf_set_chan(mac, 7, 0);
3055
3056	if (rf->rf_type != BWI_RF_T_BCM2050) {
3057		RF_WRITE(mac, 0x75, 0x80);
3058		RF_WRITE(mac, 0x79, 0x81);
3059	}
3060
3061	RF_WRITE(mac, 0x50, 0x20);
3062	RF_WRITE(mac, 0x50, 0x23);
3063
3064	if (rf->rf_type == BWI_RF_T_BCM2050) {
3065		RF_WRITE(mac, 0x50, 0x20);
3066		RF_WRITE(mac, 0x5a, 0x70);
3067	}
3068
3069	RF_WRITE(mac, 0x5b, 0x7b);
3070	RF_WRITE(mac, 0x5c, 0xb0);
3071	RF_SETBITS(mac, 0x7a, 0x7);
3072
3073	bwi_rf_set_chan(mac, orig_chan, 0);
3074
3075	PHY_WRITE(mac, 0x14, 0x80);
3076	PHY_WRITE(mac, 0x32, 0xca);
3077	PHY_WRITE(mac, 0x2a, 0x88a3);
3078
3079	bwi_mac_set_tpctl_11bg(mac, NULL);
3080
3081	if (rf->rf_type == BWI_RF_T_BCM2050)
3082		RF_WRITE(mac, 0x5d, 0xd);
3083
3084	CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4);
3085}
3086
3087void
3088bwi_phy_init_11b_rev6(struct bwi_mac *mac)
3089{
3090	struct bwi_softc *sc = mac->mac_sc;
3091	struct bwi_rf *rf = &mac->mac_rf;
3092	struct bwi_phy *phy = &mac->mac_phy;
3093	uint16_t val, ofs;
3094	u_int orig_chan;
3095
3096	PHY_WRITE(mac, 0x3e, 0x817a);
3097	RF_SETBITS(mac, 0x7a, 0x58);
3098
3099	if (rf->rf_rev == 4 || rf->rf_rev == 5) {
3100		RF_WRITE(mac, 0x51, 0x37);
3101		RF_WRITE(mac, 0x52, 0x70);
3102		RF_WRITE(mac, 0x53, 0xb3);
3103		RF_WRITE(mac, 0x54, 0x9b);
3104		RF_WRITE(mac, 0x5a, 0x88);
3105		RF_WRITE(mac, 0x5b, 0x88);
3106		RF_WRITE(mac, 0x5d, 0x88);
3107		RF_WRITE(mac, 0x5e, 0x88);
3108		RF_WRITE(mac, 0x7d, 0x88);
3109		HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1);
3110	} else if (rf->rf_rev == 8) {
3111		RF_WRITE(mac, 0x51, 0);
3112		RF_WRITE(mac, 0x52, 0x40);
3113		RF_WRITE(mac, 0x53, 0xb7);
3114		RF_WRITE(mac, 0x54, 0x98);
3115		RF_WRITE(mac, 0x5a, 0x88);
3116		RF_WRITE(mac, 0x5b, 0x6b);
3117		RF_WRITE(mac, 0x5c, 0xf);
3118		if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ) {
3119			RF_WRITE(mac, 0x5d, 0xfa);
3120			RF_WRITE(mac, 0x5e, 0xd8);
3121		} else {
3122			RF_WRITE(mac, 0x5d, 0xf5);
3123			RF_WRITE(mac, 0x5e, 0xb8);
3124		}
3125		RF_WRITE(mac, 0x73, 0x3);
3126		RF_WRITE(mac, 0x7d, 0xa8);
3127		RF_WRITE(mac, 0x7c, 0x1);
3128		RF_WRITE(mac, 0x7e, 0x8);
3129	}
3130
3131	val = 0x1e1f;
3132	for (ofs = 0x88; ofs < 0x98; ++ofs) {
3133		PHY_WRITE(mac, ofs, val);
3134		val -= 0x202;
3135	}
3136
3137	val = 0x3e3f;
3138	for (ofs = 0x98; ofs < 0xa8; ++ofs) {
3139		PHY_WRITE(mac, ofs, val);
3140		val -= 0x202;
3141	}
3142
3143	val = 0x2120;
3144	for (ofs = 0xa8; ofs < 0xc8; ++ofs) {
3145		PHY_WRITE(mac, ofs, (val & 0x3f3f));
3146		val += 0x202;
3147	}
3148
3149	if (phy->phy_mode == IEEE80211_MODE_11G) {
3150		RF_SETBITS(mac, 0x7a, 0x20);
3151		RF_SETBITS(mac, 0x51, 0x4);
3152		PHY_SETBITS(mac, 0x802, 0x100);
3153		PHY_SETBITS(mac, 0x42b, 0x2000);
3154		PHY_WRITE(mac, 0x5b, 0);
3155		PHY_WRITE(mac, 0x5c, 0);
3156	}
3157
3158	/* Force to channel 7 */
3159	orig_chan = rf->rf_curchan;
3160	if (orig_chan >= 8)
3161		bwi_rf_set_chan(mac, 1, 0);
3162	else
3163		bwi_rf_set_chan(mac, 13, 0);
3164
3165	RF_WRITE(mac, 0x50, 0x20);
3166	RF_WRITE(mac, 0x50, 0x23);
3167
3168	DELAY(40);
3169
3170	if (rf->rf_rev < 6 || rf->rf_rev == 8) {
3171		RF_SETBITS(mac, 0x7c, 0x2);
3172		RF_WRITE(mac, 0x50, 0x20);
3173	}
3174	if (rf->rf_rev <= 2) {
3175		RF_WRITE(mac, 0x7c, 0x20);
3176		RF_WRITE(mac, 0x5a, 0x70);
3177		RF_WRITE(mac, 0x5b, 0x7b);
3178		RF_WRITE(mac, 0x5c, 0xb0);
3179	}
3180
3181	RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7);
3182
3183	bwi_rf_set_chan(mac, orig_chan, 0);
3184
3185	PHY_WRITE(mac, 0x14, 0x200);
3186	if (rf->rf_rev >= 6)
3187		PHY_WRITE(mac, 0x2a, 0x88c2);
3188	else
3189		PHY_WRITE(mac, 0x2a, 0x8ac0);
3190	PHY_WRITE(mac, 0x38, 0x668);
3191
3192	bwi_mac_set_tpctl_11bg(mac, NULL);
3193
3194	if (rf->rf_rev <= 5) {
3195		PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3);
3196		if (rf->rf_rev <= 2)
3197			RF_WRITE(mac, 0x5d, 0xd);
3198	}
3199
3200	if (phy->phy_version == 4) {
3201		CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2);
3202		PHY_CLRBITS(mac, 0x61, 0xf000);
3203	} else {
3204		PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4);
3205	}
3206
3207	if (phy->phy_mode == IEEE80211_MODE_11B) {
3208		CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2);
3209		PHY_WRITE(mac, 0x16, 0x410);
3210		PHY_WRITE(mac, 0x17, 0x820);
3211		PHY_WRITE(mac, 0x62, 0x7);
3212
3213		bwi_rf_init_bcm2050(mac);
3214		bwi_rf_lo_update(mac);
3215		if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
3216			bwi_rf_calc_nrssi_slope(mac);
3217			bwi_rf_set_nrssi_thr(mac);
3218		}
3219		bwi_mac_init_tpctl_11bg(mac);
3220	} else
3221		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
3222}
3223
3224#define N(arr)	(int)(sizeof(arr) / sizeof(arr[0]))
3225void
3226bwi_phy_config_11g(struct bwi_mac *mac)
3227{
3228	struct bwi_softc *sc = mac->mac_sc;
3229	struct bwi_phy *phy = &mac->mac_phy;
3230	const uint16_t *tbl;
3231	uint16_t wrd_ofs1, wrd_ofs2;
3232	int i, n;
3233
3234	if (phy->phy_rev == 1) {
3235		PHY_WRITE(mac, 0x406, 0x4f19);
3236		PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340);
3237		PHY_WRITE(mac, 0x42c, 0x5a);
3238		PHY_WRITE(mac, 0x427, 0x1a);
3239
3240		/* Fill frequency table */
3241		for (i = 0; i < N(bwi_phy_freq_11g_rev1); ++i) {
3242			bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i,
3243			    bwi_phy_freq_11g_rev1[i]);
3244		}
3245
3246		/* Fill noise table */
3247		for (i = 0; i < N(bwi_phy_noise_11g_rev1); ++i) {
3248			bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
3249			    bwi_phy_noise_11g_rev1[i]);
3250		}
3251
3252		/* Fill rotor table */
3253		for (i = 0; i < N(bwi_phy_rotor_11g_rev1); ++i) {
3254			/* NB: data length is 4 bytes */
3255			bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i,
3256			    bwi_phy_rotor_11g_rev1[i]);
3257		}
3258	} else {
3259		bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */
3260
3261		if (phy->phy_rev == 2) {
3262			PHY_WRITE(mac, 0x4c0, 0x1861);
3263			PHY_WRITE(mac, 0x4c1, 0x271);
3264		} else if (phy->phy_rev > 2) {
3265			PHY_WRITE(mac, 0x4c0, 0x98);
3266			PHY_WRITE(mac, 0x4c1, 0x70);
3267			PHY_WRITE(mac, 0x4c9, 0x80);
3268		}
3269		PHY_SETBITS(mac, 0x42b, 0x800);
3270
3271		/* Fill RSSI table */
3272		for (i = 0; i < 64; ++i)
3273			bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i);
3274
3275		/* Fill noise table */
3276		for (i = 0; i < sizeof(bwi_phy_noise_11g); ++i) {
3277			bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
3278			    bwi_phy_noise_11g[i]);
3279		}
3280	}
3281
3282	/*
3283	 * Fill noise scale table
3284	 */
3285	if (phy->phy_rev <= 2) {
3286		tbl = bwi_phy_noise_scale_11g_rev2;
3287		n = N(bwi_phy_noise_scale_11g_rev2);
3288	} else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) {
3289		tbl = bwi_phy_noise_scale_11g_rev7;
3290		n = N(bwi_phy_noise_scale_11g_rev7);
3291	} else {
3292		tbl = bwi_phy_noise_scale_11g;
3293		n = N(bwi_phy_noise_scale_11g);
3294	}
3295	for (i = 0; i < n; ++i)
3296		bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]);
3297
3298	/*
3299	 * Fill sigma square table
3300	 */
3301	if (phy->phy_rev == 2) {
3302		tbl = bwi_phy_sigma_sq_11g_rev2;
3303		n = N(bwi_phy_sigma_sq_11g_rev2);
3304	} else if (phy->phy_rev > 2 && phy->phy_rev <= 8) {
3305		tbl = bwi_phy_sigma_sq_11g_rev7;
3306		n = N(bwi_phy_sigma_sq_11g_rev7);
3307	} else {
3308		tbl = NULL;
3309		n = 0;
3310	}
3311	for (i = 0; i < n; ++i)
3312		bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]);
3313
3314	if (phy->phy_rev == 1) {
3315		/* Fill delay table */
3316		for (i = 0; i < N(bwi_phy_delay_11g_rev1); ++i) {
3317			bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i,
3318			    bwi_phy_delay_11g_rev1[i]);
3319		}
3320
3321		/* Fill WRSSI (Wide-Band RSSI) table */
3322		for (i = 4; i < 20; ++i)
3323			bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20);
3324
3325		bwi_phy_config_agc(mac);
3326
3327		wrd_ofs1 = 0x5001;
3328		wrd_ofs2 = 0x5002;
3329	} else {
3330		/* Fill WRSSI (Wide-Band RSSI) table */
3331		for (i = 0; i < 0x20; ++i)
3332			bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820);
3333
3334		bwi_phy_config_agc(mac);
3335
3336		PHY_READ(mac, 0x400);	/* Dummy read */
3337		PHY_WRITE(mac, 0x403, 0x1000);
3338		bwi_tbl_write_2(mac, 0x3c02, 0xf);
3339		bwi_tbl_write_2(mac, 0x3c03, 0x14);
3340
3341		wrd_ofs1 = 0x401;
3342		wrd_ofs2 = 0x402;
3343	}
3344
3345	if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) {
3346		bwi_tbl_write_2(mac, wrd_ofs1, 0x2);
3347		bwi_tbl_write_2(mac, wrd_ofs2, 0x1);
3348	}
3349
3350	/* phy->phy_flags & BWI_PHY_F_LINKED ? */
3351	if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
3352		PHY_WRITE(mac, 0x46e, 0x3cf);
3353}
3354#undef N
3355
3356/*
3357 * Configure Automatic Gain Controller
3358 */
3359void
3360bwi_phy_config_agc(struct bwi_mac *mac)
3361{
3362	struct bwi_phy *phy = &mac->mac_phy;
3363	uint16_t ofs;
3364
3365	ofs = phy->phy_rev == 1 ? 0x4c00 : 0;
3366
3367	bwi_tbl_write_2(mac, ofs, 0xfe);
3368	bwi_tbl_write_2(mac, ofs + 1, 0xd);
3369	bwi_tbl_write_2(mac, ofs + 2, 0x13);
3370	bwi_tbl_write_2(mac, ofs + 3, 0x19);
3371
3372	if (phy->phy_rev == 1) {
3373		bwi_tbl_write_2(mac, 0x1800, 0x2710);
3374		bwi_tbl_write_2(mac, 0x1801, 0x9b83);
3375		bwi_tbl_write_2(mac, 0x1802, 0x9b83);
3376		bwi_tbl_write_2(mac, 0x1803, 0xf8d);
3377		PHY_WRITE(mac, 0x455, 0x4);
3378	}
3379
3380	PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700);
3381	PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf);
3382	PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80);
3383	PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300);
3384
3385	RF_SETBITS(mac, 0x7a, 0x8);
3386
3387	PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8);
3388	PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600);
3389	PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700);
3390	PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100);
3391
3392	if (phy->phy_rev == 1)
3393		PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7);
3394
3395	PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c);
3396	PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200);
3397	PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c);
3398	PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20);
3399	PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200);
3400	PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e);
3401	PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00);
3402	PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28);
3403	PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00);
3404
3405	if (phy->phy_rev == 1) {
3406		PHY_WRITE(mac, 0x430, 0x92b);
3407		PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2);
3408	} else {
3409		PHY_CLRBITS(mac, 0x41b, 0x1e);
3410		PHY_WRITE(mac, 0x41f, 0x287a);
3411		PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4);
3412
3413		if (phy->phy_rev >= 6) {
3414			PHY_WRITE(mac, 0x422, 0x287a);
3415			PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000);
3416		}
3417	}
3418
3419	PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874);
3420	PHY_WRITE(mac, 0x48e, 0x1c00);
3421
3422	if (phy->phy_rev == 1) {
3423		PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600);
3424		PHY_WRITE(mac, 0x48b, 0x5e);
3425		PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e);
3426		PHY_WRITE(mac, 0x48d, 0x2);
3427	}
3428
3429	bwi_tbl_write_2(mac, ofs + 0x800, 0);
3430	bwi_tbl_write_2(mac, ofs + 0x801, 7);
3431	bwi_tbl_write_2(mac, ofs + 0x802, 16);
3432	bwi_tbl_write_2(mac, ofs + 0x803, 28);
3433
3434	if (phy->phy_rev >= 6) {
3435		PHY_CLRBITS(mac, 0x426, 0x3);
3436		PHY_CLRBITS(mac, 0x426, 0x1000);
3437	}
3438}
3439
3440void
3441bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains)
3442{
3443	struct bwi_phy *phy = &mac->mac_phy;
3444	uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain;
3445	int i;
3446
3447	if (phy->phy_rev <= 1) {
3448		tbl_gain_ofs1 = 0x5000;
3449		tbl_gain_ofs2 = tbl_gain_ofs1 + 16;
3450	} else {
3451		tbl_gain_ofs1 = 0x400;
3452		tbl_gain_ofs2 = tbl_gain_ofs1 + 8;
3453	}
3454
3455	for (i = 0; i < 4; ++i) {
3456		if (gains != NULL) {
3457			tbl_gain = gains->tbl_gain1;
3458		} else {
3459			/* Bit swap */
3460			tbl_gain = (i & 0x1) << 1;
3461			tbl_gain |= (i & 0x2) >> 1;
3462		}
3463		bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain);
3464	}
3465
3466	for (i = 0; i < 16; ++i) {
3467		if (gains != NULL)
3468			tbl_gain = gains->tbl_gain2;
3469		else
3470			tbl_gain = i;
3471		bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain);
3472	}
3473
3474	if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) {
3475		uint16_t phy_gain1, phy_gain2;
3476
3477		if (gains != NULL) {
3478			phy_gain1 =
3479			((uint16_t)gains->phy_gain << 14) |
3480			((uint16_t)gains->phy_gain << 6);
3481			phy_gain2 = phy_gain1;
3482		} else {
3483			phy_gain1 = 0x4040;
3484			phy_gain2 = 0x4000;
3485		}
3486		PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1);
3487		PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1);
3488		PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2);
3489	}
3490	bwi_mac_dummy_xmit(mac);
3491}
3492
3493void
3494bwi_phy_clear_state(struct bwi_phy *phy)
3495{
3496	phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
3497}
3498
3499/* BWIRF */
3500
3501int16_t
3502bwi_nrssi_11g(struct bwi_mac *mac)
3503{
3504	int16_t val;
3505
3506#define NRSSI_11G_MASK		0x3f00
3507	val = (int16_t)__SHIFTOUT(PHY_READ(mac, 0x47f), NRSSI_11G_MASK);
3508	if (val >= 32)
3509		val -= 64;
3510
3511	return (val);
3512#undef NRSSI_11G_MASK
3513}
3514
3515struct bwi_rf_lo *
3516bwi_get_rf_lo(struct bwi_mac *mac, uint16_t rf_atten, uint16_t bbp_atten)
3517{
3518	int n;
3519
3520	n = rf_atten + (14 * (bbp_atten / 2));
3521	KKASSERT(n < BWI_RFLO_MAX);
3522
3523	return (&mac->mac_rf.rf_lo[n]);
3524}
3525
3526int
3527bwi_rf_lo_isused(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
3528{
3529	struct bwi_rf *rf = &mac->mac_rf;
3530	int idx;
3531
3532	idx = lo - rf->rf_lo;
3533	KKASSERT(idx >= 0 && idx < BWI_RFLO_MAX);
3534
3535	return (isset(rf->rf_lo_used, idx));
3536}
3537
3538void
3539bwi_rf_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
3540{
3541	struct bwi_softc *sc = mac->mac_sc;
3542
3543	CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl);
3544	CSR_WRITE_2(sc, BWI_RF_DATA_LO, data);
3545}
3546
3547uint16_t
3548bwi_rf_read(struct bwi_mac *mac, uint16_t ctrl)
3549{
3550	struct bwi_rf *rf = &mac->mac_rf;
3551	struct bwi_softc *sc = mac->mac_sc;
3552
3553	ctrl |= rf->rf_ctrl_rd;
3554	if (rf->rf_ctrl_adj) {
3555		/* XXX */
3556		if (ctrl < 0x70)
3557			ctrl += 0x80;
3558		else if (ctrl < 0x80)
3559			ctrl += 0x70;
3560	}
3561
3562	CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl);
3563	return (CSR_READ_2(sc, BWI_RF_DATA_LO));
3564}
3565
3566int
3567bwi_rf_attach(struct bwi_mac *mac)
3568{
3569	struct bwi_softc *sc = mac->mac_sc;
3570	struct bwi_rf *rf = &mac->mac_rf;
3571	uint16_t type, manu;
3572	uint8_t rev;
3573
3574	/*
3575	 * Get RF manufacture/type/revision
3576	 */
3577	if (sc->sc_bbp_id == BWI_BBPID_BCM4317) {
3578		/*
3579		 * Fake a BCM2050 RF
3580		 */
3581		manu = BWI_RF_MANUFACT_BCM;
3582		type = BWI_RF_T_BCM2050;
3583		if (sc->sc_bbp_rev == 0)
3584			rev = 3;
3585		else if (sc->sc_bbp_rev == 1)
3586			rev = 4;
3587		else
3588			rev = 5;
3589	} else {
3590		uint32_t val;
3591
3592		CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO);
3593		val = CSR_READ_2(sc, BWI_RF_DATA_HI);
3594		val <<= 16;
3595
3596		CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO);
3597		val |= CSR_READ_2(sc, BWI_RF_DATA_LO);
3598
3599		manu = __SHIFTOUT(val, BWI_RFINFO_MANUFACT_MASK);
3600		type = __SHIFTOUT(val, BWI_RFINFO_TYPE_MASK);
3601		rev = __SHIFTOUT(val, BWI_RFINFO_REV_MASK);
3602	}
3603	DPRINTF(1, "%s: RF manu 0x%03x, type 0x%04x, rev %u\n",
3604	    sc->sc_dev.dv_xname, manu, type, rev);
3605
3606	/*
3607	 * Verify whether the RF is supported
3608	 */
3609	rf->rf_ctrl_rd = 0;
3610	rf->rf_ctrl_adj = 0;
3611	switch (mac->mac_phy.phy_mode) {
3612	case IEEE80211_MODE_11A:
3613		if (manu != BWI_RF_MANUFACT_BCM ||
3614		    type != BWI_RF_T_BCM2060 ||
3615		    rev != 1) {
3616			DPRINTF(1, "%s: only BCM2060 rev 1 RF is supported for "
3617			    "11A PHY\n", sc->sc_dev.dv_xname);
3618			return (ENXIO);
3619		}
3620		rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11A;
3621		rf->rf_on = bwi_rf_on_11a;
3622		rf->rf_off = bwi_rf_off_11a;
3623		break;
3624	case IEEE80211_MODE_11B:
3625		if (type == BWI_RF_T_BCM2050) {
3626			rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
3627		} else if (type == BWI_RF_T_BCM2053) {
3628			rf->rf_ctrl_adj = 1;
3629		} else {
3630			DPRINTF(1, "%s: only BCM2050/BCM2053 RF is supported "
3631			    "for supported for 11B PHY\n", sc->sc_dev.dv_xname);
3632			return (ENXIO);
3633		}
3634		rf->rf_on = bwi_rf_on_11bg;
3635		rf->rf_off = bwi_rf_off_11bg;
3636		rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11b;
3637		rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11b;
3638		break;
3639	case IEEE80211_MODE_11G:
3640		if (type != BWI_RF_T_BCM2050) {
3641			DPRINTF(1, "%s: only BCM2050 RF is supported for 11G "
3642			    "PHY\n", sc->sc_dev.dv_xname);
3643			return (ENXIO);
3644		}
3645		rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
3646		rf->rf_on = bwi_rf_on_11bg;
3647		if (mac->mac_rev >= 5)
3648			rf->rf_off = bwi_rf_off_11g_rev5;
3649		else
3650			rf->rf_off = bwi_rf_off_11bg;
3651		rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11g;
3652		rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11g;
3653		break;
3654	default:
3655		DPRINTF(1, "%s: unsupported PHY mode\n", sc->sc_dev.dv_xname);
3656		return (ENXIO);
3657	}
3658
3659	rf->rf_type = type;
3660	rf->rf_rev = rev;
3661	rf->rf_manu = manu;
3662	rf->rf_curchan = IEEE80211_CHAN_ANY;
3663	rf->rf_ant_mode = BWI_ANT_MODE_AUTO;
3664
3665	return (0);
3666}
3667
3668void
3669bwi_rf_set_chan(struct bwi_mac *mac, u_int chan, int work_around)
3670{
3671	struct bwi_softc *sc = mac->mac_sc;
3672
3673	if (chan == IEEE80211_CHAN_ANY)
3674		return;
3675
3676	MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_CHAN, chan);
3677
3678	/* TODO: 11A */
3679
3680	if (work_around)
3681		bwi_rf_work_around(mac, chan);
3682
3683	CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan));
3684
3685	if (chan == 14) {
3686		if (sc->sc_locale == BWI_SPROM_LOCALE_JAPAN)
3687			HFLAGS_CLRBITS(mac, BWI_HFLAG_NOT_JAPAN);
3688		else
3689			HFLAGS_SETBITS(mac, BWI_HFLAG_NOT_JAPAN);
3690		CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, (1 << 11)); /* XXX */
3691	} else {
3692		CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0x840); /* XXX */
3693	}
3694	DELAY(8000);	/* DELAY(2000); */
3695
3696	mac->mac_rf.rf_curchan = chan;
3697}
3698
3699void
3700bwi_rf_get_gains(struct bwi_mac *mac)
3701{
3702#define SAVE_PHY_MAX	15
3703#define SAVE_RF_MAX	3
3704	struct bwi_softc *sc;
3705	struct bwi_phy *phy = &mac->mac_phy;
3706	struct bwi_rf *rf = &mac->mac_rf;
3707	uint16_t save_phy[SAVE_PHY_MAX];
3708	uint16_t save_rf[SAVE_RF_MAX];
3709	uint16_t trsw;
3710	int i, j, loop1_max, loop1, loop2;
3711
3712	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
3713	    { 0x52, 0x43, 0x7a };
3714	static const uint16_t save_phy_regs[SAVE_PHY_MAX] = {
3715	    0x0429, 0x0001, 0x0811, 0x0812,
3716	    0x0814, 0x0815, 0x005a, 0x0059,
3717	    0x0058, 0x000a, 0x0003, 0x080f,
3718	    0x0810, 0x002b, 0x0015
3719	};
3720
3721	sc = mac->mac_sc;
3722
3723	/*
3724	 * Save PHY/RF registers for later restoration
3725	 */
3726	for (i = 0; i < SAVE_PHY_MAX; ++i)
3727		save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
3728	PHY_READ(mac, 0x2d); /* dummy read */
3729
3730	for (i = 0; i < SAVE_RF_MAX; ++i)
3731		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
3732
3733	PHY_CLRBITS(mac, 0x429, 0xc000);
3734	PHY_SETBITS(mac, 0x1, 0x8000);
3735
3736	PHY_SETBITS(mac, 0x811, 0x2);
3737	PHY_CLRBITS(mac, 0x812, 0x2);
3738	PHY_SETBITS(mac, 0x811, 0x1);
3739	PHY_CLRBITS(mac, 0x812, 0x1);
3740
3741	PHY_SETBITS(mac, 0x814, 0x1);
3742	PHY_CLRBITS(mac, 0x815, 0x1);
3743	PHY_SETBITS(mac, 0x814, 0x2);
3744	PHY_CLRBITS(mac, 0x815, 0x2);
3745
3746	PHY_SETBITS(mac, 0x811, 0xc);
3747	PHY_SETBITS(mac, 0x812, 0xc);
3748	PHY_SETBITS(mac, 0x811, 0x30);
3749	PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
3750
3751	PHY_WRITE(mac, 0x5a, 0x780);
3752	PHY_WRITE(mac, 0x59, 0xc810);
3753	PHY_WRITE(mac, 0x58, 0xd);
3754	PHY_SETBITS(mac, 0xa, 0x2000);
3755
3756	PHY_SETBITS(mac, 0x814, 0x4);
3757	PHY_CLRBITS(mac, 0x815, 0x4);
3758
3759	PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
3760
3761	if (rf->rf_rev == 8) {
3762		loop1_max = 15;
3763		RF_WRITE(mac, 0x43, loop1_max);
3764	} else {
3765		loop1_max = 9;
3766	    	RF_WRITE(mac, 0x52, 0x0);
3767		RF_FILT_SETBITS(mac, 0x43, 0xfff0, loop1_max);
3768	}
3769
3770	bwi_phy_set_bbp_atten(mac, 11);
3771
3772	if (phy->phy_rev >= 3)
3773		PHY_WRITE(mac, 0x80f, 0xc020);
3774	else
3775		PHY_WRITE(mac, 0x80f, 0x8020);
3776	PHY_WRITE(mac, 0x810, 0);
3777
3778	PHY_FILT_SETBITS(mac, 0x2b, 0xffc0, 0x1);
3779	PHY_FILT_SETBITS(mac, 0x2b, 0xc0ff, 0x800);
3780	PHY_SETBITS(mac, 0x811, 0x100);
3781	PHY_CLRBITS(mac, 0x812, 0x3000);
3782
3783	if ((mac->mac_sc->sc_card_flags & BWI_CARD_F_EXT_LNA) &&
3784	    phy->phy_rev >= 7) {
3785		PHY_SETBITS(mac, 0x811, 0x800);
3786		PHY_SETBITS(mac, 0x812, 0x8000);
3787	}
3788	RF_CLRBITS(mac, 0x7a, 0xff08);
3789
3790	/*
3791	 * Find out 'loop1/loop2', which will be used to calculate
3792	 * max loopback gain later
3793	 */
3794	j = 0;
3795	for (i = 0; i < loop1_max; ++i) {
3796		for (j = 0; j < 16; ++j) {
3797			RF_WRITE(mac, 0x43, i);
3798
3799			if (bwi_rf_gain_max_reached(mac, j))
3800				goto loop1_exit;
3801		}
3802	}
3803loop1_exit:
3804	loop1 = i;
3805	loop2 = j;
3806
3807	/*
3808	 * Find out 'trsw', which will be used to calculate
3809	 * TRSW(TX/RX switch) RX gain later
3810	 */
3811	if (loop2 >= 8) {
3812		PHY_SETBITS(mac, 0x812, 0x30);
3813		trsw = 0x1b;
3814		for (i = loop2 - 8; i < 16; ++i) {
3815			trsw -= 3;
3816			if (bwi_rf_gain_max_reached(mac, i))
3817				break;
3818		}
3819	} else {
3820		trsw = 0x18;
3821	}
3822
3823	/*
3824	 * Restore saved PHY/RF registers
3825	 */
3826	/* First 4 saved PHY registers need special processing */
3827	for (i = 4; i < SAVE_PHY_MAX; ++i)
3828		PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
3829
3830	bwi_phy_set_bbp_atten(mac, mac->mac_tpctl.bbp_atten);
3831
3832	for (i = 0; i < SAVE_RF_MAX; ++i)
3833		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
3834
3835	PHY_WRITE(mac, save_phy_regs[2], save_phy[2] | 0x3);
3836	DELAY(10);
3837	PHY_WRITE(mac, save_phy_regs[2], save_phy[2]);
3838	PHY_WRITE(mac, save_phy_regs[3], save_phy[3]);
3839	PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
3840	PHY_WRITE(mac, save_phy_regs[1], save_phy[1]);
3841
3842	/*
3843	 * Calculate gains
3844	 */
3845	rf->rf_lo_gain = (loop2 * 6) - (loop1 * 4) - 11;
3846	rf->rf_rx_gain = trsw * 2;
3847	DPRINTF(1, "%s: lo gain: %u, rx gain: %u\n",
3848	    sc->sc_dev.dv_xname, rf->rf_lo_gain, rf->rf_rx_gain);
3849
3850#undef SAVE_RF_MAX
3851#undef SAVE_PHY_MAX
3852}
3853
3854void
3855bwi_rf_init(struct bwi_mac *mac)
3856{
3857	struct bwi_rf *rf = &mac->mac_rf;
3858
3859	if (rf->rf_type == BWI_RF_T_BCM2060) {
3860		/* TODO: 11A */
3861	} else {
3862		if (rf->rf_flags & BWI_RF_F_INITED)
3863			RF_WRITE(mac, 0x78, rf->rf_calib);
3864		else
3865			bwi_rf_init_bcm2050(mac);
3866	}
3867}
3868
3869void
3870bwi_rf_off_11a(struct bwi_mac *mac)
3871{
3872	RF_WRITE(mac, 0x4, 0xff);
3873	RF_WRITE(mac, 0x5, 0xfb);
3874
3875	PHY_SETBITS(mac, 0x10, 0x8);
3876	PHY_SETBITS(mac, 0x11, 0x8);
3877
3878	PHY_WRITE(mac, 0x15, 0xaa00);
3879}
3880
3881void
3882bwi_rf_off_11bg(struct bwi_mac *mac)
3883{
3884	PHY_WRITE(mac, 0x15, 0xaa00);
3885}
3886
3887void
3888bwi_rf_off_11g_rev5(struct bwi_mac *mac)
3889{
3890	PHY_SETBITS(mac, 0x811, 0x8c);
3891	PHY_CLRBITS(mac, 0x812, 0x8c);
3892}
3893
3894void
3895bwi_rf_work_around(struct bwi_mac *mac, u_int chan)
3896{
3897	struct bwi_softc *sc = mac->mac_sc;
3898	struct bwi_rf *rf = &mac->mac_rf;
3899
3900	if (chan == IEEE80211_CHAN_ANY) {
3901		DPRINTF(1, "%s: %s invalid channel!!\n",
3902		    sc->sc_dev.dv_xname, __func__);
3903		return;
3904	}
3905
3906	if (rf->rf_type != BWI_RF_T_BCM2050 || rf->rf_rev >= 6)
3907		return;
3908
3909	if (chan <= 10)
3910		CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan + 4));
3911	else
3912		CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(1));
3913	DELAY(1000);
3914	CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan));
3915}
3916
3917struct bwi_rf_lo *
3918bwi_rf_lo_find(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
3919{
3920	uint16_t rf_atten, bbp_atten;
3921	int remap_rf_atten;
3922
3923	remap_rf_atten = 1;
3924	if (tpctl == NULL) {
3925		bbp_atten = 2;
3926		rf_atten = 3;
3927	} else {
3928		if (tpctl->tp_ctrl1 == 3)
3929			remap_rf_atten = 0;
3930
3931		bbp_atten = tpctl->bbp_atten;
3932		rf_atten = tpctl->rf_atten;
3933
3934		if (bbp_atten > 6)
3935			bbp_atten = 6;
3936	}
3937
3938	if (remap_rf_atten) {
3939#define MAP_MAX	10
3940		static const uint16_t map[MAP_MAX] =
3941		{ 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 };
3942#if 0
3943		KKASSERT(rf_atten < MAP_MAX);
3944		rf_atten = map[rf_atten];
3945#else
3946		if (rf_atten >= MAP_MAX) {
3947			rf_atten = 0;	/* XXX */
3948		} else {
3949			rf_atten = map[rf_atten];
3950		}
3951#endif
3952#undef MAP_MAX
3953	}
3954
3955	return (bwi_get_rf_lo(mac, rf_atten, bbp_atten));
3956}
3957
3958void
3959bwi_rf_lo_adjust(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
3960{
3961	const struct bwi_rf_lo *lo;
3962
3963	lo = bwi_rf_lo_find(mac, tpctl);
3964	RF_LO_WRITE(mac, lo);
3965}
3966
3967void
3968bwi_rf_lo_write(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
3969{
3970	uint16_t val;
3971
3972	val = (uint8_t)lo->ctrl_lo;
3973	val |= ((uint8_t)lo->ctrl_hi) << 8;
3974
3975	PHY_WRITE(mac, BWI_PHYR_RF_LO, val);
3976}
3977
3978int
3979bwi_rf_gain_max_reached(struct bwi_mac *mac, int idx)
3980{
3981	PHY_FILT_SETBITS(mac, 0x812, 0xf0ff, idx << 8);
3982	PHY_FILT_SETBITS(mac, 0x15, 0xfff, 0xa000);
3983	PHY_SETBITS(mac, 0x15, 0xf000);
3984
3985	DELAY(20);
3986
3987	return ((PHY_READ(mac, 0x2d) >= 0xdfc));
3988}
3989
3990/* XXX use bitmap array */
3991uint16_t
3992bwi_bitswap4(uint16_t val)
3993{
3994	uint16_t ret;
3995
3996	ret = (val & 0x8) >> 3;
3997	ret |= (val & 0x4) >> 1;
3998	ret |= (val & 0x2) << 1;
3999	ret |= (val & 0x1) << 3;
4000
4001	return (ret);
4002}
4003
4004uint16_t
4005bwi_phy812_value(struct bwi_mac *mac, uint16_t lpd)
4006{
4007	struct bwi_softc *sc = mac->mac_sc;
4008	struct bwi_phy *phy = &mac->mac_phy;
4009	struct bwi_rf *rf = &mac->mac_rf;
4010	uint16_t lo_gain, ext_lna, loop;
4011
4012	if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
4013		return (0);
4014
4015	lo_gain = rf->rf_lo_gain;
4016	if (rf->rf_rev == 8)
4017		lo_gain += 0x3e;
4018	else
4019		lo_gain += 0x26;
4020
4021	if (lo_gain >= 0x46) {
4022		lo_gain -= 0x46;
4023		ext_lna = 0x3000;
4024	} else if (lo_gain >= 0x3a) {
4025		lo_gain -= 0x3a;
4026		ext_lna = 0x1000;
4027	} else if (lo_gain >= 0x2e) {
4028		lo_gain -= 0x2e;
4029		ext_lna = 0x2000;
4030	} else {
4031		lo_gain -= 0x10;
4032		ext_lna = 0;
4033	}
4034
4035	for (loop = 0; loop < 16; ++loop) {
4036		lo_gain -= (6 * loop);
4037		if (lo_gain < 6)
4038			break;
4039	}
4040
4041	if (phy->phy_rev >= 7 && (sc->sc_card_flags & BWI_CARD_F_EXT_LNA)) {
4042		if (ext_lna)
4043			ext_lna |= 0x8000;
4044		ext_lna |= (loop << 8);
4045		switch (lpd) {
4046		case 0x011:
4047			return (0x8f92);
4048		case 0x001:
4049			return ((0x8092 | ext_lna));
4050		case 0x101:
4051			return ((0x2092 | ext_lna));
4052		case 0x100:
4053			return ((0x2093 | ext_lna));
4054		default:
4055			panic("unsupported lpd\n");
4056		}
4057	} else {
4058		ext_lna |= (loop << 8);
4059		switch (lpd) {
4060		case 0x011:
4061			return (0xf92);
4062		case 0x001:
4063		case 0x101:
4064			return ((0x92 | ext_lna));
4065		case 0x100:
4066			return ((0x93 | ext_lna));
4067		default:
4068			panic("unsupported lpd\n");
4069		}
4070	}
4071
4072	panic("never reached\n");
4073
4074	return (0);
4075}
4076
4077void
4078bwi_rf_init_bcm2050(struct bwi_mac *mac)
4079{
4080#define SAVE_RF_MAX		3
4081#define SAVE_PHY_COMM_MAX	4
4082#define SAVE_PHY_11G_MAX	6
4083	uint16_t save_rf[SAVE_RF_MAX];
4084	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
4085	uint16_t save_phy_11g[SAVE_PHY_11G_MAX];
4086	uint16_t phyr_35, phyr_30 = 0, rfr_78, phyr_80f = 0, phyr_810 = 0;
4087	uint16_t bphy_ctrl = 0, bbp_atten, rf_chan_ex;
4088	uint16_t phy812_val;
4089	uint16_t calib;
4090	uint32_t test_lim, test;
4091	struct bwi_softc *sc = mac->mac_sc;
4092	struct bwi_phy *phy = &mac->mac_phy;
4093	struct bwi_rf *rf = &mac->mac_rf;
4094	int i;
4095
4096	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
4097	    { 0x0043, 0x0051, 0x0052 };
4098	static const uint16_t save_phy_regs_comm[SAVE_PHY_COMM_MAX] =
4099	    { 0x0015, 0x005a, 0x0059, 0x0058 };
4100	static const uint16_t save_phy_regs_11g[SAVE_PHY_11G_MAX] =
4101	    { 0x0811, 0x0812, 0x0814, 0x0815, 0x0429, 0x0802 };
4102
4103	/*
4104	 * Save registers for later restoring
4105	 */
4106	for (i = 0; i < SAVE_RF_MAX; ++i)
4107		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
4108	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
4109		save_phy_comm[i] = PHY_READ(mac, save_phy_regs_comm[i]);
4110
4111	if (phy->phy_mode == IEEE80211_MODE_11B) {
4112		phyr_30 = PHY_READ(mac, 0x30);
4113		bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL);
4114
4115		PHY_WRITE(mac, 0x30, 0xff);
4116		CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x3f3f);
4117	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4118		for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
4119			save_phy_11g[i] =
4120			    PHY_READ(mac, save_phy_regs_11g[i]);
4121		}
4122
4123		PHY_SETBITS(mac, 0x814, 0x3);
4124		PHY_CLRBITS(mac, 0x815, 0x3);
4125		PHY_CLRBITS(mac, 0x429, 0x8000);
4126		PHY_CLRBITS(mac, 0x802, 0x3);
4127
4128		phyr_80f = PHY_READ(mac, 0x80f);
4129		phyr_810 = PHY_READ(mac, 0x810);
4130
4131		if (phy->phy_rev >= 3)
4132			PHY_WRITE(mac, 0x80f, 0xc020);
4133		else
4134			PHY_WRITE(mac, 0x80f, 0x8020);
4135		PHY_WRITE(mac, 0x810, 0);
4136
4137		phy812_val = bwi_phy812_value(mac, 0x011);
4138		PHY_WRITE(mac, 0x812, phy812_val);
4139		if (phy->phy_rev < 7 ||
4140		    (sc->sc_card_flags & BWI_CARD_F_EXT_LNA) == 0)
4141			PHY_WRITE(mac, 0x811, 0x1b3);
4142		else
4143			PHY_WRITE(mac, 0x811, 0x9b3);
4144	}
4145	CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
4146
4147	phyr_35 = PHY_READ(mac, 0x35);
4148	PHY_CLRBITS(mac, 0x35, 0x80);
4149
4150	bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
4151	rf_chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
4152
4153	if (phy->phy_version == 0) {
4154		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
4155	} else {
4156		if (phy->phy_version >= 2)
4157			PHY_FILT_SETBITS(mac, 0x3, 0xffbf, 0x40);
4158		CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
4159	}
4160
4161	calib = bwi_rf_calibval(mac);
4162
4163	if (phy->phy_mode == IEEE80211_MODE_11B)
4164		RF_WRITE(mac, 0x78, 0x26);
4165
4166	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4167		phy812_val = bwi_phy812_value(mac, 0x011);
4168		PHY_WRITE(mac, 0x812, phy812_val);
4169	}
4170
4171	PHY_WRITE(mac, 0x15, 0xbfaf);
4172	PHY_WRITE(mac, 0x2b, 0x1403);
4173
4174	if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4175		phy812_val = bwi_phy812_value(mac, 0x001);
4176		PHY_WRITE(mac, 0x812, phy812_val);
4177	}
4178
4179	PHY_WRITE(mac, 0x15, 0xbfa0);
4180
4181	RF_SETBITS(mac, 0x51, 0x4);
4182	if (rf->rf_rev == 8)
4183		RF_WRITE(mac, 0x43, 0x1f);
4184	else {
4185		RF_WRITE(mac, 0x52, 0);
4186		RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
4187	}
4188
4189	test_lim = 0;
4190	PHY_WRITE(mac, 0x58, 0);
4191	for (i = 0; i < 16; ++i) {
4192		PHY_WRITE(mac, 0x5a, 0x480);
4193		PHY_WRITE(mac, 0x59, 0xc810);
4194
4195		PHY_WRITE(mac, 0x58, 0xd);
4196		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4197			phy812_val = bwi_phy812_value(mac, 0x101);
4198			PHY_WRITE(mac, 0x812, phy812_val);
4199		}
4200		PHY_WRITE(mac, 0x15, 0xafb0);
4201		DELAY(10);
4202
4203		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4204			phy812_val = bwi_phy812_value(mac, 0x101);
4205			PHY_WRITE(mac, 0x812, phy812_val);
4206		}
4207		PHY_WRITE(mac, 0x15, 0xefb0);
4208		DELAY(10);
4209
4210		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4211			phy812_val = bwi_phy812_value(mac, 0x100);
4212			PHY_WRITE(mac, 0x812, phy812_val);
4213		}
4214		PHY_WRITE(mac, 0x15, 0xfff0);
4215		DELAY(20);
4216
4217		test_lim += PHY_READ(mac, 0x2d);
4218
4219		PHY_WRITE(mac, 0x58, 0);
4220		if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4221			phy812_val = bwi_phy812_value(mac, 0x101);
4222			PHY_WRITE(mac, 0x812, phy812_val);
4223		}
4224		PHY_WRITE(mac, 0x15, 0xafb0);
4225	}
4226	++test_lim;
4227	test_lim >>= 9;
4228
4229	DELAY(10);
4230
4231	test = 0;
4232	PHY_WRITE(mac, 0x58, 0);
4233	for (i = 0; i < 16; ++i) {
4234		int j;
4235
4236		rfr_78 = (bwi_bitswap4(i) << 1) | 0x20;
4237		RF_WRITE(mac, 0x78, rfr_78);
4238		DELAY(10);
4239
4240		/* NB: This block is slight different than the above one */
4241		for (j = 0; j < 16; ++j) {
4242			PHY_WRITE(mac, 0x5a, 0xd80);
4243			PHY_WRITE(mac, 0x59, 0xc810);
4244
4245			PHY_WRITE(mac, 0x58, 0xd);
4246			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4247			    phy->phy_rev >= 2) {
4248				phy812_val = bwi_phy812_value(mac, 0x101);
4249				PHY_WRITE(mac, 0x812, phy812_val);
4250			}
4251			PHY_WRITE(mac, 0x15, 0xafb0);
4252			DELAY(10);
4253
4254			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4255			    phy->phy_rev >= 2) {
4256				phy812_val = bwi_phy812_value(mac, 0x101);
4257				PHY_WRITE(mac, 0x812, phy812_val);
4258			}
4259			PHY_WRITE(mac, 0x15, 0xefb0);
4260			DELAY(10);
4261
4262			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4263			    phy->phy_rev >= 2) {
4264				phy812_val = bwi_phy812_value(mac, 0x100);
4265				PHY_WRITE(mac, 0x812, phy812_val);
4266			}
4267			PHY_WRITE(mac, 0x15, 0xfff0);
4268			DELAY(10);
4269
4270			test += PHY_READ(mac, 0x2d);
4271
4272			PHY_WRITE(mac, 0x58, 0);
4273			if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
4274			    phy->phy_rev >= 2) {
4275				phy812_val = bwi_phy812_value(mac, 0x101);
4276				PHY_WRITE(mac, 0x812, phy812_val);
4277			}
4278			PHY_WRITE(mac, 0x15, 0xafb0);
4279		}
4280
4281		++test;
4282		test >>= 8;
4283
4284		if (test > test_lim)
4285			break;
4286	}
4287	if (i > 15)
4288		rf->rf_calib = rfr_78;
4289	else
4290		rf->rf_calib = calib;
4291	if (rf->rf_calib != 0xffff) {
4292		DPRINTF(1, "%s: RF calibration value: 0x%04x\n",
4293		    sc->sc_dev.dv_xname, rf->rf_calib);
4294		rf->rf_flags |= BWI_RF_F_INITED;
4295	}
4296
4297	/*
4298	 * Restore trashes registers
4299	 */
4300	PHY_WRITE(mac, save_phy_regs_comm[0], save_phy_comm[0]);
4301
4302	for (i = 0; i < SAVE_RF_MAX; ++i) {
4303		int pos = (i + 1) % SAVE_RF_MAX;
4304
4305		RF_WRITE(mac, save_rf_regs[pos], save_rf[pos]);
4306	}
4307	for (i = 1; i < SAVE_PHY_COMM_MAX; ++i)
4308		PHY_WRITE(mac, save_phy_regs_comm[i], save_phy_comm[i]);
4309
4310	CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
4311	if (phy->phy_version != 0)
4312		CSR_WRITE_2(sc, BWI_RF_CHAN_EX, rf_chan_ex);
4313
4314	PHY_WRITE(mac, 0x35, phyr_35);
4315	bwi_rf_work_around(mac, rf->rf_curchan);
4316
4317	if (phy->phy_mode == IEEE80211_MODE_11B) {
4318		PHY_WRITE(mac, 0x30, phyr_30);
4319		CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl);
4320	} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
4321		/* XXX Spec only says when PHY is linked (gmode) */
4322		CSR_CLRBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
4323
4324		for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
4325			PHY_WRITE(mac, save_phy_regs_11g[i],
4326				  save_phy_11g[i]);
4327		}
4328
4329		PHY_WRITE(mac, 0x80f, phyr_80f);
4330		PHY_WRITE(mac, 0x810, phyr_810);
4331	}
4332
4333#undef SAVE_PHY_11G_MAX
4334#undef SAVE_PHY_COMM_MAX
4335#undef SAVE_RF_MAX
4336}
4337
4338uint16_t
4339bwi_rf_calibval(struct bwi_mac *mac)
4340{
4341	uint16_t val, calib;
4342	int idx;
4343
4344	/* http://bcm-specs.sipsolutions.net/RCCTable */
4345	static const uint16_t rf_calibvals[] = {
4346		0x2, 0x3, 0x1, 0xf, 0x6, 0x7, 0x5, 0xf,
4347		0xa, 0xb, 0x9, 0xf, 0xe, 0xf, 0xd, 0xf
4348	};
4349
4350	val = RF_READ(mac, BWI_RFR_BBP_ATTEN);
4351	idx = __SHIFTOUT(val, BWI_RFR_BBP_ATTEN_CALIB_IDX);
4352	KKASSERT(idx < (int)(sizeof(rf_calibvals) / sizeof(rf_calibvals[0])));
4353
4354	calib = rf_calibvals[idx] << 1;
4355	if (val & BWI_RFR_BBP_ATTEN_CALIB_BIT)
4356		calib |= 0x1;
4357	calib |= 0x20;
4358
4359	return (calib);
4360}
4361
4362int32_t
4363_bwi_adjust_devide(int32_t num, int32_t den)
4364{
4365	if (num < 0)
4366		return ((num / den));
4367	else
4368		return ((num + den / 2) / den);
4369}
4370
4371/*
4372 * http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table
4373 * "calculating table entries"
4374 */
4375int
4376bwi_rf_calc_txpower(int8_t *txpwr, uint8_t idx, const int16_t pa_params[])
4377{
4378	int32_t m1, m2, f, dbm;
4379	int i;
4380
4381	m1 = _bwi_adjust_devide(16 * pa_params[0] + idx * pa_params[1], 32);
4382	m2 = imax(_bwi_adjust_devide(32768 + idx * pa_params[2], 256), 1);
4383
4384#define ITER_MAX	16
4385	f = 256;
4386	for (i = 0; i < ITER_MAX; ++i) {
4387		int32_t q, d;
4388
4389		q = _bwi_adjust_devide(
4390		    f * 4096 - _bwi_adjust_devide(m2 * f, 16) * f, 2048);
4391		d = abs(q - f);
4392		f = q;
4393
4394		if (d < 2)
4395			break;
4396	}
4397	if (i == ITER_MAX)
4398		return (EINVAL);
4399#undef ITER_MAX
4400
4401	dbm = _bwi_adjust_devide(m1 * f, 8192);
4402	if (dbm < -127)
4403		dbm = -127;
4404	else if (dbm > 128)
4405		dbm = 128;
4406
4407	*txpwr = dbm;
4408
4409	return (0);
4410}
4411
4412int
4413bwi_rf_map_txpower(struct bwi_mac *mac)
4414{
4415	struct bwi_softc *sc = mac->mac_sc;
4416	struct bwi_rf *rf = &mac->mac_rf;
4417	struct bwi_phy *phy = &mac->mac_phy;
4418	uint16_t sprom_ofs, val, mask;
4419	int16_t pa_params[3];
4420	int error = 0, i, ant_gain, reg_txpower_max;
4421
4422	/*
4423	 * Find out max TX power
4424	 */
4425	val = bwi_read_sprom(sc, BWI_SPROM_MAX_TXPWR);
4426	if (phy->phy_mode == IEEE80211_MODE_11A) {
4427		rf->rf_txpower_max = __SHIFTOUT(val,
4428		    BWI_SPROM_MAX_TXPWR_MASK_11A);
4429	} else {
4430		rf->rf_txpower_max = __SHIFTOUT(val,
4431		    BWI_SPROM_MAX_TXPWR_MASK_11BG);
4432
4433		if ((sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) &&
4434		    phy->phy_mode == IEEE80211_MODE_11G)
4435			rf->rf_txpower_max -= 3;
4436	}
4437	if (rf->rf_txpower_max <= 0) {
4438		DPRINTF(1, "%s: invalid max txpower in sprom\n",
4439		    sc->sc_dev.dv_xname);
4440		rf->rf_txpower_max = 74;
4441	}
4442	DPRINTF(1, "%s: max txpower from sprom: %d dBm\n",
4443	    sc->sc_dev.dv_xname, rf->rf_txpower_max);
4444
4445	/*
4446	 * Find out region/domain max TX power, which is adjusted
4447	 * by antenna gain and 1.5 dBm fluctuation as mentioned
4448	 * in v3 spec.
4449	 */
4450	val = bwi_read_sprom(sc, BWI_SPROM_ANT_GAIN);
4451	if (phy->phy_mode == IEEE80211_MODE_11A)
4452		ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11A);
4453	else
4454		ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11BG);
4455	if (ant_gain == 0xff) {
4456		DPRINTF(1, "%s: invalid antenna gain in sprom\n",
4457		    sc->sc_dev.dv_xname);
4458		ant_gain = 2;
4459	}
4460	ant_gain *= 4;
4461	DPRINTF(1, "%s: ant gain %d dBm\n", sc->sc_dev.dv_xname, ant_gain);
4462
4463	reg_txpower_max = 90 - ant_gain - 6;	/* XXX magic number */
4464	DPRINTF(1, "%s: region/domain max txpower %d dBm\n",
4465	    sc->sc_dev.dv_xname, reg_txpower_max);
4466
4467	/*
4468	 * Force max TX power within region/domain TX power limit
4469	 */
4470	if (rf->rf_txpower_max > reg_txpower_max)
4471		rf->rf_txpower_max = reg_txpower_max;
4472	DPRINTF(1, "%s: max txpower %d dBm\n",
4473	    sc->sc_dev.dv_xname, rf->rf_txpower_max);
4474
4475	/*
4476	 * Create TSSI to TX power mapping
4477	 */
4478
4479	if (sc->sc_bbp_id == BWI_BBPID_BCM4301 &&
4480	    rf->rf_type != BWI_RF_T_BCM2050) {
4481		rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
4482		bcopy(bwi_txpower_map_11b, rf->rf_txpower_map0,
4483		      sizeof(rf->rf_txpower_map0));
4484		goto back;
4485	}
4486
4487#define IS_VALID_PA_PARAM(p)	((p) != 0 && (p) != -1)
4488#define N(arr)	(int)(sizeof(arr) / sizeof(arr[0]))
4489	/*
4490	 * Extract PA parameters
4491	 */
4492	if (phy->phy_mode == IEEE80211_MODE_11A)
4493		sprom_ofs = BWI_SPROM_PA_PARAM_11A;
4494	else
4495		sprom_ofs = BWI_SPROM_PA_PARAM_11BG;
4496	for (i = 0; i < N(pa_params); ++i)
4497		pa_params[i] = (int16_t)bwi_read_sprom(sc, sprom_ofs + (i * 2));
4498
4499	for (i = 0; i < N(pa_params); ++i) {
4500		/*
4501		 * If one of the PA parameters from SPROM is not valid,
4502		 * fall back to the default values, if there are any.
4503		 */
4504		if (!IS_VALID_PA_PARAM(pa_params[i])) {
4505			const int8_t *txpower_map;
4506
4507			if (phy->phy_mode == IEEE80211_MODE_11A) {
4508				printf("%s: no tssi2dbm table for 11a PHY\n",
4509				    sc->sc_dev.dv_xname);
4510				return (ENXIO);
4511			}
4512
4513			if (phy->phy_mode == IEEE80211_MODE_11G) {
4514				DPRINTF(1, "%s: use default 11g TSSI map\n",
4515				    sc->sc_dev.dv_xname);
4516				txpower_map = bwi_txpower_map_11g;
4517			} else {
4518				txpower_map = bwi_txpower_map_11b;
4519			}
4520
4521			rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
4522			bcopy(txpower_map, rf->rf_txpower_map0,
4523			      sizeof(rf->rf_txpower_map0));
4524			goto back;
4525		}
4526	}
4527#undef N
4528
4529	/*
4530	 * All of the PA parameters from SPROM are valid.
4531	 */
4532
4533	/*
4534	 * Extract idle TSSI from SPROM.
4535	 */
4536	val = bwi_read_sprom(sc, BWI_SPROM_IDLE_TSSI);
4537	DPRINTF(1, "%s: sprom idle tssi: 0x%04x\n", sc->sc_dev.dv_xname, val);
4538
4539	if (phy->phy_mode == IEEE80211_MODE_11A)
4540		mask = BWI_SPROM_IDLE_TSSI_MASK_11A;
4541	else
4542		mask = BWI_SPROM_IDLE_TSSI_MASK_11BG;
4543
4544	rf->rf_idle_tssi0 = (int)__SHIFTOUT(val, mask);
4545	if (!IS_VALID_PA_PARAM(rf->rf_idle_tssi0))
4546		rf->rf_idle_tssi0 = 62;
4547
4548#undef IS_VALID_PA_PARAM
4549
4550	/*
4551	 * Calculate TX power map, which is indexed by TSSI
4552	 */
4553	DPRINTF(1, "%s: TSSI-TX power map:\n", sc->sc_dev.dv_xname);
4554	for (i = 0; i < BWI_TSSI_MAX; ++i) {
4555		error = bwi_rf_calc_txpower(&rf->rf_txpower_map0[i], i,
4556					    pa_params);
4557		if (error) {
4558			DPRINTF(1, "%s: bwi_rf_calc_txpower failed\n",
4559			    sc->sc_dev.dv_xname);
4560			break;
4561		}
4562		if (i != 0 && i % 8 == 0)
4563			printf("\n");
4564		printf("%d ", rf->rf_txpower_map0[i]);
4565	}
4566	printf("\n");
4567back:
4568	DPRINTF(1, "%s: idle tssi0: %d\n",
4569	    sc->sc_dev.dv_xname, rf->rf_idle_tssi0);
4570
4571	return (error);
4572}
4573
4574void
4575bwi_rf_lo_update(struct bwi_mac *mac)
4576{
4577	struct bwi_softc *sc = mac->mac_sc;
4578	struct ifnet *ifp = &sc->sc_ic.ic_if;
4579	struct bwi_rf *rf = &mac->mac_rf;
4580	struct bwi_phy *phy = &mac->mac_phy;
4581	struct bwi_tpctl *tpctl = &mac->mac_tpctl;
4582	struct rf_saveregs regs;
4583	uint16_t ant_div, chan_ex;
4584	uint8_t devi_ctrl;
4585	u_int orig_chan;
4586
4587	/*
4588	 * Save RF/PHY registers for later restoration
4589	 */
4590	orig_chan = rf->rf_curchan;
4591	bzero(&regs, sizeof(regs));
4592
4593	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4594		SAVE_PHY_REG(mac, &regs, 429);
4595		SAVE_PHY_REG(mac, &regs, 802);
4596
4597		PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
4598		PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
4599	}
4600
4601	ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
4602	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div | 0x8000);
4603	chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
4604
4605	SAVE_PHY_REG(mac, &regs, 15);
4606	SAVE_PHY_REG(mac, &regs, 2a);
4607	SAVE_PHY_REG(mac, &regs, 35);
4608	SAVE_PHY_REG(mac, &regs, 60);
4609	SAVE_RF_REG(mac, &regs, 43);
4610	SAVE_RF_REG(mac, &regs, 7a);
4611	SAVE_RF_REG(mac, &regs, 52);
4612	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4613		SAVE_PHY_REG(mac, &regs, 811);
4614		SAVE_PHY_REG(mac, &regs, 812);
4615		SAVE_PHY_REG(mac, &regs, 814);
4616		SAVE_PHY_REG(mac, &regs, 815);
4617	}
4618
4619	/* Force to channel 6 */
4620	bwi_rf_set_chan(mac, 6, 0);
4621
4622	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4623		PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
4624		PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
4625		bwi_mac_dummy_xmit(mac);
4626	}
4627	RF_WRITE(mac, 0x43, 0x6);
4628
4629	bwi_phy_set_bbp_atten(mac, 2);
4630
4631	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0);
4632
4633	PHY_WRITE(mac, 0x2e, 0x7f);
4634	PHY_WRITE(mac, 0x80f, 0x78);
4635	PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f);
4636	RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0);
4637	PHY_WRITE(mac, 0x2b, 0x203);
4638	PHY_WRITE(mac, 0x2a, 0x8a3);
4639
4640	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4641		PHY_WRITE(mac, 0x814, regs.phy_814 | 0x3);
4642		PHY_WRITE(mac, 0x815, regs.phy_815 & 0xfffc);
4643		PHY_WRITE(mac, 0x811, 0x1b3);
4644		PHY_WRITE(mac, 0x812, 0xb2);
4645	}
4646
4647	if ((ifp->if_flags & IFF_RUNNING) == 0)
4648		tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac);
4649	PHY_WRITE(mac, 0x80f, 0x8078);
4650
4651	/*
4652	 * Measure all RF LO
4653	 */
4654	devi_ctrl = _bwi_rf_lo_update(mac, regs.rf_7a);
4655
4656	/*
4657	 * Restore saved RF/PHY registers
4658	 */
4659	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4660		PHY_WRITE(mac, 0x15, 0xe300);
4661		PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa0);
4662		DELAY(5);
4663		PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa2);
4664		DELAY(2);
4665		PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa3);
4666	} else
4667		PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0);
4668
4669	if ((ifp->if_flags & IFF_RUNNING) == 0)
4670		tpctl = NULL;
4671	bwi_rf_lo_adjust(mac, tpctl);
4672
4673	PHY_WRITE(mac, 0x2e, 0x807f);
4674	if (phy->phy_flags & BWI_PHY_F_LINKED)
4675		PHY_WRITE(mac, 0x2f, 0x202);
4676	else
4677		PHY_WRITE(mac, 0x2f, 0x101);
4678
4679	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
4680
4681	RESTORE_PHY_REG(mac, &regs, 15);
4682	RESTORE_PHY_REG(mac, &regs, 2a);
4683	RESTORE_PHY_REG(mac, &regs, 35);
4684	RESTORE_PHY_REG(mac, &regs, 60);
4685
4686	RESTORE_RF_REG(mac, &regs, 43);
4687	RESTORE_RF_REG(mac, &regs, 7a);
4688
4689	regs.rf_52 &= 0xf0;
4690	regs.rf_52 |= (RF_READ(mac, 0x52) & 0xf);
4691	RF_WRITE(mac, 0x52, regs.rf_52);
4692
4693	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
4694
4695	if (phy->phy_flags & BWI_PHY_F_LINKED) {
4696		RESTORE_PHY_REG(mac, &regs, 811);
4697		RESTORE_PHY_REG(mac, &regs, 812);
4698		RESTORE_PHY_REG(mac, &regs, 814);
4699		RESTORE_PHY_REG(mac, &regs, 815);
4700		RESTORE_PHY_REG(mac, &regs, 429);
4701		RESTORE_PHY_REG(mac, &regs, 802);
4702	}
4703
4704	bwi_rf_set_chan(mac, orig_chan, 1);
4705}
4706
4707uint32_t
4708bwi_rf_lo_devi_measure(struct bwi_mac *mac, uint16_t ctrl)
4709{
4710	struct bwi_phy *phy = &mac->mac_phy;
4711	uint32_t devi = 0;
4712	int i;
4713
4714	if (phy->phy_flags & BWI_PHY_F_LINKED)
4715		ctrl <<= 8;
4716
4717	for (i = 0; i < 8; ++i) {
4718		if (phy->phy_flags & BWI_PHY_F_LINKED) {
4719			PHY_WRITE(mac, 0x15, 0xe300);
4720			PHY_WRITE(mac, 0x812, ctrl | 0xb0);
4721			DELAY(5);
4722			PHY_WRITE(mac, 0x812, ctrl | 0xb2);
4723			DELAY(2);
4724			PHY_WRITE(mac, 0x812, ctrl | 0xb3);
4725			DELAY(4);
4726			PHY_WRITE(mac, 0x15, 0xf300);
4727		} else {
4728			PHY_WRITE(mac, 0x15, ctrl | 0xefa0);
4729			DELAY(2);
4730			PHY_WRITE(mac, 0x15, ctrl | 0xefe0);
4731			DELAY(4);
4732			PHY_WRITE(mac, 0x15, ctrl | 0xffe0);
4733		}
4734		DELAY(8);
4735		devi += PHY_READ(mac, 0x2d);
4736	}
4737
4738	return (devi);
4739}
4740
4741uint16_t
4742bwi_rf_get_tp_ctrl2(struct bwi_mac *mac)
4743{
4744	uint32_t devi_min;
4745	uint16_t tp_ctrl2 = 0;
4746	int i;
4747
4748	RF_WRITE(mac, 0x52, 0);
4749	DELAY(10);
4750	devi_min = bwi_rf_lo_devi_measure(mac, 0);
4751
4752	for (i = 0; i < 16; ++i) {
4753		uint32_t devi;
4754
4755		RF_WRITE(mac, 0x52, i);
4756		DELAY(10);
4757		devi = bwi_rf_lo_devi_measure(mac, 0);
4758
4759		if (devi < devi_min) {
4760			devi_min = devi;
4761			tp_ctrl2 = i;
4762		}
4763	}
4764
4765	return (tp_ctrl2);
4766}
4767
4768uint8_t
4769_bwi_rf_lo_update(struct bwi_mac *mac, uint16_t orig_rf7a)
4770{
4771#define RF_ATTEN_LISTSZ	14
4772#define BBP_ATTEN_MAX	4	/* half */
4773	struct ifnet *ifp = &mac->mac_sc->sc_ic.ic_if;
4774	struct bwi_rf_lo lo_save, *lo;
4775	uint8_t devi_ctrl = 0;
4776	int idx, adj_rf7a = 0;
4777
4778	static const int rf_atten_list[RF_ATTEN_LISTSZ] =
4779	    { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 1, 2, 3, 4 };
4780	static const int rf_atten_init_list[RF_ATTEN_LISTSZ] =
4781            { 0, 3, 1, 5, 7, 3, 2, 0, 4, 6, -1, -1, -1, -1 };
4782	static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] =
4783	    { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 };
4784
4785	bzero(&lo_save, sizeof(lo_save));
4786	for (idx = 0; idx < RF_ATTEN_LISTSZ; ++idx) {
4787		int init_rf_atten = rf_atten_init_list[idx];
4788		int rf_atten = rf_atten_list[idx];
4789		int bbp_atten;
4790
4791		for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) {
4792			uint16_t tp_ctrl2, rf7a;
4793
4794			if ((ifp->if_flags & IFF_RUNNING) == 0) {
4795				if (idx == 0) {
4796					bzero(&lo_save, sizeof(lo_save));
4797				} else if (init_rf_atten < 0) {
4798					lo = bwi_get_rf_lo(mac,
4799					    rf_atten, 2 * bbp_atten);
4800					bcopy(lo, &lo_save, sizeof(lo_save));
4801				} else {
4802					lo = bwi_get_rf_lo(mac,
4803					    init_rf_atten, 0);
4804					bcopy(lo, &lo_save, sizeof(lo_save));
4805				}
4806
4807				devi_ctrl = 0;
4808				adj_rf7a = 0;
4809
4810				/*
4811				 * XXX
4812				 * Linux driver overflows 'val'
4813				 */
4814				if (init_rf_atten >= 0) {
4815					int val;
4816
4817					val = rf_atten * 2 + bbp_atten;
4818					if (val > 14) {
4819						adj_rf7a = 1;
4820						if (val > 17)
4821							devi_ctrl = 1;
4822						if (val > 19)
4823							devi_ctrl = 2;
4824					}
4825				}
4826			} else {
4827				lo = bwi_get_rf_lo(mac,
4828					rf_atten, 2 * bbp_atten);
4829				if (!bwi_rf_lo_isused(mac, lo))
4830					continue;
4831				bcopy(lo, &lo_save, sizeof(lo_save));
4832
4833				devi_ctrl = 3;
4834				adj_rf7a = 0;
4835			}
4836
4837			RF_WRITE(mac, BWI_RFR_ATTEN, rf_atten);
4838
4839			tp_ctrl2 = mac->mac_tpctl.tp_ctrl2;
4840			if (init_rf_atten < 0)
4841				tp_ctrl2 |= (3 << 4);
4842			RF_WRITE(mac, BWI_RFR_TXPWR, tp_ctrl2);
4843
4844			DELAY(10);
4845
4846			bwi_phy_set_bbp_atten(mac, bbp_atten * 2);
4847
4848			rf7a = orig_rf7a & 0xfff0;
4849			if (adj_rf7a)
4850				rf7a |= 0x8;
4851			RF_WRITE(mac, 0x7a, rf7a);
4852
4853			lo = bwi_get_rf_lo(mac,
4854				rf_lo_measure_order[idx], bbp_atten * 2);
4855			bwi_rf_lo_measure(mac, &lo_save, lo, devi_ctrl);
4856		}
4857	}
4858
4859	return (devi_ctrl);
4860
4861#undef RF_ATTEN_LISTSZ
4862#undef BBP_ATTEN_MAX
4863}
4864
4865void
4866bwi_rf_lo_measure(struct bwi_mac *mac, const struct bwi_rf_lo *src_lo,
4867    struct bwi_rf_lo *dst_lo, uint8_t devi_ctrl)
4868{
4869#define LO_ADJUST_MIN	1
4870#define LO_ADJUST_MAX	8
4871#define LO_ADJUST(hi, lo)	{ .ctrl_hi = hi, .ctrl_lo = lo }
4872	static const struct bwi_rf_lo rf_lo_adjust[LO_ADJUST_MAX] = {
4873		LO_ADJUST(1,	1),
4874		LO_ADJUST(1,	0),
4875		LO_ADJUST(1,	-1),
4876		LO_ADJUST(0,	-1),
4877		LO_ADJUST(-1,	-1),
4878		LO_ADJUST(-1,	0),
4879		LO_ADJUST(-1,	1),
4880		LO_ADJUST(0,	1)
4881	};
4882#undef LO_ADJUST
4883
4884	struct bwi_rf_lo lo_min;
4885	uint32_t devi_min;
4886	int found, loop_count, adjust_state;
4887
4888	bcopy(src_lo, &lo_min, sizeof(lo_min));
4889	RF_LO_WRITE(mac, &lo_min);
4890	devi_min = bwi_rf_lo_devi_measure(mac, devi_ctrl);
4891
4892	loop_count = 12;	/* XXX */
4893	adjust_state = 0;
4894	do {
4895		struct bwi_rf_lo lo_base;
4896		int i, fin;
4897
4898		found = 0;
4899		if (adjust_state == 0) {
4900			i = LO_ADJUST_MIN;
4901			fin = LO_ADJUST_MAX;
4902		} else if (adjust_state % 2 == 0) {
4903			i = adjust_state - 1;
4904			fin = adjust_state + 1;
4905		} else {
4906			i = adjust_state - 2;
4907			fin = adjust_state + 2;
4908		}
4909
4910		if (i < LO_ADJUST_MIN)
4911			i += LO_ADJUST_MAX;
4912		KKASSERT(i <= LO_ADJUST_MAX && i >= LO_ADJUST_MIN);
4913
4914		if (fin > LO_ADJUST_MAX)
4915			fin -= LO_ADJUST_MAX;
4916		KKASSERT(fin <= LO_ADJUST_MAX && fin >= LO_ADJUST_MIN);
4917
4918		bcopy(&lo_min, &lo_base, sizeof(lo_base));
4919		for (;;) {
4920			struct bwi_rf_lo lo;
4921
4922			lo.ctrl_hi = lo_base.ctrl_hi +
4923				rf_lo_adjust[i - 1].ctrl_hi;
4924			lo.ctrl_lo = lo_base.ctrl_lo +
4925				rf_lo_adjust[i - 1].ctrl_lo;
4926
4927			if (abs(lo.ctrl_lo) < 9 && abs(lo.ctrl_hi) < 9) {
4928				uint32_t devi;
4929
4930				RF_LO_WRITE(mac, &lo);
4931				devi = bwi_rf_lo_devi_measure(mac, devi_ctrl);
4932				if (devi < devi_min) {
4933					devi_min = devi;
4934					adjust_state = i;
4935					found = 1;
4936					bcopy(&lo, &lo_min, sizeof(lo_min));
4937				}
4938			}
4939			if (i == fin)
4940				break;
4941			if (i == LO_ADJUST_MAX)
4942				i = LO_ADJUST_MIN;
4943			else
4944				++i;
4945		}
4946	} while (loop_count-- && found);
4947
4948	bcopy(&lo_min, dst_lo, sizeof(*dst_lo));
4949
4950#undef LO_ADJUST_MIN
4951#undef LO_ADJUST_MAX
4952}
4953
4954void
4955bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *mac)
4956{
4957#define SAVE_RF_MAX	3
4958#define SAVE_PHY_MAX	8
4959	struct bwi_softc *sc = mac->mac_sc;
4960	struct bwi_rf *rf = &mac->mac_rf;
4961	struct bwi_phy *phy = &mac->mac_phy;
4962	uint16_t save_rf[SAVE_RF_MAX];
4963	uint16_t save_phy[SAVE_PHY_MAX];
4964	uint16_t ant_div, bbp_atten, chan_ex;
4965	int16_t nrssi[2];
4966	int i;
4967
4968	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
4969	    { 0x7a, 0x52, 0x43 };
4970	static const uint16_t save_phy_regs[SAVE_PHY_MAX] =
4971	    { 0x30, 0x26, 0x15, 0x2a, 0x20, 0x5a, 0x59, 0x58 };
4972
4973	/*
4974	 * Save RF/PHY registers for later restoration
4975	 */
4976	for (i = 0; i < SAVE_RF_MAX; ++i)
4977		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
4978	for (i = 0; i < SAVE_PHY_MAX; ++i)
4979		save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
4980
4981	ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
4982	bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
4983	chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
4984
4985	/*
4986	 * Calculate nrssi0
4987	 */
4988	if (phy->phy_rev >= 5)
4989		RF_CLRBITS(mac, 0x7a, 0xff80);
4990	else
4991		RF_CLRBITS(mac, 0x7a, 0xfff0);
4992	PHY_WRITE(mac, 0x30, 0xff);
4993
4994	CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x7f7f);
4995
4996	PHY_WRITE(mac, 0x26, 0);
4997	PHY_SETBITS(mac, 0x15, 0x20);
4998	PHY_WRITE(mac, 0x2a, 0x8a3);
4999	RF_SETBITS(mac, 0x7a, 0x80);
5000
5001	nrssi[0] = (int16_t)PHY_READ(mac, 0x27);
5002
5003	/*
5004	 * Calculate nrssi1
5005	 */
5006	RF_CLRBITS(mac, 0x7a, 0xff80);
5007	if (phy->phy_version >= 2)
5008		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x40);
5009	else if (phy->phy_version == 0)
5010		CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
5011	else
5012		CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0xdfff);
5013
5014	PHY_WRITE(mac, 0x20, 0x3f3f);
5015	PHY_WRITE(mac, 0x15, 0xf330);
5016
5017	RF_WRITE(mac, 0x5a, 0x60);
5018	RF_CLRBITS(mac, 0x43, 0xff0f);
5019
5020	PHY_WRITE(mac, 0x5a, 0x480);
5021	PHY_WRITE(mac, 0x59, 0x810);
5022	PHY_WRITE(mac, 0x58, 0xd);
5023
5024	DELAY(20);
5025
5026	nrssi[1] = (int16_t)PHY_READ(mac, 0x27);
5027
5028	/*
5029	 * Restore saved RF/PHY registers
5030	 */
5031	PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
5032	RF_WRITE(mac, save_rf_regs[0], save_rf[0]);
5033
5034	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
5035
5036	for (i = 1; i < 4; ++i)
5037		PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
5038
5039	bwi_rf_work_around(mac, rf->rf_curchan);
5040
5041	if (phy->phy_version != 0)
5042		CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
5043
5044	for (; i < SAVE_PHY_MAX; ++i)
5045		PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
5046
5047	for (i = 1; i < SAVE_RF_MAX; ++i)
5048		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
5049
5050	/*
5051	 * Install calculated narrow RSSI values
5052	 */
5053	if (nrssi[0] == nrssi[1])
5054		rf->rf_nrssi_slope = 0x10000;
5055	else
5056		rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
5057	if (nrssi[0] <= -4) {
5058		rf->rf_nrssi[0] = nrssi[0];
5059		rf->rf_nrssi[1] = nrssi[1];
5060	}
5061
5062#undef SAVE_RF_MAX
5063#undef SAVE_PHY_MAX
5064}
5065
5066void
5067bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *mac)
5068{
5069#define SAVE_RF_MAX		2
5070#define SAVE_PHY_COMM_MAX	10
5071#define SAVE_PHY6_MAX		8
5072	struct bwi_phy *phy = &mac->mac_phy;
5073	uint16_t save_rf[SAVE_RF_MAX];
5074	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
5075	uint16_t save_phy6[SAVE_PHY6_MAX];
5076	uint16_t rf7b = 0xffff;
5077	int16_t nrssi;
5078	int i, phy6_idx = 0;
5079
5080	static const uint16_t save_rf_regs[SAVE_RF_MAX] = { 0x7a, 0x43 };
5081	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
5082		0x0001, 0x0811, 0x0812, 0x0814,
5083		0x0815, 0x005a, 0x0059, 0x0058,
5084		0x000a, 0x0003
5085	};
5086	static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
5087		0x002e, 0x002f, 0x080f, 0x0810,
5088		0x0801, 0x0060, 0x0014, 0x0478
5089	};
5090
5091	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
5092		save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
5093	for (i = 0; i < SAVE_RF_MAX; ++i)
5094		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
5095
5096	PHY_CLRBITS(mac, 0x429, 0x8000);
5097	PHY_FILT_SETBITS(mac, 0x1, 0x3fff, 0x4000);
5098	PHY_SETBITS(mac, 0x811, 0xc);
5099	PHY_FILT_SETBITS(mac, 0x812, 0xfff3, 0x4);
5100	PHY_CLRBITS(mac, 0x802, 0x3);
5101
5102	if (phy->phy_rev >= 6) {
5103		for (i = 0; i < SAVE_PHY6_MAX; ++i)
5104			save_phy6[i] = PHY_READ(mac, save_phy6_regs[i]);
5105
5106		PHY_WRITE(mac, 0x2e, 0);
5107		PHY_WRITE(mac, 0x2f, 0);
5108		PHY_WRITE(mac, 0x80f, 0);
5109		PHY_WRITE(mac, 0x810, 0);
5110		PHY_SETBITS(mac, 0x478, 0x100);
5111		PHY_SETBITS(mac, 0x801, 0x40);
5112		PHY_SETBITS(mac, 0x60, 0x40);
5113		PHY_SETBITS(mac, 0x14, 0x200);
5114	}
5115
5116	RF_SETBITS(mac, 0x7a, 0x70);
5117	RF_SETBITS(mac, 0x7a, 0x80);
5118
5119	DELAY(30);
5120
5121	nrssi = bwi_nrssi_11g(mac);
5122	if (nrssi == 31) {
5123		for (i = 7; i >= 4; --i) {
5124			RF_WRITE(mac, 0x7b, i);
5125			DELAY(20);
5126			nrssi = bwi_nrssi_11g(mac);
5127			if (nrssi < 31 && rf7b == 0xffff)
5128				rf7b = i;
5129		}
5130		if (rf7b == 0xffff)
5131			rf7b = 4;
5132	} else {
5133		struct bwi_gains gains;
5134
5135		RF_CLRBITS(mac, 0x7a, 0xff80);
5136
5137		PHY_SETBITS(mac, 0x814, 0x1);
5138		PHY_CLRBITS(mac, 0x815, 0x1);
5139		PHY_SETBITS(mac, 0x811, 0xc);
5140		PHY_SETBITS(mac, 0x812, 0xc);
5141		PHY_SETBITS(mac, 0x811, 0x30);
5142		PHY_SETBITS(mac, 0x812, 0x30);
5143		PHY_WRITE(mac, 0x5a, 0x480);
5144		PHY_WRITE(mac, 0x59, 0x810);
5145		PHY_WRITE(mac, 0x58, 0xd);
5146		if (phy->phy_version == 0)
5147			PHY_WRITE(mac, 0x3, 0x122);
5148		else
5149			PHY_SETBITS(mac, 0xa, 0x2000);
5150		PHY_SETBITS(mac, 0x814, 0x4);
5151		PHY_CLRBITS(mac, 0x815, 0x4);
5152		PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
5153		RF_SETBITS(mac, 0x7a, 0xf);
5154
5155		bzero(&gains, sizeof(gains));
5156		gains.tbl_gain1 = 3;
5157		gains.tbl_gain2 = 0;
5158		gains.phy_gain = 1;
5159		bwi_set_gains(mac, &gains);
5160
5161		RF_FILT_SETBITS(mac, 0x43, 0xf0, 0xf);
5162		DELAY(30);
5163
5164		nrssi = bwi_nrssi_11g(mac);
5165		if (nrssi == -32) {
5166			for (i = 0; i < 4; ++i) {
5167				RF_WRITE(mac, 0x7b, i);
5168				DELAY(20);
5169				nrssi = bwi_nrssi_11g(mac);
5170				if (nrssi > -31 && rf7b == 0xffff)
5171					rf7b = i;
5172			}
5173			if (rf7b == 0xffff)
5174				rf7b = 3;
5175		} else {
5176			rf7b = 0;
5177		}
5178	}
5179	RF_WRITE(mac, 0x7b, rf7b);
5180
5181	/*
5182	 * Restore saved RF/PHY registers
5183	 */
5184	if (phy->phy_rev >= 6) {
5185		for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
5186			PHY_WRITE(mac, save_phy6_regs[phy6_idx],
5187			    save_phy6[phy6_idx]);
5188		}
5189	}
5190
5191	/* Saved PHY registers 0, 1, 2 are handled later */
5192	for (i = 3; i < SAVE_PHY_COMM_MAX; ++i)
5193		PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
5194
5195	for (i = SAVE_RF_MAX - 1; i >= 0; --i)
5196		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
5197
5198	PHY_SETBITS(mac, 0x802, 0x3);
5199	PHY_SETBITS(mac, 0x429, 0x8000);
5200
5201	bwi_set_gains(mac, NULL);
5202
5203	if (phy->phy_rev >= 6) {
5204		for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
5205			PHY_WRITE(mac, save_phy6_regs[phy6_idx],
5206			    save_phy6[phy6_idx]);
5207		}
5208	}
5209
5210	PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
5211	PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
5212	PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
5213
5214#undef SAVE_RF_MAX
5215#undef SAVE_PHY_COMM_MAX
5216#undef SAVE_PHY6_MAX
5217}
5218
5219void
5220bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *mac)
5221{
5222#define SAVE_RF_MAX		3
5223#define SAVE_PHY_COMM_MAX	4
5224#define SAVE_PHY3_MAX		8
5225	struct bwi_softc *sc = mac->mac_sc;
5226	struct bwi_phy *phy = &mac->mac_phy;
5227	struct bwi_rf *rf = &mac->mac_rf;
5228	uint16_t save_rf[SAVE_RF_MAX];
5229	uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
5230	uint16_t save_phy3[SAVE_PHY3_MAX];
5231	uint16_t ant_div, bbp_atten, chan_ex;
5232	struct bwi_gains gains;
5233	int16_t nrssi[2];
5234	int i, phy3_idx = 0;
5235
5236	static const uint16_t save_rf_regs[SAVE_RF_MAX] =
5237	    { 0x7a, 0x52, 0x43 };
5238	static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
5239	    { 0x15, 0x5a, 0x59, 0x58 };
5240	static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
5241		0x002e, 0x002f, 0x080f, 0x0810,
5242		0x0801, 0x0060, 0x0014, 0x0478
5243	};
5244
5245	if (rf->rf_rev >= 9)
5246		return;
5247	else if (rf->rf_rev == 8)
5248		bwi_rf_set_nrssi_ofs_11g(mac);
5249
5250	PHY_CLRBITS(mac, 0x429, 0x8000);
5251	PHY_CLRBITS(mac, 0x802, 0x3);
5252
5253	/*
5254	 * Save RF/PHY registers for later restoration
5255	 */
5256	ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
5257	CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
5258
5259	for (i = 0; i < SAVE_RF_MAX; ++i)
5260		save_rf[i] = RF_READ(mac, save_rf_regs[i]);
5261	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
5262		save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
5263
5264	bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
5265	chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
5266
5267	if (phy->phy_rev >= 3) {
5268		for (i = 0; i < SAVE_PHY3_MAX; ++i)
5269			save_phy3[i] = PHY_READ(mac, save_phy3_regs[i]);
5270
5271		PHY_WRITE(mac, 0x2e, 0);
5272		PHY_WRITE(mac, 0x810, 0);
5273
5274		if (phy->phy_rev == 4 || phy->phy_rev == 6 ||
5275		    phy->phy_rev == 7) {
5276			PHY_SETBITS(mac, 0x478, 0x100);
5277			PHY_SETBITS(mac, 0x810, 0x40);
5278		} else if (phy->phy_rev == 3 || phy->phy_rev == 5)
5279			PHY_CLRBITS(mac, 0x810, 0x40);
5280
5281		PHY_SETBITS(mac, 0x60, 0x40);
5282		PHY_SETBITS(mac, 0x14, 0x200);
5283	}
5284
5285	/*
5286	 * Calculate nrssi0
5287	 */
5288	RF_SETBITS(mac, 0x7a, 0x70);
5289
5290	bzero(&gains, sizeof(gains));
5291	gains.tbl_gain1 = 0;
5292	gains.tbl_gain2 = 8;
5293	gains.phy_gain = 0;
5294	bwi_set_gains(mac, &gains);
5295
5296	RF_CLRBITS(mac, 0x7a, 0xff08);
5297	if (phy->phy_rev >= 2) {
5298		PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x30);
5299		PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
5300	}
5301
5302	RF_SETBITS(mac, 0x7a, 0x80);
5303	DELAY(20);
5304	nrssi[0] = bwi_nrssi_11g(mac);
5305
5306	/*
5307	 * Calculate nrssi1
5308	 */
5309	RF_CLRBITS(mac, 0x7a, 0xff80);
5310	if (phy->phy_version >= 2)
5311		PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
5312	CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
5313
5314	RF_SETBITS(mac, 0x7a, 0xf);
5315	PHY_WRITE(mac, 0x15, 0xf330);
5316	if (phy->phy_rev >= 2) {
5317		PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x20);
5318		PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x20);
5319	}
5320
5321	bzero(&gains, sizeof(gains));
5322	gains.tbl_gain1 = 3;
5323	gains.tbl_gain2 = 0;
5324	gains.phy_gain = 1;
5325	bwi_set_gains(mac, &gains);
5326
5327	if (rf->rf_rev == 8) {
5328		RF_WRITE(mac, 0x43, 0x1f);
5329	} else {
5330		RF_FILT_SETBITS(mac, 0x52, 0xff0f, 0x60);
5331		RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
5332	}
5333	PHY_WRITE(mac, 0x5a, 0x480);
5334	PHY_WRITE(mac, 0x59, 0x810);
5335	PHY_WRITE(mac, 0x58, 0xd);
5336	DELAY(20);
5337
5338	nrssi[1] = bwi_nrssi_11g(mac);
5339
5340	/*
5341	 * Install calculated narrow RSSI values
5342	 */
5343	if (nrssi[1] == nrssi[0])
5344		rf->rf_nrssi_slope = 0x10000;
5345	else
5346		rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
5347	if (nrssi[0] >= -4) {
5348		rf->rf_nrssi[0] = nrssi[1];
5349		rf->rf_nrssi[1] = nrssi[0];
5350	}
5351
5352	/*
5353	 * Restore saved RF/PHY registers
5354	 */
5355	if (phy->phy_rev >= 3) {
5356		for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
5357			PHY_WRITE(mac, save_phy3_regs[phy3_idx],
5358				  save_phy3[phy3_idx]);
5359		}
5360	}
5361	if (phy->phy_rev >= 2) {
5362		PHY_CLRBITS(mac, 0x812, 0x30);
5363		PHY_CLRBITS(mac, 0x811, 0x30);
5364	}
5365
5366	for (i = 0; i < SAVE_RF_MAX; ++i)
5367		RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
5368
5369	CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
5370	CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
5371	CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
5372
5373	for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
5374		PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
5375
5376	bwi_rf_work_around(mac, rf->rf_curchan);
5377	PHY_SETBITS(mac, 0x802, 0x3);
5378	bwi_set_gains(mac, NULL);
5379	PHY_SETBITS(mac, 0x429, 0x8000);
5380
5381	if (phy->phy_rev >= 3) {
5382		for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
5383			PHY_WRITE(mac, save_phy3_regs[phy3_idx],
5384			    save_phy3[phy3_idx]);
5385		}
5386	}
5387
5388	bwi_rf_init_sw_nrssi_table(mac);
5389	bwi_rf_set_nrssi_thr_11g(mac);
5390
5391#undef SAVE_RF_MAX
5392#undef SAVE_PHY_COMM_MAX
5393#undef SAVE_PHY3_MAX
5394}
5395
5396void
5397bwi_rf_init_sw_nrssi_table(struct bwi_mac *mac)
5398{
5399	struct bwi_rf *rf = &mac->mac_rf;
5400	int d, i;
5401
5402	d = 0x1f - rf->rf_nrssi[0];
5403	for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
5404		int val;
5405
5406		val = (((i - d) * rf->rf_nrssi_slope) / 0x10000) + 0x3a;
5407		if (val < 0)
5408			val = 0;
5409		else if (val > 0x3f)
5410			val = 0x3f;
5411
5412		rf->rf_nrssi_table[i] = val;
5413	}
5414}
5415
5416void
5417bwi_rf_init_hw_nrssi_table(struct bwi_mac *mac, uint16_t adjust)
5418{
5419	int i;
5420
5421	for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
5422		int16_t val;
5423
5424		val = bwi_nrssi_read(mac, i);
5425
5426		val -= adjust;
5427		if (val < -32)
5428			val = -32;
5429		else if (val > 31);
5430			val = 31;
5431
5432		bwi_nrssi_write(mac, i, val);
5433	}
5434}
5435
5436void
5437bwi_rf_set_nrssi_thr_11b(struct bwi_mac *mac)
5438{
5439	struct bwi_rf *rf = &mac->mac_rf;
5440	int32_t thr;
5441
5442	if (rf->rf_type != BWI_RF_T_BCM2050 ||
5443	    (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0)
5444		return;
5445
5446	/*
5447	 * Calculate nrssi threshold
5448	 */
5449	if (rf->rf_rev >= 6) {
5450		thr = (rf->rf_nrssi[1] - rf->rf_nrssi[0]) * 32;
5451		thr += 20 * (rf->rf_nrssi[0] + 1);
5452		thr /= 40;
5453	} else {
5454		thr = rf->rf_nrssi[1] - 5;
5455	}
5456	if (thr < 0)
5457		thr = 0;
5458	else if (thr > 0x3e)
5459		thr = 0x3e;
5460
5461	PHY_READ(mac, BWI_PHYR_NRSSI_THR_11B);	/* dummy read */
5462	PHY_WRITE(mac, BWI_PHYR_NRSSI_THR_11B, (((uint16_t)thr) << 8) | 0x1c);
5463
5464	if (rf->rf_rev >= 6) {
5465		PHY_WRITE(mac, 0x87, 0xe0d);
5466		PHY_WRITE(mac, 0x86, 0xc0b);
5467		PHY_WRITE(mac, 0x85, 0xa09);
5468		PHY_WRITE(mac, 0x84, 0x808);
5469		PHY_WRITE(mac, 0x83, 0x808);
5470		PHY_WRITE(mac, 0x82, 0x604);
5471		PHY_WRITE(mac, 0x81, 0x302);
5472		PHY_WRITE(mac, 0x80, 0x100);
5473	}
5474}
5475
5476int32_t
5477_nrssi_threshold(const struct bwi_rf *rf, int32_t val)
5478{
5479	val *= (rf->rf_nrssi[1] - rf->rf_nrssi[0]);
5480	val += (rf->rf_nrssi[0] << 6);
5481	if (val < 32)
5482		val += 31;
5483	else
5484		val += 32;
5485	val >>= 6;
5486	if (val < -31)
5487		val = -31;
5488	else if (val > 31)
5489		val = 31;
5490
5491	return (val);
5492}
5493
5494void
5495bwi_rf_set_nrssi_thr_11g(struct bwi_mac *mac)
5496{
5497	int32_t thr1, thr2;
5498	uint16_t thr;
5499
5500	/*
5501	 * Find the two nrssi thresholds
5502	 */
5503	if ((mac->mac_phy.phy_flags & BWI_PHY_F_LINKED) == 0 ||
5504	    (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
5505	    	int16_t nrssi;
5506
5507		nrssi = bwi_nrssi_read(mac, 0x20);
5508		if (nrssi >= 32)
5509			nrssi -= 64;
5510
5511		if (nrssi < 3) {
5512			thr1 = 0x2b;
5513			thr2 = 0x27;
5514		} else {
5515			thr1 = 0x2d;
5516			thr2 = 0x2b;
5517		}
5518	} else {
5519		/* TODO Interfere mode */
5520		thr1 = _nrssi_threshold(&mac->mac_rf, 0x11);
5521		thr2 = _nrssi_threshold(&mac->mac_rf, 0xe);
5522	}
5523
5524#define NRSSI_THR1_MASK		0x003f
5525#define NRSSI_THR2_MASK		0x0fc0
5526	thr = __SHIFTIN((uint32_t)thr1, NRSSI_THR1_MASK) |
5527	    __SHIFTIN((uint32_t)thr2, NRSSI_THR2_MASK);
5528	PHY_FILT_SETBITS(mac, BWI_PHYR_NRSSI_THR_11G, 0xf000, thr);
5529#undef NRSSI_THR1_MASK
5530#undef NRSSI_THR2_MASK
5531}
5532
5533void
5534bwi_rf_clear_tssi(struct bwi_mac *mac)
5535{
5536	/* XXX use function pointer */
5537	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) {
5538		/* TODO: 11A */
5539	} else {
5540		uint16_t val;
5541		int i;
5542
5543		val = __SHIFTIN(BWI_INVALID_TSSI, BWI_LO_TSSI_MASK) |
5544		    __SHIFTIN(BWI_INVALID_TSSI, BWI_HI_TSSI_MASK);
5545
5546		for (i = 0; i < 2; ++i) {
5547			MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,
5548			    BWI_COMM_MOBJ_TSSI_DS + (i * 2), val);
5549		}
5550
5551		for (i = 0; i < 2; ++i) {
5552			MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,
5553			    BWI_COMM_MOBJ_TSSI_OFDM + (i * 2), val);
5554		}
5555	}
5556}
5557
5558void
5559bwi_rf_clear_state(struct bwi_rf *rf)
5560{
5561	int i;
5562
5563	rf->rf_flags &= ~BWI_RF_CLEAR_FLAGS;
5564	bzero(rf->rf_lo, sizeof(rf->rf_lo));
5565	bzero(rf->rf_lo_used, sizeof(rf->rf_lo_used));
5566
5567	rf->rf_nrssi_slope = 0;
5568	rf->rf_nrssi[0] = BWI_INVALID_NRSSI;
5569	rf->rf_nrssi[1] = BWI_INVALID_NRSSI;
5570
5571	for (i = 0; i < BWI_NRSSI_TBLSZ; ++i)
5572		rf->rf_nrssi_table[i] = i;
5573
5574	rf->rf_lo_gain = 0;
5575	rf->rf_rx_gain = 0;
5576
5577	bcopy(rf->rf_txpower_map0, rf->rf_txpower_map,
5578	      sizeof(rf->rf_txpower_map));
5579	rf->rf_idle_tssi = rf->rf_idle_tssi0;
5580}
5581
5582void
5583bwi_rf_on_11a(struct bwi_mac *mac)
5584{
5585	/* TODO: 11A */
5586}
5587
5588void
5589bwi_rf_on_11bg(struct bwi_mac *mac)
5590{
5591	struct bwi_phy *phy = &mac->mac_phy;
5592
5593	PHY_WRITE(mac, 0x15, 0x8000);
5594	PHY_WRITE(mac, 0x15, 0xcc00);
5595	if (phy->phy_flags & BWI_PHY_F_LINKED)
5596		PHY_WRITE(mac, 0x15, 0xc0);
5597	else
5598		PHY_WRITE(mac, 0x15, 0);
5599
5600	bwi_rf_set_chan(mac, 6 /* XXX */, 1);
5601}
5602
5603void
5604bwi_rf_set_ant_mode(struct bwi_mac *mac, int ant_mode)
5605{
5606	struct bwi_softc *sc = mac->mac_sc;
5607	struct bwi_phy *phy = &mac->mac_phy;
5608	uint16_t val;
5609
5610	KKASSERT(ant_mode == BWI_ANT_MODE_0 ||
5611	    ant_mode == BWI_ANT_MODE_1 ||
5612	    ant_mode == BWI_ANT_MODE_AUTO);
5613
5614	HFLAGS_CLRBITS(mac, BWI_HFLAG_AUTO_ANTDIV);
5615
5616	if (phy->phy_mode == IEEE80211_MODE_11B) {
5617		/* NOTE: v4/v3 conflicts, take v3 */
5618		if (mac->mac_rev == 2)
5619			val = BWI_ANT_MODE_AUTO;
5620		else
5621			val = ant_mode;
5622		val <<= 7;
5623		PHY_FILT_SETBITS(mac, 0x3e2, 0xfe7f, val);
5624	} else {	/* 11a/g */
5625		/* XXX reg/value naming */
5626		val = ant_mode << 7;
5627		PHY_FILT_SETBITS(mac, 0x401, 0x7e7f, val);
5628
5629		if (ant_mode == BWI_ANT_MODE_AUTO)
5630			PHY_CLRBITS(mac, 0x42b, 0x100);
5631
5632		if (phy->phy_mode == IEEE80211_MODE_11A) {
5633			/* TODO: 11A */
5634		} else {	/* 11g */
5635			if (ant_mode == BWI_ANT_MODE_AUTO)
5636				PHY_SETBITS(mac, 0x48c, 0x2000);
5637			else
5638				PHY_CLRBITS(mac, 0x48c, 0x2000);
5639
5640			if (phy->phy_rev >= 2) {
5641				PHY_SETBITS(mac, 0x461, 0x10);
5642				PHY_FILT_SETBITS(mac, 0x4ad, 0xff00, 0x15);
5643				if (phy->phy_rev == 2) {
5644					PHY_WRITE(mac, 0x427, 0x8);
5645				} else {
5646					PHY_FILT_SETBITS(mac, 0x427,
5647							 0xff00, 0x8);
5648				}
5649
5650				if (phy->phy_rev >= 6)
5651					PHY_WRITE(mac, 0x49b, 0xdc);
5652			}
5653		}
5654	}
5655
5656	/* XXX v4 set AUTO_ANTDIV unconditionally */
5657	if (ant_mode == BWI_ANT_MODE_AUTO)
5658		HFLAGS_SETBITS(mac, BWI_HFLAG_AUTO_ANTDIV);
5659
5660	val = ant_mode << 8;
5661	MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_BEACON,
5662	    0xfc3f, val);
5663	MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_ACK,
5664	    0xfc3f, val);
5665	MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_PROBE_RESP,
5666	    0xfc3f, val);
5667
5668	/* XXX what's these */
5669	if (phy->phy_mode == IEEE80211_MODE_11B)
5670		CSR_SETBITS_2(sc, 0x5e, 0x4);
5671
5672	CSR_WRITE_4(sc, 0x100, 0x1000000);
5673	if (mac->mac_rev < 5)
5674		CSR_WRITE_4(sc, 0x10c, 0x1000000);
5675
5676	mac->mac_rf.rf_ant_mode = ant_mode;
5677}
5678
5679int
5680bwi_rf_get_latest_tssi(struct bwi_mac *mac, int8_t tssi[], uint16_t ofs)
5681{
5682	int i;
5683
5684	for (i = 0; i < 4; ) {
5685		uint16_t val;
5686
5687		val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs + i);
5688		tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_LO_TSSI_MASK);
5689		tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_HI_TSSI_MASK);
5690	}
5691
5692	for (i = 0; i < 4; ++i) {
5693		if (tssi[i] == BWI_INVALID_TSSI)
5694			return (EINVAL);
5695	}
5696
5697	return (0);
5698}
5699
5700int
5701bwi_rf_tssi2dbm(struct bwi_mac *mac, int8_t tssi, int8_t *txpwr)
5702{
5703	struct bwi_rf *rf = &mac->mac_rf;
5704	int pwr_idx;
5705
5706	pwr_idx = rf->rf_idle_tssi + (int)tssi - rf->rf_base_tssi;
5707#if 0
5708	if (pwr_idx < 0 || pwr_idx >= BWI_TSSI_MAX)
5709		return EINVAL;
5710#else
5711	if (pwr_idx < 0)
5712		pwr_idx = 0;
5713	else if (pwr_idx >= BWI_TSSI_MAX)
5714		pwr_idx = BWI_TSSI_MAX - 1;
5715#endif
5716	*txpwr = rf->rf_txpower_map[pwr_idx];
5717
5718	return (0);
5719}
5720
5721/* IF_BWI */
5722
5723uint16_t
5724bwi_read_sprom(struct bwi_softc *sc, uint16_t ofs)
5725{
5726	return (CSR_READ_2(sc, ofs + BWI_SPROM_START));
5727}
5728
5729void
5730bwi_setup_desc32(struct bwi_softc *sc, struct bwi_desc32 *desc_array,
5731    int ndesc, int desc_idx, bus_addr_t paddr, int buf_len, int tx)
5732{
5733	struct bwi_desc32 *desc = &desc_array[desc_idx];
5734	uint32_t ctrl, addr, addr_hi, addr_lo;
5735
5736	addr_lo = __SHIFTOUT(paddr, BWI_DESC32_A_ADDR_MASK);
5737	addr_hi = __SHIFTOUT(paddr, BWI_DESC32_A_FUNC_MASK);
5738
5739	addr = __SHIFTIN(addr_lo, BWI_DESC32_A_ADDR_MASK) |
5740	    __SHIFTIN(BWI_DESC32_A_FUNC_TXRX, BWI_DESC32_A_FUNC_MASK);
5741
5742	ctrl = __SHIFTIN(buf_len, BWI_DESC32_C_BUFLEN_MASK) |
5743	     __SHIFTIN(addr_hi, BWI_DESC32_C_ADDRHI_MASK);
5744	if (desc_idx == ndesc - 1)
5745		ctrl |= BWI_DESC32_C_EOR;
5746	if (tx) {
5747		/* XXX */
5748		ctrl |= BWI_DESC32_C_FRAME_START |
5749		    BWI_DESC32_C_FRAME_END |
5750		    BWI_DESC32_C_INTR;
5751	}
5752
5753	desc->addr = htole32(addr);
5754	desc->ctrl = htole32(ctrl);
5755}
5756
5757void
5758bwi_power_on(struct bwi_softc *sc, int with_pll)
5759{
5760	uint32_t gpio_in, gpio_out, gpio_en, status;
5761
5762	DPRINTF(1, "%s\n", __func__);
5763
5764	gpio_in = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN);
5765	if (gpio_in & BWI_PCIM_GPIO_PWR_ON)
5766		goto back;
5767
5768	gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
5769	gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE);
5770
5771	gpio_out |= BWI_PCIM_GPIO_PWR_ON;
5772	gpio_en |= BWI_PCIM_GPIO_PWR_ON;
5773	if (with_pll) {
5774		/* Turn off PLL first */
5775		gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF;
5776		gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF;
5777	}
5778
5779	(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
5780	(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en);
5781	DELAY(1000);
5782
5783	if (with_pll) {
5784		/* Turn on PLL */
5785		gpio_out &= ~BWI_PCIM_GPIO_PLL_PWR_OFF;
5786		(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
5787		DELAY(5000);
5788	}
5789
5790back:
5791	/* Clear "Signaled Target Abort" */
5792	status = (sc->sc_conf_read)(sc, PCI_COMMAND_STATUS_REG);
5793	status &= ~PCI_STATUS_TARGET_TARGET_ABORT;
5794	(sc->sc_conf_write)(sc, PCI_COMMAND_STATUS_REG, status);
5795}
5796
5797int
5798bwi_power_off(struct bwi_softc *sc, int with_pll)
5799{
5800	uint32_t gpio_out, gpio_en;
5801
5802	DPRINTF(1, "%s\n", __func__);
5803
5804	(sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN); /* dummy read */
5805	gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
5806	gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE);
5807
5808	gpio_out &= ~BWI_PCIM_GPIO_PWR_ON;
5809	gpio_en |= BWI_PCIM_GPIO_PWR_ON;
5810	if (with_pll) {
5811		gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF;
5812		gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF;
5813	}
5814
5815	(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT, gpio_out);
5816	(sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE, gpio_en);
5817
5818	return (0);
5819}
5820
5821int
5822bwi_regwin_switch(struct bwi_softc *sc, struct bwi_regwin *rw,
5823    struct bwi_regwin **old_rw)
5824{
5825	int error;
5826
5827	if (old_rw != NULL)
5828		*old_rw = NULL;
5829
5830	if (!BWI_REGWIN_EXIST(rw))
5831		return (EINVAL);
5832
5833	if (sc->sc_cur_regwin != rw) {
5834		error = bwi_regwin_select(sc, rw->rw_id);
5835		if (error) {
5836			DPRINTF(1, "%s: can't select regwin %d\n",
5837			    sc->sc_dev.dv_xname, rw->rw_id);
5838			return (error);
5839		}
5840	}
5841
5842	if (old_rw != NULL)
5843		*old_rw = sc->sc_cur_regwin;
5844	sc->sc_cur_regwin = rw;
5845
5846	return (0);
5847}
5848
5849int
5850bwi_regwin_select(struct bwi_softc *sc, int id)
5851{
5852	uint32_t win = BWI_PCIM_REGWIN(id);
5853	int i;
5854
5855#define RETRY_MAX	50
5856	for (i = 0; i < RETRY_MAX; ++i) {
5857		(sc->sc_conf_write)(sc, BWI_PCIR_SEL_REGWIN, win);
5858		if ((sc->sc_conf_read)(sc, BWI_PCIR_SEL_REGWIN) == win)
5859			return (0);
5860		DELAY(10);
5861	}
5862#undef RETRY_MAX
5863
5864	return (ENXIO);
5865}
5866
5867void
5868bwi_regwin_info(struct bwi_softc *sc, uint16_t *type, uint8_t *rev)
5869{
5870	uint32_t val;
5871
5872	val = CSR_READ_4(sc, BWI_ID_HI);
5873	*type = BWI_ID_HI_REGWIN_TYPE(val);
5874	*rev = BWI_ID_HI_REGWIN_REV(val);
5875
5876	DPRINTF(1, "%s: regwin: type 0x%03x, rev %d, vendor 0x%04x\n",
5877	    sc->sc_dev.dv_xname,
5878	    *type, *rev, __SHIFTOUT(val, BWI_ID_HI_REGWIN_VENDOR_MASK));
5879}
5880
5881int
5882bwi_bbp_attach(struct bwi_softc *sc)
5883{
5884#define N(arr)	(int)(sizeof(arr) / sizeof(arr[0]))
5885	uint16_t bbp_id, rw_type;
5886	uint8_t rw_rev;
5887	uint32_t info;
5888	int error, nregwin, i;
5889
5890	/*
5891	 * Get 0th regwin information
5892	 * NOTE: 0th regwin should exist
5893	 */
5894	error = bwi_regwin_select(sc, 0);
5895	if (error) {
5896		DPRINTF(1, "%s: can't select regwin 0\n", sc->sc_dev.dv_xname);
5897		return (error);
5898	}
5899	bwi_regwin_info(sc, &rw_type, &rw_rev);
5900
5901	/*
5902	 * Find out BBP id
5903	 */
5904	bbp_id = 0;
5905	info = 0;
5906	if (rw_type == BWI_REGWIN_T_COM) {
5907		info = CSR_READ_4(sc, BWI_INFO);
5908		bbp_id = __SHIFTOUT(info, BWI_INFO_BBPID_MASK);
5909
5910		BWI_CREATE_REGWIN(&sc->sc_com_regwin, 0, rw_type, rw_rev);
5911
5912		sc->sc_cap = CSR_READ_4(sc, BWI_CAPABILITY);
5913	} else {
5914		uint16_t did = sc->sc_pci_did;
5915		uint8_t revid = sc->sc_pci_revid;
5916
5917		for (i = 0; i < N(bwi_bbpid_map); ++i) {
5918			if (did >= bwi_bbpid_map[i].did_min &&
5919			    did <= bwi_bbpid_map[i].did_max) {
5920				bbp_id = bwi_bbpid_map[i].bbp_id;
5921				break;
5922			}
5923		}
5924		if (bbp_id == 0) {
5925			DPRINTF(1, "%s: no BBP id for device id 0x%04x\n",
5926			    sc->sc_dev.dv_xname, did);
5927			return (ENXIO);
5928		}
5929
5930		info = __SHIFTIN(revid, BWI_INFO_BBPREV_MASK) |
5931		    __SHIFTIN(0, BWI_INFO_BBPPKG_MASK);
5932	}
5933
5934	/*
5935	 * Find out number of regwins
5936	 */
5937	nregwin = 0;
5938	if (rw_type == BWI_REGWIN_T_COM && rw_rev >= 4) {
5939		nregwin = __SHIFTOUT(info, BWI_INFO_NREGWIN_MASK);
5940	} else {
5941		for (i = 0; i < N(bwi_regwin_count); ++i) {
5942			if (bwi_regwin_count[i].bbp_id == bbp_id) {
5943				nregwin = bwi_regwin_count[i].nregwin;
5944				break;
5945			}
5946		}
5947		if (nregwin == 0) {
5948			DPRINTF(1, "%s: no number of win for BBP id 0x%04x\n",
5949			    sc->sc_dev.dv_xname, bbp_id);
5950			return (ENXIO);
5951		}
5952	}
5953
5954	/* Record BBP id/rev for later using */
5955	sc->sc_bbp_id = bbp_id;
5956	sc->sc_bbp_rev = __SHIFTOUT(info, BWI_INFO_BBPREV_MASK);
5957	sc->sc_bbp_pkg = __SHIFTOUT(info, BWI_INFO_BBPPKG_MASK);
5958	DPRINTF(1, "%s: BBP id 0x%04x, BBP rev 0x%x, BBP pkg %d\n",
5959	    sc->sc_dev.dv_xname, sc->sc_bbp_id, sc->sc_bbp_rev, sc->sc_bbp_pkg);
5960	DPRINTF(1, "%s: nregwin %d, cap 0x%08x\n",
5961	    sc->sc_dev.dv_xname, nregwin, sc->sc_cap);
5962
5963	/*
5964	 * Create rest of the regwins
5965	 */
5966
5967	/* Don't re-create common regwin, if it is already created */
5968	i = BWI_REGWIN_EXIST(&sc->sc_com_regwin) ? 1 : 0;
5969
5970	for (; i < nregwin; ++i) {
5971		/*
5972		 * Get regwin information
5973		 */
5974		error = bwi_regwin_select(sc, i);
5975		if (error) {
5976			DPRINTF(1, "%s: can't select regwin %d\n",
5977			    sc->sc_dev.dv_xname, i);
5978			return (error);
5979		}
5980		bwi_regwin_info(sc, &rw_type, &rw_rev);
5981
5982		/*
5983		 * Try attach:
5984		 * 1) Bus (PCI/PCIE) regwin
5985		 * 2) MAC regwin
5986		 * Ignore rest types of regwin
5987		 */
5988		if (rw_type == BWI_REGWIN_T_BUSPCI ||
5989		    rw_type == BWI_REGWIN_T_BUSPCIE) {
5990			if (BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) {
5991				DPRINTF(1, "%s: bus regwin already exists\n",
5992				    sc->sc_dev.dv_xname);
5993			} else {
5994				BWI_CREATE_REGWIN(&sc->sc_bus_regwin, i,
5995				    rw_type, rw_rev);
5996			}
5997		} else if (rw_type == BWI_REGWIN_T_MAC) {
5998			/* XXX ignore return value */
5999			bwi_mac_attach(sc, i, rw_rev);
6000		}
6001	}
6002
6003	/* At least one MAC shold exist */
6004	if (!BWI_REGWIN_EXIST(&sc->sc_mac[0].mac_regwin)) {
6005		DPRINTF(1, "%s: no MAC was found\n", sc->sc_dev.dv_xname);
6006		return (ENXIO);
6007	}
6008	KKASSERT(sc->sc_nmac > 0);
6009
6010	/* Bus regwin must exist */
6011	if (!BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) {
6012		DPRINTF(1, "%s: no bus regwin was found\n",
6013		    sc->sc_dev.dv_xname);
6014		return (ENXIO);
6015	}
6016
6017	/* Start with first MAC */
6018	error = bwi_regwin_switch(sc, &sc->sc_mac[0].mac_regwin, NULL);
6019	if (error)
6020		return (error);
6021
6022	return (0);
6023#undef N
6024}
6025
6026int
6027bwi_bus_init(struct bwi_softc *sc, struct bwi_mac *mac)
6028{
6029	struct bwi_regwin *old, *bus;
6030	uint32_t val;
6031	int error;
6032
6033	bus = &sc->sc_bus_regwin;
6034	KKASSERT(sc->sc_cur_regwin == &mac->mac_regwin);
6035
6036	/*
6037	 * Tell bus to generate requested interrupts
6038	 */
6039	if (bus->rw_rev < 6 && bus->rw_type == BWI_REGWIN_T_BUSPCI) {
6040		/*
6041		 * NOTE: Read BWI_FLAGS from MAC regwin
6042		 */
6043		val = CSR_READ_4(sc, BWI_FLAGS);
6044
6045		error = bwi_regwin_switch(sc, bus, &old);
6046		if (error)
6047			return (error);
6048
6049		CSR_SETBITS_4(sc, BWI_INTRVEC, (val & BWI_FLAGS_INTR_MASK));
6050	} else {
6051		uint32_t mac_mask;
6052
6053		mac_mask = 1 << mac->mac_id;
6054
6055		error = bwi_regwin_switch(sc, bus, &old);
6056		if (error)
6057			return (error);
6058
6059		val = (sc->sc_conf_read)(sc, BWI_PCIR_INTCTL);
6060		val |= mac_mask << 8;
6061		(sc->sc_conf_write)(sc, BWI_PCIR_INTCTL, val);
6062	}
6063
6064	if (sc->sc_flags & BWI_F_BUS_INITED)
6065		goto back;
6066
6067	if (bus->rw_type == BWI_REGWIN_T_BUSPCI) {
6068		/*
6069		 * Enable prefetch and burst
6070		 */
6071		CSR_SETBITS_4(sc, BWI_BUS_CONFIG,
6072		    BWI_BUS_CONFIG_PREFETCH | BWI_BUS_CONFIG_BURST);
6073
6074		if (bus->rw_rev < 5) {
6075			struct bwi_regwin *com = &sc->sc_com_regwin;
6076
6077			/*
6078			 * Configure timeouts for bus operation
6079			 */
6080
6081			/*
6082			 * Set service timeout and request timeout
6083			 */
6084			CSR_SETBITS_4(sc, BWI_CONF_LO,
6085			    __SHIFTIN(BWI_CONF_LO_SERVTO,
6086			    BWI_CONF_LO_SERVTO_MASK) |
6087			    __SHIFTIN(BWI_CONF_LO_REQTO,
6088			    BWI_CONF_LO_REQTO_MASK));
6089
6090			/*
6091			 * If there is common regwin, we switch to that regwin
6092			 * and switch back to bus regwin once we have done.
6093			 */
6094			if (BWI_REGWIN_EXIST(com)) {
6095				error = bwi_regwin_switch(sc, com, NULL);
6096				if (error)
6097					return (error);
6098			}
6099
6100			/* Let bus know what we have changed */
6101			CSR_WRITE_4(sc, BWI_BUS_ADDR, BWI_BUS_ADDR_MAGIC);
6102			CSR_READ_4(sc, BWI_BUS_ADDR); /* Flush */
6103			CSR_WRITE_4(sc, BWI_BUS_DATA, 0);
6104			CSR_READ_4(sc, BWI_BUS_DATA); /* Flush */
6105
6106			if (BWI_REGWIN_EXIST(com)) {
6107				error = bwi_regwin_switch(sc, bus, NULL);
6108				if (error)
6109					return (error);
6110			}
6111		} else if (bus->rw_rev >= 11) {
6112			/*
6113			 * Enable memory read multiple
6114			 */
6115			CSR_SETBITS_4(sc, BWI_BUS_CONFIG, BWI_BUS_CONFIG_MRM);
6116		}
6117	} else {
6118		/* TODO: PCIE */
6119	}
6120
6121	sc->sc_flags |= BWI_F_BUS_INITED;
6122back:
6123	return (bwi_regwin_switch(sc, old, NULL));
6124}
6125
6126void
6127bwi_get_card_flags(struct bwi_softc *sc)
6128{
6129	sc->sc_card_flags = bwi_read_sprom(sc, BWI_SPROM_CARD_FLAGS);
6130	if (sc->sc_card_flags == 0xffff)
6131		sc->sc_card_flags = 0;
6132
6133	if (sc->sc_pci_subvid == PCI_VENDOR_APPLE &&
6134	    sc->sc_pci_subdid == 0x4e && /* XXX */
6135	    sc->sc_pci_revid > 0x40)
6136		sc->sc_card_flags |= BWI_CARD_F_PA_GPIO9;
6137
6138	DPRINTF(1, "%s: card flags 0x%04x\n",
6139	    sc->sc_dev.dv_xname, sc->sc_card_flags);
6140}
6141
6142void
6143bwi_get_eaddr(struct bwi_softc *sc, uint16_t eaddr_ofs, uint8_t *eaddr)
6144{
6145	int i;
6146
6147	for (i = 0; i < 3; ++i) {
6148		*((uint16_t *)eaddr + i) =
6149		    htobe16(bwi_read_sprom(sc, eaddr_ofs + 2 * i));
6150	}
6151}
6152
6153void
6154bwi_get_clock_freq(struct bwi_softc *sc, struct bwi_clock_freq *freq)
6155{
6156	struct bwi_regwin *com;
6157	uint32_t val;
6158	u_int div;
6159	int src;
6160
6161	bzero(freq, sizeof(*freq));
6162	com = &sc->sc_com_regwin;
6163
6164	KKASSERT(BWI_REGWIN_EXIST(com));
6165	KKASSERT(sc->sc_cur_regwin == com);
6166	KKASSERT(sc->sc_cap & BWI_CAP_CLKMODE);
6167
6168	/*
6169	 * Calculate clock frequency
6170	 */
6171	src = -1;
6172	div = 0;
6173	if (com->rw_rev < 6) {
6174		val = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT);
6175		if (val & BWI_PCIM_GPIO_OUT_CLKSRC) {
6176			src = BWI_CLKSRC_PCI;
6177			div = 64;
6178		} else {
6179			src = BWI_CLKSRC_CS_OSC;
6180			div = 32;
6181		}
6182	} else if (com->rw_rev < 10) {
6183		val = CSR_READ_4(sc, BWI_CLOCK_CTRL);
6184
6185		src = __SHIFTOUT(val, BWI_CLOCK_CTRL_CLKSRC);
6186		if (src == BWI_CLKSRC_LP_OSC)
6187			div = 1;
6188		else {
6189			div = (__SHIFTOUT(val, BWI_CLOCK_CTRL_FDIV) + 1) << 2;
6190
6191			/* Unknown source */
6192			if (src >= BWI_CLKSRC_MAX)
6193				src = BWI_CLKSRC_CS_OSC;
6194		}
6195	} else {
6196		val = CSR_READ_4(sc, BWI_CLOCK_INFO);
6197
6198		src = BWI_CLKSRC_CS_OSC;
6199		div = (__SHIFTOUT(val, BWI_CLOCK_INFO_FDIV) + 1) << 2;
6200	}
6201
6202	KKASSERT(src >= 0 && src < BWI_CLKSRC_MAX);
6203	KKASSERT(div != 0);
6204
6205	DPRINTF(1, "%s: clksrc %s\n",
6206	    sc->sc_dev.dv_xname,
6207	    src == BWI_CLKSRC_PCI ? "PCI" :
6208	    (src == BWI_CLKSRC_LP_OSC ? "LP_OSC" : "CS_OSC"));
6209
6210	freq->clkfreq_min = bwi_clkfreq[src].freq_min / div;
6211	freq->clkfreq_max = bwi_clkfreq[src].freq_max / div;
6212
6213	DPRINTF(1, "%s: clkfreq min %u, max %u\n",
6214	    sc->sc_dev.dv_xname, freq->clkfreq_min, freq->clkfreq_max);
6215}
6216
6217int
6218bwi_set_clock_mode(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
6219{
6220	struct bwi_regwin *old, *com;
6221	uint32_t clk_ctrl, clk_src;
6222	int error, pwr_off = 0;
6223
6224	com = &sc->sc_com_regwin;
6225	if (!BWI_REGWIN_EXIST(com))
6226		return (0);
6227
6228	if (com->rw_rev >= 10 || com->rw_rev < 6)
6229		return (0);
6230
6231	/*
6232	 * For common regwin whose rev is [6, 10), the chip
6233	 * must be capable to change clock mode.
6234	 */
6235	if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
6236		return (0);
6237
6238	error = bwi_regwin_switch(sc, com, &old);
6239	if (error)
6240		return (error);
6241
6242	if (clk_mode == BWI_CLOCK_MODE_FAST)
6243		bwi_power_on(sc, 0);	/* Don't turn on PLL */
6244
6245	clk_ctrl = CSR_READ_4(sc, BWI_CLOCK_CTRL);
6246	clk_src = __SHIFTOUT(clk_ctrl, BWI_CLOCK_CTRL_CLKSRC);
6247
6248	switch (clk_mode) {
6249	case BWI_CLOCK_MODE_FAST:
6250		clk_ctrl &= ~BWI_CLOCK_CTRL_SLOW;
6251		clk_ctrl |= BWI_CLOCK_CTRL_IGNPLL;
6252		break;
6253	case BWI_CLOCK_MODE_SLOW:
6254		clk_ctrl |= BWI_CLOCK_CTRL_SLOW;
6255		break;
6256	case BWI_CLOCK_MODE_DYN:
6257		clk_ctrl &= ~(BWI_CLOCK_CTRL_SLOW |
6258		    BWI_CLOCK_CTRL_IGNPLL |
6259		    BWI_CLOCK_CTRL_NODYN);
6260		if (clk_src != BWI_CLKSRC_CS_OSC) {
6261			clk_ctrl |= BWI_CLOCK_CTRL_NODYN;
6262			pwr_off = 1;
6263		}
6264		break;
6265	}
6266	CSR_WRITE_4(sc, BWI_CLOCK_CTRL, clk_ctrl);
6267
6268	if (pwr_off)
6269		bwi_power_off(sc, 0);	/* Leave PLL as it is */
6270
6271	return (bwi_regwin_switch(sc, old, NULL));
6272}
6273
6274int
6275bwi_set_clock_delay(struct bwi_softc *sc)
6276{
6277	struct bwi_regwin *old, *com;
6278	int error;
6279
6280	com = &sc->sc_com_regwin;
6281	if (!BWI_REGWIN_EXIST(com))
6282		return (0);
6283
6284	error = bwi_regwin_switch(sc, com, &old);
6285	if (error)
6286		return (error);
6287
6288	if (sc->sc_bbp_id == BWI_BBPID_BCM4321) {
6289		if (sc->sc_bbp_rev == 0)
6290			CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC0);
6291		else if (sc->sc_bbp_rev == 1)
6292			CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC1);
6293	}
6294
6295	if (sc->sc_cap & BWI_CAP_CLKMODE) {
6296		if (com->rw_rev >= 10)
6297			CSR_FILT_SETBITS_4(sc, BWI_CLOCK_INFO, 0xffff, 0x40000);
6298		else {
6299			struct bwi_clock_freq freq;
6300
6301			bwi_get_clock_freq(sc, &freq);
6302			CSR_WRITE_4(sc, BWI_PLL_ON_DELAY,
6303			    howmany(freq.clkfreq_max * 150, 1000000));
6304			CSR_WRITE_4(sc, BWI_FREQ_SEL_DELAY,
6305			    howmany(freq.clkfreq_max * 15, 1000000));
6306		}
6307	}
6308
6309	return (bwi_regwin_switch(sc, old, NULL));
6310}
6311
6312int
6313bwi_init(struct ifnet *ifp)
6314{
6315	struct bwi_softc *sc = ifp->if_softc;
6316	struct ieee80211com *ic = &sc->sc_ic;
6317	struct bwi_mac *mac;
6318	int error;
6319
6320	DPRINTF(1, "%s\n", __func__);
6321
6322	error = bwi_stop(sc);
6323	if (error) {
6324		DPRINTF(1, "%s: can't stop\n", sc->sc_dev.dv_xname);
6325		return (1);
6326	}
6327
6328	/* power on cardbus socket */
6329	if (sc->sc_enable != NULL)
6330		(*sc->sc_enable)(sc);
6331
6332	bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
6333
6334	/* TODO: 2 MAC */
6335
6336	mac = &sc->sc_mac[0];
6337	error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL);
6338	if (error)
6339		goto back;
6340
6341	error = bwi_mac_init(mac);
6342	if (error)
6343		goto back;
6344
6345	bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN);
6346
6347	IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
6348
6349	bwi_set_bssid(sc, bwi_zero_addr);	/* Clear BSSID */
6350	bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, ic->ic_myaddr);
6351
6352	bwi_mac_reset_hwkeys(mac);
6353
6354	if ((mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) == 0) {
6355		int i;
6356
6357#define NRETRY	1000
6358		/*
6359		 * Drain any possible pending TX status
6360		 */
6361		for (i = 0; i < NRETRY; ++i) {
6362			if ((CSR_READ_4(sc, BWI_TXSTATUS_0) &
6363			     BWI_TXSTATUS_0_MORE) == 0)
6364				break;
6365			CSR_READ_4(sc, BWI_TXSTATUS_1);
6366		}
6367		if (i == NRETRY)
6368			DPRINTF(1, "%s: can't drain TX status\n",
6369			    sc->sc_dev.dv_xname);
6370#undef NRETRY
6371	}
6372
6373	if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
6374		bwi_mac_updateslot(mac, 1);
6375
6376	/* Start MAC */
6377	error = bwi_mac_start(mac);
6378	if (error)
6379		goto back;
6380
6381	/* Enable intrs */
6382	bwi_enable_intrs(sc, BWI_INIT_INTRS);
6383
6384	ifp->if_flags |= IFF_RUNNING;
6385	ifp->if_flags &= ~IFF_OACTIVE;
6386
6387	if (ic->ic_opmode != IEEE80211_M_MONITOR)
6388		/* start background scanning */
6389		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
6390	else
6391		/* in monitor mode change directly into run state */
6392		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
6393back:
6394	if (error)
6395		bwi_stop(sc);
6396
6397	return (0);
6398}
6399
6400int
6401bwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
6402{
6403	struct bwi_softc *sc = ifp->if_softc;
6404	struct ieee80211com *ic = &sc->sc_ic;
6405	struct ifaddr *ifa;
6406	struct ifreq *ifr;
6407	int s, error = 0;
6408	uint8_t chan;
6409
6410	s = splnet();
6411
6412	switch (cmd) {
6413	case SIOCSIFADDR:
6414		ifa = (struct ifaddr *)data;
6415		ifp->if_flags |= IFF_UP;
6416#ifdef INET
6417		if (ifa->ifa_addr->sa_family == AF_INET)
6418			arp_ifinit(&ic->ic_ac, ifa);
6419#endif
6420		/* FALLTHROUGH */
6421	case SIOCSIFFLAGS:
6422		if (ifp->if_flags & IFF_UP) {
6423			if ((ifp->if_flags & IFF_RUNNING) == 0)
6424				bwi_init(ifp);
6425		} else {
6426			if (ifp->if_flags & IFF_RUNNING)
6427				bwi_stop(sc);
6428		}
6429		break;
6430        case SIOCADDMULTI:
6431        case SIOCDELMULTI:
6432		ifr = (struct ifreq *)data;
6433		error = (cmd == SIOCADDMULTI) ?
6434		    ether_addmulti(ifr, &ic->ic_ac) :
6435		    ether_delmulti(ifr, &ic->ic_ac);
6436
6437		if (error == ENETRESET)
6438			error = 0;
6439		break;
6440	case SIOCS80211CHANNEL:
6441		/* allow fast channel switching in monitor mode */
6442		error = ieee80211_ioctl(ifp, cmd, data);
6443		if (error == ENETRESET &&
6444		    ic->ic_opmode == IEEE80211_M_MONITOR) {
6445			if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
6446			    (IFF_UP | IFF_RUNNING)) {
6447				ic->ic_bss->ni_chan = ic->ic_ibss_chan;
6448				chan = ieee80211_chan2ieee(ic,
6449				    ic->ic_bss->ni_chan);
6450				bwi_set_chan(sc, chan);
6451			}
6452			error = 0;
6453		}
6454		break;
6455	default:
6456		error = ieee80211_ioctl(ifp, cmd, data);
6457		break;
6458	}
6459
6460	if (error == ENETRESET) {
6461		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
6462		    (IFF_UP | IFF_RUNNING))
6463			bwi_init(ifp);
6464		error = 0;
6465	}
6466
6467	splx(s);
6468
6469	return (error);
6470}
6471
6472void
6473bwi_start(struct ifnet *ifp)
6474{
6475	struct bwi_softc *sc = ifp->if_softc;
6476	struct ieee80211com *ic = &sc->sc_ic;
6477	struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
6478	int trans, idx;
6479
6480	if ((ifp->if_flags & IFF_OACTIVE) || (ifp->if_flags & IFF_RUNNING) == 0)
6481		return;
6482
6483	trans = 0;
6484	idx = tbd->tbd_idx;
6485
6486	while (tbd->tbd_buf[idx].tb_mbuf == NULL) {
6487		struct ieee80211_frame *wh;
6488		struct ieee80211_node *ni;
6489		struct mbuf *m;
6490		int mgt_pkt = 0;
6491
6492		IF_POLL(&ic->ic_mgtq, m);
6493		if (m != NULL) {
6494			IF_DEQUEUE(&ic->ic_mgtq, m);
6495
6496			ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
6497			m->m_pkthdr.rcvif = NULL;
6498
6499			mgt_pkt = 1;
6500		} else {
6501			struct ether_header *eh;
6502
6503			if (ic->ic_state != IEEE80211_S_RUN)
6504				break;
6505
6506			IFQ_POLL(&ifp->if_snd, m);
6507			if (m == NULL)
6508				break;
6509
6510			IFQ_DEQUEUE(&ifp->if_snd, m);
6511
6512			if (m->m_len < sizeof(*eh)) {
6513				m = m_pullup(m, sizeof(*eh));
6514				if (m == NULL) {
6515					ifp->if_oerrors++;
6516					continue;
6517				}
6518			}
6519			eh = mtod(m, struct ether_header *);
6520
6521			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
6522			if (ni == NULL) {
6523				m_freem(m);
6524				ifp->if_oerrors++;
6525				continue;
6526			}
6527
6528			/* TODO: PS */
6529#if NBPFILTER > 0
6530			if (ifp->if_bpf != NULL)
6531				bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
6532#endif
6533			m = ieee80211_encap(ifp, m, &ni);
6534			if (m == NULL)
6535				continue;
6536		}
6537#if NBPFILTER > 0
6538		if (ic->ic_rawbpf != NULL)
6539			bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT);
6540#endif
6541		wh = mtod(m, struct ieee80211_frame *);
6542		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
6543			m = ieee80211_wep_crypt(ifp, m, 1);
6544			if (m == NULL)
6545				return;
6546		}
6547		wh = NULL;	/* Catch any invalid use */
6548
6549		if (mgt_pkt) {
6550			ieee80211_release_node(ic, ni);
6551			ni = NULL;
6552		}
6553
6554		if (bwi_encap(sc, idx, m, ni) != 0) {
6555			/* 'm' is freed in bwi_encap() if we reach here */
6556			if (ni != NULL)
6557				ieee80211_release_node(ic, ni);
6558			ifp->if_oerrors++;
6559			continue;
6560		}
6561
6562		trans = 1;
6563		tbd->tbd_used++;
6564		idx = (idx + 1) % BWI_TX_NDESC;
6565
6566		if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) {
6567			ifp->if_flags |= IFF_OACTIVE;
6568			break;
6569		}
6570	}
6571	tbd->tbd_idx = idx;
6572
6573	if (trans)
6574		sc->sc_tx_timer = 5;
6575	ifp->if_timer = 1;
6576}
6577
6578void
6579bwi_watchdog(struct ifnet *ifp)
6580{
6581	struct bwi_softc *sc = ifp->if_softc;
6582
6583	ifp->if_timer = 0;
6584
6585	if ((ifp->if_flags & IFF_RUNNING) == 0)
6586		return;
6587
6588	if (sc->sc_tx_timer) {
6589		if (--sc->sc_tx_timer == 0) {
6590			DPRINTF(1, "%s: watchdog timeout\n",
6591			    sc->sc_dev.dv_xname);
6592			ifp->if_oerrors++;
6593			/* TODO */
6594		} else
6595			ifp->if_timer = 1;
6596	}
6597
6598	ieee80211_watchdog(ifp);
6599}
6600
6601int
6602bwi_stop(struct bwi_softc *sc)
6603{
6604	struct ieee80211com *ic = &sc->sc_ic;
6605	struct ifnet *ifp = &ic->ic_if;
6606	struct bwi_mac *mac;
6607	int i, error, pwr_off = 0;
6608
6609	DPRINTF(1, "%s\n", __func__);
6610
6611	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
6612
6613	if (ifp->if_flags & IFF_RUNNING) {
6614		KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
6615		mac = (struct bwi_mac *)sc->sc_cur_regwin;
6616
6617		bwi_disable_intrs(sc, BWI_ALL_INTRS);
6618		CSR_READ_4(sc, BWI_MAC_INTR_MASK);
6619		bwi_mac_stop(mac);
6620	}
6621
6622	for (i = 0; i < sc->sc_nmac; ++i) {
6623		struct bwi_regwin *old_rw;
6624
6625		mac = &sc->sc_mac[i];
6626		if ((mac->mac_flags & BWI_MAC_F_INITED) == 0)
6627			continue;
6628
6629		error = bwi_regwin_switch(sc, &mac->mac_regwin, &old_rw);
6630		if (error)
6631			continue;
6632
6633		bwi_mac_shutdown(mac);
6634		pwr_off = 1;
6635
6636		bwi_regwin_switch(sc, old_rw, NULL);
6637	}
6638
6639	if (pwr_off)
6640		bwi_bbp_power_off(sc);
6641
6642	sc->sc_tx_timer = 0;
6643	ifp->if_timer = 0;
6644	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
6645
6646	/* power off cardbus socket */
6647	if (sc->sc_disable)
6648		sc->sc_disable(sc);
6649
6650	return (0);
6651}
6652
6653int
6654bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
6655{
6656	struct bwi_softc *sc = ic->ic_if.if_softc;
6657	int error;
6658	uint8_t chan;
6659
6660	timeout_del(&sc->sc_amrr_ch);
6661	timeout_del(&sc->sc_scan_ch);
6662	timeout_del(&sc->sc_calib_ch);
6663
6664	if (nstate == IEEE80211_S_INIT)
6665		goto back;
6666
6667	chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
6668	error = bwi_set_chan(sc, chan);
6669	if (error) {
6670		DPRINTF(1, "%s: can't set channel to %u\n",
6671		    sc->sc_dev.dv_xname,
6672		    ieee80211_chan2ieee(ic, ic->ic_des_chan));
6673		return (error);
6674	}
6675
6676	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
6677		/* Nothing to do */
6678	} else if (nstate == IEEE80211_S_RUN) {
6679		struct bwi_mac *mac;
6680
6681		bwi_set_bssid(sc, ic->ic_bss->ni_bssid);
6682
6683		KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
6684		mac = (struct bwi_mac *)sc->sc_cur_regwin;
6685
6686		/* Initial TX power calibration */
6687		bwi_mac_calibrate_txpower(mac);
6688	} else
6689		bwi_set_bssid(sc, bwi_zero_addr);
6690
6691back:
6692	error = sc->sc_newstate(ic, nstate, arg);
6693
6694	if (nstate == IEEE80211_S_SCAN) {
6695		timeout_add(&sc->sc_scan_ch,
6696			      (sc->sc_dwell_time * hz) / 1000);
6697	} else if (nstate == IEEE80211_S_RUN) {
6698		/* XXX 15 seconds */
6699		timeout_add(&sc->sc_calib_ch, hz * 15);
6700
6701		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
6702			/* start automatic rate control timer */
6703			if (ic->ic_fixed_rate == -1)
6704				timeout_add(&sc->sc_amrr_ch, hz / 2);
6705		}
6706	}
6707
6708	return (error);
6709}
6710
6711int
6712bwi_media_change(struct ifnet *ifp)
6713{
6714	int error;
6715
6716	error = ieee80211_media_change(ifp);
6717	if (error != ENETRESET)
6718		return (error);
6719
6720	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
6721		bwi_init(ifp);
6722
6723	return (0);
6724}
6725
6726void
6727bwi_iter_func(void *arg, struct ieee80211_node *ni)
6728{
6729	struct bwi_softc *sc = arg;
6730	struct bwi_node *bn = (struct bwi_node *)ni;
6731
6732	ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn);
6733}
6734
6735void
6736bwi_amrr_timeout(void *arg)
6737{
6738	struct bwi_softc *sc = arg;
6739	struct ieee80211com *ic = &sc->sc_ic;
6740
6741	if (ic->ic_opmode == IEEE80211_M_STA)
6742		bwi_iter_func(sc, ic->ic_bss);
6743	else
6744		ieee80211_iterate_nodes(ic, bwi_iter_func, sc);
6745
6746	timeout_add(&sc->sc_amrr_ch, hz / 2);
6747}
6748
6749void
6750bwi_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
6751{
6752	struct bwi_softc *sc = ic->ic_if.if_softc;
6753	int i;
6754
6755	DPRINTF(1, "%s\n", __func__);
6756
6757	ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn);
6758
6759	/* set rate to some reasonable initial value */
6760	for (i = ni->ni_rates.rs_nrates - 1;
6761	    i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; i--);
6762
6763	ni->ni_txrate = i;
6764}
6765
6766int
6767bwi_dma_alloc(struct bwi_softc *sc)
6768{
6769	int error, i, has_txstats;
6770	bus_size_t tx_ring_sz, rx_ring_sz, desc_sz = 0;
6771	uint32_t txrx_ctrl_step = 0;
6772
6773	has_txstats = 0;
6774	for (i = 0; i < sc->sc_nmac; ++i) {
6775		if (sc->sc_mac[i].mac_flags & BWI_MAC_F_HAS_TXSTATS) {
6776			has_txstats = 1;
6777			break;
6778		}
6779	}
6780
6781	switch (sc->sc_bus_space) {
6782	case BWI_BUS_SPACE_30BIT:
6783	case BWI_BUS_SPACE_32BIT:
6784		desc_sz = sizeof(struct bwi_desc32);
6785		txrx_ctrl_step = 0x20;
6786
6787		sc->sc_init_tx_ring = bwi_init_tx_ring32;
6788		sc->sc_free_tx_ring = bwi_free_tx_ring32;
6789		sc->sc_init_rx_ring = bwi_init_rx_ring32;
6790		sc->sc_free_rx_ring = bwi_free_rx_ring32;
6791		sc->sc_setup_rxdesc = bwi_setup_rx_desc32;
6792		sc->sc_setup_txdesc = bwi_setup_tx_desc32;
6793		sc->sc_rxeof = bwi_rxeof32;
6794		sc->sc_start_tx = bwi_start_tx32;
6795		if (has_txstats) {
6796			sc->sc_init_txstats = bwi_init_txstats32;
6797			sc->sc_free_txstats = bwi_free_txstats32;
6798			sc->sc_txeof_status = bwi_txeof_status32;
6799		}
6800		break;
6801
6802	case BWI_BUS_SPACE_64BIT:
6803		desc_sz = sizeof(struct bwi_desc64);
6804		txrx_ctrl_step = 0x40;
6805
6806		sc->sc_init_tx_ring = bwi_init_tx_ring64;
6807		sc->sc_free_tx_ring = bwi_free_tx_ring64;
6808		sc->sc_init_rx_ring = bwi_init_rx_ring64;
6809		sc->sc_free_rx_ring = bwi_free_rx_ring64;
6810		sc->sc_setup_rxdesc = bwi_setup_rx_desc64;
6811		sc->sc_setup_txdesc = bwi_setup_tx_desc64;
6812		sc->sc_rxeof = bwi_rxeof64;
6813		sc->sc_start_tx = bwi_start_tx64;
6814		if (has_txstats) {
6815			sc->sc_init_txstats = bwi_init_txstats64;
6816			sc->sc_free_txstats = bwi_free_txstats64;
6817			sc->sc_txeof_status = bwi_txeof_status64;
6818		}
6819		break;
6820	}
6821
6822	KKASSERT(desc_sz != 0);
6823	KKASSERT(txrx_ctrl_step != 0);
6824
6825	tx_ring_sz = roundup(desc_sz * BWI_TX_NDESC, BWI_RING_ALIGN);
6826	rx_ring_sz = roundup(desc_sz * BWI_RX_NDESC, BWI_RING_ALIGN);
6827
6828#define TXRX_CTRL(idx)	(BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step)
6829	/*
6830	 * Create TX ring DMA stuffs
6831	 */
6832	for (i = 0; i < BWI_TX_NRING; ++i) {
6833		error = bus_dmamap_create(sc->sc_dmat, tx_ring_sz, 1,
6834		    tx_ring_sz, 0, BUS_DMA_NOWAIT,
6835		    &sc->sc_tx_rdata[i].rdata_dmap);
6836		if (error) {
6837			DPRINTF(1, "%s: %dth TX ring DMA create failed\n",
6838			    sc->sc_dev.dv_xname, i);
6839			return (error);
6840		}
6841		error = bwi_dma_ring_alloc(sc,
6842		    &sc->sc_tx_rdata[i], tx_ring_sz, TXRX_CTRL(i));
6843		if (error) {
6844			DPRINTF(1, "%s: %dth TX ring DMA alloc failed\n",
6845			    sc->sc_dev.dv_xname, i);
6846			return (error);
6847		}
6848	}
6849
6850	/*
6851	 * Create RX ring DMA stuffs
6852	 */
6853	error = bus_dmamap_create(sc->sc_dmat, rx_ring_sz, 1,
6854	    rx_ring_sz, 0, BUS_DMA_NOWAIT,
6855	    &sc->sc_rx_rdata.rdata_dmap);
6856	if (error) {
6857		DPRINTF(1, "%s: RX ring DMA create failed\n",
6858		    sc->sc_dev.dv_xname);
6859		return (error);
6860	}
6861
6862	error = bwi_dma_ring_alloc(sc, &sc->sc_rx_rdata,
6863	    rx_ring_sz, TXRX_CTRL(0));
6864	if (error) {
6865		DPRINTF(1, "%s: RX ring DMA alloc failed\n",
6866		    sc->sc_dev.dv_xname);
6867		return (error);
6868	}
6869
6870	if (has_txstats) {
6871		error = bwi_dma_txstats_alloc(sc, TXRX_CTRL(3), desc_sz);
6872		if (error) {
6873			DPRINTF(1, "%s: TX stats DMA alloc failed\n",
6874			    sc->sc_dev.dv_xname);
6875			return (error);
6876		}
6877	}
6878#undef TXRX_CTRL
6879
6880	return (bwi_dma_mbuf_create(sc));
6881}
6882
6883void
6884bwi_dma_free(struct bwi_softc *sc)
6885{
6886	int i;
6887
6888	for (i = 0; i < BWI_TX_NRING; ++i) {
6889		struct bwi_ring_data *rd = &sc->sc_tx_rdata[i];
6890
6891		if (rd->rdata_desc != NULL) {
6892			bus_dmamap_unload(sc->sc_dmat,
6893			    rd->rdata_dmap);
6894			bus_dmamem_free(sc->sc_dmat,
6895			    &rd->rdata_seg, 1);
6896		}
6897	}
6898
6899	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
6900
6901	if (rd->rdata_desc != NULL) {
6902		bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap);
6903		bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, 1);
6904	}
6905
6906	bwi_dma_txstats_free(sc);
6907	bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 1);
6908}
6909
6910int
6911bwi_dma_ring_alloc(struct bwi_softc *sc,
6912    struct bwi_ring_data *rd, bus_size_t size, uint32_t txrx_ctrl)
6913{
6914	int error, nsegs;
6915
6916	error = bus_dmamem_alloc(sc->sc_dmat, size, BWI_ALIGN, 0,
6917	    &rd->rdata_seg, 1, &nsegs, BUS_DMA_NOWAIT);
6918	if (error) {
6919		DPRINTF(1, "%s: can't allocate DMA mem\n", sc->sc_dev.dv_xname);
6920		return (error);
6921	}
6922
6923	error = bus_dmamem_map(sc->sc_dmat, &rd->rdata_seg, nsegs,
6924	    size, (caddr_t *)&rd->rdata_desc, BUS_DMA_NOWAIT);
6925	if (error) {
6926		DPRINTF(1, "%s: can't map DMA mem\n", sc->sc_dev.dv_xname);
6927		return (error);
6928	}
6929
6930	error = bus_dmamap_load(sc->sc_dmat, rd->rdata_dmap, rd->rdata_desc,
6931	    size, NULL, BUS_DMA_WAITOK);
6932	if (error) {
6933		DPRINTF(1, "%s: can't load DMA mem\n", sc->sc_dev.dv_xname);
6934		bus_dmamem_free(sc->sc_dmat, &rd->rdata_seg, nsegs);
6935		rd->rdata_desc = NULL;
6936		return (error);
6937	}
6938
6939	rd->rdata_paddr = rd->rdata_dmap->dm_segs[0].ds_addr;
6940	rd->rdata_txrx_ctrl = txrx_ctrl;
6941
6942	return (0);
6943}
6944
6945int
6946bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base,
6947    bus_size_t desc_sz)
6948{
6949	struct bwi_txstats_data *st;
6950	bus_size_t dma_size;
6951	int error, nsegs;
6952
6953	st = malloc(sizeof(*st), M_DEVBUF, M_WAITOK | M_ZERO);
6954	sc->sc_txstats = st;
6955
6956	/*
6957	 * Create TX stats descriptor DMA stuffs
6958	 */
6959	dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN);
6960
6961	error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
6962	    BUS_DMA_NOWAIT, &st->stats_ring_dmap);
6963	if (error) {
6964		DPRINTF(1, "%s: can't create txstats ring DMA mem\n",
6965		    sc->sc_dev.dv_xname);
6966		return (error);
6967	}
6968
6969	error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_RING_ALIGN, 0,
6970	     &st->stats_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT);
6971	if (error) {
6972		DPRINTF(1, "%s: can't allocate txstats ring DMA mem\n",
6973		    sc->sc_dev.dv_xname);
6974		return (error);
6975	}
6976
6977	error = bus_dmamem_map(sc->sc_dmat, &st->stats_ring_seg, nsegs,
6978	    dma_size, (caddr_t *)&st->stats_ring, BUS_DMA_NOWAIT);
6979	if (error) {
6980		DPRINTF(1, "%s: can't map txstats ring DMA mem\n",
6981		    sc->sc_dev.dv_xname);
6982		return (error);
6983	}
6984
6985	error = bus_dmamap_load(sc->sc_dmat, st->stats_ring_dmap,
6986	    st->stats_ring, dma_size, NULL, BUS_DMA_WAITOK);
6987	if (error) {
6988		DPRINTF(1, "%s: can't load txstats ring DMA mem\n",
6989		    sc->sc_dev.dv_xname);
6990		bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, nsegs);
6991		return (error);
6992	}
6993
6994	bzero(&st->stats_ring, dma_size);
6995	st->stats_ring_paddr = st->stats_ring_dmap->dm_segs[0].ds_addr;
6996
6997	/*
6998	 * Create TX stats DMA stuffs
6999	 */
7000	dma_size = roundup(sizeof(struct bwi_txstats) * BWI_TXSTATS_NDESC,
7001	    BWI_ALIGN);
7002
7003	error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,
7004	    BUS_DMA_NOWAIT, &st->stats_dmap);
7005	if (error) {
7006		DPRINTF(1, "%s: can't create txstats ring DMA mem\n",
7007		    sc->sc_dev.dv_xname);
7008		return (error);
7009	}
7010	error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_ALIGN, 0,
7011	    &st->stats_seg, 1, &nsegs, BUS_DMA_NOWAIT);
7012	if (error) {
7013		DPRINTF(1, "%s: can't allocate txstats DMA mem\n",
7014		    sc->sc_dev.dv_xname);
7015		return (error);
7016	}
7017
7018	error = bus_dmamem_map(sc->sc_dmat, &st->stats_seg, nsegs,
7019	    dma_size, (caddr_t *)&st->stats, BUS_DMA_NOWAIT);
7020	if (error) {
7021		DPRINTF(1, "%s: can't map txstats DMA mem\n",
7022		    sc->sc_dev.dv_xname);
7023		return (error);
7024	}
7025
7026	error = bus_dmamap_load(sc->sc_dmat, st->stats_dmap, st->stats,
7027	    dma_size, NULL, BUS_DMA_WAITOK);
7028	if (error) {
7029		DPRINTF(1, "%s: can't load txstats DMA mem\n",
7030		    sc->sc_dev.dv_xname);
7031		bus_dmamem_free(sc->sc_dmat, &st->stats_seg, nsegs);
7032		return (error);
7033	}
7034
7035	bzero(&st->stats, dma_size);
7036	st->stats_paddr = st->stats_dmap->dm_segs[0].ds_addr;
7037	st->stats_ctrl_base = ctrl_base;
7038
7039	return (0);
7040}
7041
7042void
7043bwi_dma_txstats_free(struct bwi_softc *sc)
7044{
7045	struct bwi_txstats_data *st;
7046
7047	if (sc->sc_txstats == NULL)
7048		return;
7049	st = sc->sc_txstats;
7050
7051	bus_dmamap_unload(sc->sc_dmat, st->stats_ring_dmap);
7052	bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, 1);
7053
7054	bus_dmamap_unload(sc->sc_dmat, st->stats_dmap);
7055	bus_dmamem_free(sc->sc_dmat, &st->stats_seg, 1);
7056
7057	free(st, M_DEVBUF);
7058}
7059
7060int
7061bwi_dma_mbuf_create(struct bwi_softc *sc)
7062{
7063	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
7064	int i, j, k, ntx, error;
7065
7066	ntx = 0;
7067
7068	/*
7069	 * Create TX mbuf DMA map
7070	 */
7071	for (i = 0; i < BWI_TX_NRING; ++i) {
7072		struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
7073
7074		for (j = 0; j < BWI_TX_NDESC; ++j) {
7075			error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
7076			    0, BUS_DMA_NOWAIT, &tbd->tbd_buf[j].tb_dmap);
7077			if (error) {
7078				DPRINTF(1,
7079				    "%s: can't create %dth tbd, %dth DMA map\n",
7080				    sc->sc_dev.dv_xname, i, j);
7081				ntx = i;
7082				for (k = 0; k < j; ++k) {
7083					bus_dmamap_destroy(sc->sc_dmat,
7084					    tbd->tbd_buf[k].tb_dmap);
7085				}
7086				goto fail;
7087			}
7088		}
7089	}
7090	ntx = BWI_TX_NRING;
7091
7092	/*
7093	 * Create RX mbuf DMA map and a spare DMA map
7094	 */
7095	error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
7096	    BUS_DMA_NOWAIT, &rbd->rbd_tmp_dmap);
7097	if (error) {
7098		DPRINTF(1, "%s: can't create spare RX buf DMA map\n",
7099		    sc->sc_dev.dv_xname);
7100		goto fail;
7101	}
7102
7103	for (j = 0; j < BWI_RX_NDESC; ++j) {
7104		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
7105		    BUS_DMA_NOWAIT, &rbd->rbd_buf[j].rb_dmap);
7106		if (error) {
7107			DPRINTF(1, "%s: can't create %dth RX buf DMA map\n",
7108			    sc->sc_dev.dv_xname, j);
7109
7110			for (k = 0; k < j; ++k) {
7111				bus_dmamap_destroy(sc->sc_dmat,
7112				    rbd->rbd_buf[j].rb_dmap);
7113			}
7114			bus_dmamap_destroy(sc->sc_dmat,
7115			    rbd->rbd_tmp_dmap);
7116			goto fail;
7117		}
7118	}
7119
7120	return 0;
7121fail:
7122	bwi_dma_mbuf_destroy(sc, ntx, 0);
7123
7124	return (error);
7125}
7126
7127void
7128bwi_dma_mbuf_destroy(struct bwi_softc *sc, int ntx, int nrx)
7129{
7130	struct ieee80211com *ic = &sc->sc_ic;
7131	int i, j;
7132
7133	for (i = 0; i < ntx; ++i) {
7134		struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
7135
7136		for (j = 0; j < BWI_TX_NDESC; ++j) {
7137			struct bwi_txbuf *tb = &tbd->tbd_buf[j];
7138
7139			if (tb->tb_mbuf != NULL) {
7140				bus_dmamap_unload(sc->sc_dmat,
7141				    tb->tb_dmap);
7142				m_freem(tb->tb_mbuf);
7143			}
7144			if (tb->tb_ni != NULL)
7145				ieee80211_release_node(ic, tb->tb_ni);
7146			bus_dmamap_destroy(sc->sc_dmat, tb->tb_dmap);
7147		}
7148	}
7149
7150	if (nrx) {
7151		struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
7152
7153		bus_dmamap_destroy(sc->sc_dmat, rbd->rbd_tmp_dmap);
7154		for (j = 0; j < BWI_RX_NDESC; ++j) {
7155			struct bwi_rxbuf *rb = &rbd->rbd_buf[j];
7156
7157			if (rb->rb_mbuf != NULL) {
7158				bus_dmamap_unload(sc->sc_dmat,
7159						  rb->rb_dmap);
7160				m_freem(rb->rb_mbuf);
7161			}
7162			bus_dmamap_destroy(sc->sc_dmat, rb->rb_dmap);
7163		}
7164	}
7165}
7166
7167void
7168bwi_enable_intrs(struct bwi_softc *sc, uint32_t enable_intrs)
7169{
7170	CSR_SETBITS_4(sc, BWI_MAC_INTR_MASK, enable_intrs);
7171}
7172
7173void
7174bwi_disable_intrs(struct bwi_softc *sc, uint32_t disable_intrs)
7175{
7176	CSR_CLRBITS_4(sc, BWI_MAC_INTR_MASK, disable_intrs);
7177}
7178
7179int
7180bwi_init_tx_ring32(struct bwi_softc *sc, int ring_idx)
7181{
7182	struct bwi_ring_data *rd;
7183	struct bwi_txbuf_data *tbd;
7184	uint32_t val, addr_hi, addr_lo;
7185
7186	KKASSERT(ring_idx < BWI_TX_NRING);
7187	rd = &sc->sc_tx_rdata[ring_idx];
7188	tbd = &sc->sc_tx_bdata[ring_idx];
7189
7190	tbd->tbd_idx = 0;
7191	tbd->tbd_used = 0;
7192
7193	bzero(rd->rdata_desc, sizeof(struct bwi_desc32) * BWI_TX_NDESC);
7194	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
7195	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
7196
7197	addr_lo = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
7198	addr_hi = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
7199
7200	val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
7201	    __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
7202	    BWI_TXRX32_RINGINFO_FUNC_MASK);
7203	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, val);
7204
7205	val = __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
7206	      BWI_TXRX32_CTRL_ENABLE;
7207	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, val);
7208
7209	return (0);
7210}
7211
7212void
7213bwi_init_rxdesc_ring32(struct bwi_softc *sc, uint32_t ctrl_base,
7214    bus_addr_t paddr, int hdr_size, int ndesc)
7215{
7216	uint32_t val, addr_hi, addr_lo;
7217
7218	addr_lo = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
7219	addr_hi = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
7220
7221	val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
7222	    __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
7223	      		BWI_TXRX32_RINGINFO_FUNC_MASK);
7224	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_RINGINFO, val);
7225
7226	val = __SHIFTIN(hdr_size, BWI_RX32_CTRL_HDRSZ_MASK) |
7227	    __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
7228	    BWI_TXRX32_CTRL_ENABLE;
7229	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val);
7230
7231	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
7232	    (ndesc - 1) * sizeof(struct bwi_desc32));
7233}
7234
7235int
7236bwi_init_rx_ring32(struct bwi_softc *sc)
7237{
7238	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
7239	int i, error;
7240
7241	sc->sc_rx_bdata.rbd_idx = 0;
7242
7243	for (i = 0; i < BWI_RX_NDESC; ++i) {
7244		error = bwi_newbuf(sc, i, 1);
7245		if (error) {
7246			DPRINTF(1, "%s: can't allocate %dth RX buffer\n",
7247			    sc->sc_dev.dv_xname, i);
7248			return (error);
7249		}
7250	}
7251	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
7252	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
7253
7254	bwi_init_rxdesc_ring32(sc, rd->rdata_txrx_ctrl, rd->rdata_paddr,
7255	    sizeof(struct bwi_rxbuf_hdr), BWI_RX_NDESC);
7256	return (0);
7257}
7258
7259int
7260bwi_init_txstats32(struct bwi_softc *sc)
7261{
7262	struct bwi_txstats_data *st = sc->sc_txstats;
7263	bus_addr_t stats_paddr;
7264	int i;
7265
7266	bzero(st->stats, BWI_TXSTATS_NDESC * sizeof(struct bwi_txstats));
7267	bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,
7268	    st->stats_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
7269
7270	st->stats_idx = 0;
7271
7272	stats_paddr = st->stats_paddr;
7273	for (i = 0; i < BWI_TXSTATS_NDESC; ++i) {
7274		bwi_setup_desc32(sc, st->stats_ring, BWI_TXSTATS_NDESC, i,
7275				 stats_paddr, sizeof(struct bwi_txstats), 0);
7276		stats_paddr += sizeof(struct bwi_txstats);
7277	}
7278	bus_dmamap_sync(sc->sc_dmat, st->stats_ring_dmap, 0,
7279	    st->stats_ring_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
7280
7281	bwi_init_rxdesc_ring32(sc, st->stats_ctrl_base,
7282	    st->stats_ring_paddr, 0, BWI_TXSTATS_NDESC);
7283
7284	return (0);
7285}
7286
7287void
7288bwi_setup_rx_desc32(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
7289    int buf_len)
7290{
7291	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
7292
7293	KKASSERT(buf_idx < BWI_RX_NDESC);
7294	bwi_setup_desc32(sc, rd->rdata_desc, BWI_RX_NDESC, buf_idx,
7295	    paddr, buf_len, 0);
7296}
7297
7298void
7299bwi_setup_tx_desc32(struct bwi_softc *sc, struct bwi_ring_data *rd,
7300    int buf_idx, bus_addr_t paddr, int buf_len)
7301{
7302	KKASSERT(buf_idx < BWI_TX_NDESC);
7303	bwi_setup_desc32(sc, rd->rdata_desc, BWI_TX_NDESC, buf_idx,
7304	    paddr, buf_len, 1);
7305}
7306
7307int
7308bwi_init_tx_ring64(struct bwi_softc *sc, int ring_idx)
7309{
7310	/* TODO: 64 */
7311	return (EOPNOTSUPP);
7312}
7313
7314int
7315bwi_init_rx_ring64(struct bwi_softc *sc)
7316{
7317	/* TODO: 64 */
7318	return (EOPNOTSUPP);
7319}
7320
7321int
7322bwi_init_txstats64(struct bwi_softc *sc)
7323{
7324	/* TODO: 64 */
7325	return (EOPNOTSUPP);
7326}
7327
7328void
7329bwi_setup_rx_desc64(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
7330    int buf_len)
7331{
7332	/* TODO: 64 */
7333}
7334
7335void
7336bwi_setup_tx_desc64(struct bwi_softc *sc, struct bwi_ring_data *rd,
7337    int buf_idx, bus_addr_t paddr, int buf_len)
7338{
7339	/* TODO: 64 */
7340}
7341
7342int
7343bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init)
7344{
7345	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
7346	struct bwi_rxbuf *rxbuf = &rbd->rbd_buf[buf_idx];
7347	struct bwi_rxbuf_hdr *hdr;
7348	bus_dmamap_t map;
7349	bus_addr_t paddr;
7350	struct mbuf *m;
7351	int error;
7352
7353	KKASSERT(buf_idx < BWI_RX_NDESC);
7354
7355	MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA);
7356	if (m == NULL)
7357		return (ENOBUFS);
7358	MCLGET(m, init ? M_WAITOK : M_DONTWAIT);
7359	if (m == NULL) {
7360		error = ENOBUFS;
7361
7362		/*
7363		 * If the NIC is up and running, we need to:
7364		 * - Clear RX buffer's header.
7365		 * - Restore RX descriptor settings.
7366		 */
7367		if (init)
7368			return error;
7369		else
7370			goto back;
7371	}
7372	m->m_len = m->m_pkthdr.len = MCLBYTES;
7373
7374	/*
7375	 * Try to load RX buf into temporary DMA map
7376	 */
7377	error = bus_dmamap_load_mbuf(sc->sc_dmat, rbd->rbd_tmp_dmap, m,
7378	    init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT);
7379	if (error) {
7380		m_freem(m);
7381
7382		/*
7383		 * See the comment above
7384		 */
7385		if (init)
7386			return error;
7387		else
7388			goto back;
7389	}
7390
7391	if (!init)
7392		bus_dmamap_unload(sc->sc_dmat, rxbuf->rb_dmap);
7393	rxbuf->rb_mbuf = m;
7394
7395	/*
7396	 * Swap RX buf's DMA map with the loaded temporary one
7397	 */
7398	map = rxbuf->rb_dmap;
7399	rxbuf->rb_dmap = rbd->rbd_tmp_dmap;
7400	rbd->rbd_tmp_dmap = map;
7401	paddr = rxbuf->rb_dmap->dm_segs[0].ds_addr;
7402	rxbuf->rb_paddr = paddr;
7403
7404back:
7405	/*
7406	 * Clear RX buf header
7407	 */
7408	hdr = mtod(rxbuf->rb_mbuf, struct bwi_rxbuf_hdr *);
7409	bzero(hdr, sizeof(*hdr));
7410	bus_dmamap_sync(sc->sc_dmat, rxbuf->rb_dmap, 0,
7411	    rxbuf->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
7412
7413	/*
7414	 * Setup RX buf descriptor
7415	 */
7416	sc->sc_setup_rxdesc(sc, buf_idx, rxbuf->rb_paddr,
7417	    rxbuf->rb_mbuf->m_len - sizeof(*hdr));
7418	return error;
7419}
7420
7421void
7422bwi_set_addr_filter(struct bwi_softc *sc, uint16_t addr_ofs,
7423    const uint8_t *addr)
7424{
7425	int i;
7426
7427	CSR_WRITE_2(sc, BWI_ADDR_FILTER_CTRL,
7428	    BWI_ADDR_FILTER_CTRL_SET | addr_ofs);
7429
7430	for (i = 0; i < (IEEE80211_ADDR_LEN / 2); ++i) {
7431		uint16_t addr_val;
7432
7433		addr_val = (uint16_t)addr[i * 2] |
7434		    (((uint16_t)addr[(i * 2) + 1]) << 8);
7435		CSR_WRITE_2(sc, BWI_ADDR_FILTER_DATA, addr_val);
7436	}
7437}
7438
7439int
7440bwi_set_chan(struct bwi_softc *sc, u_int8_t chan)
7441{
7442	struct bwi_mac *mac;
7443
7444	KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
7445	mac = (struct bwi_mac *)sc->sc_cur_regwin;
7446
7447	bwi_rf_set_chan(mac, chan, 0);
7448
7449	return (0);
7450}
7451
7452void
7453bwi_next_scan(void *xsc)
7454{
7455	struct bwi_softc *sc = xsc;
7456	struct ieee80211com *ic = &sc->sc_ic;
7457	struct ifnet *ifp = &ic->ic_if;
7458	int s;
7459
7460	s = splnet();
7461
7462	if (ic->ic_state == IEEE80211_S_SCAN)
7463		ieee80211_next_scan(ifp);
7464
7465	splx(s);
7466}
7467
7468void
7469bwi_rxeof(struct bwi_softc *sc, int end_idx)
7470{
7471	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
7472	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
7473	struct ieee80211com *ic = &sc->sc_ic;
7474	struct ifnet *ifp = &ic->ic_if;
7475	int idx;
7476
7477	idx = rbd->rbd_idx;
7478	while (idx != end_idx) {
7479		struct bwi_rxbuf *rb = &rbd->rbd_buf[idx];
7480		struct bwi_rxbuf_hdr *hdr;
7481		struct ieee80211_frame *wh;
7482		struct ieee80211_node *ni;
7483		struct mbuf *m;
7484		uint8_t plcp_signal;
7485		uint16_t flags2;
7486		int buflen, wh_ofs, hdr_extra;
7487
7488		m = rb->rb_mbuf;
7489		bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0,
7490		    rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
7491
7492		if (bwi_newbuf(sc, idx, 0)) {
7493			ifp->if_ierrors++;
7494			goto next;
7495		}
7496
7497		hdr = mtod(m, struct bwi_rxbuf_hdr *);
7498		flags2 = letoh16(hdr->rxh_flags2);
7499
7500		hdr_extra = 0;
7501		if (flags2 & BWI_RXH_F2_TYPE2FRAME)
7502			hdr_extra = 2;
7503		wh_ofs = hdr_extra + 6;
7504
7505		buflen = letoh16(hdr->rxh_buflen);
7506		if (buflen <= wh_ofs) {
7507			DPRINTF(1, "%s: zero length data, hdr_extra %d\n",
7508			    sc->sc_dev.dv_xname, hdr_extra);
7509			ifp->if_ierrors++;
7510			m_freem(m);
7511			goto next;
7512		}
7513
7514		plcp_signal = *((uint8_t *)(hdr + 1) + hdr_extra);
7515
7516		m->m_pkthdr.rcvif = ifp;
7517		m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr);
7518		m_adj(m, sizeof(*hdr) + wh_ofs);
7519
7520#if NBPFILTER > 0
7521		/* RX radio tap */
7522		if (sc->sc_drvbpf != NULL) {
7523			struct mbuf mb;
7524			struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap;
7525
7526			/* TODO: calculate rate and signal */
7527			tap->wr_tsf = hdr->rxh_tsf;
7528			tap->wr_flags = 0;
7529			tap->wr_rate = 0;
7530			tap->wr_chan_freq =
7531			    htole16(ic->ic_bss->ni_chan->ic_freq);
7532			tap->wr_chan_flags =
7533			    htole16(ic->ic_bss->ni_chan->ic_flags);
7534			tap->wr_antsignal = 0;
7535			tap->wr_antnoise = 0;
7536
7537			mb.m_data = (caddr_t)tap;
7538			mb.m_len = sc->sc_rxtap_len;
7539			mb.m_next = m;
7540			mb.m_nextpkt = NULL;
7541			mb.m_type = 0;
7542			mb.m_flags = 0;
7543			bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
7544		}
7545#endif
7546
7547		m_adj(m, -IEEE80211_CRC_LEN);
7548
7549		wh = mtod(m, struct ieee80211_frame *);
7550		ni = ieee80211_find_rxnode(ic, wh);
7551
7552		ieee80211_input(ifp, m, ni, hdr->rxh_rssi,
7553		    letoh16(hdr->rxh_tsf));
7554
7555		ieee80211_release_node(ic, ni);
7556next:
7557		idx = (idx + 1) % BWI_RX_NDESC;
7558	}
7559
7560	rbd->rbd_idx = idx;
7561	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
7562	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
7563}
7564
7565void
7566bwi_rxeof32(struct bwi_softc *sc)
7567{
7568	uint32_t val, rx_ctrl;
7569	int end_idx;
7570
7571	rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl;
7572
7573	val = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
7574	end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
7575	    sizeof(struct bwi_desc32);
7576
7577	bwi_rxeof(sc, end_idx);
7578
7579	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX,
7580	    end_idx * sizeof(struct bwi_desc32));
7581}
7582
7583void
7584bwi_rxeof64(struct bwi_softc *sc)
7585{
7586	/* TODO: 64 */
7587}
7588
7589void
7590bwi_reset_rx_ring32(struct bwi_softc *sc, uint32_t rx_ctrl)
7591{
7592	int i;
7593
7594	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_CTRL, 0);
7595
7596#define NRETRY 10
7597	for (i = 0; i < NRETRY; ++i) {
7598		uint32_t status;
7599
7600		status = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
7601		if (__SHIFTOUT(status, BWI_RX32_STATUS_STATE_MASK) ==
7602		    BWI_RX32_STATUS_STATE_DISABLED)
7603			break;
7604
7605		DELAY(1000);
7606	}
7607	if (i == NRETRY)
7608		DPRINTF(1, "%s: reset rx ring timedout\n", sc->sc_dev.dv_xname);
7609#undef NRETRY
7610
7611	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_RINGINFO, 0);
7612}
7613
7614void
7615bwi_free_txstats32(struct bwi_softc *sc)
7616{
7617	bwi_reset_rx_ring32(sc, sc->sc_txstats->stats_ctrl_base);
7618}
7619
7620void
7621bwi_free_rx_ring32(struct bwi_softc *sc)
7622{
7623	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
7624	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
7625	int i;
7626
7627	bwi_reset_rx_ring32(sc, rd->rdata_txrx_ctrl);
7628
7629	for (i = 0; i < BWI_RX_NDESC; ++i) {
7630		struct bwi_rxbuf *rb = &rbd->rbd_buf[i];
7631
7632		if (rb->rb_mbuf != NULL) {
7633			bus_dmamap_unload(sc->sc_dmat, rb->rb_dmap);
7634			m_freem(rb->rb_mbuf);
7635			rb->rb_mbuf = NULL;
7636		}
7637	}
7638}
7639
7640void
7641bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx)
7642{
7643	struct ieee80211com *ic = &sc->sc_ic;
7644	struct bwi_ring_data *rd;
7645	struct bwi_txbuf_data *tbd;
7646	uint32_t state, val;
7647	int i;
7648
7649	KKASSERT(ring_idx < BWI_TX_NRING);
7650	rd = &sc->sc_tx_rdata[ring_idx];
7651	tbd = &sc->sc_tx_bdata[ring_idx];
7652
7653#define NRETRY 10
7654	for (i = 0; i < NRETRY; ++i) {
7655		val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
7656		state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
7657		if (state == BWI_TX32_STATUS_STATE_DISABLED ||
7658		    state == BWI_TX32_STATUS_STATE_IDLE ||
7659		    state == BWI_TX32_STATUS_STATE_STOPPED)
7660			break;
7661
7662		DELAY(1000);
7663	}
7664	if (i == NRETRY) {
7665		DPRINTF(1, "%s: wait for TX ring(%d) stable timed out\n",
7666		    sc->sc_dev.dv_xname, ring_idx);
7667	}
7668
7669	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0);
7670	for (i = 0; i < NRETRY; ++i) {
7671		val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
7672		state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
7673		if (state == BWI_TX32_STATUS_STATE_DISABLED)
7674			break;
7675
7676		DELAY(1000);
7677	}
7678	if (i == NRETRY)
7679		DPRINTF(1, "%s: reset TX ring (%d) timed out\n",
7680		    sc->sc_dev.dv_xname, ring_idx);
7681#undef NRETRY
7682
7683	DELAY(1000);
7684
7685	CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, 0);
7686
7687	for (i = 0; i < BWI_TX_NDESC; ++i) {
7688		struct bwi_txbuf *tb = &tbd->tbd_buf[i];
7689
7690		if (tb->tb_mbuf != NULL) {
7691			bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap);
7692			m_freem(tb->tb_mbuf);
7693			tb->tb_mbuf = NULL;
7694		}
7695		if (tb->tb_ni != NULL) {
7696			ieee80211_release_node(ic, tb->tb_ni);
7697			tb->tb_ni = NULL;
7698		}
7699	}
7700}
7701
7702void
7703bwi_free_txstats64(struct bwi_softc *sc)
7704{
7705	/* TODO: 64 */
7706}
7707
7708void
7709bwi_free_rx_ring64(struct bwi_softc *sc)
7710{
7711	/* TODO: 64 */
7712}
7713
7714void
7715bwi_free_tx_ring64(struct bwi_softc *sc, int ring_idx)
7716{
7717	/* TODO: 64 */
7718}
7719
7720/* XXX does not belong here */
7721uint8_t
7722bwi_rate2plcp(uint8_t rate)
7723{
7724	rate &= IEEE80211_RATE_VAL;
7725
7726	switch (rate) {
7727	case 2:		return (0xa);
7728	case 4:		return (0x14);
7729	case 11:	return (0x37);
7730	case 22:	return (0x6e);
7731	case 44:	return (0xdc);
7732
7733	case 12:	return (0xb);
7734	case 18:	return (0xf);
7735	case 24:	return (0xa);
7736	case 36:	return (0xe);
7737	case 48:	return (0x9);
7738	case 72:	return (0xd);
7739	case 96:	return (0x8);
7740	case 108:	return (0xc);
7741
7742	default:
7743		panic("unsupported rate %u\n", rate);
7744	}
7745}
7746
7747void
7748bwi_ofdm_plcp_header(uint32_t *plcp0, int pkt_len, uint8_t rate)
7749{
7750/* XXX does not belong here */
7751#define IEEE80211_OFDM_PLCP_SIG_MASK	0x0000000f
7752#define IEEE80211_OFDM_PLCP_LEN_MASK	0x0001ffe0
7753
7754	uint32_t plcp;
7755
7756	plcp = __SHIFTIN(bwi_rate2plcp(rate), IEEE80211_OFDM_PLCP_SIG_MASK) |
7757	    __SHIFTIN(pkt_len, IEEE80211_OFDM_PLCP_LEN_MASK);
7758	*plcp0 = htole32(plcp);
7759}
7760
7761void
7762bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *plcp, int pkt_len,
7763		   uint8_t rate)
7764{
7765	int len, service, pkt_bitlen;
7766
7767	pkt_bitlen = pkt_len * NBBY;
7768	len = howmany(pkt_bitlen * 2, rate);
7769
7770	service = IEEE80211_DS_PLCP_SERVICE_LOCKED;
7771	if (rate == (11 * 2)) {
7772		int pkt_bitlen1;
7773
7774		/*
7775		 * PLCP service field needs to be adjusted,
7776		 * if TX rate is 11Mbytes/s
7777		 */
7778		pkt_bitlen1 = len * 11;
7779		if (pkt_bitlen1 - pkt_bitlen >= NBBY)
7780			service |= IEEE80211_DS_PLCP_SERVICE_LENEXT7;
7781	}
7782
7783	plcp->i_signal = bwi_rate2plcp(rate);
7784	plcp->i_service = service;
7785	plcp->i_length = htole16(len);
7786	/* NOTE: do NOT touch i_crc */
7787}
7788
7789void
7790bwi_plcp_header(void *plcp, int pkt_len, uint8_t rate)
7791{
7792	enum bwi_modtype modtype;
7793
7794	/*
7795	 * Assume caller has zeroed 'plcp'
7796	 */
7797
7798	modtype = bwi_rate2modtype(rate);
7799	if (modtype == IEEE80211_MODTYPE_OFDM)
7800		bwi_ofdm_plcp_header(plcp, pkt_len, rate);
7801	else if (modtype == IEEE80211_MODTYPE_DS)
7802		bwi_ds_plcp_header(plcp, pkt_len, rate);
7803	else
7804		panic("unsupport modulation type %u\n", modtype);
7805}
7806
7807enum bwi_modtype
7808bwi_rate2modtype(u_int8_t rate)
7809{
7810	rate &= IEEE80211_RATE_VAL;
7811
7812	if (rate == 44)
7813		return IEEE80211_MODTYPE_PBCC;
7814	else if (rate == 22 || rate < 12)
7815		return IEEE80211_MODTYPE_DS;
7816	else
7817		return IEEE80211_MODTYPE_OFDM;
7818}
7819
7820u_int8_t
7821bwi_ack_rate(struct ieee80211_node *ni, u_int8_t rate)
7822{
7823	const struct ieee80211_rateset *rs = &ni->ni_rates;
7824	u_int8_t ack_rate = 0;
7825	enum bwi_modtype modtype;
7826	int i;
7827
7828	rate &= IEEE80211_RATE_VAL;
7829
7830	modtype = bwi_rate2modtype(rate);
7831
7832	for (i = 0; i < rs->rs_nrates; ++i) {
7833		u_int8_t rate1 = rs->rs_rates[i] & IEEE80211_RATE_VAL;
7834
7835		if (rate1 > rate) {
7836			if (ack_rate != 0)
7837				return ack_rate;
7838			else
7839				break;
7840		}
7841
7842		if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) &&
7843		    bwi_rate2modtype(rate1) == modtype)
7844			ack_rate = rate1;
7845	}
7846
7847	switch (rate) {
7848	/* CCK */
7849	case 2:
7850	case 4:
7851	case 11:
7852	case 22:
7853		ack_rate = rate;
7854		break;
7855	/* PBCC */
7856	case 44:
7857		ack_rate = 22;
7858		break;
7859
7860	/* OFDM */
7861	case 12:
7862	case 18:
7863		ack_rate = 12;
7864		break;
7865	case 24:
7866	case 36:
7867		ack_rate = 24;
7868		break;
7869	case 48:
7870	case 72:
7871	case 96:
7872	case 108:
7873		ack_rate = 48;
7874		break;
7875	default:
7876		panic("unsupported rate %d\n", rate);
7877	}
7878	return ack_rate;
7879}
7880
7881#define IEEE80211_OFDM_TXTIME(kbps, frmlen)	\
7882	(IEEE80211_OFDM_PREAMBLE_TIME +		\
7883	 IEEE80211_OFDM_SIGNAL_TIME +		\
7884	(IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME))
7885
7886#define IEEE80211_OFDM_SYM_TIME			4
7887#define IEEE80211_OFDM_PREAMBLE_TIME		16
7888#define IEEE80211_OFDM_SIGNAL_EXT_TIME		6
7889#define IEEE80211_OFDM_SIGNAL_TIME		4
7890
7891#define IEEE80211_OFDM_PLCP_SERVICE_NBITS	16
7892#define IEEE80211_OFDM_TAIL_NBITS		6
7893
7894#define IEEE80211_OFDM_NBITS(frmlen)		\
7895	(IEEE80211_OFDM_PLCP_SERVICE_NBITS +	\
7896	 ((frmlen) * NBBY) +			\
7897	 IEEE80211_OFDM_TAIL_NBITS)
7898
7899#define IEEE80211_OFDM_NBITS_PER_SYM(kbps)	\
7900	(((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000)
7901
7902#define IEEE80211_OFDM_NSYMS(kbps, frmlen)	\
7903	howmany(IEEE80211_OFDM_NBITS((frmlen)),	\
7904	IEEE80211_OFDM_NBITS_PER_SYM((kbps)))
7905
7906#define IEEE80211_CCK_TXTIME(kbps, frmlen)	\
7907	(((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps))
7908
7909#define IEEE80211_CCK_PREAMBLE_LEN		144
7910#define IEEE80211_CCK_PLCP_HDR_TIME		48
7911#define IEEE80211_CCK_SHPREAMBLE_LEN		72
7912#define IEEE80211_CCK_SHPLCP_HDR_TIME		24
7913
7914#define IEEE80211_CCK_NBITS(frmlen)		((frmlen) * NBBY)
7915
7916u_int16_t
7917bwi_txtime(struct ieee80211com *ic, struct ieee80211_node *ni, u_int len,
7918    u_int8_t rs_rate, uint32_t flags)
7919{
7920	enum bwi_modtype modtype;
7921	u_int16_t txtime;
7922	int rate;
7923
7924	rs_rate &= IEEE80211_RATE_VAL;
7925
7926	rate = rs_rate * 500;	/* ieee80211 rate -> kbps */
7927
7928	modtype = bwi_rate2modtype(rs_rate);
7929	if (modtype == IEEE80211_MODTYPE_OFDM) {
7930		/*
7931		 * IEEE Std 802.11a-1999, page 37, equation (29)
7932		 * IEEE Std 802.11g-2003, page 44, equation (42)
7933		 */
7934		txtime = IEEE80211_OFDM_TXTIME(rate, len);
7935		if (ic->ic_curmode == IEEE80211_MODE_11G)
7936			txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME;
7937	} else {
7938		/*
7939		 * IEEE Std 802.11b-1999, page 28, subclause 18.3.4
7940		 * IEEE Std 802.11g-2003, page 45, equation (43)
7941		 */
7942		if (modtype == IEEE80211_MODTYPE_PBCC)
7943			++len;
7944		txtime = IEEE80211_CCK_TXTIME(rate, len);
7945
7946		/*
7947		 * Short preamble is not applicable for DS 1Mbits/s
7948		 */
7949		if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) {
7950			txtime += IEEE80211_CCK_SHPREAMBLE_LEN +
7951				  IEEE80211_CCK_SHPLCP_HDR_TIME;
7952		} else {
7953			txtime += IEEE80211_CCK_PREAMBLE_LEN +
7954				  IEEE80211_CCK_PLCP_HDR_TIME;
7955		}
7956	}
7957	return txtime;
7958}
7959
7960int
7961bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
7962    struct ieee80211_node *ni)
7963{
7964	DPRINTF(2, "%s\n", __func__);
7965
7966	struct ieee80211com *ic = &sc->sc_ic;
7967	struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
7968	struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
7969	struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
7970	struct bwi_mac *mac;
7971	struct bwi_txbuf_hdr *hdr;
7972	struct ieee80211_frame *wh;
7973	uint8_t rate, rate_fb;
7974	uint32_t mac_ctrl;
7975	uint16_t phy_ctrl;
7976	bus_addr_t paddr;
7977	int pkt_len, error;
7978#if 0
7979	const uint8_t *p;
7980	int i;
7981#endif
7982
7983	KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
7984	mac = (struct bwi_mac *)sc->sc_cur_regwin;
7985
7986	wh = mtod(m, struct ieee80211_frame *);
7987
7988	/* Get 802.11 frame len before prepending TX header */
7989	pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN;
7990
7991	/*
7992	 * Find TX rate
7993	 */
7994	bzero(tb->tb_rate_idx, sizeof(tb->tb_rate_idx));
7995	if (ni != NULL) {
7996		if (ic->ic_fixed_rate != -1) {
7997			rate = ic->ic_sup_rates[ic->ic_curmode].
7998			    rs_rates[ic->ic_fixed_rate];
7999		} else {
8000			/* AMRR rate control */
8001			rate = rate_fb = ni->ni_rates.rs_rates[ni->ni_txrate];
8002		}
8003	} else {
8004		/* Fixed at 1Mbytes/s for mgt frames */
8005		rate = rate_fb = (1 * 2);
8006	}
8007
8008	rate &= IEEE80211_RATE_VAL;
8009
8010	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
8011		rate = rate_fb = (1 * 2);
8012
8013	if (rate == 0 || rate_fb == 0) {
8014		DPRINTF(1, "%s: invalid rate %u or fallback rate %u",
8015		    sc->sc_dev.dv_xname, rate, rate_fb);
8016		rate = rate_fb = (1 * 2); /* Force 1Mbytes/s */
8017	}
8018
8019#if NBPFILTER > 0
8020	/* TX radio tap */
8021	if (sc->sc_drvbpf != NULL) {
8022		struct mbuf mb;
8023		struct bwi_tx_radiotap_hdr *tap = &sc->sc_txtap;
8024
8025		tap->wt_flags = 0;
8026		tap->wt_rate = rate;
8027		tap->wt_chan_freq =
8028		    htole16(ic->ic_bss->ni_chan->ic_freq);
8029		tap->wt_chan_flags =
8030		    htole16(ic->ic_bss->ni_chan->ic_flags);
8031
8032		mb.m_data = (caddr_t)tap;
8033		mb.m_len = sc->sc_txtap_len;
8034		mb.m_next = m;
8035		mb.m_nextpkt = NULL;
8036		mb.m_type = 0;
8037		mb.m_flags = 0;
8038		bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
8039	}
8040#endif
8041
8042	/*
8043	 * Setup the embedded TX header
8044	 */
8045	M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
8046	if (m == NULL) {
8047		DPRINTF(1, "%s: prepend TX header failed\n",
8048		    sc->sc_dev.dv_xname);
8049		return (ENOBUFS);
8050	}
8051	hdr = mtod(m, struct bwi_txbuf_hdr *);
8052
8053	bzero(hdr, sizeof(*hdr));
8054
8055	bcopy(wh->i_fc, hdr->txh_fc, sizeof(hdr->txh_fc));
8056	bcopy(wh->i_addr1, hdr->txh_addr1, sizeof(hdr->txh_addr1));
8057
8058	if (ni != NULL && !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
8059		uint16_t dur;
8060		uint8_t ack_rate;
8061
8062		ack_rate = bwi_ack_rate(ni, rate_fb);
8063		dur = bwi_txtime(ic, ni,
8064		    sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN,
8065		    ack_rate, ic->ic_flags & ~IEEE80211_F_SHPREAMBLE);
8066
8067		hdr->txh_fb_duration = htole16(dur);
8068	}
8069
8070	hdr->txh_id = __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) |
8071	    __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK);
8072
8073	bwi_plcp_header(hdr->txh_plcp, pkt_len, rate);
8074	bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate_fb);
8075
8076	phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode,
8077	    BWI_TXH_PHY_C_ANTMODE_MASK);
8078	if (bwi_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM)
8079		phy_ctrl |= BWI_TXH_PHY_C_OFDM;
8080	else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (2 * 1))
8081		phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE;
8082
8083	mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG;
8084	if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
8085		mac_ctrl |= BWI_TXH_MAC_C_ACK;
8086	if (bwi_rate2modtype(rate_fb) == IEEE80211_MODTYPE_OFDM)
8087		mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM;
8088
8089	hdr->txh_mac_ctrl = htole32(mac_ctrl);
8090	hdr->txh_phy_ctrl = htole16(phy_ctrl);
8091
8092	/* Catch any further usage */
8093	hdr = NULL;
8094	wh = NULL;
8095
8096	/* DMA load */
8097	error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m,
8098	    BUS_DMA_NOWAIT);
8099	if (error && error != EFBIG) {
8100		DPRINTF(1, "%s: can't load TX buffer (1) %d\n",
8101		    sc->sc_dev.dv_xname, error);
8102		goto back;
8103	}
8104
8105	if (error) {	/* error == EFBIG */
8106		struct mbuf *m_new;
8107
8108		error = 0;
8109
8110		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
8111		if (m_new == NULL) {
8112			m_freem(m);
8113			error = ENOBUFS;
8114			printf("%s: can't defrag TX buffer\n",
8115			    sc->sc_dev.dv_xname);
8116			goto back;
8117		}
8118
8119		M_DUP_PKTHDR(m_new, m);
8120		if (m->m_pkthdr.len > MHLEN) {
8121			MCLGET(m_new, M_DONTWAIT);
8122			if (!(m_new->m_flags & M_EXT)) {
8123				m_freem(m);
8124				m_freem(m_new);
8125				error = ENOBUFS;
8126			}
8127		}
8128
8129		if (error) {
8130			printf("%s: can't defrag TX buffer\n",
8131			    sc->sc_dev.dv_xname);
8132			goto back;
8133		}
8134
8135		m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, caddr_t));
8136		m_freem(m);
8137		m_new->m_len = m_new->m_pkthdr.len;
8138		m = m_new;
8139
8140		error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m,
8141		    BUS_DMA_NOWAIT);
8142		if (error) {
8143			DPRINTF(1, "%s: can't load TX buffer (2) %d\n",
8144			    sc->sc_dev.dv_xname, error);
8145			goto back;
8146		}
8147	}
8148	error = 0;
8149
8150	bus_dmamap_sync(sc->sc_dmat, tb->tb_dmap, 0,
8151	    tb->tb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8152
8153	tb->tb_mbuf = m;
8154	tb->tb_ni = ni;
8155
8156#if 0
8157	p = mtod(m, const uint8_t *);
8158	for (i = 0; i < m->m_pkthdr.len; ++i) {
8159		if (i != 0 && i % 8 == 0)
8160			printf("\n");
8161		printf("%02x ", p[i]);
8162	}
8163	printf("\n");
8164
8165	DPRINTF(1, "%s: idx %d, pkt_len %d, buflen %d\n",
8166	    sc->sc_dev.dv_xname, idx, pkt_len, m->m_pkthdr.len);
8167#endif
8168
8169	/* Setup TX descriptor */
8170	paddr = tb->tb_dmap->dm_segs[0].ds_addr;
8171	sc->sc_setup_txdesc(sc, rd, idx, paddr, m->m_pkthdr.len);
8172	bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
8173	    rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
8174
8175	/* Kick start */
8176	sc->sc_start_tx(sc, rd->rdata_txrx_ctrl, idx);
8177
8178back:
8179	if (error)
8180		m_freem(m);
8181	return (error);
8182}
8183
8184void
8185bwi_start_tx32(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
8186{
8187	idx = (idx + 1) % BWI_TX_NDESC;
8188	CSR_WRITE_4(sc, tx_ctrl + BWI_TX32_INDEX,
8189	    idx * sizeof(struct bwi_desc32));
8190}
8191
8192void
8193bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
8194{
8195	/* TODO: 64 */
8196}
8197
8198void
8199bwi_txeof_status32(struct bwi_softc *sc)
8200{
8201	struct ifnet *ifp = &sc->sc_ic.ic_if;
8202	uint32_t val, ctrl_base;
8203	int end_idx;
8204
8205	ctrl_base = sc->sc_txstats->stats_ctrl_base;
8206
8207	val = CSR_READ_4(sc, ctrl_base + BWI_RX32_STATUS);
8208	end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
8209	    sizeof(struct bwi_desc32);
8210
8211	bwi_txeof_status(sc, end_idx);
8212
8213	CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
8214	    end_idx * sizeof(struct bwi_desc32));
8215
8216	if ((ifp->if_flags & IFF_OACTIVE) == 0)
8217		ifp->if_start(ifp);
8218}
8219
8220void
8221bwi_txeof_status64(struct bwi_softc *sc)
8222{
8223	/* TODO: 64 */
8224}
8225
8226void
8227_bwi_txeof(struct bwi_softc *sc, uint16_t tx_id)
8228{
8229	struct ieee80211com *ic = &sc->sc_ic;
8230	struct ifnet *ifp = &sc->sc_ic.ic_if;
8231	struct bwi_txbuf_data *tbd;
8232	struct bwi_txbuf *tb;
8233	int ring_idx, buf_idx;
8234
8235	if (tx_id == 0) {
8236		DPRINTF(1, "%s: zero tx id\n", sc->sc_dev.dv_xname);
8237		return;
8238	}
8239
8240	ring_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_RING_MASK);
8241	buf_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_IDX_MASK);
8242
8243	KKASSERT(ring_idx == BWI_TX_DATA_RING);
8244	KKASSERT(buf_idx < BWI_TX_NDESC);
8245#if 0
8246	DPRINTF(1, "%s: txeof idx %d\n", sc->sc_dev.dv_xname, buf_idx);
8247#endif
8248	tbd = &sc->sc_tx_bdata[ring_idx];
8249	KKASSERT(tbd->tbd_used > 0);
8250	tbd->tbd_used--;
8251
8252	tb = &tbd->tbd_buf[buf_idx];
8253
8254	bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap);
8255	m_freem(tb->tb_mbuf);
8256	tb->tb_mbuf = NULL;
8257
8258	if (tb->tb_ni != NULL) {
8259		ieee80211_release_node(ic, tb->tb_ni);
8260		tb->tb_ni = NULL;
8261	}
8262
8263	if (tbd->tbd_used == 0)
8264		sc->sc_tx_timer = 0;
8265
8266	ifp->if_flags &= ~IFF_OACTIVE;
8267}
8268
8269void
8270bwi_txeof_status(struct bwi_softc *sc, int end_idx)
8271{
8272	struct bwi_txstats_data *st = sc->sc_txstats;
8273	int idx;
8274
8275	bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,
8276	    st->stats_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
8277
8278	idx = st->stats_idx;
8279	while (idx != end_idx) {
8280		_bwi_txeof(sc, letoh16(st->stats[idx].txs_id));
8281		idx = (idx + 1) % BWI_TXSTATS_NDESC;
8282	}
8283	st->stats_idx = idx;
8284}
8285
8286void
8287bwi_txeof(struct bwi_softc *sc)
8288{
8289	struct ifnet *ifp = &sc->sc_ic.ic_if;
8290
8291	for (;;) {
8292		uint32_t tx_status0, tx_status1;
8293		uint16_t tx_id, tx_info;
8294
8295		tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0);
8296		if (tx_status0 == 0)
8297			break;
8298		tx_status1 = CSR_READ_4(sc, BWI_TXSTATUS_1);
8299
8300		tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK);
8301		tx_info = BWI_TXSTATUS_0_INFO(tx_status0);
8302
8303		if (tx_info & 0x30) /* XXX */
8304			continue;
8305
8306		_bwi_txeof(sc, letoh16(tx_id));
8307	}
8308
8309	if ((ifp->if_flags & IFF_OACTIVE) == 0)
8310		ifp->if_start(ifp);
8311}
8312
8313int
8314bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
8315{
8316	bwi_power_on(sc, 1);
8317
8318	return (bwi_set_clock_mode(sc, clk_mode));
8319}
8320
8321void
8322bwi_bbp_power_off(struct bwi_softc *sc)
8323{
8324	bwi_set_clock_mode(sc, BWI_CLOCK_MODE_SLOW);
8325	bwi_power_off(sc, 1);
8326}
8327
8328int
8329bwi_get_pwron_delay(struct bwi_softc *sc)
8330{
8331	struct bwi_regwin *com, *old;
8332	struct bwi_clock_freq freq;
8333	uint32_t val;
8334	int error;
8335
8336	com = &sc->sc_com_regwin;
8337	KKASSERT(BWI_REGWIN_EXIST(com));
8338
8339	if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
8340		return (0);
8341
8342	error = bwi_regwin_switch(sc, com, &old);
8343	if (error)
8344		return (error);
8345
8346	bwi_get_clock_freq(sc, &freq);
8347
8348	val = CSR_READ_4(sc, BWI_PLL_ON_DELAY);
8349	sc->sc_pwron_delay = howmany((val + 2) * 1000000, freq.clkfreq_min);
8350	DPRINTF(1, "%s: power on delay %u\n",
8351	    sc->sc_dev.dv_xname, sc->sc_pwron_delay);
8352
8353	return (bwi_regwin_switch(sc, old, NULL));
8354}
8355
8356int
8357bwi_bus_attach(struct bwi_softc *sc)
8358{
8359	struct bwi_regwin *bus, *old;
8360	int error;
8361
8362	bus = &sc->sc_bus_regwin;
8363
8364	error = bwi_regwin_switch(sc, bus, &old);
8365	if (error)
8366		return (error);
8367
8368	if (!bwi_regwin_is_enabled(sc, bus))
8369		bwi_regwin_enable(sc, bus, 0);
8370
8371	/* Disable interripts */
8372	CSR_WRITE_4(sc, BWI_INTRVEC, 0);
8373
8374	return (bwi_regwin_switch(sc, old, NULL));
8375}
8376
8377const char *
8378bwi_regwin_name(const struct bwi_regwin *rw)
8379{
8380	switch (rw->rw_type) {
8381	case BWI_REGWIN_T_COM:
8382		return ("COM");
8383	case BWI_REGWIN_T_BUSPCI:
8384		return ("PCI");
8385	case BWI_REGWIN_T_MAC:
8386		return ("MAC");
8387	case BWI_REGWIN_T_BUSPCIE:
8388		return ("PCIE");
8389	}
8390	panic("unknown regwin type 0x%04x\n", rw->rw_type);
8391
8392	return (NULL);
8393}
8394
8395uint32_t
8396bwi_regwin_disable_bits(struct bwi_softc *sc)
8397{
8398	uint32_t busrev;
8399
8400	/* XXX cache this */
8401	busrev = __SHIFTOUT(CSR_READ_4(sc, BWI_ID_LO), BWI_ID_LO_BUSREV_MASK);
8402	DPRINTF(1, "%s: bus rev %u\n", sc->sc_dev.dv_xname, busrev);
8403
8404	if (busrev == BWI_BUSREV_0)
8405		return (BWI_STATE_LO_DISABLE1);
8406	else if (busrev == BWI_BUSREV_1)
8407		return (BWI_STATE_LO_DISABLE2);
8408	else
8409		return ((BWI_STATE_LO_DISABLE1 | BWI_STATE_LO_DISABLE2));
8410}
8411
8412int
8413bwi_regwin_is_enabled(struct bwi_softc *sc, struct bwi_regwin *rw)
8414{
8415	uint32_t val, disable_bits;
8416
8417	disable_bits = bwi_regwin_disable_bits(sc);
8418	val = CSR_READ_4(sc, BWI_STATE_LO);
8419
8420	if ((val & (BWI_STATE_LO_CLOCK |
8421	    BWI_STATE_LO_RESET |
8422	    disable_bits)) == BWI_STATE_LO_CLOCK) {
8423		DPRINTF(1, "%s: %s is enabled\n",
8424		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
8425		return (1);
8426	} else {
8427		DPRINTF(1, "%s: %s is disabled\n",
8428		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
8429		return (0);
8430	}
8431}
8432
8433void
8434bwi_regwin_disable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
8435{
8436	uint32_t state_lo, disable_bits;
8437	int i;
8438
8439	state_lo = CSR_READ_4(sc, BWI_STATE_LO);
8440
8441	/*
8442	 * If current regwin is in 'reset' state, it was already disabled.
8443	 */
8444	if (state_lo & BWI_STATE_LO_RESET) {
8445		DPRINTF(1, "%s: %s was already disabled\n",
8446		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
8447		return;
8448	}
8449
8450	disable_bits = bwi_regwin_disable_bits(sc);
8451
8452	/*
8453	 * Disable normal clock
8454	 */
8455	state_lo = BWI_STATE_LO_CLOCK | disable_bits;
8456	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
8457
8458	/*
8459	 * Wait until normal clock is disabled
8460	 */
8461#define NRETRY	1000
8462	for (i = 0; i < NRETRY; ++i) {
8463		state_lo = CSR_READ_4(sc, BWI_STATE_LO);
8464		if (state_lo & disable_bits)
8465			break;
8466		DELAY(10);
8467	}
8468	if (i == NRETRY) {
8469		DPRINTF(1, "%s: %s disable clock timeout\n",
8470		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
8471	}
8472
8473	for (i = 0; i < NRETRY; ++i) {
8474		uint32_t state_hi;
8475
8476		state_hi = CSR_READ_4(sc, BWI_STATE_HI);
8477		if ((state_hi & BWI_STATE_HI_BUSY) == 0)
8478			break;
8479		DELAY(10);
8480	}
8481	if (i == NRETRY) {
8482		DPRINTF(1, "%s: %s wait BUSY unset timeout\n",
8483		    sc->sc_dev.dv_xname, bwi_regwin_name(rw));
8484	}
8485#undef NRETRY
8486
8487	/*
8488	 * Reset and disable regwin with gated clock
8489	 */
8490	state_lo = BWI_STATE_LO_RESET | disable_bits |
8491	    BWI_STATE_LO_CLOCK | BWI_STATE_LO_GATED_CLOCK |
8492	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
8493	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
8494
8495	/* Flush pending bus write */
8496	CSR_READ_4(sc, BWI_STATE_LO);
8497	DELAY(1);
8498
8499	/* Reset and disable regwin */
8500	state_lo = BWI_STATE_LO_RESET | disable_bits |
8501		   __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
8502	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
8503
8504	/* Flush pending bus write */
8505	CSR_READ_4(sc, BWI_STATE_LO);
8506	DELAY(1);
8507}
8508
8509void
8510bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
8511{
8512	uint32_t state_lo, state_hi, imstate;
8513
8514	bwi_regwin_disable(sc, rw, flags);
8515
8516	/* Reset regwin with gated clock */
8517	state_lo = BWI_STATE_LO_RESET |
8518	    BWI_STATE_LO_CLOCK |
8519	    BWI_STATE_LO_GATED_CLOCK |
8520	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
8521	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
8522
8523	/* Flush pending bus write */
8524	CSR_READ_4(sc, BWI_STATE_LO);
8525	DELAY(1);
8526
8527	state_hi = CSR_READ_4(sc, BWI_STATE_HI);
8528	if (state_hi & BWI_STATE_HI_SERROR)
8529		CSR_WRITE_4(sc, BWI_STATE_HI, 0);
8530
8531	imstate = CSR_READ_4(sc, BWI_IMSTATE);
8532	if (imstate & (BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT)) {
8533		imstate &= ~(BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT);
8534		CSR_WRITE_4(sc, BWI_IMSTATE, imstate);
8535	}
8536
8537	/* Enable regwin with gated clock */
8538	state_lo = BWI_STATE_LO_CLOCK |
8539	    BWI_STATE_LO_GATED_CLOCK |
8540	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
8541	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
8542
8543	/* Flush pending bus write */
8544	CSR_READ_4(sc, BWI_STATE_LO);
8545	DELAY(1);
8546
8547	/* Enable regwin with normal clock */
8548	state_lo = BWI_STATE_LO_CLOCK |
8549	    __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
8550	CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
8551
8552	/* Flush pending bus write */
8553	CSR_READ_4(sc, BWI_STATE_LO);
8554	DELAY(1);
8555}
8556
8557void
8558bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid)
8559{
8560	struct ieee80211com *ic = &sc->sc_ic;
8561	struct bwi_mac *mac;
8562	struct bwi_myaddr_bssid buf;
8563	const uint8_t *p;
8564	uint32_t val;
8565	int n, i;
8566
8567	KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
8568	mac = (struct bwi_mac *)sc->sc_cur_regwin;
8569
8570	bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid);
8571
8572	bcopy(ic->ic_myaddr, buf.myaddr, sizeof(buf.myaddr));
8573	bcopy(bssid, buf.bssid, sizeof(buf.bssid));
8574
8575	n = sizeof(buf) / sizeof(val);
8576	p = (const uint8_t *)&buf;
8577	for (i = 0; i < n; ++i) {
8578		int j;
8579
8580		val = 0;
8581		for (j = 0; j < sizeof(val); ++j)
8582			val |= ((uint32_t)(*p++)) << (j * 8);
8583
8584		TMPLT_WRITE_4(mac, 0x20 + (i * sizeof(val)), val);
8585	}
8586}
8587
8588void
8589bwi_updateslot(struct ieee80211com *ic)
8590{
8591	struct bwi_softc *sc = ic->ic_if.if_softc;
8592	struct bwi_mac *mac;
8593	struct ifnet *ifp = &ic->ic_if;
8594
8595	if ((ifp->if_flags & IFF_RUNNING) == 0)
8596		return;
8597
8598	DPRINTF(2, "%s\n", __func__);
8599
8600	KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
8601	mac = (struct bwi_mac *)sc->sc_cur_regwin;
8602
8603	bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT));
8604}
8605
8606void
8607bwi_calibrate(void *xsc)
8608{
8609	struct bwi_softc *sc = xsc;
8610	struct ieee80211com *ic = &sc->sc_ic;
8611	int s;
8612
8613	s = splnet();
8614
8615	if (ic->ic_state == IEEE80211_S_RUN) {
8616		struct bwi_mac *mac;
8617
8618		KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
8619		mac = (struct bwi_mac *)sc->sc_cur_regwin;
8620
8621		if (ic->ic_opmode != IEEE80211_M_MONITOR)
8622			bwi_mac_calibrate_txpower(mac);
8623
8624		/* XXX 15 seconds */
8625		timeout_add(&sc->sc_calib_ch, hz * 15);
8626	}
8627
8628	splx(s);
8629}
8630