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