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