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