Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name bwi.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -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 -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/lib/clang/13.0.0 -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/swsmu -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/powerplay -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/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 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 -D CONFIG_DRM_AMD_DC_DCN3_0 -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 -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 /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/ic/bwi.c
1/* $OpenBSD: bwi.c,v 1.132 2022/01/09 05:42:38 jsg 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_set_maxlen(&ifp->if_snd, IFQ_MAXLEN)((&ifp->if_snd)->ifq_maxlen = (256));
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;
Value stored to 'sc' is never read
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,bwi_memobj_write_2(((mac)), ((0x1)), ((0x54)), ((bwi_memobj_read_2
(((mac)), ((0x1)), ((0x54))) & (0xfc3f)) | (val)))
5866 0xfc3f, val)bwi_memobj_write_2(((mac)), ((0x1)), ((0x54)), ((bwi_memobj_read_2
(((mac)), ((0x1)), ((0x54))) & (0xfc3f)) | (val)))
;
5867 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_ACK,bwi_memobj_write_2(((mac)), ((0x1)), ((0x22)), ((bwi_memobj_read_2
(((mac)), ((0x1)), ((0x22))) & (0xfc3f)) | (val)))
5868 0xfc3f, val)bwi_memobj_write_2(((mac)), ((0x1)), ((0x22)), ((bwi_memobj_read_2
(((mac)), ((0x1)), ((0x22))) & (0xfc3f)) | (val)))
;
5869 MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_PROBE_RESP,bwi_memobj_write_2(((mac)), ((0x1)), ((0x188)), ((bwi_memobj_read_2
(((mac)), ((0x1)), ((0x188))) & (0xfc3f)) | (val)))
5870 0xfc3f, val)bwi_memobj_write_2(((mac)), ((0x1)), ((0x188)), ((bwi_memobj_read_2
(((mac)), ((0x1)), ((0x188))) & (0xfc3f)) | (val)))
;
5871
5872 /* XXX what's these */
5873 if (phy->phy_mode == IEEE80211_MODE_11B)
5874 CSR_SETBITS_2(sc, 0x5e, 0x4)((((sc))->sc_mem_bt)->write_2((((sc))->sc_mem_bh), (
((0x5e))), ((((((sc))->sc_mem_bt)->read_2((((sc))->sc_mem_bh
), (((0x5e))))) | (0x4)))))
;
5875
5876 CSR_WRITE_4(sc, 0x100, 0x1000000)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x100
)), ((0x1000000))))
;
5877 if (mac->mac_revmac_regwin.rw_rev < 5)
5878 CSR_WRITE_4(sc, 0x10c, 0x1000000)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x10c
)), ((0x1000000))))
;
5879
5880 mac->mac_rf.rf_ant_mode = ant_mode;
5881}
5882
5883int
5884bwi_rf_get_latest_tssi(struct bwi_mac *mac, int8_t tssi[], uint16_t ofs)
5885{
5886 int i;
5887
5888 for (i = 0; i < 4; ) {
5889 uint16_t val;
5890
5891 val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs + i)bwi_memobj_read_2((mac), (0x1), (ofs + i));
5892 tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_LO_TSSI_MASK)(((val) & (0x00ff)) / ((((0x00ff) - 1) & (0x00ff)) ^ (
0x00ff)))
;
5893 tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_HI_TSSI_MASK)(((val) & (0xff00)) / ((((0xff00) - 1) & (0xff00)) ^ (
0xff00)))
;
5894 }
5895
5896 for (i = 0; i < 4; ++i) {
5897 if (tssi[i] == BWI_INVALID_TSSI0x7f)
5898 return (EINVAL22);
5899 }
5900
5901 return (0);
5902}
5903
5904int
5905bwi_rf_tssi2dbm(struct bwi_mac *mac, int8_t tssi, int8_t *txpwr)
5906{
5907 struct bwi_rf *rf = &mac->mac_rf;
5908 int pwr_idx;
5909
5910 pwr_idx = rf->rf_idle_tssi + (int)tssi - rf->rf_base_tssi;
5911#if 0
5912 if (pwr_idx < 0 || pwr_idx >= BWI_TSSI_MAX64)
5913 return EINVAL22;
5914#else
5915 if (pwr_idx < 0)
5916 pwr_idx = 0;
5917 else if (pwr_idx >= BWI_TSSI_MAX64)
5918 pwr_idx = BWI_TSSI_MAX64 - 1;
5919#endif
5920 *txpwr = rf->rf_txpower_map[pwr_idx];
5921
5922 return (0);
5923}
5924
5925int
5926bwi_rf_calc_rssi_bcm2050(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
5927{
5928 uint16_t flags1, flags3;
5929 int rssi, lna_gain;
5930
5931 rssi = hdr->rxh_rssi;
5932 flags1 = letoh16(hdr->rxh_flags1)((__uint16_t)(hdr->rxh_flags1));
5933 flags3 = letoh16(hdr->rxh_flags3)((__uint16_t)(hdr->rxh_flags3));
5934
5935#define NEW_BCM2050_RSSI
5936#ifdef NEW_BCM2050_RSSI
5937 if (flags1 & BWI_RXH_F1_OFDM(1 << 0)) {
5938 if (rssi > 127)
5939 rssi -= 256;
5940 if (flags3 & BWI_RXH_F3_BCM2050_RSSI(1 << 10))
5941 rssi += 17;
5942 else
5943 rssi -= 4;
5944 return (rssi);
5945 }
5946
5947 if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI(1 << 3)) {
5948 struct bwi_rf *rf = &mac->mac_rf;
5949
5950 if (rssi >= BWI_NRSSI_TBLSZ64)
5951 rssi = BWI_NRSSI_TBLSZ64 - 1;
5952
5953 rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128;
5954 rssi -= 67;
5955 } else {
5956 rssi = ((31 - rssi) * -149) / 128;
5957 rssi -= 68;
5958 }
5959
5960 if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G)
5961 return (rssi);
5962
5963 if (flags3 & BWI_RXH_F3_BCM2050_RSSI(1 << 10))
5964 rssi += 20;
5965
5966 lna_gain = __SHIFTOUT(letoh16(hdr->rxh_phyinfo),(((((__uint16_t)(hdr->rxh_phyinfo))) & ((3 << 14
))) / (((((3 << 14)) - 1) & ((3 << 14))) ^ ((
3 << 14))))
5967 BWI_RXH_PHYINFO_LNAGAIN)(((((__uint16_t)(hdr->rxh_phyinfo))) & ((3 << 14
))) / (((((3 << 14)) - 1) & ((3 << 14))) ^ ((
3 << 14))))
;
5968 DPRINTF(3, "lna_gain %d, phyinfo 0x%04x\n",
5969 lna_gain, letoh16(hdr->rxh_phyinfo));
5970 switch (lna_gain) {
5971 case 0:
5972 rssi += 27;
5973 break;
5974 case 1:
5975 rssi += 6;
5976 break;
5977 case 2:
5978 rssi += 12;
5979 break;
5980 case 3:
5981 /*
5982 * XXX
5983 * According to v3 spec, we should do _nothing_ here,
5984 * but it seems that the result RSSI will be too low
5985 * (relative to what ath(4) says). Raise it a little
5986 * bit.
5987 */
5988 rssi += 5;
5989 break;
5990 default:
5991 panic("impossible lna gain %d", lna_gain);
5992 }
5993#else /* !NEW_BCM2050_RSSI */
5994 lna_gain = 0; /* shut up gcc warning */
5995
5996 if (flags1 & BWI_RXH_F1_OFDM(1 << 0)) {
5997 if (rssi > 127)
5998 rssi -= 256;
5999 rssi = (rssi * 73) / 64;
6000
6001 if (flags3 & BWI_RXH_F3_BCM2050_RSSI(1 << 10))
6002 rssi += 25;
6003 else
6004 rssi -= 3;
6005 return (rssi);
6006 }
6007
6008 if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI(1 << 3)) {
6009 struct bwi_rf *rf = &mac->mac_rf;
6010
6011 if (rssi >= BWI_NRSSI_TBLSZ64)
6012 rssi = BWI_NRSSI_TBLSZ64 - 1;
6013
6014 rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128;
6015 rssi -= 57;
6016 } else {
6017 rssi = ((31 - rssi) * -149) / 128;
6018 rssi -= 68;
6019 }
6020
6021 if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G)
6022 return (rssi);
6023
6024 if (flags3 & BWI_RXH_F3_BCM2050_RSSI(1 << 10))
6025 rssi += 25;
6026#endif /* NEW_BCM2050_RSSI */
6027 return (rssi);
6028}
6029
6030int
6031bwi_rf_calc_rssi_bcm2053(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
6032{
6033 uint16_t flags1;
6034 int rssi;
6035
6036 rssi = (((int)hdr->rxh_rssi - 11) * 103) / 64;
6037
6038 flags1 = letoh16(hdr->rxh_flags1)((__uint16_t)(hdr->rxh_flags1));
6039 if (flags1 & BWI_RXH_F1_BCM2053_RSSI(1 << 14))
6040 rssi -= 109;
6041 else
6042 rssi -= 83;
6043
6044 return (rssi);
6045}
6046
6047int
6048bwi_rf_calc_rssi_bcm2060(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
6049{
6050 int rssi;
6051
6052 rssi = hdr->rxh_rssi;
6053 if (rssi > 127)
6054 rssi -= 256;
6055
6056 return (rssi);
6057}
6058
6059uint16_t
6060bwi_rf_lo_measure_11b(struct bwi_mac *mac)
6061{
6062 uint16_t val;
6063 int i;
6064
6065 val = 0;
6066 for (i = 0; i < 10; ++i) {
6067 PHY_WRITE(mac, 0x15, 0xafa0)bwi_phy_write((mac), (0x15), (0xafa0));
6068 DELAY(1)(*delay_func)(1);
6069 PHY_WRITE(mac, 0x15, 0xefa0)bwi_phy_write((mac), (0x15), (0xefa0));
6070 DELAY(10)(*delay_func)(10);
6071 PHY_WRITE(mac, 0x15, 0xffa0)bwi_phy_write((mac), (0x15), (0xffa0));
6072 DELAY(40)(*delay_func)(40);
6073
6074 val += PHY_READ(mac, 0x2c)bwi_phy_read((mac), (0x2c));
6075 }
6076
6077 return (val);
6078}
6079
6080void
6081bwi_rf_lo_update_11b(struct bwi_mac *mac)
6082{
6083 struct bwi_softc *sc = mac->mac_sc;
6084 struct bwi_rf *rf = &mac->mac_rf;
6085 struct rf_saveregs regs;
6086 uint16_t rf_val, phy_val, min_val, val;
6087 uint16_t rf52, bphy_ctrl;
6088 int i;
6089
6090 DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
6091
6092 bzero(&regs, sizeof(regs))__builtin_bzero((&regs), (sizeof(regs)));
6093 bphy_ctrl = 0;
6094
6095 /*
6096 * Save RF/PHY registers for later restoration
6097 */
6098 SAVE_PHY_REG(mac, &regs, 15)(&regs)->phy_15 = bwi_phy_read(((mac)), (0x15));
6099 rf52 = RF_READ(mac, 0x52)bwi_rf_read((mac), (0x52)) & 0xfff0;
6100 if (rf->rf_type == BWI_RF_T_BCM20500x2050) {
6101 SAVE_PHY_REG(mac, &regs, 0a)(&regs)->phy_0a = bwi_phy_read(((mac)), (0x0a));
6102 SAVE_PHY_REG(mac, &regs, 2a)(&regs)->phy_2a = bwi_phy_read(((mac)), (0x2a));
6103 SAVE_PHY_REG(mac, &regs, 35)(&regs)->phy_35 = bwi_phy_read(((mac)), (0x35));
6104 SAVE_PHY_REG(mac, &regs, 03)(&regs)->phy_03 = bwi_phy_read(((mac)), (0x03));
6105 SAVE_PHY_REG(mac, &regs, 01)(&regs)->phy_01 = bwi_phy_read(((mac)), (0x01));
6106 SAVE_PHY_REG(mac, &regs, 30)(&regs)->phy_30 = bwi_phy_read(((mac)), (0x30));
6107
6108 SAVE_RF_REG(mac, &regs, 43)(&regs)->rf_43 = bwi_rf_read(((mac)), (0x43));
6109 SAVE_RF_REG(mac, &regs, 7a)(&regs)->rf_7a = bwi_rf_read(((mac)), (0x7a));
6110
6111 bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x03ec
))))
;
6112
6113 SAVE_RF_REG(mac, &regs, 52)(&regs)->rf_52 = bwi_rf_read(((mac)), (0x52));
6114 regs.rf_52 &= 0xf0;
6115
6116 PHY_WRITE(mac, 0x30, 0xff)bwi_phy_write((mac), (0x30), (0xff));
6117 CSR_WRITE_2(sc, BWI_PHY_CTRL, 0x3f3f)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03fc
)), ((0x3f3f))))
;
6118 PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f)bwi_phy_write((mac), (0x35), (regs.phy_35 & 0xff7f));
6119 RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0)bwi_rf_write((mac), (0x7a), (regs.rf_7a & 0xfff0));
6120 }
6121
6122 PHY_WRITE(mac, 0x15, 0xb000)bwi_phy_write((mac), (0x15), (0xb000));
6123
6124 if (rf->rf_type == BWI_RF_T_BCM20500x2050) {
6125 PHY_WRITE(mac, 0x2b, 0x203)bwi_phy_write((mac), (0x2b), (0x203));
6126 PHY_WRITE(mac, 0x2a, 0x8a3)bwi_phy_write((mac), (0x2a), (0x8a3));
6127 } else {
6128 PHY_WRITE(mac, 0x2b, 0x1402)bwi_phy_write((mac), (0x2b), (0x1402));
6129 }
6130
6131 /*
6132 * Setup RF signal
6133 */
6134 rf_val = 0;
6135 min_val = 65535;
6136
6137 for (i = 0; i < 4; ++i) {
6138 RF_WRITE(mac, 0x52, rf52 | i)bwi_rf_write((mac), (0x52), (rf52 | i));
6139 bwi_rf_lo_measure_11b(mac); /* Ignore return value */
6140 }
6141 for (i = 0; i < 10; ++i) {
6142 RF_WRITE(mac, 0x52, rf52 | i)bwi_rf_write((mac), (0x52), (rf52 | i));
6143
6144 val = bwi_rf_lo_measure_11b(mac) / 10;
6145 if (val < min_val) {
6146 min_val = val;
6147 rf_val = i;
6148 }
6149 }
6150 RF_WRITE(mac, 0x52, rf52 | rf_val)bwi_rf_write((mac), (0x52), (rf52 | rf_val));
6151
6152 /*
6153 * Setup PHY signal
6154 */
6155 phy_val = 0;
6156 min_val = 65535;
6157
6158 for (i = -4; i < 5; i += 2) {
6159 int j;
6160
6161 for (j = -4; j < 5; j += 2) {
6162 uint16_t phy2f;
6163
6164 phy2f = (0x100 * i) + j;
6165 if (j < 0)
6166 phy2f += 0x100;
6167 PHY_WRITE(mac, 0x2f, phy2f)bwi_phy_write((mac), (0x2f), (phy2f));
6168
6169 val = bwi_rf_lo_measure_11b(mac) / 10;
6170 if (val < min_val) {
6171 min_val = val;
6172 phy_val = phy2f;
6173 }
6174 }
6175 }
6176 PHY_WRITE(mac, 0x2f, phy_val + 0x101)bwi_phy_write((mac), (0x2f), (phy_val + 0x101));
6177
6178 /*
6179 * Restore saved RF/PHY registers
6180 */
6181 if (rf->rf_type == BWI_RF_T_BCM20500x2050) {
6182 RESTORE_PHY_REG(mac, &regs, 0a)bwi_phy_write(((mac)), (0x0a), ((&regs)->phy_0a));
6183 RESTORE_PHY_REG(mac, &regs, 2a)bwi_phy_write(((mac)), (0x2a), ((&regs)->phy_2a));
6184 RESTORE_PHY_REG(mac, &regs, 35)bwi_phy_write(((mac)), (0x35), ((&regs)->phy_35));
6185 RESTORE_PHY_REG(mac, &regs, 03)bwi_phy_write(((mac)), (0x03), ((&regs)->phy_03));
6186 RESTORE_PHY_REG(mac, &regs, 01)bwi_phy_write(((mac)), (0x01), ((&regs)->phy_01));
6187 RESTORE_PHY_REG(mac, &regs, 30)bwi_phy_write(((mac)), (0x30), ((&regs)->phy_30));
6188
6189 RESTORE_RF_REG(mac, &regs, 43)bwi_rf_write(((mac)), (0x43), ((&regs)->rf_43));
6190 RESTORE_RF_REG(mac, &regs, 7a)bwi_rf_write(((mac)), (0x7a), ((&regs)->rf_7a));
6191
6192 RF_FILT_SETBITS(mac, 0x52, 0xf, regs.rf_52)bwi_rf_write(((mac)), ((0x52)), ((bwi_rf_read(((mac)), ((0x52
))) & (0xf)) | (regs.rf_52)))
;
6193
6194 CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x03ec
)), ((bphy_ctrl))))
;
6195 }
6196 RESTORE_PHY_REG(mac, &regs, 15)bwi_phy_write(((mac)), (0x15), ((&regs)->phy_15));
6197
6198 bwi_rf_workaround(mac, rf->rf_curchan);
6199}
6200
6201/* INTERFACE */
6202
6203uint16_t
6204bwi_read_sprom(struct bwi_softc *sc, uint16_t ofs)
6205{
6206 return (CSR_READ_2(sc, ofs + BWI_SPROM_START)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((ofs +
0x1000))))
);
6207}
6208
6209void
6210bwi_setup_desc32(struct bwi_softc *sc, struct bwi_desc32 *desc_array,
6211 int ndesc, int desc_idx, bus_addr_t paddr, int buf_len, int tx)
6212{
6213 struct bwi_desc32 *desc = &desc_array[desc_idx];
6214 uint32_t ctrl, addr, addr_hi, addr_lo;
6215
6216 if (sc->sc_bus_space == BWI_BUS_SPACE_30BIT && paddr >= 0x40000000)
6217 panic("bad paddr 0x%lx", (long)paddr);
6218
6219 addr_lo = __SHIFTOUT(paddr, BWI_DESC32_A_ADDR_MASK)(((paddr) & (0x3fffffff)) / ((((0x3fffffff) - 1) & (0x3fffffff
)) ^ (0x3fffffff)))
;
6220 addr_hi = __SHIFTOUT(paddr, BWI_DESC32_A_FUNC_MASK)(((paddr) & (0xc0000000)) / ((((0xc0000000) - 1) & (0xc0000000
)) ^ (0xc0000000)))
;
6221
6222 addr = __SHIFTIN(addr_lo, BWI_DESC32_A_ADDR_MASK)((addr_lo) * ((((0x3fffffff) - 1) & (0x3fffffff)) ^ (0x3fffffff
)))
|
6223 __SHIFTIN(BWI_DESC32_A_FUNC_TXRX, BWI_DESC32_A_FUNC_MASK)((0x1) * ((((0xc0000000) - 1) & (0xc0000000)) ^ (0xc0000000
)))
;
6224
6225 ctrl = __SHIFTIN(buf_len, BWI_DESC32_C_BUFLEN_MASK)((buf_len) * ((((0x00001fff) - 1) & (0x00001fff)) ^ (0x00001fff
)))
|
6226 __SHIFTIN(addr_hi, BWI_DESC32_C_ADDRHI_MASK)((addr_hi) * ((((0x00030000) - 1) & (0x00030000)) ^ (0x00030000
)))
;
6227 if (desc_idx == ndesc - 1)
6228 ctrl |= BWI_DESC32_C_EOR(1 << 28);
6229 if (tx) {
6230 /* XXX */
6231 ctrl |= BWI_DESC32_C_FRAME_START(1U << 31) |
6232 BWI_DESC32_C_FRAME_END(1 << 30) |
6233 BWI_DESC32_C_INTR(1 << 29);
6234 }
6235
6236 desc->addr = htole32(addr)((__uint32_t)(addr));
6237 desc->ctrl = htole32(ctrl)((__uint32_t)(ctrl));
6238}
6239
6240void
6241bwi_power_on(struct bwi_softc *sc, int with_pll)
6242{
6243 uint32_t gpio_in, gpio_out, gpio_en, status;
6244
6245 DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
6246
6247 gpio_in = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN0x000000b0);
6248 if (gpio_in & BWI_PCIM_GPIO_PWR_ON(1 << 6))
6249 goto back;
6250
6251 gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT0x000000b4);
6252 gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE0x000000b8);
6253
6254 gpio_out |= BWI_PCIM_GPIO_PWR_ON(1 << 6);
6255 gpio_en |= BWI_PCIM_GPIO_PWR_ON(1 << 6);
6256 if (with_pll) {
6257 /* Turn off PLL first */
6258 gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF(1 << 7);
6259 gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF(1 << 7);
6260 }
6261
6262 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT0x000000b4, gpio_out);
6263 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE0x000000b8, gpio_en);
6264 DELAY(1000)(*delay_func)(1000);
6265
6266 if (with_pll) {
6267 /* Turn on PLL */
6268 gpio_out &= ~BWI_PCIM_GPIO_PLL_PWR_OFF(1 << 7);
6269 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT0x000000b4, gpio_out);
6270 DELAY(5000)(*delay_func)(5000);
6271 }
6272
6273back:
6274 /* Clear "Signaled Target Abort" */
6275 status = (sc->sc_conf_read)(sc, PCI_COMMAND_STATUS_REG0x04);
6276 status &= ~PCI_STATUS_TARGET_TARGET_ABORT0x08000000;
6277 (sc->sc_conf_write)(sc, PCI_COMMAND_STATUS_REG0x04, status);
6278}
6279
6280int
6281bwi_power_off(struct bwi_softc *sc, int with_pll)
6282{
6283 uint32_t gpio_out, gpio_en;
6284
6285 DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
6286
6287 (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_IN0x000000b0); /* dummy read */
6288 gpio_out = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT0x000000b4);
6289 gpio_en = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_ENABLE0x000000b8);
6290
6291 gpio_out &= ~BWI_PCIM_GPIO_PWR_ON(1 << 6);
6292 gpio_en |= BWI_PCIM_GPIO_PWR_ON(1 << 6);
6293 if (with_pll) {
6294 gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF(1 << 7);
6295 gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF(1 << 7);
6296 }
6297
6298 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_OUT0x000000b4, gpio_out);
6299 (sc->sc_conf_write)(sc, BWI_PCIR_GPIO_ENABLE0x000000b8, gpio_en);
6300
6301 return (0);
6302}
6303
6304int
6305bwi_regwin_switch(struct bwi_softc *sc, struct bwi_regwin *rw,
6306 struct bwi_regwin **old_rw)
6307{
6308 int error;
6309
6310 if (old_rw != NULL((void *)0))
6311 *old_rw = NULL((void *)0);
6312
6313 if (!BWI_REGWIN_EXIST(rw)((rw)->rw_flags & 0x1))
6314 return (EINVAL22);
6315
6316 if (sc->sc_cur_regwin != rw) {
6317 error = bwi_regwin_select(sc, rw->rw_id);
6318 if (error) {
6319 printf("%s: can't select regwin %d\n",
6320 sc->sc_dev.dv_xname, rw->rw_id);
6321 return (error);
6322 }
6323 }
6324
6325 if (old_rw != NULL((void *)0))
6326 *old_rw = sc->sc_cur_regwin;
6327 sc->sc_cur_regwin = rw;
6328
6329 return (0);
6330}
6331
6332int
6333bwi_regwin_select(struct bwi_softc *sc, int id)
6334{
6335 uint32_t win = BWI_PCIM_REGWIN(id)(((id) * 0x1000) + 0x18000000);
6336 int i;
6337
6338#define RETRY_MAX 50
6339 for (i = 0; i < RETRY_MAX; ++i) {
6340 (sc->sc_conf_write)(sc, BWI_PCIR_SEL_REGWIN0x00000080, win);
6341 if ((sc->sc_conf_read)(sc, BWI_PCIR_SEL_REGWIN0x00000080) == win)
6342 return (0);
6343 DELAY(10)(*delay_func)(10);
6344 }
6345#undef RETRY_MAX
6346
6347 return (ENXIO6);
6348}
6349
6350void
6351bwi_regwin_info(struct bwi_softc *sc, uint16_t *type, uint8_t *rev)
6352{
6353 uint32_t val;
6354
6355 val = CSR_READ_4(sc, BWI_ID_HI)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000ffc
))))
;
6356 *type = BWI_ID_HI_REGWIN_TYPE(val)(((val) & 0x8ff0) >> 4);
6357 *rev = BWI_ID_HI_REGWIN_REV(val)(((val) & 0xf) | (((val) & 0x7000) >> 8));
6358
6359 DPRINTF(1, "%s: regwin: type 0x%03x, rev %d, vendor 0x%04x\n",
6360 sc->sc_dev.dv_xname,
6361 *type, *rev, __SHIFTOUT(val, BWI_ID_HI_REGWIN_VENDOR_MASK));
6362}
6363
6364void
6365bwi_led_attach(struct bwi_softc *sc)
6366{
6367 const uint8_t *led_act = NULL((void *)0);
6368 uint16_t gpio, val[BWI_LED_MAX4];
6369 int i;
6370
6371 for (i = 0; i < nitems(bwi_vendor_led_act)(sizeof((bwi_vendor_led_act)) / sizeof((bwi_vendor_led_act)[0
]))
; ++i) {
6372 if (sc->sc_pci_subvid == bwi_vendor_led_act[i].vid) {
6373 led_act = bwi_vendor_led_act[i].led_act;
6374 break;
6375 }
6376 }
6377 if (led_act == NULL((void *)0))
6378 led_act = bwi_default_led_act;
6379
6380 gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO010x64);
6381 val[0] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_0)(((gpio) & (0x00ff)) / ((((0x00ff) - 1) & (0x00ff)) ^
(0x00ff)))
;
6382 val[1] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_1)(((gpio) & (0xff00)) / ((((0xff00) - 1) & (0xff00)) ^
(0xff00)))
;
6383
6384 gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO230x0066);
6385 val[2] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_2)(((gpio) & (0x00ff)) / ((((0x00ff) - 1) & (0x00ff)) ^
(0x00ff)))
;
6386 val[3] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_3)(((gpio) & (0xff00)) / ((((0xff00) - 1) & (0xff00)) ^
(0xff00)))
;
6387
6388 for (i = 0; i < BWI_LED_MAX4; ++i) {
6389 struct bwi_led *led = &sc->sc_leds[i];
6390
6391 if (val[i] == 0xff) {
6392 led->l_act = led_act[i];
6393 } else {
6394 if (val[i] & BWI_LED_ACT_LOW(1 << 7))
6395 led->l_flags |= BWI_LED_F_ACTLOW0x1;
6396 led->l_act = __SHIFTOUT(val[i], BWI_LED_ACT_MASK)(((val[i]) & (0x7f)) / ((((0x7f) - 1) & (0x7f)) ^ (0x7f
)))
;
6397 }
6398 led->l_mask = (1 << i);
6399
6400 if (led->l_act == BWI_LED_ACT_BLINK_SLOW7 ||
6401 led->l_act == BWI_LED_ACT_BLINK_POLL8 ||
6402 led->l_act == BWI_LED_ACT_BLINK2) {
6403 led->l_flags |= BWI_LED_F_BLINK0x2;
6404 if (led->l_act == BWI_LED_ACT_BLINK_POLL8)
6405 led->l_flags |= BWI_LED_F_POLLABLE0x4;
6406 else if (led->l_act == BWI_LED_ACT_BLINK_SLOW7)
6407 led->l_flags |= BWI_LED_F_SLOW0x8;
6408
6409 if (sc->sc_blink_led == NULL((void *)0)) {
6410 sc->sc_blink_led = led;
6411 if (led->l_flags & BWI_LED_F_SLOW0x8)
6412 BWI_LED_SLOWDOWN(sc->sc_led_idle)(sc->sc_led_idle) = (((sc->sc_led_idle) * 3) / 2);
6413 }
6414 }
6415
6416 DPRINTF(1, "%s: %dth led, act %d, lowact %d\n",
6417 sc->sc_dev.dv_xname, i, led->l_act,
6418 led->l_flags & BWI_LED_F_ACTLOW);
6419 }
6420 timeout_set(&sc->sc_led_blink_next_ch, bwi_led_blink_next, sc);
6421 timeout_set(&sc->sc_led_blink_end_ch, bwi_led_blink_end, sc);
6422}
6423
6424uint16_t
6425bwi_led_onoff(struct bwi_led *led, uint16_t val, int on)
6426{
6427 if (led->l_flags & BWI_LED_F_ACTLOW0x1)
6428 on = !on;
6429 if (on)
6430 val |= led->l_mask;
6431 else
6432 val &= ~led->l_mask;
6433
6434 return (val);
6435}
6436
6437void
6438bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate)
6439{
6440 struct ieee80211com *ic = &sc->sc_ic;
6441 uint16_t val;
6442 int i;
6443
6444 if (nstate == IEEE80211_S_INIT) {
6445 timeout_del(&sc->sc_led_blink_next_ch);
6446 timeout_del(&sc->sc_led_blink_end_ch);
6447 sc->sc_led_blinking = 0;
6448 }
6449
6450 if ((ic->ic_ific_ac.ac_if.if_flags & IFF_RUNNING0x40) == 0)
6451 return;
6452
6453 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x049c
))))
;
6454 for (i = 0; i < BWI_LED_MAX4; ++i) {
6455 struct bwi_led *led = &sc->sc_leds[i];
6456 int on;
6457
6458 if (led->l_act == BWI_LED_ACT_UNKN9 ||
6459 led->l_act == BWI_LED_ACT_NULL11)
6460 continue;
6461
6462 if ((led->l_flags & BWI_LED_F_BLINK0x2) &&
6463 nstate != IEEE80211_S_INIT)
6464 continue;
6465
6466 switch (led->l_act) {
6467 case BWI_LED_ACT_ON1: /* Always on */
6468 on = 1;
6469 break;
6470 case BWI_LED_ACT_OFF0: /* Always off */
6471 case BWI_LED_ACT_5GHZ4: /* TODO: 11A */
6472 on = 0;
6473 break;
6474 default:
6475 on = 1;
6476 switch (nstate) {
6477 case IEEE80211_S_INIT:
6478 on = 0;
6479 break;
6480 case IEEE80211_S_RUN:
6481 if (led->l_act == BWI_LED_ACT_11G6 &&
6482 ic->ic_curmode != IEEE80211_MODE_11G)
6483 on = 0;
6484 break;
6485 default:
6486 if (led->l_act == BWI_LED_ACT_ASSOC10)
6487 on = 0;
6488 break;
6489 }
6490 break;
6491 }
6492
6493 val = bwi_led_onoff(led, val, on);
6494 }
6495 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x049c
)), ((val))))
;
6496}
6497
6498void
6499bwi_led_event(struct bwi_softc *sc, int event)
6500{
6501 struct bwi_led *led = sc->sc_blink_led;
6502 int rate;
6503
6504 if (event == BWI_LED_EVENT_POLL0) {
6505 if ((led->l_flags & BWI_LED_F_POLLABLE0x4) == 0)
6506 return;
6507 if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
6508 return;
6509 }
6510
6511 sc->sc_led_ticks = ticks;
6512 if (sc->sc_led_blinking)
6513 return;
6514
6515 switch (event) {
6516 case BWI_LED_EVENT_RX2:
6517 rate = sc->sc_rx_rate;
6518 break;
6519 case BWI_LED_EVENT_TX1:
6520 rate = sc->sc_tx_rate;
6521 break;
6522 case BWI_LED_EVENT_POLL0:
6523 rate = 0;
6524 break;
6525 default:
6526 panic("unknown LED event %d", event);
6527 break;
6528 }
6529 bwi_led_blink_start(sc, bwi_led_duration[rate].on_dur,
6530 bwi_led_duration[rate].off_dur);
6531}
6532
6533void
6534bwi_led_blink_start(struct bwi_softc *sc, int on_dur, int off_dur)
6535{
6536 struct bwi_led *led = sc->sc_blink_led;
6537 uint16_t val;
6538
6539 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x049c
))))
;
6540 val = bwi_led_onoff(led, val, 1);
6541 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x049c
)), ((val))))
;
6542
6543 if (led->l_flags & BWI_LED_F_SLOW0x8) {
6544 BWI_LED_SLOWDOWN(on_dur)(on_dur) = (((on_dur) * 3) / 2);
6545 BWI_LED_SLOWDOWN(off_dur)(off_dur) = (((off_dur) * 3) / 2);
6546 }
6547
6548 sc->sc_led_blinking = 1;
6549 sc->sc_led_blink_offdur = off_dur;
6550
6551 timeout_add(&sc->sc_led_blink_next_ch, on_dur);
6552}
6553
6554void
6555bwi_led_blink_next(void *xsc)
6556{
6557 struct bwi_softc *sc = xsc;
6558 uint16_t val;
6559
6560 val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL)(((sc)->sc_mem_bt)->read_2(((sc)->sc_mem_bh), ((0x049c
))))
;
6561 val = bwi_led_onoff(sc->sc_blink_led, val, 0);
6562 CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x049c
)), ((val))))
;
6563
6564 timeout_add(&sc->sc_led_blink_end_ch, sc->sc_led_blink_offdur);
6565}
6566
6567void
6568bwi_led_blink_end(void *xsc)
6569{
6570 struct bwi_softc *sc = xsc;
6571
6572 sc->sc_led_blinking = 0;
6573}
6574
6575int
6576bwi_bbp_attach(struct bwi_softc *sc)
6577{
6578 uint16_t bbp_id, rw_type;
6579 uint8_t rw_rev;
6580 uint32_t info;
6581 int error, nregwin, i;
6582
6583 /*
6584 * Get 0th regwin information
6585 * NOTE: 0th regwin should exist
6586 */
6587 error = bwi_regwin_select(sc, 0);
6588 if (error) {
6589 printf("%s: can't select regwin 0\n", sc->sc_dev.dv_xname);
6590 return (error);
6591 }
6592 bwi_regwin_info(sc, &rw_type, &rw_rev);
6593
6594 /*
6595 * Find out BBP id
6596 */
6597 bbp_id = 0;
6598 info = 0;
6599 if (rw_type == BWI_REGWIN_T_COM0x800) {
6600 info = CSR_READ_4(sc, BWI_INFO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000000
))))
;
6601 bbp_id = __SHIFTOUT(info, BWI_INFO_BBPID_MASK)(((info) & (0x0000ffff)) / ((((0x0000ffff) - 1) & (0x0000ffff
)) ^ (0x0000ffff)))
;
6602
6603 BWI_CREATE_REGWIN(&sc->sc_com_regwin, 0, rw_type, rw_rev)do { (&sc->sc_com_regwin)->rw_flags = 0x1; (&sc
->sc_com_regwin)->rw_type = (rw_type); (&sc->sc_com_regwin
)->rw_id = (0); (&sc->sc_com_regwin)->rw_rev = (
rw_rev); } while (0)
;
6604
6605 sc->sc_cap = CSR_READ_4(sc, BWI_CAPABILITY)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000004
))))
;
6606 } else {
6607 uint16_t did = sc->sc_pci_did;
6608 uint8_t revid = sc->sc_pci_revid;
6609
6610 for (i = 0; i < nitems(bwi_bbpid_map)(sizeof((bwi_bbpid_map)) / sizeof((bwi_bbpid_map)[0])); ++i) {
6611 if (did >= bwi_bbpid_map[i].did_min &&
6612 did <= bwi_bbpid_map[i].did_max) {
6613 bbp_id = bwi_bbpid_map[i].bbp_id;
6614 break;
6615 }
6616 }
6617 if (bbp_id == 0) {
6618 printf("%s: no BBP id for device id 0x%04x\n",
6619 sc->sc_dev.dv_xname, did);
6620 return (ENXIO6);
6621 }
6622
6623 info = __SHIFTIN(revid, BWI_INFO_BBPREV_MASK)((revid) * ((((0x000f0000) - 1) & (0x000f0000)) ^ (0x000f0000
)))
|
6624 __SHIFTIN(0, BWI_INFO_BBPPKG_MASK)((0) * ((((0x00f00000) - 1) & (0x00f00000)) ^ (0x00f00000
)))
;
6625 }
6626
6627 /*
6628 * Find out number of regwins
6629 */
6630 nregwin = 0;
6631 if (rw_type == BWI_REGWIN_T_COM0x800 && rw_rev >= 4) {
6632 nregwin = __SHIFTOUT(info, BWI_INFO_NREGWIN_MASK)(((info) & (0x0f000000)) / ((((0x0f000000) - 1) & (0x0f000000
)) ^ (0x0f000000)))
;
6633 } else {
6634 for (i = 0; i < nitems(bwi_regwin_count)(sizeof((bwi_regwin_count)) / sizeof((bwi_regwin_count)[0])); ++i) {
6635 if (bwi_regwin_count[i].bbp_id == bbp_id) {
6636 nregwin = bwi_regwin_count[i].nregwin;
6637 break;
6638 }
6639 }
6640 if (nregwin == 0) {
6641 printf("%s: no number of win for BBP id 0x%04x\n",
6642 sc->sc_dev.dv_xname, bbp_id);
6643 return (ENXIO6);
6644 }
6645 }
6646
6647 /* Record BBP id/rev for later using */
6648 sc->sc_bbp_id = bbp_id;
6649 sc->sc_bbp_rev = __SHIFTOUT(info, BWI_INFO_BBPREV_MASK)(((info) & (0x000f0000)) / ((((0x000f0000) - 1) & (0x000f0000
)) ^ (0x000f0000)))
;
6650 sc->sc_bbp_pkg = __SHIFTOUT(info, BWI_INFO_BBPPKG_MASK)(((info) & (0x00f00000)) / ((((0x00f00000) - 1) & (0x00f00000
)) ^ (0x00f00000)))
;
6651 DPRINTF(1, "%s: BBP id 0x%04x, BBP rev 0x%x, BBP pkg %d\n",
6652 sc->sc_dev.dv_xname, sc->sc_bbp_id, sc->sc_bbp_rev, sc->sc_bbp_pkg);
6653 DPRINTF(1, "%s: nregwin %d, cap 0x%08x\n",
6654 sc->sc_dev.dv_xname, nregwin, sc->sc_cap);
6655
6656 /*
6657 * Create rest of the regwins
6658 */
6659
6660 /* Don't re-create common regwin, if it is already created */
6661 i = BWI_REGWIN_EXIST(&sc->sc_com_regwin)((&sc->sc_com_regwin)->rw_flags & 0x1) ? 1 : 0;
6662
6663 for (; i < nregwin; ++i) {
6664 /*
6665 * Get regwin information
6666 */
6667 error = bwi_regwin_select(sc, i);
6668 if (error) {
6669 printf("%s: can't select regwin %d\n",
6670 sc->sc_dev.dv_xname, i);
6671 return (error);
6672 }
6673 bwi_regwin_info(sc, &rw_type, &rw_rev);
6674
6675 /*
6676 * Try attach:
6677 * 1) Bus (PCI/PCIE) regwin
6678 * 2) MAC regwin
6679 * Ignore rest types of regwin
6680 */
6681 if (rw_type == BWI_REGWIN_T_BUSPCI0x804 ||
6682 rw_type == BWI_REGWIN_T_BUSPCIE0x820) {
6683 if (BWI_REGWIN_EXIST(&sc->sc_bus_regwin)((&sc->sc_bus_regwin)->rw_flags & 0x1)) {
6684 printf("%s: bus regwin already exists\n",
6685 sc->sc_dev.dv_xname);
6686 } else {
6687 BWI_CREATE_REGWIN(&sc->sc_bus_regwin, i,do { (&sc->sc_bus_regwin)->rw_flags = 0x1; (&sc
->sc_bus_regwin)->rw_type = (rw_type); (&sc->sc_bus_regwin
)->rw_id = (i); (&sc->sc_bus_regwin)->rw_rev = (
rw_rev); } while (0)
6688 rw_type, rw_rev)do { (&sc->sc_bus_regwin)->rw_flags = 0x1; (&sc
->sc_bus_regwin)->rw_type = (rw_type); (&sc->sc_bus_regwin
)->rw_id = (i); (&sc->sc_bus_regwin)->rw_rev = (
rw_rev); } while (0)
;
6689 }
6690 } else if (rw_type == BWI_REGWIN_T_MAC0x812) {
6691 /* XXX ignore return value */
6692 bwi_mac_attach(sc, i, rw_rev);
6693 }
6694 }
6695
6696 /* At least one MAC should exist */
6697 if (!BWI_REGWIN_EXIST(&sc->sc_mac[0].mac_regwin)((&sc->sc_mac[0].mac_regwin)->rw_flags & 0x1)) {
6698 printf("%s: no MAC was found\n", sc->sc_dev.dv_xname);
6699 return (ENXIO6);
6700 }
6701 KASSERT(sc->sc_nmac > 0)((sc->sc_nmac > 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c"
, 6701, "sc->sc_nmac > 0"))
;
6702
6703 /* Bus regwin must exist */
6704 if (!BWI_REGWIN_EXIST(&sc->sc_bus_regwin)((&sc->sc_bus_regwin)->rw_flags & 0x1)) {
6705 printf("%s: no bus regwin was found\n", sc->sc_dev.dv_xname);
6706 return (ENXIO6);
6707 }
6708
6709 /* Start with first MAC */
6710 error = bwi_regwin_switch(sc, &sc->sc_mac[0].mac_regwin, NULL((void *)0));
6711 if (error)
6712 return (error);
6713
6714 return (0);
6715}
6716
6717int
6718bwi_bus_init(struct bwi_softc *sc, struct bwi_mac *mac)
6719{
6720 struct bwi_regwin *old, *bus;
6721 uint32_t val;
6722 int error;
6723
6724 bus = &sc->sc_bus_regwin;
6725 KASSERT(sc->sc_cur_regwin == &mac->mac_regwin)((sc->sc_cur_regwin == &mac->mac_regwin) ? (void)0 :
__assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c", 6725, "sc->sc_cur_regwin == &mac->mac_regwin"
))
;
6726
6727 /*
6728 * Tell bus to generate requested interrupts
6729 */
6730 if (bus->rw_rev < 6 && bus->rw_type == BWI_REGWIN_T_BUSPCI0x804) {
6731 /*
6732 * NOTE: Read BWI_FLAGS from MAC regwin
6733 */
6734 val = CSR_READ_4(sc, BWI_FLAGS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f18
))))
;
6735
6736 error = bwi_regwin_switch(sc, bus, &old);
6737 if (error)
6738 return (error);
6739
6740 CSR_SETBITS_4(sc, BWI_INTRVEC, (val & BWI_FLAGS_INTR_MASK))((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), (
((0x00000f94))), ((((((sc))->sc_mem_bt)->read_4((((sc))
->sc_mem_bh), (((0x00000f94))))) | ((val & 0x0000003f)
)))))
;
6741 } else {
6742 uint32_t mac_mask;
6743
6744 mac_mask = 1 << mac->mac_idmac_regwin.rw_id;
6745
6746 error = bwi_regwin_switch(sc, bus, &old);
6747 if (error)
6748 return (error);
6749
6750 val = (sc->sc_conf_read)(sc, BWI_PCIR_INTCTL0x00000094);
6751 val |= mac_mask << 8;
6752 (sc->sc_conf_write)(sc, BWI_PCIR_INTCTL0x00000094, val);
6753 }
6754
6755 if (sc->sc_flags & BWI_F_BUS_INITED0x1)
6756 goto back;
6757
6758 if (bus->rw_type == BWI_REGWIN_T_BUSPCI0x804) {
6759 /*
6760 * Enable prefetch and burst
6761 */
6762 CSR_SETBITS_4(sc, BWI_BUS_CONFIG,((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), (
((0x00000108))), ((((((sc))->sc_mem_bt)->read_4((((sc))
->sc_mem_bh), (((0x00000108))))) | ((1 << 2) | (1 <<
3))))))
6763 BWI_BUS_CONFIG_PREFETCH | BWI_BUS_CONFIG_BURST)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), (
((0x00000108))), ((((((sc))->sc_mem_bt)->read_4((((sc))
->sc_mem_bh), (((0x00000108))))) | ((1 << 2) | (1 <<
3))))))
;
6764
6765 if (bus->rw_rev < 5) {
6766 struct bwi_regwin *com = &sc->sc_com_regwin;
6767
6768 /*
6769 * Configure timeouts for bus operation
6770 */
6771
6772 /*
6773 * Set service timeout and request timeout
6774 */
6775 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))))))))
6776 __SHIFTIN(BWI_CONF_LO_SERVTO,((((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))))))))
6777 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))))))))
6778 __SHIFTIN(BWI_CONF_LO_REQTO,((((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))))))))
6779 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))))))))
;
6780
6781 /*
6782 * If there is common regwin, we switch to that regwin
6783 * and switch back to bus regwin once we have done.
6784 */
6785 if (BWI_REGWIN_EXIST(com)((com)->rw_flags & 0x1)) {
6786 error = bwi_regwin_switch(sc, com, NULL((void *)0));
6787 if (error)
6788 return (error);
6789 }
6790
6791 /* Let bus know what we have changed */
6792 CSR_WRITE_4(sc, BWI_BUS_ADDR, BWI_BUS_ADDR_MAGIC)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000050
)), ((0xfd8))))
;
6793 CSR_READ_4(sc, BWI_BUS_ADDR)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000050
))))
; /* Flush */
6794 CSR_WRITE_4(sc, BWI_BUS_DATA, 0)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000054
)), ((0))))
;
6795 CSR_READ_4(sc, BWI_BUS_DATA)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000054
))))
; /* Flush */
6796
6797 if (BWI_REGWIN_EXIST(com)((com)->rw_flags & 0x1)) {
6798 error = bwi_regwin_switch(sc, bus, NULL((void *)0));
6799 if (error)
6800 return (error);
6801 }
6802 } else if (bus->rw_rev >= 11) {
6803 /*
6804 * Enable memory read multiple
6805 */
6806 CSR_SETBITS_4(sc, BWI_BUS_CONFIG, BWI_BUS_CONFIG_MRM)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), (
((0x00000108))), ((((((sc))->sc_mem_bt)->read_4((((sc))
->sc_mem_bh), (((0x00000108))))) | ((1 << 5))))))
;
6807 }
6808 } else {
6809 /* TODO: PCIE */
6810 }
6811
6812 sc->sc_flags |= BWI_F_BUS_INITED0x1;
6813back:
6814 return (bwi_regwin_switch(sc, old, NULL((void *)0)));
6815}
6816
6817void
6818bwi_get_card_flags(struct bwi_softc *sc)
6819{
6820 sc->sc_card_flags = bwi_read_sprom(sc, BWI_SPROM_CARD_FLAGS0x72);
6821 if (sc->sc_card_flags == 0xffff)
6822 sc->sc_card_flags = 0;
6823
6824 if (sc->sc_pci_subvid == PCI_VENDOR_APPLE0x106b &&
6825 sc->sc_pci_subdid == 0x4e && /* XXX */
6826 sc->sc_pci_revid > 0x40)
6827 sc->sc_card_flags |= BWI_CARD_F_PA_GPIO9(1 << 1);
6828
6829 DPRINTF(1, "%s: card flags 0x%04x\n",
6830 sc->sc_dev.dv_xname, sc->sc_card_flags);
6831}
6832
6833void
6834bwi_get_eaddr(struct bwi_softc *sc, uint16_t eaddr_ofs, uint8_t *eaddr)
6835{
6836 int i;
6837
6838 for (i = 0; i < 3; ++i) {
6839 *((uint16_t *)eaddr + i) =
6840 htobe16(bwi_read_sprom(sc, eaddr_ofs + 2 * i))(__uint16_t)(__builtin_constant_p(bwi_read_sprom(sc, eaddr_ofs
+ 2 * i)) ? (__uint16_t)(((__uint16_t)(bwi_read_sprom(sc, eaddr_ofs
+ 2 * i)) & 0xffU) << 8 | ((__uint16_t)(bwi_read_sprom
(sc, eaddr_ofs + 2 * i)) & 0xff00U) >> 8) : __swap16md
(bwi_read_sprom(sc, eaddr_ofs + 2 * i)))
;
6841 }
6842}
6843
6844void
6845bwi_get_clock_freq(struct bwi_softc *sc, struct bwi_clock_freq *freq)
6846{
6847 struct bwi_regwin *com;
6848 uint32_t val;
6849 uint div;
6850 int src;
6851
6852 bzero(freq, sizeof(*freq))__builtin_bzero((freq), (sizeof(*freq)));
6853 com = &sc->sc_com_regwin;
6854
6855 KASSERT(BWI_REGWIN_EXIST(com))((((com)->rw_flags & 0x1)) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/ic/bwi.c", 6855, "BWI_REGWIN_EXIST(com)")
)
;
6856 KASSERT(sc->sc_cur_regwin == com)((sc->sc_cur_regwin == com) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/ic/bwi.c", 6856, "sc->sc_cur_regwin == com"
))
;
6857 KASSERT(sc->sc_cap & BWI_CAP_CLKMODE)((sc->sc_cap & (1 << 18)) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/ic/bwi.c", 6857, "sc->sc_cap & BWI_CAP_CLKMODE"
))
;
6858
6859 /*
6860 * Calculate clock frequency
6861 */
6862 src = -1;
6863 div = 0;
6864 if (com->rw_rev < 6) {
6865 val = (sc->sc_conf_read)(sc, BWI_PCIR_GPIO_OUT0x000000b4);
6866 if (val & BWI_PCIM_GPIO_OUT_CLKSRC(1 << 4)) {
6867 src = BWI_CLKSRC_PCI2;
6868 div = 64;
6869 } else {
6870 src = BWI_CLKSRC_CS_OSC1;
6871 div = 32;
6872 }
6873 } else if (com->rw_rev < 10) {
6874 val = CSR_READ_4(sc, BWI_CLOCK_CTRL)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x000000b8
))))
;
6875
6876 src = __SHIFTOUT(val, BWI_CLOCK_CTRL_CLKSRC)(((val) & ((7 << 0))) / (((((7 << 0)) - 1) &
((7 << 0))) ^ ((7 << 0))))
;
6877 if (src == BWI_CLKSRC_LP_OSC0)
6878 div = 1;
6879 else {
6880 div = (__SHIFTOUT(val, BWI_CLOCK_CTRL_FDIV)(((val) & ((0xffff << 16))) / (((((0xffff << 16
)) - 1) & ((0xffff << 16))) ^ ((0xffff << 16)
)))
+ 1) << 2;
6881
6882 /* Unknown source */
6883 if (src >= BWI_CLKSRC_MAX3)
6884 src = BWI_CLKSRC_CS_OSC1;
6885 }
6886 } else {
6887 val = CSR_READ_4(sc, BWI_CLOCK_INFO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x000000c0
))))
;
6888
6889 src = BWI_CLKSRC_CS_OSC1;
6890 div = (__SHIFTOUT(val, BWI_CLOCK_INFO_FDIV)(((val) & ((0xffff << 16))) / (((((0xffff << 16
)) - 1) & ((0xffff << 16))) ^ ((0xffff << 16)
)))
+ 1) << 2;
6891 }
6892
6893 KASSERT(src >= 0 && src < BWI_CLKSRC_MAX)((src >= 0 && src < 3) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/ic/bwi.c", 6893, "src >= 0 && src < BWI_CLKSRC_MAX"
))
;
6894 KASSERT(div != 0)((div != 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c"
, 6894, "div != 0"))
;
6895
6896 DPRINTF(1, "%s: clksrc %s\n",
6897 sc->sc_dev.dv_xname,
6898 src == BWI_CLKSRC_PCI ? "PCI" :
6899 (src == BWI_CLKSRC_LP_OSC ? "LP_OSC" : "CS_OSC"));
6900
6901 freq->clkfreq_min = bwi_clkfreq[src].freq_min / div;
6902 freq->clkfreq_max = bwi_clkfreq[src].freq_max / div;
6903
6904 DPRINTF(1, "%s: clkfreq min %u, max %u\n",
6905 sc->sc_dev.dv_xname, freq->clkfreq_min, freq->clkfreq_max);
6906}
6907
6908int
6909bwi_set_clock_mode(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
6910{
6911 struct bwi_regwin *old, *com;
6912 uint32_t clk_ctrl, clk_src;
6913 int error, pwr_off = 0;
6914
6915 com = &sc->sc_com_regwin;
6916 if (!BWI_REGWIN_EXIST(com)((com)->rw_flags & 0x1))
6917 return (0);
6918
6919 if (com->rw_rev >= 10 || com->rw_rev < 6)
6920 return (0);
6921
6922 /*
6923 * For common regwin whose rev is [6, 10), the chip
6924 * must be capable to change clock mode.
6925 */
6926 if ((sc->sc_cap & BWI_CAP_CLKMODE(1 << 18)) == 0)
6927 return (0);
6928
6929 error = bwi_regwin_switch(sc, com, &old);
6930 if (error)
6931 return (error);
6932
6933 if (clk_mode == BWI_CLOCK_MODE_FAST)
6934 bwi_power_on(sc, 0); /* Don't turn on PLL */
6935
6936 clk_ctrl = CSR_READ_4(sc, BWI_CLOCK_CTRL)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x000000b8
))))
;
6937 clk_src = __SHIFTOUT(clk_ctrl, BWI_CLOCK_CTRL_CLKSRC)(((clk_ctrl) & ((7 << 0))) / (((((7 << 0)) - 1
) & ((7 << 0))) ^ ((7 << 0))))
;
6938
6939 switch (clk_mode) {
6940 case BWI_CLOCK_MODE_FAST:
6941 clk_ctrl &= ~BWI_CLOCK_CTRL_SLOW(1 << 11);
6942 clk_ctrl |= BWI_CLOCK_CTRL_IGNPLL(1 << 12);
6943 break;
6944 case BWI_CLOCK_MODE_SLOW:
6945 clk_ctrl |= BWI_CLOCK_CTRL_SLOW(1 << 11);
6946 break;
6947 case BWI_CLOCK_MODE_DYN:
6948 clk_ctrl &= ~(BWI_CLOCK_CTRL_SLOW(1 << 11) |
6949 BWI_CLOCK_CTRL_IGNPLL(1 << 12) |
6950 BWI_CLOCK_CTRL_NODYN(1 << 13));
6951 if (clk_src != BWI_CLKSRC_CS_OSC1) {
6952 clk_ctrl |= BWI_CLOCK_CTRL_NODYN(1 << 13);
6953 pwr_off = 1;
6954 }
6955 break;
6956 }
6957 CSR_WRITE_4(sc, BWI_CLOCK_CTRL, clk_ctrl)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x000000b8
)), ((clk_ctrl))))
;
6958
6959 if (pwr_off)
6960 bwi_power_off(sc, 0); /* Leave PLL as it is */
6961
6962 return (bwi_regwin_switch(sc, old, NULL((void *)0)));
6963}
6964
6965int
6966bwi_set_clock_delay(struct bwi_softc *sc)
6967{
6968 struct bwi_regwin *old, *com;
6969 int error;
6970
6971 com = &sc->sc_com_regwin;
6972 if (!BWI_REGWIN_EXIST(com)((com)->rw_flags & 0x1))
6973 return (0);
6974
6975 error = bwi_regwin_switch(sc, com, &old);
6976 if (error)
6977 return (error);
6978
6979 if (sc->sc_bbp_id == BWI_BBPID_BCM43210x4321) {
6980 if (sc->sc_bbp_rev == 0)
6981 CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC0)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000028
)), ((0x3a4))))
;
6982 else if (sc->sc_bbp_rev == 1)
6983 CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC1)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000028
)), ((0xa4))))
;
6984 }
6985
6986 if (sc->sc_cap & BWI_CAP_CLKMODE(1 << 18)) {
6987 if (com->rw_rev >= 10)
6988 CSR_FILT_SETBITS_4(sc, BWI_CLOCK_INFO, 0xffff, 0x40000)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), (
((0x000000c0))), (((((((sc))->sc_mem_bt)->read_4((((sc)
)->sc_mem_bh), (((0x000000c0))))) & (0xffff)) | (0x40000
)))))
;
6989 else {
6990 struct bwi_clock_freq freq;
6991
6992 bwi_get_clock_freq(sc, &freq);
6993 CSR_WRITE_4(sc, BWI_PLL_ON_DELAY,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0xb0
)), (((((freq.clkfreq_max * 150) + ((1000000) - 1)) / (1000000
))))))
6994 howmany(freq.clkfreq_max * 150, 1000000))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0xb0
)), (((((freq.clkfreq_max * 150) + ((1000000) - 1)) / (1000000
))))))
;
6995 CSR_WRITE_4(sc, BWI_FREQ_SEL_DELAY,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0xb4
)), (((((freq.clkfreq_max * 15) + ((1000000) - 1)) / (1000000
))))))
6996 howmany(freq.clkfreq_max * 15, 1000000))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0xb4
)), (((((freq.clkfreq_max * 15) + ((1000000) - 1)) / (1000000
))))))
;
6997 }
6998 }
6999
7000 return (bwi_regwin_switch(sc, old, NULL((void *)0)));
7001}
7002
7003int
7004bwi_init(struct ifnet *ifp)
7005{
7006 struct bwi_softc *sc = ifp->if_softc;
7007
7008 bwi_init_statechg(sc, 1);
7009
7010 return (0);
7011}
7012
7013void
7014bwi_init_statechg(struct bwi_softc *sc, int statechg)
7015{
7016 struct ieee80211com *ic = &sc->sc_ic;
7017 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
7018 struct bwi_mac *mac;
7019 int error;
7020
7021 DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
7022
7023 error = bwi_stop(sc, statechg);
7024 if (error) {
7025 DPRINTF(1, "%s: can't stop\n", sc->sc_dev.dv_xname);
7026 return;
7027 }
7028
7029 /* power on cardbus socket */
7030 if (sc->sc_enable != NULL((void *)0))
7031 (*sc->sc_enable)(sc);
7032
7033 bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
7034
7035 /* TODO: 2 MAC */
7036
7037 mac = &sc->sc_mac[0];
7038 error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL((void *)0));
7039 if (error)
7040 goto back;
7041
7042 error = bwi_mac_init(mac);
7043 if (error)
7044 goto back;
7045
7046 bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN);
7047
7048 IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl))__builtin_memcpy((ic->ic_myaddr), (((caddr_t)((ifp->if_sadl
)->sdl_data + (ifp->if_sadl)->sdl_nlen))), (6))
;
7049
7050 bwi_set_bssid(sc, bwi_zero_addr); /* Clear BSSID */
7051 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR0, ic->ic_myaddr);
7052
7053 bwi_mac_reset_hwkeys(mac);
7054
7055 if ((mac->mac_flags & BWI_MAC_F_HAS_TXSTATS0x4) == 0) {
7056 int i;
7057
7058#define NRETRY 1000
7059 /*
7060 * Drain any possible pending TX status
7061 */
7062 for (i = 0; i < NRETRY; ++i) {
7063 if ((CSR_READ_4(sc, BWI_TXSTATUS_0)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000170
))))
&
7064 BWI_TXSTATUS_0_MORE(1 << 0)) == 0)
7065 break;
7066 CSR_READ_4(sc, BWI_TXSTATUS_1)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000174
))))
;
7067 }
7068 if (i == NRETRY)
7069 printf("%s: can't drain TX status\n",
7070 sc->sc_dev.dv_xname);
7071#undef NRETRY
7072 }
7073
7074 if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
7075 bwi_mac_updateslot(mac, 1);
7076
7077 /* Start MAC */
7078 error = bwi_mac_start(mac);
7079 if (error)
7080 goto back;
7081
7082 /* Enable intrs */
7083 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))
);
7084
7085 ifp->if_flags |= IFF_RUNNING0x40;
7086 ifq_clr_oactive(&ifp->if_snd);
7087
7088 if (statechg) {
7089 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
7090 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_SCAN), (-1)));
7091 } else {
7092 ieee80211_new_state(ic, IEEE80211_S_RUN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_RUN), (-1)));
7093 }
7094 } else {
7095 ieee80211_new_state(ic, ic->ic_state, -1)(((ic)->ic_newstate)((ic), (ic->ic_state), (-1)));
7096 }
7097
7098back:
7099 if (error)
7100 bwi_stop(sc, 1);
7101 else
7102 bwi_start(ifp);
7103}
7104
7105int
7106bwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
7107{
7108 struct bwi_softc *sc = ifp->if_softc;
7109 struct ieee80211com *ic = &sc->sc_ic;
7110 int s, error = 0;
7111 uint8_t chan;
7112
7113 s = splnet()splraise(0x7);
7114
7115 switch (cmd) {
7116 case SIOCSIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((12)))
:
7117 ifp->if_flags |= IFF_UP0x1;
7118 /* FALLTHROUGH */
7119 case SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
:
7120 if (ifp->if_flags & IFF_UP0x1) {
7121 if ((ifp->if_flags & IFF_RUNNING0x40) == 0)
7122 bwi_init(ifp);
7123 } else {
7124 if (ifp->if_flags & IFF_RUNNING0x40)
7125 bwi_stop(sc, 1);
7126 }
7127 break;
7128 case SIOCS80211CHANNEL((unsigned long)0x80000000 | ((sizeof(struct ieee80211chanreq
) & 0x1fff) << 16) | ((('i')) << 8) | ((238))
)
:
7129 /* allow fast channel switching in monitor mode */
7130 error = ieee80211_ioctl(ifp, cmd, data);
7131 if (error == ENETRESET52 &&
7132 ic->ic_opmode == IEEE80211_M_MONITOR) {
7133 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) ==
7134 (IFF_UP0x1 | IFF_RUNNING0x40)) {
7135 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
7136 chan = ieee80211_chan2ieee(ic,
7137 ic->ic_bss->ni_chan);
7138 bwi_set_chan(sc, chan);
7139 }
7140 error = 0;
7141 }
7142 break;
7143 default:
7144 error = ieee80211_ioctl(ifp, cmd, data);
7145 break;
7146 }
7147
7148 if (error == ENETRESET52) {
7149 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) ==
7150 (IFF_UP0x1 | IFF_RUNNING0x40))
7151 bwi_init(ifp);
7152 error = 0;
7153 }
7154
7155 splx(s)spllower(s);
7156
7157 return (error);
7158}
7159
7160void
7161bwi_start(struct ifnet *ifp)
7162{
7163 struct bwi_softc *sc = ifp->if_softc;
7164 struct ieee80211com *ic = &sc->sc_ic;
7165 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING1];
7166 int trans, idx;
7167
7168 if (ifq_is_oactive(&ifp->if_snd) || (ifp->if_flags & IFF_RUNNING0x40) == 0)
7169 return;
7170
7171 trans = 0;
7172 idx = tbd->tbd_idx;
7173
7174 while (tbd->tbd_buf[idx].tb_mbuf == NULL((void *)0)) {
7175 struct ieee80211_frame *wh;
7176 struct ieee80211_node *ni;
7177 struct ieee80211_key *k;
7178 struct mbuf *m;
7179 int mgt_pkt = 0;
7180
7181 m = mq_dequeue(&ic->ic_mgtq);
7182 if (m != NULL((void *)0)) {
7183 ni = m->m_pkthdrM_dat.MH.MH_pkthdr.ph_cookie;
7184
7185 mgt_pkt = 1;
7186 } else {
7187 struct ether_header *eh;
7188
7189 if (ic->ic_state != IEEE80211_S_RUN)
7190 break;
7191
7192 m = ifq_dequeue(&ifp->if_snd);
7193 if (m == NULL((void *)0))
7194 break;
7195
7196 if (m->m_lenm_hdr.mh_len < sizeof(*eh)) {
7197 m = m_pullup(m, sizeof(*eh));
7198 if (m == NULL((void *)0)) {
7199 ifp->if_oerrorsif_data.ifi_oerrors++;
7200 continue;
7201 }
7202 }
7203 eh = mtod(m, struct ether_header *)((struct ether_header *)((m)->m_hdr.mh_data));
7204
7205 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
7206 if (ni == NULL((void *)0)) {
7207 m_freem(m);
7208 ifp->if_oerrorsif_data.ifi_oerrors++;
7209 continue;
7210 }
7211
7212 /* TODO: PS */
7213#if NBPFILTER1 > 0
7214 if (ifp->if_bpf != NULL((void *)0))
7215 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT(1 << 1));
7216#endif
7217 m = ieee80211_encap(ifp, m, &ni);
7218 if (m == NULL((void *)0))
7219 continue;
7220 }
7221#if NBPFILTER1 > 0
7222 if (ic->ic_rawbpf != NULL((void *)0))
7223 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT(1 << 1));
7224#endif
7225 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
7226 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40) {
7227 k = ieee80211_get_txkey(ic, wh, ni);
7228 if ((m = ieee80211_encrypt(ic, m, k)) == NULL((void *)0))
7229 return;
7230 }
7231 wh = NULL((void *)0); /* Catch any invalid use */
7232
7233 if (mgt_pkt) {
7234 ieee80211_release_node(ic, ni);
7235 ni = NULL((void *)0);
7236 }
7237
7238 if (bwi_encap(sc, idx, m, ni) != 0) {
7239 /* 'm' is freed in bwi_encap() if we reach here */
7240 if (ni != NULL((void *)0))
7241 ieee80211_release_node(ic, ni);
7242 ifp->if_oerrorsif_data.ifi_oerrors++;
7243 continue;
7244 }
7245
7246 trans = 1;
7247 tbd->tbd_used++;
7248 idx = (idx + 1) % BWI_TX_NDESC128;
7249
7250 if (tbd->tbd_used + BWI_TX_NSPRDESC2 >= BWI_TX_NDESC128) {
7251 ifq_set_oactive(&ifp->if_snd);
7252 break;
7253 }
7254 }
7255 tbd->tbd_idx = idx;
7256
7257 if (trans)
7258 sc->sc_tx_timer = 5;
7259 ifp->if_timer = 1;
7260}
7261
7262void
7263bwi_watchdog(struct ifnet *ifp)
7264{
7265 struct bwi_softc *sc = ifp->if_softc;
7266
7267 ifp->if_timer = 0;
7268
7269 if ((ifp->if_flags & IFF_RUNNING0x40) == 0)
7270 return;
7271
7272 if (sc->sc_tx_timer) {
7273 if (--sc->sc_tx_timer == 0) {
7274 printf("%s: watchdog timeout\n",
7275 sc->sc_dev.dv_xname);
7276 ifp->if_oerrorsif_data.ifi_oerrors++;
7277 /* TODO */
7278 } else
7279 ifp->if_timer = 1;
7280 }
7281
7282 ieee80211_watchdog(ifp);
7283}
7284
7285void
7286bwi_newstate_begin(struct bwi_softc *sc, enum ieee80211_state nstate)
7287{
7288 timeout_del(&sc->sc_scan_ch);
7289 timeout_del(&sc->sc_calib_ch);
7290
7291 bwi_led_newstate(sc, nstate);
7292
7293 if (nstate == IEEE80211_S_INIT)
7294 sc->sc_txpwrcb_type = BWI_TXPWR_INIT;
7295}
7296
7297int
7298bwi_stop(struct bwi_softc *sc, int state_chg)
7299{
7300 struct ieee80211com *ic = &sc->sc_ic;
7301 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
7302 struct bwi_mac *mac;
7303 int i, error, pwr_off = 0;
7304
7305 DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
7306
7307 if (state_chg)
7308 ieee80211_new_state(ic, IEEE80211_S_INIT, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_INIT), (-1)));
7309 else
7310 bwi_newstate_begin(sc, IEEE80211_S_INIT);
7311
7312 if (ifp->if_flags & IFF_RUNNING0x40) {
7313 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", 7313, "sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC"
))
;
7314 mac = (struct bwi_mac *)sc->sc_cur_regwin;
7315
7316 bwi_disable_intrs(sc, BWI_ALL_INTRS0xffffffff);
7317 CSR_READ_4(sc, BWI_MAC_INTR_MASK)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x0000012c
))))
;
7318 bwi_mac_stop(mac);
7319 }
7320
7321 for (i = 0; i < sc->sc_nmac; ++i) {
7322 struct bwi_regwin *old_rw;
7323
7324 mac = &sc->sc_mac[i];
7325 if ((mac->mac_flags & BWI_MAC_F_INITED0x8) == 0)
7326 continue;
7327
7328 error = bwi_regwin_switch(sc, &mac->mac_regwin, &old_rw);
7329 if (error)
7330 continue;
7331
7332 bwi_mac_shutdown(mac);
7333 pwr_off = 1;
7334
7335 bwi_regwin_switch(sc, old_rw, NULL((void *)0));
7336 }
7337
7338 if (pwr_off)
7339 bwi_bbp_power_off(sc);
7340
7341 sc->sc_tx_timer = 0;
7342 ifp->if_timer = 0;
7343 ifp->if_flags &= ~IFF_RUNNING0x40;
7344 ifq_clr_oactive(&ifp->if_snd);
7345
7346 /* power off cardbus socket */
7347 if (sc->sc_disable)
7348 sc->sc_disable(sc);
7349
7350 return (0);
7351}
7352
7353int
7354bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
7355{
7356 struct bwi_softc *sc = ic->ic_ific_ac.ac_if.if_softc;
7357 struct ieee80211_node *ni;
7358 int error;
7359 uint8_t chan;
7360
7361 timeout_del(&sc->sc_amrr_ch);
7362
7363 bwi_newstate_begin(sc, nstate);
7364
7365 if (nstate == IEEE80211_S_INIT)
7366 goto back;
7367
7368 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
7369 error = bwi_set_chan(sc, chan);
7370 if (error) {
7371 printf("%s: can't set channel to %u\n",
7372 sc->sc_dev.dv_xname,
7373 ieee80211_chan2ieee(ic, ic->ic_des_chan));
7374 return (error);
7375 }
7376
7377 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
7378 /* Nothing to do */
7379 } else if (nstate == IEEE80211_S_RUN) {
7380 struct bwi_mac *mac;
7381
7382 ni = ic->ic_bss;
7383
7384 bwi_set_bssid(sc, ic->ic_bss->ni_bssid);
7385
7386 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", 7386, "sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC"
))
;
7387 mac = (struct bwi_mac *)sc->sc_cur_regwin;
7388
7389 /* Initial TX power calibration */
7390 bwi_mac_calibrate_txpower(mac, BWI_TXPWR_INIT);
7391#ifdef notyet
7392 sc->sc_txpwrcb_type = BWI_TXPWR_FORCE;
7393#else
7394 sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
7395#endif
7396 if (ic->ic_opmode == IEEE80211_M_STA) {
7397 /* fake a join to init the tx rate */
7398 bwi_newassoc(ic, ni, 1);
7399 }
7400
7401 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
7402 /* start automatic rate control timer */
7403 if (ic->ic_fixed_rate == -1)
7404 timeout_add_msec(&sc->sc_amrr_ch, 500);
7405 }
7406 } else
7407 bwi_set_bssid(sc, bwi_zero_addr);
7408
7409back:
7410 error = sc->sc_newstate(ic, nstate, arg);
7411
7412 if (nstate == IEEE80211_S_SCAN) {
7413 timeout_add_msec(&sc->sc_scan_ch, sc->sc_dwell_time);
7414 } else if (nstate == IEEE80211_S_RUN) {
7415 /* XXX 15 seconds */
7416 timeout_add_sec(&sc->sc_calib_ch, 1);
7417 }
7418
7419 return (error);
7420}
7421
7422int
7423bwi_media_change(struct ifnet *ifp)
7424{
7425 int error;
7426
7427 error = ieee80211_media_change(ifp);
7428 if (error != ENETRESET52)
7429 return (error);
7430
7431 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) == (IFF_UP0x1 | IFF_RUNNING0x40))
7432 bwi_init(ifp);
7433
7434 return (0);
7435}
7436
7437void
7438bwi_iter_func(void *arg, struct ieee80211_node *ni)
7439{
7440 struct bwi_softc *sc = arg;
7441 struct bwi_node *bn = (struct bwi_node *)ni;
7442
7443 ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn);
7444}
7445
7446void
7447bwi_amrr_timeout(void *arg)
7448{
7449 struct bwi_softc *sc = arg;
7450 struct ieee80211com *ic = &sc->sc_ic;
7451
7452 if (ic->ic_opmode == IEEE80211_M_STA)
7453 bwi_iter_func(sc, ic->ic_bss);
7454#ifndef IEEE80211_STA_ONLY
7455 else
7456 ieee80211_iterate_nodes(ic, bwi_iter_func, sc);
7457#endif
7458
7459 timeout_add_msec(&sc->sc_amrr_ch, 500);
7460}
7461
7462void
7463bwi_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
7464{
7465 struct bwi_softc *sc = ic->ic_ific_ac.ac_if.if_softc;
7466 int i;
7467
7468 DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
7469
7470 ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn);
7471
7472 /* set rate to some reasonable initial value */
7473 for (i = ni->ni_rates.rs_nrates - 1;
7474 i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL0x7f) > 72;
7475 i--);
7476
7477 ni->ni_txrate = i;
7478}
7479
7480struct ieee80211_node *
7481bwi_node_alloc(struct ieee80211com *ic)
7482{
7483 struct bwi_node *bn;
7484
7485 bn = malloc(sizeof(*bn), M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
7486 if (bn == NULL((void *)0))
7487 return (NULL((void *)0));
7488
7489 return ((struct ieee80211_node *)bn);
7490}
7491
7492struct uvm_constraint_range bwi_constraint = { 0x0, (0x40000000 - 1) };
7493struct kmem_pa_mode bwi_pa_mode = {
7494 .kp_align = BWI_RING_ALIGN0x1000,
7495 .kp_constraint = &bwi_constraint,
7496 .kp_zero = 1
7497};
7498
7499int
7500bwi_dma_alloc(struct bwi_softc *sc)
7501{
7502 int error, i, has_txstats;
7503 bus_size_t tx_ring_sz, rx_ring_sz, desc_sz = 0;
7504 uint32_t txrx_ctrl_step = 0;
7505 int s;
7506
7507 has_txstats = 0;
7508 for (i = 0; i < sc->sc_nmac; ++i) {
7509 if (sc->sc_mac[i].mac_flags & BWI_MAC_F_HAS_TXSTATS0x4) {
7510 has_txstats = 1;
7511 break;
7512 }
7513 }
7514
7515 switch (sc->sc_bus_space) {
7516 case BWI_BUS_SPACE_30BIT:
7517 /*
7518 * 30bit devices must use bounce buffers but
7519 * otherwise work like 32bit devices.
7520 */
7521 sc->sc_newbuf = bwi_newbuf30;
7522
7523 /* XXX implement txstats for 30bit? */
7524 has_txstats = 0;
7525
7526 /* FALLTHROUGH */
7527 case BWI_BUS_SPACE_32BIT:
7528 desc_sz = sizeof(struct bwi_desc32);
7529 txrx_ctrl_step = 0x20;
7530
7531 sc->sc_init_tx_ring = bwi_init_tx_ring32;
7532 sc->sc_free_tx_ring = bwi_free_tx_ring32;
7533 sc->sc_init_rx_ring = bwi_init_rx_ring32;
7534 sc->sc_free_rx_ring = bwi_free_rx_ring32;
7535 if (sc->sc_newbuf == NULL((void *)0))
7536 sc->sc_newbuf = bwi_newbuf;
7537 sc->sc_setup_rxdesc = bwi_setup_rx_desc32;
7538 sc->sc_setup_txdesc = bwi_setup_tx_desc32;
7539 sc->sc_rxeof = bwi_rxeof32;
7540 sc->sc_start_tx = bwi_start_tx32;
7541 if (has_txstats) {
7542 sc->sc_init_txstats = bwi_init_txstats32;
7543 sc->sc_free_txstats = bwi_free_txstats32;
7544 sc->sc_txeof_status = bwi_txeof_status32;
7545 }
7546 break;
7547
7548 default:
7549 panic("unsupported bus space type %d", sc->sc_bus_space);
7550 }
7551
7552 KASSERT(desc_sz != 0)((desc_sz != 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c"
, 7552, "desc_sz != 0"))
;
7553 KASSERT(txrx_ctrl_step != 0)((txrx_ctrl_step != 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c"
, 7553, "txrx_ctrl_step != 0"))
;
7554
7555 tx_ring_sz = roundup(desc_sz * BWI_TX_NDESC, BWI_RING_ALIGN)((((desc_sz * 128)+((0x1000)-1))/(0x1000))*(0x1000));
7556 rx_ring_sz = roundup(desc_sz * BWI_RX_NDESC, BWI_RING_ALIGN)((((desc_sz * 64)+((0x1000)-1))/(0x1000))*(0x1000));
7557
7558 s = splvm()splraise(0xa);
7559
7560#define TXRX_CTRL(idx) (BWI_TXRX_CTRL_BASE0x200 + (idx) * txrx_ctrl_step)
7561 /*
7562 * Create TX ring DMA stuffs
7563 */
7564 for (i = 0; i < BWI_TX_NRING6; ++i) {
7565 error = bwi_dma_ring_alloc(sc,
7566 &sc->sc_tx_rdata[i], tx_ring_sz, TXRX_CTRL(i));
7567 if (error) {
7568 printf("%s: %dth TX ring DMA alloc failed\n",
7569 sc->sc_dev.dv_xname, i);
7570 bwi_dma_free(sc);
7571 splx(s)spllower(s);
7572 return (error);
7573 }
7574 }
7575
7576 /*
7577 * Create RX ring DMA stuffs
7578 */
7579 error = bwi_dma_ring_alloc(sc, &sc->sc_rx_rdata,
7580 rx_ring_sz, TXRX_CTRL(0));
7581 if (error) {
7582 printf("%s: RX ring DMA alloc failed\n", sc->sc_dev.dv_xname);
7583 bwi_dma_free(sc);
7584 splx(s)spllower(s);
7585 return (error);
7586 }
7587
7588 if (has_txstats) {
7589 error = bwi_dma_txstats_alloc(sc, TXRX_CTRL(3), desc_sz);
7590 if (error) {
7591 printf("%s: TX stats DMA alloc failed\n",
7592 sc->sc_dev.dv_xname);
7593 bwi_dma_free(sc);
7594 splx(s)spllower(s);
7595 return (error);
7596 }
7597 }
7598#undef TXRX_CTRL
7599
7600 if (sc->sc_bus_space == BWI_BUS_SPACE_30BIT)
7601 error = bwi_dma_mbuf_create30(sc);
7602 else
7603 error = bwi_dma_mbuf_create(sc);
7604 if (error)
7605 bwi_dma_free(sc);
7606
7607 splx(s)spllower(s);
7608
7609 return (error);
7610}
7611
7612void
7613bwi_dma_free(struct bwi_softc *sc)
7614{
7615 struct bwi_ring_data *rd;
7616 int i;
7617
7618 for (i = 0; i < BWI_TX_NRING6; ++i) {
7619 rd = &sc->sc_tx_rdata[i];
7620
7621 if (rd->rdata_desc != NULL((void *)0)) {
7622 bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (rd->
rdata_dmap))
;
7623 km_free(rd->rdata_desc, rd->rdata_ring_sz,
7624 &kv_intrsafe, &bwi_pa_mode);
7625 rd->rdata_desc = NULL((void *)0);
7626 }
7627 }
7628
7629 rd = &sc->sc_rx_rdata;
7630
7631 if (rd->rdata_desc != NULL((void *)0)) {
7632 bus_dmamap_unload(sc->sc_dmat, rd->rdata_dmap)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (rd->
rdata_dmap))
;
7633 km_free(rd->rdata_desc, rd->rdata_ring_sz,
7634 &kv_intrsafe, &bwi_pa_mode);
7635 rd->rdata_desc = NULL((void *)0);
7636 }
7637
7638 bwi_dma_txstats_free(sc);
7639
7640 if (sc->sc_bus_space == BWI_BUS_SPACE_30BIT) {
7641 for (i = 0; i < BWI_TX_NRING6; ++i) {
7642 if (sc->sc_bounce_tx_data[i] != NULL((void *)0)) {
7643 km_free(sc->sc_bounce_tx_data[i],
7644 BWI_TX_NDESC128 * MCLBYTES(1 << 11),
7645 &kv_intrsafe, &bwi_pa_mode);
7646 sc->sc_bounce_tx_data[i] = NULL((void *)0);
7647 }
7648 }
7649
7650 if (sc->sc_bounce_rx_data != NULL((void *)0)) {
7651 km_free(sc->sc_bounce_rx_data, BWI_RX_NDESC64 * MCLBYTES(1 << 11),
7652 &kv_intrsafe, &bwi_pa_mode);
7653 sc->sc_bounce_rx_data = NULL((void *)0);
7654 }
7655 }
7656}
7657
7658int
7659bwi_dma_ring_alloc(struct bwi_softc *sc,
7660 struct bwi_ring_data *rd, bus_size_t size, uint32_t txrx_ctrl)
7661{
7662 int error;
7663
7664 /* Allocate rings below 1GB so 30bit devices can access them.*/
7665 rd->rdata_desc = (caddr_t)km_alloc(size, &kv_intrsafe, &bwi_pa_mode,
7666 &kd_nowait);
7667 if (rd->rdata_desc == NULL((void *)0)) {
7668 printf(": could not allocate ring DMA memory\n");
7669 return (ENOMEM12);
7670 }
7671
7672 error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (size
), (1), (size), (0), (0x0001), (&rd->rdata_dmap))
7673 BUS_DMA_NOWAIT, &rd->rdata_dmap)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (size
), (1), (size), (0), (0x0001), (&rd->rdata_dmap))
;
7674 if (error) {
7675 printf(": cannot create ring DMA map (error %d)\n", error);
7676 km_free(rd->rdata_desc, size, &kv_intrsafe, &bwi_pa_mode);
7677 rd->rdata_desc = NULL((void *)0);
7678 return (error);
7679 }
7680
7681 error = bus_dmamap_load(sc->sc_dmat, rd->rdata_dmap, rd->rdata_desc,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (rd->
rdata_dmap), (rd->rdata_desc), (size), (((void *)0)), (0x0000
))
7682 size, NULL, BUS_DMA_WAITOK)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (rd->
rdata_dmap), (rd->rdata_desc), (size), (((void *)0)), (0x0000
))
;
7683 if (error) {
7684 printf("%s: can't load DMA mem\n", sc->sc_dev.dv_xname);
7685 bus_dmamap_destroy(sc->sc_dmat, rd->rdata_dmap)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (rd
->rdata_dmap))
;
7686 km_free(rd->rdata_desc, size, &kv_intrsafe, &bwi_pa_mode);
7687 rd->rdata_desc = NULL((void *)0);
7688 return (error);
7689 }
7690
7691 rd->rdata_ring_sz = size;
7692 rd->rdata_paddr = rd->rdata_dmap->dm_segs[0].ds_addr;
7693 rd->rdata_txrx_ctrl = txrx_ctrl;
7694
7695 return (0);
7696}
7697
7698int
7699bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base,
7700 bus_size_t desc_sz)
7701{
7702 struct bwi_txstats_data *st;
7703 bus_size_t dma_size;
7704 int error, nsegs;
7705
7706 st = malloc(sizeof(*st), M_DEVBUF2, M_WAITOK0x0001 | M_ZERO0x0008);
7707 sc->sc_txstats = st;
7708
7709 /*
7710 * Create TX stats descriptor DMA stuffs
7711 */
7712 dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN)((((desc_sz * 64)+((0x1000)-1))/(0x1000))*(0x1000));
7713
7714 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (dma_size
), (1), (dma_size), (0), (0x0001), (&st->stats_ring_dmap
))
7715 BUS_DMA_NOWAIT, &st->stats_ring_dmap)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (dma_size
), (1), (dma_size), (0), (0x0001), (&st->stats_ring_dmap
))
;
7716 if (error) {
7717 printf("%s: can't create txstats ring DMA mem\n",
7718 sc->sc_dev.dv_xname);
7719 return (error);
7720 }
7721
7722 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_RING_ALIGN, 0,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (dma_size
), (0x1000), (0), (&st->stats_ring_seg), (1), (&nsegs
), (0x0001 | 0x1000))
7723 &st->stats_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (dma_size
), (0x1000), (0), (&st->stats_ring_seg), (1), (&nsegs
), (0x0001 | 0x1000))
;
7724 if (error) {
7725 printf("%s: can't allocate txstats ring DMA mem\n",
7726 sc->sc_dev.dv_xname);
7727 return (error);
7728 }
7729
7730 error = bus_dmamem_map(sc->sc_dmat, &st->stats_ring_seg, nsegs,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&st
->stats_ring_seg), (nsegs), (dma_size), ((caddr_t *)&st
->stats_ring), (0x0001))
7731 dma_size, (caddr_t *)&st->stats_ring, BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&st
->stats_ring_seg), (nsegs), (dma_size), ((caddr_t *)&st
->stats_ring), (0x0001))
;
7732 if (error) {
7733 printf("%s: can't map txstats ring DMA mem\n",
7734 sc->sc_dev.dv_xname);
7735 return (error);
7736 }
7737
7738 error = bus_dmamap_load(sc->sc_dmat, st->stats_ring_dmap,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (st->
stats_ring_dmap), (st->stats_ring), (dma_size), (((void *)
0)), (0x0000))
7739 st->stats_ring, dma_size, NULL, BUS_DMA_WAITOK)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (st->
stats_ring_dmap), (st->stats_ring), (dma_size), (((void *)
0)), (0x0000))
;
7740 if (error) {
7741 printf("%s: can't load txstats ring DMA mem\n",
7742 sc->sc_dev.dv_xname);
7743 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, nsegs)(*(sc->sc_dmat)->_dmamem_free)((sc->sc_dmat), (&
st->stats_ring_seg), (nsegs))
;
7744 return (error);
7745 }
7746
7747 st->stats_ring_paddr = st->stats_ring_dmap->dm_segs[0].ds_addr;
7748
7749 /*
7750 * Create TX stats DMA stuffs
7751 */
7752 dma_size = roundup(sizeof(struct bwi_txstats) * BWI_TXSTATS_NDESC,((((sizeof(struct bwi_txstats) * 64)+((0x1000)-1))/(0x1000))*
(0x1000))
7753 BWI_ALIGN)((((sizeof(struct bwi_txstats) * 64)+((0x1000)-1))/(0x1000))*
(0x1000))
;
7754
7755 error = bus_dmamap_create(sc->sc_dmat, dma_size, 1, dma_size, 0,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (dma_size
), (1), (dma_size), (0), (0x0001), (&st->stats_dmap))
7756 BUS_DMA_NOWAIT, &st->stats_dmap)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (dma_size
), (1), (dma_size), (0), (0x0001), (&st->stats_dmap))
;
7757 if (error) {
7758 printf("%s: can't create txstats ring DMA mem\n",
7759 sc->sc_dev.dv_xname);
7760 return (error);
7761 }
7762 error = bus_dmamem_alloc(sc->sc_dmat, dma_size, BWI_ALIGN, 0,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (dma_size
), (0x1000), (0), (&st->stats_seg), (1), (&nsegs),
(0x0001 | 0x1000))
7763 &st->stats_seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (dma_size
), (0x1000), (0), (&st->stats_seg), (1), (&nsegs),
(0x0001 | 0x1000))
;
7764 if (error) {
7765 printf("%s: can't allocate txstats DMA mem\n",
7766 sc->sc_dev.dv_xname);
7767 return (error);
7768 }
7769
7770 error = bus_dmamem_map(sc->sc_dmat, &st->stats_seg, nsegs,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&st
->stats_seg), (nsegs), (dma_size), ((caddr_t *)&st->
stats), (0x0001))
7771 dma_size, (caddr_t *)&st->stats, BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&st
->stats_seg), (nsegs), (dma_size), ((caddr_t *)&st->
stats), (0x0001))
;
7772 if (error) {
7773 printf("%s: can't map txstats DMA mem\n", sc->sc_dev.dv_xname);
7774 return (error);
7775 }
7776
7777 error = bus_dmamap_load(sc->sc_dmat, st->stats_dmap, st->stats,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (st->
stats_dmap), (st->stats), (dma_size), (((void *)0)), (0x0000
))
7778 dma_size, NULL, BUS_DMA_WAITOK)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (st->
stats_dmap), (st->stats), (dma_size), (((void *)0)), (0x0000
))
;
7779 if (error) {
7780 printf("%s: can't load txstats DMA mem\n", sc->sc_dev.dv_xname);
7781 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, nsegs)(*(sc->sc_dmat)->_dmamem_free)((sc->sc_dmat), (&
st->stats_seg), (nsegs))
;
7782 return (error);
7783 }
7784
7785 st->stats_paddr = st->stats_dmap->dm_segs[0].ds_addr;
7786 st->stats_ctrl_base = ctrl_base;
7787
7788 return (0);
7789}
7790
7791void
7792bwi_dma_txstats_free(struct bwi_softc *sc)
7793{
7794 struct bwi_txstats_data *st;
7795
7796 if (sc->sc_txstats == NULL((void *)0))
7797 return;
7798 st = sc->sc_txstats;
7799
7800 bus_dmamap_unload(sc->sc_dmat, st->stats_ring_dmap)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (st->
stats_ring_dmap))
;
7801 bus_dmamem_free(sc->sc_dmat, &st->stats_ring_seg, 1)(*(sc->sc_dmat)->_dmamem_free)((sc->sc_dmat), (&
st->stats_ring_seg), (1))
;
7802
7803 bus_dmamap_unload(sc->sc_dmat, st->stats_dmap)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (st->
stats_dmap))
;
7804 bus_dmamem_free(sc->sc_dmat, &st->stats_seg, 1)(*(sc->sc_dmat)->_dmamem_free)((sc->sc_dmat), (&
st->stats_seg), (1))
;
7805
7806 free(st, M_DEVBUF2, sizeof *st);
7807}
7808
7809int
7810bwi_dma_mbuf_create30(struct bwi_softc *sc)
7811{
7812 int i, j, k, error;
7813
7814 for (i = 0; i < BWI_TX_NRING6; ++i) {
7815 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
7816
7817 sc->sc_bounce_tx_data[i] = (caddr_t)km_alloc(
7818 BWI_TX_NDESC128 * MCLBYTES(1 << 11), &kv_intrsafe,
7819 &bwi_pa_mode, &kd_waitok);
7820 if (sc->sc_bounce_tx_data[i] == NULL((void *)0)) {
7821 printf(": could not allocate TX mbuf bounce buffer\n");
7822 error = ENOMEM12;
7823 break;
7824 }
7825
7826 for (j = 0; j < BWI_TX_NDESC128; ++j) {
7827 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&tbd->tbd_buf
[j].tb_dmap))
7828 1, MCLBYTES, 0, BUS_DMA_NOWAIT,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&tbd->tbd_buf
[j].tb_dmap))
7829 &tbd->tbd_buf[j].tb_dmap)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&tbd->tbd_buf
[j].tb_dmap))
;
7830 if (error) {
7831 printf(": cannot create TX mbuf DMA map\n");
7832 for (k = 0; k < j; ++k) {
7833 bus_dmamap_destroy(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (tbd
->tbd_buf[k].tb_dmap))
7834 tbd->tbd_buf[k].tb_dmap)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (tbd
->tbd_buf[k].tb_dmap))
;
7835 }
7836 break;
7837 }
7838 }
7839 }
7840 if (error) {
7841 bwi_dma_mbuf_destroy(sc, i, 0);
7842 for (j = 0; j < i; ++j)
7843 km_free(sc->sc_bounce_tx_data[j], BWI_TX_NDESC128,
7844 &kv_intrsafe, &bwi_pa_mode);
7845 return (error);
7846 }
7847
7848 for (i = 0; i < BWI_TX_NRING6; ++i) {
7849 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
7850
7851 for (j = 0; j < BWI_TX_NDESC128; ++j) {
7852 struct bwi_txbuf *tb = &tbd->tbd_buf[j];
7853
7854 error = bus_dmamap_load(sc->sc_dmat, tb->tb_dmap,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (tb->
tb_dmap), (sc->sc_bounce_tx_data[i] + ((1 << 11) * j
)), ((1 << 11)), (((void *)0)), (0x0001))
7855 sc->sc_bounce_tx_data[i] + (MCLBYTES * j),(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (tb->
tb_dmap), (sc->sc_bounce_tx_data[i] + ((1 << 11) * j
)), ((1 << 11)), (((void *)0)), (0x0001))
7856 MCLBYTES, NULL, BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (tb->
tb_dmap), (sc->sc_bounce_tx_data[i] + ((1 << 11) * j
)), ((1 << 11)), (((void *)0)), (0x0001))
;
7857 if (error) {
7858 printf(": cannot create TX mbuf DMA map\n");
7859 for (k = 0; k < j; ++k) {
7860 bus_dmamap_destroy(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (tbd
->tbd_buf[k].tb_dmap))
7861 tbd->tbd_buf[k].tb_dmap)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (tbd
->tbd_buf[k].tb_dmap))
;
7862 }
7863 break;
7864 }
7865 }
7866 }
7867 if (error) {
7868 bwi_dma_mbuf_destroy(sc, BWI_TX_NRING6, 0);
7869 for (i = 0; i < BWI_TX_NRING6; ++i)
7870 km_free(sc->sc_bounce_tx_data[i], BWI_TX_NDESC128,
7871 &kv_intrsafe, &bwi_pa_mode);
7872 return (error);
7873 }
7874
7875 sc->sc_bounce_rx_data = (caddr_t)km_alloc(BWI_RX_NDESC64 * MCLBYTES(1 << 11),
7876 &kv_intrsafe, &bwi_pa_mode, &kd_waitok);
7877 if (sc->sc_bounce_rx_data == NULL((void *)0)) {
7878 printf(": could not allocate RX mbuf bounce buffer\n");
7879 bwi_dma_mbuf_destroy(sc, BWI_TX_NRING6, 0);
7880 for (i = 0; i < BWI_TX_NRING6; ++i)
7881 km_free(sc->sc_bounce_tx_data[i], BWI_TX_NDESC128,
7882 &kv_intrsafe, &bwi_pa_mode);
7883 return (ENOMEM12);
7884 }
7885
7886 for (i = 0; i < BWI_RX_NDESC64; ++i) {
7887 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&sc->sc_rx_bdata
.rbd_buf[i].rb_dmap))
7888 MCLBYTES, 0, BUS_DMA_NOWAIT,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&sc->sc_rx_bdata
.rbd_buf[i].rb_dmap))
7889 &sc->sc_rx_bdata.rbd_buf[i].rb_dmap)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&sc->sc_rx_bdata
.rbd_buf[i].rb_dmap))
;
7890 if (error) {
7891 printf(": cannot create RX mbuf DMA map\n");
7892 for (j = 0; j < i; ++j) {
7893 bus_dmamap_destroy(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (sc
->sc_rx_bdata.rbd_buf[j].rb_dmap))
7894 sc->sc_rx_bdata.rbd_buf[j].rb_dmap)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (sc
->sc_rx_bdata.rbd_buf[j].rb_dmap))
;
7895 }
7896 break;
7897 }
7898 }
7899 if (error) {
7900 bwi_dma_mbuf_destroy(sc, BWI_TX_NRING6, 0);
7901 for (i = 0; i < BWI_TX_NRING6; ++i)
7902 km_free(sc->sc_bounce_tx_data[i], BWI_TX_NDESC128,
7903 &kv_intrsafe, &bwi_pa_mode);
7904 km_free(sc->sc_bounce_rx_data, BWI_RX_NDESC64 * MCLBYTES(1 << 11),
7905 &kv_intrsafe, &bwi_pa_mode);
7906 return (error);
7907 }
7908
7909 for (i = 0; i < BWI_RX_NDESC64; ++i) {
7910 error = bwi_newbuf30(sc, i, 1);
7911 if (error) {
7912 printf(": cannot create RX mbuf DMA map\n");
7913 break;
7914 }
7915 }
7916 if (error) {
7917 bwi_dma_mbuf_destroy(sc, BWI_TX_NRING6, 1);
7918 for (i = 0; i < BWI_TX_NRING6; ++i)
7919 km_free(sc->sc_bounce_tx_data[i], BWI_TX_NDESC128,
7920 &kv_intrsafe, &bwi_pa_mode);
7921 km_free(sc->sc_bounce_rx_data, BWI_RX_NDESC64 * MCLBYTES(1 << 11),
7922 &kv_intrsafe, &bwi_pa_mode);
7923 return (error);
7924 }
7925
7926 return (0);
7927}
7928
7929int
7930bwi_dma_mbuf_create(struct bwi_softc *sc)
7931{
7932 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
7933 int i, j, k, ntx, error;
7934
7935 ntx = 0;
7936
7937 /*
7938 * Create TX mbuf DMA map
7939 */
7940 for (i = 0; i < BWI_TX_NRING6; ++i) {
7941 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
7942
7943 for (j = 0; j < BWI_TX_NDESC128; ++j) {
7944 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&tbd->tbd_buf
[j].tb_dmap))
7945 0, BUS_DMA_NOWAIT, &tbd->tbd_buf[j].tb_dmap)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&tbd->tbd_buf
[j].tb_dmap))
;
7946 if (error) {
7947 printf(
7948 "%s: can't create %dth tbd, %dth DMA map\n",
7949 sc->sc_dev.dv_xname, i, j);
7950 ntx = i;
7951 for (k = 0; k < j; ++k) {
7952 bus_dmamap_destroy(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (tbd
->tbd_buf[k].tb_dmap))
7953 tbd->tbd_buf[k].tb_dmap)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (tbd
->tbd_buf[k].tb_dmap))
;
7954 }
7955 goto fail;
7956 }
7957 }
7958 }
7959 ntx = BWI_TX_NRING6;
7960
7961 /*
7962 * Create RX mbuf DMA map and a spare DMA map
7963 */
7964 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&rbd->rbd_tmp_dmap
))
7965 BUS_DMA_NOWAIT, &rbd->rbd_tmp_dmap)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&rbd->rbd_tmp_dmap
))
;
7966 if (error) {
7967 printf("%s: can't create spare RX buf DMA map\n",
7968 sc->sc_dev.dv_xname);
7969 goto fail;
7970 }
7971
7972 for (j = 0; j < BWI_RX_NDESC64; ++j) {
7973 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&rbd->rbd_buf
[j].rb_dmap))
7974 BUS_DMA_NOWAIT, &rbd->rbd_buf[j].rb_dmap)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0001), (&rbd->rbd_buf
[j].rb_dmap))
;
7975 if (error) {
7976 printf("%s: can't create %dth RX buf DMA map\n",
7977 sc->sc_dev.dv_xname, j);
7978
7979 for (k = 0; k < j; ++k) {
7980 bus_dmamap_destroy(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (rbd
->rbd_buf[k].rb_dmap))
7981 rbd->rbd_buf[k].rb_dmap)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (rbd
->rbd_buf[k].rb_dmap))
;
7982 }
7983 bus_dmamap_destroy(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (rbd
->rbd_tmp_dmap))
7984 rbd->rbd_tmp_dmap)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (rbd
->rbd_tmp_dmap))
;
7985 goto fail;
7986 }
7987 }
7988
7989 return 0;
7990fail:
7991 bwi_dma_mbuf_destroy(sc, ntx, 0);
7992
7993 return (error);
7994}
7995
7996void
7997bwi_dma_mbuf_destroy(struct bwi_softc *sc, int ntx, int nrx)
7998{
7999 struct ieee80211com *ic = &sc->sc_ic;
8000 int i, j;
8001
8002 for (i = 0; i < ntx; ++i) {
8003 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
8004
8005 for (j = 0; j < BWI_TX_NDESC128; ++j) {
8006 struct bwi_txbuf *tb = &tbd->tbd_buf[j];
8007
8008 if (tb->tb_mbuf != NULL((void *)0)) {
8009 bus_dmamap_unload(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (tb->
tb_dmap))
8010 tb->tb_dmap)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (tb->
tb_dmap))
;
8011 m_freem(tb->tb_mbuf);
8012 }
8013 if (tb->tb_ni != NULL((void *)0))
8014 ieee80211_release_node(ic, tb->tb_ni);
8015 bus_dmamap_destroy(sc->sc_dmat, tb->tb_dmap)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (tb
->tb_dmap))
;
8016 }
8017 }
8018
8019 if (nrx) {
8020 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8021
8022 bus_dmamap_destroy(sc->sc_dmat, rbd->rbd_tmp_dmap)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (rbd
->rbd_tmp_dmap))
;
8023 for (j = 0; j < BWI_RX_NDESC64; ++j) {
8024 struct bwi_rxbuf *rb = &rbd->rbd_buf[j];
8025
8026 if (rb->rb_mbuf != NULL((void *)0)) {
8027 bus_dmamap_unload(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (rb->
rb_dmap))
8028 rb->rb_dmap)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (rb->
rb_dmap))
;
8029 m_freem(rb->rb_mbuf);
8030 }
8031 bus_dmamap_destroy(sc->sc_dmat, rb->rb_dmap)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (rb
->rb_dmap))
;
8032 }
8033 }
8034}
8035
8036void
8037bwi_enable_intrs(struct bwi_softc *sc, uint32_t enable_intrs)
8038{
8039 CSR_SETBITS_4(sc, BWI_MAC_INTR_MASK, enable_intrs)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), (
((0x0000012c))), ((((((sc))->sc_mem_bt)->read_4((((sc))
->sc_mem_bh), (((0x0000012c))))) | (enable_intrs)))))
;
8040}
8041
8042void
8043bwi_disable_intrs(struct bwi_softc *sc, uint32_t disable_intrs)
8044{
8045 CSR_CLRBITS_4(sc, BWI_MAC_INTR_MASK, disable_intrs)((((sc))->sc_mem_bt)->write_4((((sc))->sc_mem_bh), (
((0x0000012c))), ((((((sc))->sc_mem_bt)->read_4((((sc))
->sc_mem_bh), (((0x0000012c))))) & ~(disable_intrs))))
)
;
8046}
8047
8048int
8049bwi_init_tx_ring32(struct bwi_softc *sc, int ring_idx)
8050{
8051 struct bwi_ring_data *rd;
8052 struct bwi_txbuf_data *tbd;
8053 uint32_t val, addr_hi, addr_lo;
8054
8055 KASSERT(ring_idx < BWI_TX_NRING)((ring_idx < 6) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c"
, 8055, "ring_idx < BWI_TX_NRING"))
;
8056 rd = &sc->sc_tx_rdata[ring_idx];
8057 tbd = &sc->sc_tx_bdata[ring_idx];
8058
8059 tbd->tbd_idx = 0;
8060 tbd->tbd_used = 0;
8061
8062 bzero(rd->rdata_desc, sizeof(struct bwi_desc32) * BWI_TX_NDESC)__builtin_bzero((rd->rdata_desc), (sizeof(struct bwi_desc32
) * 128))
;
8063 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rd->
rdata_dmap), (0), (rd->rdata_dmap->dm_mapsize), (0x04))
8064 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rd->
rdata_dmap), (0), (rd->rdata_dmap->dm_mapsize), (0x04))
;
8065
8066 addr_lo = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_ADDR_MASK)(((rd->rdata_paddr) & (0x3fffffff)) / ((((0x3fffffff) -
1) & (0x3fffffff)) ^ (0x3fffffff)))
;
8067 addr_hi = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_FUNC_MASK)(((rd->rdata_paddr) & (0xc0000000)) / ((((0xc0000000) -
1) & (0xc0000000)) ^ (0xc0000000)))
;
8068
8069 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK)((addr_lo) * ((((0x3fffffff) - 1) & (0x3fffffff)) ^ (0x3fffffff
)))
|
8070 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,((0x1) * ((((0xc0000000) - 1) & (0xc0000000)) ^ (0xc0000000
)))
8071 BWI_TXRX32_RINGINFO_FUNC_MASK)((0x1) * ((((0xc0000000) - 1) & (0xc0000000)) ^ (0xc0000000
)))
;
8072 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, val)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((rd->
rdata_txrx_ctrl + 0x4)), ((val))))
;
8073
8074 val = __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK)((addr_hi) * ((((0x00030000) - 1) & (0x00030000)) ^ (0x00030000
)))
|
8075 BWI_TXRX32_CTRL_ENABLE(1 << 0);
8076 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, val)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((rd->
rdata_txrx_ctrl + 0x0)), ((val))))
;
8077
8078 return (0);
8079}
8080
8081void
8082bwi_init_rxdesc_ring32(struct bwi_softc *sc, uint32_t ctrl_base,
8083 bus_addr_t paddr, int hdr_size, int ndesc)
8084{
8085 uint32_t val, addr_hi, addr_lo;
8086
8087 addr_lo = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_ADDR_MASK)(((paddr) & (0x3fffffff)) / ((((0x3fffffff) - 1) & (0x3fffffff
)) ^ (0x3fffffff)))
;
8088 addr_hi = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_FUNC_MASK)(((paddr) & (0xc0000000)) / ((((0xc0000000) - 1) & (0xc0000000
)) ^ (0xc0000000)))
;
8089
8090 val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK)((addr_lo) * ((((0x3fffffff) - 1) & (0x3fffffff)) ^ (0x3fffffff
)))
|
8091 __SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,((0x1) * ((((0xc0000000) - 1) & (0xc0000000)) ^ (0xc0000000
)))
8092 BWI_TXRX32_RINGINFO_FUNC_MASK)((0x1) * ((((0xc0000000) - 1) & (0xc0000000)) ^ (0xc0000000
)))
;
8093 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_RINGINFO, val)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((ctrl_base
+ 0x14)), ((val))))
;
8094
8095 val = __SHIFTIN(hdr_size, BWI_RX32_CTRL_HDRSZ_MASK)((hdr_size) * ((((0x00fe) - 1) & (0x00fe)) ^ (0x00fe))) |
8096 __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK)((addr_hi) * ((((0x00030000) - 1) & (0x00030000)) ^ (0x00030000
)))
|
8097 BWI_TXRX32_CTRL_ENABLE(1 << 0);
8098 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((ctrl_base
+ 0x10)), ((val))))
;
8099
8100 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((ctrl_base
+ 0x18)), (((ndesc - 1) * sizeof(struct bwi_desc32)))))
8101 (ndesc - 1) * sizeof(struct bwi_desc32))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((ctrl_base
+ 0x18)), (((ndesc - 1) * sizeof(struct bwi_desc32)))))
;
8102}
8103
8104int
8105bwi_init_rx_ring32(struct bwi_softc *sc)
8106{
8107 struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8108 int i, error;
8109
8110 sc->sc_rx_bdata.rbd_idx = 0;
8111 bzero(rd->rdata_desc, sizeof(struct bwi_desc32) * BWI_RX_NDESC)__builtin_bzero((rd->rdata_desc), (sizeof(struct bwi_desc32
) * 64))
;
8112
8113 for (i = 0; i < BWI_RX_NDESC64; ++i) {
8114 error = sc->sc_newbuf(sc, i, 1);
8115 if (error) {
8116 printf("%s: can't allocate %dth RX buffer\n",
8117 sc->sc_dev.dv_xname, i);
8118 return (error);
8119 }
8120 }
8121 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rd->
rdata_dmap), (0), (rd->rdata_dmap->dm_mapsize), (0x04))
8122 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rd->
rdata_dmap), (0), (rd->rdata_dmap->dm_mapsize), (0x04))
;
8123
8124 bwi_init_rxdesc_ring32(sc, rd->rdata_txrx_ctrl, rd->rdata_paddr,
8125 sizeof(struct bwi_rxbuf_hdr), BWI_RX_NDESC64);
8126 return (0);
8127}
8128
8129int
8130bwi_init_txstats32(struct bwi_softc *sc)
8131{
8132 struct bwi_txstats_data *st = sc->sc_txstats;
8133 bus_addr_t stats_paddr;
8134 int i;
8135
8136 bzero(st->stats, BWI_TXSTATS_NDESC * sizeof(struct bwi_txstats))__builtin_bzero((st->stats), (64 * sizeof(struct bwi_txstats
)))
;
8137 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (st->
stats_dmap), (0), (st->stats_dmap->dm_mapsize), (0x04))
8138 st->stats_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (st->
stats_dmap), (0), (st->stats_dmap->dm_mapsize), (0x04))
;
8139
8140 st->stats_idx = 0;
8141
8142 stats_paddr = st->stats_paddr;
8143 for (i = 0; i < BWI_TXSTATS_NDESC64; ++i) {
8144 bwi_setup_desc32(sc, st->stats_ring, BWI_TXSTATS_NDESC64, i,
8145 stats_paddr, sizeof(struct bwi_txstats), 0);
8146 stats_paddr += sizeof(struct bwi_txstats);
8147 }
8148 bus_dmamap_sync(sc->sc_dmat, st->stats_ring_dmap, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (st->
stats_ring_dmap), (0), (st->stats_ring_dmap->dm_mapsize
), (0x04))
8149 st->stats_ring_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (st->
stats_ring_dmap), (0), (st->stats_ring_dmap->dm_mapsize
), (0x04))
;
8150
8151 bwi_init_rxdesc_ring32(sc, st->stats_ctrl_base,
8152 st->stats_ring_paddr, 0, BWI_TXSTATS_NDESC64);
8153
8154 return (0);
8155}
8156
8157void
8158bwi_setup_rx_desc32(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
8159 int buf_len)
8160{
8161 struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8162
8163 KASSERT(buf_idx < BWI_RX_NDESC)((buf_idx < 64) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c"
, 8163, "buf_idx < BWI_RX_NDESC"))
;
8164 bwi_setup_desc32(sc, rd->rdata_desc, BWI_RX_NDESC64, buf_idx,
8165 paddr, buf_len, 0);
8166}
8167
8168void
8169bwi_setup_tx_desc32(struct bwi_softc *sc, struct bwi_ring_data *rd,
8170 int buf_idx, bus_addr_t paddr, int buf_len)
8171{
8172 KASSERT(buf_idx < BWI_TX_NDESC)((buf_idx < 128) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c"
, 8172, "buf_idx < BWI_TX_NDESC"))
;
8173 bwi_setup_desc32(sc, rd->rdata_desc, BWI_TX_NDESC128, buf_idx,
8174 paddr, buf_len, 1);
8175}
8176
8177int
8178bwi_newbuf30(struct bwi_softc *sc, int buf_idx, int init)
8179{
8180 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8181 struct bwi_rxbuf *rb = &rbd->rbd_buf[buf_idx];
8182 struct mbuf *m;
8183 struct bwi_rxbuf_hdr *hdr;
8184 int error;
8185
8186 KASSERT(buf_idx < BWI_RX_NDESC)((buf_idx < 64) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c"
, 8186, "buf_idx < BWI_RX_NDESC"))
;
8187
8188 /* Create host-side mbuf. */
8189 MGETHDR(m, init ? M_WAITOK : M_NOWAIT, MT_DATA)m = m_gethdr((init ? 0x0001 : 0x0002), (1));
8190 if (m == NULL((void *)0))
8191 return (ENOBUFS55);
8192 MCLGET(m, init ? M_WAITOK : M_NOWAIT)(void) m_clget((m), (init ? 0x0001 : 0x0002), (1 << 11)
)
;
8193 if (m == NULL((void *)0))
8194 return (ENOBUFS55);
8195 m->m_lenm_hdr.mh_len = m->m_pkthdrM_dat.MH.MH_pkthdr.len = MCLBYTES(1 << 11);
8196
8197 if (init) {
8198 /* Load device-side RX DMA buffer. */
8199 error = bus_dmamap_load(sc->sc_dmat, rb->rb_dmap,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (rb->
rb_dmap), (sc->sc_bounce_rx_data + ((1 << 11) * buf_idx
)), ((1 << 11)), (((void *)0)), (0x0000))
8200 sc->sc_bounce_rx_data + (MCLBYTES * buf_idx),(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (rb->
rb_dmap), (sc->sc_bounce_rx_data + ((1 << 11) * buf_idx
)), ((1 << 11)), (((void *)0)), (0x0000))
8201 MCLBYTES, NULL, BUS_DMA_WAITOK)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (rb->
rb_dmap), (sc->sc_bounce_rx_data + ((1 << 11) * buf_idx
)), ((1 << 11)), (((void *)0)), (0x0000))
;
8202 if (error) {
8203 m_freem(m);
8204 return (error);
8205 }
8206 }
8207
8208 rb->rb_mbuf = m;
8209 rb->rb_paddr = rb->rb_dmap->dm_segs[0].ds_addr;
8210
8211 /*
8212 * Clear RX buf header
8213 */
8214 hdr = (struct bwi_rxbuf_hdr *)(sc->sc_bounce_rx_data +
8215 (MCLBYTES(1 << 11) * buf_idx));
8216 bzero(hdr, sizeof(*hdr))__builtin_bzero((hdr), (sizeof(*hdr)));
8217 bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rb->
rb_dmap), (0), (rb->rb_dmap->dm_mapsize), (0x04))
8218 rb->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rb->
rb_dmap), (0), (rb->rb_dmap->dm_mapsize), (0x04))
;
8219
8220 /*
8221 * Setup RX buf descriptor
8222 */
8223 sc->sc_setup_rxdesc(sc, buf_idx, rb->rb_paddr,
8224 m->m_lenm_hdr.mh_len - sizeof(*hdr));
8225
8226 return (0);
8227}
8228
8229int
8230bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init)
8231{
8232 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8233 struct bwi_rxbuf *rxbuf = &rbd->rbd_buf[buf_idx];
8234 struct bwi_rxbuf_hdr *hdr;
8235 bus_dmamap_t map;
8236 bus_addr_t paddr;
8237 struct mbuf *m;
8238 int error;
8239
8240 KASSERT(buf_idx < BWI_RX_NDESC)((buf_idx < 64) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c"
, 8240, "buf_idx < BWI_RX_NDESC"))
;
8241
8242 MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA)m = m_gethdr((init ? 0x0001 : 0x0002), (1));
8243 if (m == NULL((void *)0))
8244 return (ENOBUFS55);
8245 MCLGET(m, init ? M_WAITOK : M_DONTWAIT)(void) m_clget((m), (init ? 0x0001 : 0x0002), (1 << 11)
)
;
8246 if (m == NULL((void *)0)) {
8247 error = ENOBUFS55;
8248
8249 /*
8250 * If the NIC is up and running, we need to:
8251 * - Clear RX buffer's header.
8252 * - Restore RX descriptor settings.
8253 */
8254 if (init)
8255 return error;
8256 else
8257 goto back;
8258 }
8259 m->m_lenm_hdr.mh_len = m->m_pkthdrM_dat.MH.MH_pkthdr.len = MCLBYTES(1 << 11);
8260
8261 /*
8262 * Try to load RX buf into temporary DMA map
8263 */
8264 error = bus_dmamap_load_mbuf(sc->sc_dmat, rbd->rbd_tmp_dmap, m,(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
rbd->rbd_tmp_dmap), (m), (init ? 0x0000 : 0x0001))
8265 init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
rbd->rbd_tmp_dmap), (m), (init ? 0x0000 : 0x0001))
;
8266 if (error) {
8267 m_freem(m);
8268
8269 /*
8270 * See the comment above
8271 */
8272 if (init)
8273 return error;
8274 else
8275 goto back;
8276 }
8277
8278 if (!init)
8279 bus_dmamap_unload(sc->sc_dmat, rxbuf->rb_dmap)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (rxbuf
->rb_dmap))
;
8280 rxbuf->rb_mbuf = m;
8281
8282 /*
8283 * Swap RX buf's DMA map with the loaded temporary one
8284 */
8285 map = rxbuf->rb_dmap;
8286 rxbuf->rb_dmap = rbd->rbd_tmp_dmap;
8287 rbd->rbd_tmp_dmap = map;
8288 paddr = rxbuf->rb_dmap->dm_segs[0].ds_addr;
8289 rxbuf->rb_paddr = paddr;
8290
8291back:
8292 /*
8293 * Clear RX buf header
8294 */
8295 hdr = mtod(rxbuf->rb_mbuf, struct bwi_rxbuf_hdr *)((struct bwi_rxbuf_hdr *)((rxbuf->rb_mbuf)->m_hdr.mh_data
))
;
8296 bzero(hdr, sizeof(*hdr))__builtin_bzero((hdr), (sizeof(*hdr)));
8297 bus_dmamap_sync(sc->sc_dmat, rxbuf->rb_dmap, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rxbuf
->rb_dmap), (0), (rxbuf->rb_dmap->dm_mapsize), (0x04
))
8298 rxbuf->rb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rxbuf
->rb_dmap), (0), (rxbuf->rb_dmap->dm_mapsize), (0x04
))
;
8299
8300 /*
8301 * Setup RX buf descriptor
8302 */
8303 sc->sc_setup_rxdesc(sc, buf_idx, rxbuf->rb_paddr,
8304 rxbuf->rb_mbuf->m_lenm_hdr.mh_len - sizeof(*hdr));
8305 return error;
8306}
8307
8308void
8309bwi_set_addr_filter(struct bwi_softc *sc, uint16_t addr_ofs,
8310 const uint8_t *addr)
8311{
8312 int i;
8313
8314 CSR_WRITE_2(sc, BWI_ADDR_FILTER_CTRL,(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x0420
)), ((0x0020 | addr_ofs))))
8315 BWI_ADDR_FILTER_CTRL_SET | addr_ofs)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x0420
)), ((0x0020 | addr_ofs))))
;
8316
8317 for (i = 0; i < (IEEE80211_ADDR_LEN6 / 2); ++i) {
8318 uint16_t addr_val;
8319
8320 addr_val = (uint16_t)addr[i * 2] |
8321 (((uint16_t)addr[(i * 2) + 1]) << 8);
8322 CSR_WRITE_2(sc, BWI_ADDR_FILTER_DATA, addr_val)(((sc)->sc_mem_bt)->write_2(((sc)->sc_mem_bh), ((0x422
)), ((addr_val))))
;
8323 }
8324}
8325
8326int
8327bwi_set_chan(struct bwi_softc *sc, uint8_t chan)
8328{
8329 struct bwi_mac *mac;
8330
8331 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", 8331, "sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC"
))
;
8332 mac = (struct bwi_mac *)sc->sc_cur_regwin;
8333
8334 bwi_rf_set_chan(mac, chan, 0);
8335
8336 return (0);
8337}
8338
8339void
8340bwi_next_scan(void *xsc)
8341{
8342 struct bwi_softc *sc = xsc;
8343 struct ieee80211com *ic = &sc->sc_ic;
8344 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
8345 int s;
8346
8347 s = splnet()splraise(0x7);
8348
8349 if (ic->ic_state == IEEE80211_S_SCAN)
8350 ieee80211_next_scan(ifp);
8351
8352 splx(s)spllower(s);
8353}
8354
8355int
8356bwi_rxeof(struct bwi_softc *sc, int end_idx)
8357{
8358 struct mbuf_list ml = MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 };
8359 struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8360 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8361 struct ieee80211com *ic = &sc->sc_ic;
8362 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
8363 int idx, rx_data = 0;
8364
8365 idx = rbd->rbd_idx;
8366 while (idx != end_idx) {
8367 struct bwi_rxbuf *rb = &rbd->rbd_buf[idx];
8368 struct bwi_rxbuf_hdr *hdr;
8369 struct ieee80211_frame *wh;
8370 struct ieee80211_rxinfo rxi;
8371 struct ieee80211_node *ni;
8372 struct mbuf *m;
8373 uint32_t plcp;
8374 uint16_t flags2;
8375 int buflen, wh_ofs, hdr_extra, rssi, type, rate;
8376
8377 bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rb->
rb_dmap), (0), (rb->rb_dmap->dm_mapsize), (0x02))
8378 rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rb->
rb_dmap), (0), (rb->rb_dmap->dm_mapsize), (0x02))
;
8379
8380 if (sc->sc_bus_space == BWI_BUS_SPACE_30BIT) {
8381 /* Bounce for 30bit devices. */
8382 if (m_copyback(rb->rb_mbuf, 0, MCLBYTES(1 << 11),
8383 sc->sc_bounce_rx_data + (MCLBYTES(1 << 11) * idx),
8384 M_NOWAIT0x0002) == ENOBUFS55) {
8385 ifp->if_ierrorsif_data.ifi_ierrors++;
8386 goto next;
8387 }
8388 }
8389
8390 m = rb->rb_mbuf;
8391
8392 if (sc->sc_newbuf(sc, idx, 0)) {
8393 ifp->if_ierrorsif_data.ifi_ierrors++;
8394 goto next;
8395 }
8396
8397 hdr = mtod(m, struct bwi_rxbuf_hdr *)((struct bwi_rxbuf_hdr *)((m)->m_hdr.mh_data));
8398 flags2 = letoh16(hdr->rxh_flags2)((__uint16_t)(hdr->rxh_flags2));
8399
8400 hdr_extra = 0;
8401 if (flags2 & BWI_RXH_F2_TYPE2FRAME(1 << 2))
8402 hdr_extra = 2;
8403 wh_ofs = hdr_extra + 6;
8404
8405 buflen = letoh16(hdr->rxh_buflen)((__uint16_t)(hdr->rxh_buflen));
8406 if (buflen <= wh_ofs) {
8407 printf("%s: zero length data, hdr_extra %d\n",
8408 sc->sc_dev.dv_xname, hdr_extra);
8409 ifp->if_ierrorsif_data.ifi_ierrors++;
8410 m_freem(m);
8411 goto next;
8412 }
8413
8414 bcopy((uint8_t *)(hdr + 1) + hdr_extra, &plcp, sizeof(plcp));
8415 rssi = bwi_calc_rssi(sc, hdr);
8416
8417 m->m_lenm_hdr.mh_len = m->m_pkthdrM_dat.MH.MH_pkthdr.len = buflen + sizeof(*hdr);
8418 m_adj(m, sizeof(*hdr) + wh_ofs);
8419
8420 if (htole16(hdr->rxh_flags1)((__uint16_t)(hdr->rxh_flags1)) & BWI_RXH_F1_OFDM(1 << 0))
8421 rate = bwi_plcp2rate(plcp, IEEE80211_MODE_11G);
8422 else
8423 rate = bwi_plcp2rate(plcp, IEEE80211_MODE_11B);
8424
8425#if NBPFILTER1 > 0
8426 /* RX radio tap */
8427 if (sc->sc_drvbpf != NULL((void *)0)) {
8428 struct mbuf mb;
8429 struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtapsc_rxtapu.th;
8430
8431 tap->wr_tsf = hdr->rxh_tsf;
8432 tap->wr_flags = IEEE80211_RADIOTAP_F_FCS0x10;
8433 tap->wr_rate = rate;
8434 tap->wr_chan_freq =
8435 htole16(ic->ic_bss->ni_chan->ic_freq)((__uint16_t)(ic->ic_bss->ni_chan->ic_freq));
8436 tap->wr_chan_flags =
8437 htole16(ic->ic_bss->ni_chan->ic_flags)((__uint16_t)(ic->ic_bss->ni_chan->ic_flags));
8438 tap->wr_antsignal = rssi;
8439 tap->wr_antnoise = BWI_NOISE_FLOOR-95;
8440
8441 mb.m_datam_hdr.mh_data = (caddr_t)tap;
8442 mb.m_lenm_hdr.mh_len = sc->sc_rxtap_len;
8443 mb.m_nextm_hdr.mh_next = m;
8444 mb.m_nextpktm_hdr.mh_nextpkt = NULL((void *)0);
8445 mb.m_typem_hdr.mh_type = 0;
8446 mb.m_flagsm_hdr.mh_flags = 0;
8447 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN(1 << 0));
8448 }
8449#endif
8450
8451 m_adj(m, -IEEE80211_CRC_LEN4);
8452
8453 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
8454 ni = ieee80211_find_rxnode(ic, wh);
8455 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK0x0c;
8456
8457 rxi.rxi_rssi = hdr->rxh_rssi;
8458 rxi.rxi_tstamp = letoh16(hdr->rxh_tsf)((__uint16_t)(hdr->rxh_tsf));
8459 ieee80211_inputm(ifp, m, ni, &rxi, &ml);
8460
8461 ieee80211_release_node(ic, ni);
8462
8463 if (type == IEEE80211_FC0_TYPE_DATA0x08) {
8464 rx_data = 1;
8465 sc->sc_rx_rate = rate;
8466 }
8467next:
8468 idx = (idx + 1) % BWI_RX_NDESC64;
8469 }
8470 if_input(ifp, &ml);
8471
8472 rbd->rbd_idx = idx;
8473 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rd->
rdata_dmap), (0), (rd->rdata_dmap->dm_mapsize), (0x04))
8474 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rd->
rdata_dmap), (0), (rd->rdata_dmap->dm_mapsize), (0x04))
;
8475
8476 return (rx_data);
8477}
8478
8479int
8480bwi_rxeof32(struct bwi_softc *sc)
8481{
8482 uint32_t val, rx_ctrl;
8483 int end_idx, rx_data;
8484
8485 rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl;
8486
8487 val = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((rx_ctrl
+ 0x1c))))
;
8488 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK)(((val) & (0x0fff)) / ((((0x0fff) - 1) & (0x0fff)) ^ (
0x0fff)))
/
8489 sizeof(struct bwi_desc32);
8490
8491 rx_data = bwi_rxeof(sc, end_idx);
8492
8493 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((rx_ctrl
+ 0x18)), ((end_idx * sizeof(struct bwi_desc32)))))
8494 end_idx * sizeof(struct bwi_desc32))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((rx_ctrl
+ 0x18)), ((end_idx * sizeof(struct bwi_desc32)))))
;
8495
8496 return (rx_data);
8497}
8498
8499void
8500bwi_reset_rx_ring32(struct bwi_softc *sc, uint32_t rx_ctrl)
8501{
8502 int i;
8503
8504 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_CTRL, 0)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((rx_ctrl
+ 0x10)), ((0))))
;
8505
8506#define NRETRY 10
8507 for (i = 0; i < NRETRY; ++i) {
8508 uint32_t status;
8509
8510 status = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((rx_ctrl
+ 0x1c))))
;
8511 if (__SHIFTOUT(status, BWI_RX32_STATUS_STATE_MASK)(((status) & (0xf000)) / ((((0xf000) - 1) & (0xf000))
^ (0xf000)))
==
8512 BWI_RX32_STATUS_STATE_DISABLED0)
8513 break;
8514
8515 DELAY(1000)(*delay_func)(1000);
8516 }
8517 if (i == NRETRY)
8518 printf("%s: reset rx ring timedout\n", sc->sc_dev.dv_xname);
8519#undef NRETRY
8520
8521 CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_RINGINFO, 0)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((rx_ctrl
+ 0x14)), ((0))))
;
8522}
8523
8524void
8525bwi_free_txstats32(struct bwi_softc *sc)
8526{
8527 bwi_reset_rx_ring32(sc, sc->sc_txstats->stats_ctrl_base);
8528}
8529
8530void
8531bwi_free_rx_ring32(struct bwi_softc *sc)
8532{
8533 struct bwi_ring_data *rd = &sc->sc_rx_rdata;
8534 struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
8535 int i;
8536
8537 bwi_reset_rx_ring32(sc, rd->rdata_txrx_ctrl);
8538
8539 for (i = 0; i < BWI_RX_NDESC64; ++i) {
8540 struct bwi_rxbuf *rb = &rbd->rbd_buf[i];
8541
8542 if (rb->rb_mbuf != NULL((void *)0)) {
8543 bus_dmamap_unload(sc->sc_dmat, rb->rb_dmap)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (rb->
rb_dmap))
;
8544 m_freem(rb->rb_mbuf);
8545 rb->rb_mbuf = NULL((void *)0);
8546 }
8547 }
8548}
8549
8550void
8551bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx)
8552{
8553 struct ieee80211com *ic = &sc->sc_ic;
8554 struct bwi_ring_data *rd;
8555 struct bwi_txbuf_data *tbd;
8556 uint32_t state, val;
8557 int i;
8558
8559 KASSERT(ring_idx < BWI_TX_NRING)((ring_idx < 6) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c"
, 8559, "ring_idx < BWI_TX_NRING"))
;
8560 rd = &sc->sc_tx_rdata[ring_idx];
8561 tbd = &sc->sc_tx_bdata[ring_idx];
8562
8563#define NRETRY 10
8564 for (i = 0; i < NRETRY; ++i) {
8565 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((rd->
rdata_txrx_ctrl + 0xc))))
;
8566 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK)(((val) & (0xf000)) / ((((0xf000) - 1) & (0xf000)) ^ (
0xf000)))
;
8567 if (state == BWI_TX32_STATUS_STATE_DISABLED0 ||
8568 state == BWI_TX32_STATUS_STATE_IDLE2 ||
8569 state == BWI_TX32_STATUS_STATE_STOPPED3)
8570 break;
8571
8572 DELAY(1000)(*delay_func)(1000);
8573 }
8574 if (i == NRETRY) {
8575 printf("%s: wait for TX ring(%d) stable timed out\n",
8576 sc->sc_dev.dv_xname, ring_idx);
8577 }
8578
8579 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((rd->
rdata_txrx_ctrl + 0x0)), ((0))))
;
8580 for (i = 0; i < NRETRY; ++i) {
8581 val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((rd->
rdata_txrx_ctrl + 0xc))))
;
8582 state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK)(((val) & (0xf000)) / ((((0xf000) - 1) & (0xf000)) ^ (
0xf000)))
;
8583 if (state == BWI_TX32_STATUS_STATE_DISABLED0)
8584 break;
8585
8586 DELAY(1000)(*delay_func)(1000);
8587 }
8588 if (i == NRETRY)
8589 printf("%s: reset TX ring (%d) timed out\n",
8590 sc->sc_dev.dv_xname, ring_idx);
8591#undef NRETRY
8592
8593 DELAY(1000)(*delay_func)(1000);
8594
8595 CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, 0)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((rd->
rdata_txrx_ctrl + 0x4)), ((0))))
;
8596
8597 for (i = 0; i < BWI_TX_NDESC128; ++i) {
8598 struct bwi_txbuf *tb = &tbd->tbd_buf[i];
8599
8600 if (tb->tb_mbuf != NULL((void *)0)) {
8601 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (tb->
tb_dmap))
;
8602 m_freem(tb->tb_mbuf);
8603 tb->tb_mbuf = NULL((void *)0);
8604 }
8605 if (tb->tb_ni != NULL((void *)0)) {
8606 ieee80211_release_node(ic, tb->tb_ni);
8607 tb->tb_ni = NULL((void *)0);
8608 }
8609 }
8610}
8611
8612uint8_t
8613bwi_plcp2rate(uint32_t plcp0, enum ieee80211_phymode phymode)
8614{
8615 uint32_t plcp = letoh32(plcp0)((__uint32_t)(plcp0)) & IEEE80211_OFDM_PLCP_RATE_MASK0x0000000f;
8616 return (ieee80211_plcp2rate(plcp, phymode));
8617}
8618
8619void
8620bwi_ofdm_plcp_header(uint32_t *plcp0, int pkt_len, uint8_t rate)
8621{
8622 uint32_t plcp;
8623
8624 plcp = __SHIFTIN(ieee80211_rate2plcp(rate, IEEE80211_MODE_11G),((ieee80211_rate2plcp(rate, IEEE80211_MODE_11G)) * ((((0x0000000f
) - 1) & (0x0000000f)) ^ (0x0000000f)))
8625 IEEE80211_OFDM_PLCP_RATE_MASK)((ieee80211_rate2plcp(rate, IEEE80211_MODE_11G)) * ((((0x0000000f
) - 1) & (0x0000000f)) ^ (0x0000000f)))
|
8626 __SHIFTIN(pkt_len, IEEE80211_OFDM_PLCP_LEN_MASK)((pkt_len) * ((((0x0001ffe0) - 1) & (0x0001ffe0)) ^ (0x0001ffe0
)))
;
8627 *plcp0 = htole32(plcp)((__uint32_t)(plcp));
8628}
8629
8630void
8631bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *plcp, int pkt_len,
8632 uint8_t rate)
8633{
8634 int len, service, pkt_bitlen;
8635
8636 pkt_bitlen = pkt_len * NBBY8;
8637 len = howmany(pkt_bitlen * 2, rate)(((pkt_bitlen * 2) + ((rate) - 1)) / (rate));
8638
8639 service = IEEE80211_DS_PLCP_SERVICE_LOCKED0x04;
8640 if (rate == (11 * 2)) {
8641 int pkt_bitlen1;
8642
8643 /*
8644 * PLCP service field needs to be adjusted,
8645 * if TX rate is 11Mbytes/s
8646 */
8647 pkt_bitlen1 = len * 11;
8648 if (pkt_bitlen1 - pkt_bitlen >= NBBY8)
8649 service |= IEEE80211_DS_PLCP_SERVICE_LENEXT70x80;
8650 }
8651
8652 plcp->i_signal = ieee80211_rate2plcp(rate, IEEE80211_MODE_11B);
8653 plcp->i_service = service;
8654 plcp->i_length = htole16(len)((__uint16_t)(len));
8655 /* NOTE: do NOT touch i_crc */
8656}
8657
8658void
8659bwi_plcp_header(void *plcp, int pkt_len, uint8_t rate)
8660{
8661 enum bwi_modtype modtype;
8662
8663 /*
8664 * Assume caller has zeroed 'plcp'
8665 */
8666
8667 modtype = bwi_rate2modtype(rate);
8668 if (modtype == IEEE80211_MODTYPE_OFDM)
8669 bwi_ofdm_plcp_header(plcp, pkt_len, rate);
8670 else if (modtype == IEEE80211_MODTYPE_DS)
8671 bwi_ds_plcp_header(plcp, pkt_len, rate);
8672 else
8673 panic("unsupported modulation type %u", modtype);
8674}
8675
8676enum bwi_modtype
8677bwi_rate2modtype(uint8_t rate)
8678{
8679 rate &= IEEE80211_RATE_VAL0x7f;
8680
8681 if (rate == 44)
8682 return IEEE80211_MODTYPE_PBCC;
8683 else if (rate == 22 || rate < 12)
8684 return IEEE80211_MODTYPE_DS;
8685 else
8686 return IEEE80211_MODTYPE_OFDM;
8687}
8688
8689uint8_t
8690bwi_ack_rate(struct ieee80211_node *ni, uint8_t rate)
8691{
8692 const struct ieee80211_rateset *rs = &ni->ni_rates;
8693 uint8_t ack_rate = 0;
8694 enum bwi_modtype modtype;
8695 int i;
8696
8697 rate &= IEEE80211_RATE_VAL0x7f;
8698
8699 modtype = bwi_rate2modtype(rate);
8700
8701 for (i = 0; i < rs->rs_nrates; ++i) {
8702 uint8_t rate1 = rs->rs_rates[i] & IEEE80211_RATE_VAL0x7f;
8703
8704 if (rate1 > rate) {
8705 if (ack_rate != 0)
8706 return ack_rate;
8707 else
8708 break;
8709 }
8710
8711 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC0x80) &&
8712 bwi_rate2modtype(rate1) == modtype)
8713 ack_rate = rate1;
8714 }
8715
8716 switch (rate) {
8717 /* CCK */
8718 case 2:
8719 case 4:
8720 case 11:
8721 case 22:
8722 ack_rate = rate;
8723 break;
8724 /* PBCC */
8725 case 44:
8726 ack_rate = 22;
8727 break;
8728
8729 /* OFDM */
8730 case 12:
8731 case 18:
8732 ack_rate = 12;
8733 break;
8734 case 24:
8735 case 36:
8736 ack_rate = 24;
8737 break;
8738 case 48:
8739 case 72:
8740 case 96:
8741 case 108:
8742 ack_rate = 48;
8743 break;
8744 default:
8745 panic("unsupported rate %d", rate);
8746 }
8747 return ack_rate;
8748}
8749
8750#define IEEE80211_OFDM_TXTIME(kbps, frmlen)(16 + 4 + (((((16 + ((((frmlen))) * 8) + 6)) + (((((((kbps)))
* 4) / 1000)) - 1)) / ((((((kbps))) * 4) / 1000))) * 4))
\
8751 (IEEE80211_OFDM_PREAMBLE_TIME16 + \
8752 IEEE80211_OFDM_SIGNAL_TIME4 + \
8753 (IEEE80211_OFDM_NSYMS((kbps), (frmlen))((((16 + ((((frmlen))) * 8) + 6)) + (((((((kbps))) * 4) / 1000
)) - 1)) / ((((((kbps))) * 4) / 1000)))
* IEEE80211_OFDM_SYM_TIME4))
8754
8755#define IEEE80211_OFDM_SYM_TIME4 4
8756#define IEEE80211_OFDM_PREAMBLE_TIME16 16
8757#define IEEE80211_OFDM_SIGNAL_EXT_TIME6 6
8758#define IEEE80211_OFDM_SIGNAL_TIME4 4
8759
8760#define IEEE80211_OFDM_PLCP_SERVICE_NBITS16 16
8761#define IEEE80211_OFDM_TAIL_NBITS6 6
8762
8763#define IEEE80211_OFDM_NBITS(frmlen)(16 + ((frmlen) * 8) + 6) \
8764 (IEEE80211_OFDM_PLCP_SERVICE_NBITS16 + \
8765 ((frmlen) * NBBY8) + \
8766 IEEE80211_OFDM_TAIL_NBITS6)
8767
8768#define IEEE80211_OFDM_NBITS_PER_SYM(kbps)(((kbps) * 4) / 1000) \
8769 (((kbps) * IEEE80211_OFDM_SYM_TIME4) / 1000)
8770
8771#define IEEE80211_OFDM_NSYMS(kbps, frmlen)((((16 + (((frmlen)) * 8) + 6)) + ((((((kbps)) * 4) / 1000)) -
1)) / (((((kbps)) * 4) / 1000)))
\
8772 howmany(IEEE80211_OFDM_NBITS((frmlen)), \((((16 + (((frmlen)) * 8) + 6)) + ((((((kbps)) * 4) / 1000)) -
1)) / (((((kbps)) * 4) / 1000)))
8773 IEEE80211_OFDM_NBITS_PER_SYM((kbps)))((((16 + (((frmlen)) * 8) + 6)) + ((((((kbps)) * 4) / 1000)) -
1)) / (((((kbps)) * 4) / 1000)))
8774
8775#define IEEE80211_CCK_TXTIME(kbps, frmlen)((((((frmlen)) * 8) * 1000) + (kbps) - 1) / (kbps)) \
8776 (((IEEE80211_CCK_NBITS((frmlen))(((frmlen)) * 8) * 1000) + (kbps) - 1) / (kbps))
8777
8778#define IEEE80211_CCK_PREAMBLE_LEN144 144
8779#define IEEE80211_CCK_PLCP_HDR_TIME48 48
8780#define IEEE80211_CCK_SHPREAMBLE_LEN72 72
8781#define IEEE80211_CCK_SHPLCP_HDR_TIME24 24
8782
8783#define IEEE80211_CCK_NBITS(frmlen)((frmlen) * 8) ((frmlen) * NBBY8)
8784
8785uint16_t
8786bwi_txtime(struct ieee80211com *ic, struct ieee80211_node *ni, uint len,
8787 uint8_t rs_rate, uint32_t flags)
8788{
8789 enum bwi_modtype modtype;
8790 uint16_t txtime;
8791 int rate;
8792
8793 rs_rate &= IEEE80211_RATE_VAL0x7f;
8794
8795 rate = rs_rate * 500; /* ieee80211 rate -> kbps */
8796
8797 modtype = bwi_rate2modtype(rs_rate);
8798 if (modtype == IEEE80211_MODTYPE_OFDM) {
8799 /*
8800 * IEEE Std 802.11a-1999, page 37, equation (29)
8801 * IEEE Std 802.11g-2003, page 44, equation (42)
8802 */
8803 txtime = IEEE80211_OFDM_TXTIME(rate, len)(16 + 4 + (((((16 + ((((len))) * 8) + 6)) + (((((((rate))) * 4
) / 1000)) - 1)) / ((((((rate))) * 4) / 1000))) * 4))
;
8804 if (ic->ic_curmode == IEEE80211_MODE_11G)
8805 txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME6;
8806 } else {
8807 /*
8808 * IEEE Std 802.11b-1999, page 28, subclause 18.3.4
8809 * IEEE Std 802.11g-2003, page 45, equation (43)
8810 */
8811 if (modtype == IEEE80211_MODTYPE_PBCC)
8812 ++len;
8813 txtime = IEEE80211_CCK_TXTIME(rate, len)((((((len)) * 8) * 1000) + (rate) - 1) / (rate));
8814
8815 /*
8816 * Short preamble is not applicable for DS 1Mbits/s
8817 */
8818 if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE0x00040000)) {
8819 txtime += IEEE80211_CCK_SHPREAMBLE_LEN72 +
8820 IEEE80211_CCK_SHPLCP_HDR_TIME24;
8821 } else {
8822 txtime += IEEE80211_CCK_PREAMBLE_LEN144 +
8823 IEEE80211_CCK_PLCP_HDR_TIME48;
8824 }
8825 }
8826 return txtime;
8827}
8828
8829int
8830bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
8831 struct ieee80211_node *ni)
8832{
8833 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
8834
8835 struct ieee80211com *ic = &sc->sc_ic;
8836 struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING1];
8837 struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING1];
8838 struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
8839 struct bwi_mac *mac;
8840 struct bwi_txbuf_hdr *hdr;
8841 struct ieee80211_frame *wh;
8842 uint8_t rate;
8843 uint32_t mac_ctrl;
8844 uint16_t phy_ctrl;
8845 bus_addr_t paddr;
8846 int pkt_len, error = 0;
8847#if 0
8848 const uint8_t *p;
8849 int i;
8850#endif
8851
8852 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", 8852, "sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC"
))
;
8853 mac = (struct bwi_mac *)sc->sc_cur_regwin;
8854
8855 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
8856
8857 /* Get 802.11 frame len before prepending TX header */
8858 pkt_len = m->m_pkthdrM_dat.MH.MH_pkthdr.len + IEEE80211_CRC_LEN4;
8859
8860 /*
8861 * Find TX rate
8862 */
8863 bzero(tb->tb_rate_idx, sizeof(tb->tb_rate_idx))__builtin_bzero((tb->tb_rate_idx), (sizeof(tb->tb_rate_idx
)))
;
8864 if (ni != NULL((void *)0)) {
8865 if (ic->ic_fixed_rate != -1) {
8866 rate = ic->ic_sup_rates[ic->ic_curmode].
8867 rs_rates[ic->ic_fixed_rate];
8868 } else {
8869 /* AMRR rate control */
8870 rate = ni->ni_rates.rs_rates[ni->ni_txrate];
8871 }
8872 } else {
8873 /* Fixed at 1Mbytes/s for mgt frames */
8874 rate = (1 * 2);
8875 }
8876
8877 rate &= IEEE80211_RATE_VAL0x7f;
8878
8879 if (IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01))
8880 rate = (1 * 2);
8881
8882 if (rate == 0) {
8883 printf("%s: invalid rate %u or fallback rate",
8884 sc->sc_dev.dv_xname, rate);
8885 rate = (1 * 2); /* Force 1Mbytes/s */
8886 }
8887 sc->sc_tx_rate = rate;
8888
8889#if NBPFILTER1 > 0
8890 /* TX radio tap */
8891 if (sc->sc_drvbpf != NULL((void *)0)) {
8892 struct mbuf mb;
8893 struct bwi_tx_radiotap_hdr *tap = &sc->sc_txtapsc_txtapu.th;
8894
8895 tap->wt_flags = 0;
8896 tap->wt_rate = rate;
8897 tap->wt_chan_freq =
8898 htole16(ic->ic_bss->ni_chan->ic_freq)((__uint16_t)(ic->ic_bss->ni_chan->ic_freq));
8899 tap->wt_chan_flags =
8900 htole16(ic->ic_bss->ni_chan->ic_flags)((__uint16_t)(ic->ic_bss->ni_chan->ic_flags));
8901
8902 mb.m_datam_hdr.mh_data = (caddr_t)tap;
8903 mb.m_lenm_hdr.mh_len = sc->sc_txtap_len;
8904 mb.m_nextm_hdr.mh_next = m;
8905 mb.m_nextpktm_hdr.mh_nextpkt = NULL((void *)0);
8906 mb.m_typem_hdr.mh_type = 0;
8907 mb.m_flagsm_hdr.mh_flags = 0;
8908 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT(1 << 1));
8909 }
8910#endif
8911
8912 /*
8913 * Setup the embedded TX header
8914 */
8915 M_PREPEND(m, sizeof(*hdr), M_DONTWAIT)(m) = m_prepend((m), (sizeof(*hdr)), (0x0002));
8916 if (m == NULL((void *)0)) {
8917 printf("%s: prepend TX header failed\n", sc->sc_dev.dv_xname);
8918 return (ENOBUFS55);
8919 }
8920 hdr = mtod(m, struct bwi_txbuf_hdr *)((struct bwi_txbuf_hdr *)((m)->m_hdr.mh_data));
8921
8922 bzero(hdr, sizeof(*hdr))__builtin_bzero((hdr), (sizeof(*hdr)));
8923
8924 bcopy(wh->i_fc, hdr->txh_fc, sizeof(hdr->txh_fc));
8925 bcopy(wh->i_addr1, hdr->txh_addr1, sizeof(hdr->txh_addr1));
8926
8927 if (ni != NULL((void *)0) && !IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01)) {
8928 uint16_t dur;
8929 uint8_t ack_rate;
8930
8931 ack_rate = bwi_ack_rate(ni, rate);
8932 dur = bwi_txtime(ic, ni,
8933 sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN4,
8934 ack_rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE0x00040000);
8935
8936 hdr->txh_fb_duration = htole16(dur)((__uint16_t)(dur));
8937 }
8938
8939 hdr->txh_id = __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK)((1) * ((((0xe000) - 1) & (0xe000)) ^ (0xe000))) |
8940 __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK)((idx) * ((((0x1fff) - 1) & (0x1fff)) ^ (0x1fff)));
8941
8942 bwi_plcp_header(hdr->txh_plcp, pkt_len, rate);
8943 bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate);
8944
8945 phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode,((mac->mac_rf.rf_ant_mode) * ((((0x0300) - 1) & (0x0300
)) ^ (0x0300)))
8946 BWI_TXH_PHY_C_ANTMODE_MASK)((mac->mac_rf.rf_ant_mode) * ((((0x0300) - 1) & (0x0300
)) ^ (0x0300)))
;
8947 if (bwi_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM)
8948 phy_ctrl |= BWI_TXH_PHY_C_OFDM(1 << 0);
8949 else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE0x00040000) && rate != (2 * 1))
8950 phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE(1 << 4);
8951
8952 mac_ctrl = BWI_TXH_MAC_C_HWSEQ(1 << 4) | BWI_TXH_MAC_C_FIRST_FRAG(1 << 3);
8953 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01))
8954 mac_ctrl |= BWI_TXH_MAC_C_ACK(1 << 0);
8955 if (bwi_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM)
8956 mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM(1 << 8);
8957
8958 hdr->txh_mac_ctrl = htole32(mac_ctrl)((__uint32_t)(mac_ctrl));
8959 hdr->txh_phy_ctrl = htole16(phy_ctrl)((__uint16_t)(phy_ctrl));
8960
8961 /* Catch any further usage */
8962 hdr = NULL((void *)0);
8963 wh = NULL((void *)0);
8964
8965 if (sc->sc_bus_space == BWI_BUS_SPACE_30BIT) {
8966 /* Bounce for 30bit devices. */
8967 m_copydata(m, 0, m->m_pkthdrM_dat.MH.MH_pkthdr.len,
8968 sc->sc_bounce_tx_data[BWI_TX_DATA_RING1] +
8969 (MCLBYTES(1 << 11) * idx));
8970 } else {
8971 /* DMA load */
8972 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m,(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
tb->tb_dmap), (m), (0x0001))
8973 BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
tb->tb_dmap), (m), (0x0001))
;
8974 if (error && error != EFBIG27) {
8975 printf("%s: can't load TX buffer (1) %d\n",
8976 sc->sc_dev.dv_xname, error);
8977 goto back;
8978 }
8979
8980 if (error) { /* error == EFBIG */
8981 if (m_defrag(m, M_DONTWAIT0x0002)) {
8982 printf("%s: can't defrag TX buffer\n",
8983 sc->sc_dev.dv_xname);
8984 goto back;
8985 }
8986 error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap,(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
tb->tb_dmap), (m), (0x0001))
8987 m, BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
tb->tb_dmap), (m), (0x0001))
;
8988 if (error) {
8989 printf("%s: can't load TX buffer (2) %d\n",
8990 sc->sc_dev.dv_xname, error);
8991 goto back;
8992 }
8993 }
8994 error = 0;
8995 }
8996
8997 bus_dmamap_sync(sc->sc_dmat, tb->tb_dmap, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (tb->
tb_dmap), (0), (tb->tb_dmap->dm_mapsize), (0x04))
8998 tb->tb_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (tb->
tb_dmap), (0), (tb->tb_dmap->dm_mapsize), (0x04))
;
8999
9000 tb->tb_mbuf = m;
9001 tb->tb_ni = ni;
9002
9003#if 0
9004 p = mtod(m, const uint8_t *)((const uint8_t *)((m)->m_hdr.mh_data));
9005 for (i = 0; i < m->m_pkthdrM_dat.MH.MH_pkthdr.len; ++i) {
9006 if (i != 0 && i % 8 == 0)
9007 printf("\n");
9008 printf("%02x ", p[i]);
9009 }
9010 printf("\n");
9011
9012 DPRINTF(1, "%s: idx %d, pkt_len %d, buflen %d\n",
9013 sc->sc_dev.dv_xname, idx, pkt_len, m->m_pkthdr.len);
9014#endif
9015
9016 /* Setup TX descriptor */
9017 paddr = tb->tb_dmap->dm_segs[0].ds_addr;
9018 sc->sc_setup_txdesc(sc, rd, idx, paddr, m->m_pkthdrM_dat.MH.MH_pkthdr.len);
9019 bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rd->
rdata_dmap), (0), (rd->rdata_dmap->dm_mapsize), (0x04))
9020 rd->rdata_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (rd->
rdata_dmap), (0), (rd->rdata_dmap->dm_mapsize), (0x04))
;
9021
9022 /* Kick start */
9023 sc->sc_start_tx(sc, rd->rdata_txrx_ctrl, idx);
9024
9025back:
9026 if (error)
9027 m_freem(m);
9028 return (error);
9029}
9030
9031void
9032bwi_start_tx32(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
9033{
9034 idx = (idx + 1) % BWI_TX_NDESC128;
9035 CSR_WRITE_4(sc, tx_ctrl + BWI_TX32_INDEX,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((tx_ctrl
+ 0x8)), ((idx * sizeof(struct bwi_desc32)))))
9036 idx * sizeof(struct bwi_desc32))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((tx_ctrl
+ 0x8)), ((idx * sizeof(struct bwi_desc32)))))
;
9037}
9038
9039void
9040bwi_txeof_status32(struct bwi_softc *sc)
9041{
9042 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
9043 uint32_t val, ctrl_base;
9044 int end_idx;
9045
9046 ctrl_base = sc->sc_txstats->stats_ctrl_base;
9047
9048 val = CSR_READ_4(sc, ctrl_base + BWI_RX32_STATUS)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((ctrl_base
+ 0x1c))))
;
9049 end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK)(((val) & (0x0fff)) / ((((0x0fff) - 1) & (0x0fff)) ^ (
0x0fff)))
/
9050 sizeof(struct bwi_desc32);
9051
9052 bwi_txeof_status(sc, end_idx);
9053
9054 CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((ctrl_base
+ 0x18)), ((end_idx * sizeof(struct bwi_desc32)))))
9055 end_idx * sizeof(struct bwi_desc32))(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((ctrl_base
+ 0x18)), ((end_idx * sizeof(struct bwi_desc32)))))
;
9056
9057 if (ifq_is_oactive(&ifp->if_snd) == 0)
9058 ifp->if_start(ifp);
9059}
9060
9061void
9062_bwi_txeof(struct bwi_softc *sc, uint16_t tx_id)
9063{
9064 struct ieee80211com *ic = &sc->sc_ic;
9065 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
9066 struct bwi_txbuf_data *tbd;
9067 struct bwi_txbuf *tb;
9068 int ring_idx, buf_idx;
9069
9070 if (tx_id == 0) {
9071 printf("%s: zero tx id\n", sc->sc_dev.dv_xname);
9072 return;
9073 }
9074
9075 ring_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_RING_MASK)(((tx_id) & (0xe000)) / ((((0xe000) - 1) & (0xe000)) ^
(0xe000)))
;
9076 buf_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_IDX_MASK)(((tx_id) & (0x1fff)) / ((((0x1fff) - 1) & (0x1fff)) ^
(0x1fff)))
;
9077
9078 KASSERT(ring_idx == BWI_TX_DATA_RING)((ring_idx == 1) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c"
, 9078, "ring_idx == BWI_TX_DATA_RING"))
;
9079 KASSERT(buf_idx < BWI_TX_NDESC)((buf_idx < 128) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/bwi.c"
, 9079, "buf_idx < BWI_TX_NDESC"))
;
9080#if 0
9081 DPRINTF(1, "%s: txeof idx %d\n", sc->sc_dev.dv_xname, buf_idx);
9082#endif
9083 tbd = &sc->sc_tx_bdata[ring_idx];
9084 KASSERT(tbd->tbd_used > 0)((tbd->tbd_used > 0) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/ic/bwi.c", 9084, "tbd->tbd_used > 0"
))
;
9085 tbd->tbd_used--;
9086
9087 tb = &tbd->tbd_buf[buf_idx];
9088
9089 bus_dmamap_unload(sc->sc_dmat, tb->tb_dmap)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (tb->
tb_dmap))
;
9090 m_freem(tb->tb_mbuf);
9091 tb->tb_mbuf = NULL((void *)0);
9092
9093 if (tb->tb_ni != NULL((void *)0)) {
9094 ieee80211_release_node(ic, tb->tb_ni);
9095 tb->tb_ni = NULL((void *)0);
9096 }
9097
9098 if (tbd->tbd_used == 0)
9099 sc->sc_tx_timer = 0;
9100
9101 ifq_clr_oactive(&ifp->if_snd);
9102}
9103
9104void
9105bwi_txeof_status(struct bwi_softc *sc, int end_idx)
9106{
9107 struct bwi_txstats_data *st = sc->sc_txstats;
9108 int idx;
9109
9110 bus_dmamap_sync(sc->sc_dmat, st->stats_dmap, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (st->
stats_dmap), (0), (st->stats_dmap->dm_mapsize), (0x02))
9111 st->stats_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (st->
stats_dmap), (0), (st->stats_dmap->dm_mapsize), (0x02))
;
9112
9113 idx = st->stats_idx;
9114 while (idx != end_idx) {
9115 _bwi_txeof(sc, letoh16(st->stats[idx].txs_id)((__uint16_t)(st->stats[idx].txs_id)));
9116 idx = (idx + 1) % BWI_TXSTATS_NDESC64;
9117 }
9118 st->stats_idx = idx;
9119}
9120
9121void
9122bwi_txeof(struct bwi_softc *sc)
9123{
9124 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
9125
9126 for (;;) {
9127 uint32_t tx_status0, tx_status1;
9128 uint16_t tx_id, tx_info;
9129
9130 tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000170
))))
;
9131 if (tx_status0 == 0)
9132 break;
9133 tx_status1 = CSR_READ_4(sc, BWI_TXSTATUS_1)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000174
))))
;
9134
9135 tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK)(((tx_status0) & (0xffff0000)) / ((((0xffff0000) - 1) &
(0xffff0000)) ^ (0xffff0000)))
;
9136 tx_info = BWI_TXSTATUS_0_INFO(tx_status0)(((tx_status0) & 0xfff0) | (((tx_status0) & 0xf) >>
1))
;
9137
9138 if (tx_info & 0x30) /* XXX */
9139 continue;
9140
9141 _bwi_txeof(sc, letoh16(tx_id)((__uint16_t)(tx_id)));
9142 }
9143
9144 if (ifq_is_oactive(&ifp->if_snd) == 0)
9145 ifp->if_start(ifp);
9146}
9147
9148int
9149bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
9150{
9151 bwi_power_on(sc, 1);
9152
9153 return (bwi_set_clock_mode(sc, clk_mode));
9154}
9155
9156void
9157bwi_bbp_power_off(struct bwi_softc *sc)
9158{
9159 bwi_set_clock_mode(sc, BWI_CLOCK_MODE_SLOW);
9160 bwi_power_off(sc, 1);
9161}
9162
9163int
9164bwi_get_pwron_delay(struct bwi_softc *sc)
9165{
9166 struct bwi_regwin *com, *old;
9167 struct bwi_clock_freq freq;
9168 uint32_t val;
9169 int error;
9170
9171 com = &sc->sc_com_regwin;
9172 KASSERT(BWI_REGWIN_EXIST(com))((((com)->rw_flags & 0x1)) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/ic/bwi.c", 9172, "BWI_REGWIN_EXIST(com)")
)
;
9173
9174 if ((sc->sc_cap & BWI_CAP_CLKMODE(1 << 18)) == 0)
9175 return (0);
9176
9177 error = bwi_regwin_switch(sc, com, &old);
9178 if (error)
9179 return (error);
9180
9181 bwi_get_clock_freq(sc, &freq);
9182
9183 val = CSR_READ_4(sc, BWI_PLL_ON_DELAY)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0xb0
))))
;
9184 sc->sc_pwron_delay = howmany((val + 2) * 1000000, freq.clkfreq_min)((((val + 2) * 1000000) + ((freq.clkfreq_min) - 1)) / (freq.clkfreq_min
))
;
9185 DPRINTF(1, "%s: power on delay %u\n",
9186 sc->sc_dev.dv_xname, sc->sc_pwron_delay);
9187
9188 return (bwi_regwin_switch(sc, old, NULL((void *)0)));
9189}
9190
9191int
9192bwi_bus_attach(struct bwi_softc *sc)
9193{
9194 struct bwi_regwin *bus, *old;
9195 int error;
9196
9197 bus = &sc->sc_bus_regwin;
9198
9199 error = bwi_regwin_switch(sc, bus, &old);
9200 if (error)
9201 return (error);
9202
9203 if (!bwi_regwin_is_enabled(sc, bus))
9204 bwi_regwin_enable(sc, bus, 0);
9205
9206 /* Disable interrupts */
9207 CSR_WRITE_4(sc, BWI_INTRVEC, 0)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000f94
)), ((0))))
;
9208
9209 return (bwi_regwin_switch(sc, old, NULL((void *)0)));
9210}
9211
9212const char *
9213bwi_regwin_name(const struct bwi_regwin *rw)
9214{
9215 switch (rw->rw_type) {
9216 case BWI_REGWIN_T_COM0x800:
9217 return ("COM");
9218 case BWI_REGWIN_T_BUSPCI0x804:
9219 return ("PCI");
9220 case BWI_REGWIN_T_MAC0x812:
9221 return ("MAC");
9222 case BWI_REGWIN_T_BUSPCIE0x820:
9223 return ("PCIE");
9224 }
9225 panic("unknown regwin type 0x%04x", rw->rw_type);
9226
9227 return (NULL((void *)0));
9228}
9229
9230uint32_t
9231bwi_regwin_disable_bits(struct bwi_softc *sc)
9232{
9233 uint32_t busrev;
9234
9235 /* XXX cache this */
9236 busrev = __SHIFTOUT(CSR_READ_4(sc, BWI_ID_LO), BWI_ID_LO_BUSREV_MASK)((((((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000ff8
))))) & (0xf0000000)) / ((((0xf0000000) - 1) & (0xf0000000
)) ^ (0xf0000000)))
;
9237 DPRINTF(1, "%s: bus rev %u\n", sc->sc_dev.dv_xname, busrev);
9238
9239 if (busrev == BWI_BUSREV_00)
9240 return (BWI_STATE_LO_DISABLE1(1 << 1));
9241 else if (busrev == BWI_BUSREV_11)
9242 return (BWI_STATE_LO_DISABLE2(1 << 2));
9243 else
9244 return ((BWI_STATE_LO_DISABLE1(1 << 1) | BWI_STATE_LO_DISABLE2(1 << 2)));
9245}
9246
9247int
9248bwi_regwin_is_enabled(struct bwi_softc *sc, struct bwi_regwin *rw)
9249{
9250 uint32_t val, disable_bits;
9251
9252 disable_bits = bwi_regwin_disable_bits(sc);
9253 val = CSR_READ_4(sc, BWI_STATE_LO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f98
))))
;
9254
9255 if ((val & (BWI_STATE_LO_CLOCK(1 << 16) |
9256 BWI_STATE_LO_RESET(1 << 0) |
9257 disable_bits)) == BWI_STATE_LO_CLOCK(1 << 16)) {
9258 DPRINTF(1, "%s: %s is enabled\n",
9259 sc->sc_dev.dv_xname, bwi_regwin_name(rw));
9260 return (1);
9261 } else {
9262 DPRINTF(1, "%s: %s is disabled\n",
9263 sc->sc_dev.dv_xname, bwi_regwin_name(rw));
9264 return (0);
9265 }
9266}
9267
9268void
9269bwi_regwin_disable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
9270{
9271 uint32_t state_lo, disable_bits;
9272 int i;
9273
9274 state_lo = CSR_READ_4(sc, BWI_STATE_LO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f98
))))
;
9275
9276 /*
9277 * If current regwin is in 'reset' state, it was already disabled.
9278 */
9279 if (state_lo & BWI_STATE_LO_RESET(1 << 0)) {
9280 DPRINTF(1, "%s: %s was already disabled\n",
9281 sc->sc_dev.dv_xname, bwi_regwin_name(rw));
9282 return;
9283 }
9284
9285 disable_bits = bwi_regwin_disable_bits(sc);
9286
9287 /*
9288 * Disable normal clock
9289 */
9290 state_lo = BWI_STATE_LO_CLOCK(1 << 16) | disable_bits;
9291 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000f98
)), ((state_lo))))
;
9292
9293 /*
9294 * Wait until normal clock is disabled
9295 */
9296#define NRETRY 1000
9297 for (i = 0; i < NRETRY; ++i) {
9298 state_lo = CSR_READ_4(sc, BWI_STATE_LO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f98
))))
;
9299 if (state_lo & disable_bits)
9300 break;
9301 DELAY(10)(*delay_func)(10);
9302 }
9303 if (i == NRETRY) {
9304 printf("%s: %s disable clock timeout\n",
9305 sc->sc_dev.dv_xname, bwi_regwin_name(rw));
9306 }
9307
9308 for (i = 0; i < NRETRY; ++i) {
9309 uint32_t state_hi;
9310
9311 state_hi = CSR_READ_4(sc, BWI_STATE_HI)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f9c
))))
;
9312 if ((state_hi & BWI_STATE_HI_BUSY(1 << 2)) == 0)
9313 break;
9314 DELAY(10)(*delay_func)(10);
9315 }
9316 if (i == NRETRY) {
9317 printf("%s: %s wait BUSY unset timeout\n",
9318 sc->sc_dev.dv_xname, bwi_regwin_name(rw));
9319 }
9320#undef NRETRY
9321
9322 /*
9323 * Reset and disable regwin with gated clock
9324 */
9325 state_lo = BWI_STATE_LO_RESET(1 << 0) | disable_bits |
9326 BWI_STATE_LO_CLOCK(1 << 16) | BWI_STATE_LO_GATED_CLOCK(1 << 17) |
9327 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK)((flags) * ((((0x3ffc0000) - 1) & (0x3ffc0000)) ^ (0x3ffc0000
)))
;
9328 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000f98
)), ((state_lo))))
;
9329
9330 /* Flush pending bus write */
9331 CSR_READ_4(sc, BWI_STATE_LO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f98
))))
;
9332 DELAY(1)(*delay_func)(1);
9333
9334 /* Reset and disable regwin */
9335 state_lo = BWI_STATE_LO_RESET(1 << 0) | disable_bits |
9336 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK)((flags) * ((((0x3ffc0000) - 1) & (0x3ffc0000)) ^ (0x3ffc0000
)))
;
9337 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000f98
)), ((state_lo))))
;
9338
9339 /* Flush pending bus write */
9340 CSR_READ_4(sc, BWI_STATE_LO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f98
))))
;
9341 DELAY(1)(*delay_func)(1);
9342}
9343
9344void
9345bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
9346{
9347 uint32_t state_lo, state_hi, imstate;
9348
9349 bwi_regwin_disable(sc, rw, flags);
9350
9351 /* Reset regwin with gated clock */
9352 state_lo = BWI_STATE_LO_RESET(1 << 0) |
9353 BWI_STATE_LO_CLOCK(1 << 16) |
9354 BWI_STATE_LO_GATED_CLOCK(1 << 17) |
9355 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK)((flags) * ((((0x3ffc0000) - 1) & (0x3ffc0000)) ^ (0x3ffc0000
)))
;
9356 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000f98
)), ((state_lo))))
;
9357
9358 /* Flush pending bus write */
9359 CSR_READ_4(sc, BWI_STATE_LO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f98
))))
;
9360 DELAY(1)(*delay_func)(1);
9361
9362 state_hi = CSR_READ_4(sc, BWI_STATE_HI)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f9c
))))
;
9363 if (state_hi & BWI_STATE_HI_SERROR(1 << 0))
9364 CSR_WRITE_4(sc, BWI_STATE_HI, 0)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000f9c
)), ((0))))
;
9365
9366 imstate = CSR_READ_4(sc, BWI_IMSTATE)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f90
))))
;
9367 if (imstate & (BWI_IMSTATE_INBAND_ERR(1 << 17) | BWI_IMSTATE_TIMEOUT(1 << 18))) {
9368 imstate &= ~(BWI_IMSTATE_INBAND_ERR(1 << 17) | BWI_IMSTATE_TIMEOUT(1 << 18));
9369 CSR_WRITE_4(sc, BWI_IMSTATE, imstate)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000f90
)), ((imstate))))
;
9370 }
9371
9372 /* Enable regwin with gated clock */
9373 state_lo = BWI_STATE_LO_CLOCK(1 << 16) |
9374 BWI_STATE_LO_GATED_CLOCK(1 << 17) |
9375 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK)((flags) * ((((0x3ffc0000) - 1) & (0x3ffc0000)) ^ (0x3ffc0000
)))
;
9376 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000f98
)), ((state_lo))))
;
9377
9378 /* Flush pending bus write */
9379 CSR_READ_4(sc, BWI_STATE_LO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f98
))))
;
9380 DELAY(1)(*delay_func)(1);
9381
9382 /* Enable regwin with normal clock */
9383 state_lo = BWI_STATE_LO_CLOCK(1 << 16) |
9384 __SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK)((flags) * ((((0x3ffc0000) - 1) & (0x3ffc0000)) ^ (0x3ffc0000
)))
;
9385 CSR_WRITE_4(sc, BWI_STATE_LO, state_lo)(((sc)->sc_mem_bt)->write_4(((sc)->sc_mem_bh), ((0x00000f98
)), ((state_lo))))
;
9386
9387 /* Flush pending bus write */
9388 CSR_READ_4(sc, BWI_STATE_LO)(((sc)->sc_mem_bt)->read_4(((sc)->sc_mem_bh), ((0x00000f98
))))
;
9389 DELAY(1)(*delay_func)(1);
9390}
9391
9392void
9393bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid)
9394{
9395 struct ieee80211com *ic = &sc->sc_ic;
9396 struct bwi_mac *mac;
9397 struct bwi_myaddr_bssid buf;
9398 const uint8_t *p;
9399 uint32_t val;
9400 int n, i;
9401
9402 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", 9402, "sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC"
))
;
9403 mac = (struct bwi_mac *)sc->sc_cur_regwin;
9404
9405 bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID3, bssid);
9406
9407 bcopy(ic->ic_myaddr, buf.myaddr, sizeof(buf.myaddr));
9408 bcopy(bssid, buf.bssid, sizeof(buf.bssid));
9409
9410 n = sizeof(buf) / sizeof(val);
9411 p = (const uint8_t *)&buf;
9412 for (i = 0; i < n; ++i) {
9413 int j;
9414
9415 val = 0;
9416 for (j = 0; j < sizeof(val); ++j)
9417 val |= ((uint32_t)(*p++)) << (j * 8);
9418
9419 TMPLT_WRITE_4(mac, 0x20 + (i * sizeof(val)), val)bwi_tmplt_write_4((mac), (0x20 + (i * sizeof(val))), (val));
9420 }
9421}
9422
9423void
9424bwi_updateslot(struct ieee80211com *ic)
9425{
9426 struct bwi_softc *sc = ic->ic_ific_ac.ac_if.if_softc;
9427 struct bwi_mac *mac;
9428 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
9429
9430 if ((ifp->if_flags & IFF_RUNNING0x40) == 0)
9431 return;
9432
9433 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
9434
9435 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", 9435, "sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC"
))
;
9436 mac = (struct bwi_mac *)sc->sc_cur_regwin;
9437
9438 bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT0x00020000));
9439}
9440
9441void
9442bwi_calibrate(void *xsc)
9443{
9444 struct bwi_softc *sc = xsc;
9445 struct ieee80211com *ic = &sc->sc_ic;
9446 int s;
9447
9448 s = splnet()splraise(0x7);
9449
9450 if (ic->ic_state == IEEE80211_S_RUN) {
9451 struct bwi_mac *mac;
9452
9453 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", 9453, "sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC"
))
;
9454 mac = (struct bwi_mac *)sc->sc_cur_regwin;
9455
9456 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
9457 bwi_mac_calibrate_txpower(mac, sc->sc_txpwrcb_type);
9458 sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
9459 }
9460
9461 /* XXX 15 seconds */
9462 timeout_add_sec(&sc->sc_calib_ch, 15);
9463 }
9464
9465 splx(s)spllower(s);
9466}
9467
9468int
9469bwi_calc_rssi(struct bwi_softc *sc, const struct bwi_rxbuf_hdr *hdr)
9470{
9471 struct bwi_mac *mac;
9472
9473 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", 9473, "sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC"
))
;
9474 mac = (struct bwi_mac *)sc->sc_cur_regwin;
9475
9476 return (bwi_rf_calc_rssi(mac, hdr));
9477}