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