Bug Summary

File:dev/ic/bwi.c
Warning:line 7935, column 2
Value stored to 'ntx' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name bwi.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/ic/bwi.c
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
76int 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
99extern int ticks;
100
101/* XXX end porting goop */
102
103/* MAC */
104struct bwi_retry_lim {
105 uint16_t shretry;
106 uint16_t shretry_fb;
107 uint16_t lgretry;
108 uint16_t lgretry_fb;
109};
110
111struct bwi_clock_freq {
112 uint clkfreq_min;
113 uint clkfreq_max;
114};
115
116/* XXX does not belong here */
117struct 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
124enum 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 */
132void bwi_tmplt_write_4(struct bwi_mac *, uint32_t, uint32_t);
133void bwi_hostflags_write(struct bwi_mac *, uint64_t);
134uint64_t bwi_hostflags_read(struct bwi_mac *);
135uint16_t bwi_memobj_read_2(struct bwi_mac *, uint16_t, uint16_t);
136uint32_t bwi_memobj_read_4(struct bwi_mac *, uint16_t, uint16_t);
137void bwi_memobj_write_2(struct bwi_mac *, uint16_t, uint16_t,
138 uint16_t);
139void bwi_memobj_write_4(struct bwi_mac *, uint16_t, uint16_t,
140 uint32_t);
141int bwi_mac_lateattach(struct bwi_mac *);
142int bwi_mac_init(struct bwi_mac *);
143void bwi_mac_reset(struct bwi_mac *, int);
144void bwi_mac_set_tpctl_11bg(struct bwi_mac *,
145 const struct bwi_tpctl *);
146int bwi_mac_test(struct bwi_mac *);
147void bwi_mac_setup_tpctl(struct bwi_mac *);
148void bwi_mac_dummy_xmit(struct bwi_mac *);
149void bwi_mac_init_tpctl_11bg(struct bwi_mac *);
150void bwi_mac_detach(struct bwi_mac *);
151int bwi_get_firmware(const char *, const uint8_t *, size_t,
152 size_t *, size_t *);
153int bwi_fwimage_is_valid(struct bwi_softc *, uint8_t *,
154 size_t, char *, uint8_t);
155int bwi_mac_fw_alloc(struct bwi_mac *);
156void bwi_mac_fw_free(struct bwi_mac *);
157int bwi_mac_fw_load(struct bwi_mac *);
158int bwi_mac_gpio_init(struct bwi_mac *);
159int bwi_mac_gpio_fini(struct bwi_mac *);
160int bwi_mac_fw_load_iv(struct bwi_mac *, uint8_t *, size_t);
161int bwi_mac_fw_init(struct bwi_mac *);
162void bwi_mac_opmode_init(struct bwi_mac *);
163void bwi_mac_hostflags_init(struct bwi_mac *);
164void bwi_mac_bss_param_init(struct bwi_mac *);
165void bwi_mac_set_retry_lim(struct bwi_mac *,
166 const struct bwi_retry_lim *);
167void bwi_mac_set_ackrates(struct bwi_mac *,
168 const struct ieee80211_rateset *);
169int bwi_mac_start(struct bwi_mac *);
170int bwi_mac_stop(struct bwi_mac *);
171int bwi_mac_config_ps(struct bwi_mac *);
172void bwi_mac_reset_hwkeys(struct bwi_mac *);
173void bwi_mac_shutdown(struct bwi_mac *);
174int bwi_mac_get_property(struct bwi_mac *);
175void bwi_mac_updateslot(struct bwi_mac *, int);
176int bwi_mac_attach(struct bwi_softc *, int, uint8_t);
177void bwi_mac_balance_atten(int *, int *);
178void bwi_mac_adjust_tpctl(struct bwi_mac *, int, int);
179void bwi_mac_calibrate_txpower(struct bwi_mac *,
180 enum bwi_txpwrcb_type);
181void bwi_mac_lock(struct bwi_mac *);
182void bwi_mac_unlock(struct bwi_mac *);
183void bwi_mac_set_promisc(struct bwi_mac *, int);
184
185/* PHY */
186void bwi_phy_write(struct bwi_mac *, uint16_t, uint16_t);
187uint16_t bwi_phy_read(struct bwi_mac *, uint16_t);
188int bwi_phy_attach(struct bwi_mac *);
189void bwi_phy_set_bbp_atten(struct bwi_mac *, uint16_t);
190int bwi_phy_calibrate(struct bwi_mac *);
191void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
192void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
193void bwi_nrssi_write(struct bwi_mac *, uint16_t, int16_t);
194int16_t bwi_nrssi_read(struct bwi_mac *, uint16_t);
195void bwi_phy_init_11a(struct bwi_mac *);
196void bwi_phy_init_11g(struct bwi_mac *);
197void bwi_phy_init_11b_rev2(struct bwi_mac *);
198void bwi_phy_init_11b_rev4(struct bwi_mac *);
199void bwi_phy_init_11b_rev5(struct bwi_mac *);
200void bwi_phy_init_11b_rev6(struct bwi_mac *);
201void bwi_phy_config_11g(struct bwi_mac *);
202void bwi_phy_config_agc(struct bwi_mac *);
203void bwi_set_gains(struct bwi_mac *, const struct bwi_gains *);
204void bwi_phy_clear_state(struct bwi_phy *);
205
206/* RF */
207int16_t bwi_nrssi_11g(struct bwi_mac *);
208struct bwi_rf_lo
209 *bwi_get_rf_lo(struct bwi_mac *, uint16_t, uint16_t);
210int bwi_rf_lo_isused(struct bwi_mac *, const struct bwi_rf_lo *);
211void bwi_rf_write(struct bwi_mac *, uint16_t, uint16_t);
212uint16_t bwi_rf_read(struct bwi_mac *, uint16_t);
213int bwi_rf_attach(struct bwi_mac *);
214void bwi_rf_set_chan(struct bwi_mac *, uint, int);
215void bwi_rf_get_gains(struct bwi_mac *);
216void bwi_rf_init(struct bwi_mac *);
217void bwi_rf_off_11a(struct bwi_mac *);
218void bwi_rf_off_11bg(struct bwi_mac *);
219void bwi_rf_off_11g_rev5(struct bwi_mac *);
220void bwi_rf_workaround(struct bwi_mac *, uint);
221struct bwi_rf_lo
222 *bwi_rf_lo_find(struct bwi_mac *, const struct bwi_tpctl *);
223void bwi_rf_lo_adjust(struct bwi_mac *, const struct bwi_tpctl *);
224void bwi_rf_lo_write(struct bwi_mac *, const struct bwi_rf_lo *);
225int bwi_rf_gain_max_reached(struct bwi_mac *, int);
226uint16_t bwi_bitswap4(uint16_t);
227uint16_t bwi_phy812_value(struct bwi_mac *, uint16_t);
228void bwi_rf_init_bcm2050(struct bwi_mac *);
229uint16_t bwi_rf_calibval(struct bwi_mac *);
230int32_t _bwi_adjust_devide(int32_t, int32_t);
231int bwi_rf_calc_txpower(int8_t *, uint8_t, const int16_t[]);
232int bwi_rf_map_txpower(struct bwi_mac *);
233void bwi_rf_lo_update_11g(struct bwi_mac *);
234uint32_t bwi_rf_lo_devi_measure(struct bwi_mac *, uint16_t);
235uint16_t bwi_rf_get_tp_ctrl2(struct bwi_mac *);
236uint8_t _bwi_rf_lo_update_11g(struct bwi_mac *, uint16_t);
237void bwi_rf_lo_measure_11g(struct bwi_mac *,
238 const struct bwi_rf_lo *, struct bwi_rf_lo *, uint8_t);
239void bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *);
240void bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *);
241void bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *);
242void bwi_rf_init_sw_nrssi_table(struct bwi_mac *);
243void bwi_rf_init_hw_nrssi_table(struct bwi_mac *, uint16_t);
244void bwi_rf_set_nrssi_thr_11b(struct bwi_mac *);
245int32_t _nrssi_threshold(const struct bwi_rf *, int32_t);
246void bwi_rf_set_nrssi_thr_11g(struct bwi_mac *);
247void bwi_rf_clear_tssi(struct bwi_mac *);
248void bwi_rf_clear_state(struct bwi_rf *);
249void bwi_rf_on_11a(struct bwi_mac *);
250void bwi_rf_on_11bg(struct bwi_mac *);
251void bwi_rf_set_ant_mode(struct bwi_mac *, int);
252int bwi_rf_get_latest_tssi(struct bwi_mac *, int8_t[], uint16_t);
253int bwi_rf_tssi2dbm(struct bwi_mac *, int8_t, int8_t *);
254int bwi_rf_calc_rssi_bcm2050(struct bwi_mac *,
255 const struct bwi_rxbuf_hdr *);
256int bwi_rf_calc_rssi_bcm2053(struct bwi_mac *,
257 const struct bwi_rxbuf_hdr *);
258int bwi_rf_calc_rssi_bcm2060(struct bwi_mac *,
259 const struct bwi_rxbuf_hdr *);
260uint16_t bwi_rf_lo_measure_11b(struct bwi_mac *);
261void bwi_rf_lo_update_11b(struct bwi_mac *);
262
263/* INTERFACE */
264uint16_t bwi_read_sprom(struct bwi_softc *, uint16_t);
265void bwi_setup_desc32(struct bwi_softc *, struct bwi_desc32 *, int,
266 int, bus_addr_t, int, int);
267void bwi_power_on(struct bwi_softc *, int);
268int bwi_power_off(struct bwi_softc *, int);
269int bwi_regwin_switch(struct bwi_softc *, struct bwi_regwin *,
270 struct bwi_regwin **);
271int bwi_regwin_select(struct bwi_softc *, int);
272void bwi_regwin_info(struct bwi_softc *, uint16_t *, uint8_t *);
273void bwi_led_attach(struct bwi_softc *);
274void bwi_led_newstate(struct bwi_softc *, enum ieee80211_state);
275uint16_t bwi_led_onoff(struct bwi_led *, uint16_t, int);
276void bwi_led_event(struct bwi_softc *, int);
277void bwi_led_blink_start(struct bwi_softc *, int, int);
278void bwi_led_blink_next(void *);
279void bwi_led_blink_end(void *);
280int bwi_bbp_attach(struct bwi_softc *);
281int bwi_bus_init(struct bwi_softc *, struct bwi_mac *);
282void bwi_get_card_flags(struct bwi_softc *);
283void bwi_get_eaddr(struct bwi_softc *, uint16_t, uint8_t *);
284void bwi_get_clock_freq(struct bwi_softc *,
285 struct bwi_clock_freq *);
286int bwi_set_clock_mode(struct bwi_softc *, enum bwi_clock_mode);
287int bwi_set_clock_delay(struct bwi_softc *);
288int bwi_ioctl(struct ifnet *, u_long, caddr_t);
289void bwi_start(struct ifnet *);
290void bwi_watchdog(struct ifnet *);
291void bwi_newstate_begin(struct bwi_softc *, enum ieee80211_state);
292void bwi_init_statechg(struct bwi_softc *, int);
293int bwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
294int bwi_media_change(struct ifnet *);
295void bwi_iter_func(void *, struct ieee80211_node *);
296void bwi_amrr_timeout(void *);
297void bwi_newassoc(struct ieee80211com *, struct ieee80211_node *,
298 int);
299struct ieee80211_node
300 *bwi_node_alloc(struct ieee80211com *ic);
301int bwi_dma_alloc(struct bwi_softc *);
302void bwi_dma_free(struct bwi_softc *);
303int bwi_dma_ring_alloc(struct bwi_softc *,
304 struct bwi_ring_data *, bus_size_t, uint32_t);
305int bwi_dma_txstats_alloc(struct bwi_softc *, uint32_t,
306 bus_size_t);
307void bwi_dma_txstats_free(struct bwi_softc *);
308int bwi_dma_mbuf_create30(struct bwi_softc *);
309int bwi_dma_mbuf_create(struct bwi_softc *);
310void bwi_dma_mbuf_destroy(struct bwi_softc *, int, int);
311void bwi_enable_intrs(struct bwi_softc *, uint32_t);
312void bwi_disable_intrs(struct bwi_softc *, uint32_t);
313int bwi_init_tx_ring32(struct bwi_softc *, int);
314void bwi_init_rxdesc_ring32(struct bwi_softc *, uint32_t,
315 bus_addr_t, int, int);
316int bwi_init_rx_ring32(struct bwi_softc *);
317int bwi_init_txstats32(struct bwi_softc *);
318void bwi_setup_rx_desc32(struct bwi_softc *, int, bus_addr_t, int);
319void bwi_setup_tx_desc32(struct bwi_softc *, struct bwi_ring_data *,
320 int, bus_addr_t, int);
321int bwi_newbuf30(struct bwi_softc *, int, int);
322int bwi_newbuf(struct bwi_softc *, int, int);
323void bwi_set_addr_filter(struct bwi_softc *, uint16_t,
324 const uint8_t *);
325int bwi_set_chan(struct bwi_softc *, uint8_t);
326void bwi_next_scan(void *);
327int bwi_rxeof(struct bwi_softc *, int);
328int bwi_rxeof32(struct bwi_softc *);
329void bwi_reset_rx_ring32(struct bwi_softc *, uint32_t);
330void bwi_free_txstats32(struct bwi_softc *);
331void bwi_free_rx_ring32(struct bwi_softc *);
332void bwi_free_tx_ring32(struct bwi_softc *, int);
333uint8_t bwi_plcp2rate(uint32_t, enum ieee80211_phymode);
334void bwi_ofdm_plcp_header(uint32_t *, int, uint8_t);
335void bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *, int,
336 uint8_t);
337void bwi_plcp_header(void *, int, uint8_t);
338int bwi_encap(struct bwi_softc *, int, struct mbuf *,
339 struct ieee80211_node *);
340void bwi_start_tx32(struct bwi_softc *, uint32_t, int);
341void bwi_txeof_status32(struct bwi_softc *);
342void _bwi_txeof(struct bwi_softc *, uint16_t);
343void bwi_txeof_status(struct bwi_softc *, int);
344void bwi_txeof(struct bwi_softc *);
345int bwi_bbp_power_on(struct bwi_softc *, enum bwi_clock_mode);
346void bwi_bbp_power_off(struct bwi_softc *);
347int bwi_get_pwron_delay(struct bwi_softc *sc);
348int bwi_bus_attach(struct bwi_softc *);
349const char *bwi_regwin_name(const struct bwi_regwin *);
350int bwi_regwin_is_enabled(struct bwi_softc *, struct bwi_regwin *);
351uint32_t bwi_regwin_disable_bits(struct bwi_softc *);
352void bwi_regwin_enable(struct bwi_softc *, struct bwi_regwin *,
353 uint32_t);
354void bwi_regwin_disable(struct bwi_softc *, struct bwi_regwin *,
355 uint32_t);
356void bwi_set_bssid(struct bwi_softc *, const uint8_t *);
357void bwi_updateslot(struct ieee80211com *);
358void bwi_calibrate(void *);
359int bwi_calc_rssi(struct bwi_softc *,
360 const struct bwi_rxbuf_hdr *);
361uint8_t bwi_ack_rate(struct ieee80211_node *, uint8_t);
362uint16_t bwi_txtime(struct ieee80211com *, struct ieee80211_node *,
363 uint, uint8_t, uint32_t);
364enum bwi_modtype
365 bwi_rate2modtype(uint8_t);
366
367
368static 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
372static 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
394static 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
};
396static const uint16_t bwi_phy_noise_11g_rev1[] =
397 { BWI_PHY_NOISE_11G_REV10x013c, 0x01f5, 0x031a, 0x0631, 0x0001, 0x0001, 0x0001, 0x0001 };
398static const uint16_t bwi_phy_noise_11g[] =
399 { BWI_PHY_NOISE_11G0x5484, 0x3c40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
400static 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
};
402static 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
};
404static 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
};
406static 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
};
408static 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
};
410static 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
};
412static 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
423struct 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
450static 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
};
452static 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
457struct 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
468struct cfdriver bwi_cd = {
469 NULL((void *)0), "bwi", DV_IFNET
470};
471
472static 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
485static 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
507static 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
524const 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
532const 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
537const 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
565static const uint8_t bwi_zero_addr[IEEE80211_ADDR_LEN6];
566
567
568/* CODE */
569
570int
571bwi_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
700int
701bwi_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);
889fail:
890 return (error);
891}
892
893int
894bwi_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
917void
918bwi_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
929void
930bwi_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
943uint64_t
944bwi_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
960uint16_t
961bwi_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
977uint32_t
978bwi_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
1002void
1003bwi_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
1020void
1021bwi_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
1040int
1041bwi_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
1083int
1084bwi_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
1254void
1255bwi_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
1300void
1301bwi_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
1337int
1338bwi_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
1386void
1387bwi_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 }
1480back:
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
1486void
1487bwi_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
1551void
1552bwi_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
1618void
1619bwi_mac_detach(struct bwi_mac *mac)
1620{
1621 bwi_mac_fw_free(mac);
1622}
1623
1624int
1625bwi_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
1658int
1659bwi_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
1704int
1705bwi_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
1825back:
1826 return (0);
1827}
1828
1829void
1830bwi_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
1838int
1839bwi_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
1913out:
1914 return (error);
1915}
1916
1917int
1918bwi_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
1952int
1953bwi_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
1969int
1970bwi_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
2049int
2050bwi_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
2071void
2072bwi_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
2146void
2147bwi_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
2175void
2176bwi_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
2225void
2226bwi_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
2241void
2242bwi_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
2277int
2278bwi_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
2292int
2293bwi_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
2322int
2323bwi_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
2356void
2357bwi_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
2363void
2364bwi_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
2390int
2391bwi_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
2443void
2444bwi_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
2466int
2467bwi_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
2523void
2524bwi_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
2581void
2582bwi_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 */
2637void
2638bwi_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
2738calib:
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
2745void
2746bwi_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
2769void
2770bwi_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
2791void
2792bwi_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
2807void
2808bwi_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
2817uint16_t
2818bwi_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
2827int
2828bwi_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
2898void
2899bwi_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
2917int
2918bwi_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
2940void
2941bwi_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
2950void
2951bwi_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
2963void
2964bwi_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
2970int16_t
2971bwi_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
2977void
2978bwi_phy_init_11a(struct bwi_mac *mac)
2979{
2980 /* TODO: 11A */
2981}
2982
2983void
2984bwi_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
3096void
3097bwi_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
3108void
3109bwi_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
3177void
3178bwi_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
3278void
3279bwi_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
3418void
3419bwi_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 */
3552void
3553bwi_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
3633void
3634bwi_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
3686void
3687bwi_phy_clear_state(struct bwi_phy *phy)
3688{
3689 phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS(0x1);
3690}
3691
3692/* RF */
3693
3694int16_t
3695bwi_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
3708struct bwi_rf_lo *
3709bwi_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
3719int
3720bwi_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
3731void
3732bwi_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
3740uint16_t
3741bwi_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
3759int
3760bwi_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
3871void
3872bwi_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
3902void
3903bwi_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 }
4006loop1_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
4057void
4058bwi_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
4072void
4073bwi_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
4084void
4085bwi_rf_off_11bg(struct bwi_mac *mac)
4086{
4087 PHY_WRITE(mac, 0x15, 0xaa00)bwi_phy_write((mac), (0x15), (0xaa00));
4088}
4089
4090void
4091bwi_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
4097void
4098bwi_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
4120struct bwi_rf_lo *
4121bwi_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
4161void
4162bwi_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
4170void
4171bwi_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
4181int
4182bwi_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 */
4194uint16_t
4195bwi_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
4207uint16_t
4208bwi_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
4280void
4281bwi_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
4541uint16_t
4542bwi_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
4565int32_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 */
4578int
4579bwi_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
4615int
4616bwi_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");
4769back:
4770 DPRINTF(1, "%s: idle tssi0: %d\n",
4771 sc->sc_dev.dv_xname, rf->rf_idle_tssi0);
4772
4773 return (error);
4774}
4775
4776void
4777bwi_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(&regs, sizeof(regs))__builtin_bzero((&regs), (sizeof(regs)));
4796
4797 if (phy->phy_flags & BWI_PHY_F_LINKED0x2) {
4798 SAVE_PHY_REG(mac, &regs, 429)(&regs)->phy_429 = bwi_phy_read(((mac)), (0x429));
4799 SAVE_PHY_REG(mac, &regs, 802)(&regs)->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, &regs, 15)(&regs)->phy_15 = bwi_phy_read(((mac)), (0x15));
4810 SAVE_PHY_REG(mac, &regs, 2a)(&regs)->phy_2a = bwi_phy_read(((mac)), (0x2a));
4811 SAVE_PHY_REG(mac, &regs, 35)(&regs)->phy_35 = bwi_phy_read(((mac)), (0x35));
4812 SAVE_PHY_REG(mac, &regs, 60)(&regs)->phy_60 = bwi_phy_read(((mac)), (0x60));
4813 SAVE_RF_REG(mac, &regs, 43)(&regs)->rf_43 = bwi_rf_read(((mac)), (0x43));
4814 SAVE_RF_REG(mac, &regs, 7a)(&regs)->rf_7a = bwi_rf_read(((mac)), (0x7a));
4815 SAVE_RF_REG(mac, &regs, 52)(&regs)->rf_52 = bwi_rf_read(((mac)), (0x52));
4816 if (phy->phy_flags & BWI_PHY_F_LINKED0x2) {
4817 SAVE_PHY_REG(mac, &regs, 811)(&regs)->phy_811 = bwi_phy_read(((mac)), (0x811));
4818 SAVE_PHY_REG(mac, &regs, 812)(&regs)->phy_812 = bwi_phy_read(((mac)), (0x812));
4819 SAVE_PHY_REG(mac, &regs, 814)(&regs)->phy_814 = bwi_phy_read(((mac)), (0x814));
4820 SAVE_PHY_REG(mac, &regs, 815)(&regs)->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, &regs, 15)bwi_phy_write(((mac)), (0x15), ((&regs)->phy_15));
4886 RESTORE_PHY_REG(mac, &regs, 2a)bwi_phy_write(((mac)), (0x2a), ((&regs)->phy_2a));
4887 RESTORE_PHY_REG(mac, &regs, 35)bwi_phy_write(((mac)), (0x35), ((&regs)->phy_35));
4888 RESTORE_PHY_REG(mac, &regs, 60)bwi_phy_write(((mac)), (0x60), ((&regs)->phy_60));
4889
4890 RESTORE_RF_REG(mac, &regs, 43)bwi_rf_write(((mac)), (0x43), ((&regs)->rf_43));
4891 RESTORE_RF_REG(mac, &regs, 7a)bwi_rf_write(((mac)), (0x7a), ((&regs)->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, &regs, 811)bwi_phy_write(((mac)), (0x811), ((&regs)->phy_811));
4901 RESTORE_PHY_REG(mac, &regs, 812)bwi_phy_write(((mac)), (0x812), ((&regs)->phy_812));
4902 RESTORE_PHY_REG(mac, &regs, 814)bwi_phy_write(((mac)), (0x814), ((&regs)->phy_814));
4903 RESTORE_PHY_REG(mac, &regs, 815)bwi_phy_write(((mac)), (0x815), ((&regs)->phy_815));
4904 RESTORE_PHY_REG(mac, &regs, 429)bwi_phy_write(((mac)), (0x429), ((&regs)->phy_429));
4905 RESTORE_PHY_REG(mac, &regs, 802)bwi_phy_write(((mac)), (0x802), ((&regs)->phy_802));
4906 }
4907
4908 bwi_rf_set_chan(mac, orig_chan, 1);
4909}
4910
4911uint32_t
4912bwi_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
4945uint16_t
4946bwi_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
4972uint8_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
5069void
5070bwi_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
5158void
5159bwi_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
5270void
5271bwi_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
5423void
5424bwi_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
5600void
5601bwi_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
5620void
5621bwi_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
5640void
5641bwi_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
5680int32_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
5698void
5699bwi_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
5737void
5738bwi_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
5762void
5763bwi_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
5786void
5787bwi_rf_on_11a(struct bwi_mac *mac)
5788{
5789 /* TODO: 11A */
5790}
5791
5792void
5793bwi_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
5807void
5808bwi_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,