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