File: | dev/ic/bwi.c |
Warning: | line 7935, column 2 Value stored to 'ntx' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: bwi.c,v 1.134 2023/11/10 15:51:20 bluhm Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 2007 The DragonFly Project. All rights reserved. |
5 | * |
6 | * This code is derived from software contributed to The DragonFly Project |
7 | * by Sepherosa Ziehau <sepherosa@gmail.com> |
8 | * |
9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions |
11 | * are met: |
12 | * |
13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in |
17 | * the documentation and/or other materials provided with the |
18 | * distribution. |
19 | * 3. Neither the name of The DragonFly Project nor the names of its |
20 | * contributors may be used to endorse or promote products derived |
21 | * from this software without specific, prior written permission. |
22 | * |
23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
28 | * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, |
29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
31 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
32 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
33 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
34 | * SUCH DAMAGE. |
35 | * |
36 | * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.1 2007/09/08 06:15:54 sephe Exp $ |
37 | */ |
38 | |
39 | #include "bpfilter.h" |
40 | |
41 | #include <sys/param.h> |
42 | |
43 | #include <sys/device.h> |
44 | #include <sys/kernel.h> |
45 | #include <sys/malloc.h> |
46 | #include <sys/mbuf.h> |
47 | #include <sys/socket.h> |
48 | #include <sys/sockio.h> |
49 | #include <sys/systm.h> |
50 | #include <sys/endian.h> |
51 | |
52 | #include <machine/bus.h> |
53 | #include <machine/intr.h> |
54 | |
55 | #include <net/if.h> |
56 | #include <net/if_dl.h> |
57 | #include <net/if_media.h> |
58 | |
59 | #if NBPFILTER1 > 0 |
60 | #include <net/bpf.h> |
61 | #endif |
62 | |
63 | #include <netinet/in.h> |
64 | #include <netinet/if_ether.h> |
65 | |
66 | #include <net80211/ieee80211_var.h> |
67 | #include <net80211/ieee80211_amrr.h> |
68 | #include <net80211/ieee80211_radiotap.h> |
69 | |
70 | #include <dev/ic/bwireg.h> |
71 | #include <dev/ic/bwivar.h> |
72 | |
73 | #include <uvm/uvm_extern.h> |
74 | |
75 | #ifdef BWI_DEBUG |
76 | int bwi_debug = 1; |
77 | #define DPRINTF(l, x...) do { if ((l) <= bwi_debug) printf(x); } while (0) |
78 | #else |
79 | #define DPRINTF(l, x...) |
80 | #endif |
81 | |
82 | /* XXX temporary porting goop */ |
83 | #include <dev/pci/pcireg.h> |
84 | #include <dev/pci/pcidevs.h> |
85 | |
86 | /* XXX does not belong here */ |
87 | #define IEEE80211_OFDM_PLCP_RATE_MASK0x0000000f 0x0000000f |
88 | #define IEEE80211_OFDM_PLCP_LEN_MASK0x0001ffe0 0x0001ffe0 |
89 | |
90 | /* |
91 | * Contention window (slots). |
92 | */ |
93 | #define IEEE80211_CW_MAX1023 1023 /* aCWmax */ |
94 | #define IEEE80211_CW_MIN_031 31 /* DS/CCK aCWmin, ERP aCWmin(0) */ |
95 | #define IEEE80211_CW_MIN_115 15 /* OFDM aCWmin, ERP aCWmin(1) */ |
96 | |
97 | #define __unused__attribute__((__unused__)) __attribute__((__unused__)) |
98 | |
99 | extern int ticks; |
100 | |
101 | /* XXX end porting goop */ |
102 | |
103 | /* MAC */ |
104 | struct bwi_retry_lim { |
105 | uint16_t shretry; |
106 | uint16_t shretry_fb; |
107 | uint16_t lgretry; |
108 | uint16_t lgretry_fb; |
109 | }; |
110 | |
111 | struct bwi_clock_freq { |
112 | uint clkfreq_min; |
113 | uint clkfreq_max; |
114 | }; |
115 | |
116 | /* XXX does not belong here */ |
117 | struct ieee80211_ds_plcp_hdr { |
118 | uint8_t i_signal; |
119 | uint8_t i_service; |
120 | uint16_t i_length; |
121 | uint16_t i_crc; |
122 | } __packed__attribute__((__packed__)); |
123 | |
124 | enum bwi_modtype { |
125 | IEEE80211_MODTYPE_DS = 0, /* DS/CCK modulation */ |
126 | IEEE80211_MODTYPE_PBCC = 1, /* PBCC modulation */ |
127 | IEEE80211_MODTYPE_OFDM = 2 /* OFDM modulation */ |
128 | }; |
129 | #define IEEE80211_MODTYPE_CCKIEEE80211_MODTYPE_DS IEEE80211_MODTYPE_DS |
130 | |
131 | /* MAC */ |
132 | void bwi_tmplt_write_4(struct bwi_mac *, uint32_t, uint32_t); |
133 | void bwi_hostflags_write(struct bwi_mac *, uint64_t); |
134 | uint64_t bwi_hostflags_read(struct bwi_mac *); |
135 | uint16_t bwi_memobj_read_2(struct bwi_mac *, uint16_t, uint16_t); |
136 | uint32_t bwi_memobj_read_4(struct bwi_mac *, uint16_t, uint16_t); |
137 | void bwi_memobj_write_2(struct bwi_mac *, uint16_t, uint16_t, |
138 | uint16_t); |
139 | void bwi_memobj_write_4(struct bwi_mac *, uint16_t, uint16_t, |
140 | uint32_t); |
141 | int bwi_mac_lateattach(struct bwi_mac *); |
142 | int bwi_mac_init(struct bwi_mac *); |
143 | void bwi_mac_reset(struct bwi_mac *, int); |
144 | void bwi_mac_set_tpctl_11bg(struct bwi_mac *, |
145 | const struct bwi_tpctl *); |
146 | int bwi_mac_test(struct bwi_mac *); |
147 | void bwi_mac_setup_tpctl(struct bwi_mac *); |
148 | void bwi_mac_dummy_xmit(struct bwi_mac *); |
149 | void bwi_mac_init_tpctl_11bg(struct bwi_mac *); |
150 | void bwi_mac_detach(struct bwi_mac *); |
151 | int bwi_get_firmware(const char *, const uint8_t *, size_t, |
152 | size_t *, size_t *); |
153 | int bwi_fwimage_is_valid(struct bwi_softc *, uint8_t *, |
154 | size_t, char *, uint8_t); |
155 | int bwi_mac_fw_alloc(struct bwi_mac *); |
156 | void bwi_mac_fw_free(struct bwi_mac *); |
157 | int bwi_mac_fw_load(struct bwi_mac *); |
158 | int bwi_mac_gpio_init(struct bwi_mac *); |
159 | int bwi_mac_gpio_fini(struct bwi_mac *); |
160 | int bwi_mac_fw_load_iv(struct bwi_mac *, uint8_t *, size_t); |
161 | int bwi_mac_fw_init(struct bwi_mac *); |
162 | void bwi_mac_opmode_init(struct bwi_mac *); |
163 | void bwi_mac_hostflags_init(struct bwi_mac *); |
164 | void bwi_mac_bss_param_init(struct bwi_mac *); |
165 | void bwi_mac_set_retry_lim(struct bwi_mac *, |
166 | const struct bwi_retry_lim *); |
167 | void bwi_mac_set_ackrates(struct bwi_mac *, |
168 | const struct ieee80211_rateset *); |
169 | int bwi_mac_start(struct bwi_mac *); |
170 | int bwi_mac_stop(struct bwi_mac *); |
171 | int bwi_mac_config_ps(struct bwi_mac *); |
172 | void bwi_mac_reset_hwkeys(struct bwi_mac *); |
173 | void bwi_mac_shutdown(struct bwi_mac *); |
174 | int bwi_mac_get_property(struct bwi_mac *); |
175 | void bwi_mac_updateslot(struct bwi_mac *, int); |
176 | int bwi_mac_attach(struct bwi_softc *, int, uint8_t); |
177 | void bwi_mac_balance_atten(int *, int *); |
178 | void bwi_mac_adjust_tpctl(struct bwi_mac *, int, int); |
179 | void bwi_mac_calibrate_txpower(struct bwi_mac *, |
180 | enum bwi_txpwrcb_type); |
181 | void bwi_mac_lock(struct bwi_mac *); |
182 | void bwi_mac_unlock(struct bwi_mac *); |
183 | void bwi_mac_set_promisc(struct bwi_mac *, int); |
184 | |
185 | /* PHY */ |
186 | void bwi_phy_write(struct bwi_mac *, uint16_t, uint16_t); |
187 | uint16_t bwi_phy_read(struct bwi_mac *, uint16_t); |
188 | int bwi_phy_attach(struct bwi_mac *); |
189 | void bwi_phy_set_bbp_atten(struct bwi_mac *, uint16_t); |
190 | int bwi_phy_calibrate(struct bwi_mac *); |
191 | void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t); |
192 | void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t); |
193 | void bwi_nrssi_write(struct bwi_mac *, uint16_t, int16_t); |
194 | int16_t bwi_nrssi_read(struct bwi_mac *, uint16_t); |
195 | void bwi_phy_init_11a(struct bwi_mac *); |
196 | void bwi_phy_init_11g(struct bwi_mac *); |
197 | void bwi_phy_init_11b_rev2(struct bwi_mac *); |
198 | void bwi_phy_init_11b_rev4(struct bwi_mac *); |
199 | void bwi_phy_init_11b_rev5(struct bwi_mac *); |
200 | void bwi_phy_init_11b_rev6(struct bwi_mac *); |
201 | void bwi_phy_config_11g(struct bwi_mac *); |
202 | void bwi_phy_config_agc(struct bwi_mac *); |
203 | void bwi_set_gains(struct bwi_mac *, const struct bwi_gains *); |
204 | void bwi_phy_clear_state(struct bwi_phy *); |
205 | |
206 | /* RF */ |
207 | int16_t bwi_nrssi_11g(struct bwi_mac *); |
208 | struct bwi_rf_lo |
209 | *bwi_get_rf_lo(struct bwi_mac *, uint16_t, uint16_t); |
210 | int bwi_rf_lo_isused(struct bwi_mac *, const struct bwi_rf_lo *); |
211 | void bwi_rf_write(struct bwi_mac *, uint16_t, uint16_t); |
212 | uint16_t bwi_rf_read(struct bwi_mac *, uint16_t); |
213 | int bwi_rf_attach(struct bwi_mac *); |
214 | void bwi_rf_set_chan(struct bwi_mac *, uint, int); |
215 | void bwi_rf_get_gains(struct bwi_mac *); |
216 | void bwi_rf_init(struct bwi_mac *); |
217 | void bwi_rf_off_11a(struct bwi_mac *); |
218 | void bwi_rf_off_11bg(struct bwi_mac *); |
219 | void bwi_rf_off_11g_rev5(struct bwi_mac *); |
220 | void bwi_rf_workaround(struct bwi_mac *, uint); |
221 | struct bwi_rf_lo |
222 | *bwi_rf_lo_find(struct bwi_mac *, const struct bwi_tpctl *); |
223 | void bwi_rf_lo_adjust(struct bwi_mac *, const struct bwi_tpctl *); |
224 | void bwi_rf_lo_write(struct bwi_mac *, const struct bwi_rf_lo *); |
225 | int bwi_rf_gain_max_reached(struct bwi_mac *, int); |
226 | uint16_t bwi_bitswap4(uint16_t); |
227 | uint16_t bwi_phy812_value(struct bwi_mac *, uint16_t); |
228 | void bwi_rf_init_bcm2050(struct bwi_mac *); |
229 | uint16_t bwi_rf_calibval(struct bwi_mac *); |
230 | int32_t _bwi_adjust_devide(int32_t, int32_t); |
231 | int bwi_rf_calc_txpower(int8_t *, uint8_t, const int16_t[]); |
232 | int bwi_rf_map_txpower(struct bwi_mac *); |
233 | void bwi_rf_lo_update_11g(struct bwi_mac *); |
234 | uint32_t bwi_rf_lo_devi_measure(struct bwi_mac *, uint16_t); |
235 | uint16_t bwi_rf_get_tp_ctrl2(struct bwi_mac *); |
236 | uint8_t _bwi_rf_lo_update_11g(struct bwi_mac *, uint16_t); |
237 | void bwi_rf_lo_measure_11g(struct bwi_mac *, |
238 | const struct bwi_rf_lo *, struct bwi_rf_lo *, uint8_t); |
239 | void bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *); |
240 | void bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *); |
241 | void bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *); |
242 | void bwi_rf_init_sw_nrssi_table(struct bwi_mac *); |
243 | void bwi_rf_init_hw_nrssi_table(struct bwi_mac *, uint16_t); |
244 | void bwi_rf_set_nrssi_thr_11b(struct bwi_mac *); |
245 | int32_t _nrssi_threshold(const struct bwi_rf *, int32_t); |
246 | void bwi_rf_set_nrssi_thr_11g(struct bwi_mac *); |
247 | void bwi_rf_clear_tssi(struct bwi_mac *); |
248 | void bwi_rf_clear_state(struct bwi_rf *); |
249 | void bwi_rf_on_11a(struct bwi_mac *); |
250 | void bwi_rf_on_11bg(struct bwi_mac *); |
251 | void bwi_rf_set_ant_mode(struct bwi_mac *, int); |
252 | int bwi_rf_get_latest_tssi(struct bwi_mac *, int8_t[], uint16_t); |
253 | int bwi_rf_tssi2dbm(struct bwi_mac *, int8_t, int8_t *); |
254 | int bwi_rf_calc_rssi_bcm2050(struct bwi_mac *, |
255 | const struct bwi_rxbuf_hdr *); |
256 | int bwi_rf_calc_rssi_bcm2053(struct bwi_mac *, |
257 | const struct bwi_rxbuf_hdr *); |
258 | int bwi_rf_calc_rssi_bcm2060(struct bwi_mac *, |
259 | const struct bwi_rxbuf_hdr *); |
260 | uint16_t bwi_rf_lo_measure_11b(struct bwi_mac *); |
261 | void bwi_rf_lo_update_11b(struct bwi_mac *); |
262 | |
263 | /* INTERFACE */ |
264 | uint16_t bwi_read_sprom(struct bwi_softc *, uint16_t); |
265 | void bwi_setup_desc32(struct bwi_softc *, struct bwi_desc32 *, int, |
266 | int, bus_addr_t, int, int); |
267 | void bwi_power_on(struct bwi_softc *, int); |
268 | int bwi_power_off(struct bwi_softc *, int); |
269 | int bwi_regwin_switch(struct bwi_softc *, struct bwi_regwin *, |
270 | struct bwi_regwin **); |
271 | int bwi_regwin_select(struct bwi_softc *, int); |
272 | void bwi_regwin_info(struct bwi_softc *, uint16_t *, uint8_t *); |
273 | void bwi_led_attach(struct bwi_softc *); |
274 | void bwi_led_newstate(struct bwi_softc *, enum ieee80211_state); |
275 | uint16_t bwi_led_onoff(struct bwi_led *, uint16_t, int); |
276 | void bwi_led_event(struct bwi_softc *, int); |
277 | void bwi_led_blink_start(struct bwi_softc *, int, int); |
278 | void bwi_led_blink_next(void *); |
279 | void bwi_led_blink_end(void *); |
280 | int bwi_bbp_attach(struct bwi_softc *); |
281 | int bwi_bus_init(struct bwi_softc *, struct bwi_mac *); |
282 | void bwi_get_card_flags(struct bwi_softc *); |
283 | void bwi_get_eaddr(struct bwi_softc *, uint16_t, uint8_t *); |
284 | void bwi_get_clock_freq(struct bwi_softc *, |
285 | struct bwi_clock_freq *); |
286 | int bwi_set_clock_mode(struct bwi_softc *, enum bwi_clock_mode); |
287 | int bwi_set_clock_delay(struct bwi_softc *); |
288 | int bwi_ioctl(struct ifnet *, u_long, caddr_t); |
289 | void bwi_start(struct ifnet *); |
290 | void bwi_watchdog(struct ifnet *); |
291 | void bwi_newstate_begin(struct bwi_softc *, enum ieee80211_state); |
292 | void bwi_init_statechg(struct bwi_softc *, int); |
293 | int bwi_newstate(struct ieee80211com *, enum ieee80211_state, int); |
294 | int bwi_media_change(struct ifnet *); |
295 | void bwi_iter_func(void *, struct ieee80211_node *); |
296 | void bwi_amrr_timeout(void *); |
297 | void bwi_newassoc(struct ieee80211com *, struct ieee80211_node *, |
298 | int); |
299 | struct ieee80211_node |
300 | *bwi_node_alloc(struct ieee80211com *ic); |
301 | int bwi_dma_alloc(struct bwi_softc *); |
302 | void bwi_dma_free(struct bwi_softc *); |
303 | int bwi_dma_ring_alloc(struct bwi_softc *, |
304 | struct bwi_ring_data *, bus_size_t, uint32_t); |
305 | int bwi_dma_txstats_alloc(struct bwi_softc *, uint32_t, |
306 | bus_size_t); |
307 | void bwi_dma_txstats_free(struct bwi_softc *); |
308 | int bwi_dma_mbuf_create30(struct bwi_softc *); |
309 | int bwi_dma_mbuf_create(struct bwi_softc *); |
310 | void bwi_dma_mbuf_destroy(struct bwi_softc *, int, int); |
311 | void bwi_enable_intrs(struct bwi_softc *, uint32_t); |
312 | void bwi_disable_intrs(struct bwi_softc *, uint32_t); |
313 | int bwi_init_tx_ring32(struct bwi_softc *, int); |
314 | void bwi_init_rxdesc_ring32(struct bwi_softc *, uint32_t, |
315 | bus_addr_t, int, int); |
316 | int bwi_init_rx_ring32(struct bwi_softc *); |
317 | int bwi_init_txstats32(struct bwi_softc *); |
318 | void bwi_setup_rx_desc32(struct bwi_softc *, int, bus_addr_t, int); |
319 | void bwi_setup_tx_desc32(struct bwi_softc *, struct bwi_ring_data *, |
320 | int, bus_addr_t, int); |
321 | int bwi_newbuf30(struct bwi_softc *, int, int); |
322 | int bwi_newbuf(struct bwi_softc *, int, int); |
323 | void bwi_set_addr_filter(struct bwi_softc *, uint16_t, |
324 | const uint8_t *); |
325 | int bwi_set_chan(struct bwi_softc *, uint8_t); |
326 | void bwi_next_scan(void *); |
327 | int bwi_rxeof(struct bwi_softc *, int); |
328 | int bwi_rxeof32(struct bwi_softc *); |
329 | void bwi_reset_rx_ring32(struct bwi_softc *, uint32_t); |
330 | void bwi_free_txstats32(struct bwi_softc *); |
331 | void bwi_free_rx_ring32(struct bwi_softc *); |
332 | void bwi_free_tx_ring32(struct bwi_softc *, int); |
333 | uint8_t bwi_plcp2rate(uint32_t, enum ieee80211_phymode); |
334 | void bwi_ofdm_plcp_header(uint32_t *, int, uint8_t); |
335 | void bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *, int, |
336 | uint8_t); |
337 | void bwi_plcp_header(void *, int, uint8_t); |
338 | int bwi_encap(struct bwi_softc *, int, struct mbuf *, |
339 | struct ieee80211_node *); |
340 | void bwi_start_tx32(struct bwi_softc *, uint32_t, int); |
341 | void bwi_txeof_status32(struct bwi_softc *); |
342 | void _bwi_txeof(struct bwi_softc *, uint16_t); |
343 | void bwi_txeof_status(struct bwi_softc *, int); |
344 | void bwi_txeof(struct bwi_softc *); |
345 | int bwi_bbp_power_on(struct bwi_softc *, enum bwi_clock_mode); |
346 | void bwi_bbp_power_off(struct bwi_softc *); |
347 | int bwi_get_pwron_delay(struct bwi_softc *sc); |
348 | int bwi_bus_attach(struct bwi_softc *); |
349 | const char *bwi_regwin_name(const struct bwi_regwin *); |
350 | int bwi_regwin_is_enabled(struct bwi_softc *, struct bwi_regwin *); |
351 | uint32_t bwi_regwin_disable_bits(struct bwi_softc *); |
352 | void bwi_regwin_enable(struct bwi_softc *, struct bwi_regwin *, |
353 | uint32_t); |
354 | void bwi_regwin_disable(struct bwi_softc *, struct bwi_regwin *, |
355 | uint32_t); |
356 | void bwi_set_bssid(struct bwi_softc *, const uint8_t *); |
357 | void bwi_updateslot(struct ieee80211com *); |
358 | void bwi_calibrate(void *); |
359 | int bwi_calc_rssi(struct bwi_softc *, |
360 | const struct bwi_rxbuf_hdr *); |
361 | uint8_t bwi_ack_rate(struct ieee80211_node *, uint8_t); |
362 | uint16_t bwi_txtime(struct ieee80211com *, struct ieee80211_node *, |
363 | uint, uint8_t, uint32_t); |
364 | enum bwi_modtype |
365 | bwi_rate2modtype(uint8_t); |
366 | |
367 | |
368 | static const uint8_t bwi_sup_macrev[] = { 2, 4, 5, 6, 7, 9, 10 }; |
369 | |
370 | #define SUP_BPHY(num) { .rev = num, .init = bwi_phy_init_11b_rev##num } |
371 | |
372 | static const struct { |
373 | uint8_t rev; |
374 | void (*init)(struct bwi_mac *); |
375 | } bwi_sup_bphy[] = { |
376 | SUP_BPHY(2), |
377 | SUP_BPHY(4), |
378 | SUP_BPHY(5), |
379 | SUP_BPHY(6) |
380 | }; |
381 | |
382 | #undef SUP_BPHY |
383 | |
384 | #define BWI_PHYTBL_WRSSI0x1000 0x1000 |
385 | #define BWI_PHYTBL_NOISE_SCALE0x1400 0x1400 |
386 | #define BWI_PHYTBL_NOISE0x1800 0x1800 |
387 | #define BWI_PHYTBL_ROTOR0x2000 0x2000 |
388 | #define BWI_PHYTBL_DELAY0x2400 0x2400 |
389 | #define BWI_PHYTBL_RSSI0x4000 0x4000 |
390 | #define BWI_PHYTBL_SIGMA_SQ0x5000 0x5000 |
391 | #define BWI_PHYTBL_WRSSI_REV10x5400 0x5400 |
392 | #define BWI_PHYTBL_FREQ0x5800 0x5800 |
393 | |
394 | static const uint16_t bwi_phy_freq_11g_rev1[] = |
395 | { BWI_PHY_FREQ_11G_REV10x0089, 0x02e9, 0x0409, 0x04e9, 0x05a9, 0x0669, 0x0709, 0x0789 , 0x0829, 0x08a9, 0x0929, 0x0989, 0x0a09, 0x0a69, 0x0ac9, 0x0b29 , 0x0ba9, 0x0be9, 0x0c49, 0x0ca9, 0x0d09, 0x0d69, 0x0da9, 0x0e09 , 0x0e69, 0x0ea9, 0x0f09, 0x0f49, 0x0fa9, 0x0fe9, 0x1029, 0x1089 , 0x10c9, 0x1109, 0x1169, 0x11a9, 0x11e9, 0x1229, 0x1289, 0x12c9 , 0x1309, 0x1349, 0x1389, 0x13c9, 0x1409, 0x1449, 0x14a9, 0x14e9 , 0x1529, 0x1569, 0x15a9, 0x15e9, 0x1629, 0x1669, 0x16a9, 0x16e8 , 0x1728, 0x1768, 0x17a8, 0x17e8, 0x1828, 0x1868, 0x18a8, 0x18e8 , 0x1928, 0x1968, 0x19a8, 0x19e8, 0x1a28, 0x1a68, 0x1aa8, 0x1ae8 , 0x1b28, 0x1b68, 0x1ba8, 0x1be8, 0x1c28, 0x1c68, 0x1ca8, 0x1ce8 , 0x1d28, 0x1d68, 0x1dc8, 0x1e08, 0x1e48, 0x1e88, 0x1ec8, 0x1f08 , 0x1f48, 0x1f88, 0x1fe8, 0x2028, 0x2068, 0x20a8, 0x2108, 0x2148 , 0x2188, 0x21c8, 0x2228, 0x2268, 0x22c8, 0x2308, 0x2348, 0x23a8 , 0x23e8, 0x2448, 0x24a8, 0x24e8, 0x2548, 0x25a8, 0x2608, 0x2668 , 0x26c8, 0x2728, 0x2787, 0x27e7, 0x2847, 0x28c7, 0x2947, 0x29a7 , 0x2a27, 0x2ac7, 0x2b47, 0x2be7, 0x2ca7, 0x2d67, 0x2e47, 0x2f67 , 0x3247, 0x3526, 0x3646, 0x3726, 0x3806, 0x38a6, 0x3946, 0x39e6 , 0x3a66, 0x3ae6, 0x3b66, 0x3bc6, 0x3c45, 0x3ca5, 0x3d05, 0x3d85 , 0x3de5, 0x3e45, 0x3ea5, 0x3ee5, 0x3f45, 0x3fa5, 0x4005, 0x4045 , 0x40a5, 0x40e5, 0x4145, 0x4185, 0x41e5, 0x4225, 0x4265, 0x42c5 , 0x4305, 0x4345, 0x43a5, 0x43e5, 0x4424, 0x4464, 0x44c4, 0x4504 , 0x4544, 0x4584, 0x45c4, 0x4604, 0x4644, 0x46a4, 0x46e4, 0x4724 , 0x4764, 0x47a4, 0x47e4, 0x4824, 0x4864, 0x48a4, 0x48e4, 0x4924 , 0x4964, 0x49a4, 0x49e4, 0x4a24, 0x4a64, 0x4aa4, 0x4ae4, 0x4b23 , 0x4b63, 0x4ba3, 0x4be3, 0x4c23, 0x4c63, 0x4ca3, 0x4ce3, 0x4d23 , 0x4d63, 0x4da3, 0x4de3, 0x4e23, 0x4e63, 0x4ea3, 0x4ee3, 0x4f23 , 0x4f63, 0x4fc3, 0x5003, 0x5043, 0x5083, 0x50c3, 0x5103, 0x5143 , 0x5183, 0x51e2, 0x5222, 0x5262, 0x52a2, 0x52e2, 0x5342, 0x5382 , 0x53c2, 0x5402, 0x5462, 0x54a2, 0x5502, 0x5542, 0x55a2, 0x55e2 , 0x5642, 0x5682, 0x56e2, 0x5722, 0x5782, 0x57e1, 0x5841, 0x58a1 , 0x5901, 0x5961, 0x59c1, 0x5a21, 0x5aa1, 0x5b01, 0x5b81, 0x5be1 , 0x5c61, 0x5d01, 0x5d80, 0x5e20, 0x5ee0, 0x5fa0, 0x6080, 0x61c0 }; |
396 | static const uint16_t bwi_phy_noise_11g_rev1[] = |
397 | { BWI_PHY_NOISE_11G_REV10x013c, 0x01f5, 0x031a, 0x0631, 0x0001, 0x0001, 0x0001, 0x0001 }; |
398 | static const uint16_t bwi_phy_noise_11g[] = |
399 | { BWI_PHY_NOISE_11G0x5484, 0x3c40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; |
400 | static const uint32_t bwi_phy_rotor_11g_rev1[] = |
401 | { BWI_PHY_ROTOR_11G_REV10xfeb93ffd, 0xfec63ffd, 0xfed23ffd, 0xfedf3ffd, 0xfeec3ffe, 0xfef83ffe , 0xff053ffe, 0xff113ffe, 0xff1e3ffe, 0xff2a3fff, 0xff373fff, 0xff443fff, 0xff503fff, 0xff5d3fff, 0xff693fff, 0xff763fff, 0xff824000 , 0xff8f4000, 0xff9b4000, 0xffa84000, 0xffb54000, 0xffc14000, 0xffce4000, 0xffda4000, 0xffe74000, 0xfff34000, 0x00004000, 0x000d4000 , 0x00194000, 0x00264000, 0x00324000, 0x003f4000, 0x004b4000, 0x00584000, 0x00654000, 0x00714000, 0x007e4000, 0x008a3fff, 0x00973fff , 0x00a33fff, 0x00b03fff, 0x00bc3fff, 0x00c93fff, 0x00d63fff, 0x00e23ffe, 0x00ef3ffe, 0x00fb3ffe, 0x01083ffe, 0x01143ffe, 0x01213ffd , 0x012e3ffd, 0x013a3ffd, 0x01473ffd }; |
402 | static const uint16_t bwi_phy_noise_scale_11g_rev2[] = |
403 | { BWI_PHY_NOISE_SCALE_11G_REV20x6c77, 0x5162, 0x3b40, 0x3335, 0x2f2d, 0x2a2a, 0x2527, 0x1f21 , 0x1a1d, 0x1719, 0x1616, 0x1414, 0x1414, 0x1400, 0x1414, 0x1614 , 0x1716, 0x1a19, 0x1f1d, 0x2521, 0x2a27, 0x2f2a, 0x332d, 0x3b35 , 0x5140, 0x6c62, 0x0077 }; |
404 | static const uint16_t bwi_phy_noise_scale_11g_rev7[] = |
405 | { BWI_PHY_NOISE_SCALE_11G_REV70xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4 , 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4 , 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4 , 0xa4a4, 0xa4a4, 0x00a4 }; |
406 | static const uint16_t bwi_phy_noise_scale_11g[] = |
407 | { BWI_PHY_NOISE_SCALE_11G0xd8dd, 0xcbd4, 0xbcc0, 0xb6b7, 0xb2b0, 0xadad, 0xa7a9, 0x9fa1 , 0x969b, 0x9195, 0x8f8f, 0x8a8a, 0x8a8a, 0x8a00, 0x8a8a, 0x8f8a , 0x918f, 0x9695, 0x9f9b, 0xa7a1, 0xada9, 0xb2ad, 0xb6b0, 0xbcb7 , 0xcbc0, 0xd8d4, 0x00dd }; |
408 | static const uint16_t bwi_phy_sigma_sq_11g_rev2[] = |
409 | { BWI_PHY_SIGMA_SQ_11G_REV20x007a, 0x0075, 0x0071, 0x006c, 0x0067, 0x0063, 0x005e, 0x0059 , 0x0054, 0x0050, 0x004b, 0x0046, 0x0042, 0x003d, 0x003d, 0x003d , 0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003d , 0x003d, 0x003d, 0x0000, 0x003d, 0x003d, 0x003d, 0x003d, 0x003d , 0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003d, 0x003d , 0x0042, 0x0046, 0x004b, 0x0050, 0x0054, 0x0059, 0x005e, 0x0063 , 0x0067, 0x006c, 0x0071, 0x0075, 0x007a }; |
410 | static const uint16_t bwi_phy_sigma_sq_11g_rev7[] = |
411 | { BWI_PHY_SIGMA_SQ_11G_REV70x00de, 0x00dc, 0x00da, 0x00d8, 0x00d6, 0x00d4, 0x00d2, 0x00cf , 0x00cd, 0x00ca, 0x00c7, 0x00c4, 0x00c1, 0x00be, 0x00be, 0x00be , 0x00be, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be , 0x00be, 0x00be, 0x0000, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be , 0x00be, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be, 0x00be , 0x00c1, 0x00c4, 0x00c7, 0x00ca, 0x00cd, 0x00cf, 0x00d2, 0x00d4 , 0x00d6, 0x00d8, 0x00da, 0x00dc, 0x00de }; |
412 | static const uint32_t bwi_phy_delay_11g_rev1[] = |
413 | { BWI_PHY_DELAY_11G_REV10xdb93cb87, 0xd666cf64, 0xd1fdd358, 0xcda6d826, 0xca38dd9f, 0xc729e2b4 , 0xc469e88e, 0xc26aee2b, 0xc0def46c, 0xc073fa62, 0xc01d00d5, 0xc0760743, 0xc1560d1e, 0xc2e51369, 0xc4ed18ff, 0xc7ac1ed7, 0xcb2823b2 , 0xcefa28d9, 0xd2f62d3f, 0xd7bb3197, 0xdce53568, 0xe1fe3875, 0xe7d13b35, 0xed663d35, 0xf39b3ec4, 0xf98e3fa7, 0x00004000, 0x06723fa7 , 0x0c653ec4, 0x129a3d35, 0x182f3b35, 0x1e023875, 0x231b3568, 0x28453197, 0x2d0a2d3f, 0x310628d9, 0x34d823b2, 0x38541ed7, 0x3b1318ff , 0x3d1b1369, 0x3eaa0d1e, 0x3f8a0743, 0x3fe300d5, 0x3f8dfa62, 0x3f22f46c, 0x3d96ee2b, 0x3b97e88e, 0x38d7e2b4, 0x35c8dd9f, 0x325ad826 , 0x2e03d358, 0x299acf64, 0x246dcb87 }; |
414 | |
415 | /* RF */ |
416 | #define RF_LO_WRITE(mac, lo)bwi_rf_lo_write((mac), (lo)) bwi_rf_lo_write((mac), (lo)) |
417 | |
418 | #define BWI_RF_2GHZ_CHAN(chan)(ieee80211_ieee2mhz((chan), 0x0080) - 2400) \ |
419 | (ieee80211_ieee2mhz((chan), IEEE80211_CHAN_2GHZ0x0080) - 2400) |
420 | |
421 | #define BWI_DEFAULT_IDLE_TSSI52 52 |
422 | |
423 | struct rf_saveregs { |
424 | uint16_t phy_01; |
425 | uint16_t phy_03; |
426 | uint16_t phy_0a; |
427 | uint16_t phy_15; |
428 | uint16_t phy_2a; |
429 | uint16_t phy_30; |
430 | uint16_t phy_35; |
431 | uint16_t phy_60; |
432 | uint16_t phy_429; |
433 | uint16_t phy_802; |
434 | uint16_t phy_811; |
435 | uint16_t phy_812; |
436 | uint16_t phy_814; |
437 | uint16_t phy_815; |
438 | |
439 | uint16_t rf_43; |
440 | uint16_t rf_52; |
441 | uint16_t rf_7a; |
442 | }; |
443 | |
444 | #define SAVE_RF_REG(mac, regs, n)(regs)->rf_n = bwi_rf_read(((mac)), (0xn)) (regs)->rf_##n = RF_READ((mac), 0x##n)bwi_rf_read(((mac)), (0x##n)) |
445 | #define RESTORE_RF_REG(mac, regs, n)bwi_rf_write(((mac)), (0xn), ((regs)->rf_n)) RF_WRITE((mac), 0x##n, (regs)->rf_##n)bwi_rf_write(((mac)), (0x##n), ((regs)->rf_##n)) |
446 | |
447 | #define SAVE_PHY_REG(mac, regs, n)(regs)->phy_n = bwi_phy_read(((mac)), (0xn)) (regs)->phy_##n = PHY_READ((mac), 0x##n)bwi_phy_read(((mac)), (0x##n)) |
448 | #define RESTORE_PHY_REG(mac, regs, n)bwi_phy_write(((mac)), (0xn), ((regs)->phy_n)) PHY_WRITE((mac), 0x##n, (regs)->phy_##n)bwi_phy_write(((mac)), (0x##n), ((regs)->phy_##n)) |
449 | |
450 | static const int8_t bwi_txpower_map_11b[BWI_TSSI_MAX64] = |
451 | { BWI_TXPOWER_MAP_11B0x4d, 0x4c, 0x4b, 0x4a, 0x4a, 0x49, 0x48, 0x47, 0x47, 0x46, 0x45 , 0x45, 0x44, 0x43, 0x42, 0x42, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x32, 0x31 , 0x30, 0x2f, 0x2d, 0x2c, 0x2b, 0x29, 0x28, 0x26, 0x25, 0x23, 0x21, 0x1f, 0x1d, 0x1a, 0x17, 0x14, 0x10, 0x0c, 0x06, 0x00, - 7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7 }; |
452 | static const int8_t bwi_txpower_map_11g[BWI_TSSI_MAX64] = |
453 | { BWI_TXPOWER_MAP_11G77, 77, 77, 76, 76, 76, 75, 75, 74, 74, 73, 73, 73, 72, 72, 71 , 71, 70, 70, 69, 68, 68, 67, 67, 66, 65, 65, 64, 63, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 50, 49, 47, 45, 43, 40 , 37, 33, 28, 22, 14, 5, -7, -20, -20, -20, -20, -20, -20, -20 , -20, -20, -20 }; |
454 | |
455 | /* IF_BWI */ |
456 | |
457 | struct bwi_myaddr_bssid { |
458 | uint8_t myaddr[IEEE80211_ADDR_LEN6]; |
459 | uint8_t bssid[IEEE80211_ADDR_LEN6]; |
460 | } __packed__attribute__((__packed__)); |
461 | |
462 | #define IEEE80211_DS_PLCP_SERVICE_LOCKED0x04 0x04 |
463 | #define IEEE80211_DS_PLCL_SERVICE_PBCC0x08 0x08 |
464 | #define IEEE80211_DS_PLCP_SERVICE_LENEXT50x20 0x20 |
465 | #define IEEE80211_DS_PLCP_SERVICE_LENEXT60x40 0x40 |
466 | #define IEEE80211_DS_PLCP_SERVICE_LENEXT70x80 0x80 |
467 | |
468 | struct cfdriver bwi_cd = { |
469 | NULL((void *)0), "bwi", DV_IFNET |
470 | }; |
471 | |
472 | static const struct { |
473 | uint16_t did_min; |
474 | uint16_t did_max; |
475 | uint16_t bbp_id; |
476 | } bwi_bbpid_map[] = { |
477 | { 0x4301, 0x4301, 0x4301 }, |
478 | { 0x4305, 0x4307, 0x4307 }, |
479 | { 0x4402, 0x4403, 0x4402 }, |
480 | { 0x4610, 0x4615, 0x4610 }, |
481 | { 0x4710, 0x4715, 0x4710 }, |
482 | { 0x4720, 0x4725, 0x4309 } |
483 | }; |
484 | |
485 | static const struct { |
486 | uint16_t bbp_id; |
487 | int nregwin; |
488 | } bwi_regwin_count[] = { |
489 | { 0x4301, 5 }, |
490 | { 0x4306, 6 }, |
491 | { 0x4307, 5 }, |
492 | { 0x4310, 8 }, |
493 | { 0x4401, 3 }, |
494 | { 0x4402, 3 }, |
495 | { 0x4610, 9 }, |
496 | { 0x4704, 9 }, |
497 | { 0x4710, 9 }, |
498 | { 0x5365, 7 } |
499 | }; |
500 | |
501 | #define CLKSRC(src) \ |
502 | [BWI_CLKSRC_ ## src] = { \ |
503 | .freq_min = BWI_CLKSRC_ ##src## _FMIN, \ |
504 | .freq_max = BWI_CLKSRC_ ##src## _FMAX \ |
505 | } |
506 | |
507 | static const struct { |
508 | uint freq_min; |
509 | uint freq_max; |
510 | } bwi_clkfreq[BWI_CLKSRC_MAX3] = { |
511 | CLKSRC(LP_OSC), |
512 | CLKSRC(CS_OSC), |
513 | CLKSRC(PCI) |
514 | }; |
515 | |
516 | #undef CLKSRC |
517 | |
518 | #define VENDOR_LED_ACT(vendor) \ |
519 | { \ |
520 | .vid = PCI_VENDOR_##vendor, \ |
521 | .led_act = { BWI_VENDOR_LED_ACT_##vendor } \ |
522 | } |
523 | |
524 | const struct { |
525 | uint16_t vid; |
526 | uint8_t led_act[BWI_LED_MAX4]; |
527 | } bwi_vendor_led_act[] = { |
528 | VENDOR_LED_ACT(COMPAQ), |
529 | VENDOR_LED_ACT(LINKSYS) |
530 | }; |
531 | |
532 | const uint8_t bwi_default_led_act[BWI_LED_MAX4] = |
533 | { BWI_VENDOR_LED_ACT_DEFAULT2, 5, 4, 0 }; |
534 | |
535 | #undef VENDOR_LED_ACT |
536 | |
537 | const struct { |
538 | int on_dur; |
539 | int off_dur; |
540 | } bwi_led_duration[109] = { |
541 | { 400, 100 }, { 0, 0 }, { 150 , 75 }, { 0, 0 }, { 90, 45 }, |
542 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
543 | { 0, 0 }, { 66, 34 }, { 53, 26 }, { 0, 0 }, { 0, 0 }, |
544 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 42, 21 }, { 0, 0 }, |
545 | { 0, 0 }, { 0, 0 }, { 35, 17 }, { 0, 0 }, { 32, 16 }, |
546 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
547 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
548 | { 0, 0 }, { 21, 10 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
549 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
550 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 16, 8 }, { 0, 0 }, |
551 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
552 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
553 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
554 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
555 | { 0, 0 }, { 0, 0 }, { 11, 5 }, { 0, 0 }, { 0, 0 }, |
556 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
557 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
558 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
559 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
560 | { 0, 0 }, { 9, 4 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
561 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, |
562 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 7, 3 } |
563 | }; |
564 | |
565 | static const uint8_t bwi_zero_addr[IEEE80211_ADDR_LEN6]; |
566 | |
567 | |
568 | /* CODE */ |
569 | |
570 | int |
571 | bwi_intr(void *xsc) |
572 | { |
573 | struct bwi_softc *sc = xsc; |
574 | struct bwi_mac *mac; |
575 | struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if; |
576 | uint32_t intr_status; |
577 | uint32_t txrx_intr_status[BWI_TXRX_NRING6]; |
578 | int i, txrx_error, tx = 0, rx_data = -1; |
579 | |
580 | if ((ifp->if_flags & IFF_RUNNING0x40) == 0) |
581 | return (0); |
582 | |
583 | /* |
584 | * Get interrupt status |
585 | */ |
586 | intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000128 )))); |
587 | if (intr_status == 0xffffffff) /* Not for us */ |
588 | return (0); |
589 | |
590 | intr_status &= CSR_READ_4(sc, BWI_MAC_INTR_MASK)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x0000012c )))); |
591 | if (intr_status == 0) /* Nothing is interesting */ |
592 | return (0); |
593 | |
594 | DPRINTF(2, "%s: intr status 0x%08x\n", |
595 | sc->sc_dev.dv_xname, intr_status); |
596 | |
597 | KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC)((sc->sc_cur_regwin->rw_type == 0x812) ? (void)0 : __assert ("diagnostic ", "/usr/src/sys/dev/ic/bwi.c", 597, "sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC" )); |
598 | mac = (struct bwi_mac *)sc->sc_cur_regwin; |
599 | |
600 | txrx_error = 0; |
601 | |
602 | for (i = 0; i < BWI_TXRX_NRING6; ++i) { |
603 | uint32_t mask; |
604 | |
605 | if (BWI_TXRX_IS_RX(i)((i) % 3 == 0)) |
606 | mask = BWI_TXRX_RX_INTRS(((1 << 15) | (1 << 14) | (1 << 12) | (1 << 11) | (1 << 10)) | (1 << 16)); |
607 | else |
608 | mask = BWI_TXRX_TX_INTRS((1 << 15) | (1 << 14) | (1 << 12) | (1 << 11) | (1 << 10)); |
609 | |
610 | txrx_intr_status[i] = |
611 | CSR_READ_4(sc, BWI_TXRX_INTR_STATUS(i))(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), (((0x20 + ((i) * 8)))))) & mask; |
612 | |
613 | if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR((1 << 15) | (1 << 14) | (1 << 12) | (1 << 11) | (1 << 10))) { |
614 | printf("%s: intr fatal TX/RX (%d) error 0x%08x\n", |
615 | sc->sc_dev.dv_xname, i, txrx_intr_status[i]); |
616 | txrx_error = 1; |
617 | } |
618 | } |
619 | |
620 | /* |
621 | * Acknowledge interrupt |
622 | */ |
623 | CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, intr_status)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000128 )), ((intr_status)))); |
624 | |
625 | for (i = 0; i < BWI_TXRX_NRING6; ++i) |
626 | CSR_WRITE_4(sc, BWI_TXRX_INTR_STATUS(i), txrx_intr_status[i])(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), (((0x20 + ((i) * 8)))), ((txrx_intr_status[i])))); |
627 | |
628 | /* Disable all interrupts */ |
629 | bwi_disable_intrs(sc, BWI_ALL_INTRS0xffffffff); |
630 | |
631 | if (intr_status & BWI_INTR_PHY_TXERR(1 << 11)) { |
632 | if (mac->mac_flags & BWI_MAC_F_PHYE_RESET0x80) { |
633 | printf("intr PHY TX error\n"); |
634 | /* XXX to netisr0? */ |
635 | bwi_init_statechg(sc, 0); |
636 | return (1); |
637 | } |
638 | } |
639 | |
640 | if (txrx_error) { |
641 | /* TODO: reset device */ |
642 | } |
643 | |
644 | if (intr_status & BWI_INTR_TBTT(1 << 2)) |
645 | bwi_mac_config_ps(mac); |
646 | |
647 | if (intr_status & BWI_INTR_EO_ATIM(1 << 5)) |
648 | printf("%s: EO_ATIM\n", sc->sc_dev.dv_xname); |
649 | |
650 | if (intr_status & BWI_INTR_PMQ(1 << 6)) { |
651 | for (;;) { |
652 | if ((CSR_READ_4(sc, BWI_MAC_PS_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000140 )))) & 0x8) == 0) |
653 | break; |
654 | } |
655 | CSR_WRITE_2(sc, BWI_MAC_PS_STATUS, 0x2)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x00000140 )), ((0x2)))); |
656 | } |
657 | |
658 | if (intr_status & BWI_INTR_NOISE(1 << 18)) |
659 | printf("%s: intr noise\n", sc->sc_dev.dv_xname); |
660 | |
661 | if (txrx_intr_status[0] & BWI_TXRX_INTR_RX(1 << 16)) |
662 | rx_data = sc->sc_rxeof(sc); |
663 | |
664 | if (txrx_intr_status[3] & BWI_TXRX_INTR_RX(1 << 16)) { |
665 | sc->sc_txeof_status(sc); |
666 | tx = 1; |
667 | } |
668 | |
669 | if (intr_status & BWI_INTR_TX_DONE(1 << 29)) { |
670 | bwi_txeof(sc); |
671 | tx = 1; |
672 | } |
673 | |
674 | /* Re-enable interrupts */ |
675 | bwi_enable_intrs(sc, BWI_INIT_INTRS((1 << 0) | (1 << 1) | (1 << 2) | (1 << 5) | (1 << 6) | (1 << 9) | (1 << 11) | (1 << 15) | (1 << 16) | (1 << 18) | (1 << 28) | ( 1 << 29))); |
676 | |
677 | if (sc->sc_blink_led != NULL((void *)0) && sc->sc_led_blink) { |
678 | int evt = BWI_LED_EVENT_NONE-1; |
679 | |
680 | if (tx && rx_data > 0) { |
681 | if (sc->sc_rx_rate > sc->sc_tx_rate) |
682 | evt = BWI_LED_EVENT_RX2; |
683 | else |
684 | evt = BWI_LED_EVENT_TX1; |
685 | } else if (tx) { |
686 | evt = BWI_LED_EVENT_TX1; |
687 | } else if (rx_data > 0) { |
688 | evt = BWI_LED_EVENT_RX2; |
689 | } else if (rx_data == 0) { |
690 | evt = BWI_LED_EVENT_POLL0; |
691 | } |
692 | |
693 | if (evt != BWI_LED_EVENT_NONE-1) |
694 | bwi_led_event(sc, evt); |
695 | } |
696 | |
697 | return (1); |
698 | } |
699 | |
700 | int |
701 | bwi_attach(struct bwi_softc *sc) |
702 | { |
703 | struct ieee80211com *ic = &sc->sc_ic; |
704 | struct ifnet *ifp = &ic->ic_ific_ac.ac_if; |
705 | struct bwi_mac *mac; |
706 | struct bwi_phy *phy; |
707 | int i, error; |
708 | |
709 | DPRINTF(1, "\n"); |
710 | |
711 | /* Initialize LED vars */ |
712 | sc->sc_led_idle = (2350 * hz) / 1000; |
713 | sc->sc_led_blink = 1; |
714 | |
715 | /* AMRR rate control */ |
716 | sc->sc_amrr.amrr_min_success_threshold = 1; |
717 | sc->sc_amrr.amrr_max_success_threshold = 15; |
718 | timeout_set(&sc->sc_amrr_ch, bwi_amrr_timeout, sc); |
719 | |
720 | timeout_set(&sc->sc_scan_ch, bwi_next_scan, sc); |
721 | timeout_set(&sc->sc_calib_ch, bwi_calibrate, sc); |
722 | |
723 | bwi_power_on(sc, 1); |
724 | |
725 | error = bwi_bbp_attach(sc); |
726 | if (error) |
727 | goto fail; |
728 | |
729 | error = bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST); |
730 | if (error) |
731 | goto fail; |
732 | |
733 | if (BWI_REGWIN_EXIST(&sc->sc_com_regwin)((&sc->sc_com_regwin)->rw_flags & 0x1)) { |
734 | error = bwi_set_clock_delay(sc); |
735 | if (error) |
736 | goto fail; |
737 | |
738 | error = bwi_set_clock_mode(sc, BWI_CLOCK_MODE_FAST); |
739 | if (error) |
740 | goto fail; |
741 | |
742 | error = bwi_get_pwron_delay(sc); |
743 | if (error) |
744 | goto fail; |
745 | } |
746 | |
747 | error = bwi_bus_attach(sc); |
748 | if (error) |
749 | goto fail; |
750 | |
751 | bwi_get_card_flags(sc); |
752 | |
753 | bwi_led_attach(sc); |
754 | |
755 | for (i = 0; i < sc->sc_nmac; ++i) { |
756 | struct bwi_regwin *old; |
757 | |
758 | mac = &sc->sc_mac[i]; |
759 | error = bwi_regwin_switch(sc, &mac->mac_regwin, &old); |
760 | if (error) |
761 | goto fail; |
762 | |
763 | error = bwi_mac_lateattach(mac); |
764 | if (error) |
765 | goto fail; |
766 | |
767 | error = bwi_regwin_switch(sc, old, NULL((void *)0)); |
768 | if (error) |
769 | goto fail; |
770 | } |
771 | |
772 | /* |
773 | * XXX First MAC is known to exist |
774 | * TODO2 |
775 | */ |
776 | mac = &sc->sc_mac[0]; |
777 | phy = &mac->mac_phy; |
778 | |
779 | bwi_bbp_power_off(sc); |
780 | |
781 | error = bwi_dma_alloc(sc); |
782 | if (error) |
783 | goto fail; |
784 | |
785 | /* setup interface */ |
786 | ifp->if_softc = sc; |
787 | ifp->if_ioctl = bwi_ioctl; |
788 | ifp->if_start = bwi_start; |
789 | ifp->if_watchdog = bwi_watchdog; |
790 | ifp->if_flags = IFF_SIMPLEX0x800 | IFF_BROADCAST0x2 | IFF_MULTICAST0x8000; |
791 | strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ16); |
792 | ifq_init_maxlen(&ifp->if_snd, IFQ_MAXLEN256); |
793 | |
794 | /* Get locale */ |
795 | sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO),(((bwi_read_sprom(sc, 0x5c)) & ((0x0f << 8))) / ((( ((0x0f << 8)) - 1) & ((0x0f << 8))) ^ ((0x0f << 8)))) |
796 | BWI_SPROM_CARD_INFO_LOCALE)(((bwi_read_sprom(sc, 0x5c)) & ((0x0f << 8))) / ((( ((0x0f << 8)) - 1) & ((0x0f << 8))) ^ ((0x0f << 8)))); |
797 | DPRINTF(1, "%s: locale: %d\n", sc->sc_dev.dv_xname, sc->sc_locale); |
798 | |
799 | /* |
800 | * Setup ratesets, phytype, channels and get MAC address |
801 | */ |
802 | if (phy->phy_mode == IEEE80211_MODE_11B || |
803 | phy->phy_mode == IEEE80211_MODE_11G) { |
804 | uint16_t chan_flags; |
805 | |
806 | ic->ic_sup_rates[IEEE80211_MODE_11B] = |
807 | ieee80211_std_rateset_11b; |
808 | |
809 | if (phy->phy_mode == IEEE80211_MODE_11B) { |
810 | chan_flags = IEEE80211_CHAN_B(0x0080 | 0x0020); |
811 | ic->ic_phytype = IEEE80211_T_DS; |
812 | } else { |
813 | chan_flags = IEEE80211_CHAN_CCK0x0020 | |
814 | IEEE80211_CHAN_OFDM0x0040 | |
815 | IEEE80211_CHAN_DYN0x0400 | |
816 | IEEE80211_CHAN_2GHZ0x0080; |
817 | ic->ic_phytype = IEEE80211_T_OFDM; |
818 | ic->ic_sup_rates[IEEE80211_MODE_11G] = |
819 | ieee80211_std_rateset_11g; |
820 | } |
821 | |
822 | /* XXX depend on locale */ |
823 | for (i = 1; i <= 14; ++i) { |
824 | ic->ic_channels[i].ic_freq = |
825 | ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ0x0080); |
826 | ic->ic_channels[i].ic_flags = chan_flags; |
827 | } |
828 | |
829 | bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR0x48, ic->ic_myaddr); |
830 | if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)(*(ic->ic_myaddr) & 0x01)) { |
831 | bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR0x54, ic->ic_myaddr); |
832 | if (IEEE80211_IS_MULTICAST(ic->ic_myaddr)(*(ic->ic_myaddr) & 0x01)) { |
833 | printf("%s: invalid MAC address: %s\n", |
834 | sc->sc_dev.dv_xname, |
835 | ether_sprintf(ic->ic_myaddr)); |
836 | } |
837 | } |
838 | } else if (phy->phy_mode == IEEE80211_MODE_11A) { |
839 | /* TODO: 11A */ |
840 | error = ENXIO6; |
841 | goto fail; |
842 | } else |
843 | panic("unknown phymode %d", phy->phy_mode); |
844 | |
845 | printf(", address %s\n", ether_sprintf(ic->ic_myaddr)); |
846 | |
847 | sc->sc_fw_version = BWI_FW_VERSION33; |
848 | sc->sc_dwell_time = 200; |
849 | |
850 | ic->ic_caps = IEEE80211_C_SHSLOT0x00000080 | |
851 | IEEE80211_C_SHPREAMBLE0x00000100 | |
852 | IEEE80211_C_WEP0x00000001 | |
853 | IEEE80211_C_RSN0x00001000 | |
854 | IEEE80211_C_MONITOR0x00000200; |
855 | ic->ic_state = IEEE80211_S_INIT; |
856 | ic->ic_opmode = IEEE80211_M_STA; |
857 | |
858 | ic->ic_updateslot = bwi_updateslot; |
859 | |
860 | if_attach(ifp); |
861 | ieee80211_ifattach(ifp); |
862 | |
863 | sc->sc_newstate = ic->ic_newstate; |
864 | ic->ic_newstate = bwi_newstate; |
865 | ic->ic_newassoc = bwi_newassoc; |
866 | ic->ic_node_alloc = bwi_node_alloc; |
867 | |
868 | ieee80211_media_init(ifp, bwi_media_change, ieee80211_media_status); |
869 | |
870 | if (error) { |
871 | ieee80211_ifdetach(ifp); |
872 | goto fail; |
873 | } |
874 | |
875 | #if NBPFILTER1 > 0 |
876 | bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO127, |
877 | sizeof(struct ieee80211_frame) + 64); |
878 | |
879 | sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); |
880 | sc->sc_rxtapsc_rxtapu.th.wr_ihdr.it_len = htole16(sc->sc_rxtap_len)((__uint16_t)(sc->sc_rxtap_len)); |
881 | sc->sc_rxtapsc_rxtapu.th.wr_ihdr.it_present = htole32(BWI_RX_RADIOTAP_PRESENT)((__uint32_t)(((1 << IEEE80211_RADIOTAP_TSFT) | (1 << IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE ) | (1 << IEEE80211_RADIOTAP_CHANNEL) | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL ) | (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)))); |
882 | |
883 | sc->sc_txtap_len = sizeof(sc->sc_txtapu); |
884 | sc->sc_txtapsc_txtapu.th.wt_ihdr.it_len = htole16(sc->sc_txtap_len)((__uint16_t)(sc->sc_txtap_len)); |
885 | sc->sc_txtapsc_txtapu.th.wt_ihdr.it_present = htole32(BWI_TX_RADIOTAP_PRESENT)((__uint32_t)(((1 << IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_CHANNEL )))); |
886 | #endif |
887 | |
888 | return (0); |
889 | fail: |
890 | return (error); |
891 | } |
892 | |
893 | int |
894 | bwi_detach(void *arg) |
895 | { |
896 | struct bwi_softc *sc = arg; |
897 | struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if; |
898 | int s, i; |
899 | |
900 | bwi_stop(sc, 1); |
901 | ieee80211_ifdetach(ifp); |
902 | if_detach(ifp); |
903 | |
904 | for (i = 0; i < sc->sc_nmac; ++i) |
905 | bwi_mac_detach(&sc->sc_mac[i]); |
906 | |
907 | s = splvm()splraise(0xa); |
908 | bwi_dma_free(sc); |
909 | splx(s)spllower(s); |
910 | bwi_dma_mbuf_destroy(sc, BWI_TX_NRING6, 1); |
911 | |
912 | return (0); |
913 | } |
914 | |
915 | /* MAC */ |
916 | |
917 | void |
918 | bwi_tmplt_write_4(struct bwi_mac *mac, uint32_t ofs, uint32_t val) |
919 | { |
920 | struct bwi_softc *sc = mac->mac_sc; |
921 | |
922 | if (mac->mac_flags & BWI_MAC_F_BSWAP0x1) |
923 | val = swap32(val)(__uint32_t)(__builtin_constant_p(val) ? (__uint32_t)(((__uint32_t )(val) & 0xff) << 24 | ((__uint32_t)(val) & 0xff00 ) << 8 | ((__uint32_t)(val) & 0xff0000) >> 8 | ((__uint32_t)(val) & 0xff000000) >> 24) : __swap32md (val)); |
924 | |
925 | CSR_WRITE_4(sc, BWI_MAC_TMPLT_CTRL, ofs)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000130 )), ((ofs)))); |
926 | CSR_WRITE_4(sc, BWI_MAC_TMPLT_DATA, val)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000134 )), ((val)))); |
927 | } |
928 | |
929 | void |
930 | bwi_hostflags_write(struct bwi_mac *mac, uint64_t flags) |
931 | { |
932 | uint64_t val; |
933 | |
934 | val = flags & 0xffff; |
935 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO, val)bwi_memobj_write_2((mac), (0x1), (0x5e), (val)); |
936 | |
937 | val = (flags >> 16) & 0xffff; |
938 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI, val)bwi_memobj_write_2((mac), (0x1), (0x60), (val)); |
939 | |
940 | /* HI has unclear meaning, so leave it as it is */ |
941 | } |
942 | |
943 | uint64_t |
944 | bwi_hostflags_read(struct bwi_mac *mac) |
945 | { |
946 | uint64_t flags, val; |
947 | |
948 | /* HI has unclear meaning, so don't touch it */ |
949 | flags = 0; |
950 | |
951 | val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI)bwi_memobj_read_2((mac), (0x1), (0x60)); |
952 | flags |= val << 16; |
953 | |
954 | val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO)bwi_memobj_read_2((mac), (0x1), (0x5e)); |
955 | flags |= val; |
956 | |
957 | return (flags); |
958 | } |
959 | |
960 | uint16_t |
961 | bwi_memobj_read_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0) |
962 | { |
963 | struct bwi_softc *sc = mac->mac_sc; |
964 | uint32_t data_reg; |
965 | int ofs; |
966 | |
967 | data_reg = BWI_MOBJ_DATA0x00000164; |
968 | ofs = ofs0 / 4; |
969 | |
970 | if (ofs0 % 4 != 0) |
971 | data_reg = BWI_MOBJ_DATA_UNALIGN0x0166; |
972 | |
973 | CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((obj_id) << 16 | (ofs)))))); |
974 | return (CSR_READ_2(sc, data_reg)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((data_reg ))))); |
975 | } |
976 | |
977 | uint32_t |
978 | bwi_memobj_read_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0) |
979 | { |
980 | struct bwi_softc *sc = mac->mac_sc; |
981 | int ofs; |
982 | |
983 | ofs = ofs0 / 4; |
984 | if (ofs0 % 4 != 0) { |
985 | uint32_t ret; |
986 | |
987 | CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((obj_id) << 16 | (ofs)))))); |
988 | ret = CSR_READ_2(sc, BWI_MOBJ_DATA_UNALIGN)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x0166 )))); |
989 | ret <<= 16; |
990 | |
991 | CSR_WRITE_4(sc, BWI_MOBJ_CTRL,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((obj_id) << 16 | (ofs + 1)))))) |
992 | BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((obj_id) << 16 | (ofs + 1)))))); |
993 | ret |= CSR_READ_2(sc, BWI_MOBJ_DATA)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x00000164 )))); |
994 | |
995 | return (ret); |
996 | } else { |
997 | CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((obj_id) << 16 | (ofs)))))); |
998 | return (CSR_READ_4(sc, BWI_MOBJ_DATA)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000164 ))))); |
999 | } |
1000 | } |
1001 | |
1002 | void |
1003 | bwi_memobj_write_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0, |
1004 | uint16_t v) |
1005 | { |
1006 | struct bwi_softc *sc = mac->mac_sc; |
1007 | uint32_t data_reg; |
1008 | int ofs; |
1009 | |
1010 | data_reg = BWI_MOBJ_DATA0x00000164; |
1011 | ofs = ofs0 / 4; |
1012 | |
1013 | if (ofs0 % 4 != 0) |
1014 | data_reg = BWI_MOBJ_DATA_UNALIGN0x0166; |
1015 | |
1016 | CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((obj_id) << 16 | (ofs)))))); |
1017 | CSR_WRITE_2(sc, data_reg, v)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((data_reg )), ((v)))); |
1018 | } |
1019 | |
1020 | void |
1021 | bwi_memobj_write_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0, |
1022 | uint32_t v) |
1023 | { |
1024 | struct bwi_softc *sc = mac->mac_sc; |
1025 | int ofs; |
1026 | |
1027 | ofs = ofs0 / 4; |
1028 | if (ofs0 % 4 != 0) { |
1029 | CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((obj_id) << 16 | (ofs)))))); |
1030 | CSR_WRITE_2(sc, BWI_MOBJ_DATA_UNALIGN, v >> 16)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x0166 )), ((v >> 16)))); |
1031 | CSR_WRITE_4(sc, BWI_MOBJ_CTRL,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((obj_id) << 16 | (ofs + 1)))))) |
1032 | BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((obj_id) << 16 | (ofs + 1)))))); |
1033 | CSR_WRITE_2(sc, BWI_MOBJ_DATA, v & 0xffff)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x00000164 )), ((v & 0xffff)))); |
1034 | } else { |
1035 | CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((obj_id) << 16 | (ofs)))))); |
1036 | CSR_WRITE_4(sc, BWI_MOBJ_DATA, v)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000164 )), ((v)))); |
1037 | } |
1038 | } |
1039 | |
1040 | int |
1041 | bwi_mac_lateattach(struct bwi_mac *mac) |
1042 | { |
1043 | int error; |
1044 | |
1045 | if (mac->mac_revmac_regwin.rw_rev >= 5) |
1046 | CSR_READ_4(mac->mac_sc, BWI_STATE_HI)(((mac->mac_sc)->sc_mem_bt)->read_4(((mac->mac_sc )->sc_mem_bh), ((0x00000f9c)))); /* dummy read */ |
1047 | |
1048 | bwi_mac_reset(mac, 1); |
1049 | |
1050 | error = bwi_phy_attach(mac); |
1051 | if (error) |
1052 | return (error); |
1053 | |
1054 | error = bwi_rf_attach(mac); |
1055 | if (error) |
1056 | return (error); |
1057 | |
1058 | /* Link 11B/G PHY, unlink 11A PHY */ |
1059 | if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) |
1060 | bwi_mac_reset(mac, 0); |
1061 | else |
1062 | bwi_mac_reset(mac, 1); |
1063 | |
1064 | error = bwi_mac_test(mac); |
1065 | if (error) |
1066 | return (error); |
1067 | |
1068 | error = bwi_mac_get_property(mac); |
1069 | if (error) |
1070 | return (error); |
1071 | |
1072 | error = bwi_rf_map_txpower(mac); |
1073 | if (error) |
1074 | return (error); |
1075 | |
1076 | bwi_rf_off(mac); |
1077 | CSR_WRITE_2(mac->mac_sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC)(((mac->mac_sc)->sc_mem_bt)->write_2(((mac->mac_sc )->sc_mem_bh), ((0x03e6)), ((0x00f4)))); |
1078 | bwi_regwin_disable(mac->mac_sc, &mac->mac_regwin, 0); |
1079 | |
1080 | return (0); |
1081 | } |
1082 | |
1083 | int |
1084 | bwi_mac_init(struct bwi_mac *mac) |
1085 | { |
1086 | struct bwi_softc *sc = mac->mac_sc; |
1087 | int error, i; |
1088 | |
1089 | /* Clear MAC/PHY/RF states */ |
1090 | bwi_mac_setup_tpctl(mac); |
1091 | bwi_rf_clear_state(&mac->mac_rf); |
1092 | bwi_phy_clear_state(&mac->mac_phy); |
1093 | |
1094 | /* Enable MAC and linked it to PHY */ |
1095 | if (!bwi_regwin_is_enabled(sc, &mac->mac_regwin)) |
1096 | bwi_mac_reset(mac, 1); |
1097 | |
1098 | /* Initialize backplane */ |
1099 | error = bwi_bus_init(sc, mac); |
1100 | if (error) |
1101 | return (error); |
1102 | |
1103 | /* XXX work around for hardware bugs? */ |
1104 | if (sc->sc_bus_regwin.rw_rev <= 5 && |
1105 | sc->sc_bus_regwin.rw_type != BWI_REGWIN_T_BUSPCIE0x820) { |
1106 | CSR_SETBITS_4(sc, BWI_CONF_LO,((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000fa8))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000fa8))))) | (((2) * ((((0x00000007) - 1) & (0x00000007)) ^ (0x00000007))) | ((3) * ((((0x00000070 ) - 1) & (0x00000070)) ^ (0x00000070)))))))) |
1107 | __SHIFTIN(BWI_CONF_LO_SERVTO, BWI_CONF_LO_SERVTO_MASK) |((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000fa8))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000fa8))))) | (((2) * ((((0x00000007) - 1) & (0x00000007)) ^ (0x00000007))) | ((3) * ((((0x00000070 ) - 1) & (0x00000070)) ^ (0x00000070)))))))) |
1108 | __SHIFTIN(BWI_CONF_LO_REQTO, BWI_CONF_LO_REQTO_MASK))((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000fa8))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000fa8))))) | (((2) * ((((0x00000007) - 1) & (0x00000007)) ^ (0x00000007))) | ((3) * ((((0x00000070 ) - 1) & (0x00000070)) ^ (0x00000070)))))))); |
1109 | } |
1110 | |
1111 | /* Calibrate PHY */ |
1112 | error = bwi_phy_calibrate(mac); |
1113 | if (error) { |
1114 | printf("%s: PHY calibrate failed\n", sc->sc_dev.dv_xname); |
1115 | return (error); |
1116 | } |
1117 | |
1118 | /* Prepare to initialize firmware */ |
1119 | CSR_WRITE_4(sc, BWI_MAC_STATUS,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000120 )), (((1U << 2) | (1U << 10))))) |
1120 | BWI_MAC_STATUS_UCODE_JUMP0 |(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000120 )), (((1U << 2) | (1U << 10))))) |
1121 | BWI_MAC_STATUS_IHREN)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000120 )), (((1U << 2) | (1U << 10))))); |
1122 | |
1123 | /* |
1124 | * Load and initialize firmwares |
1125 | */ |
1126 | error = bwi_mac_fw_alloc(mac); |
1127 | if (error) |
1128 | return (error); |
1129 | |
1130 | error = bwi_mac_fw_load(mac); |
1131 | if (error) |
1132 | return (error); |
1133 | |
1134 | error = bwi_mac_gpio_init(mac); |
1135 | if (error) |
1136 | return (error); |
1137 | |
1138 | error = bwi_mac_fw_init(mac); |
1139 | if (error) |
1140 | return (error); |
1141 | |
1142 | /* |
1143 | * Turn on RF |
1144 | */ |
1145 | bwi_rf_on(mac); |
1146 | |
1147 | /* TODO: LED, hardware rf enabled is only related to LED setting */ |
1148 | |
1149 | /* |
1150 | * Initialize PHY |
1151 | */ |
1152 | CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e6 )), ((0)))); |
1153 | bwi_phy_init(mac); |
1154 | |
1155 | /* TODO: interference mitigation */ |
1156 | |
1157 | /* |
1158 | * Setup antenna mode |
1159 | */ |
1160 | bwi_rf_set_ant_mode(mac, mac->mac_rf.rf_ant_mode); |
1161 | |
1162 | /* |
1163 | * Initialize operation mode (RX configuration) |
1164 | */ |
1165 | bwi_mac_opmode_init(mac); |
1166 | |
1167 | /* XXX what's these */ |
1168 | if (mac->mac_revmac_regwin.rw_rev < 3) { |
1169 | CSR_WRITE_2(sc, 0x60e, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x60e )), ((0)))); |
1170 | CSR_WRITE_2(sc, 0x610, 0x8000)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x610 )), ((0x8000)))); |
1171 | CSR_WRITE_2(sc, 0x604, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x604 )), ((0)))); |
1172 | CSR_WRITE_2(sc, 0x606, 0x200)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x606 )), ((0x200)))); |
1173 | } else { |
1174 | CSR_WRITE_4(sc, 0x188, 0x80000000)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x188 )), ((0x80000000)))); |
1175 | CSR_WRITE_4(sc, 0x18c, 0x2000000)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x18c )), ((0x2000000)))); |
1176 | } |
1177 | |
1178 | /* |
1179 | * Initialize TX/RX interrupts' mask |
1180 | */ |
1181 | CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_TIMER1)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000128 )), (((1 << 14))))); |
1182 | for (i = 0; i < BWI_TXRX_NRING6; ++i) { |
1183 | uint32_t intrs; |
1184 | |
1185 | if (BWI_TXRX_IS_RX(i)((i) % 3 == 0)) |
1186 | intrs = BWI_TXRX_RX_INTRS(((1 << 15) | (1 << 14) | (1 << 12) | (1 << 11) | (1 << 10)) | (1 << 16)); |
1187 | else |
1188 | intrs = BWI_TXRX_TX_INTRS((1 << 15) | (1 << 14) | (1 << 12) | (1 << 11) | (1 << 10)); |
1189 | CSR_WRITE_4(sc, BWI_TXRX_INTR_MASK(i), intrs)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), (((0x24 + ((i) * 8)))), ((intrs)))); |
1190 | } |
1191 | |
1192 | /* XXX what's this */ |
1193 | CSR_SETBITS_4(sc, BWI_STATE_LO, 0x100000)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000f98))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000f98))))) | (0x100000))))); |
1194 | |
1195 | /* Setup MAC power up delay */ |
1196 | CSR_WRITE_2(sc, BWI_MAC_POWERUP_DELAY, sc->sc_pwron_delay)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x06a8 )), ((sc->sc_pwron_delay)))); |
1197 | |
1198 | /* Set MAC regwin revision */ |
1199 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_MACREV, mac->mac_rev)bwi_memobj_write_2((mac), (0x1), (0x16), (mac->mac_regwin. rw_rev)); |
1200 | |
1201 | /* |
1202 | * Initialize host flags |
1203 | */ |
1204 | bwi_mac_hostflags_init(mac); |
1205 | |
1206 | /* |
1207 | * Initialize BSS parameters |
1208 | */ |
1209 | bwi_mac_bss_param_init(mac); |
1210 | |
1211 | /* |
1212 | * Initialize TX rings |
1213 | */ |
1214 | for (i = 0; i < BWI_TX_NRING6; ++i) { |
1215 | error = sc->sc_init_tx_ring(sc, i); |
1216 | if (error) { |
1217 | printf("%s: can't initialize %dth TX ring\n", |
1218 | sc->sc_dev.dv_xname, i); |
1219 | return (error); |
1220 | } |
1221 | } |
1222 | |
1223 | /* |
1224 | * Initialize RX ring |
1225 | */ |
1226 | error = sc->sc_init_rx_ring(sc); |
1227 | if (error) { |
1228 | printf("%s: can't initialize RX ring\n", sc->sc_dev.dv_xname); |
1229 | return (error); |
1230 | } |
1231 | |
1232 | /* |
1233 | * Initialize TX stats if the current MAC uses that |
1234 | */ |
1235 | if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS0x4) { |
1236 | error = sc->sc_init_txstats(sc); |
1237 | if (error) { |
1238 | printf("%s: can't initialize TX stats ring\n", |
1239 | sc->sc_dev.dv_xname); |
1240 | return (error); |
1241 | } |
1242 | } |
1243 | |
1244 | /* XXX what's these */ |
1245 | CSR_WRITE_2(sc, 0x612, 0x50)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x612 )), ((0x50)))); /* Force Pre-TBTT to 80? */ |
1246 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x416, 0x50)bwi_memobj_write_2((mac), (0x1), (0x416), (0x50)); |
1247 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x414, 0x1f4)bwi_memobj_write_2((mac), (0x1), (0x414), (0x1f4)); |
1248 | |
1249 | mac->mac_flags |= BWI_MAC_F_INITED0x8; |
1250 | |
1251 | return (0); |
1252 | } |
1253 | |
1254 | void |
1255 | bwi_mac_reset(struct bwi_mac *mac, int link_phy) |
1256 | { |
1257 | struct bwi_softc *sc = mac->mac_sc; |
1258 | uint32_t flags, state_lo, status; |
1259 | |
1260 | flags = BWI_STATE_LO_FLAG_PHYRST(1 << 1) | BWI_STATE_LO_FLAG_PHYCLKEN(1 << 0); |
1261 | if (link_phy) |
1262 | flags |= BWI_STATE_LO_FLAG_PHYLNK(1 << 11); |
1263 | bwi_regwin_enable(sc, &mac->mac_regwin, flags); |
1264 | DELAY(2000)(*delay_func)(2000); |
1265 | |
1266 | state_lo = CSR_READ_4(sc, BWI_STATE_LO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f98 )))); |
1267 | state_lo |= BWI_STATE_LO_GATED_CLOCK(1 << 17); |
1268 | state_lo &= ~__SHIFTIN(BWI_STATE_LO_FLAG_PHYRST,(((1 << 1)) * ((((0x3ffc0000) - 1) & (0x3ffc0000)) ^ (0x3ffc0000))) |
1269 | BWI_STATE_LO_FLAGS_MASK)(((1 << 1)) * ((((0x3ffc0000) - 1) & (0x3ffc0000)) ^ (0x3ffc0000))); |
1270 | CSR_WRITE_4(sc, BWI_STATE_LO, state_lo)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000f98 )), ((state_lo)))); |
1271 | /* Flush pending bus write */ |
1272 | CSR_READ_4(sc, BWI_STATE_LO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f98 )))); |
1273 | DELAY(1000)(*delay_func)(1000); |
1274 | |
1275 | state_lo &= ~BWI_STATE_LO_GATED_CLOCK(1 << 17); |
1276 | CSR_WRITE_4(sc, BWI_STATE_LO, state_lo)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000f98 )), ((state_lo)))); |
1277 | /* Flush pending bus write */ |
1278 | CSR_READ_4(sc, BWI_STATE_LO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f98 )))); |
1279 | DELAY(1000)(*delay_func)(1000); |
1280 | |
1281 | CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e6 )), ((0)))); |
1282 | |
1283 | status = CSR_READ_4(sc, BWI_MAC_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000120 )))); |
1284 | status |= BWI_MAC_STATUS_IHREN(1U << 10); |
1285 | if (link_phy) |
1286 | status |= BWI_MAC_STATUS_PHYLNK(1U << 31); |
1287 | else |
1288 | status &= ~BWI_MAC_STATUS_PHYLNK(1U << 31); |
1289 | CSR_WRITE_4(sc, BWI_MAC_STATUS, status)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000120 )), ((status)))); |
1290 | |
1291 | if (link_phy) { |
1292 | DPRINTF(1, "%s: PHY is linked\n", sc->sc_dev.dv_xname); |
1293 | mac->mac_phy.phy_flags |= BWI_PHY_F_LINKED0x2; |
1294 | } else { |
1295 | DPRINTF(1, "%s: PHY is unlinked\n", sc->sc_dev.dv_xname); |
1296 | mac->mac_phy.phy_flags &= ~BWI_PHY_F_LINKED0x2; |
1297 | } |
1298 | } |
1299 | |
1300 | void |
1301 | bwi_mac_set_tpctl_11bg(struct bwi_mac *mac, const struct bwi_tpctl *new_tpctl) |
1302 | { |
1303 | struct bwi_rf *rf = &mac->mac_rf; |
1304 | struct bwi_tpctl *tpctl = &mac->mac_tpctl; |
1305 | |
1306 | if (new_tpctl != NULL((void *)0)) { |
1307 | KASSERT(new_tpctl->bbp_atten <= BWI_BBP_ATTEN_MAX)((new_tpctl->bbp_atten <= 11) ? (void)0 : __assert("diagnostic " , "/usr/src/sys/dev/ic/bwi.c", 1307, "new_tpctl->bbp_atten <= BWI_BBP_ATTEN_MAX" )); |
1308 | KASSERT(new_tpctl->rf_atten <=((new_tpctl->rf_atten <= (rf->rf_rev < 6 ? 9 : 31 )) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c" , 1310, "new_tpctl->rf_atten <= (rf->rf_rev < 6 ? BWI_RF_ATTEN_MAX0 : BWI_RF_ATTEN_MAX1)" )) |
1309 | (rf->rf_rev < 6 ? BWI_RF_ATTEN_MAX0((new_tpctl->rf_atten <= (rf->rf_rev < 6 ? 9 : 31 )) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c" , 1310, "new_tpctl->rf_atten <= (rf->rf_rev < 6 ? BWI_RF_ATTEN_MAX0 : BWI_RF_ATTEN_MAX1)" )) |
1310 | : BWI_RF_ATTEN_MAX1))((new_tpctl->rf_atten <= (rf->rf_rev < 6 ? 9 : 31 )) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c" , 1310, "new_tpctl->rf_atten <= (rf->rf_rev < 6 ? BWI_RF_ATTEN_MAX0 : BWI_RF_ATTEN_MAX1)" )); |
1311 | KASSERT(new_tpctl->tp_ctrl1 <= BWI_TPCTL1_MAX)((new_tpctl->tp_ctrl1 <= 7) ? (void)0 : __assert("diagnostic " , "/usr/src/sys/dev/ic/bwi.c", 1311, "new_tpctl->tp_ctrl1 <= BWI_TPCTL1_MAX" )); |
1312 | |
1313 | tpctl->bbp_atten = new_tpctl->bbp_atten; |
1314 | tpctl->rf_atten = new_tpctl->rf_atten; |
1315 | tpctl->tp_ctrl1 = new_tpctl->tp_ctrl1; |
1316 | } |
1317 | |
1318 | /* Set BBP attenuation */ |
1319 | bwi_phy_set_bbp_atten(mac, tpctl->bbp_atten); |
1320 | |
1321 | /* Set RF attenuation */ |
1322 | RF_WRITE(mac, BWI_RFR_ATTEN, tpctl->rf_atten)bwi_rf_write((mac), (0x43), (tpctl->rf_atten)); |
1323 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RF_ATTEN,bwi_memobj_write_2((mac), (0x1), (0x64), (tpctl->rf_atten) ) |
1324 | tpctl->rf_atten)bwi_memobj_write_2((mac), (0x1), (0x64), (tpctl->rf_atten) ); |
1325 | |
1326 | /* Set TX power */ |
1327 | if (rf->rf_type == BWI_RF_T_BCM20500x2050) { |
1328 | RF_FILT_SETBITS(mac, BWI_RFR_TXPWR, ~BWI_RFR_TXPWR1_MASK,bwi_rf_write(((mac)), ((0x52)), ((bwi_rf_read(((mac)), ((0x52 ))) & (~0x0070)) | (((tpctl->tp_ctrl1) * ((((0x0070) - 1) & (0x0070)) ^ (0x0070)))))) |
1329 | __SHIFTIN(tpctl->tp_ctrl1, BWI_RFR_TXPWR1_MASK))bwi_rf_write(((mac)), ((0x52)), ((bwi_rf_read(((mac)), ((0x52 ))) & (~0x0070)) | (((tpctl->tp_ctrl1) * ((((0x0070) - 1) & (0x0070)) ^ (0x0070)))))); |
1330 | } |
1331 | |
1332 | /* Adjust RF Local Oscillator */ |
1333 | if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G) |
1334 | bwi_rf_lo_adjust(mac, tpctl); |
1335 | } |
1336 | |
1337 | int |
1338 | bwi_mac_test(struct bwi_mac *mac) |
1339 | { |
1340 | struct bwi_softc *sc = mac->mac_sc; |
1341 | uint32_t orig_val, val; |
1342 | |
1343 | #define TEST_VAL1 0xaa5555aa |
1344 | #define TEST_VAL2 0x55aaaa55 |
1345 | /* Save it for later restoring */ |
1346 | orig_val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0)bwi_memobj_read_4((mac), (0x1), (0)); |
1347 | |
1348 | /* Test 1 */ |
1349 | MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL1)bwi_memobj_write_4((mac), (0x1), (0), (TEST_VAL1)); |
1350 | val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0)bwi_memobj_read_4((mac), (0x1), (0)); |
1351 | if (val != TEST_VAL1) { |
1352 | printf("%s: TEST1 failed\n", sc->sc_dev.dv_xname); |
1353 | return (ENXIO6); |
1354 | } |
1355 | |
1356 | /* Test 2 */ |
1357 | MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL2)bwi_memobj_write_4((mac), (0x1), (0), (TEST_VAL2)); |
1358 | val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0)bwi_memobj_read_4((mac), (0x1), (0)); |
1359 | if (val != TEST_VAL2) { |
1360 | printf("%s: TEST2 failed\n", sc->sc_dev.dv_xname); |
1361 | return (ENXIO6); |
1362 | } |
1363 | |
1364 | /* Restore to the original value */ |
1365 | MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, orig_val)bwi_memobj_write_4((mac), (0x1), (0), (orig_val)); |
1366 | |
1367 | val = CSR_READ_4(sc, BWI_MAC_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000120 )))); |
1368 | if ((val & ~BWI_MAC_STATUS_PHYLNK(1U << 31)) != BWI_MAC_STATUS_IHREN(1U << 10)) { |
1369 | printf("%s: %s failed, MAC status 0x%08x\n", |
1370 | sc->sc_dev.dv_xname, __func__, val); |
1371 | return (ENXIO6); |
1372 | } |
1373 | |
1374 | val = CSR_READ_4(sc, BWI_MAC_INTR_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000128 )))); |
1375 | if (val != 0) { |
1376 | printf("%s: %s failed, intr status %08x\n", |
1377 | sc->sc_dev.dv_xname, __func__, val); |
1378 | return (ENXIO6); |
1379 | } |
1380 | #undef TEST_VAL2 |
1381 | #undef TEST_VAL1 |
1382 | |
1383 | return (0); |
1384 | } |
1385 | |
1386 | void |
1387 | bwi_mac_setup_tpctl(struct bwi_mac *mac) |
1388 | { |
1389 | struct bwi_softc *sc = mac->mac_sc; |
1390 | struct bwi_rf *rf = &mac->mac_rf; |
1391 | struct bwi_phy *phy = &mac->mac_phy; |
1392 | struct bwi_tpctl *tpctl = &mac->mac_tpctl; |
1393 | |
1394 | /* Calc BBP attenuation */ |
1395 | if (rf->rf_type == BWI_RF_T_BCM20500x2050 && rf->rf_rev < 6) |
1396 | tpctl->bbp_atten = 0; |
1397 | else |
1398 | tpctl->bbp_atten = 2; |
1399 | |
1400 | /* Calc TX power CTRL1?? */ |
1401 | tpctl->tp_ctrl1 = 0; |
1402 | if (rf->rf_type == BWI_RF_T_BCM20500x2050) { |
1403 | if (rf->rf_rev == 1) |
1404 | tpctl->tp_ctrl1 = 3; |
1405 | else if (rf->rf_rev < 6) |
1406 | tpctl->tp_ctrl1 = 2; |
1407 | else if (rf->rf_rev == 8) |
1408 | tpctl->tp_ctrl1 = 1; |
1409 | } |
1410 | |
1411 | /* Empty TX power CTRL2?? */ |
1412 | tpctl->tp_ctrl2 = 0xffff; |
1413 | |
1414 | /* |
1415 | * Calc RF attenuation |
1416 | */ |
1417 | if (phy->phy_mode == IEEE80211_MODE_11A) { |
1418 | tpctl->rf_atten = 0x60; |
1419 | goto back; |
1420 | } |
1421 | |
1422 | if (BWI_IS_BRCM_BCM4309G(sc)((sc)->sc_pci_subvid == 0x14e4 && (sc)->sc_pci_subdid == 0x421) && sc->sc_pci_revid < 0x51) { |
1423 | tpctl->rf_atten = sc->sc_pci_revid < 0x43 ? 2 : 3; |
1424 | goto back; |
1425 | } |
1426 | |
1427 | tpctl->rf_atten = 5; |
1428 | |
1429 | if (rf->rf_type != BWI_RF_T_BCM20500x2050) { |
1430 | if (rf->rf_type == BWI_RF_T_BCM20530x2053 && rf->rf_rev == 1) |
1431 | tpctl->rf_atten = 6; |
1432 | goto back; |
1433 | } |
1434 | |
1435 | /* |
1436 | * NB: If we reaches here and the card is BRCM_BCM4309G, |
1437 | * then the card's PCI revision must >= 0x51 |
1438 | */ |
1439 | |
1440 | /* BCM2050 RF */ |
1441 | switch (rf->rf_rev) { |
1442 | case 1: |
1443 | if (phy->phy_mode == IEEE80211_MODE_11G) { |
1444 | if (BWI_IS_BRCM_BCM4309G(sc)((sc)->sc_pci_subvid == 0x14e4 && (sc)->sc_pci_subdid == 0x421) || BWI_IS_BRCM_BU4306(sc)((sc)->sc_pci_subvid == 0x14e4 && (sc)->sc_pci_subdid == 0x416)) |
1445 | tpctl->rf_atten = 3; |
1446 | else |
1447 | tpctl->rf_atten = 1; |
1448 | } else { |
1449 | if (BWI_IS_BRCM_BCM4309G(sc)((sc)->sc_pci_subvid == 0x14e4 && (sc)->sc_pci_subdid == 0x421)) |
1450 | tpctl->rf_atten = 7; |
1451 | else |
1452 | tpctl->rf_atten = 6; |
1453 | } |
1454 | break; |
1455 | case 2: |
1456 | if (phy->phy_mode == IEEE80211_MODE_11G) { |
1457 | /* |
1458 | * NOTE: Order of following conditions is critical |
1459 | */ |
1460 | if (BWI_IS_BRCM_BCM4309G(sc)((sc)->sc_pci_subvid == 0x14e4 && (sc)->sc_pci_subdid == 0x421)) |
1461 | tpctl->rf_atten = 3; |
1462 | else if (BWI_IS_BRCM_BU4306(sc)((sc)->sc_pci_subvid == 0x14e4 && (sc)->sc_pci_subdid == 0x416)) |
1463 | tpctl->rf_atten = 5; |
1464 | else if (sc->sc_bbp_id == BWI_BBPID_BCM43200x4320) |
1465 | tpctl->rf_atten = 4; |
1466 | else |
1467 | tpctl->rf_atten = 3; |
1468 | } else { |
1469 | tpctl->rf_atten = 6; |
1470 | } |
1471 | break; |
1472 | case 4: |
1473 | case 5: |
1474 | tpctl->rf_atten = 1; |
1475 | break; |
1476 | case 8: |
1477 | tpctl->rf_atten = 0x1a; |
1478 | break; |
1479 | } |
1480 | back: |
1481 | DPRINTF(1, "%s: bbp atten: %u, rf atten: %u, ctrl1: %u, ctrl2: %u\n", |
1482 | sc->sc_dev.dv_xname, tpctl->bbp_atten, tpctl->rf_atten, |
1483 | tpctl->tp_ctrl1, tpctl->tp_ctrl2); |
1484 | } |
1485 | |
1486 | void |
1487 | bwi_mac_dummy_xmit(struct bwi_mac *mac) |
1488 | { |
1489 | #define PACKET_LEN 5 |
1490 | struct bwi_softc *sc = mac->mac_sc; |
1491 | struct bwi_rf *rf = &mac->mac_rf; |
1492 | const uint32_t *packet; |
1493 | uint16_t val_50c; |
1494 | int wait_max, i; |
1495 | |
1496 | static const uint32_t packet_11a[PACKET_LEN] = |
1497 | { 0x000201cc, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 }; |
1498 | static const uint32_t packet_11bg[PACKET_LEN] = |
1499 | { 0x000b846e, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 }; |
1500 | |
1501 | if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) { |
1502 | wait_max = 30; |
1503 | packet = packet_11a; |
1504 | val_50c = 1; |
1505 | } else { |
1506 | wait_max = 250; |
1507 | packet = packet_11bg; |
1508 | val_50c = 0; |
1509 | } |
1510 | |
1511 | for (i = 0; i < PACKET_LEN; ++i) |
1512 | TMPLT_WRITE_4(mac, i * 4, packet[i])bwi_tmplt_write_4((mac), (i * 4), (packet[i])); |
1513 | |
1514 | CSR_READ_4(sc, BWI_MAC_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000120 )))); /* dummy read */ |
1515 | |
1516 | CSR_WRITE_2(sc, 0x568, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x568 )), ((0)))); |
1517 | CSR_WRITE_2(sc, 0x7c0, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x7c0 )), ((0)))); |
1518 | CSR_WRITE_2(sc, 0x50c, val_50c)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x50c )), ((val_50c)))); |
1519 | CSR_WRITE_2(sc, 0x508, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x508 )), ((0)))); |
1520 | CSR_WRITE_2(sc, 0x50a, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x50a )), ((0)))); |
1521 | CSR_WRITE_2(sc, 0x54c, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x54c )), ((0)))); |
1522 | CSR_WRITE_2(sc, 0x56a, 0x14)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x56a )), ((0x14)))); |
1523 | CSR_WRITE_2(sc, 0x568, 0x826)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x568 )), ((0x826)))); |
1524 | CSR_WRITE_2(sc, 0x500, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x500 )), ((0)))); |
1525 | CSR_WRITE_2(sc, 0x502, 0x30)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x502 )), ((0x30)))); |
1526 | |
1527 | if (rf->rf_type == BWI_RF_T_BCM20500x2050 && rf->rf_rev <= 5) |
1528 | RF_WRITE(mac, 0x51, 0x17)bwi_rf_write((mac), (0x51), (0x17)); |
1529 | |
1530 | for (i = 0; i < wait_max; ++i) { |
1531 | if (CSR_READ_2(sc, 0x50e)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x50e )))) & 0x80) |
1532 | break; |
1533 | DELAY(10)(*delay_func)(10); |
1534 | } |
1535 | for (i = 0; i < 10; ++i) { |
1536 | if (CSR_READ_2(sc, 0x50e)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x50e )))) & 0x400) |
1537 | break; |
1538 | DELAY(10)(*delay_func)(10); |
1539 | } |
1540 | for (i = 0; i < 10; ++i) { |
1541 | if ((CSR_READ_2(sc, 0x690)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x690 )))) & 0x100) == 0) |
1542 | break; |
1543 | DELAY(10)(*delay_func)(10); |
1544 | } |
1545 | |
1546 | if (rf->rf_type == BWI_RF_T_BCM20500x2050 && rf->rf_rev <= 5) |
1547 | RF_WRITE(mac, 0x51, 0x37)bwi_rf_write((mac), (0x51), (0x37)); |
1548 | #undef PACKET_LEN |
1549 | } |
1550 | |
1551 | void |
1552 | bwi_mac_init_tpctl_11bg(struct bwi_mac *mac) |
1553 | { |
1554 | struct bwi_softc *sc = mac->mac_sc; |
1555 | struct bwi_phy *phy = &mac->mac_phy; |
1556 | struct bwi_rf *rf = &mac->mac_rf; |
1557 | struct bwi_tpctl tpctl_orig; |
1558 | int restore_tpctl = 0; |
1559 | |
1560 | KASSERT(phy->phy_mode != IEEE80211_MODE_11A)((phy->phy_mode != IEEE80211_MODE_11A) ? (void)0 : __assert ("diagnostic ", "/usr/src/sys/dev/ic/bwi.c", 1560, "phy->phy_mode != IEEE80211_MODE_11A" )); |
1561 | |
1562 | if (BWI_IS_BRCM_BU4306(sc)((sc)->sc_pci_subvid == 0x14e4 && (sc)->sc_pci_subdid == 0x416)) |
1563 | return; |
1564 | |
1565 | PHY_WRITE(mac, 0x28, 0x8018)bwi_phy_write((mac), (0x28), (0x8018)); |
1566 | CSR_CLRBITS_2(sc, BWI_BBP_ATTEN, 0x20)((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), ( ((0x03e6))), ((((((sc))->sc_mem_bt)->read_2((((sc))-> sc_mem_bh), (((0x03e6))))) & ~(0x20))))); |
1567 | |
1568 | if (phy->phy_mode == IEEE80211_MODE_11G) { |
1569 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) == 0) |
1570 | return; |
1571 | PHY_WRITE(mac, 0x47a, 0xc111)bwi_phy_write((mac), (0x47a), (0xc111)); |
1572 | } |
1573 | if (mac->mac_flags & BWI_MAC_F_TPCTL_INITED0x2) |
1574 | return; |
1575 | |
1576 | if (phy->phy_mode == IEEE80211_MODE_11B && phy->phy_rev >= 2 && |
1577 | rf->rf_type == BWI_RF_T_BCM20500x2050) { |
1578 | RF_SETBITS(mac, 0x76, 0x84)bwi_rf_write(((mac)), ((0x76)), (bwi_rf_read(((mac)), ((0x76) )) | (0x84))); |
1579 | } else { |
1580 | struct bwi_tpctl tpctl; |
1581 | |
1582 | /* Backup original TX power control variables */ |
1583 | bcopy(&mac->mac_tpctl, &tpctl_orig, sizeof(tpctl_orig)); |
1584 | restore_tpctl = 1; |
1585 | |
1586 | bcopy(&mac->mac_tpctl, &tpctl, sizeof(tpctl)); |
1587 | tpctl.bbp_atten = 11; |
1588 | tpctl.tp_ctrl1 = 0; |
1589 | #ifdef notyet |
1590 | if (rf->rf_rev >= 6 && rf->rf_rev <= 8) |
1591 | tpctl.rf_atten = 31; |
1592 | else |
1593 | #endif |
1594 | tpctl.rf_atten = 9; |
1595 | |
1596 | bwi_mac_set_tpctl_11bg(mac, &tpctl); |
1597 | } |
1598 | |
1599 | bwi_mac_dummy_xmit(mac); |
1600 | |
1601 | mac->mac_flags |= BWI_MAC_F_TPCTL_INITED0x2; |
1602 | rf->rf_base_tssi = PHY_READ(mac, 0x29)bwi_phy_read((mac), (0x29)); |
1603 | DPRINTF(1, "%s: base tssi %d\n", sc->sc_dev.dv_xname, rf->rf_base_tssi); |
1604 | |
1605 | if (abs(rf->rf_base_tssi - rf->rf_idle_tssi) >= 20) { |
1606 | printf("%s: base tssi measure failed\n", sc->sc_dev.dv_xname); |
1607 | mac->mac_flags |= BWI_MAC_F_TPCTL_ERROR0x40; |
1608 | } |
1609 | |
1610 | if (restore_tpctl) |
1611 | bwi_mac_set_tpctl_11bg(mac, &tpctl_orig); |
1612 | else |
1613 | RF_CLRBITS(mac, 0x76, 0x84)bwi_rf_write(((mac)), ((0x76)), (bwi_rf_read(((mac)), ((0x76) )) & ~(0x84))); |
1614 | |
1615 | bwi_rf_clear_tssi(mac); |
1616 | } |
1617 | |
1618 | void |
1619 | bwi_mac_detach(struct bwi_mac *mac) |
1620 | { |
1621 | bwi_mac_fw_free(mac); |
1622 | } |
1623 | |
1624 | int |
1625 | bwi_get_firmware(const char *name, const uint8_t *ucode, size_t size_ucode, |
1626 | size_t *size, size_t *offset) |
1627 | { |
1628 | int i, nfiles, off = 0, ret = 1; |
1629 | struct fwheader *h; |
1630 | |
1631 | if ((h = malloc(sizeof(struct fwheader), M_DEVBUF2, M_NOWAIT0x0002)) == NULL((void *)0)) |
1632 | return (ret); |
1633 | |
1634 | /* get number of firmware files */ |
1635 | bcopy(ucode, &nfiles, sizeof(nfiles)); |
1636 | nfiles = ntohl(nfiles)(__uint32_t)(__builtin_constant_p(nfiles) ? (__uint32_t)(((__uint32_t )(nfiles) & 0xff) << 24 | ((__uint32_t)(nfiles) & 0xff00) << 8 | ((__uint32_t)(nfiles) & 0xff0000) >> 8 | ((__uint32_t)(nfiles) & 0xff000000) >> 24) : __swap32md (nfiles)); |
1637 | off += sizeof(nfiles); |
1638 | |
1639 | /* parse header and search the firmware */ |
1640 | for (i = 0; i < nfiles && off < size_ucode; i++) { |
1641 | bzero(h, sizeof(struct fwheader))__builtin_bzero((h), (sizeof(struct fwheader))); |
1642 | bcopy(ucode + off, h, sizeof(struct fwheader)); |
1643 | off += sizeof(struct fwheader); |
1644 | |
1645 | if (strcmp(name, h->filename) == 0) { |
1646 | ret = 0; |
1647 | *size = ntohl(h->filesize)(__uint32_t)(__builtin_constant_p(h->filesize) ? (__uint32_t )(((__uint32_t)(h->filesize) & 0xff) << 24 | ((__uint32_t )(h->filesize) & 0xff00) << 8 | ((__uint32_t)(h-> filesize) & 0xff0000) >> 8 | ((__uint32_t)(h->filesize ) & 0xff000000) >> 24) : __swap32md(h->filesize) ); |
1648 | *offset = ntohl(h->fileoffset)(__uint32_t)(__builtin_constant_p(h->fileoffset) ? (__uint32_t )(((__uint32_t)(h->fileoffset) & 0xff) << 24 | ( (__uint32_t)(h->fileoffset) & 0xff00) << 8 | ((__uint32_t )(h->fileoffset) & 0xff0000) >> 8 | ((__uint32_t )(h->fileoffset) & 0xff000000) >> 24) : __swap32md (h->fileoffset)); |
1649 | break; |
1650 | } |
1651 | } |
1652 | |
1653 | free(h, M_DEVBUF2, sizeof *h); |
1654 | |
1655 | return (ret); |
1656 | } |
1657 | |
1658 | int |
1659 | bwi_fwimage_is_valid(struct bwi_softc *sc, uint8_t *fw, size_t fw_len, |
1660 | char *fw_name, uint8_t fw_type) |
1661 | { |
1662 | const struct bwi_fwhdr *hdr; |
1663 | |
1664 | if (fw_len < sizeof(*hdr)) { |
1665 | printf("%s: invalid firmware (%s): invalid size %zu\n", |
1666 | sc->sc_dev.dv_xname, fw_name, fw_len); |
1667 | return (1); |
1668 | } |
1669 | |
1670 | hdr = (const struct bwi_fwhdr *)fw; |
1671 | |
1672 | if (fw_type != BWI_FW_T_IV'i') { |
1673 | /* |
1674 | * Don't verify IV's size, it has different meaning |
1675 | */ |
1676 | if (betoh32(hdr->fw_size)(__uint32_t)(__builtin_constant_p(hdr->fw_size) ? (__uint32_t )(((__uint32_t)(hdr->fw_size) & 0xff) << 24 | (( __uint32_t)(hdr->fw_size) & 0xff00) << 8 | ((__uint32_t )(hdr->fw_size) & 0xff0000) >> 8 | ((__uint32_t) (hdr->fw_size) & 0xff000000) >> 24) : __swap32md (hdr->fw_size)) != fw_len - sizeof(*hdr)) { |
1677 | printf("%s: invalid firmware (%s): size mismatch, " |
1678 | "fw %u, real %zu\n", |
1679 | sc->sc_dev.dv_xname, |
1680 | fw_name, |
1681 | betoh32(hdr->fw_size)(__uint32_t)(__builtin_constant_p(hdr->fw_size) ? (__uint32_t )(((__uint32_t)(hdr->fw_size) & 0xff) << 24 | (( __uint32_t)(hdr->fw_size) & 0xff00) << 8 | ((__uint32_t )(hdr->fw_size) & 0xff0000) >> 8 | ((__uint32_t) (hdr->fw_size) & 0xff000000) >> 24) : __swap32md (hdr->fw_size)), |
1682 | fw_len - sizeof(*hdr)); |
1683 | return (1); |
1684 | } |
1685 | } |
1686 | |
1687 | if (hdr->fw_type != fw_type) { |
1688 | printf("%s: invalid firmware (%s): type mismatch, " |
1689 | "fw \'%c\', target \'%c\'\n", |
1690 | sc->sc_dev.dv_xname, fw_name, hdr->fw_type, fw_type); |
1691 | return (1); |
1692 | } |
1693 | |
1694 | if (hdr->fw_gen != BWI_FW_GEN_11) { |
1695 | printf("%s: invalid firmware (%s): wrong generation, " |
1696 | "fw %d, target %d\n", |
1697 | sc->sc_dev.dv_xname, fw_name, hdr->fw_gen, BWI_FW_GEN_11); |
1698 | return (1); |
1699 | } |
1700 | |
1701 | return (0); |
1702 | } |
1703 | |
1704 | int |
1705 | bwi_mac_fw_alloc(struct bwi_mac *mac) |
1706 | { |
1707 | struct bwi_softc *sc = mac->mac_sc; |
1708 | char *name = "bwi-airforce"; |
1709 | size_t offset; |
1710 | char fwname[64]; |
1711 | int idx, error; |
1712 | |
1713 | if (mac->mac_fw == NULL((void *)0)) { |
1714 | error = loadfirmware(name, &mac->mac_fw, &mac->mac_fw_size); |
1715 | if (error != 0) { |
1716 | printf("%s: error %d, could not read firmware %s\n", |
1717 | sc->sc_dev.dv_xname, error, name); |
1718 | mac->mac_fw = NULL((void *)0); |
1719 | return (EIO5); |
1720 | } |
1721 | } |
1722 | |
1723 | if (mac->mac_ucode == NULL((void *)0)) { |
1724 | snprintf(fwname, sizeof(fwname), "ucode%d.fw", |
1725 | mac->mac_revmac_regwin.rw_rev >= 5 ? 5 : mac->mac_revmac_regwin.rw_rev); |
1726 | |
1727 | error = bwi_get_firmware(fwname, mac->mac_fw, mac->mac_fw_size, |
1728 | &mac->mac_ucode_size, &offset); |
1729 | if (error != 0) { |
1730 | printf("%s: error %d, could not read firmware %s!\n", |
1731 | sc->sc_dev.dv_xname, error, fwname); |
1732 | return (ENOMEM12); |
1733 | } |
1734 | mac->mac_ucode = (mac->mac_fw + offset); |
1735 | DPRINTF(1, "%s: loaded firmware file %s\n", |
1736 | sc->sc_dev.dv_xname, fwname); |
1737 | |
1738 | if (bwi_fwimage_is_valid(sc, mac->mac_ucode, |
1739 | mac->mac_ucode_size, fwname, BWI_FW_T_UCODE'u')) |
1740 | return (EINVAL22); |
1741 | } |
1742 | |
1743 | if (mac->mac_pcm == NULL((void *)0)) { |
1744 | snprintf(fwname, sizeof(fwname), "pcm%d.fw", |
1745 | mac->mac_revmac_regwin.rw_rev < 5 ? 4 : 5); |
1746 | |
1747 | error = bwi_get_firmware(fwname, mac->mac_fw, mac->mac_fw_size, |
1748 | &mac->mac_pcm_size, &offset); |
1749 | if (error != 0) { |
1750 | printf("%s: error %d, could not read firmware %s!\n", |
1751 | sc->sc_dev.dv_xname, error, fwname); |
1752 | return (ENOMEM12); |
1753 | } |
1754 | mac->mac_pcm = (mac->mac_fw + offset); |
1755 | DPRINTF(1, "%s: loaded firmware file %s\n", |
1756 | sc->sc_dev.dv_xname, fwname); |
1757 | |
1758 | if (bwi_fwimage_is_valid(sc, mac->mac_pcm, |
1759 | mac->mac_pcm_size, fwname, BWI_FW_T_PCM'p')) |
1760 | return (EINVAL22); |
1761 | } |
1762 | |
1763 | if (mac->mac_iv == NULL((void *)0)) { |
1764 | /* TODO: 11A */ |
1765 | if (mac->mac_revmac_regwin.rw_rev == 2 || mac->mac_revmac_regwin.rw_rev == 4) { |
1766 | idx = 2; |
1767 | } else if (mac->mac_revmac_regwin.rw_rev >= 5 && mac->mac_revmac_regwin.rw_rev <= 10) { |
1768 | idx = 5; |
1769 | } else { |
1770 | printf("%s: no suitable IV for MAC rev %d\n", |
1771 | sc->sc_dev.dv_xname, mac->mac_revmac_regwin.rw_rev); |
1772 | return (ENODEV19); |
1773 | } |
1774 | |
1775 | snprintf(fwname, sizeof(fwname), "b0g0initvals%d.fw", idx); |
1776 | |
1777 | error = bwi_get_firmware(fwname, mac->mac_fw, mac->mac_fw_size, |
1778 | &mac->mac_iv_size, &offset); |
1779 | if (error != 0) { |
1780 | printf("%s: error %d, could not read firmware %s!\n", |
1781 | sc->sc_dev.dv_xname, error, fwname); |
1782 | return (ENOMEM12); |
1783 | } |
1784 | mac->mac_iv = (mac->mac_fw + offset); |
1785 | DPRINTF(1, "%s: loaded firmware file %s\n", |
1786 | sc->sc_dev.dv_xname, fwname); |
1787 | |
1788 | if (bwi_fwimage_is_valid(sc, mac->mac_iv, |
1789 | mac->mac_iv_size, fwname, BWI_FW_T_IV'i')) |
1790 | return (EINVAL22); |
1791 | } |
1792 | |
1793 | if (mac->mac_iv_ext == NULL((void *)0)) { |
1794 | /* TODO: 11A */ |
1795 | if (mac->mac_revmac_regwin.rw_rev == 2 || mac->mac_revmac_regwin.rw_rev == 4 || |
1796 | mac->mac_revmac_regwin.rw_rev >= 11) { |
1797 | /* No extended IV */ |
1798 | goto back; |
1799 | } else if (mac->mac_revmac_regwin.rw_rev >= 5 && mac->mac_revmac_regwin.rw_rev <= 10) { |
1800 | idx = 5; |
1801 | } else { |
1802 | printf("%s: no suitable ExtIV for MAC rev %d\n", |
1803 | sc->sc_dev.dv_xname, mac->mac_revmac_regwin.rw_rev); |
1804 | return (ENODEV19); |
1805 | } |
1806 | |
1807 | snprintf(fwname, sizeof(fwname), "b0g0bsinitvals%d.fw", idx); |
1808 | |
1809 | error = bwi_get_firmware(fwname, mac->mac_fw, mac->mac_fw_size, |
1810 | &mac->mac_iv_ext_size, &offset); |
1811 | if (error != 0) { |
1812 | printf("%s: error %d, could not read firmware %s!\n", |
1813 | sc->sc_dev.dv_xname, error, fwname); |
1814 | return (ENOMEM12); |
1815 | } |
1816 | mac->mac_iv_ext = (mac->mac_fw + offset); |
1817 | DPRINTF(1, "%s: loaded firmware file %s\n", |
1818 | sc->sc_dev.dv_xname, fwname); |
1819 | |
1820 | if (bwi_fwimage_is_valid(sc, mac->mac_iv_ext, |
1821 | mac->mac_iv_ext_size, fwname, BWI_FW_T_IV'i')) |
1822 | return (EINVAL22); |
1823 | } |
1824 | |
1825 | back: |
1826 | return (0); |
1827 | } |
1828 | |
1829 | void |
1830 | bwi_mac_fw_free(struct bwi_mac *mac) |
1831 | { |
1832 | if (mac->mac_fw != NULL((void *)0)) { |
1833 | free(mac->mac_fw, M_DEVBUF2, mac->mac_fw_size); |
1834 | mac->mac_fw = NULL((void *)0); |
1835 | } |
1836 | } |
1837 | |
1838 | int |
1839 | bwi_mac_fw_load(struct bwi_mac *mac) |
1840 | { |
1841 | struct bwi_softc *sc = mac->mac_sc; |
1842 | uint16_t fw_rev; |
1843 | const uint32_t *fw; |
1844 | int fw_len, i, error = 0; |
1845 | |
1846 | /* |
1847 | * Load FW image |
1848 | */ |
1849 | fw = (const uint32_t *)(mac->mac_ucode + BWI_FWHDR_SZsizeof(struct bwi_fwhdr)); |
1850 | fw_len = (mac->mac_ucode_size - BWI_FWHDR_SZsizeof(struct bwi_fwhdr)) / sizeof(uint32_t); |
1851 | |
1852 | CSR_WRITE_4(sc, BWI_MOBJ_CTRL,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((0x0 | 0x100) << 16 | (0)))))) |
1853 | BWI_MOBJ_CTRL_VAL(BWI_FW_UCODE_MOBJ | BWI_WR_MOBJ_AUTOINC, 0))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((0x0 | 0x100) << 16 | (0)))))); |
1854 | for (i = 0; i < fw_len; ++i) { |
1855 | CSR_WRITE_4(sc, BWI_MOBJ_DATA, betoh32(fw[i]))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000164 )), (((__uint32_t)(__builtin_constant_p(fw[i]) ? (__uint32_t) (((__uint32_t)(fw[i]) & 0xff) << 24 | ((__uint32_t) (fw[i]) & 0xff00) << 8 | ((__uint32_t)(fw[i]) & 0xff0000) >> 8 | ((__uint32_t)(fw[i]) & 0xff000000 ) >> 24) : __swap32md(fw[i])))))); |
1856 | DELAY(10)(*delay_func)(10); |
1857 | } |
1858 | |
1859 | /* |
1860 | * Load PCM image |
1861 | */ |
1862 | fw = (const uint32_t *)(mac->mac_pcm + BWI_FWHDR_SZsizeof(struct bwi_fwhdr)); |
1863 | fw_len = (mac->mac_pcm_size - BWI_FWHDR_SZsizeof(struct bwi_fwhdr)) / sizeof(uint32_t); |
1864 | |
1865 | CSR_WRITE_4(sc, BWI_MOBJ_CTRL,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((0x3) << 16 | (0x01ea)))))) |
1866 | BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01ea))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((0x3) << 16 | (0x01ea)))))); |
1867 | CSR_WRITE_4(sc, BWI_MOBJ_DATA, 0x4000)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000164 )), ((0x4000)))); |
1868 | |
1869 | CSR_WRITE_4(sc, BWI_MOBJ_CTRL,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((0x3) << 16 | (0x01eb)))))) |
1870 | BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01eb))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000160 )), ((((0x3) << 16 | (0x01eb)))))); |
1871 | for (i = 0; i < fw_len; ++i) { |
1872 | CSR_WRITE_4(sc, BWI_MOBJ_DATA, betoh32(fw[i]))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000164 )), (((__uint32_t)(__builtin_constant_p(fw[i]) ? (__uint32_t) (((__uint32_t)(fw[i]) & 0xff) << 24 | ((__uint32_t) (fw[i]) & 0xff00) << 8 | ((__uint32_t)(fw[i]) & 0xff0000) >> 8 | ((__uint32_t)(fw[i]) & 0xff000000 ) >> 24) : __swap32md(fw[i])))))); |
1873 | DELAY(10)(*delay_func)(10); |
1874 | } |
1875 | |
1876 | CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_ALL_INTRS)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000128 )), ((0xffffffff)))); |
1877 | CSR_WRITE_4(sc, BWI_MAC_STATUS,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000120 )), (((1U << 1) | (1U << 10) | (1U << 17))) )) |
1878 | BWI_MAC_STATUS_UCODE_START |(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000120 )), (((1U << 1) | (1U << 10) | (1U << 17))) )) |
1879 | BWI_MAC_STATUS_IHREN |(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000120 )), (((1U << 1) | (1U << 10) | (1U << 17))) )) |
1880 | BWI_MAC_STATUS_INFRA)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000120 )), (((1U << 1) | (1U << 10) | (1U << 17))) )); |
1881 | |
1882 | #define NRETRY 200 |
1883 | for (i = 0; i < NRETRY; ++i) { |
1884 | uint32_t intr_status; |
1885 | |
1886 | intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000128 )))); |
1887 | if (intr_status == BWI_INTR_READY(1 << 0)) |
1888 | break; |
1889 | DELAY(10)(*delay_func)(10); |
1890 | } |
1891 | if (i == NRETRY) { |
1892 | printf("%s: firmware (fw & pcm) loading timed out\n", |
1893 | sc->sc_dev.dv_xname); |
1894 | error = ETIMEDOUT60; |
1895 | goto out; |
1896 | } |
1897 | #undef NRETRY |
1898 | |
1899 | CSR_READ_4(sc, BWI_MAC_INTR_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000128 )))); /* dummy read */ |
1900 | |
1901 | fw_rev = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWREV)bwi_memobj_read_2((mac), (0x1), (0x0)); |
1902 | if (fw_rev > BWI_FW_VERSION3_REVMAX0x128) { |
1903 | printf("%s: firmware version 4 is not supported yet\n", |
1904 | sc->sc_dev.dv_xname); |
1905 | error = ENODEV19; |
1906 | goto out; |
1907 | } |
1908 | |
1909 | DPRINTF(1, "%s: firmware rev 0x%04x, patch level 0x%04x\n", |
1910 | sc->sc_dev.dv_xname, fw_rev, |
1911 | MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV)); |
1912 | |
1913 | out: |
1914 | return (error); |
1915 | } |
1916 | |
1917 | int |
1918 | bwi_mac_gpio_init(struct bwi_mac *mac) |
1919 | { |
1920 | struct bwi_softc *sc = mac->mac_sc; |
1921 | struct bwi_regwin *old, *gpio_rw; |
1922 | uint32_t filt, bits; |
1923 | int error; |
1924 | |
1925 | CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_GPOSEL_MASK)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000120))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000120))))) & ~((3U << 14)) )))); |
1926 | /* TODO: LED */ |
1927 | |
1928 | CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0xf)((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), ( ((0x049e))), ((((((sc))->sc_mem_bt)->read_2((((sc))-> sc_mem_bh), (((0x049e))))) | (0xf))))); |
1929 | |
1930 | filt = 0x1f; |
1931 | bits = 0xf; |
1932 | if (sc->sc_bbp_id == BWI_BBPID_BCM43010x4301) { |
1933 | filt |= 0x60; |
1934 | bits |= 0x60; |
1935 | } |
1936 | if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9(1 << 1)) { |
1937 | CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0x200)((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), ( ((0x049e))), ((((((sc))->sc_mem_bt)->read_2((((sc))-> sc_mem_bh), (((0x049e))))) | (0x200))))); |
1938 | filt |= 0x200; |
1939 | bits |= 0x200; |
1940 | } |
1941 | |
1942 | gpio_rw = BWI_GPIO_REGWIN(sc)(((&(sc)->sc_com_regwin)->rw_flags & 0x1) ? & (sc)->sc_com_regwin : &(sc)->sc_bus_regwin); |
1943 | error = bwi_regwin_switch(sc, gpio_rw, &old); |
1944 | if (error) |
1945 | return (error); |
1946 | |
1947 | CSR_FILT_SETBITS_4(sc, BWI_GPIO_CTRL, filt, bits)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x0000006c))), (((((((sc))->sc_mem_bt)->read_4((((sc) )->sc_mem_bh), (((0x0000006c))))) & (filt)) | (bits))) )); |
1948 | |
1949 | return (bwi_regwin_switch(sc, old, NULL((void *)0))); |
1950 | } |
1951 | |
1952 | int |
1953 | bwi_mac_gpio_fini(struct bwi_mac *mac) |
1954 | { |
1955 | struct bwi_softc *sc = mac->mac_sc; |
1956 | struct bwi_regwin *old, *gpio_rw; |
1957 | int error; |
1958 | |
1959 | gpio_rw = BWI_GPIO_REGWIN(sc)(((&(sc)->sc_com_regwin)->rw_flags & 0x1) ? & (sc)->sc_com_regwin : &(sc)->sc_bus_regwin); |
1960 | error = bwi_regwin_switch(sc, gpio_rw, &old); |
1961 | if (error) |
1962 | return (error); |
1963 | |
1964 | CSR_WRITE_4(sc, BWI_GPIO_CTRL, 0)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x0000006c )), ((0)))); |
1965 | |
1966 | return (bwi_regwin_switch(sc, old, NULL((void *)0))); |
1967 | } |
1968 | |
1969 | int |
1970 | bwi_mac_fw_load_iv(struct bwi_mac *mac, uint8_t *fw, size_t fw_len) |
1971 | { |
1972 | struct bwi_softc *sc = mac->mac_sc; |
1973 | const struct bwi_fwhdr *hdr; |
1974 | const struct bwi_fw_iv *iv; |
1975 | int n, i, iv_img_size; |
1976 | |
1977 | /* Get the number of IVs in the IV image */ |
1978 | hdr = (const struct bwi_fwhdr *)fw; |
1979 | n = betoh32(hdr->fw_iv_cnt)(__uint32_t)(__builtin_constant_p(hdr->fw_size) ? (__uint32_t )(((__uint32_t)(hdr->fw_size) & 0xff) << 24 | (( __uint32_t)(hdr->fw_size) & 0xff00) << 8 | ((__uint32_t )(hdr->fw_size) & 0xff0000) >> 8 | ((__uint32_t) (hdr->fw_size) & 0xff000000) >> 24) : __swap32md (hdr->fw_size)); |
1980 | DPRINTF(1, "%s: IV count %d\n", sc->sc_dev.dv_xname, n); |
1981 | |
1982 | /* Calculate the IV image size, for later sanity check */ |
1983 | iv_img_size = fw_len - sizeof(*hdr); |
1984 | |
1985 | /* Locate the first IV */ |
1986 | iv = (const struct bwi_fw_iv *)(fw + sizeof(*hdr)); |
1987 | |
1988 | for (i = 0; i < n; ++i) { |
1989 | uint16_t iv_ofs, ofs; |
1990 | int sz = 0; |
1991 | |
1992 | if (iv_img_size < sizeof(iv->iv_ofs)) { |
1993 | printf("%s: invalid IV image, ofs\n", |
1994 | sc->sc_dev.dv_xname); |
1995 | return (EINVAL22); |
1996 | } |
1997 | iv_img_size -= sizeof(iv->iv_ofs); |
1998 | sz += sizeof(iv->iv_ofs); |
1999 | |
2000 | iv_ofs = betoh16(iv->iv_ofs)(__uint16_t)(__builtin_constant_p(iv->iv_ofs) ? (__uint16_t )(((__uint16_t)(iv->iv_ofs) & 0xffU) << 8 | ((__uint16_t )(iv->iv_ofs) & 0xff00U) >> 8) : __swap16md(iv-> iv_ofs)); |
2001 | |
2002 | ofs = __SHIFTOUT(iv_ofs, BWI_FW_IV_OFS_MASK)(((iv_ofs) & (0x7fff)) / ((((0x7fff) - 1) & (0x7fff)) ^ (0x7fff))); |
2003 | if (ofs >= 0x1000) { |
2004 | printf("%s: invalid ofs (0x%04x) for %dth iv\n", |
2005 | sc->sc_dev.dv_xname, ofs, i); |
2006 | return (EINVAL22); |
2007 | } |
2008 | |
2009 | if (iv_ofs & BWI_FW_IV_IS_32BIT(1 << 15)) { |
2010 | uint32_t val32; |
2011 | |
2012 | if (iv_img_size < sizeof(iv->iv_val.val32)) { |
2013 | printf("%s: invalid IV image, val32\n", |
2014 | sc->sc_dev.dv_xname); |
2015 | return (EINVAL22); |
2016 | } |
2017 | iv_img_size -= sizeof(iv->iv_val.val32); |
2018 | sz += sizeof(iv->iv_val.val32); |
2019 | |
2020 | val32 = betoh32(iv->iv_val.val32)(__uint32_t)(__builtin_constant_p(iv->iv_val.val32) ? (__uint32_t )(((__uint32_t)(iv->iv_val.val32) & 0xff) << 24 | ((__uint32_t)(iv->iv_val.val32) & 0xff00) << 8 | ((__uint32_t)(iv->iv_val.val32) & 0xff0000) >> 8 | ((__uint32_t)(iv->iv_val.val32) & 0xff000000) >> 24) : __swap32md(iv->iv_val.val32)); |
2021 | CSR_WRITE_4(sc, ofs, val32)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((ofs )), ((val32)))); |
2022 | } else { |
2023 | uint16_t val16; |
2024 | |
2025 | if (iv_img_size < sizeof(iv->iv_val.val16)) { |
2026 | printf("%s: invalid IV image, val16\n", |
2027 | sc->sc_dev.dv_xname); |
2028 | return (EINVAL22); |
2029 | } |
2030 | iv_img_size -= sizeof(iv->iv_val.val16); |
2031 | sz += sizeof(iv->iv_val.val16); |
2032 | |
2033 | val16 = betoh16(iv->iv_val.val16)(__uint16_t)(__builtin_constant_p(iv->iv_val.val16) ? (__uint16_t )(((__uint16_t)(iv->iv_val.val16) & 0xffU) << 8 | ((__uint16_t)(iv->iv_val.val16) & 0xff00U) >> 8 ) : __swap16md(iv->iv_val.val16)); |
2034 | CSR_WRITE_2(sc, ofs, val16)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((ofs )), ((val16)))); |
2035 | } |
2036 | |
2037 | iv = (const struct bwi_fw_iv *)((const uint8_t *)iv + sz); |
2038 | } |
2039 | |
2040 | if (iv_img_size != 0) { |
2041 | printf("%s: invalid IV image, size left %d\n", |
2042 | sc->sc_dev.dv_xname, iv_img_size); |
2043 | return (EINVAL22); |
2044 | } |
2045 | |
2046 | return (0); |
2047 | } |
2048 | |
2049 | int |
2050 | bwi_mac_fw_init(struct bwi_mac *mac) |
2051 | { |
2052 | struct bwi_softc *sc = mac->mac_sc; |
2053 | int error; |
2054 | |
2055 | error = bwi_mac_fw_load_iv(mac, mac->mac_iv, mac->mac_iv_size); |
2056 | if (error) { |
2057 | printf("%s: load IV failed\n", sc->sc_dev.dv_xname); |
2058 | return (error); |
2059 | } |
2060 | |
2061 | if (mac->mac_iv_ext != NULL((void *)0)) { |
2062 | error = bwi_mac_fw_load_iv(mac, mac->mac_iv_ext, |
2063 | mac->mac_iv_ext_size); |
2064 | if (error) |
2065 | printf("%s: load ExtIV failed\n", sc->sc_dev.dv_xname); |
2066 | } |
2067 | |
2068 | return (error); |
2069 | } |
2070 | |
2071 | void |
2072 | bwi_mac_opmode_init(struct bwi_mac *mac) |
2073 | { |
2074 | struct bwi_softc *sc = mac->mac_sc; |
2075 | struct ieee80211com *ic = &sc->sc_ic; |
2076 | uint32_t mac_status; |
2077 | uint16_t pre_tbtt; |
2078 | |
2079 | CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000120))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000120))))) & ~((1U << 17)) )))); |
2080 | CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000120))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000120))))) | ((1U << 17)))))); |
2081 | CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000120))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000120))))) | ((1U << 20)))))); |
2082 | |
2083 | /* Set probe resp timeout to infinite */ |
2084 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 0)bwi_memobj_write_2((mac), (0x1), (0x74), (0)); |
2085 | |
2086 | /* |
2087 | * TODO: factor out following part |
2088 | */ |
2089 | |
2090 | mac_status = CSR_READ_4(sc, BWI_MAC_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000120 )))); |
2091 | mac_status &= ~(BWI_MAC_STATUS_OPMODE_HOSTAP(1U << 18) | |
2092 | BWI_MAC_STATUS_PASS_CTL(1U << 22) | |
2093 | BWI_MAC_STATUS_PASS_BADPLCP(1U << 21) | |
2094 | BWI_MAC_STATUS_PASS_BADFCS(1U << 23) | |
2095 | BWI_MAC_STATUS_PROMISC(1U << 24)); |
2096 | mac_status |= BWI_MAC_STATUS_INFRA(1U << 17); |
2097 | |
2098 | /* Always turn on PROMISC on old hardware */ |
2099 | if (mac->mac_revmac_regwin.rw_rev < 5) |
2100 | mac_status |= BWI_MAC_STATUS_PROMISC(1U << 24); |
2101 | |
2102 | switch (ic->ic_opmode) { |
2103 | #ifndef IEEE80211_STA_ONLY |
2104 | case IEEE80211_M_IBSS: |
2105 | mac_status &= ~BWI_MAC_STATUS_INFRA(1U << 17); |
2106 | break; |
2107 | case IEEE80211_M_HOSTAP: |
2108 | mac_status |= BWI_MAC_STATUS_OPMODE_HOSTAP(1U << 18); |
2109 | break; |
2110 | #endif |
2111 | case IEEE80211_M_MONITOR: |
2112 | #if 0 |
2113 | /* Do you want data from your microwave oven? */ |
2114 | mac_status |= BWI_MAC_STATUS_PASS_CTL(1U << 22) | |
2115 | BWI_MAC_STATUS_PASS_BADPLCP(1U << 21) | |
2116 | BWI_MAC_STATUS_PASS_BADFCS(1U << 23); |
2117 | #else |
2118 | mac_status |= BWI_MAC_STATUS_PASS_CTL(1U << 22); |
2119 | #endif |
2120 | /* Promisc? */ |
2121 | break; |
2122 | default: |
2123 | break; |
2124 | } |
2125 | |
2126 | if (ic->ic_ific_ac.ac_if.if_flags & IFF_PROMISC0x100) |
2127 | mac_status |= BWI_MAC_STATUS_PROMISC(1U << 24); |
2128 | |
2129 | CSR_WRITE_4(sc, BWI_MAC_STATUS, mac_status)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000120 )), ((mac_status)))); |
2130 | |
2131 | #ifndef IEEE80211_STA_ONLY |
2132 | if (ic->ic_opmode != IEEE80211_M_IBSS && |
2133 | ic->ic_opmode != IEEE80211_M_HOSTAP) { |
2134 | #endif |
2135 | if (sc->sc_bbp_id == BWI_BBPID_BCM43060x4306 && sc->sc_bbp_rev == 3) |
2136 | pre_tbtt = 100; |
2137 | else |
2138 | pre_tbtt = 50; |
2139 | #ifndef IEEE80211_STA_ONLY |
2140 | } else |
2141 | pre_tbtt = 2; |
2142 | #endif |
2143 | CSR_WRITE_2(sc, BWI_MAC_PRE_TBTT, pre_tbtt)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x0612 )), ((pre_tbtt)))); |
2144 | } |
2145 | |
2146 | void |
2147 | bwi_mac_hostflags_init(struct bwi_mac *mac) |
2148 | { |
2149 | struct bwi_softc *sc = mac->mac_sc; |
2150 | struct bwi_phy *phy = &mac->mac_phy; |
2151 | struct bwi_rf *rf = &mac->mac_rf; |
2152 | uint64_t host_flags; |
2153 | |
2154 | if (phy->phy_mode == IEEE80211_MODE_11A) |
2155 | return; |
2156 | |
2157 | host_flags = HFLAGS_READ(mac)bwi_hostflags_read((mac)); |
2158 | host_flags |= BWI_HFLAG_SYM_WA0x2ULL; |
2159 | |
2160 | if (phy->phy_mode == IEEE80211_MODE_11G) { |
2161 | if (phy->phy_rev == 1) |
2162 | host_flags |= BWI_HFLAG_GDC_WA0x20ULL; |
2163 | if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9(1 << 1)) |
2164 | host_flags |= BWI_HFLAG_OFDM_PA0x40ULL; |
2165 | } else if (phy->phy_mode == IEEE80211_MODE_11B) { |
2166 | if (phy->phy_rev >= 2 && rf->rf_type == BWI_RF_T_BCM20500x2050) |
2167 | host_flags &= ~BWI_HFLAG_GDC_WA0x20ULL; |
2168 | } else { |
2169 | panic("unknown PHY mode %u", phy->phy_mode); |
2170 | } |
2171 | |
2172 | HFLAGS_WRITE(mac, host_flags)bwi_hostflags_write((mac), (host_flags)); |
2173 | } |
2174 | |
2175 | void |
2176 | bwi_mac_bss_param_init(struct bwi_mac *mac) |
2177 | { |
2178 | struct bwi_softc *sc = mac->mac_sc; |
2179 | struct bwi_phy *phy = &mac->mac_phy; |
2180 | struct bwi_retry_lim lim; |
2181 | uint16_t cw_min; |
2182 | |
2183 | /* |
2184 | * Set short/long retry limits |
2185 | */ |
2186 | bzero(&lim, sizeof(lim))__builtin_bzero((&lim), (sizeof(lim))); |
2187 | lim.shretry = BWI_SHRETRY7; |
2188 | lim.shretry_fb = BWI_SHRETRY_FB3; |
2189 | lim.lgretry = BWI_LGRETRY4; |
2190 | lim.lgretry_fb = BWI_LGRETRY_FB2; |
2191 | bwi_mac_set_retry_lim(mac, &lim); |
2192 | |
2193 | /* |
2194 | * Implicitly prevent firmware from sending probe response |
2195 | * by setting its "probe response timeout" to 1us. |
2196 | */ |
2197 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 1)bwi_memobj_write_2((mac), (0x1), (0x74), (1)); |
2198 | |
2199 | /* |
2200 | * XXX MAC level acknowledge and CW min/max should depend |
2201 | * on the char rateset of the IBSS/BSS to join. |
2202 | */ |
2203 | |
2204 | /* |
2205 | * Set MAC level acknowledge rates |
2206 | */ |
2207 | bwi_mac_set_ackrates(mac, &sc->sc_ic.ic_sup_rates[phy->phy_mode]); |
2208 | |
2209 | /* |
2210 | * Set CW min |
2211 | */ |
2212 | if (phy->phy_mode == IEEE80211_MODE_11B) |
2213 | cw_min = IEEE80211_CW_MIN_031; |
2214 | else |
2215 | cw_min = IEEE80211_CW_MIN_115; |
2216 | MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMIN, cw_min)bwi_memobj_write_2((mac), (0x2), (0xc), (cw_min)); |
2217 | |
2218 | /* |
2219 | * Set CW max |
2220 | */ |
2221 | MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMAX,bwi_memobj_write_2((mac), (0x2), (0x10), (1023)) |
2222 | IEEE80211_CW_MAX)bwi_memobj_write_2((mac), (0x2), (0x10), (1023)); |
2223 | } |
2224 | |
2225 | void |
2226 | bwi_mac_set_retry_lim(struct bwi_mac *mac, const struct bwi_retry_lim *lim) |
2227 | { |
2228 | /* Short/Long retry limit */ |
2229 | MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_SHRETRY,bwi_memobj_write_2((mac), (0x2), (0x18), (lim->shretry)) |
2230 | lim->shretry)bwi_memobj_write_2((mac), (0x2), (0x18), (lim->shretry)); |
2231 | MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_LGRETRY,bwi_memobj_write_2((mac), (0x2), (0x1c), (lim->lgretry)) |
2232 | lim->lgretry)bwi_memobj_write_2((mac), (0x2), (0x1c), (lim->lgretry)); |
2233 | |
2234 | /* Short/Long retry fallback limit */ |
2235 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SHRETRY_FB,bwi_memobj_write_2((mac), (0x1), (0x44), (lim->shretry_fb) ) |
2236 | lim->shretry_fb)bwi_memobj_write_2((mac), (0x1), (0x44), (lim->shretry_fb) ); |
2237 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_LGRETEY_FB,bwi_memobj_write_2((mac), (0x1), (0x46), (lim->lgretry_fb) ) |
2238 | lim->lgretry_fb)bwi_memobj_write_2((mac), (0x1), (0x46), (lim->lgretry_fb) ); |
2239 | } |
2240 | |
2241 | void |
2242 | bwi_mac_set_ackrates(struct bwi_mac *mac, const struct ieee80211_rateset *rs) |
2243 | { |
2244 | struct bwi_softc *sc; |
2245 | int i; |
2246 | |
2247 | sc = mac->mac_sc; |
2248 | |
2249 | DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__); |
2250 | |
2251 | /* XXX not standard conforming */ |
2252 | for (i = 0; i < rs->rs_nrates; ++i) { |
2253 | enum bwi_modtype modtype; |
2254 | uint16_t ofs; |
2255 | |
2256 | modtype = bwi_rate2modtype(rs->rs_rates[i]); |
2257 | switch (modtype) { |
2258 | case IEEE80211_MODTYPE_DS: |
2259 | ofs = 0x4c0; |
2260 | ofs += (ieee80211_rate2plcp(rs->rs_rates[i], |
2261 | IEEE80211_MODE_11B) & 0xf) * 2; |
2262 | break; |
2263 | case IEEE80211_MODTYPE_OFDM: |
2264 | ofs = 0x480; |
2265 | ofs += (ieee80211_rate2plcp(rs->rs_rates[i], |
2266 | IEEE80211_MODE_11G) & 0xf) * 2; |
2267 | break; |
2268 | default: |
2269 | panic("unsupported modtype %u", modtype); |
2270 | } |
2271 | |
2272 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, ofs + 0x20,bwi_memobj_write_2((mac), (0x1), (ofs + 0x20), (bwi_memobj_read_2 ((mac), (0x1), (ofs)))) |
2273 | MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs))bwi_memobj_write_2((mac), (0x1), (ofs + 0x20), (bwi_memobj_read_2 ((mac), (0x1), (ofs)))); |
2274 | } |
2275 | } |
2276 | |
2277 | int |
2278 | bwi_mac_start(struct bwi_mac *mac) |
2279 | { |
2280 | struct bwi_softc *sc = mac->mac_sc; |
2281 | |
2282 | CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000120))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000120))))) | ((1U << 0)))))); |
2283 | CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_READY)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000128 )), (((1 << 0))))); |
2284 | |
2285 | /* Flush pending bus writes */ |
2286 | CSR_READ_4(sc, BWI_MAC_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000120 )))); |
2287 | CSR_READ_4(sc, BWI_MAC_INTR_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000128 )))); |
2288 | |
2289 | return (bwi_mac_config_ps(mac)); |
2290 | } |
2291 | |
2292 | int |
2293 | bwi_mac_stop(struct bwi_mac *mac) |
2294 | { |
2295 | struct bwi_softc *sc = mac->mac_sc; |
2296 | int error, i; |
2297 | |
2298 | error = bwi_mac_config_ps(mac); |
2299 | if (error) |
2300 | return (error); |
2301 | |
2302 | CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000120))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000120))))) & ~((1U << 0))) ))); |
2303 | |
2304 | /* Flush pending bus write */ |
2305 | CSR_READ_4(sc, BWI_MAC_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000120 )))); |
2306 | |
2307 | #define NRETRY 10000 |
2308 | for (i = 0; i < NRETRY; ++i) { |
2309 | if (CSR_READ_4(sc, BWI_MAC_INTR_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000128 )))) & BWI_INTR_READY(1 << 0)) |
2310 | break; |
2311 | DELAY(1)(*delay_func)(1); |
2312 | } |
2313 | if (i == NRETRY) { |
2314 | printf("%s: can't stop MAC\n", sc->sc_dev.dv_xname); |
2315 | return (ETIMEDOUT60); |
2316 | } |
2317 | #undef NRETRY |
2318 | |
2319 | return (0); |
2320 | } |
2321 | |
2322 | int |
2323 | bwi_mac_config_ps(struct bwi_mac *mac) |
2324 | { |
2325 | struct bwi_softc *sc = mac->mac_sc; |
2326 | uint32_t status; |
2327 | |
2328 | status = CSR_READ_4(sc, BWI_MAC_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000120 )))); |
2329 | |
2330 | status &= ~BWI_MAC_STATUS_HW_PS(1U << 25); |
2331 | status |= BWI_MAC_STATUS_WAKEUP(1U << 26); |
2332 | CSR_WRITE_4(sc, BWI_MAC_STATUS, status)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000120 )), ((status)))); |
2333 | |
2334 | /* Flush pending bus write */ |
2335 | CSR_READ_4(sc, BWI_MAC_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000120 )))); |
2336 | |
2337 | if (mac->mac_revmac_regwin.rw_rev >= 5) { |
2338 | int i; |
2339 | |
2340 | #define NRETRY 100 |
2341 | for (i = 0; i < NRETRY; ++i) { |
2342 | if (MOBJ_READ_2(mac, BWI_COMM_MOBJ,bwi_memobj_read_2((mac), (0x1), (0x40)) |
2343 | BWI_COMM_MOBJ_UCODE_STATE)bwi_memobj_read_2((mac), (0x1), (0x40)) != BWI_UCODE_STATE_PS4) |
2344 | break; |
2345 | DELAY(10)(*delay_func)(10); |
2346 | } |
2347 | if (i == NRETRY) { |
2348 | printf("%s: config PS failed\n", sc->sc_dev.dv_xname); |
2349 | return (ETIMEDOUT60); |
2350 | } |
2351 | #undef NRETRY |
2352 | } |
2353 | return (0); |
2354 | } |
2355 | |
2356 | void |
2357 | bwi_mac_reset_hwkeys(struct bwi_mac *mac) |
2358 | { |
2359 | /* TODO: firmware crypto */ |
2360 | MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_KEYTABLE_OFS)bwi_memobj_read_2((mac), (0x1), (0x56)); |
2361 | } |
2362 | |
2363 | void |
2364 | bwi_mac_shutdown(struct bwi_mac *mac) |
2365 | { |
2366 | struct bwi_softc *sc = mac->mac_sc; |
2367 | int i; |
2368 | |
2369 | if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS0x4) |
2370 | sc->sc_free_txstats(sc); |
2371 | |
2372 | sc->sc_free_rx_ring(sc); |
2373 | |
2374 | for (i = 0; i < BWI_TX_NRING6; ++i) |
2375 | sc->sc_free_tx_ring(sc, i); |
2376 | |
2377 | bwi_rf_off(mac); |
2378 | |
2379 | /* TODO: LED */ |
2380 | |
2381 | bwi_mac_gpio_fini(mac); |
2382 | |
2383 | bwi_rf_off(mac); /* XXX again */ |
2384 | CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e6 )), ((0x00f4)))); |
2385 | bwi_regwin_disable(sc, &mac->mac_regwin, 0); |
2386 | |
2387 | mac->mac_flags &= ~BWI_MAC_F_INITED0x8; |
2388 | } |
2389 | |
2390 | int |
2391 | bwi_mac_get_property(struct bwi_mac *mac) |
2392 | { |
2393 | struct bwi_softc *sc = mac->mac_sc; |
2394 | enum bwi_bus_space old_bus_space; |
2395 | uint32_t val; |
2396 | |
2397 | /* |
2398 | * Byte swap |
2399 | */ |
2400 | val = CSR_READ_4(sc, BWI_MAC_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000120 )))); |
2401 | if (val & BWI_MAC_STATUS_BSWAP(1U << 16)) { |
2402 | DPRINTF(1, "%s: need byte swap\n", sc->sc_dev.dv_xname); |
2403 | mac->mac_flags |= BWI_MAC_F_BSWAP0x1; |
2404 | } |
2405 | |
2406 | /* |
2407 | * DMA address space |
2408 | */ |
2409 | old_bus_space = sc->sc_bus_space; |
2410 | |
2411 | val = CSR_READ_4(sc, BWI_STATE_HI)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f9c )))); |
2412 | if (__SHIFTOUT(val, BWI_STATE_HI_FLAGS_MASK)(((val) & (0x1fff0000)) / ((((0x1fff0000) - 1) & (0x1fff0000 )) ^ (0x1fff0000))) & |
2413 | BWI_STATE_HI_FLAG_64BIT0x1000) { |
2414 | /* 64bit address */ |
2415 | sc->sc_bus_space = BWI_BUS_SPACE_64BIT; |
2416 | printf(": 64bit bus space not supported\n"); |
2417 | return (ENODEV19); |
2418 | } else { |
2419 | uint32_t txrx_reg = BWI_TXRX_CTRL_BASE0x200 + BWI_TX32_CTRL0x0; |
2420 | |
2421 | CSR_WRITE_4(sc, txrx_reg, BWI_TXRX32_CTRL_ADDRHI_MASK)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((txrx_reg )), ((0x00030000)))); |
2422 | if (CSR_READ_4(sc, txrx_reg)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((txrx_reg )))) & BWI_TXRX32_CTRL_ADDRHI_MASK0x00030000) { |
2423 | /* 32bit address */ |
2424 | sc->sc_bus_space = BWI_BUS_SPACE_32BIT; |
2425 | DPRINTF(1, "%s: 32bit bus space\n", |
2426 | sc->sc_dev.dv_xname); |
2427 | } else { |
2428 | /* 30bit address */ |
2429 | sc->sc_bus_space = BWI_BUS_SPACE_30BIT; |
2430 | DPRINTF(1, "%s: 30bit bus space\n", |
2431 | sc->sc_dev.dv_xname); |
2432 | } |
2433 | } |
2434 | |
2435 | if (old_bus_space != 0 && old_bus_space != sc->sc_bus_space) { |
2436 | printf("%s: MACs bus space mismatch!\n", sc->sc_dev.dv_xname); |
2437 | return (ENXIO6); |
2438 | } |
2439 | |
2440 | return (0); |
2441 | } |
2442 | |
2443 | void |
2444 | bwi_mac_updateslot(struct bwi_mac *mac, int shslot) |
2445 | { |
2446 | struct bwi_softc *sc; |
2447 | uint16_t slot_time; |
2448 | |
2449 | sc = mac->mac_sc; |
2450 | |
2451 | DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__); |
2452 | |
2453 | if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B) |
2454 | return; |
2455 | |
2456 | if (shslot) |
2457 | slot_time = IEEE80211_DUR_DS_SHSLOT9; |
2458 | else |
2459 | slot_time = IEEE80211_DUR_DS_SLOT20; |
2460 | |
2461 | CSR_WRITE_2(mac->mac_sc, BWI_MAC_SLOTTIME,(((mac->mac_sc)->sc_mem_bt)->write_2(((mac->mac_sc )->sc_mem_bh), ((0x0684)), ((slot_time + 510)))) |
2462 | slot_time + BWI_MAC_SLOTTIME_ADJUST)(((mac->mac_sc)->sc_mem_bt)->write_2(((mac->mac_sc )->sc_mem_bh), ((0x0684)), ((slot_time + 510)))); |
2463 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SLOTTIME, slot_time)bwi_memobj_write_2((mac), (0x1), (0x10), (slot_time)); |
2464 | } |
2465 | |
2466 | int |
2467 | bwi_mac_attach(struct bwi_softc *sc, int id, uint8_t rev) |
2468 | { |
2469 | struct bwi_mac *mac; |
2470 | int i; |
2471 | |
2472 | KASSERT(sc->sc_nmac <= BWI_MAC_MAX && sc->sc_nmac >= 0)((sc->sc_nmac <= 2 && sc->sc_nmac >= 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c" , 2472, "sc->sc_nmac <= BWI_MAC_MAX && sc->sc_nmac >= 0" )); |
2473 | |
2474 | if (sc->sc_nmac == BWI_MAC_MAX2) { |
2475 | printf("%s: too many MACs\n", sc->sc_dev.dv_xname); |
2476 | return (0); |
2477 | } |
2478 | |
2479 | /* |
2480 | * More than one MAC is only supported by BCM4309 |
2481 | */ |
2482 | if (sc->sc_nmac != 0 && |
2483 | sc->sc_pci_did != PCI_PRODUCT_BROADCOM_BCM43090x4324) { |
2484 | DPRINTF(1, "%s: ignore second MAC\n", sc->sc_dev.dv_xname); |
2485 | return (0); |
2486 | } |
2487 | |
2488 | mac = &sc->sc_mac[sc->sc_nmac]; |
2489 | |
2490 | /* XXX will this happen? */ |
2491 | if (BWI_REGWIN_EXIST(&mac->mac_regwin)((&mac->mac_regwin)->rw_flags & 0x1)) { |
2492 | printf("%s: %dth MAC already attached\n", |
2493 | sc->sc_dev.dv_xname, sc->sc_nmac); |
2494 | return (0); |
2495 | } |
2496 | |
2497 | /* |
2498 | * Test whether the revision of this MAC is supported |
2499 | */ |
2500 | for (i = 0; i < nitems(bwi_sup_macrev)(sizeof((bwi_sup_macrev)) / sizeof((bwi_sup_macrev)[0])); ++i) { |
2501 | if (bwi_sup_macrev[i] == rev) |
2502 | break; |
2503 | } |
2504 | if (i == nitems(bwi_sup_macrev)(sizeof((bwi_sup_macrev)) / sizeof((bwi_sup_macrev)[0]))) { |
2505 | printf("%s: MAC rev %u is not supported\n", |
2506 | sc->sc_dev.dv_xname, rev); |
2507 | return (ENXIO6); |
2508 | } |
2509 | |
2510 | BWI_CREATE_MAC(mac, sc, id, rev)do { do { (&(mac)->mac_regwin)->rw_flags = 0x1; (& (mac)->mac_regwin)->rw_type = (0x812); (&(mac)-> mac_regwin)->rw_id = ((id)); (&(mac)->mac_regwin)-> rw_rev = ((rev)); } while (0); (mac)->mac_sc = (sc); } while (0); |
2511 | sc->sc_nmac++; |
2512 | |
2513 | if (mac->mac_revmac_regwin.rw_rev < 5) { |
2514 | mac->mac_flags |= BWI_MAC_F_HAS_TXSTATS0x4; |
2515 | DPRINTF(1, "%s: has TX stats\n", sc->sc_dev.dv_xname); |
2516 | } else { |
2517 | mac->mac_flags |= BWI_MAC_F_PHYE_RESET0x80; |
2518 | } |
2519 | |
2520 | return (0); |
2521 | } |
2522 | |
2523 | void |
2524 | bwi_mac_balance_atten(int *bbp_atten0, int *rf_atten0) |
2525 | { |
2526 | int bbp_atten, rf_atten, rf_atten_lim = -1; |
2527 | |
2528 | bbp_atten = *bbp_atten0; |
2529 | rf_atten = *rf_atten0; |
2530 | |
2531 | /* |
2532 | * RF attenuation affects TX power BWI_RF_ATTEN_FACTOR times |
2533 | * as much as BBP attenuation, so we try our best to keep RF |
2534 | * attenuation within range. BBP attenuation will be clamped |
2535 | * later if it is out of range during balancing. |
2536 | * |
2537 | * BWI_RF_ATTEN_MAX0 is used as RF attenuation upper limit. |
2538 | */ |
2539 | |
2540 | /* |
2541 | * Use BBP attenuation to balance RF attenuation |
2542 | */ |
2543 | if (rf_atten < 0) |
2544 | rf_atten_lim = 0; |
2545 | else if (rf_atten > BWI_RF_ATTEN_MAX09) |
2546 | rf_atten_lim = BWI_RF_ATTEN_MAX09; |
2547 | |
2548 | if (rf_atten_lim >= 0) { |
2549 | bbp_atten += (BWI_RF_ATTEN_FACTOR4 * (rf_atten - rf_atten_lim)); |
2550 | rf_atten = rf_atten_lim; |
2551 | } |
2552 | |
2553 | /* |
2554 | * If possible, use RF attenuation to balance BBP attenuation |
2555 | * NOTE: RF attenuation is still kept within range. |
2556 | */ |
2557 | while (rf_atten < BWI_RF_ATTEN_MAX09 && bbp_atten > BWI_BBP_ATTEN_MAX11) { |
2558 | bbp_atten -= BWI_RF_ATTEN_FACTOR4; |
2559 | ++rf_atten; |
2560 | } |
2561 | while (rf_atten > 0 && bbp_atten < 0) { |
2562 | bbp_atten += BWI_RF_ATTEN_FACTOR4; |
2563 | --rf_atten; |
2564 | } |
2565 | |
2566 | /* RF attenuation MUST be within range */ |
2567 | KASSERT(rf_atten >= 0 && rf_atten <= BWI_RF_ATTEN_MAX0)((rf_atten >= 0 && rf_atten <= 9) ? (void)0 : __assert ("diagnostic ", "/usr/src/sys/dev/ic/bwi.c", 2567, "rf_atten >= 0 && rf_atten <= BWI_RF_ATTEN_MAX0" )); |
2568 | |
2569 | /* |
2570 | * Clamp BBP attenuation |
2571 | */ |
2572 | if (bbp_atten < 0) |
2573 | bbp_atten = 0; |
2574 | else if (bbp_atten > BWI_BBP_ATTEN_MAX11) |
2575 | bbp_atten = BWI_BBP_ATTEN_MAX11; |
2576 | |
2577 | *rf_atten0 = rf_atten; |
2578 | *bbp_atten0 = bbp_atten; |
2579 | } |
2580 | |
2581 | void |
2582 | bwi_mac_adjust_tpctl(struct bwi_mac *mac, int rf_atten_adj, int bbp_atten_adj) |
2583 | { |
2584 | struct bwi_softc *sc = mac->mac_sc; |
2585 | struct bwi_rf *rf = &mac->mac_rf; |
2586 | struct bwi_tpctl tpctl; |
2587 | int bbp_atten, rf_atten, tp_ctrl1; |
2588 | |
2589 | bcopy(&mac->mac_tpctl, &tpctl, sizeof(tpctl)); |
2590 | |
2591 | /* NOTE: Use signed value to do calculation */ |
2592 | bbp_atten = tpctl.bbp_atten; |
2593 | rf_atten = tpctl.rf_atten; |
2594 | tp_ctrl1 = tpctl.tp_ctrl1; |
2595 | |
2596 | bbp_atten += bbp_atten_adj; |
2597 | rf_atten += rf_atten_adj; |
2598 | |
2599 | bwi_mac_balance_atten(&bbp_atten, &rf_atten); |
2600 | |
2601 | if (rf->rf_type == BWI_RF_T_BCM20500x2050 && rf->rf_rev == 2) { |
2602 | if (rf_atten <= 1) { |
2603 | if (tp_ctrl1 == 0) { |
2604 | tp_ctrl1 = 3; |
2605 | bbp_atten += 2; |
2606 | rf_atten += 2; |
2607 | } else if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9(1 << 1)) { |
2608 | bbp_atten += |
2609 | (BWI_RF_ATTEN_FACTOR4 * (rf_atten - 2)); |
2610 | rf_atten = 2; |
2611 | } |
2612 | } else if (rf_atten > 4 && tp_ctrl1 != 0) { |
2613 | tp_ctrl1 = 0; |
2614 | if (bbp_atten < 3) { |
2615 | bbp_atten += 2; |
2616 | rf_atten -= 3; |
2617 | } else { |
2618 | bbp_atten -= 2; |
2619 | rf_atten -= 2; |
2620 | } |
2621 | } |
2622 | bwi_mac_balance_atten(&bbp_atten, &rf_atten); |
2623 | } |
2624 | |
2625 | tpctl.bbp_atten = bbp_atten; |
2626 | tpctl.rf_atten = rf_atten; |
2627 | tpctl.tp_ctrl1 = tp_ctrl1; |
2628 | |
2629 | bwi_mac_lock(mac); |
2630 | bwi_mac_set_tpctl_11bg(mac, &tpctl); |
2631 | bwi_mac_unlock(mac); |
2632 | } |
2633 | |
2634 | /* |
2635 | * http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower |
2636 | */ |
2637 | void |
2638 | bwi_mac_calibrate_txpower(struct bwi_mac *mac, enum bwi_txpwrcb_type type) |
2639 | { |
2640 | struct bwi_softc *sc = mac->mac_sc; |
2641 | struct bwi_rf *rf = &mac->mac_rf; |
2642 | int8_t tssi[4], tssi_avg, cur_txpwr; |
2643 | int error, i, ofdm_tssi; |
2644 | int txpwr_diff, rf_atten_adj, bbp_atten_adj; |
2645 | |
2646 | if (mac->mac_flags & BWI_MAC_F_TPCTL_ERROR0x40) { |
2647 | DPRINTF(1, "%s: tpctl error happened, can't set txpower\n", |
2648 | sc->sc_dev.dv_xname); |
2649 | return; |
2650 | } |
2651 | |
2652 | if (BWI_IS_BRCM_BU4306(sc)((sc)->sc_pci_subvid == 0x14e4 && (sc)->sc_pci_subdid == 0x416)) { |
2653 | DPRINTF(1, "%s: BU4306, can't set txpower\n", |
2654 | sc->sc_dev.dv_xname); |
2655 | return; |
2656 | } |
2657 | |
2658 | /* |
2659 | * Save latest TSSI and reset the related memory objects |
2660 | */ |
2661 | ofdm_tssi = 0; |
2662 | error = bwi_rf_get_latest_tssi(mac, tssi, BWI_COMM_MOBJ_TSSI_DS0x58); |
2663 | if (error) { |
2664 | DPRINTF(1, "%s: no DS tssi\n", sc->sc_dev.dv_xname); |
2665 | |
2666 | if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B) { |
2667 | if (type == BWI_TXPWR_FORCE) { |
2668 | rf_atten_adj = 0; |
2669 | bbp_atten_adj = 1; |
2670 | goto calib; |
2671 | } else { |
2672 | return; |
2673 | } |
2674 | } |
2675 | |
2676 | error = bwi_rf_get_latest_tssi(mac, tssi, |
2677 | BWI_COMM_MOBJ_TSSI_OFDM0x70); |
2678 | if (error) { |
2679 | DPRINTF(1, "%s: no OFDM tssi\n", sc->sc_dev.dv_xname); |
2680 | if (type == BWI_TXPWR_FORCE) { |
2681 | rf_atten_adj = 0; |
2682 | bbp_atten_adj = 1; |
2683 | goto calib; |
2684 | } else { |
2685 | return; |
2686 | } |
2687 | } |
2688 | |
2689 | for (i = 0; i < 4; ++i) { |
2690 | tssi[i] += 0x20; |
2691 | tssi[i] &= 0x3f; |
2692 | } |
2693 | ofdm_tssi = 1; |
2694 | } |
2695 | bwi_rf_clear_tssi(mac); |
2696 | |
2697 | DPRINTF(1, "%s: tssi0 %d, tssi1 %d, tssi2 %d, tssi3 %d\n", |
2698 | sc->sc_dev.dv_xname, tssi[0], tssi[1], tssi[2], tssi[3]); |
2699 | |
2700 | /* |
2701 | * Calculate RF/BBP attenuation adjustment based on |
2702 | * the difference between desired TX power and sampled |
2703 | * TX power. |
2704 | */ |
2705 | /* +8 == "each incremented by 1/2" */ |
2706 | tssi_avg = (tssi[0] + tssi[1] + tssi[2] + tssi[3] + 8) / 4; |
2707 | if (ofdm_tssi && (HFLAGS_READ(mac)bwi_hostflags_read((mac)) & BWI_HFLAG_PWR_BOOST_DS0x8ULL)) |
2708 | tssi_avg -= 13; |
2709 | |
2710 | DPRINTF(1, "%s: tssi avg %d\n", sc->sc_dev.dv_xname, tssi_avg); |
2711 | |
2712 | error = bwi_rf_tssi2dbm(mac, tssi_avg, &cur_txpwr); |
2713 | if (error) |
2714 | return; |
2715 | DPRINTF(1, "%s: current txpower %d\n", sc->sc_dev.dv_xname, cur_txpwr); |
2716 | |
2717 | txpwr_diff = rf->rf_txpower_max - cur_txpwr; /* XXX ni_txpower */ |
2718 | |
2719 | rf_atten_adj = -howmany(txpwr_diff, 8)(((txpwr_diff) + ((8) - 1)) / (8)); |
2720 | |
2721 | if (type == BWI_TXPWR_INIT) { |
2722 | /* |
2723 | * Move toward EEPROM max TX power as fast as we can |
2724 | */ |
2725 | bbp_atten_adj = -txpwr_diff; |
2726 | } else { |
2727 | bbp_atten_adj = -(txpwr_diff / 2); |
2728 | } |
2729 | bbp_atten_adj -= (BWI_RF_ATTEN_FACTOR4 * rf_atten_adj); |
2730 | |
2731 | if (rf_atten_adj == 0 && bbp_atten_adj == 0) { |
2732 | DPRINTF(1, "%s: no need to adjust RF/BBP attenuation\n", |
2733 | sc->sc_dev.dv_xname); |
2734 | /* TODO: LO */ |
2735 | return; |
2736 | } |
2737 | |
2738 | calib: |
2739 | DPRINTF(1, "%s: rf atten adjust %d, bbp atten adjust %d\n", |
2740 | sc->sc_dev.dv_xname, rf_atten_adj, bbp_atten_adj); |
2741 | bwi_mac_adjust_tpctl(mac, rf_atten_adj, bbp_atten_adj); |
2742 | /* TODO: LO */ |
2743 | } |
2744 | |
2745 | void |
2746 | bwi_mac_lock(struct bwi_mac *mac) |
2747 | { |
2748 | struct bwi_softc *sc = mac->mac_sc; |
2749 | |
2750 | KASSERT((mac->mac_flags & BWI_MAC_F_LOCKED) == 0)(((mac->mac_flags & 0x20) == 0) ? (void)0 : __assert("diagnostic " , "/usr/src/sys/dev/ic/bwi.c", 2750, "(mac->mac_flags & BWI_MAC_F_LOCKED) == 0" )); |
2751 | |
2752 | if (mac->mac_revmac_regwin.rw_rev < 3) |
2753 | bwi_mac_stop(mac); |
2754 | else |
2755 | #ifndef IEEE80211_STA_ONLY |
2756 | if (sc->sc_ic.ic_opmode != IEEE80211_M_HOSTAP) |
2757 | #endif |
2758 | bwi_mac_config_ps(mac); |
2759 | |
2760 | CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000120))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000120))))) | ((1U << 19)))))); |
2761 | |
2762 | /* Flush pending bus write */ |
2763 | CSR_READ_4(sc, BWI_MAC_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000120 )))); |
2764 | DELAY(10)(*delay_func)(10); |
2765 | |
2766 | mac->mac_flags |= BWI_MAC_F_LOCKED0x20; |
2767 | } |
2768 | |
2769 | void |
2770 | bwi_mac_unlock(struct bwi_mac *mac) |
2771 | { |
2772 | struct bwi_softc *sc = mac->mac_sc; |
2773 | |
2774 | KASSERT(mac->mac_flags & BWI_MAC_F_LOCKED)((mac->mac_flags & 0x20) ? (void)0 : __assert("diagnostic " , "/usr/src/sys/dev/ic/bwi.c", 2774, "mac->mac_flags & BWI_MAC_F_LOCKED" )); |
2775 | |
2776 | CSR_READ_2(sc, BWI_PHYINFO)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03e0 )))); /* dummy read */ |
2777 | |
2778 | CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000120))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000120))))) & ~((1U << 19)) )))); |
2779 | |
2780 | if (mac->mac_revmac_regwin.rw_rev < 3) |
2781 | bwi_mac_start(mac); |
2782 | else |
2783 | #ifndef IEEE80211_STA_ONLY |
2784 | if (sc->sc_ic.ic_opmode != IEEE80211_M_HOSTAP) |
2785 | #endif |
2786 | bwi_mac_config_ps(mac); |
2787 | |
2788 | mac->mac_flags &= ~BWI_MAC_F_LOCKED0x20; |
2789 | } |
2790 | |
2791 | void |
2792 | bwi_mac_set_promisc(struct bwi_mac *mac, int promisc) |
2793 | { |
2794 | struct bwi_softc *sc = mac->mac_sc; |
2795 | |
2796 | if (mac->mac_revmac_regwin.rw_rev < 5) /* Promisc is always on */ |
2797 | return; |
2798 | |
2799 | if (promisc) |
2800 | CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000120))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000120))))) | ((1U << 24)))))); |
2801 | else |
2802 | CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), ( ((0x00000120))), ((((((sc))->sc_mem_bt)->read_4((((sc)) ->sc_mem_bh), (((0x00000120))))) & ~((1U << 24)) )))); |
2803 | } |
2804 | |
2805 | /* PHY */ |
2806 | |
2807 | void |
2808 | bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data) |
2809 | { |
2810 | struct bwi_softc *sc = mac->mac_sc; |
2811 | |
2812 | /* TODO: 11A */ |
2813 | CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03fc )), ((ctrl)))); |
2814 | CSR_WRITE_2(sc, BWI_PHY_DATA, data)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03fe )), ((data)))); |
2815 | } |
2816 | |
2817 | uint16_t |
2818 | bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl) |
2819 | { |
2820 | struct bwi_softc *sc = mac->mac_sc; |
2821 | |
2822 | /* TODO: 11A */ |
2823 | CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03fc )), ((ctrl)))); |
2824 | return (CSR_READ_2(sc, BWI_PHY_DATA)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03fe ))))); |
2825 | } |
2826 | |
2827 | int |
2828 | bwi_phy_attach(struct bwi_mac *mac) |
2829 | { |
2830 | struct bwi_softc *sc = mac->mac_sc; |
2831 | struct bwi_phy *phy = &mac->mac_phy; |
2832 | uint8_t phyrev, phytype, phyver; |
2833 | uint16_t val; |
2834 | int i; |
2835 | |
2836 | /* Get PHY type/revision/version */ |
2837 | val = CSR_READ_2(sc, BWI_PHYINFO)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03e0 )))); |
2838 | phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK)(((val) & (0x000f)) / ((((0x000f) - 1) & (0x000f)) ^ ( 0x000f))); |
2839 | phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK)(((val) & (0x0f00)) / ((((0x0f00) - 1) & (0x0f00)) ^ ( 0x0f00))); |
2840 | phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK)(((val) & (0xf000)) / ((((0xf000) - 1) & (0xf000)) ^ ( 0xf000))); |
2841 | DPRINTF(1, "%s: PHY type %d, rev %d, ver %d\n", |
2842 | sc->sc_dev.dv_xname, phytype, phyrev, phyver); |
2843 | |
2844 | /* |
2845 | * Verify whether the revision of the PHY type is supported |
2846 | * Convert PHY type to ieee80211_phymode |
2847 | */ |
2848 | switch (phytype) { |
2849 | case BWI_PHYINFO_TYPE_11A0: |
2850 | if (phyrev >= 4) { |
2851 | printf("%s: unsupported 11A PHY, rev %u\n", |
2852 | sc->sc_dev.dv_xname, phyrev); |
2853 | return (ENXIO6); |
2854 | } |
2855 | phy->phy_init = bwi_phy_init_11a; |
2856 | phy->phy_mode = IEEE80211_MODE_11A; |
2857 | phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A0x072; |
2858 | phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A0x073; |
2859 | phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A0x074; |
2860 | break; |
2861 | case BWI_PHYINFO_TYPE_11B1: |
2862 | for (i = 0; i < nitems(bwi_sup_bphy)(sizeof((bwi_sup_bphy)) / sizeof((bwi_sup_bphy)[0])); ++i) { |
2863 | if (phyrev == bwi_sup_bphy[i].rev) { |
2864 | phy->phy_init = bwi_sup_bphy[i].init; |
2865 | break; |
2866 | } |
2867 | } |
2868 | if (i == nitems(bwi_sup_bphy)(sizeof((bwi_sup_bphy)) / sizeof((bwi_sup_bphy)[0]))) { |
2869 | printf("%s: unsupported 11B PHY, rev %u\n", |
2870 | sc->sc_dev.dv_xname, phyrev); |
2871 | return (ENXIO6); |
2872 | } |
2873 | phy->phy_mode = IEEE80211_MODE_11B; |
2874 | break; |
2875 | case BWI_PHYINFO_TYPE_11G2: |
2876 | if (phyrev > 8) { |
2877 | printf("%s: unsupported 11G PHY, rev %u\n", |
2878 | sc->sc_dev.dv_xname, phyrev); |
2879 | return (ENXIO6); |
2880 | } |
2881 | phy->phy_init = bwi_phy_init_11g; |
2882 | phy->phy_mode = IEEE80211_MODE_11G; |
2883 | phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G0x472; |
2884 | phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G0x473; |
2885 | phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G0x474; |
2886 | break; |
2887 | default: |
2888 | printf("%s: unsupported PHY type %d\n", |
2889 | sc->sc_dev.dv_xname, phytype); |
2890 | return (ENXIO6); |
2891 | } |
2892 | phy->phy_rev = phyrev; |
2893 | phy->phy_version = phyver; |
2894 | |
2895 | return (0); |
2896 | } |
2897 | |
2898 | void |
2899 | bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten) |
2900 | { |
2901 | struct bwi_phy *phy = &mac->mac_phy; |
2902 | uint16_t mask = 0x000f; |
2903 | |
2904 | if (phy->phy_version == 0) { |
2905 | CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask,((((mac->mac_sc))->sc_mem_bt)->write_2((((mac->mac_sc ))->sc_mem_bh), (((0x03e6))), (((((((mac->mac_sc))-> sc_mem_bt)->read_2((((mac->mac_sc))->sc_mem_bh), ((( 0x03e6))))) & (~mask)) | (((bbp_atten) * ((((mask) - 1) & (mask)) ^ (mask)))))))) |
2906 | __SHIFTIN(bbp_atten, mask))((((mac->mac_sc))->sc_mem_bt)->write_2((((mac->mac_sc ))->sc_mem_bh), (((0x03e6))), (((((((mac->mac_sc))-> sc_mem_bt)->read_2((((mac->mac_sc))->sc_mem_bh), ((( 0x03e6))))) & (~mask)) | (((bbp_atten) * ((((mask) - 1) & (mask)) ^ (mask)))))))); |
2907 | } else { |
2908 | if (phy->phy_version > 1) |
2909 | mask <<= 2; |
2910 | else |
2911 | mask <<= 3; |
2912 | PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask,bwi_phy_write(((mac)), ((0x060)), ((bwi_phy_read(((mac)), ((0x060 ))) & (~mask)) | (((bbp_atten) * ((((mask) - 1) & (mask )) ^ (mask)))))) |
2913 | __SHIFTIN(bbp_atten, mask))bwi_phy_write(((mac)), ((0x060)), ((bwi_phy_read(((mac)), ((0x060 ))) & (~mask)) | (((bbp_atten) * ((((mask) - 1) & (mask )) ^ (mask)))))); |
2914 | } |
2915 | } |
2916 | |
2917 | int |
2918 | bwi_phy_calibrate(struct bwi_mac *mac) |
2919 | { |
2920 | struct bwi_phy *phy = &mac->mac_phy; |
2921 | |
2922 | /* Dummy read */ |
2923 | CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS)(((mac->mac_sc)->sc_mem_bt)->read_4(((mac->mac_sc )->sc_mem_bh), ((0x00000120)))); |
2924 | |
2925 | /* Don't re-init */ |
2926 | if (phy->phy_flags & BWI_PHY_F_CALIBRATED0x1) |
2927 | return (0); |
2928 | |
2929 | if (phy->phy_mode == IEEE80211_MODE_11G && phy->phy_rev == 1) { |
2930 | bwi_mac_reset(mac, 0); |
2931 | bwi_phy_init_11g(mac); |
2932 | bwi_mac_reset(mac, 1); |
2933 | } |
2934 | |
2935 | phy->phy_flags |= BWI_PHY_F_CALIBRATED0x1; |
2936 | |
2937 | return (0); |
2938 | } |
2939 | |
2940 | void |
2941 | bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data) |
2942 | { |
2943 | struct bwi_phy *phy = &mac->mac_phy; |
2944 | |
2945 | KASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0)((phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c" , 2945, "phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0" )); |
2946 | PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs)bwi_phy_write((mac), (phy->phy_tbl_ctrl), (ofs)); |
2947 | PHY_WRITE(mac, phy->phy_tbl_data_lo, data)bwi_phy_write((mac), (phy->phy_tbl_data_lo), (data)); |
2948 | } |
2949 | |
2950 | void |
2951 | bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data) |
2952 | { |
2953 | struct bwi_phy *phy = &mac->mac_phy; |
2954 | |
2955 | KASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 &&((phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 && phy->phy_tbl_ctrl != 0) ? (void)0 : __assert ("diagnostic ", "/usr/src/sys/dev/ic/bwi.c", 2956, "phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 && phy->phy_tbl_ctrl != 0" )) |
2956 | phy->phy_tbl_ctrl != 0)((phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 && phy->phy_tbl_ctrl != 0) ? (void)0 : __assert ("diagnostic ", "/usr/src/sys/dev/ic/bwi.c", 2956, "phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 && phy->phy_tbl_ctrl != 0" )); |
2957 | |
2958 | PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs)bwi_phy_write((mac), (phy->phy_tbl_ctrl), (ofs)); |
2959 | PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16)bwi_phy_write((mac), (phy->phy_tbl_data_hi), (data >> 16)); |
2960 | PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff)bwi_phy_write((mac), (phy->phy_tbl_data_lo), (data & 0xffff )); |
2961 | } |
2962 | |
2963 | void |
2964 | bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data) |
2965 | { |
2966 | PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs)bwi_phy_write((mac), (0x803), (ofs)); |
2967 | PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data)bwi_phy_write((mac), (0x804), ((uint16_t)data)); |
2968 | } |
2969 | |
2970 | int16_t |
2971 | bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs) |
2972 | { |
2973 | PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs)bwi_phy_write((mac), (0x803), (ofs)); |
2974 | return ((int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA)bwi_phy_read((mac), (0x804))); |
2975 | } |
2976 | |
2977 | void |
2978 | bwi_phy_init_11a(struct bwi_mac *mac) |
2979 | { |
2980 | /* TODO: 11A */ |
2981 | } |
2982 | |
2983 | void |
2984 | bwi_phy_init_11g(struct bwi_mac *mac) |
2985 | { |
2986 | struct bwi_softc *sc = mac->mac_sc; |
2987 | struct bwi_phy *phy = &mac->mac_phy; |
2988 | struct bwi_rf *rf = &mac->mac_rf; |
2989 | const struct bwi_tpctl *tpctl = &mac->mac_tpctl; |
2990 | |
2991 | if (phy->phy_rev == 1) |
2992 | bwi_phy_init_11b_rev5(mac); |
2993 | else |
2994 | bwi_phy_init_11b_rev6(mac); |
2995 | |
2996 | if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED0x2)) |
2997 | bwi_phy_config_11g(mac); |
2998 | |
2999 | if (phy->phy_rev >= 2) { |
3000 | PHY_WRITE(mac, 0x814, 0)bwi_phy_write((mac), (0x814), (0)); |
3001 | PHY_WRITE(mac, 0x815, 0)bwi_phy_write((mac), (0x815), (0)); |
3002 | |
3003 | if (phy->phy_rev == 2) { |
3004 | PHY_WRITE(mac, 0x811, 0)bwi_phy_write((mac), (0x811), (0)); |
3005 | PHY_WRITE(mac, 0x15, 0xc0)bwi_phy_write((mac), (0x15), (0xc0)); |
3006 | } else if (phy->phy_rev > 5) { |
3007 | PHY_WRITE(mac, 0x811, 0x400)bwi_phy_write((mac), (0x811), (0x400)); |
3008 | PHY_WRITE(mac, 0x15, 0xc0)bwi_phy_write((mac), (0x15), (0xc0)); |
3009 | } |
3010 | } |
3011 | |
3012 | if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED0x2)) { |
3013 | uint16_t val; |
3014 | |
3015 | val = PHY_READ(mac, 0x400)bwi_phy_read((mac), (0x400)) & 0xff; |
3016 | if (val == 3 || val == 5) { |
3017 | PHY_WRITE(mac, 0x4c2, 0x1816)bwi_phy_write((mac), (0x4c2), (0x1816)); |
3018 | PHY_WRITE(mac, 0x4c3, 0x8006)bwi_phy_write((mac), (0x4c3), (0x8006)); |
3019 | if (val == 5) { |
3020 | PHY_FILT_SETBITS(mac, 0x4cc,bwi_phy_write(((mac)), ((0x4cc)), ((bwi_phy_read(((mac)), ((0x4cc ))) & (0xff)) | (0x1f00))) |
3021 | 0xff, 0x1f00)bwi_phy_write(((mac)), ((0x4cc)), ((bwi_phy_read(((mac)), ((0x4cc ))) & (0xff)) | (0x1f00))); |
3022 | } |
3023 | } |
3024 | } |
3025 | |
3026 | if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED0x2)) || |
3027 | phy->phy_rev >= 2) |
3028 | PHY_WRITE(mac, 0x47e, 0x78)bwi_phy_write((mac), (0x47e), (0x78)); |
3029 | |
3030 | if (rf->rf_rev == 8) { |
3031 | PHY_SETBITS(mac, 0x801, 0x80)bwi_phy_write(((mac)), ((0x801)), (bwi_phy_read(((mac)), ((0x801 ))) | (0x80))); |
3032 | PHY_SETBITS(mac, 0x43e, 0x4)bwi_phy_write(((mac)), ((0x43e)), (bwi_phy_read(((mac)), ((0x43e ))) | (0x4))); |
3033 | } |
3034 | |
3035 | if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED0x2)) |
3036 | bwi_rf_get_gains(mac); |
3037 | |
3038 | if (rf->rf_rev != 8) |
3039 | bwi_rf_init(mac); |
3040 | |
3041 | if (tpctl->tp_ctrl2 == 0xffff) { |
3042 | bwi_rf_lo_update(mac); |
3043 | } else { |
3044 | if (rf->rf_type == BWI_RF_T_BCM20500x2050 && rf->rf_rev == 8) { |
3045 | RF_WRITE(mac, 0x52,bwi_rf_write((mac), (0x52), ((tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2)) |
3046 | (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2)bwi_rf_write((mac), (0x52), ((tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2)); |
3047 | } else { |
3048 | RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl2)bwi_rf_write(((mac)), ((0x52)), ((bwi_rf_read(((mac)), ((0x52 ))) & (0xfff0)) | (tpctl->tp_ctrl2))); |
3049 | } |
3050 | |
3051 | if (phy->phy_rev >= 6) { |
3052 | PHY_FILT_SETBITS(mac, 0x36, 0xfff,bwi_phy_write(((mac)), ((0x36)), ((bwi_phy_read(((mac)), ((0x36 ))) & (0xfff)) | (tpctl->tp_ctrl2 << 12))) |
3053 | tpctl->tp_ctrl2 << 12)bwi_phy_write(((mac)), ((0x36)), ((bwi_phy_read(((mac)), ((0x36 ))) & (0xfff)) | (tpctl->tp_ctrl2 << 12))); |
3054 | } |
3055 | |
3056 | if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9(1 << 1)) |
3057 | PHY_WRITE(mac, 0x2e, 0x8075)bwi_phy_write((mac), (0x2e), (0x8075)); |
3058 | else |
3059 | PHY_WRITE(mac, 0x2e, 0x807f)bwi_phy_write((mac), (0x2e), (0x807f)); |
3060 | |
3061 | if (phy->phy_rev < 2) |
3062 | PHY_WRITE(mac, 0x2f, 0x101)bwi_phy_write((mac), (0x2f), (0x101)); |
3063 | else |
3064 | PHY_WRITE(mac, 0x2f, 0x202)bwi_phy_write((mac), (0x2f), (0x202)); |
3065 | } |
3066 | |
3067 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || phy->phy_rev >= 2) { |
3068 | bwi_rf_lo_adjust(mac, tpctl); |
3069 | PHY_WRITE(mac, 0x80f, 0x8078)bwi_phy_write((mac), (0x80f), (0x8078)); |
3070 | } |
3071 | |
3072 | if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI(1 << 3)) == 0) { |
3073 | bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */); |
3074 | bwi_rf_set_nrssi_thr(mac); |
3075 | } else if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || phy->phy_rev >= 2) { |
3076 | if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI-1000) { |
3077 | KASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI)((rf->rf_nrssi[1] == -1000) ? (void)0 : __assert("diagnostic " , "/usr/src/sys/dev/ic/bwi.c", 3077, "rf->rf_nrssi[1] == BWI_INVALID_NRSSI" )); |
3078 | bwi_rf_calc_nrssi_slope(mac); |
3079 | } else { |
3080 | KASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI)((rf->rf_nrssi[1] != -1000) ? (void)0 : __assert("diagnostic " , "/usr/src/sys/dev/ic/bwi.c", 3080, "rf->rf_nrssi[1] != BWI_INVALID_NRSSI" )); |
3081 | bwi_rf_set_nrssi_thr(mac); |
3082 | } |
3083 | } |
3084 | |
3085 | if (rf->rf_rev == 8) |
3086 | PHY_WRITE(mac, 0x805, 0x3230)bwi_phy_write((mac), (0x805), (0x3230)); |
3087 | |
3088 | bwi_mac_init_tpctl_11bg(mac); |
3089 | |
3090 | if (sc->sc_bbp_id == BWI_BBPID_BCM43060x4306 && sc->sc_bbp_pkg == 2) { |
3091 | PHY_CLRBITS(mac, 0x429, 0x4000)bwi_phy_write(((mac)), ((0x429)), (bwi_phy_read(((mac)), ((0x429 ))) & ~(0x4000))); |
3092 | PHY_CLRBITS(mac, 0x4c3, 0x8000)bwi_phy_write(((mac)), ((0x4c3)), (bwi_phy_read(((mac)), ((0x4c3 ))) & ~(0x8000))); |
3093 | } |
3094 | } |
3095 | |
3096 | void |
3097 | bwi_phy_init_11b_rev2(struct bwi_mac *mac) |
3098 | { |
3099 | struct bwi_softc *sc; |
3100 | |
3101 | sc = mac->mac_sc; |
3102 | |
3103 | /* TODO: 11B */ |
3104 | printf("%s: %s is not implemented yet\n", |
3105 | sc->sc_dev.dv_xname, __func__); |
3106 | } |
3107 | |
3108 | void |
3109 | bwi_phy_init_11b_rev4(struct bwi_mac *mac) |
3110 | { |
3111 | struct bwi_softc *sc = mac->mac_sc; |
3112 | struct bwi_rf *rf = &mac->mac_rf; |
3113 | uint16_t val, ofs; |
3114 | u_int chan; |
3115 | |
3116 | CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03ec )), ((0x3f22)))); |
3117 | |
3118 | PHY_WRITE(mac, 0x20, 0x301c)bwi_phy_write((mac), (0x20), (0x301c)); |
3119 | PHY_WRITE(mac, 0x26, 0)bwi_phy_write((mac), (0x26), (0)); |
3120 | PHY_WRITE(mac, 0x30, 0xc6)bwi_phy_write((mac), (0x30), (0xc6)); |
3121 | PHY_WRITE(mac, 0x88, 0x3e00)bwi_phy_write((mac), (0x88), (0x3e00)); |
3122 | |
3123 | for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202) |
3124 | PHY_WRITE(mac, 0x89 + ofs, val)bwi_phy_write((mac), (0x89 + ofs), (val)); |
3125 | |
3126 | CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e4 )), ((0x3000)))); |
3127 | |
3128 | chan = rf->rf_curchan; |
3129 | if (chan == IEEE80211_CHAN_ANY0xffff) |
3130 | chan = 6; /* Force to channel 6 */ |
3131 | bwi_rf_set_chan(mac, chan, 0); |
3132 | |
3133 | if (rf->rf_type != BWI_RF_T_BCM20500x2050) { |
3134 | RF_WRITE(mac, 0x75, 0x80)bwi_rf_write((mac), (0x75), (0x80)); |
3135 | RF_WRITE(mac, 0x79, 0x81)bwi_rf_write((mac), (0x79), (0x81)); |
3136 | } |
3137 | |
3138 | RF_WRITE(mac, 0x50, 0x20)bwi_rf_write((mac), (0x50), (0x20)); |
3139 | RF_WRITE(mac, 0x50, 0x23)bwi_rf_write((mac), (0x50), (0x23)); |
3140 | |
3141 | if (rf->rf_type == BWI_RF_T_BCM20500x2050) { |
3142 | RF_WRITE(mac, 0x50, 0x20)bwi_rf_write((mac), (0x50), (0x20)); |
3143 | RF_WRITE(mac, 0x5a, 0x70)bwi_rf_write((mac), (0x5a), (0x70)); |
3144 | RF_WRITE(mac, 0x5b, 0x7b)bwi_rf_write((mac), (0x5b), (0x7b)); |
3145 | RF_WRITE(mac, 0x5c, 0xb0)bwi_rf_write((mac), (0x5c), (0xb0)); |
3146 | RF_WRITE(mac, 0x7a, 0xf)bwi_rf_write((mac), (0x7a), (0xf)); |
3147 | PHY_WRITE(mac, 0x38, 0x677)bwi_phy_write((mac), (0x38), (0x677)); |
3148 | bwi_rf_init_bcm2050(mac); |
3149 | } |
3150 | |
3151 | PHY_WRITE(mac, 0x14, 0x80)bwi_phy_write((mac), (0x14), (0x80)); |
3152 | PHY_WRITE(mac, 0x32, 0xca)bwi_phy_write((mac), (0x32), (0xca)); |
3153 | if (rf->rf_type == BWI_RF_T_BCM20500x2050) |
3154 | PHY_WRITE(mac, 0x32, 0xe0)bwi_phy_write((mac), (0x32), (0xe0)); |
3155 | PHY_WRITE(mac, 0x35, 0x7c2)bwi_phy_write((mac), (0x35), (0x7c2)); |
3156 | |
3157 | bwi_rf_lo_update(mac); |
3158 | |
3159 | PHY_WRITE(mac, 0x26, 0xcc00)bwi_phy_write((mac), (0x26), (0xcc00)); |
3160 | if (rf->rf_type == BWI_RF_T_BCM20500x2050) |
3161 | PHY_WRITE(mac, 0x26, 0xce00)bwi_phy_write((mac), (0x26), (0xce00)); |
3162 | |
3163 | CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f4 )), ((0x1100)))); |
3164 | |
3165 | PHY_WRITE(mac, 0x2a, 0x88a3)bwi_phy_write((mac), (0x2a), (0x88a3)); |
3166 | if (rf->rf_type == BWI_RF_T_BCM20500x2050) |
3167 | PHY_WRITE(mac, 0x2a, 0x88c2)bwi_phy_write((mac), (0x2a), (0x88c2)); |
3168 | |
3169 | bwi_mac_set_tpctl_11bg(mac, NULL((void *)0)); |
3170 | if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI(1 << 3)) { |
3171 | bwi_rf_calc_nrssi_slope(mac); |
3172 | bwi_rf_set_nrssi_thr(mac); |
3173 | } |
3174 | bwi_mac_init_tpctl_11bg(mac); |
3175 | } |
3176 | |
3177 | void |
3178 | bwi_phy_init_11b_rev5(struct bwi_mac *mac) |
3179 | { |
3180 | struct bwi_softc *sc = mac->mac_sc; |
3181 | struct bwi_rf *rf = &mac->mac_rf; |
3182 | struct bwi_phy *phy = &mac->mac_phy; |
3183 | uint orig_chan; |
3184 | |
3185 | if (phy->phy_version == 1) |
3186 | RF_SETBITS(mac, 0x7a, 0x50)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0x50))); |
3187 | |
3188 | if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM0x14e4 && |
3189 | sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU43060x416) { |
3190 | uint16_t ofs, val; |
3191 | |
3192 | val = 0x2120; |
3193 | for (ofs = 0xa8; ofs < 0xc7; ++ofs) { |
3194 | PHY_WRITE(mac, ofs, val)bwi_phy_write((mac), (ofs), (val)); |
3195 | val += 0x202; |
3196 | } |
3197 | } |
3198 | |
3199 | PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700)bwi_phy_write(((mac)), ((0x35)), ((bwi_phy_read(((mac)), ((0x35 ))) & (0xf0ff)) | (0x700))); |
3200 | |
3201 | if (rf->rf_type == BWI_RF_T_BCM20500x2050) |
3202 | PHY_WRITE(mac, 0x38, 0x667)bwi_phy_write((mac), (0x38), (0x667)); |
3203 | |
3204 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || phy->phy_rev >= 2) { |
3205 | if (rf->rf_type == BWI_RF_T_BCM20500x2050) { |
3206 | RF_SETBITS(mac, 0x7a, 0x20)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0x20))); |
3207 | RF_SETBITS(mac, 0x51, 0x4)bwi_rf_write(((mac)), ((0x51)), (bwi_rf_read(((mac)), ((0x51) )) | (0x4))); |
3208 | } |
3209 | |
3210 | CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e2 )), ((0)))); |
3211 | |
3212 | PHY_SETBITS(mac, 0x802, 0x100)bwi_phy_write(((mac)), ((0x802)), (bwi_phy_read(((mac)), ((0x802 ))) | (0x100))); |
3213 | PHY_SETBITS(mac, 0x42b, 0x2000)bwi_phy_write(((mac)), ((0x42b)), (bwi_phy_read(((mac)), ((0x42b ))) | (0x2000))); |
3214 | PHY_WRITE(mac, 0x1c, 0x186a)bwi_phy_write((mac), (0x1c), (0x186a)); |
3215 | |
3216 | PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900)bwi_phy_write(((mac)), ((0x13)), ((bwi_phy_read(((mac)), ((0x13 ))) & (0xff)) | (0x1900))); |
3217 | PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64)bwi_phy_write(((mac)), ((0x35)), ((bwi_phy_read(((mac)), ((0x35 ))) & (0xffc0)) | (0x64))); |
3218 | PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa)bwi_phy_write(((mac)), ((0x5d)), ((bwi_phy_read(((mac)), ((0x5d ))) & (0xff80)) | (0xa))); |
3219 | } |
3220 | |
3221 | /* TODO: bad_frame_preempt? */ |
3222 | |
3223 | if (phy->phy_version == 1) { |
3224 | PHY_WRITE(mac, 0x26, 0xce00)bwi_phy_write((mac), (0x26), (0xce00)); |
3225 | PHY_WRITE(mac, 0x21, 0x3763)bwi_phy_write((mac), (0x21), (0x3763)); |
3226 | PHY_WRITE(mac, 0x22, 0x1bc3)bwi_phy_write((mac), (0x22), (0x1bc3)); |
3227 | PHY_WRITE(mac, 0x23, 0x6f9)bwi_phy_write((mac), (0x23), (0x6f9)); |
3228 | PHY_WRITE(mac, 0x24, 0x37e)bwi_phy_write((mac), (0x24), (0x37e)); |
3229 | } else |
3230 | PHY_WRITE(mac, 0x26, 0xcc00)bwi_phy_write((mac), (0x26), (0xcc00)); |
3231 | PHY_WRITE(mac, 0x30, 0xc6)bwi_phy_write((mac), (0x30), (0xc6)); |
3232 | |
3233 | CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03ec )), ((0x3f22)))); |
3234 | |
3235 | if (phy->phy_version == 1) |
3236 | PHY_WRITE(mac, 0x20, 0x3e1c)bwi_phy_write((mac), (0x20), (0x3e1c)); |
3237 | else |
3238 | PHY_WRITE(mac, 0x20, 0x301c)bwi_phy_write((mac), (0x20), (0x301c)); |
3239 | |
3240 | if (phy->phy_version == 0) |
3241 | CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e4 )), ((0x3000)))); |
3242 | |
3243 | /* Force to channel 7 */ |
3244 | orig_chan = rf->rf_curchan; |
3245 | bwi_rf_set_chan(mac, 7, 0); |
3246 | |
3247 | if (rf->rf_type != BWI_RF_T_BCM20500x2050) { |
3248 | RF_WRITE(mac, 0x75, 0x80)bwi_rf_write((mac), (0x75), (0x80)); |
3249 | RF_WRITE(mac, 0x79, 0x81)bwi_rf_write((mac), (0x79), (0x81)); |
3250 | } |
3251 | |
3252 | RF_WRITE(mac, 0x50, 0x20)bwi_rf_write((mac), (0x50), (0x20)); |
3253 | RF_WRITE(mac, 0x50, 0x23)bwi_rf_write((mac), (0x50), (0x23)); |
3254 | |
3255 | if (rf->rf_type == BWI_RF_T_BCM20500x2050) { |
3256 | RF_WRITE(mac, 0x50, 0x20)bwi_rf_write((mac), (0x50), (0x20)); |
3257 | RF_WRITE(mac, 0x5a, 0x70)bwi_rf_write((mac), (0x5a), (0x70)); |
3258 | } |
3259 | |
3260 | RF_WRITE(mac, 0x5b, 0x7b)bwi_rf_write((mac), (0x5b), (0x7b)); |
3261 | RF_WRITE(mac, 0x5c, 0xb0)bwi_rf_write((mac), (0x5c), (0xb0)); |
3262 | RF_SETBITS(mac, 0x7a, 0x7)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0x7))); |
3263 | |
3264 | bwi_rf_set_chan(mac, orig_chan, 0); |
3265 | |
3266 | PHY_WRITE(mac, 0x14, 0x80)bwi_phy_write((mac), (0x14), (0x80)); |
3267 | PHY_WRITE(mac, 0x32, 0xca)bwi_phy_write((mac), (0x32), (0xca)); |
3268 | PHY_WRITE(mac, 0x2a, 0x88a3)bwi_phy_write((mac), (0x2a), (0x88a3)); |
3269 | |
3270 | bwi_mac_set_tpctl_11bg(mac, NULL((void *)0)); |
3271 | |
3272 | if (rf->rf_type == BWI_RF_T_BCM20500x2050) |
3273 | RF_WRITE(mac, 0x5d, 0xd)bwi_rf_write((mac), (0x5d), (0xd)); |
3274 | |
3275 | CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4)((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), ( ((0x03e4))), (((((((sc))->sc_mem_bt)->read_2((((sc))-> sc_mem_bh), (((0x03e4))))) & (0xffc0)) | (0x4))))); |
3276 | } |
3277 | |
3278 | void |
3279 | bwi_phy_init_11b_rev6(struct bwi_mac *mac) |
3280 | { |
3281 | struct bwi_softc *sc = mac->mac_sc; |
3282 | struct bwi_rf *rf = &mac->mac_rf; |
3283 | struct bwi_phy *phy = &mac->mac_phy; |
3284 | uint16_t val, ofs; |
3285 | uint orig_chan; |
3286 | |
3287 | PHY_WRITE(mac, 0x3e, 0x817a)bwi_phy_write((mac), (0x3e), (0x817a)); |
3288 | RF_SETBITS(mac, 0x7a, 0x58)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0x58))); |
3289 | |
3290 | if (rf->rf_rev == 4 || rf->rf_rev == 5) { |
3291 | RF_WRITE(mac, 0x51, 0x37)bwi_rf_write((mac), (0x51), (0x37)); |
3292 | RF_WRITE(mac, 0x52, 0x70)bwi_rf_write((mac), (0x52), (0x70)); |
3293 | RF_WRITE(mac, 0x53, 0xb3)bwi_rf_write((mac), (0x53), (0xb3)); |
3294 | RF_WRITE(mac, 0x54, 0x9b)bwi_rf_write((mac), (0x54), (0x9b)); |
3295 | RF_WRITE(mac, 0x5a, 0x88)bwi_rf_write((mac), (0x5a), (0x88)); |
3296 | RF_WRITE(mac, 0x5b, 0x88)bwi_rf_write((mac), (0x5b), (0x88)); |
3297 | RF_WRITE(mac, 0x5d, 0x88)bwi_rf_write((mac), (0x5d), (0x88)); |
3298 | RF_WRITE(mac, 0x5e, 0x88)bwi_rf_write((mac), (0x5e), (0x88)); |
3299 | RF_WRITE(mac, 0x7d, 0x88)bwi_rf_write((mac), (0x7d), (0x88)); |
3300 | HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1)bwi_hostflags_write(((mac)), (bwi_hostflags_read(((mac))) & ~(0x200ULL))); |
3301 | } else if (rf->rf_rev == 8) { |
3302 | RF_WRITE(mac, 0x51, 0)bwi_rf_write((mac), (0x51), (0)); |
3303 | RF_WRITE(mac, 0x52, 0x40)bwi_rf_write((mac), (0x52), (0x40)); |
3304 | RF_WRITE(mac, 0x53, 0xb7)bwi_rf_write((mac), (0x53), (0xb7)); |
3305 | RF_WRITE(mac, 0x54, 0x98)bwi_rf_write((mac), (0x54), (0x98)); |
3306 | RF_WRITE(mac, 0x5a, 0x88)bwi_rf_write((mac), (0x5a), (0x88)); |
3307 | RF_WRITE(mac, 0x5b, 0x6b)bwi_rf_write((mac), (0x5b), (0x6b)); |
3308 | RF_WRITE(mac, 0x5c, 0xf)bwi_rf_write((mac), (0x5c), (0xf)); |
3309 | if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ(1 << 15)) { |
3310 | RF_WRITE(mac, 0x5d, 0xfa)bwi_rf_write((mac), (0x5d), (0xfa)); |
3311 | RF_WRITE(mac, 0x5e, 0xd8)bwi_rf_write((mac), (0x5e), (0xd8)); |
3312 | } else { |
3313 | RF_WRITE(mac, 0x5d, 0xf5)bwi_rf_write((mac), (0x5d), (0xf5)); |
3314 | RF_WRITE(mac, 0x5e, 0xb8)bwi_rf_write((mac), (0x5e), (0xb8)); |
3315 | } |
3316 | RF_WRITE(mac, 0x73, 0x3)bwi_rf_write((mac), (0x73), (0x3)); |
3317 | RF_WRITE(mac, 0x7d, 0xa8)bwi_rf_write((mac), (0x7d), (0xa8)); |
3318 | RF_WRITE(mac, 0x7c, 0x1)bwi_rf_write((mac), (0x7c), (0x1)); |
3319 | RF_WRITE(mac, 0x7e, 0x8)bwi_rf_write((mac), (0x7e), (0x8)); |
3320 | } |
3321 | |
3322 | val = 0x1e1f; |
3323 | for (ofs = 0x88; ofs < 0x98; ++ofs) { |
3324 | PHY_WRITE(mac, ofs, val)bwi_phy_write((mac), (ofs), (val)); |
3325 | val -= 0x202; |
3326 | } |
3327 | |
3328 | val = 0x3e3f; |
3329 | for (ofs = 0x98; ofs < 0xa8; ++ofs) { |
3330 | PHY_WRITE(mac, ofs, val)bwi_phy_write((mac), (ofs), (val)); |
3331 | val -= 0x202; |
3332 | } |
3333 | |
3334 | val = 0x2120; |
3335 | for (ofs = 0xa8; ofs < 0xc8; ++ofs) { |
3336 | PHY_WRITE(mac, ofs, (val & 0x3f3f))bwi_phy_write((mac), (ofs), ((val & 0x3f3f))); |
3337 | val += 0x202; |
3338 | |
3339 | /* XXX: delay 10 us to avoid PCI parity errors with BCM4318 */ |
3340 | DELAY(10)(*delay_func)(10); |
3341 | } |
3342 | |
3343 | if (phy->phy_mode == IEEE80211_MODE_11G) { |
3344 | RF_SETBITS(mac, 0x7a, 0x20)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0x20))); |
3345 | RF_SETBITS(mac, 0x51, 0x4)bwi_rf_write(((mac)), ((0x51)), (bwi_rf_read(((mac)), ((0x51) )) | (0x4))); |
3346 | PHY_SETBITS(mac, 0x802, 0x100)bwi_phy_write(((mac)), ((0x802)), (bwi_phy_read(((mac)), ((0x802 ))) | (0x100))); |
3347 | PHY_SETBITS(mac, 0x42b, 0x2000)bwi_phy_write(((mac)), ((0x42b)), (bwi_phy_read(((mac)), ((0x42b ))) | (0x2000))); |
3348 | PHY_WRITE(mac, 0x5b, 0)bwi_phy_write((mac), (0x5b), (0)); |
3349 | PHY_WRITE(mac, 0x5c, 0)bwi_phy_write((mac), (0x5c), (0)); |
3350 | } |
3351 | |
3352 | /* Force to channel 7 */ |
3353 | orig_chan = rf->rf_curchan; |
3354 | if (orig_chan >= 8) |
3355 | bwi_rf_set_chan(mac, 1, 0); |
3356 | else |
3357 | bwi_rf_set_chan(mac, 13, 0); |
3358 | |
3359 | RF_WRITE(mac, 0x50, 0x20)bwi_rf_write((mac), (0x50), (0x20)); |
3360 | RF_WRITE(mac, 0x50, 0x23)bwi_rf_write((mac), (0x50), (0x23)); |
3361 | |
3362 | DELAY(40)(*delay_func)(40); |
3363 | |
3364 | if (rf->rf_rev < 6 || rf->rf_rev == 8) { |
3365 | RF_SETBITS(mac, 0x7c, 0x2)bwi_rf_write(((mac)), ((0x7c)), (bwi_rf_read(((mac)), ((0x7c) )) | (0x2))); |
3366 | RF_WRITE(mac, 0x50, 0x20)bwi_rf_write((mac), (0x50), (0x20)); |
3367 | } |
3368 | if (rf->rf_rev <= 2) { |
3369 | RF_WRITE(mac, 0x7c, 0x20)bwi_rf_write((mac), (0x7c), (0x20)); |
3370 | RF_WRITE(mac, 0x5a, 0x70)bwi_rf_write((mac), (0x5a), (0x70)); |
3371 | RF_WRITE(mac, 0x5b, 0x7b)bwi_rf_write((mac), (0x5b), (0x7b)); |
3372 | RF_WRITE(mac, 0x5c, 0xb0)bwi_rf_write((mac), (0x5c), (0xb0)); |
3373 | } |
3374 | |
3375 | RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7)bwi_rf_write(((mac)), ((0x7a)), ((bwi_rf_read(((mac)), ((0x7a ))) & (0xf8)) | (0x7))); |
3376 | |
3377 | bwi_rf_set_chan(mac, orig_chan, 0); |
3378 | |
3379 | PHY_WRITE(mac, 0x14, 0x200)bwi_phy_write((mac), (0x14), (0x200)); |
3380 | if (rf->rf_rev >= 6) |
3381 | PHY_WRITE(mac, 0x2a, 0x88c2)bwi_phy_write((mac), (0x2a), (0x88c2)); |
3382 | else |
3383 | PHY_WRITE(mac, 0x2a, 0x8ac0)bwi_phy_write((mac), (0x2a), (0x8ac0)); |
3384 | PHY_WRITE(mac, 0x38, 0x668)bwi_phy_write((mac), (0x38), (0x668)); |
3385 | |
3386 | bwi_mac_set_tpctl_11bg(mac, NULL((void *)0)); |
3387 | |
3388 | if (rf->rf_rev <= 5) { |
3389 | PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3)bwi_phy_write(((mac)), ((0x5d)), ((bwi_phy_read(((mac)), ((0x5d ))) & (0xff80)) | (0x3))); |
3390 | if (rf->rf_rev <= 2) |
3391 | RF_WRITE(mac, 0x5d, 0xd)bwi_rf_write((mac), (0x5d), (0xd)); |
3392 | } |
3393 | |
3394 | if (phy->phy_version == 4) { |
3395 | CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e4 )), ((0x0009)))); |
3396 | PHY_CLRBITS(mac, 0x61, 0xf000)bwi_phy_write(((mac)), ((0x61)), (bwi_phy_read(((mac)), ((0x61 ))) & ~(0xf000))); |
3397 | } else { |
3398 | PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4)bwi_phy_write(((mac)), ((0x2)), ((bwi_phy_read(((mac)), ((0x2 ))) & (0xffc0)) | (0x4))); |
3399 | } |
3400 | |
3401 | if (phy->phy_mode == IEEE80211_MODE_11B) { |
3402 | CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e6 )), ((0x8140)))); |
3403 | PHY_WRITE(mac, 0x16, 0x410)bwi_phy_write((mac), (0x16), (0x410)); |
3404 | PHY_WRITE(mac, 0x17, 0x820)bwi_phy_write((mac), (0x17), (0x820)); |
3405 | PHY_WRITE(mac, 0x62, 0x7)bwi_phy_write((mac), (0x62), (0x7)); |
3406 | |
3407 | bwi_rf_init_bcm2050(mac); |
3408 | bwi_rf_lo_update(mac); |
3409 | if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI(1 << 3)) { |
3410 | bwi_rf_calc_nrssi_slope(mac); |
3411 | bwi_rf_set_nrssi_thr(mac); |
3412 | } |
3413 | bwi_mac_init_tpctl_11bg(mac); |
3414 | } else |
3415 | CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e6 )), ((0)))); |
3416 | } |
3417 | |
3418 | void |
3419 | bwi_phy_config_11g(struct bwi_mac *mac) |
3420 | { |
3421 | struct bwi_softc *sc = mac->mac_sc; |
3422 | struct bwi_phy *phy = &mac->mac_phy; |
3423 | const uint16_t *tbl; |
3424 | uint16_t wrd_ofs1, wrd_ofs2; |
3425 | int i, n; |
3426 | |
3427 | if (phy->phy_rev == 1) { |
3428 | PHY_WRITE(mac, 0x406, 0x4f19)bwi_phy_write((mac), (0x406), (0x4f19)); |
3429 | PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340)bwi_phy_write(((mac)), ((0x429)), ((bwi_phy_read(((mac)), ((0x429 ))) & (0xfc3f)) | (0x340))); |
3430 | PHY_WRITE(mac, 0x42c, 0x5a)bwi_phy_write((mac), (0x42c), (0x5a)); |
3431 | PHY_WRITE(mac, 0x427, 0x1a)bwi_phy_write((mac), (0x427), (0x1a)); |
3432 | |
3433 | /* Fill frequency table */ |
3434 | for (i = 0; i < nitems(bwi_phy_freq_11g_rev1)(sizeof((bwi_phy_freq_11g_rev1)) / sizeof((bwi_phy_freq_11g_rev1 )[0])); ++i) { |
3435 | bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ0x5800 + i, |
3436 | bwi_phy_freq_11g_rev1[i]); |
3437 | } |
3438 | |
3439 | /* Fill noise table */ |
3440 | for (i = 0; i < nitems(bwi_phy_noise_11g_rev1)(sizeof((bwi_phy_noise_11g_rev1)) / sizeof((bwi_phy_noise_11g_rev1 )[0])); ++i) { |
3441 | bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE0x1800 + i, |
3442 | bwi_phy_noise_11g_rev1[i]); |
3443 | } |
3444 | |
3445 | /* Fill rotor table */ |
3446 | for (i = 0; i < nitems(bwi_phy_rotor_11g_rev1)(sizeof((bwi_phy_rotor_11g_rev1)) / sizeof((bwi_phy_rotor_11g_rev1 )[0])); ++i) { |
3447 | /* NB: data length is 4 bytes */ |
3448 | bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR0x2000 + i, |
3449 | bwi_phy_rotor_11g_rev1[i]); |
3450 | } |
3451 | } else { |
3452 | bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */ |
3453 | |
3454 | if (phy->phy_rev == 2) { |
3455 | PHY_WRITE(mac, 0x4c0, 0x1861)bwi_phy_write((mac), (0x4c0), (0x1861)); |
3456 | PHY_WRITE(mac, 0x4c1, 0x271)bwi_phy_write((mac), (0x4c1), (0x271)); |
3457 | } else if (phy->phy_rev > 2) { |
3458 | PHY_WRITE(mac, 0x4c0, 0x98)bwi_phy_write((mac), (0x4c0), (0x98)); |
3459 | PHY_WRITE(mac, 0x4c1, 0x70)bwi_phy_write((mac), (0x4c1), (0x70)); |
3460 | PHY_WRITE(mac, 0x4c9, 0x80)bwi_phy_write((mac), (0x4c9), (0x80)); |
3461 | } |
3462 | PHY_SETBITS(mac, 0x42b, 0x800)bwi_phy_write(((mac)), ((0x42b)), (bwi_phy_read(((mac)), ((0x42b ))) | (0x800))); |
3463 | |
3464 | /* Fill RSSI table */ |
3465 | for (i = 0; i < 64; ++i) |
3466 | bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI0x4000 + i, i); |
3467 | |
3468 | /* Fill noise table */ |
3469 | for (i = 0; i < nitems(bwi_phy_noise_11g)(sizeof((bwi_phy_noise_11g)) / sizeof((bwi_phy_noise_11g)[0]) ); ++i) { |
3470 | bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE0x1800 + i, |
3471 | bwi_phy_noise_11g[i]); |
3472 | } |
3473 | } |
3474 | |
3475 | /* |
3476 | * Fill noise scale table |
3477 | */ |
3478 | if (phy->phy_rev <= 2) { |
3479 | tbl = bwi_phy_noise_scale_11g_rev2; |
3480 | n = nitems(bwi_phy_noise_scale_11g_rev2)(sizeof((bwi_phy_noise_scale_11g_rev2)) / sizeof((bwi_phy_noise_scale_11g_rev2 )[0])); |
3481 | } else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449)bwi_phy_read((mac), (0x449)) & 0x200)) { |
3482 | tbl = bwi_phy_noise_scale_11g_rev7; |
3483 | n = nitems(bwi_phy_noise_scale_11g_rev7)(sizeof((bwi_phy_noise_scale_11g_rev7)) / sizeof((bwi_phy_noise_scale_11g_rev7 )[0])); |
3484 | } else { |
3485 | tbl = bwi_phy_noise_scale_11g; |
3486 | n = nitems(bwi_phy_noise_scale_11g)(sizeof((bwi_phy_noise_scale_11g)) / sizeof((bwi_phy_noise_scale_11g )[0])); |
3487 | } |
3488 | for (i = 0; i < n; ++i) |
3489 | bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE0x1400 + i, tbl[i]); |
3490 | |
3491 | /* |
3492 | * Fill sigma square table |
3493 | */ |
3494 | if (phy->phy_rev == 2) { |
3495 | tbl = bwi_phy_sigma_sq_11g_rev2; |
3496 | n = nitems(bwi_phy_sigma_sq_11g_rev2)(sizeof((bwi_phy_sigma_sq_11g_rev2)) / sizeof((bwi_phy_sigma_sq_11g_rev2 )[0])); |
3497 | } else if (phy->phy_rev > 2 && phy->phy_rev <= 8) { |
3498 | tbl = bwi_phy_sigma_sq_11g_rev7; |
3499 | n = nitems(bwi_phy_sigma_sq_11g_rev7)(sizeof((bwi_phy_sigma_sq_11g_rev7)) / sizeof((bwi_phy_sigma_sq_11g_rev7 )[0])); |
3500 | } else { |
3501 | tbl = NULL((void *)0); |
3502 | n = 0; |
3503 | } |
3504 | for (i = 0; i < n; ++i) |
3505 | bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ0x5000 + i, tbl[i]); |
3506 | |
3507 | if (phy->phy_rev == 1) { |
3508 | /* Fill delay table */ |
3509 | for (i = 0; i < nitems(bwi_phy_delay_11g_rev1)(sizeof((bwi_phy_delay_11g_rev1)) / sizeof((bwi_phy_delay_11g_rev1 )[0])); ++i) { |
3510 | bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY0x2400 + i, |
3511 | bwi_phy_delay_11g_rev1[i]); |
3512 | } |
3513 | |
3514 | /* Fill WRSSI (Wide-Band RSSI) table */ |
3515 | for (i = 4; i < 20; ++i) |
3516 | bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV10x5400 + i, 0x20); |
3517 | |
3518 | bwi_phy_config_agc(mac); |
3519 | |
3520 | wrd_ofs1 = 0x5001; |
3521 | wrd_ofs2 = 0x5002; |
3522 | } else { |
3523 | /* Fill WRSSI (Wide-Band RSSI) table */ |
3524 | for (i = 0; i < 0x20; ++i) |
3525 | bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI0x1000 + i, 0x820); |
3526 | |
3527 | bwi_phy_config_agc(mac); |
3528 | |
3529 | PHY_READ(mac, 0x400)bwi_phy_read((mac), (0x400)); /* Dummy read */ |
3530 | PHY_WRITE(mac, 0x403, 0x1000)bwi_phy_write((mac), (0x403), (0x1000)); |
3531 | bwi_tbl_write_2(mac, 0x3c02, 0xf); |
3532 | bwi_tbl_write_2(mac, 0x3c03, 0x14); |
3533 | |
3534 | wrd_ofs1 = 0x401; |
3535 | wrd_ofs2 = 0x402; |
3536 | } |
3537 | |
3538 | if (!(BWI_IS_BRCM_BU4306(sc)((sc)->sc_pci_subvid == 0x14e4 && (sc)->sc_pci_subdid == 0x416) && sc->sc_pci_revid == 0x17)) { |
3539 | bwi_tbl_write_2(mac, wrd_ofs1, 0x2); |
3540 | bwi_tbl_write_2(mac, wrd_ofs2, 0x1); |
3541 | } |
3542 | |
3543 | /* phy->phy_flags & BWI_PHY_F_LINKED ? */ |
3544 | if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9(1 << 1)) |
3545 | PHY_WRITE(mac, 0x46e, 0x3cf)bwi_phy_write((mac), (0x46e), (0x3cf)); |
3546 | } |
3547 | #undef N |
3548 | |
3549 | /* |
3550 | * Configure Automatic Gain Controller |
3551 | */ |
3552 | void |
3553 | bwi_phy_config_agc(struct bwi_mac *mac) |
3554 | { |
3555 | struct bwi_phy *phy = &mac->mac_phy; |
3556 | uint16_t ofs; |
3557 | |
3558 | ofs = phy->phy_rev == 1 ? 0x4c00 : 0; |
3559 | |
3560 | bwi_tbl_write_2(mac, ofs, 0xfe); |
3561 | bwi_tbl_write_2(mac, ofs + 1, 0xd); |
3562 | bwi_tbl_write_2(mac, ofs + 2, 0x13); |
3563 | bwi_tbl_write_2(mac, ofs + 3, 0x19); |
3564 | |
3565 | if (phy->phy_rev == 1) { |
3566 | bwi_tbl_write_2(mac, 0x1800, 0x2710); |
3567 | bwi_tbl_write_2(mac, 0x1801, 0x9b83); |
3568 | bwi_tbl_write_2(mac, 0x1802, 0x9b83); |
3569 | bwi_tbl_write_2(mac, 0x1803, 0xf8d); |
3570 | PHY_WRITE(mac, 0x455, 0x4)bwi_phy_write((mac), (0x455), (0x4)); |
3571 | } |
3572 | |
3573 | PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700)bwi_phy_write(((mac)), ((0x4a5)), ((bwi_phy_read(((mac)), ((0x4a5 ))) & (0xff)) | (0x5700))); |
3574 | PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf)bwi_phy_write(((mac)), ((0x41a)), ((bwi_phy_read(((mac)), ((0x41a ))) & (0xff80)) | (0xf))); |
3575 | PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80)bwi_phy_write(((mac)), ((0x41a)), ((bwi_phy_read(((mac)), ((0x41a ))) & (0xc07f)) | (0x2b80))); |
3576 | PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300)bwi_phy_write(((mac)), ((0x48c)), ((bwi_phy_read(((mac)), ((0x48c ))) & (0xf0ff)) | (0x300))); |
3577 | |
3578 | RF_SETBITS(mac, 0x7a, 0x8)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0x8))); |
3579 | |
3580 | PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8)bwi_phy_write(((mac)), ((0x4a0)), ((bwi_phy_read(((mac)), ((0x4a0 ))) & (0xfff0)) | (0x8))); |
3581 | PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600)bwi_phy_write(((mac)), ((0x4a1)), ((bwi_phy_read(((mac)), ((0x4a1 ))) & (0xf0ff)) | (0x600))); |
3582 | PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700)bwi_phy_write(((mac)), ((0x4a2)), ((bwi_phy_read(((mac)), ((0x4a2 ))) & (0xf0ff)) | (0x700))); |
3583 | PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100)bwi_phy_write(((mac)), ((0x4a0)), ((bwi_phy_read(((mac)), ((0x4a0 ))) & (0xf0ff)) | (0x100))); |
3584 | |
3585 | if (phy->phy_rev == 1) |
3586 | PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7)bwi_phy_write(((mac)), ((0x4a2)), ((bwi_phy_read(((mac)), ((0x4a2 ))) & (0xfff0)) | (0x7))); |
3587 | |
3588 | PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c)bwi_phy_write(((mac)), ((0x488)), ((bwi_phy_read(((mac)), ((0x488 ))) & (0xff00)) | (0x1c))); |
3589 | PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200)bwi_phy_write(((mac)), ((0x488)), ((bwi_phy_read(((mac)), ((0x488 ))) & (0xc0ff)) | (0x200))); |
3590 | PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c)bwi_phy_write(((mac)), ((0x496)), ((bwi_phy_read(((mac)), ((0x496 ))) & (0xff00)) | (0x1c))); |
3591 | PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20)bwi_phy_write(((mac)), ((0x489)), ((bwi_phy_read(((mac)), ((0x489 ))) & (0xff00)) | (0x20))); |
3592 | PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200)bwi_phy_write(((mac)), ((0x489)), ((bwi_phy_read(((mac)), ((0x489 ))) & (0xc0ff)) | (0x200))); |
3593 | PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e)bwi_phy_write(((mac)), ((0x482)), ((bwi_phy_read(((mac)), ((0x482 ))) & (0xff00)) | (0x2e))); |
3594 | PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00)bwi_phy_write(((mac)), ((0x496)), ((bwi_phy_read(((mac)), ((0x496 ))) & (0xff)) | (0x1a00))); |
3595 | PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28)bwi_phy_write(((mac)), ((0x481)), ((bwi_phy_read(((mac)), ((0x481 ))) & (0xff00)) | (0x28))); |
3596 | PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00)bwi_phy_write(((mac)), ((0x481)), ((bwi_phy_read(((mac)), ((0x481 ))) & (0xff)) | (0x2c00))); |
3597 | |
3598 | if (phy->phy_rev == 1) { |
3599 | PHY_WRITE(mac, 0x430, 0x92b)bwi_phy_write((mac), (0x430), (0x92b)); |
3600 | PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2)bwi_phy_write(((mac)), ((0x41b)), ((bwi_phy_read(((mac)), ((0x41b ))) & (0xffe1)) | (0x2))); |
3601 | } else { |
3602 | PHY_CLRBITS(mac, 0x41b, 0x1e)bwi_phy_write(((mac)), ((0x41b)), (bwi_phy_read(((mac)), ((0x41b ))) & ~(0x1e))); |
3603 | PHY_WRITE(mac, 0x41f, 0x287a)bwi_phy_write((mac), (0x41f), (0x287a)); |
3604 | PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4)bwi_phy_write(((mac)), ((0x420)), ((bwi_phy_read(((mac)), ((0x420 ))) & (0xfff0)) | (0x4))); |
3605 | |
3606 | if (phy->phy_rev >= 6) { |
3607 | PHY_WRITE(mac, 0x422, 0x287a)bwi_phy_write((mac), (0x422), (0x287a)); |
3608 | PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000)bwi_phy_write(((mac)), ((0x420)), ((bwi_phy_read(((mac)), ((0x420 ))) & (0xfff)) | (0x3000))); |
3609 | } |
3610 | } |
3611 | |
3612 | PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874)bwi_phy_write(((mac)), ((0x4a8)), ((bwi_phy_read(((mac)), ((0x4a8 ))) & (0x8080)) | (0x7874))); |
3613 | PHY_WRITE(mac, 0x48e, 0x1c00)bwi_phy_write((mac), (0x48e), (0x1c00)); |
3614 | |
3615 | if (phy->phy_rev == 1) { |
3616 | PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600)bwi_phy_write(((mac)), ((0x4ab)), ((bwi_phy_read(((mac)), ((0x4ab ))) & (0xf0ff)) | (0x600))); |
3617 | PHY_WRITE(mac, 0x48b, 0x5e)bwi_phy_write((mac), (0x48b), (0x5e)); |
3618 | PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e)bwi_phy_write(((mac)), ((0x48c)), ((bwi_phy_read(((mac)), ((0x48c ))) & (0xff00)) | (0x1e))); |
3619 | PHY_WRITE(mac, 0x48d, 0x2)bwi_phy_write((mac), (0x48d), (0x2)); |
3620 | } |
3621 | |
3622 | bwi_tbl_write_2(mac, ofs + 0x800, 0); |
3623 | bwi_tbl_write_2(mac, ofs + 0x801, 7); |
3624 | bwi_tbl_write_2(mac, ofs + 0x802, 16); |
3625 | bwi_tbl_write_2(mac, ofs + 0x803, 28); |
3626 | |
3627 | if (phy->phy_rev >= 6) { |
3628 | PHY_CLRBITS(mac, 0x426, 0x3)bwi_phy_write(((mac)), ((0x426)), (bwi_phy_read(((mac)), ((0x426 ))) & ~(0x3))); |
3629 | PHY_CLRBITS(mac, 0x426, 0x1000)bwi_phy_write(((mac)), ((0x426)), (bwi_phy_read(((mac)), ((0x426 ))) & ~(0x1000))); |
3630 | } |
3631 | } |
3632 | |
3633 | void |
3634 | bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains) |
3635 | { |
3636 | struct bwi_phy *phy = &mac->mac_phy; |
3637 | uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain; |
3638 | int i; |
3639 | |
3640 | if (phy->phy_rev <= 1) { |
3641 | tbl_gain_ofs1 = 0x5000; |
3642 | tbl_gain_ofs2 = tbl_gain_ofs1 + 16; |
3643 | } else { |
3644 | tbl_gain_ofs1 = 0x400; |
3645 | tbl_gain_ofs2 = tbl_gain_ofs1 + 8; |
3646 | } |
3647 | |
3648 | for (i = 0; i < 4; ++i) { |
3649 | if (gains != NULL((void *)0)) { |
3650 | tbl_gain = gains->tbl_gain1; |
3651 | } else { |
3652 | /* Bit swap */ |
3653 | tbl_gain = (i & 0x1) << 1; |
3654 | tbl_gain |= (i & 0x2) >> 1; |
3655 | } |
3656 | bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain); |
3657 | } |
3658 | |
3659 | for (i = 0; i < 16; ++i) { |
3660 | if (gains != NULL((void *)0)) |
3661 | tbl_gain = gains->tbl_gain2; |
3662 | else |
3663 | tbl_gain = i; |
3664 | bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain); |
3665 | } |
3666 | |
3667 | if (gains == NULL((void *)0) || (gains != NULL((void *)0) && gains->phy_gain != -1)) { |
3668 | uint16_t phy_gain1, phy_gain2; |
3669 | |
3670 | if (gains != NULL((void *)0)) { |
3671 | phy_gain1 = |
3672 | ((uint16_t)gains->phy_gain << 14) | |
3673 | ((uint16_t)gains->phy_gain << 6); |
3674 | phy_gain2 = phy_gain1; |
3675 | } else { |
3676 | phy_gain1 = 0x4040; |
3677 | phy_gain2 = 0x4000; |
3678 | } |
3679 | PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1)bwi_phy_write(((mac)), ((0x4a0)), ((bwi_phy_read(((mac)), ((0x4a0 ))) & (0xbfbf)) | (phy_gain1))); |
3680 | PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1)bwi_phy_write(((mac)), ((0x4a1)), ((bwi_phy_read(((mac)), ((0x4a1 ))) & (0xbfbf)) | (phy_gain1))); |
3681 | PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2)bwi_phy_write(((mac)), ((0x4a2)), ((bwi_phy_read(((mac)), ((0x4a2 ))) & (0xbfbf)) | (phy_gain2))); |
3682 | } |
3683 | bwi_mac_dummy_xmit(mac); |
3684 | } |
3685 | |
3686 | void |
3687 | bwi_phy_clear_state(struct bwi_phy *phy) |
3688 | { |
3689 | phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS(0x1); |
3690 | } |
3691 | |
3692 | /* RF */ |
3693 | |
3694 | int16_t |
3695 | bwi_nrssi_11g(struct bwi_mac *mac) |
3696 | { |
3697 | int16_t val; |
3698 | |
3699 | #define NRSSI_11G_MASK 0x3f00 |
3700 | val = (int16_t)__SHIFTOUT(PHY_READ(mac, 0x47f), NRSSI_11G_MASK)(((bwi_phy_read((mac), (0x47f))) & (NRSSI_11G_MASK)) / (( ((NRSSI_11G_MASK) - 1) & (NRSSI_11G_MASK)) ^ (NRSSI_11G_MASK ))); |
3701 | if (val >= 32) |
3702 | val -= 64; |
3703 | |
3704 | return (val); |
3705 | #undef NRSSI_11G_MASK |
3706 | } |
3707 | |
3708 | struct bwi_rf_lo * |
3709 | bwi_get_rf_lo(struct bwi_mac *mac, uint16_t rf_atten, uint16_t bbp_atten) |
3710 | { |
3711 | int n; |
3712 | |
3713 | n = rf_atten + (14 * (bbp_atten / 2)); |
3714 | KASSERT(n < BWI_RFLO_MAX)((n < 56) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c" , 3714, "n < BWI_RFLO_MAX")); |
3715 | |
3716 | return (&mac->mac_rf.rf_lo[n]); |
3717 | } |
3718 | |
3719 | int |
3720 | bwi_rf_lo_isused(struct bwi_mac *mac, const struct bwi_rf_lo *lo) |
3721 | { |
3722 | struct bwi_rf *rf = &mac->mac_rf; |
3723 | int idx; |
3724 | |
3725 | idx = lo - rf->rf_lo; |
3726 | KASSERT(idx >= 0 && idx < BWI_RFLO_MAX)((idx >= 0 && idx < 56) ? (void)0 : __assert("diagnostic " , "/usr/src/sys/dev/ic/bwi.c", 3726, "idx >= 0 && idx < BWI_RFLO_MAX" )); |
3727 | |
3728 | return (isset(rf->rf_lo_used, idx)((rf->rf_lo_used)[(idx)>>3] & (1<<((idx)& (8 -1))))); |
3729 | } |
3730 | |
3731 | void |
3732 | bwi_rf_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data) |
3733 | { |
3734 | struct bwi_softc *sc = mac->mac_sc; |
3735 | |
3736 | CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f6 )), ((ctrl)))); |
3737 | CSR_WRITE_2(sc, BWI_RF_DATA_LO, data)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x3fa )), ((data)))); |
3738 | } |
3739 | |
3740 | uint16_t |
3741 | bwi_rf_read(struct bwi_mac *mac, uint16_t ctrl) |
3742 | { |
3743 | struct bwi_rf *rf = &mac->mac_rf; |
3744 | struct bwi_softc *sc = mac->mac_sc; |
3745 | |
3746 | ctrl |= rf->rf_ctrl_rd; |
3747 | if (rf->rf_ctrl_adj) { |
3748 | /* XXX */ |
3749 | if (ctrl < 0x70) |
3750 | ctrl += 0x80; |
3751 | else if (ctrl < 0x80) |
3752 | ctrl += 0x70; |
3753 | } |
3754 | |
3755 | CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f6 )), ((ctrl)))); |
3756 | return (CSR_READ_2(sc, BWI_RF_DATA_LO)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x3fa ))))); |
3757 | } |
3758 | |
3759 | int |
3760 | bwi_rf_attach(struct bwi_mac *mac) |
3761 | { |
3762 | struct bwi_softc *sc = mac->mac_sc; |
3763 | struct bwi_phy *phy = &mac->mac_phy; |
3764 | struct bwi_rf *rf = &mac->mac_rf; |
3765 | uint16_t type, manu; |
3766 | uint8_t rev; |
3767 | |
3768 | /* |
3769 | * Get RF manufacture/type/revision |
3770 | */ |
3771 | if (sc->sc_bbp_id == BWI_BBPID_BCM43170x4317) { |
3772 | /* |
3773 | * Fake a BCM2050 RF |
3774 | */ |
3775 | manu = BWI_RF_MANUFACT_BCM0x17f; |
3776 | type = BWI_RF_T_BCM20500x2050; |
3777 | if (sc->sc_bbp_rev == 0) |
3778 | rev = 3; |
3779 | else if (sc->sc_bbp_rev == 1) |
3780 | rev = 4; |
3781 | else |
3782 | rev = 5; |
3783 | } else { |
3784 | uint32_t val; |
3785 | |
3786 | CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f6 )), ((0x1)))); |
3787 | val = CSR_READ_2(sc, BWI_RF_DATA_HI)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x3f8 )))); |
3788 | val <<= 16; |
3789 | |
3790 | CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f6 )), ((0x1)))); |
3791 | val |= CSR_READ_2(sc, BWI_RF_DATA_LO)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x3fa )))); |
3792 | |
3793 | manu = __SHIFTOUT(val, BWI_RFINFO_MANUFACT_MASK)(((val) & (0x0fff)) / ((((0x0fff) - 1) & (0x0fff)) ^ ( 0x0fff))); |
3794 | type = __SHIFTOUT(val, BWI_RFINFO_TYPE_MASK)(((val) & (0x0ffff000)) / ((((0x0ffff000) - 1) & (0x0ffff000 )) ^ (0x0ffff000))); |
3795 | rev = __SHIFTOUT(val, BWI_RFINFO_REV_MASK)(((val) & (0xf0000000)) / ((((0xf0000000) - 1) & (0xf0000000 )) ^ (0xf0000000))); |
3796 | } |
3797 | DPRINTF(1, "%s: RF manu 0x%03x, type 0x%04x, rev %u\n", |
3798 | sc->sc_dev.dv_xname, manu, type, rev); |
3799 | |
3800 | /* |
3801 | * Verify whether the RF is supported |
3802 | */ |
3803 | rf->rf_ctrl_rd = 0; |
3804 | rf->rf_ctrl_adj = 0; |
3805 | switch (phy->phy_mode) { |
3806 | case IEEE80211_MODE_11A: |
3807 | if (manu != BWI_RF_MANUFACT_BCM0x17f || |
3808 | type != BWI_RF_T_BCM20600x2060 || |
3809 | rev != 1) { |
3810 | printf("%s: only BCM2060 rev 1 RF is supported for " |
3811 | "11A PHY\n", sc->sc_dev.dv_xname); |
3812 | return (ENXIO6); |
3813 | } |
3814 | rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11A0x40; |
3815 | rf->rf_on = bwi_rf_on_11a; |
3816 | rf->rf_off = bwi_rf_off_11a; |
3817 | rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2060; |
3818 | break; |
3819 | case IEEE80211_MODE_11B: |
3820 | if (type == BWI_RF_T_BCM20500x2050) { |
3821 | rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG0x80; |
3822 | rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050; |
3823 | } else if (type == BWI_RF_T_BCM20530x2053) { |
3824 | rf->rf_ctrl_adj = 1; |
3825 | rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2053; |
3826 | } else { |
3827 | printf("%s: only BCM2050/BCM2053 RF is supported " |
3828 | "for supported for 11B PHY\n", sc->sc_dev.dv_xname); |
3829 | return (ENXIO6); |
3830 | } |
3831 | rf->rf_on = bwi_rf_on_11bg; |
3832 | rf->rf_off = bwi_rf_off_11bg; |
3833 | rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11b; |
3834 | rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11b; |
3835 | if (phy->phy_rev == 6) |
3836 | rf->rf_lo_update = bwi_rf_lo_update_11g; |
3837 | else |
3838 | rf->rf_lo_update = bwi_rf_lo_update_11b; |
3839 | break; |
3840 | case IEEE80211_MODE_11G: |
3841 | if (type != BWI_RF_T_BCM20500x2050) { |
3842 | printf("%s: only BCM2050 RF is supported for 11G " |
3843 | "PHY\n", sc->sc_dev.dv_xname); |
3844 | return (ENXIO6); |
3845 | } |
3846 | rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG0x80; |
3847 | rf->rf_on = bwi_rf_on_11bg; |
3848 | if (mac->mac_revmac_regwin.rw_rev >= 5) |
3849 | rf->rf_off = bwi_rf_off_11g_rev5; |
3850 | else |
3851 | rf->rf_off = bwi_rf_off_11bg; |
3852 | rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11g; |
3853 | rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11g; |
3854 | rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050; |
3855 | rf->rf_lo_update = bwi_rf_lo_update_11g; |
3856 | break; |
3857 | default: |
3858 | printf("%s: unsupported PHY mode\n", sc->sc_dev.dv_xname); |
3859 | return (ENXIO6); |
3860 | } |
3861 | |
3862 | rf->rf_type = type; |
3863 | rf->rf_rev = rev; |
3864 | rf->rf_manu = manu; |
3865 | rf->rf_curchan = IEEE80211_CHAN_ANY0xffff; |
3866 | rf->rf_ant_mode = BWI_ANT_MODE_AUTO3; |
3867 | |
3868 | return (0); |
3869 | } |
3870 | |
3871 | void |
3872 | bwi_rf_set_chan(struct bwi_mac *mac, uint chan, int work_around) |
3873 | { |
3874 | struct bwi_softc *sc = mac->mac_sc; |
3875 | |
3876 | if (chan == IEEE80211_CHAN_ANY0xffff) |
3877 | return; |
3878 | |
3879 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_CHAN, chan)bwi_memobj_write_2((mac), (0x1), (0xa0), (chan)); |
3880 | |
3881 | /* TODO: 11A */ |
3882 | |
3883 | if (work_around) |
3884 | bwi_rf_workaround(mac, chan); |
3885 | |
3886 | CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan))(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f0 )), (((ieee80211_ieee2mhz((chan), 0x0080) - 2400))))); |
3887 | |
3888 | if (chan == 14) { |
3889 | if (sc->sc_locale == BWI_SPROM_LOCALE_JAPAN5) |
3890 | HFLAGS_CLRBITS(mac, BWI_HFLAG_NOT_JAPAN)bwi_hostflags_write(((mac)), (bwi_hostflags_read(((mac))) | ( 0x80ULL))); |
3891 | else |
3892 | HFLAGS_SETBITS(mac, BWI_HFLAG_NOT_JAPAN)bwi_hostflags_write(((mac)), (bwi_hostflags_read(((mac))) & ~(0x80ULL))); |
3893 | CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, (1 << 11))((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), ( ((0x03f4))), ((((((sc))->sc_mem_bt)->read_2((((sc))-> sc_mem_bh), (((0x03f4))))) | ((1 << 11)))))); /* XXX */ |
3894 | } else { |
3895 | CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0x840)((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), ( ((0x03f4))), ((((((sc))->sc_mem_bt)->read_2((((sc))-> sc_mem_bh), (((0x03f4))))) & ~(0x840))))); /* XXX */ |
3896 | } |
3897 | DELAY(8000)(*delay_func)(8000); /* DELAY(2000); */ |
3898 | |
3899 | mac->mac_rf.rf_curchan = chan; |
3900 | } |
3901 | |
3902 | void |
3903 | bwi_rf_get_gains(struct bwi_mac *mac) |
3904 | { |
3905 | #define SAVE_PHY_MAX 15 |
3906 | #define SAVE_RF_MAX 3 |
3907 | struct bwi_softc *sc; |
3908 | struct bwi_phy *phy = &mac->mac_phy; |
3909 | struct bwi_rf *rf = &mac->mac_rf; |
3910 | uint16_t save_phy[SAVE_PHY_MAX]; |
3911 | uint16_t save_rf[SAVE_RF_MAX]; |
3912 | uint16_t trsw; |
3913 | int i, j, loop1_max, loop1, loop2; |
3914 | |
3915 | static const uint16_t save_rf_regs[SAVE_RF_MAX] = |
3916 | { 0x52, 0x43, 0x7a }; |
3917 | static const uint16_t save_phy_regs[SAVE_PHY_MAX] = { |
3918 | 0x0429, 0x0001, 0x0811, 0x0812, |
3919 | 0x0814, 0x0815, 0x005a, 0x0059, |
3920 | 0x0058, 0x000a, 0x0003, 0x080f, |
3921 | 0x0810, 0x002b, 0x0015 |
3922 | }; |
3923 | |
3924 | sc = mac->mac_sc; |
3925 | |
3926 | /* |
3927 | * Save PHY/RF registers for later restoration |
3928 | */ |
3929 | for (i = 0; i < SAVE_PHY_MAX; ++i) |
3930 | save_phy[i] = PHY_READ(mac, save_phy_regs[i])bwi_phy_read((mac), (save_phy_regs[i])); |
3931 | PHY_READ(mac, 0x2d)bwi_phy_read((mac), (0x2d)); /* dummy read */ |
3932 | |
3933 | for (i = 0; i < SAVE_RF_MAX; ++i) |
3934 | save_rf[i] = RF_READ(mac, save_rf_regs[i])bwi_rf_read((mac), (save_rf_regs[i])); |
3935 | |
3936 | PHY_CLRBITS(mac, 0x429, 0xc000)bwi_phy_write(((mac)), ((0x429)), (bwi_phy_read(((mac)), ((0x429 ))) & ~(0xc000))); |
3937 | PHY_SETBITS(mac, 0x1, 0x8000)bwi_phy_write(((mac)), ((0x1)), (bwi_phy_read(((mac)), ((0x1) )) | (0x8000))); |
3938 | |
3939 | PHY_SETBITS(mac, 0x811, 0x2)bwi_phy_write(((mac)), ((0x811)), (bwi_phy_read(((mac)), ((0x811 ))) | (0x2))); |
3940 | PHY_CLRBITS(mac, 0x812, 0x2)bwi_phy_write(((mac)), ((0x812)), (bwi_phy_read(((mac)), ((0x812 ))) & ~(0x2))); |
3941 | PHY_SETBITS(mac, 0x811, 0x1)bwi_phy_write(((mac)), ((0x811)), (bwi_phy_read(((mac)), ((0x811 ))) | (0x1))); |
3942 | PHY_CLRBITS(mac, 0x812, 0x1)bwi_phy_write(((mac)), ((0x812)), (bwi_phy_read(((mac)), ((0x812 ))) & ~(0x1))); |
3943 | |
3944 | PHY_SETBITS(mac, 0x814, 0x1)bwi_phy_write(((mac)), ((0x814)), (bwi_phy_read(((mac)), ((0x814 ))) | (0x1))); |
3945 | PHY_CLRBITS(mac, 0x815, 0x1)bwi_phy_write(((mac)), ((0x815)), (bwi_phy_read(((mac)), ((0x815 ))) & ~(0x1))); |
3946 | PHY_SETBITS(mac, 0x814, 0x2)bwi_phy_write(((mac)), ((0x814)), (bwi_phy_read(((mac)), ((0x814 ))) | (0x2))); |
3947 | PHY_CLRBITS(mac, 0x815, 0x2)bwi_phy_write(((mac)), ((0x815)), (bwi_phy_read(((mac)), ((0x815 ))) & ~(0x2))); |
3948 | |
3949 | PHY_SETBITS(mac, 0x811, 0xc)bwi_phy_write(((mac)), ((0x811)), (bwi_phy_read(((mac)), ((0x811 ))) | (0xc))); |
3950 | PHY_SETBITS(mac, 0x812, 0xc)bwi_phy_write(((mac)), ((0x812)), (bwi_phy_read(((mac)), ((0x812 ))) | (0xc))); |
3951 | PHY_SETBITS(mac, 0x811, 0x30)bwi_phy_write(((mac)), ((0x811)), (bwi_phy_read(((mac)), ((0x811 ))) | (0x30))); |
3952 | PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10)bwi_phy_write(((mac)), ((0x812)), ((bwi_phy_read(((mac)), ((0x812 ))) & (0xffcf)) | (0x10))); |
3953 | |
3954 | PHY_WRITE(mac, 0x5a, 0x780)bwi_phy_write((mac), (0x5a), (0x780)); |
3955 | PHY_WRITE(mac, 0x59, 0xc810)bwi_phy_write((mac), (0x59), (0xc810)); |
3956 | PHY_WRITE(mac, 0x58, 0xd)bwi_phy_write((mac), (0x58), (0xd)); |
3957 | PHY_SETBITS(mac, 0xa, 0x2000)bwi_phy_write(((mac)), ((0xa)), (bwi_phy_read(((mac)), ((0xa) )) | (0x2000))); |
3958 | |
3959 | PHY_SETBITS(mac, 0x814, 0x4)bwi_phy_write(((mac)), ((0x814)), (bwi_phy_read(((mac)), ((0x814 ))) | (0x4))); |
3960 | PHY_CLRBITS(mac, 0x815, 0x4)bwi_phy_write(((mac)), ((0x815)), (bwi_phy_read(((mac)), ((0x815 ))) & ~(0x4))); |
3961 | |
3962 | PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40)bwi_phy_write(((mac)), ((0x3)), ((bwi_phy_read(((mac)), ((0x3 ))) & (0xff9f)) | (0x40))); |
3963 | |
3964 | if (rf->rf_rev == 8) { |
3965 | loop1_max = 15; |
3966 | RF_WRITE(mac, 0x43, loop1_max)bwi_rf_write((mac), (0x43), (loop1_max)); |
3967 | } else { |
3968 | loop1_max = 9; |
3969 | RF_WRITE(mac, 0x52, 0x0)bwi_rf_write((mac), (0x52), (0x0)); |
3970 | RF_FILT_SETBITS(mac, 0x43, 0xfff0, loop1_max)bwi_rf_write(((mac)), ((0x43)), ((bwi_rf_read(((mac)), ((0x43 ))) & (0xfff0)) | (loop1_max))); |
3971 | } |
3972 | |
3973 | bwi_phy_set_bbp_atten(mac, 11); |
3974 | |
3975 | if (phy->phy_rev >= 3) |
3976 | PHY_WRITE(mac, 0x80f, 0xc020)bwi_phy_write((mac), (0x80f), (0xc020)); |
3977 | else |
3978 | PHY_WRITE(mac, 0x80f, 0x8020)bwi_phy_write((mac), (0x80f), (0x8020)); |
3979 | PHY_WRITE(mac, 0x810, 0)bwi_phy_write((mac), (0x810), (0)); |
3980 | |
3981 | PHY_FILT_SETBITS(mac, 0x2b, 0xffc0, 0x1)bwi_phy_write(((mac)), ((0x2b)), ((bwi_phy_read(((mac)), ((0x2b ))) & (0xffc0)) | (0x1))); |
3982 | PHY_FILT_SETBITS(mac, 0x2b, 0xc0ff, 0x800)bwi_phy_write(((mac)), ((0x2b)), ((bwi_phy_read(((mac)), ((0x2b ))) & (0xc0ff)) | (0x800))); |
3983 | PHY_SETBITS(mac, 0x811, 0x100)bwi_phy_write(((mac)), ((0x811)), (bwi_phy_read(((mac)), ((0x811 ))) | (0x100))); |
3984 | PHY_CLRBITS(mac, 0x812, 0x3000)bwi_phy_write(((mac)), ((0x812)), (bwi_phy_read(((mac)), ((0x812 ))) & ~(0x3000))); |
3985 | |
3986 | if ((mac->mac_sc->sc_card_flags & BWI_CARD_F_EXT_LNA(1 << 12)) && |
3987 | phy->phy_rev >= 7) { |
3988 | PHY_SETBITS(mac, 0x811, 0x800)bwi_phy_write(((mac)), ((0x811)), (bwi_phy_read(((mac)), ((0x811 ))) | (0x800))); |
3989 | PHY_SETBITS(mac, 0x812, 0x8000)bwi_phy_write(((mac)), ((0x812)), (bwi_phy_read(((mac)), ((0x812 ))) | (0x8000))); |
3990 | } |
3991 | RF_CLRBITS(mac, 0x7a, 0xff08)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) & ~(0xff08))); |
3992 | |
3993 | /* |
3994 | * Find out 'loop1/loop2', which will be used to calculate |
3995 | * max loopback gain later |
3996 | */ |
3997 | j = 0; |
3998 | for (i = 0; i < loop1_max; ++i) { |
3999 | for (j = 0; j < 16; ++j) { |
4000 | RF_WRITE(mac, 0x43, i)bwi_rf_write((mac), (0x43), (i)); |
4001 | |
4002 | if (bwi_rf_gain_max_reached(mac, j)) |
4003 | goto loop1_exit; |
4004 | } |
4005 | } |
4006 | loop1_exit: |
4007 | loop1 = i; |
4008 | loop2 = j; |
4009 | |
4010 | /* |
4011 | * Find out 'trsw', which will be used to calculate |
4012 | * TRSW(TX/RX switch) RX gain later |
4013 | */ |
4014 | if (loop2 >= 8) { |
4015 | PHY_SETBITS(mac, 0x812, 0x30)bwi_phy_write(((mac)), ((0x812)), (bwi_phy_read(((mac)), ((0x812 ))) | (0x30))); |
4016 | trsw = 0x1b; |
4017 | for (i = loop2 - 8; i < 16; ++i) { |
4018 | trsw -= 3; |
4019 | if (bwi_rf_gain_max_reached(mac, i)) |
4020 | break; |
4021 | } |
4022 | } else { |
4023 | trsw = 0x18; |
4024 | } |
4025 | |
4026 | /* |
4027 | * Restore saved PHY/RF registers |
4028 | */ |
4029 | /* First 4 saved PHY registers need special processing */ |
4030 | for (i = 4; i < SAVE_PHY_MAX; ++i) |
4031 | PHY_WRITE(mac, save_phy_regs[i], save_phy[i])bwi_phy_write((mac), (save_phy_regs[i]), (save_phy[i])); |
4032 | |
4033 | bwi_phy_set_bbp_atten(mac, mac->mac_tpctl.bbp_atten); |
4034 | |
4035 | for (i = 0; i < SAVE_RF_MAX; ++i) |
4036 | RF_WRITE(mac, save_rf_regs[i], save_rf[i])bwi_rf_write((mac), (save_rf_regs[i]), (save_rf[i])); |
4037 | |
4038 | PHY_WRITE(mac, save_phy_regs[2], save_phy[2] | 0x3)bwi_phy_write((mac), (save_phy_regs[2]), (save_phy[2] | 0x3)); |
4039 | DELAY(10)(*delay_func)(10); |
4040 | PHY_WRITE(mac, save_phy_regs[2], save_phy[2])bwi_phy_write((mac), (save_phy_regs[2]), (save_phy[2])); |
4041 | PHY_WRITE(mac, save_phy_regs[3], save_phy[3])bwi_phy_write((mac), (save_phy_regs[3]), (save_phy[3])); |
4042 | PHY_WRITE(mac, save_phy_regs[0], save_phy[0])bwi_phy_write((mac), (save_phy_regs[0]), (save_phy[0])); |
4043 | PHY_WRITE(mac, save_phy_regs[1], save_phy[1])bwi_phy_write((mac), (save_phy_regs[1]), (save_phy[1])); |
4044 | |
4045 | /* |
4046 | * Calculate gains |
4047 | */ |
4048 | rf->rf_lo_gain = (loop2 * 6) - (loop1 * 4) - 11; |
4049 | rf->rf_rx_gain = trsw * 2; |
4050 | DPRINTF(1, "%s: lo gain: %u, rx gain: %u\n", |
4051 | sc->sc_dev.dv_xname, rf->rf_lo_gain, rf->rf_rx_gain); |
4052 | |
4053 | #undef SAVE_RF_MAX |
4054 | #undef SAVE_PHY_MAX |
4055 | } |
4056 | |
4057 | void |
4058 | bwi_rf_init(struct bwi_mac *mac) |
4059 | { |
4060 | struct bwi_rf *rf = &mac->mac_rf; |
4061 | |
4062 | if (rf->rf_type == BWI_RF_T_BCM20600x2060) { |
4063 | /* TODO: 11A */ |
4064 | } else { |
4065 | if (rf->rf_flags & BWI_RF_F_INITED0x1) |
4066 | RF_WRITE(mac, 0x78, rf->rf_calib)bwi_rf_write((mac), (0x78), (rf->rf_calib)); |
4067 | else |
4068 | bwi_rf_init_bcm2050(mac); |
4069 | } |
4070 | } |
4071 | |
4072 | void |
4073 | bwi_rf_off_11a(struct bwi_mac *mac) |
4074 | { |
4075 | RF_WRITE(mac, 0x4, 0xff)bwi_rf_write((mac), (0x4), (0xff)); |
4076 | RF_WRITE(mac, 0x5, 0xfb)bwi_rf_write((mac), (0x5), (0xfb)); |
4077 | |
4078 | PHY_SETBITS(mac, 0x10, 0x8)bwi_phy_write(((mac)), ((0x10)), (bwi_phy_read(((mac)), ((0x10 ))) | (0x8))); |
4079 | PHY_SETBITS(mac, 0x11, 0x8)bwi_phy_write(((mac)), ((0x11)), (bwi_phy_read(((mac)), ((0x11 ))) | (0x8))); |
4080 | |
4081 | PHY_WRITE(mac, 0x15, 0xaa00)bwi_phy_write((mac), (0x15), (0xaa00)); |
4082 | } |
4083 | |
4084 | void |
4085 | bwi_rf_off_11bg(struct bwi_mac *mac) |
4086 | { |
4087 | PHY_WRITE(mac, 0x15, 0xaa00)bwi_phy_write((mac), (0x15), (0xaa00)); |
4088 | } |
4089 | |
4090 | void |
4091 | bwi_rf_off_11g_rev5(struct bwi_mac *mac) |
4092 | { |
4093 | PHY_SETBITS(mac, 0x811, 0x8c)bwi_phy_write(((mac)), ((0x811)), (bwi_phy_read(((mac)), ((0x811 ))) | (0x8c))); |
4094 | PHY_CLRBITS(mac, 0x812, 0x8c)bwi_phy_write(((mac)), ((0x812)), (bwi_phy_read(((mac)), ((0x812 ))) & ~(0x8c))); |
4095 | } |
4096 | |
4097 | void |
4098 | bwi_rf_workaround(struct bwi_mac *mac, uint chan) |
4099 | { |
4100 | struct bwi_softc *sc = mac->mac_sc; |
4101 | struct bwi_rf *rf = &mac->mac_rf; |
4102 | |
4103 | if (chan == IEEE80211_CHAN_ANY0xffff) { |
4104 | printf("%s: %s invalid channel!\n", |
4105 | sc->sc_dev.dv_xname, __func__); |
4106 | return; |
4107 | } |
4108 | |
4109 | if (rf->rf_type != BWI_RF_T_BCM20500x2050 || rf->rf_rev >= 6) |
4110 | return; |
4111 | |
4112 | if (chan <= 10) |
4113 | CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan + 4))(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f0 )), (((ieee80211_ieee2mhz((chan + 4), 0x0080) - 2400))))); |
4114 | else |
4115 | CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(1))(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f0 )), (((ieee80211_ieee2mhz((1), 0x0080) - 2400))))); |
4116 | DELAY(1000)(*delay_func)(1000); |
4117 | CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan))(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f0 )), (((ieee80211_ieee2mhz((chan), 0x0080) - 2400))))); |
4118 | } |
4119 | |
4120 | struct bwi_rf_lo * |
4121 | bwi_rf_lo_find(struct bwi_mac *mac, const struct bwi_tpctl *tpctl) |
4122 | { |
4123 | uint16_t rf_atten, bbp_atten; |
4124 | int remap_rf_atten; |
4125 | |
4126 | remap_rf_atten = 1; |
4127 | if (tpctl == NULL((void *)0)) { |
4128 | bbp_atten = 2; |
4129 | rf_atten = 3; |
4130 | } else { |
4131 | if (tpctl->tp_ctrl1 == 3) |
4132 | remap_rf_atten = 0; |
4133 | |
4134 | bbp_atten = tpctl->bbp_atten; |
4135 | rf_atten = tpctl->rf_atten; |
4136 | |
4137 | if (bbp_atten > 6) |
4138 | bbp_atten = 6; |
4139 | } |
4140 | |
4141 | if (remap_rf_atten) { |
4142 | #define MAP_MAX 10 |
4143 | static const uint16_t map[MAP_MAX] = |
4144 | { 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 }; |
4145 | #if 0 |
4146 | KASSERT(rf_atten < MAP_MAX)((rf_atten < MAP_MAX) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c" , 4146, "rf_atten < MAP_MAX")); |
4147 | rf_atten = map[rf_atten]; |
4148 | #else |
4149 | if (rf_atten >= MAP_MAX) { |
4150 | rf_atten = 0; /* XXX */ |
4151 | } else { |
4152 | rf_atten = map[rf_atten]; |
4153 | } |
4154 | #endif |
4155 | #undef MAP_MAX |
4156 | } |
4157 | |
4158 | return (bwi_get_rf_lo(mac, rf_atten, bbp_atten)); |
4159 | } |
4160 | |
4161 | void |
4162 | bwi_rf_lo_adjust(struct bwi_mac *mac, const struct bwi_tpctl *tpctl) |
4163 | { |
4164 | const struct bwi_rf_lo *lo; |
4165 | |
4166 | lo = bwi_rf_lo_find(mac, tpctl); |
4167 | RF_LO_WRITE(mac, lo)bwi_rf_lo_write((mac), (lo)); |
4168 | } |
4169 | |
4170 | void |
4171 | bwi_rf_lo_write(struct bwi_mac *mac, const struct bwi_rf_lo *lo) |
4172 | { |
4173 | uint16_t val; |
4174 | |
4175 | val = (uint8_t)lo->ctrl_lo; |
4176 | val |= ((uint8_t)lo->ctrl_hi) << 8; |
4177 | |
4178 | PHY_WRITE(mac, BWI_PHYR_RF_LO, val)bwi_phy_write((mac), (0x810), (val)); |
4179 | } |
4180 | |
4181 | int |
4182 | bwi_rf_gain_max_reached(struct bwi_mac *mac, int idx) |
4183 | { |
4184 | PHY_FILT_SETBITS(mac, 0x812, 0xf0ff, idx << 8)bwi_phy_write(((mac)), ((0x812)), ((bwi_phy_read(((mac)), ((0x812 ))) & (0xf0ff)) | (idx << 8))); |
4185 | PHY_FILT_SETBITS(mac, 0x15, 0xfff, 0xa000)bwi_phy_write(((mac)), ((0x15)), ((bwi_phy_read(((mac)), ((0x15 ))) & (0xfff)) | (0xa000))); |
4186 | PHY_SETBITS(mac, 0x15, 0xf000)bwi_phy_write(((mac)), ((0x15)), (bwi_phy_read(((mac)), ((0x15 ))) | (0xf000))); |
4187 | |
4188 | DELAY(20)(*delay_func)(20); |
4189 | |
4190 | return ((PHY_READ(mac, 0x2d)bwi_phy_read((mac), (0x2d)) >= 0xdfc)); |
4191 | } |
4192 | |
4193 | /* XXX use bitmap array */ |
4194 | uint16_t |
4195 | bwi_bitswap4(uint16_t val) |
4196 | { |
4197 | uint16_t ret; |
4198 | |
4199 | ret = (val & 0x8) >> 3; |
4200 | ret |= (val & 0x4) >> 1; |
4201 | ret |= (val & 0x2) << 1; |
4202 | ret |= (val & 0x1) << 3; |
4203 | |
4204 | return (ret); |
4205 | } |
4206 | |
4207 | uint16_t |
4208 | bwi_phy812_value(struct bwi_mac *mac, uint16_t lpd) |
4209 | { |
4210 | struct bwi_softc *sc = mac->mac_sc; |
4211 | struct bwi_phy *phy = &mac->mac_phy; |
4212 | struct bwi_rf *rf = &mac->mac_rf; |
4213 | uint16_t lo_gain, ext_lna, loop; |
4214 | |
4215 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) == 0) |
4216 | return (0); |
4217 | |
4218 | lo_gain = rf->rf_lo_gain; |
4219 | if (rf->rf_rev == 8) |
4220 | lo_gain += 0x3e; |
4221 | else |
4222 | lo_gain += 0x26; |
4223 | |
4224 | if (lo_gain >= 0x46) { |
4225 | lo_gain -= 0x46; |
4226 | ext_lna = 0x3000; |
4227 | } else if (lo_gain >= 0x3a) { |
4228 | lo_gain -= 0x3a; |
4229 | ext_lna = 0x1000; |
4230 | } else if (lo_gain >= 0x2e) { |
4231 | lo_gain -= 0x2e; |
4232 | ext_lna = 0x2000; |
4233 | } else { |
4234 | lo_gain -= 0x10; |
4235 | ext_lna = 0; |
4236 | } |
4237 | |
4238 | for (loop = 0; loop < 16; ++loop) { |
4239 | lo_gain -= (6 * loop); |
4240 | if (lo_gain < 6) |
4241 | break; |
4242 | } |
4243 | |
4244 | if (phy->phy_rev >= 7 && (sc->sc_card_flags & BWI_CARD_F_EXT_LNA(1 << 12))) { |
4245 | if (ext_lna) |
4246 | ext_lna |= 0x8000; |
4247 | ext_lna |= (loop << 8); |
4248 | switch (lpd) { |
4249 | case 0x011: |
4250 | return (0x8f92); |
4251 | case 0x001: |
4252 | return ((0x8092 | ext_lna)); |
4253 | case 0x101: |
4254 | return ((0x2092 | ext_lna)); |
4255 | case 0x100: |
4256 | return ((0x2093 | ext_lna)); |
4257 | default: |
4258 | panic("unsupported lpd"); |
4259 | } |
4260 | } else { |
4261 | ext_lna |= (loop << 8); |
4262 | switch (lpd) { |
4263 | case 0x011: |
4264 | return (0xf92); |
4265 | case 0x001: |
4266 | case 0x101: |
4267 | return ((0x92 | ext_lna)); |
4268 | case 0x100: |
4269 | return ((0x93 | ext_lna)); |
4270 | default: |
4271 | panic("unsupported lpd"); |
4272 | } |
4273 | } |
4274 | |
4275 | panic("never reached"); |
4276 | |
4277 | return (0); |
4278 | } |
4279 | |
4280 | void |
4281 | bwi_rf_init_bcm2050(struct bwi_mac *mac) |
4282 | { |
4283 | #define SAVE_RF_MAX 3 |
4284 | #define SAVE_PHY_COMM_MAX 4 |
4285 | #define SAVE_PHY_11G_MAX 6 |
4286 | uint16_t save_rf[SAVE_RF_MAX]; |
4287 | uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; |
4288 | uint16_t save_phy_11g[SAVE_PHY_11G_MAX]; |
4289 | uint16_t phyr_35, phyr_30 = 0, rfr_78, phyr_80f = 0, phyr_810 = 0; |
4290 | uint16_t bphy_ctrl = 0, bbp_atten, rf_chan_ex; |
4291 | uint16_t phy812_val; |
4292 | uint16_t calib; |
4293 | uint32_t test_lim, test; |
4294 | struct bwi_softc *sc = mac->mac_sc; |
4295 | struct bwi_phy *phy = &mac->mac_phy; |
4296 | struct bwi_rf *rf = &mac->mac_rf; |
4297 | int i; |
4298 | |
4299 | static const uint16_t save_rf_regs[SAVE_RF_MAX] = |
4300 | { 0x0043, 0x0051, 0x0052 }; |
4301 | static const uint16_t save_phy_regs_comm[SAVE_PHY_COMM_MAX] = |
4302 | { 0x0015, 0x005a, 0x0059, 0x0058 }; |
4303 | static const uint16_t save_phy_regs_11g[SAVE_PHY_11G_MAX] = |
4304 | { 0x0811, 0x0812, 0x0814, 0x0815, 0x0429, 0x0802 }; |
4305 | |
4306 | /* |
4307 | * Save registers for later restoring |
4308 | */ |
4309 | for (i = 0; i < SAVE_RF_MAX; ++i) |
4310 | save_rf[i] = RF_READ(mac, save_rf_regs[i])bwi_rf_read((mac), (save_rf_regs[i])); |
4311 | for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) |
4312 | save_phy_comm[i] = PHY_READ(mac, save_phy_regs_comm[i])bwi_phy_read((mac), (save_phy_regs_comm[i])); |
4313 | |
4314 | if (phy->phy_mode == IEEE80211_MODE_11B) { |
4315 | phyr_30 = PHY_READ(mac, 0x30)bwi_phy_read((mac), (0x30)); |
4316 | bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03ec )))); |
4317 | |
4318 | PHY_WRITE(mac, 0x30, 0xff)bwi_phy_write((mac), (0x30), (0xff)); |
4319 | CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x3f3f)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03ec )), ((0x3f3f)))); |
4320 | } else if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || phy->phy_rev >= 2) { |
4321 | for (i = 0; i < SAVE_PHY_11G_MAX; ++i) { |
4322 | save_phy_11g[i] = |
4323 | PHY_READ(mac, save_phy_regs_11g[i])bwi_phy_read((mac), (save_phy_regs_11g[i])); |
4324 | } |
4325 | |
4326 | PHY_SETBITS(mac, 0x814, 0x3)bwi_phy_write(((mac)), ((0x814)), (bwi_phy_read(((mac)), ((0x814 ))) | (0x3))); |
4327 | PHY_CLRBITS(mac, 0x815, 0x3)bwi_phy_write(((mac)), ((0x815)), (bwi_phy_read(((mac)), ((0x815 ))) & ~(0x3))); |
4328 | PHY_CLRBITS(mac, 0x429, 0x8000)bwi_phy_write(((mac)), ((0x429)), (bwi_phy_read(((mac)), ((0x429 ))) & ~(0x8000))); |
4329 | PHY_CLRBITS(mac, 0x802, 0x3)bwi_phy_write(((mac)), ((0x802)), (bwi_phy_read(((mac)), ((0x802 ))) & ~(0x3))); |
4330 | |
4331 | phyr_80f = PHY_READ(mac, 0x80f)bwi_phy_read((mac), (0x80f)); |
4332 | phyr_810 = PHY_READ(mac, 0x810)bwi_phy_read((mac), (0x810)); |
4333 | |
4334 | if (phy->phy_rev >= 3) |
4335 | PHY_WRITE(mac, 0x80f, 0xc020)bwi_phy_write((mac), (0x80f), (0xc020)); |
4336 | else |
4337 | PHY_WRITE(mac, 0x80f, 0x8020)bwi_phy_write((mac), (0x80f), (0x8020)); |
4338 | PHY_WRITE(mac, 0x810, 0)bwi_phy_write((mac), (0x810), (0)); |
4339 | |
4340 | phy812_val = bwi_phy812_value(mac, 0x011); |
4341 | PHY_WRITE(mac, 0x812, phy812_val)bwi_phy_write((mac), (0x812), (phy812_val)); |
4342 | if (phy->phy_rev < 7 || |
4343 | (sc->sc_card_flags & BWI_CARD_F_EXT_LNA(1 << 12)) == 0) |
4344 | PHY_WRITE(mac, 0x811, 0x1b3)bwi_phy_write((mac), (0x811), (0x1b3)); |
4345 | else |
4346 | PHY_WRITE(mac, 0x811, 0x9b3)bwi_phy_write((mac), (0x811), (0x9b3)); |
4347 | } |
4348 | CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000)((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), ( ((0x03e2))), ((((((sc))->sc_mem_bt)->read_2((((sc))-> sc_mem_bh), (((0x03e2))))) | (0x8000))))); |
4349 | |
4350 | phyr_35 = PHY_READ(mac, 0x35)bwi_phy_read((mac), (0x35)); |
4351 | PHY_CLRBITS(mac, 0x35, 0x80)bwi_phy_write(((mac)), ((0x35)), (bwi_phy_read(((mac)), ((0x35 ))) & ~(0x80))); |
4352 | |
4353 | bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03e6 )))); |
4354 | rf_chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03f4 )))); |
4355 | |
4356 | if (phy->phy_version == 0) { |
4357 | CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e6 )), ((0x122)))); |
4358 | } else { |
4359 | if (phy->phy_version >= 2) |
4360 | PHY_FILT_SETBITS(mac, 0x3, 0xffbf, 0x40)bwi_phy_write(((mac)), ((0x3)), ((bwi_phy_read(((mac)), ((0x3 ))) & (0xffbf)) | (0x40))); |
4361 | CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000)((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), ( ((0x03f4))), ((((((sc))->sc_mem_bt)->read_2((((sc))-> sc_mem_bh), (((0x03f4))))) | (0x2000))))); |
4362 | } |
4363 | |
4364 | calib = bwi_rf_calibval(mac); |
4365 | |
4366 | if (phy->phy_mode == IEEE80211_MODE_11B) |
4367 | RF_WRITE(mac, 0x78, 0x26)bwi_rf_write((mac), (0x78), (0x26)); |
4368 | |
4369 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || phy->phy_rev >= 2) { |
4370 | phy812_val = bwi_phy812_value(mac, 0x011); |
4371 | PHY_WRITE(mac, 0x812, phy812_val)bwi_phy_write((mac), (0x812), (phy812_val)); |
4372 | } |
4373 | |
4374 | PHY_WRITE(mac, 0x15, 0xbfaf)bwi_phy_write((mac), (0x15), (0xbfaf)); |
4375 | PHY_WRITE(mac, 0x2b, 0x1403)bwi_phy_write((mac), (0x2b), (0x1403)); |
4376 | |
4377 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || phy->phy_rev >= 2) { |
4378 | phy812_val = bwi_phy812_value(mac, 0x001); |
4379 | PHY_WRITE(mac, 0x812, phy812_val)bwi_phy_write((mac), (0x812), (phy812_val)); |
4380 | } |
4381 | |
4382 | PHY_WRITE(mac, 0x15, 0xbfa0)bwi_phy_write((mac), (0x15), (0xbfa0)); |
4383 | |
4384 | RF_SETBITS(mac, 0x51, 0x4)bwi_rf_write(((mac)), ((0x51)), (bwi_rf_read(((mac)), ((0x51) )) | (0x4))); |
4385 | if (rf->rf_rev == 8) |
4386 | RF_WRITE(mac, 0x43, 0x1f)bwi_rf_write((mac), (0x43), (0x1f)); |
4387 | else { |
4388 | RF_WRITE(mac, 0x52, 0)bwi_rf_write((mac), (0x52), (0)); |
4389 | RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9)bwi_rf_write(((mac)), ((0x43)), ((bwi_rf_read(((mac)), ((0x43 ))) & (0xfff0)) | (0x9))); |
4390 | } |
4391 | |
4392 | test_lim = 0; |
4393 | PHY_WRITE(mac, 0x58, 0)bwi_phy_write((mac), (0x58), (0)); |
4394 | for (i = 0; i < 16; ++i) { |
4395 | PHY_WRITE(mac, 0x5a, 0x480)bwi_phy_write((mac), (0x5a), (0x480)); |
4396 | PHY_WRITE(mac, 0x59, 0xc810)bwi_phy_write((mac), (0x59), (0xc810)); |
4397 | |
4398 | PHY_WRITE(mac, 0x58, 0xd)bwi_phy_write((mac), (0x58), (0xd)); |
4399 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || phy->phy_rev >= 2) { |
4400 | phy812_val = bwi_phy812_value(mac, 0x101); |
4401 | PHY_WRITE(mac, 0x812, phy812_val)bwi_phy_write((mac), (0x812), (phy812_val)); |
4402 | } |
4403 | PHY_WRITE(mac, 0x15, 0xafb0)bwi_phy_write((mac), (0x15), (0xafb0)); |
4404 | DELAY(10)(*delay_func)(10); |
4405 | |
4406 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || phy->phy_rev >= 2) { |
4407 | phy812_val = bwi_phy812_value(mac, 0x101); |
4408 | PHY_WRITE(mac, 0x812, phy812_val)bwi_phy_write((mac), (0x812), (phy812_val)); |
4409 | } |
4410 | PHY_WRITE(mac, 0x15, 0xefb0)bwi_phy_write((mac), (0x15), (0xefb0)); |
4411 | DELAY(10)(*delay_func)(10); |
4412 | |
4413 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || phy->phy_rev >= 2) { |
4414 | phy812_val = bwi_phy812_value(mac, 0x100); |
4415 | PHY_WRITE(mac, 0x812, phy812_val)bwi_phy_write((mac), (0x812), (phy812_val)); |
4416 | } |
4417 | PHY_WRITE(mac, 0x15, 0xfff0)bwi_phy_write((mac), (0x15), (0xfff0)); |
4418 | DELAY(20)(*delay_func)(20); |
4419 | |
4420 | test_lim += PHY_READ(mac, 0x2d)bwi_phy_read((mac), (0x2d)); |
4421 | |
4422 | PHY_WRITE(mac, 0x58, 0)bwi_phy_write((mac), (0x58), (0)); |
4423 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || phy->phy_rev >= 2) { |
4424 | phy812_val = bwi_phy812_value(mac, 0x101); |
4425 | PHY_WRITE(mac, 0x812, phy812_val)bwi_phy_write((mac), (0x812), (phy812_val)); |
4426 | } |
4427 | PHY_WRITE(mac, 0x15, 0xafb0)bwi_phy_write((mac), (0x15), (0xafb0)); |
4428 | } |
4429 | ++test_lim; |
4430 | test_lim >>= 9; |
4431 | |
4432 | DELAY(10)(*delay_func)(10); |
4433 | |
4434 | test = 0; |
4435 | PHY_WRITE(mac, 0x58, 0)bwi_phy_write((mac), (0x58), (0)); |
4436 | for (i = 0; i < 16; ++i) { |
4437 | int j; |
4438 | |
4439 | rfr_78 = (bwi_bitswap4(i) << 1) | 0x20; |
4440 | RF_WRITE(mac, 0x78, rfr_78)bwi_rf_write((mac), (0x78), (rfr_78)); |
4441 | DELAY(10)(*delay_func)(10); |
4442 | |
4443 | /* NB: This block is slight different than the above one */ |
4444 | for (j = 0; j < 16; ++j) { |
4445 | PHY_WRITE(mac, 0x5a, 0xd80)bwi_phy_write((mac), (0x5a), (0xd80)); |
4446 | PHY_WRITE(mac, 0x59, 0xc810)bwi_phy_write((mac), (0x59), (0xc810)); |
4447 | |
4448 | PHY_WRITE(mac, 0x58, 0xd)bwi_phy_write((mac), (0x58), (0xd)); |
4449 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || |
4450 | phy->phy_rev >= 2) { |
4451 | phy812_val = bwi_phy812_value(mac, 0x101); |
4452 | PHY_WRITE(mac, 0x812, phy812_val)bwi_phy_write((mac), (0x812), (phy812_val)); |
4453 | } |
4454 | PHY_WRITE(mac, 0x15, 0xafb0)bwi_phy_write((mac), (0x15), (0xafb0)); |
4455 | DELAY(10)(*delay_func)(10); |
4456 | |
4457 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || |
4458 | phy->phy_rev >= 2) { |
4459 | phy812_val = bwi_phy812_value(mac, 0x101); |
4460 | PHY_WRITE(mac, 0x812, phy812_val)bwi_phy_write((mac), (0x812), (phy812_val)); |
4461 | } |
4462 | PHY_WRITE(mac, 0x15, 0xefb0)bwi_phy_write((mac), (0x15), (0xefb0)); |
4463 | DELAY(10)(*delay_func)(10); |
4464 | |
4465 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || |
4466 | phy->phy_rev >= 2) { |
4467 | phy812_val = bwi_phy812_value(mac, 0x100); |
4468 | PHY_WRITE(mac, 0x812, phy812_val)bwi_phy_write((mac), (0x812), (phy812_val)); |
4469 | } |
4470 | PHY_WRITE(mac, 0x15, 0xfff0)bwi_phy_write((mac), (0x15), (0xfff0)); |
4471 | DELAY(10)(*delay_func)(10); |
4472 | |
4473 | test += PHY_READ(mac, 0x2d)bwi_phy_read((mac), (0x2d)); |
4474 | |
4475 | PHY_WRITE(mac, 0x58, 0)bwi_phy_write((mac), (0x58), (0)); |
4476 | if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || |
4477 | phy->phy_rev >= 2) { |
4478 | phy812_val = bwi_phy812_value(mac, 0x101); |
4479 | PHY_WRITE(mac, 0x812, phy812_val)bwi_phy_write((mac), (0x812), (phy812_val)); |
4480 | } |
4481 | PHY_WRITE(mac, 0x15, 0xafb0)bwi_phy_write((mac), (0x15), (0xafb0)); |
4482 | } |
4483 | |
4484 | ++test; |
4485 | test >>= 8; |
4486 | |
4487 | if (test > test_lim) |
4488 | break; |
4489 | } |
4490 | if (i > 15) |
4491 | rf->rf_calib = rfr_78; |
4492 | else |
4493 | rf->rf_calib = calib; |
4494 | if (rf->rf_calib != 0xffff) { |
4495 | DPRINTF(1, "%s: RF calibration value: 0x%04x\n", |
4496 | sc->sc_dev.dv_xname, rf->rf_calib); |
4497 | rf->rf_flags |= BWI_RF_F_INITED0x1; |
4498 | } |
4499 | |
4500 | /* |
4501 | * Restore trashes registers |
4502 | */ |
4503 | PHY_WRITE(mac, save_phy_regs_comm[0], save_phy_comm[0])bwi_phy_write((mac), (save_phy_regs_comm[0]), (save_phy_comm[ 0])); |
4504 | |
4505 | for (i = 0; i < SAVE_RF_MAX; ++i) { |
4506 | int pos = (i + 1) % SAVE_RF_MAX; |
4507 | |
4508 | RF_WRITE(mac, save_rf_regs[pos], save_rf[pos])bwi_rf_write((mac), (save_rf_regs[pos]), (save_rf[pos])); |
4509 | } |
4510 | for (i = 1; i < SAVE_PHY_COMM_MAX; ++i) |
4511 | PHY_WRITE(mac, save_phy_regs_comm[i], save_phy_comm[i])bwi_phy_write((mac), (save_phy_regs_comm[i]), (save_phy_comm[ i])); |
4512 | |
4513 | CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e6 )), ((bbp_atten)))); |
4514 | if (phy->phy_version != 0) |
4515 | CSR_WRITE_2(sc, BWI_RF_CHAN_EX, rf_chan_ex)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f4 )), ((rf_chan_ex)))); |
4516 | |
4517 | PHY_WRITE(mac, 0x35, phyr_35)bwi_phy_write((mac), (0x35), (phyr_35)); |
4518 | bwi_rf_workaround(mac, rf->rf_curchan); |
4519 | |
4520 | if (phy->phy_mode == IEEE80211_MODE_11B) { |
4521 | PHY_WRITE(mac, 0x30, phyr_30)bwi_phy_write((mac), (0x30), (phyr_30)); |
4522 | CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03ec )), ((bphy_ctrl)))); |
4523 | } else if ((phy->phy_flags & BWI_PHY_F_LINKED0x2) || phy->phy_rev >= 2) { |
4524 | /* XXX Spec only says when PHY is linked (gmode) */ |
4525 | CSR_CLRBITS_2(sc, BWI_RF_ANTDIV, 0x8000)((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), ( ((0x03e2))), ((((((sc))->sc_mem_bt)->read_2((((sc))-> sc_mem_bh), (((0x03e2))))) & ~(0x8000))))); |
4526 | |
4527 | for (i = 0; i < SAVE_PHY_11G_MAX; ++i) { |
4528 | PHY_WRITE(mac, save_phy_regs_11g[i],bwi_phy_write((mac), (save_phy_regs_11g[i]), (save_phy_11g[i] )) |
4529 | save_phy_11g[i])bwi_phy_write((mac), (save_phy_regs_11g[i]), (save_phy_11g[i] )); |
4530 | } |
4531 | |
4532 | PHY_WRITE(mac, 0x80f, phyr_80f)bwi_phy_write((mac), (0x80f), (phyr_80f)); |
4533 | PHY_WRITE(mac, 0x810, phyr_810)bwi_phy_write((mac), (0x810), (phyr_810)); |
4534 | } |
4535 | |
4536 | #undef SAVE_PHY_11G_MAX |
4537 | #undef SAVE_PHY_COMM_MAX |
4538 | #undef SAVE_RF_MAX |
4539 | } |
4540 | |
4541 | uint16_t |
4542 | bwi_rf_calibval(struct bwi_mac *mac) |
4543 | { |
4544 | uint16_t val, calib; |
4545 | int idx; |
4546 | |
4547 | /* http://bcm-specs.sipsolutions.net/RCCTable */ |
4548 | static const uint16_t rf_calibvals[] = { |
4549 | 0x2, 0x3, 0x1, 0xf, 0x6, 0x7, 0x5, 0xf, |
4550 | 0xa, 0xb, 0x9, 0xf, 0xe, 0xf, 0xd, 0xf |
4551 | }; |
4552 | |
4553 | val = RF_READ(mac, BWI_RFR_BBP_ATTEN)bwi_rf_read((mac), (0x60)); |
4554 | idx = __SHIFTOUT(val, BWI_RFR_BBP_ATTEN_CALIB_IDX)(((val) & ((0x0f << 1))) / (((((0x0f << 1)) - 1) & ((0x0f << 1))) ^ ((0x0f << 1)))); |
4555 | KASSERT(idx < (int)(sizeof(rf_calibvals) / sizeof(rf_calibvals[0])))((idx < (int)(sizeof(rf_calibvals) / sizeof(rf_calibvals[0 ]))) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c" , 4555, "idx < (int)(sizeof(rf_calibvals) / sizeof(rf_calibvals[0]))" )); |
4556 | |
4557 | calib = rf_calibvals[idx] << 1; |
4558 | if (val & BWI_RFR_BBP_ATTEN_CALIB_BIT(1 << 0)) |
4559 | calib |= 0x1; |
4560 | calib |= 0x20; |
4561 | |
4562 | return (calib); |
4563 | } |
4564 | |
4565 | int32_t |
4566 | _bwi_adjust_devide(int32_t num, int32_t den) |
4567 | { |
4568 | if (num < 0) |
4569 | return ((num / den)); |
4570 | else |
4571 | return ((num + den / 2) / den); |
4572 | } |
4573 | |
4574 | /* |
4575 | * http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table |
4576 | * "calculating table entries" |
4577 | */ |
4578 | int |
4579 | bwi_rf_calc_txpower(int8_t *txpwr, uint8_t idx, const int16_t pa_params[]) |
4580 | { |
4581 | int32_t m1, m2, f, dbm; |
4582 | int i; |
4583 | |
4584 | m1 = _bwi_adjust_devide(16 * pa_params[0] + idx * pa_params[1], 32); |
4585 | m2 = imax(_bwi_adjust_devide(32768 + idx * pa_params[2], 256), 1); |
4586 | |
4587 | #define ITER_MAX 16 |
4588 | f = 256; |
4589 | for (i = 0; i < ITER_MAX; ++i) { |
4590 | int32_t q, d; |
4591 | |
4592 | q = _bwi_adjust_devide( |
4593 | f * 4096 - _bwi_adjust_devide(m2 * f, 16) * f, 2048); |
4594 | d = abs(q - f); |
4595 | f = q; |
4596 | |
4597 | if (d < 2) |
4598 | break; |
4599 | } |
4600 | if (i == ITER_MAX) |
4601 | return (EINVAL22); |
4602 | #undef ITER_MAX |
4603 | |
4604 | dbm = _bwi_adjust_devide(m1 * f, 8192); |
4605 | if (dbm < -127) |
4606 | dbm = -127; |
4607 | else if (dbm > 128) |
4608 | dbm = 128; |
4609 | |
4610 | *txpwr = dbm; |
4611 | |
4612 | return (0); |
4613 | } |
4614 | |
4615 | int |
4616 | bwi_rf_map_txpower(struct bwi_mac *mac) |
4617 | { |
4618 | struct bwi_softc *sc = mac->mac_sc; |
4619 | struct bwi_rf *rf = &mac->mac_rf; |
4620 | struct bwi_phy *phy = &mac->mac_phy; |
4621 | uint16_t sprom_ofs, val, mask; |
4622 | int16_t pa_params[3]; |
4623 | int error = 0, i, ant_gain, reg_txpower_max; |
4624 | |
4625 | /* |
4626 | * Find out max TX power |
4627 | */ |
4628 | val = bwi_read_sprom(sc, BWI_SPROM_MAX_TXPWR0x68); |
4629 | if (phy->phy_mode == IEEE80211_MODE_11A) { |
4630 | rf->rf_txpower_max = __SHIFTOUT(val,(((val) & (0xff00)) / ((((0xff00) - 1) & (0xff00)) ^ ( 0xff00))) |
4631 | BWI_SPROM_MAX_TXPWR_MASK_11A)(((val) & (0xff00)) / ((((0xff00) - 1) & (0xff00)) ^ ( 0xff00))); |
4632 | } else { |
4633 | rf->rf_txpower_max = __SHIFTOUT(val,(((val) & (0x00ff)) / ((((0x00ff) - 1) & (0x00ff)) ^ ( 0x00ff))) |
4634 | BWI_SPROM_MAX_TXPWR_MASK_11BG)(((val) & (0x00ff)) / ((((0x00ff) - 1) & (0x00ff)) ^ ( 0x00ff))); |
4635 | |
4636 | if ((sc->sc_card_flags & BWI_CARD_F_PA_GPIO9(1 << 1)) && |
4637 | phy->phy_mode == IEEE80211_MODE_11G) |
4638 | rf->rf_txpower_max -= 3; |
4639 | } |
4640 | if (rf->rf_txpower_max <= 0) { |
4641 | printf("%s: invalid max txpower in sprom\n", |
4642 | sc->sc_dev.dv_xname); |
4643 | rf->rf_txpower_max = 74; |
4644 | } |
4645 | DPRINTF(1, "%s: max txpower from sprom: %d dBm\n", |
4646 | sc->sc_dev.dv_xname, rf->rf_txpower_max); |
4647 | |
4648 | /* |
4649 | * Find out region/domain max TX power, which is adjusted |
4650 | * by antenna gain and 1.5 dBm fluctuation as mentioned |
4651 | * in v3 spec. |
4652 | */ |
4653 | val = bwi_read_sprom(sc, BWI_SPROM_ANT_GAIN0x74); |
4654 | if (phy->phy_mode == IEEE80211_MODE_11A) |
4655 | ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11A)(((val) & (0x00ff)) / ((((0x00ff) - 1) & (0x00ff)) ^ ( 0x00ff))); |
4656 | else |
4657 | ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11BG)(((val) & (0xff00)) / ((((0xff00) - 1) & (0xff00)) ^ ( 0xff00))); |
4658 | if (ant_gain == 0xff) { |
4659 | /* XXX why this always invalid? */ |
4660 | DPRINTF(1, "%s: invalid antenna gain in sprom\n", |
4661 | sc->sc_dev.dv_xname); |
4662 | ant_gain = 2; |
4663 | } |
4664 | ant_gain *= 4; |
4665 | DPRINTF(1, "%s: ant gain %d dBm\n", sc->sc_dev.dv_xname, ant_gain); |
4666 | |
4667 | reg_txpower_max = 90 - ant_gain - 6; /* XXX magic number */ |
4668 | DPRINTF(1, "%s: region/domain max txpower %d dBm\n", |
4669 | sc->sc_dev.dv_xname, reg_txpower_max); |
4670 | |
4671 | /* |
4672 | * Force max TX power within region/domain TX power limit |
4673 | */ |
4674 | if (rf->rf_txpower_max > reg_txpower_max) |
4675 | rf->rf_txpower_max = reg_txpower_max; |
4676 | DPRINTF(1, "%s: max txpower %d dBm\n", |
4677 | sc->sc_dev.dv_xname, rf->rf_txpower_max); |
4678 | |
4679 | /* |
4680 | * Create TSSI to TX power mapping |
4681 | */ |
4682 | |
4683 | if (sc->sc_bbp_id == BWI_BBPID_BCM43010x4301 && |
4684 | rf->rf_type != BWI_RF_T_BCM20500x2050) { |
4685 | rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI52; |
4686 | bcopy(bwi_txpower_map_11b, rf->rf_txpower_map0, |
4687 | sizeof(rf->rf_txpower_map0)); |
4688 | goto back; |
4689 | } |
4690 | |
4691 | #define IS_VALID_PA_PARAM(p) ((p) != 0 && (p) != -1) |
4692 | /* |
4693 | * Extract PA parameters |
4694 | */ |
4695 | if (phy->phy_mode == IEEE80211_MODE_11A) |
4696 | sprom_ofs = BWI_SPROM_PA_PARAM_11A0x6a; |
4697 | else |
4698 | sprom_ofs = BWI_SPROM_PA_PARAM_11BG0x5e; |
4699 | for (i = 0; i < nitems(pa_params)(sizeof((pa_params)) / sizeof((pa_params)[0])); ++i) |
4700 | pa_params[i] = (int16_t)bwi_read_sprom(sc, sprom_ofs + (i * 2)); |
4701 | |
4702 | for (i = 0; i < nitems(pa_params)(sizeof((pa_params)) / sizeof((pa_params)[0])); ++i) { |
4703 | /* |
4704 | * If one of the PA parameters from SPROM is not valid, |
4705 | * fall back to the default values, if there are any. |
4706 | */ |
4707 | if (!IS_VALID_PA_PARAM(pa_params[i])) { |
4708 | const int8_t *txpower_map; |
4709 | |
4710 | if (phy->phy_mode == IEEE80211_MODE_11A) { |
4711 | printf("%s: no tssi2dbm table for 11a PHY\n", |
4712 | sc->sc_dev.dv_xname); |
4713 | return (ENXIO6); |
4714 | } |
4715 | |
4716 | if (phy->phy_mode == IEEE80211_MODE_11G) { |
4717 | DPRINTF(1, "%s: use default 11g TSSI map\n", |
4718 | sc->sc_dev.dv_xname); |
4719 | txpower_map = bwi_txpower_map_11g; |
4720 | } else { |
4721 | txpower_map = bwi_txpower_map_11b; |
4722 | } |
4723 | |
4724 | rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI52; |
4725 | bcopy(txpower_map, rf->rf_txpower_map0, |
4726 | sizeof(rf->rf_txpower_map0)); |
4727 | goto back; |
4728 | } |
4729 | } |
4730 | |
4731 | /* |
4732 | * All of the PA parameters from SPROM are valid. |
4733 | */ |
4734 | |
4735 | /* |
4736 | * Extract idle TSSI from SPROM. |
4737 | */ |
4738 | val = bwi_read_sprom(sc, BWI_SPROM_IDLE_TSSI0x70); |
4739 | DPRINTF(1, "%s: sprom idle tssi: 0x%04x\n", sc->sc_dev.dv_xname, val); |
4740 | |
4741 | if (phy->phy_mode == IEEE80211_MODE_11A) |
4742 | mask = BWI_SPROM_IDLE_TSSI_MASK_11A0xff00; |
4743 | else |
4744 | mask = BWI_SPROM_IDLE_TSSI_MASK_11BG0x00ff; |
4745 | |
4746 | rf->rf_idle_tssi0 = (int)__SHIFTOUT(val, mask)(((val) & (mask)) / ((((mask) - 1) & (mask)) ^ (mask) )); |
4747 | if (!IS_VALID_PA_PARAM(rf->rf_idle_tssi0)) |
4748 | rf->rf_idle_tssi0 = 62; |
4749 | |
4750 | #undef IS_VALID_PA_PARAM |
4751 | |
4752 | /* |
4753 | * Calculate TX power map, which is indexed by TSSI |
4754 | */ |
4755 | DPRINTF(1, "%s: TSSI-TX power map:\n", sc->sc_dev.dv_xname); |
4756 | for (i = 0; i < BWI_TSSI_MAX64; ++i) { |
4757 | error = bwi_rf_calc_txpower(&rf->rf_txpower_map0[i], i, |
4758 | pa_params); |
4759 | if (error) { |
4760 | printf("%s: bwi_rf_calc_txpower failed\n", |
4761 | sc->sc_dev.dv_xname); |
4762 | break; |
4763 | } |
4764 | if (i != 0 && i % 8 == 0) |
4765 | DPRINTF(1, "\n"); |
4766 | DPRINTF(1, "%d ", rf->rf_txpower_map0[i]); |
4767 | } |
4768 | DPRINTF(1, "\n"); |
4769 | back: |
4770 | DPRINTF(1, "%s: idle tssi0: %d\n", |
4771 | sc->sc_dev.dv_xname, rf->rf_idle_tssi0); |
4772 | |
4773 | return (error); |
4774 | } |
4775 | |
4776 | void |
4777 | bwi_rf_lo_update_11g(struct bwi_mac *mac) |
4778 | { |
4779 | struct bwi_softc *sc = mac->mac_sc; |
4780 | struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if; |
4781 | struct bwi_rf *rf = &mac->mac_rf; |
4782 | struct bwi_phy *phy = &mac->mac_phy; |
4783 | struct bwi_tpctl *tpctl = &mac->mac_tpctl; |
4784 | struct rf_saveregs regs; |
4785 | uint16_t ant_div, chan_ex; |
4786 | uint8_t devi_ctrl; |
4787 | uint orig_chan; |
4788 | |
4789 | DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__); |
4790 | |
4791 | /* |
4792 | * Save RF/PHY registers for later restoration |
4793 | */ |
4794 | orig_chan = rf->rf_curchan; |
4795 | bzero(®s, sizeof(regs))__builtin_bzero((®s), (sizeof(regs))); |
4796 | |
4797 | if (phy->phy_flags & BWI_PHY_F_LINKED0x2) { |
4798 | SAVE_PHY_REG(mac, ®s, 429)(®s)->phy_429 = bwi_phy_read(((mac)), (0x429)); |
4799 | SAVE_PHY_REG(mac, ®s, 802)(®s)->phy_802 = bwi_phy_read(((mac)), (0x802)); |
4800 | |
4801 | PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff)bwi_phy_write((mac), (0x429), (regs.phy_429 & 0x7fff)); |
4802 | PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc)bwi_phy_write((mac), (0x802), (regs.phy_802 & 0xfffc)); |
4803 | } |
4804 | |
4805 | ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03e2 )))); |
4806 | CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div | 0x8000)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e2 )), ((ant_div | 0x8000)))); |
4807 | chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03f4 )))); |
4808 | |
4809 | SAVE_PHY_REG(mac, ®s, 15)(®s)->phy_15 = bwi_phy_read(((mac)), (0x15)); |
4810 | SAVE_PHY_REG(mac, ®s, 2a)(®s)->phy_2a = bwi_phy_read(((mac)), (0x2a)); |
4811 | SAVE_PHY_REG(mac, ®s, 35)(®s)->phy_35 = bwi_phy_read(((mac)), (0x35)); |
4812 | SAVE_PHY_REG(mac, ®s, 60)(®s)->phy_60 = bwi_phy_read(((mac)), (0x60)); |
4813 | SAVE_RF_REG(mac, ®s, 43)(®s)->rf_43 = bwi_rf_read(((mac)), (0x43)); |
4814 | SAVE_RF_REG(mac, ®s, 7a)(®s)->rf_7a = bwi_rf_read(((mac)), (0x7a)); |
4815 | SAVE_RF_REG(mac, ®s, 52)(®s)->rf_52 = bwi_rf_read(((mac)), (0x52)); |
4816 | if (phy->phy_flags & BWI_PHY_F_LINKED0x2) { |
4817 | SAVE_PHY_REG(mac, ®s, 811)(®s)->phy_811 = bwi_phy_read(((mac)), (0x811)); |
4818 | SAVE_PHY_REG(mac, ®s, 812)(®s)->phy_812 = bwi_phy_read(((mac)), (0x812)); |
4819 | SAVE_PHY_REG(mac, ®s, 814)(®s)->phy_814 = bwi_phy_read(((mac)), (0x814)); |
4820 | SAVE_PHY_REG(mac, ®s, 815)(®s)->phy_815 = bwi_phy_read(((mac)), (0x815)); |
4821 | } |
4822 | |
4823 | /* Force to channel 6 */ |
4824 | bwi_rf_set_chan(mac, 6, 0); |
4825 | |
4826 | if (phy->phy_flags & BWI_PHY_F_LINKED0x2) { |
4827 | PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff)bwi_phy_write((mac), (0x429), (regs.phy_429 & 0x7fff)); |
4828 | PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc)bwi_phy_write((mac), (0x802), (regs.phy_802 & 0xfffc)); |
4829 | bwi_mac_dummy_xmit(mac); |
4830 | } |
4831 | RF_WRITE(mac, 0x43, 0x6)bwi_rf_write((mac), (0x43), (0x6)); |
4832 | |
4833 | bwi_phy_set_bbp_atten(mac, 2); |
4834 | |
4835 | CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f4 )), ((0)))); |
4836 | |
4837 | PHY_WRITE(mac, 0x2e, 0x7f)bwi_phy_write((mac), (0x2e), (0x7f)); |
4838 | PHY_WRITE(mac, 0x80f, 0x78)bwi_phy_write((mac), (0x80f), (0x78)); |
4839 | PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f)bwi_phy_write((mac), (0x35), (regs.phy_35 & 0xff7f)); |
4840 | RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0)bwi_rf_write((mac), (0x7a), (regs.rf_7a & 0xfff0)); |
4841 | PHY_WRITE(mac, 0x2b, 0x203)bwi_phy_write((mac), (0x2b), (0x203)); |
4842 | PHY_WRITE(mac, 0x2a, 0x8a3)bwi_phy_write((mac), (0x2a), (0x8a3)); |
4843 | |
4844 | if (phy->phy_flags & BWI_PHY_F_LINKED0x2) { |
4845 | PHY_WRITE(mac, 0x814, regs.phy_814 | 0x3)bwi_phy_write((mac), (0x814), (regs.phy_814 | 0x3)); |
4846 | PHY_WRITE(mac, 0x815, regs.phy_815 & 0xfffc)bwi_phy_write((mac), (0x815), (regs.phy_815 & 0xfffc)); |
4847 | PHY_WRITE(mac, 0x811, 0x1b3)bwi_phy_write((mac), (0x811), (0x1b3)); |
4848 | PHY_WRITE(mac, 0x812, 0xb2)bwi_phy_write((mac), (0x812), (0xb2)); |
4849 | } |
4850 | |
4851 | if ((ifp->if_flags & IFF_RUNNING0x40) == 0) |
4852 | tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac); |
4853 | PHY_WRITE(mac, 0x80f, 0x8078)bwi_phy_write((mac), (0x80f), (0x8078)); |
4854 | |
4855 | /* |
4856 | * Measure all RF LO |
4857 | */ |
4858 | devi_ctrl = _bwi_rf_lo_update_11g(mac, regs.rf_7a); |
4859 | |
4860 | /* |
4861 | * Restore saved RF/PHY registers |
4862 | */ |
4863 | if (phy->phy_flags & BWI_PHY_F_LINKED0x2) { |
4864 | PHY_WRITE(mac, 0x15, 0xe300)bwi_phy_write((mac), (0x15), (0xe300)); |
4865 | PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa0)bwi_phy_write((mac), (0x812), ((devi_ctrl << 8) | 0xa0) ); |
4866 | DELAY(5)(*delay_func)(5); |
4867 | PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa2)bwi_phy_write((mac), (0x812), ((devi_ctrl << 8) | 0xa2) ); |
4868 | DELAY(2)(*delay_func)(2); |
4869 | PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa3)bwi_phy_write((mac), (0x812), ((devi_ctrl << 8) | 0xa3) ); |
4870 | } else |
4871 | PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0)bwi_phy_write((mac), (0x15), (devi_ctrl | 0xefa0)); |
4872 | |
4873 | if ((ifp->if_flags & IFF_RUNNING0x40) == 0) |
4874 | tpctl = NULL((void *)0); |
4875 | bwi_rf_lo_adjust(mac, tpctl); |
4876 | |
4877 | PHY_WRITE(mac, 0x2e, 0x807f)bwi_phy_write((mac), (0x2e), (0x807f)); |
4878 | if (phy->phy_flags & BWI_PHY_F_LINKED0x2) |
4879 | PHY_WRITE(mac, 0x2f, 0x202)bwi_phy_write((mac), (0x2f), (0x202)); |
4880 | else |
4881 | PHY_WRITE(mac, 0x2f, 0x101)bwi_phy_write((mac), (0x2f), (0x101)); |
4882 | |
4883 | CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f4 )), ((chan_ex)))); |
4884 | |
4885 | RESTORE_PHY_REG(mac, ®s, 15)bwi_phy_write(((mac)), (0x15), ((®s)->phy_15)); |
4886 | RESTORE_PHY_REG(mac, ®s, 2a)bwi_phy_write(((mac)), (0x2a), ((®s)->phy_2a)); |
4887 | RESTORE_PHY_REG(mac, ®s, 35)bwi_phy_write(((mac)), (0x35), ((®s)->phy_35)); |
4888 | RESTORE_PHY_REG(mac, ®s, 60)bwi_phy_write(((mac)), (0x60), ((®s)->phy_60)); |
4889 | |
4890 | RESTORE_RF_REG(mac, ®s, 43)bwi_rf_write(((mac)), (0x43), ((®s)->rf_43)); |
4891 | RESTORE_RF_REG(mac, ®s, 7a)bwi_rf_write(((mac)), (0x7a), ((®s)->rf_7a)); |
4892 | |
4893 | regs.rf_52 &= 0xf0; |
4894 | regs.rf_52 |= (RF_READ(mac, 0x52)bwi_rf_read((mac), (0x52)) & 0xf); |
4895 | RF_WRITE(mac, 0x52, regs.rf_52)bwi_rf_write((mac), (0x52), (regs.rf_52)); |
4896 | |
4897 | CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e2 )), ((ant_div)))); |
4898 | |
4899 | if (phy->phy_flags & BWI_PHY_F_LINKED0x2) { |
4900 | RESTORE_PHY_REG(mac, ®s, 811)bwi_phy_write(((mac)), (0x811), ((®s)->phy_811)); |
4901 | RESTORE_PHY_REG(mac, ®s, 812)bwi_phy_write(((mac)), (0x812), ((®s)->phy_812)); |
4902 | RESTORE_PHY_REG(mac, ®s, 814)bwi_phy_write(((mac)), (0x814), ((®s)->phy_814)); |
4903 | RESTORE_PHY_REG(mac, ®s, 815)bwi_phy_write(((mac)), (0x815), ((®s)->phy_815)); |
4904 | RESTORE_PHY_REG(mac, ®s, 429)bwi_phy_write(((mac)), (0x429), ((®s)->phy_429)); |
4905 | RESTORE_PHY_REG(mac, ®s, 802)bwi_phy_write(((mac)), (0x802), ((®s)->phy_802)); |
4906 | } |
4907 | |
4908 | bwi_rf_set_chan(mac, orig_chan, 1); |
4909 | } |
4910 | |
4911 | uint32_t |
4912 | bwi_rf_lo_devi_measure(struct bwi_mac *mac, uint16_t ctrl) |
4913 | { |
4914 | struct bwi_phy *phy = &mac->mac_phy; |
4915 | uint32_t devi = 0; |
4916 | int i; |
4917 | |
4918 | if (phy->phy_flags & BWI_PHY_F_LINKED0x2) |
4919 | ctrl <<= 8; |
4920 | |
4921 | for (i = 0; i < 8; ++i) { |
4922 | if (phy->phy_flags & BWI_PHY_F_LINKED0x2) { |
4923 | PHY_WRITE(mac, 0x15, 0xe300)bwi_phy_write((mac), (0x15), (0xe300)); |
4924 | PHY_WRITE(mac, 0x812, ctrl | 0xb0)bwi_phy_write((mac), (0x812), (ctrl | 0xb0)); |
4925 | DELAY(5)(*delay_func)(5); |
4926 | PHY_WRITE(mac, 0x812, ctrl | 0xb2)bwi_phy_write((mac), (0x812), (ctrl | 0xb2)); |
4927 | DELAY(2)(*delay_func)(2); |
4928 | PHY_WRITE(mac, 0x812, ctrl | 0xb3)bwi_phy_write((mac), (0x812), (ctrl | 0xb3)); |
4929 | DELAY(4)(*delay_func)(4); |
4930 | PHY_WRITE(mac, 0x15, 0xf300)bwi_phy_write((mac), (0x15), (0xf300)); |
4931 | } else { |
4932 | PHY_WRITE(mac, 0x15, ctrl | 0xefa0)bwi_phy_write((mac), (0x15), (ctrl | 0xefa0)); |
4933 | DELAY(2)(*delay_func)(2); |
4934 | PHY_WRITE(mac, 0x15, ctrl | 0xefe0)bwi_phy_write((mac), (0x15), (ctrl | 0xefe0)); |
4935 | DELAY(4)(*delay_func)(4); |
4936 | PHY_WRITE(mac, 0x15, ctrl | 0xffe0)bwi_phy_write((mac), (0x15), (ctrl | 0xffe0)); |
4937 | } |
4938 | DELAY(8)(*delay_func)(8); |
4939 | devi += PHY_READ(mac, 0x2d)bwi_phy_read((mac), (0x2d)); |
4940 | } |
4941 | |
4942 | return (devi); |
4943 | } |
4944 | |
4945 | uint16_t |
4946 | bwi_rf_get_tp_ctrl2(struct bwi_mac *mac) |
4947 | { |
4948 | uint32_t devi_min; |
4949 | uint16_t tp_ctrl2 = 0; |
4950 | int i; |
4951 | |
4952 | RF_WRITE(mac, 0x52, 0)bwi_rf_write((mac), (0x52), (0)); |
4953 | DELAY(10)(*delay_func)(10); |
4954 | devi_min = bwi_rf_lo_devi_measure(mac, 0); |
4955 | |
4956 | for (i = 0; i < 16; ++i) { |
4957 | uint32_t devi; |
4958 | |
4959 | RF_WRITE(mac, 0x52, i)bwi_rf_write((mac), (0x52), (i)); |
4960 | DELAY(10)(*delay_func)(10); |
4961 | devi = bwi_rf_lo_devi_measure(mac, 0); |
4962 | |
4963 | if (devi < devi_min) { |
4964 | devi_min = devi; |
4965 | tp_ctrl2 = i; |
4966 | } |
4967 | } |
4968 | |
4969 | return (tp_ctrl2); |
4970 | } |
4971 | |
4972 | uint8_t |
4973 | _bwi_rf_lo_update_11g(struct bwi_mac *mac, uint16_t orig_rf7a) |
4974 | { |
4975 | #define RF_ATTEN_LISTSZ 14 |
4976 | #define BBP_ATTEN_MAX 4 /* half */ |
4977 | struct ifnet *ifp = &mac->mac_sc->sc_ic.ic_ific_ac.ac_if; |
4978 | struct bwi_rf_lo lo_save, *lo; |
4979 | uint8_t devi_ctrl = 0; |
4980 | int idx, adj_rf7a = 0; |
4981 | |
4982 | static const int rf_atten_list[RF_ATTEN_LISTSZ] = |
4983 | { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 1, 2, 3, 4 }; |
4984 | static const int rf_atten_init_list[RF_ATTEN_LISTSZ] = |
4985 | { 0, 3, 1, 5, 7, 3, 2, 0, 4, 6, -1, -1, -1, -1 }; |
4986 | static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] = |
4987 | { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 }; |
4988 | |
4989 | bzero(&lo_save, sizeof(lo_save))__builtin_bzero((&lo_save), (sizeof(lo_save))); |
4990 | for (idx = 0; idx < RF_ATTEN_LISTSZ; ++idx) { |
4991 | int init_rf_atten = rf_atten_init_list[idx]; |
4992 | int rf_atten = rf_atten_list[idx]; |
4993 | int bbp_atten; |
4994 | |
4995 | for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) { |
4996 | uint16_t tp_ctrl2, rf7a; |
4997 | |
4998 | if ((ifp->if_flags & IFF_RUNNING0x40) == 0) { |
4999 | if (idx == 0) { |
5000 | bzero(&lo_save, sizeof(lo_save))__builtin_bzero((&lo_save), (sizeof(lo_save))); |
5001 | } else if (init_rf_atten < 0) { |
5002 | lo = bwi_get_rf_lo(mac, |
5003 | rf_atten, 2 * bbp_atten); |
5004 | bcopy(lo, &lo_save, sizeof(lo_save)); |
5005 | } else { |
5006 | lo = bwi_get_rf_lo(mac, |
5007 | init_rf_atten, 0); |
5008 | bcopy(lo, &lo_save, sizeof(lo_save)); |
5009 | } |
5010 | |
5011 | devi_ctrl = 0; |
5012 | adj_rf7a = 0; |
5013 | |
5014 | /* |
5015 | * XXX |
5016 | * Linux driver overflows 'val' |
5017 | */ |
5018 | if (init_rf_atten >= 0) { |
5019 | int val; |
5020 | |
5021 | val = rf_atten * 2 + bbp_atten; |
5022 | if (val > 14) { |
5023 | adj_rf7a = 1; |
5024 | if (val > 17) |
5025 | devi_ctrl = 1; |
5026 | if (val > 19) |
5027 | devi_ctrl = 2; |
5028 | } |
5029 | } |
5030 | } else { |
5031 | lo = bwi_get_rf_lo(mac, |
5032 | rf_atten, 2 * bbp_atten); |
5033 | if (!bwi_rf_lo_isused(mac, lo)) |
5034 | continue; |
5035 | bcopy(lo, &lo_save, sizeof(lo_save)); |
5036 | |
5037 | devi_ctrl = 3; |
5038 | adj_rf7a = 0; |
5039 | } |
5040 | |
5041 | RF_WRITE(mac, BWI_RFR_ATTEN, rf_atten)bwi_rf_write((mac), (0x43), (rf_atten)); |
5042 | |
5043 | tp_ctrl2 = mac->mac_tpctl.tp_ctrl2; |
5044 | if (init_rf_atten < 0) |
5045 | tp_ctrl2 |= (3 << 4); |
5046 | RF_WRITE(mac, BWI_RFR_TXPWR, tp_ctrl2)bwi_rf_write((mac), (0x52), (tp_ctrl2)); |
5047 | |
5048 | DELAY(10)(*delay_func)(10); |
5049 | |
5050 | bwi_phy_set_bbp_atten(mac, bbp_atten * 2); |
5051 | |
5052 | rf7a = orig_rf7a & 0xfff0; |
5053 | if (adj_rf7a) |
5054 | rf7a |= 0x8; |
5055 | RF_WRITE(mac, 0x7a, rf7a)bwi_rf_write((mac), (0x7a), (rf7a)); |
5056 | |
5057 | lo = bwi_get_rf_lo(mac, |
5058 | rf_lo_measure_order[idx], bbp_atten * 2); |
5059 | bwi_rf_lo_measure_11g(mac, &lo_save, lo, devi_ctrl); |
5060 | } |
5061 | } |
5062 | |
5063 | return (devi_ctrl); |
5064 | |
5065 | #undef RF_ATTEN_LISTSZ |
5066 | #undef BBP_ATTEN_MAX |
5067 | } |
5068 | |
5069 | void |
5070 | bwi_rf_lo_measure_11g(struct bwi_mac *mac, const struct bwi_rf_lo *src_lo, |
5071 | struct bwi_rf_lo *dst_lo, uint8_t devi_ctrl) |
5072 | { |
5073 | #define LO_ADJUST_MIN 1 |
5074 | #define LO_ADJUST_MAX 8 |
5075 | #define LO_ADJUST(hi, lo) { .ctrl_hi = hi, .ctrl_lo = lo } |
5076 | static const struct bwi_rf_lo rf_lo_adjust[LO_ADJUST_MAX] = { |
5077 | LO_ADJUST(1, 1), |
5078 | LO_ADJUST(1, 0), |
5079 | LO_ADJUST(1, -1), |
5080 | LO_ADJUST(0, -1), |
5081 | LO_ADJUST(-1, -1), |
5082 | LO_ADJUST(-1, 0), |
5083 | LO_ADJUST(-1, 1), |
5084 | LO_ADJUST(0, 1) |
5085 | }; |
5086 | #undef LO_ADJUST |
5087 | |
5088 | struct bwi_rf_lo lo_min; |
5089 | uint32_t devi_min; |
5090 | int found, loop_count, adjust_state; |
5091 | |
5092 | bcopy(src_lo, &lo_min, sizeof(lo_min)); |
5093 | RF_LO_WRITE(mac, &lo_min)bwi_rf_lo_write((mac), (&lo_min)); |
5094 | devi_min = bwi_rf_lo_devi_measure(mac, devi_ctrl); |
5095 | |
5096 | loop_count = 12; /* XXX */ |
5097 | adjust_state = 0; |
5098 | do { |
5099 | struct bwi_rf_lo lo_base; |
5100 | int i, fin; |
5101 | |
5102 | found = 0; |
5103 | if (adjust_state == 0) { |
5104 | i = LO_ADJUST_MIN; |
5105 | fin = LO_ADJUST_MAX; |
5106 | } else if (adjust_state % 2 == 0) { |
5107 | i = adjust_state - 1; |
5108 | fin = adjust_state + 1; |
5109 | } else { |
5110 | i = adjust_state - 2; |
5111 | fin = adjust_state + 2; |
5112 | } |
5113 | |
5114 | if (i < LO_ADJUST_MIN) |
5115 | i += LO_ADJUST_MAX; |
5116 | KASSERT(i <= LO_ADJUST_MAX && i >= LO_ADJUST_MIN)((i <= LO_ADJUST_MAX && i >= LO_ADJUST_MIN) ? ( void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c", 5116, "i <= LO_ADJUST_MAX && i >= LO_ADJUST_MIN" )); |
5117 | |
5118 | if (fin > LO_ADJUST_MAX) |
5119 | fin -= LO_ADJUST_MAX; |
5120 | KASSERT(fin <= LO_ADJUST_MAX && fin >= LO_ADJUST_MIN)((fin <= LO_ADJUST_MAX && fin >= LO_ADJUST_MIN) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c" , 5120, "fin <= LO_ADJUST_MAX && fin >= LO_ADJUST_MIN" )); |
5121 | |
5122 | bcopy(&lo_min, &lo_base, sizeof(lo_base)); |
5123 | for (;;) { |
5124 | struct bwi_rf_lo lo; |
5125 | |
5126 | lo.ctrl_hi = lo_base.ctrl_hi + |
5127 | rf_lo_adjust[i - 1].ctrl_hi; |
5128 | lo.ctrl_lo = lo_base.ctrl_lo + |
5129 | rf_lo_adjust[i - 1].ctrl_lo; |
5130 | |
5131 | if (abs(lo.ctrl_lo) < 9 && abs(lo.ctrl_hi) < 9) { |
5132 | uint32_t devi; |
5133 | |
5134 | RF_LO_WRITE(mac, &lo)bwi_rf_lo_write((mac), (&lo)); |
5135 | devi = bwi_rf_lo_devi_measure(mac, devi_ctrl); |
5136 | if (devi < devi_min) { |
5137 | devi_min = devi; |
5138 | adjust_state = i; |
5139 | found = 1; |
5140 | bcopy(&lo, &lo_min, sizeof(lo_min)); |
5141 | } |
5142 | } |
5143 | if (i == fin) |
5144 | break; |
5145 | if (i == LO_ADJUST_MAX) |
5146 | i = LO_ADJUST_MIN; |
5147 | else |
5148 | ++i; |
5149 | } |
5150 | } while (loop_count-- && found); |
5151 | |
5152 | bcopy(&lo_min, dst_lo, sizeof(*dst_lo)); |
5153 | |
5154 | #undef LO_ADJUST_MIN |
5155 | #undef LO_ADJUST_MAX |
5156 | } |
5157 | |
5158 | void |
5159 | bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *mac) |
5160 | { |
5161 | #define SAVE_RF_MAX 3 |
5162 | #define SAVE_PHY_MAX 8 |
5163 | struct bwi_softc *sc = mac->mac_sc; |
5164 | struct bwi_rf *rf = &mac->mac_rf; |
5165 | struct bwi_phy *phy = &mac->mac_phy; |
5166 | uint16_t save_rf[SAVE_RF_MAX]; |
5167 | uint16_t save_phy[SAVE_PHY_MAX]; |
5168 | uint16_t ant_div, bbp_atten, chan_ex; |
5169 | int16_t nrssi[2]; |
5170 | int i; |
5171 | |
5172 | static const uint16_t save_rf_regs[SAVE_RF_MAX] = |
5173 | { 0x7a, 0x52, 0x43 }; |
5174 | static const uint16_t save_phy_regs[SAVE_PHY_MAX] = |
5175 | { 0x30, 0x26, 0x15, 0x2a, 0x20, 0x5a, 0x59, 0x58 }; |
5176 | |
5177 | /* |
5178 | * Save RF/PHY registers for later restoration |
5179 | */ |
5180 | for (i = 0; i < SAVE_RF_MAX; ++i) |
5181 | save_rf[i] = RF_READ(mac, save_rf_regs[i])bwi_rf_read((mac), (save_rf_regs[i])); |
5182 | for (i = 0; i < SAVE_PHY_MAX; ++i) |
5183 | save_phy[i] = PHY_READ(mac, save_phy_regs[i])bwi_phy_read((mac), (save_phy_regs[i])); |
5184 | |
5185 | ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03e2 )))); |
5186 | bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03e6 )))); |
5187 | chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03f4 )))); |
5188 | |
5189 | /* |
5190 | * Calculate nrssi0 |
5191 | */ |
5192 | if (phy->phy_rev >= 5) |
5193 | RF_CLRBITS(mac, 0x7a, 0xff80)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) & ~(0xff80))); |
5194 | else |
5195 | RF_CLRBITS(mac, 0x7a, 0xfff0)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) & ~(0xfff0))); |
5196 | PHY_WRITE(mac, 0x30, 0xff)bwi_phy_write((mac), (0x30), (0xff)); |
5197 | |
5198 | CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x7f7f)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03ec )), ((0x7f7f)))); |
5199 | |
5200 | PHY_WRITE(mac, 0x26, 0)bwi_phy_write((mac), (0x26), (0)); |
5201 | PHY_SETBITS(mac, 0x15, 0x20)bwi_phy_write(((mac)), ((0x15)), (bwi_phy_read(((mac)), ((0x15 ))) | (0x20))); |
5202 | PHY_WRITE(mac, 0x2a, 0x8a3)bwi_phy_write((mac), (0x2a), (0x8a3)); |
5203 | RF_SETBITS(mac, 0x7a, 0x80)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0x80))); |
5204 | |
5205 | nrssi[0] = (int16_t)PHY_READ(mac, 0x27)bwi_phy_read((mac), (0x27)); |
5206 | |
5207 | /* |
5208 | * Calculate nrssi1 |
5209 | */ |
5210 | RF_CLRBITS(mac, 0x7a, 0xff80)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) & ~(0xff80))); |
5211 | if (phy->phy_version >= 2) |
5212 | CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x40)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e6 )), ((0x40)))); |
5213 | else if (phy->phy_version == 0) |
5214 | CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e6 )), ((0x122)))); |
5215 | else |
5216 | CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0xdfff)((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), ( ((0x03f4))), ((((((sc))->sc_mem_bt)->read_2((((sc))-> sc_mem_bh), (((0x03f4))))) & ~(0xdfff))))); |
5217 | |
5218 | PHY_WRITE(mac, 0x20, 0x3f3f)bwi_phy_write((mac), (0x20), (0x3f3f)); |
5219 | PHY_WRITE(mac, 0x15, 0xf330)bwi_phy_write((mac), (0x15), (0xf330)); |
5220 | |
5221 | RF_WRITE(mac, 0x5a, 0x60)bwi_rf_write((mac), (0x5a), (0x60)); |
5222 | RF_CLRBITS(mac, 0x43, 0xff0f)bwi_rf_write(((mac)), ((0x43)), (bwi_rf_read(((mac)), ((0x43) )) & ~(0xff0f))); |
5223 | |
5224 | PHY_WRITE(mac, 0x5a, 0x480)bwi_phy_write((mac), (0x5a), (0x480)); |
5225 | PHY_WRITE(mac, 0x59, 0x810)bwi_phy_write((mac), (0x59), (0x810)); |
5226 | PHY_WRITE(mac, 0x58, 0xd)bwi_phy_write((mac), (0x58), (0xd)); |
5227 | |
5228 | DELAY(20)(*delay_func)(20); |
5229 | |
5230 | nrssi[1] = (int16_t)PHY_READ(mac, 0x27)bwi_phy_read((mac), (0x27)); |
5231 | |
5232 | /* |
5233 | * Restore saved RF/PHY registers |
5234 | */ |
5235 | PHY_WRITE(mac, save_phy_regs[0], save_phy[0])bwi_phy_write((mac), (save_phy_regs[0]), (save_phy[0])); |
5236 | RF_WRITE(mac, save_rf_regs[0], save_rf[0])bwi_rf_write((mac), (save_rf_regs[0]), (save_rf[0])); |
5237 | |
5238 | CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e2 )), ((ant_div)))); |
5239 | |
5240 | for (i = 1; i < 4; ++i) |
5241 | PHY_WRITE(mac, save_phy_regs[i], save_phy[i])bwi_phy_write((mac), (save_phy_regs[i]), (save_phy[i])); |
5242 | |
5243 | bwi_rf_workaround(mac, rf->rf_curchan); |
5244 | |
5245 | if (phy->phy_version != 0) |
5246 | CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f4 )), ((chan_ex)))); |
5247 | |
5248 | for (; i < SAVE_PHY_MAX; ++i) |
5249 | PHY_WRITE(mac, save_phy_regs[i], save_phy[i])bwi_phy_write((mac), (save_phy_regs[i]), (save_phy[i])); |
5250 | |
5251 | for (i = 1; i < SAVE_RF_MAX; ++i) |
5252 | RF_WRITE(mac, save_rf_regs[i], save_rf[i])bwi_rf_write((mac), (save_rf_regs[i]), (save_rf[i])); |
5253 | |
5254 | /* |
5255 | * Install calculated narrow RSSI values |
5256 | */ |
5257 | if (nrssi[0] == nrssi[1]) |
5258 | rf->rf_nrssi_slope = 0x10000; |
5259 | else |
5260 | rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]); |
5261 | if (nrssi[0] <= -4) { |
5262 | rf->rf_nrssi[0] = nrssi[0]; |
5263 | rf->rf_nrssi[1] = nrssi[1]; |
5264 | } |
5265 | |
5266 | #undef SAVE_RF_MAX |
5267 | #undef SAVE_PHY_MAX |
5268 | } |
5269 | |
5270 | void |
5271 | bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *mac) |
5272 | { |
5273 | #define SAVE_RF_MAX 2 |
5274 | #define SAVE_PHY_COMM_MAX 10 |
5275 | #define SAVE_PHY6_MAX 8 |
5276 | struct bwi_phy *phy = &mac->mac_phy; |
5277 | uint16_t save_rf[SAVE_RF_MAX]; |
5278 | uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; |
5279 | uint16_t save_phy6[SAVE_PHY6_MAX]; |
5280 | uint16_t rf7b = 0xffff; |
5281 | int16_t nrssi; |
5282 | int i, phy6_idx = 0; |
5283 | |
5284 | static const uint16_t save_rf_regs[SAVE_RF_MAX] = { 0x7a, 0x43 }; |
5285 | static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = { |
5286 | 0x0001, 0x0811, 0x0812, 0x0814, |
5287 | 0x0815, 0x005a, 0x0059, 0x0058, |
5288 | 0x000a, 0x0003 |
5289 | }; |
5290 | static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = { |
5291 | 0x002e, 0x002f, 0x080f, 0x0810, |
5292 | 0x0801, 0x0060, 0x0014, 0x0478 |
5293 | }; |
5294 | |
5295 | for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) |
5296 | save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i])bwi_phy_read((mac), (save_phy_comm_regs[i])); |
5297 | for (i = 0; i < SAVE_RF_MAX; ++i) |
5298 | save_rf[i] = RF_READ(mac, save_rf_regs[i])bwi_rf_read((mac), (save_rf_regs[i])); |
5299 | |
5300 | PHY_CLRBITS(mac, 0x429, 0x8000)bwi_phy_write(((mac)), ((0x429)), (bwi_phy_read(((mac)), ((0x429 ))) & ~(0x8000))); |
5301 | PHY_FILT_SETBITS(mac, 0x1, 0x3fff, 0x4000)bwi_phy_write(((mac)), ((0x1)), ((bwi_phy_read(((mac)), ((0x1 ))) & (0x3fff)) | (0x4000))); |
5302 | PHY_SETBITS(mac, 0x811, 0xc)bwi_phy_write(((mac)), ((0x811)), (bwi_phy_read(((mac)), ((0x811 ))) | (0xc))); |
5303 | PHY_FILT_SETBITS(mac, 0x812, 0xfff3, 0x4)bwi_phy_write(((mac)), ((0x812)), ((bwi_phy_read(((mac)), ((0x812 ))) & (0xfff3)) | (0x4))); |
5304 | PHY_CLRBITS(mac, 0x802, 0x3)bwi_phy_write(((mac)), ((0x802)), (bwi_phy_read(((mac)), ((0x802 ))) & ~(0x3))); |
5305 | |
5306 | if (phy->phy_rev >= 6) { |
5307 | for (i = 0; i < SAVE_PHY6_MAX; ++i) |
5308 | save_phy6[i] = PHY_READ(mac, save_phy6_regs[i])bwi_phy_read((mac), (save_phy6_regs[i])); |
5309 | |
5310 | PHY_WRITE(mac, 0x2e, 0)bwi_phy_write((mac), (0x2e), (0)); |
5311 | PHY_WRITE(mac, 0x2f, 0)bwi_phy_write((mac), (0x2f), (0)); |
5312 | PHY_WRITE(mac, 0x80f, 0)bwi_phy_write((mac), (0x80f), (0)); |
5313 | PHY_WRITE(mac, 0x810, 0)bwi_phy_write((mac), (0x810), (0)); |
5314 | PHY_SETBITS(mac, 0x478, 0x100)bwi_phy_write(((mac)), ((0x478)), (bwi_phy_read(((mac)), ((0x478 ))) | (0x100))); |
5315 | PHY_SETBITS(mac, 0x801, 0x40)bwi_phy_write(((mac)), ((0x801)), (bwi_phy_read(((mac)), ((0x801 ))) | (0x40))); |
5316 | PHY_SETBITS(mac, 0x60, 0x40)bwi_phy_write(((mac)), ((0x60)), (bwi_phy_read(((mac)), ((0x60 ))) | (0x40))); |
5317 | PHY_SETBITS(mac, 0x14, 0x200)bwi_phy_write(((mac)), ((0x14)), (bwi_phy_read(((mac)), ((0x14 ))) | (0x200))); |
5318 | } |
5319 | |
5320 | RF_SETBITS(mac, 0x7a, 0x70)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0x70))); |
5321 | RF_SETBITS(mac, 0x7a, 0x80)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0x80))); |
5322 | |
5323 | DELAY(30)(*delay_func)(30); |
5324 | |
5325 | nrssi = bwi_nrssi_11g(mac); |
5326 | if (nrssi == 31) { |
5327 | for (i = 7; i >= 4; --i) { |
5328 | RF_WRITE(mac, 0x7b, i)bwi_rf_write((mac), (0x7b), (i)); |
5329 | DELAY(20)(*delay_func)(20); |
5330 | nrssi = bwi_nrssi_11g(mac); |
5331 | if (nrssi < 31 && rf7b == 0xffff) |
5332 | rf7b = i; |
5333 | } |
5334 | if (rf7b == 0xffff) |
5335 | rf7b = 4; |
5336 | } else { |
5337 | struct bwi_gains gains; |
5338 | |
5339 | RF_CLRBITS(mac, 0x7a, 0xff80)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) & ~(0xff80))); |
5340 | |
5341 | PHY_SETBITS(mac, 0x814, 0x1)bwi_phy_write(((mac)), ((0x814)), (bwi_phy_read(((mac)), ((0x814 ))) | (0x1))); |
5342 | PHY_CLRBITS(mac, 0x815, 0x1)bwi_phy_write(((mac)), ((0x815)), (bwi_phy_read(((mac)), ((0x815 ))) & ~(0x1))); |
5343 | PHY_SETBITS(mac, 0x811, 0xc)bwi_phy_write(((mac)), ((0x811)), (bwi_phy_read(((mac)), ((0x811 ))) | (0xc))); |
5344 | PHY_SETBITS(mac, 0x812, 0xc)bwi_phy_write(((mac)), ((0x812)), (bwi_phy_read(((mac)), ((0x812 ))) | (0xc))); |
5345 | PHY_SETBITS(mac, 0x811, 0x30)bwi_phy_write(((mac)), ((0x811)), (bwi_phy_read(((mac)), ((0x811 ))) | (0x30))); |
5346 | PHY_SETBITS(mac, 0x812, 0x30)bwi_phy_write(((mac)), ((0x812)), (bwi_phy_read(((mac)), ((0x812 ))) | (0x30))); |
5347 | PHY_WRITE(mac, 0x5a, 0x480)bwi_phy_write((mac), (0x5a), (0x480)); |
5348 | PHY_WRITE(mac, 0x59, 0x810)bwi_phy_write((mac), (0x59), (0x810)); |
5349 | PHY_WRITE(mac, 0x58, 0xd)bwi_phy_write((mac), (0x58), (0xd)); |
5350 | if (phy->phy_version == 0) |
5351 | PHY_WRITE(mac, 0x3, 0x122)bwi_phy_write((mac), (0x3), (0x122)); |
5352 | else |
5353 | PHY_SETBITS(mac, 0xa, 0x2000)bwi_phy_write(((mac)), ((0xa)), (bwi_phy_read(((mac)), ((0xa) )) | (0x2000))); |
5354 | PHY_SETBITS(mac, 0x814, 0x4)bwi_phy_write(((mac)), ((0x814)), (bwi_phy_read(((mac)), ((0x814 ))) | (0x4))); |
5355 | PHY_CLRBITS(mac, 0x815, 0x4)bwi_phy_write(((mac)), ((0x815)), (bwi_phy_read(((mac)), ((0x815 ))) & ~(0x4))); |
5356 | PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40)bwi_phy_write(((mac)), ((0x3)), ((bwi_phy_read(((mac)), ((0x3 ))) & (0xff9f)) | (0x40))); |
5357 | RF_SETBITS(mac, 0x7a, 0xf)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0xf))); |
5358 | |
5359 | bzero(&gains, sizeof(gains))__builtin_bzero((&gains), (sizeof(gains))); |
5360 | gains.tbl_gain1 = 3; |
5361 | gains.tbl_gain2 = 0; |
5362 | gains.phy_gain = 1; |
5363 | bwi_set_gains(mac, &gains); |
5364 | |
5365 | RF_FILT_SETBITS(mac, 0x43, 0xf0, 0xf)bwi_rf_write(((mac)), ((0x43)), ((bwi_rf_read(((mac)), ((0x43 ))) & (0xf0)) | (0xf))); |
5366 | DELAY(30)(*delay_func)(30); |
5367 | |
5368 | nrssi = bwi_nrssi_11g(mac); |
5369 | if (nrssi == -32) { |
5370 | for (i = 0; i < 4; ++i) { |
5371 | RF_WRITE(mac, 0x7b, i)bwi_rf_write((mac), (0x7b), (i)); |
5372 | DELAY(20)(*delay_func)(20); |
5373 | nrssi = bwi_nrssi_11g(mac); |
5374 | if (nrssi > -31 && rf7b == 0xffff) |
5375 | rf7b = i; |
5376 | } |
5377 | if (rf7b == 0xffff) |
5378 | rf7b = 3; |
5379 | } else { |
5380 | rf7b = 0; |
5381 | } |
5382 | } |
5383 | RF_WRITE(mac, 0x7b, rf7b)bwi_rf_write((mac), (0x7b), (rf7b)); |
5384 | |
5385 | /* |
5386 | * Restore saved RF/PHY registers |
5387 | */ |
5388 | if (phy->phy_rev >= 6) { |
5389 | for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) { |
5390 | PHY_WRITE(mac, save_phy6_regs[phy6_idx],bwi_phy_write((mac), (save_phy6_regs[phy6_idx]), (save_phy6[phy6_idx ])) |
5391 | save_phy6[phy6_idx])bwi_phy_write((mac), (save_phy6_regs[phy6_idx]), (save_phy6[phy6_idx ])); |
5392 | } |
5393 | } |
5394 | |
5395 | /* Saved PHY registers 0, 1, 2 are handled later */ |
5396 | for (i = 3; i < SAVE_PHY_COMM_MAX; ++i) |
5397 | PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i])bwi_phy_write((mac), (save_phy_comm_regs[i]), (save_phy_comm[ i])); |
5398 | |
5399 | for (i = SAVE_RF_MAX - 1; i >= 0; --i) |
5400 | RF_WRITE(mac, save_rf_regs[i], save_rf[i])bwi_rf_write((mac), (save_rf_regs[i]), (save_rf[i])); |
5401 | |
5402 | PHY_SETBITS(mac, 0x802, 0x3)bwi_phy_write(((mac)), ((0x802)), (bwi_phy_read(((mac)), ((0x802 ))) | (0x3))); |
5403 | PHY_SETBITS(mac, 0x429, 0x8000)bwi_phy_write(((mac)), ((0x429)), (bwi_phy_read(((mac)), ((0x429 ))) | (0x8000))); |
5404 | |
5405 | bwi_set_gains(mac, NULL((void *)0)); |
5406 | |
5407 | if (phy->phy_rev >= 6) { |
5408 | for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) { |
5409 | PHY_WRITE(mac, save_phy6_regs[phy6_idx],bwi_phy_write((mac), (save_phy6_regs[phy6_idx]), (save_phy6[phy6_idx ])) |
5410 | save_phy6[phy6_idx])bwi_phy_write((mac), (save_phy6_regs[phy6_idx]), (save_phy6[phy6_idx ])); |
5411 | } |
5412 | } |
5413 | |
5414 | PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0])bwi_phy_write((mac), (save_phy_comm_regs[0]), (save_phy_comm[ 0])); |
5415 | PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2])bwi_phy_write((mac), (save_phy_comm_regs[2]), (save_phy_comm[ 2])); |
5416 | PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1])bwi_phy_write((mac), (save_phy_comm_regs[1]), (save_phy_comm[ 1])); |
5417 | |
5418 | #undef SAVE_RF_MAX |
5419 | #undef SAVE_PHY_COMM_MAX |
5420 | #undef SAVE_PHY6_MAX |
5421 | } |
5422 | |
5423 | void |
5424 | bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *mac) |
5425 | { |
5426 | #define SAVE_RF_MAX 3 |
5427 | #define SAVE_PHY_COMM_MAX 4 |
5428 | #define SAVE_PHY3_MAX 8 |
5429 | struct bwi_softc *sc = mac->mac_sc; |
5430 | struct bwi_phy *phy = &mac->mac_phy; |
5431 | struct bwi_rf *rf = &mac->mac_rf; |
5432 | uint16_t save_rf[SAVE_RF_MAX]; |
5433 | uint16_t save_phy_comm[SAVE_PHY_COMM_MAX]; |
5434 | uint16_t save_phy3[SAVE_PHY3_MAX]; |
5435 | uint16_t ant_div, bbp_atten, chan_ex; |
5436 | struct bwi_gains gains; |
5437 | int16_t nrssi[2]; |
5438 | int i, phy3_idx = 0; |
5439 | |
5440 | static const uint16_t save_rf_regs[SAVE_RF_MAX] = |
5441 | { 0x7a, 0x52, 0x43 }; |
5442 | static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = |
5443 | { 0x15, 0x5a, 0x59, 0x58 }; |
5444 | static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = { |
5445 | 0x002e, 0x002f, 0x080f, 0x0810, |
5446 | 0x0801, 0x0060, 0x0014, 0x0478 |
5447 | }; |
5448 | |
5449 | if (rf->rf_rev >= 9) |
5450 | return; |
5451 | else if (rf->rf_rev == 8) |
5452 | bwi_rf_set_nrssi_ofs_11g(mac); |
5453 | |
5454 | PHY_CLRBITS(mac, 0x429, 0x8000)bwi_phy_write(((mac)), ((0x429)), (bwi_phy_read(((mac)), ((0x429 ))) & ~(0x8000))); |
5455 | PHY_CLRBITS(mac, 0x802, 0x3)bwi_phy_write(((mac)), ((0x802)), (bwi_phy_read(((mac)), ((0x802 ))) & ~(0x3))); |
5456 | |
5457 | /* |
5458 | * Save RF/PHY registers for later restoration |
5459 | */ |
5460 | ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03e2 )))); |
5461 | CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000)((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), ( ((0x03e2))), ((((((sc))->sc_mem_bt)->read_2((((sc))-> sc_mem_bh), (((0x03e2))))) | (0x8000))))); |
5462 | |
5463 | for (i = 0; i < SAVE_RF_MAX; ++i) |
5464 | save_rf[i] = RF_READ(mac, save_rf_regs[i])bwi_rf_read((mac), (save_rf_regs[i])); |
5465 | for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) |
5466 | save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i])bwi_phy_read((mac), (save_phy_comm_regs[i])); |
5467 | |
5468 | bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03e6 )))); |
5469 | chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03f4 )))); |
5470 | |
5471 | if (phy->phy_rev >= 3) { |
5472 | for (i = 0; i < SAVE_PHY3_MAX; ++i) |
5473 | save_phy3[i] = PHY_READ(mac, save_phy3_regs[i])bwi_phy_read((mac), (save_phy3_regs[i])); |
5474 | |
5475 | PHY_WRITE(mac, 0x2e, 0)bwi_phy_write((mac), (0x2e), (0)); |
5476 | PHY_WRITE(mac, 0x810, 0)bwi_phy_write((mac), (0x810), (0)); |
5477 | |
5478 | if (phy->phy_rev == 4 || phy->phy_rev == 6 || |
5479 | phy->phy_rev == 7) { |
5480 | PHY_SETBITS(mac, 0x478, 0x100)bwi_phy_write(((mac)), ((0x478)), (bwi_phy_read(((mac)), ((0x478 ))) | (0x100))); |
5481 | PHY_SETBITS(mac, 0x810, 0x40)bwi_phy_write(((mac)), ((0x810)), (bwi_phy_read(((mac)), ((0x810 ))) | (0x40))); |
5482 | } else if (phy->phy_rev == 3 || phy->phy_rev == 5) |
5483 | PHY_CLRBITS(mac, 0x810, 0x40)bwi_phy_write(((mac)), ((0x810)), (bwi_phy_read(((mac)), ((0x810 ))) & ~(0x40))); |
5484 | |
5485 | PHY_SETBITS(mac, 0x60, 0x40)bwi_phy_write(((mac)), ((0x60)), (bwi_phy_read(((mac)), ((0x60 ))) | (0x40))); |
5486 | PHY_SETBITS(mac, 0x14, 0x200)bwi_phy_write(((mac)), ((0x14)), (bwi_phy_read(((mac)), ((0x14 ))) | (0x200))); |
5487 | } |
5488 | |
5489 | /* |
5490 | * Calculate nrssi0 |
5491 | */ |
5492 | RF_SETBITS(mac, 0x7a, 0x70)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0x70))); |
5493 | |
5494 | bzero(&gains, sizeof(gains))__builtin_bzero((&gains), (sizeof(gains))); |
5495 | gains.tbl_gain1 = 0; |
5496 | gains.tbl_gain2 = 8; |
5497 | gains.phy_gain = 0; |
5498 | bwi_set_gains(mac, &gains); |
5499 | |
5500 | RF_CLRBITS(mac, 0x7a, 0xff08)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) & ~(0xff08))); |
5501 | if (phy->phy_rev >= 2) { |
5502 | PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x30)bwi_phy_write(((mac)), ((0x811)), ((bwi_phy_read(((mac)), ((0x811 ))) & (0xffcf)) | (0x30))); |
5503 | PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10)bwi_phy_write(((mac)), ((0x812)), ((bwi_phy_read(((mac)), ((0x812 ))) & (0xffcf)) | (0x10))); |
5504 | } |
5505 | |
5506 | RF_SETBITS(mac, 0x7a, 0x80)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0x80))); |
5507 | DELAY(20)(*delay_func)(20); |
5508 | nrssi[0] = bwi_nrssi_11g(mac); |
5509 | |
5510 | /* |
5511 | * Calculate nrssi1 |
5512 | */ |
5513 | RF_CLRBITS(mac, 0x7a, 0xff80)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) & ~(0xff80))); |
5514 | if (phy->phy_version >= 2) |
5515 | PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40)bwi_phy_write(((mac)), ((0x3)), ((bwi_phy_read(((mac)), ((0x3 ))) & (0xff9f)) | (0x40))); |
5516 | CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000)((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), ( ((0x03f4))), ((((((sc))->sc_mem_bt)->read_2((((sc))-> sc_mem_bh), (((0x03f4))))) | (0x2000))))); |
5517 | |
5518 | RF_SETBITS(mac, 0x7a, 0xf)bwi_rf_write(((mac)), ((0x7a)), (bwi_rf_read(((mac)), ((0x7a) )) | (0xf))); |
5519 | PHY_WRITE(mac, 0x15, 0xf330)bwi_phy_write((mac), (0x15), (0xf330)); |
5520 | if (phy->phy_rev >= 2) { |
5521 | PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x20)bwi_phy_write(((mac)), ((0x812)), ((bwi_phy_read(((mac)), ((0x812 ))) & (0xffcf)) | (0x20))); |
5522 | PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x20)bwi_phy_write(((mac)), ((0x811)), ((bwi_phy_read(((mac)), ((0x811 ))) & (0xffcf)) | (0x20))); |
5523 | } |
5524 | |
5525 | bzero(&gains, sizeof(gains))__builtin_bzero((&gains), (sizeof(gains))); |
5526 | gains.tbl_gain1 = 3; |
5527 | gains.tbl_gain2 = 0; |
5528 | gains.phy_gain = 1; |
5529 | bwi_set_gains(mac, &gains); |
5530 | |
5531 | if (rf->rf_rev == 8) { |
5532 | RF_WRITE(mac, 0x43, 0x1f)bwi_rf_write((mac), (0x43), (0x1f)); |
5533 | } else { |
5534 | RF_FILT_SETBITS(mac, 0x52, 0xff0f, 0x60)bwi_rf_write(((mac)), ((0x52)), ((bwi_rf_read(((mac)), ((0x52 ))) & (0xff0f)) | (0x60))); |
5535 | RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9)bwi_rf_write(((mac)), ((0x43)), ((bwi_rf_read(((mac)), ((0x43 ))) & (0xfff0)) | (0x9))); |
5536 | } |
5537 | PHY_WRITE(mac, 0x5a, 0x480)bwi_phy_write((mac), (0x5a), (0x480)); |
5538 | PHY_WRITE(mac, 0x59, 0x810)bwi_phy_write((mac), (0x59), (0x810)); |
5539 | PHY_WRITE(mac, 0x58, 0xd)bwi_phy_write((mac), (0x58), (0xd)); |
5540 | DELAY(20)(*delay_func)(20); |
5541 | |
5542 | nrssi[1] = bwi_nrssi_11g(mac); |
5543 | |
5544 | /* |
5545 | * Install calculated narrow RSSI values |
5546 | */ |
5547 | if (nrssi[1] == nrssi[0]) |
5548 | rf->rf_nrssi_slope = 0x10000; |
5549 | else |
5550 | rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]); |
5551 | if (nrssi[0] >= -4) { |
5552 | rf->rf_nrssi[0] = nrssi[1]; |
5553 | rf->rf_nrssi[1] = nrssi[0]; |
5554 | } |
5555 | |
5556 | /* |
5557 | * Restore saved RF/PHY registers |
5558 | */ |
5559 | if (phy->phy_rev >= 3) { |
5560 | for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) { |
5561 | PHY_WRITE(mac, save_phy3_regs[phy3_idx],bwi_phy_write((mac), (save_phy3_regs[phy3_idx]), (save_phy3[phy3_idx ])) |
5562 | save_phy3[phy3_idx])bwi_phy_write((mac), (save_phy3_regs[phy3_idx]), (save_phy3[phy3_idx ])); |
5563 | } |
5564 | } |
5565 | if (phy->phy_rev >= 2) { |
5566 | PHY_CLRBITS(mac, 0x812, 0x30)bwi_phy_write(((mac)), ((0x812)), (bwi_phy_read(((mac)), ((0x812 ))) & ~(0x30))); |
5567 | PHY_CLRBITS(mac, 0x811, 0x30)bwi_phy_write(((mac)), ((0x811)), (bwi_phy_read(((mac)), ((0x811 ))) & ~(0x30))); |
5568 | } |
5569 | |
5570 | for (i = 0; i < SAVE_RF_MAX; ++i) |
5571 | RF_WRITE(mac, save_rf_regs[i], save_rf[i])bwi_rf_write((mac), (save_rf_regs[i]), (save_rf[i])); |
5572 | |
5573 | CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e2 )), ((ant_div)))); |
5574 | CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03e6 )), ((bbp_atten)))); |
5575 | CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03f4 )), ((chan_ex)))); |
5576 | |
5577 | for (i = 0; i < SAVE_PHY_COMM_MAX; ++i) |
5578 | PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i])bwi_phy_write((mac), (save_phy_comm_regs[i]), (save_phy_comm[ i])); |
5579 | |
5580 | bwi_rf_workaround(mac, rf->rf_curchan); |
5581 | PHY_SETBITS(mac, 0x802, 0x3)bwi_phy_write(((mac)), ((0x802)), (bwi_phy_read(((mac)), ((0x802 ))) | (0x3))); |
5582 | bwi_set_gains(mac, NULL((void *)0)); |
5583 | PHY_SETBITS(mac, 0x429, 0x8000)bwi_phy_write(((mac)), ((0x429)), (bwi_phy_read(((mac)), ((0x429 ))) | (0x8000))); |
5584 | |
5585 | if (phy->phy_rev >= 3) { |
5586 | for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) { |
5587 | PHY_WRITE(mac, save_phy3_regs[phy3_idx],bwi_phy_write((mac), (save_phy3_regs[phy3_idx]), (save_phy3[phy3_idx ])) |
5588 | save_phy3[phy3_idx])bwi_phy_write((mac), (save_phy3_regs[phy3_idx]), (save_phy3[phy3_idx ])); |
5589 | } |
5590 | } |
5591 | |
5592 | bwi_rf_init_sw_nrssi_table(mac); |
5593 | bwi_rf_set_nrssi_thr_11g(mac); |
5594 | |
5595 | #undef SAVE_RF_MAX |
5596 | #undef SAVE_PHY_COMM_MAX |
5597 | #undef SAVE_PHY3_MAX |
5598 | } |
5599 | |
5600 | void |
5601 | bwi_rf_init_sw_nrssi_table(struct bwi_mac *mac) |
5602 | { |
5603 | struct bwi_rf *rf = &mac->mac_rf; |
5604 | int d, i; |
5605 | |
5606 | d = 0x1f - rf->rf_nrssi[0]; |
5607 | for (i = 0; i < BWI_NRSSI_TBLSZ64; ++i) { |
5608 | int val; |
5609 | |
5610 | val = (((i - d) * rf->rf_nrssi_slope) / 0x10000) + 0x3a; |
5611 | if (val < 0) |
5612 | val = 0; |
5613 | else if (val > 0x3f) |
5614 | val = 0x3f; |
5615 | |
5616 | rf->rf_nrssi_table[i] = val; |
5617 | } |
5618 | } |
5619 | |
5620 | void |
5621 | bwi_rf_init_hw_nrssi_table(struct bwi_mac *mac, uint16_t adjust) |
5622 | { |
5623 | int i; |
5624 | |
5625 | for (i = 0; i < BWI_NRSSI_TBLSZ64; ++i) { |
5626 | int16_t val; |
5627 | |
5628 | val = bwi_nrssi_read(mac, i); |
5629 | |
5630 | val -= adjust; |
5631 | if (val < -32) |
5632 | val = -32; |
5633 | else if (val > 31) |
5634 | val = 31; |
5635 | |
5636 | bwi_nrssi_write(mac, i, val); |
5637 | } |
5638 | } |
5639 | |
5640 | void |
5641 | bwi_rf_set_nrssi_thr_11b(struct bwi_mac *mac) |
5642 | { |
5643 | struct bwi_rf *rf = &mac->mac_rf; |
5644 | int32_t thr; |
5645 | |
5646 | if (rf->rf_type != BWI_RF_T_BCM20500x2050 || |
5647 | (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI(1 << 3)) == 0) |
5648 | return; |
5649 | |
5650 | /* |
5651 | * Calculate nrssi threshold |
5652 | */ |
5653 | if (rf->rf_rev >= 6) { |
5654 | thr = (rf->rf_nrssi[1] - rf->rf_nrssi[0]) * 32; |
5655 | thr += 20 * (rf->rf_nrssi[0] + 1); |
5656 | thr /= 40; |
5657 | } else { |
5658 | thr = rf->rf_nrssi[1] - 5; |
5659 | } |
5660 | if (thr < 0) |
5661 | thr = 0; |
5662 | else if (thr > 0x3e) |
5663 | thr = 0x3e; |
5664 | |
5665 | PHY_READ(mac, BWI_PHYR_NRSSI_THR_11B)bwi_phy_read((mac), (0x020)); /* dummy read */ |
5666 | PHY_WRITE(mac, BWI_PHYR_NRSSI_THR_11B, (((uint16_t)thr) << 8) | 0x1c)bwi_phy_write((mac), (0x020), ((((uint16_t)thr) << 8) | 0x1c)); |
5667 | |
5668 | if (rf->rf_rev >= 6) { |
5669 | PHY_WRITE(mac, 0x87, 0xe0d)bwi_phy_write((mac), (0x87), (0xe0d)); |
5670 | PHY_WRITE(mac, 0x86, 0xc0b)bwi_phy_write((mac), (0x86), (0xc0b)); |
5671 | PHY_WRITE(mac, 0x85, 0xa09)bwi_phy_write((mac), (0x85), (0xa09)); |
5672 | PHY_WRITE(mac, 0x84, 0x808)bwi_phy_write((mac), (0x84), (0x808)); |
5673 | PHY_WRITE(mac, 0x83, 0x808)bwi_phy_write((mac), (0x83), (0x808)); |
5674 | PHY_WRITE(mac, 0x82, 0x604)bwi_phy_write((mac), (0x82), (0x604)); |
5675 | PHY_WRITE(mac, 0x81, 0x302)bwi_phy_write((mac), (0x81), (0x302)); |
5676 | PHY_WRITE(mac, 0x80, 0x100)bwi_phy_write((mac), (0x80), (0x100)); |
5677 | } |
5678 | } |
5679 | |
5680 | int32_t |
5681 | _nrssi_threshold(const struct bwi_rf *rf, int32_t val) |
5682 | { |
5683 | val *= (rf->rf_nrssi[1] - rf->rf_nrssi[0]); |
5684 | val += (rf->rf_nrssi[0] << 6); |
5685 | if (val < 32) |
5686 | val += 31; |
5687 | else |
5688 | val += 32; |
5689 | val >>= 6; |
5690 | if (val < -31) |
5691 | val = -31; |
5692 | else if (val > 31) |
5693 | val = 31; |
5694 | |
5695 | return (val); |
5696 | } |
5697 | |
5698 | void |
5699 | bwi_rf_set_nrssi_thr_11g(struct bwi_mac *mac) |
5700 | { |
5701 | int32_t thr1, thr2; |
5702 | uint16_t thr; |
5703 | |
5704 | /* |
5705 | * Find the two nrssi thresholds |
5706 | */ |
5707 | if ((mac->mac_phy.phy_flags & BWI_PHY_F_LINKED0x2) == 0 || |
5708 | (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI(1 << 3)) == 0) { |
5709 | int16_t nrssi; |
5710 | |
5711 | nrssi = bwi_nrssi_read(mac, 0x20); |
5712 | if (nrssi >= 32) |
5713 | nrssi -= 64; |
5714 | |
5715 | if (nrssi < 3) { |
5716 | thr1 = 0x2b; |
5717 | thr2 = 0x27; |
5718 | } else { |
5719 | thr1 = 0x2d; |
5720 | thr2 = 0x2b; |
5721 | } |
5722 | } else { |
5723 | /* TODO Interfere mode */ |
5724 | thr1 = _nrssi_threshold(&mac->mac_rf, 0x11); |
5725 | thr2 = _nrssi_threshold(&mac->mac_rf, 0xe); |
5726 | } |
5727 | |
5728 | #define NRSSI_THR1_MASK 0x003f |
5729 | #define NRSSI_THR2_MASK 0x0fc0 |
5730 | thr = __SHIFTIN((uint32_t)thr1, NRSSI_THR1_MASK)(((uint32_t)thr1) * ((((NRSSI_THR1_MASK) - 1) & (NRSSI_THR1_MASK )) ^ (NRSSI_THR1_MASK))) | |
5731 | __SHIFTIN((uint32_t)thr2, NRSSI_THR2_MASK)(((uint32_t)thr2) * ((((NRSSI_THR2_MASK) - 1) & (NRSSI_THR2_MASK )) ^ (NRSSI_THR2_MASK))); |
5732 | PHY_FILT_SETBITS(mac, BWI_PHYR_NRSSI_THR_11G, 0xf000, thr)bwi_phy_write(((mac)), ((0x48a)), ((bwi_phy_read(((mac)), ((0x48a ))) & (0xf000)) | (thr))); |
5733 | #undef NRSSI_THR1_MASK |
5734 | #undef NRSSI_THR2_MASK |
5735 | } |
5736 | |
5737 | void |
5738 | bwi_rf_clear_tssi(struct bwi_mac *mac) |
5739 | { |
5740 | /* XXX use function pointer */ |
5741 | if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) { |
5742 | /* TODO: 11A */ |
5743 | } else { |
5744 | uint16_t val; |
5745 | int i; |
5746 | |
5747 | val = __SHIFTIN(BWI_INVALID_TSSI, BWI_LO_TSSI_MASK)((0x7f) * ((((0x00ff) - 1) & (0x00ff)) ^ (0x00ff))) | |
5748 | __SHIFTIN(BWI_INVALID_TSSI, BWI_HI_TSSI_MASK)((0x7f) * ((((0xff00) - 1) & (0xff00)) ^ (0xff00))); |
5749 | |
5750 | for (i = 0; i < 2; ++i) { |
5751 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,bwi_memobj_write_2((mac), (0x1), (0x58 + (i * 2)), (val)) |
5752 | BWI_COMM_MOBJ_TSSI_DS + (i * 2), val)bwi_memobj_write_2((mac), (0x1), (0x58 + (i * 2)), (val)); |
5753 | } |
5754 | |
5755 | for (i = 0; i < 2; ++i) { |
5756 | MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,bwi_memobj_write_2((mac), (0x1), (0x70 + (i * 2)), (val)) |
5757 | BWI_COMM_MOBJ_TSSI_OFDM + (i * 2), val)bwi_memobj_write_2((mac), (0x1), (0x70 + (i * 2)), (val)); |
5758 | } |
5759 | } |
5760 | } |
5761 | |
5762 | void |
5763 | bwi_rf_clear_state(struct bwi_rf *rf) |
5764 | { |
5765 | int i; |
5766 | |
5767 | rf->rf_flags &= ~BWI_RF_CLEAR_FLAGS(0x1); |
5768 | bzero(rf->rf_lo, sizeof(rf->rf_lo))__builtin_bzero((rf->rf_lo), (sizeof(rf->rf_lo))); |
5769 | bzero(rf->rf_lo_used, sizeof(rf->rf_lo_used))__builtin_bzero((rf->rf_lo_used), (sizeof(rf->rf_lo_used ))); |
5770 | |
5771 | rf->rf_nrssi_slope = 0; |
5772 | rf->rf_nrssi[0] = BWI_INVALID_NRSSI-1000; |
5773 | rf->rf_nrssi[1] = BWI_INVALID_NRSSI-1000; |
5774 | |
5775 | for (i = 0; i < BWI_NRSSI_TBLSZ64; ++i) |
5776 | rf->rf_nrssi_table[i] = i; |
5777 | |
5778 | rf->rf_lo_gain = 0; |
5779 | rf->rf_rx_gain = 0; |
5780 | |
5781 | bcopy(rf->rf_txpower_map0, rf->rf_txpower_map, |
5782 | sizeof(rf->rf_txpower_map)); |
5783 | rf->rf_idle_tssi = rf->rf_idle_tssi0; |
5784 | } |
5785 | |
5786 | void |
5787 | bwi_rf_on_11a(struct bwi_mac *mac) |
5788 | { |
5789 | /* TODO: 11A */ |
5790 | } |
5791 | |
5792 | void |
5793 | bwi_rf_on_11bg(struct bwi_mac *mac) |
5794 | { |
5795 | struct bwi_phy *phy = &mac->mac_phy; |
5796 | |
5797 | PHY_WRITE(mac, 0x15, 0x8000)bwi_phy_write((mac), (0x15), (0x8000)); |
5798 | PHY_WRITE(mac, 0x15, 0xcc00)bwi_phy_write((mac), (0x15), (0xcc00)); |
5799 | if (phy->phy_flags & BWI_PHY_F_LINKED0x2) |
5800 | PHY_WRITE(mac, 0x15, 0xc0)bwi_phy_write((mac), (0x15), (0xc0)); |
5801 | else |
5802 | PHY_WRITE(mac, 0x15, 0)bwi_phy_write((mac), (0x15), (0)); |
5803 | |
5804 | bwi_rf_set_chan(mac, 6 /* XXX */, 1); |
5805 | } |
5806 | |
5807 | void |
5808 | bwi_rf_set_ant_mode(struct bwi_mac *mac, int ant_mode) |
5809 | { |
5810 | struct bwi_softc *sc = mac->mac_sc; |
5811 | struct bwi_phy *phy = &mac->mac_phy; |
5812 | uint16_t val; |
5813 | |
5814 | KASSERT(ant_mode == BWI_ANT_MODE_0 ||((ant_mode == 0 || ant_mode == 1 || ant_mode == 3) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c", 5816, "ant_mode == BWI_ANT_MODE_0 || ant_mode == BWI_ANT_MODE_1 || ant_mode == BWI_ANT_MODE_AUTO" )) |
5815 | ant_mode == BWI_ANT_MODE_1 ||((ant_mode == 0 || ant_mode == 1 || ant_mode == 3) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c", 5816, "ant_mode == BWI_ANT_MODE_0 || ant_mode == BWI_ANT_MODE_1 || ant_mode == BWI_ANT_MODE_AUTO" )) |
5816 | ant_mode == BWI_ANT_MODE_AUTO)((ant_mode == 0 || ant_mode == 1 || ant_mode == 3) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c", 5816, "ant_mode == BWI_ANT_MODE_0 || ant_mode == BWI_ANT_MODE_1 || ant_mode == BWI_ANT_MODE_AUTO" )); |
5817 | |
5818 | HFLAGS_CLRBITS(mac, BWI_HFLAG_AUTO_ANTDIV)bwi_hostflags_write(((mac)), (bwi_hostflags_read(((mac))) | ( 0x1ULL))); |
5819 | |
5820 | if (phy->phy_mode == IEEE80211_MODE_11B) { |
5821 | /* NOTE: v4/v3 conflicts, take v3 */ |
5822 | if (mac->mac_revmac_regwin.rw_rev == 2) |
5823 | val = BWI_ANT_MODE_AUTO3; |
5824 | else |
5825 | val = ant_mode; |
5826 | val <<= 7; |
5827 | PHY_FILT_SETBITS(mac, 0x3e2, 0xfe7f, val)bwi_phy_write(((mac)), ((0x3e2)), ((bwi_phy_read(((mac)), ((0x3e2 ))) & (0xfe7f)) | (val))); |
5828 | } else { /* 11a/g */ |
5829 | /* XXX reg/value naming */ |
5830 | val = ant_mode << 7; |
5831 | PHY_FILT_SETBITS(mac, 0x401, 0x7e7f, val)bwi_phy_write(((mac)), ((0x401)), ((bwi_phy_read(((mac)), ((0x401 ))) & (0x7e7f)) | (val))); |
5832 | |
5833 | if (ant_mode == BWI_ANT_MODE_AUTO3) |
5834 | PHY_CLRBITS(mac, 0x42b, 0x100)bwi_phy_write(((mac)), ((0x42b)), (bwi_phy_read(((mac)), ((0x42b ))) & ~(0x100))); |
5835 | |
5836 | if (phy->phy_mode == IEEE80211_MODE_11A) { |
5837 | /* TODO: 11A */ |
5838 | } else { /* 11g */ |
5839 | if (ant_mode == BWI_ANT_MODE_AUTO3) |
5840 | PHY_SETBITS(mac, 0x48c, 0x2000)bwi_phy_write(((mac)), ((0x48c)), (bwi_phy_read(((mac)), ((0x48c ))) | (0x2000))); |
5841 | else |
5842 | PHY_CLRBITS(mac, 0x48c, 0x2000)bwi_phy_write(((mac)), ((0x48c)), (bwi_phy_read(((mac)), ((0x48c ))) & ~(0x2000))); |
5843 | |
5844 | if (phy->phy_rev >= 2) { |
5845 | PHY_SETBITS(mac, 0x461, 0x10)bwi_phy_write(((mac)), ((0x461)), (bwi_phy_read(((mac)), ((0x461 ))) | (0x10))); |
5846 | PHY_FILT_SETBITS(mac, 0x4ad, 0xff00, 0x15)bwi_phy_write(((mac)), ((0x4ad)), ((bwi_phy_read(((mac)), ((0x4ad ))) & (0xff00)) | (0x15))); |
5847 | if (phy->phy_rev == 2) { |
5848 | PHY_WRITE(mac, 0x427, 0x8)bwi_phy_write((mac), (0x427), (0x8)); |
5849 | } else { |
5850 | PHY_FILT_SETBITS(mac, 0x427,bwi_phy_write(((mac)), ((0x427)), ((bwi_phy_read(((mac)), ((0x427 ))) & (0xff00)) | (0x8))) |
5851 | 0xff00, 0x8)bwi_phy_write(((mac)), ((0x427)), ((bwi_phy_read(((mac)), ((0x427 ))) & (0xff00)) | (0x8))); |
5852 | } |
5853 | |
5854 | if (phy->phy_rev >= 6) |
5855 | PHY_WRITE(mac, 0x49b, 0xdc)bwi_phy_write((mac), (0x49b), (0xdc)); |
5856 | } |
5857 | } |
5858 | } |
5859 | |
5860 | /* XXX v4 set AUTO_ANTDIV unconditionally */ |
5861 | if (ant_mode == BWI_ANT_MODE_AUTO3) |
5862 | HFLAGS_SETBITS(mac, BWI_HFLAG_AUTO_ANTDIV)bwi_hostflags_write(((mac)), (bwi_hostflags_read(((mac))) & ~(0x1ULL))); |
5863 | |
5864 | val = ant_mode << 8; |
5865 | MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_BEACON, |