Bug Summary

File:dev/ic/ar9285.c
Warning:line 810, column 2
Value stored to 'max_ant_gain' 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 ar9285.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/ar9285.c
1/* $OpenBSD: ar9285.c,v 1.30 2022/01/09 05:42:38 jsg Exp $ */
2
3/*-
4 * Copyright (c) 2009-2010 Damien Bergamini <damien.bergamini@free.fr>
5 * Copyright (c) 2008-2010 Atheros Communications Inc.
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20/*
21 * Driver for Atheros 802.11a/g/n chipsets.
22 * Routines for AR9285 and AR9271 chipsets.
23 */
24
25#include "athn_usb.h"
26#include "bpfilter.h"
27
28#include <sys/param.h>
29#include <sys/sockio.h>
30#include <sys/mbuf.h>
31#include <sys/kernel.h>
32#include <sys/socket.h>
33#include <sys/systm.h>
34#include <sys/malloc.h>
35#include <sys/queue.h>
36#include <sys/timeout.h>
37#include <sys/conf.h>
38#include <sys/device.h>
39#include <sys/endian.h>
40
41#include <machine/bus.h>
42#include <machine/intr.h>
43
44#if NBPFILTER1 > 0
45#include <net/bpf.h>
46#endif
47#include <net/if.h>
48#include <net/if_media.h>
49
50#include <netinet/in.h>
51#include <netinet/if_ether.h>
52
53#include <net80211/ieee80211_var.h>
54#include <net80211/ieee80211_amrr.h>
55#include <net80211/ieee80211_ra.h>
56#include <net80211/ieee80211_radiotap.h>
57
58#include <dev/ic/athnreg.h>
59#include <dev/ic/athnvar.h>
60
61#include <dev/ic/ar5008reg.h>
62#include <dev/ic/ar9280reg.h>
63#include <dev/ic/ar9285reg.h>
64
65int ar9285_attach(struct athn_softc *);
66void ar9285_setup(struct athn_softc *);
67void ar9285_swap_rom(struct athn_softc *);
68const struct ar_spur_chan *ar9285_get_spur_chans(struct athn_softc *, int);
69void ar9285_init_from_rom(struct athn_softc *, struct ieee80211_channel *,
70 struct ieee80211_channel *);
71void ar9285_pa_calib(struct athn_softc *);
72void ar9271_pa_calib(struct athn_softc *);
73int ar9285_cl_cal(struct athn_softc *, struct ieee80211_channel *,
74 struct ieee80211_channel *);
75void ar9271_load_ani(struct athn_softc *);
76int ar9285_init_calib(struct athn_softc *, struct ieee80211_channel *,
77 struct ieee80211_channel *);
78void ar9285_get_pdadcs(struct athn_softc *, struct ieee80211_channel *,
79 int, uint8_t, uint8_t *, uint8_t *);
80void ar9285_set_power_calib(struct athn_softc *,
81 struct ieee80211_channel *);
82void ar9285_set_txpower(struct athn_softc *, struct ieee80211_channel *,
83 struct ieee80211_channel *);
84
85/* Extern functions. */
86uint8_t athn_chan2fbin(struct ieee80211_channel *);
87void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *);
88int ar5008_attach(struct athn_softc *);
89void ar5008_write_txpower(struct athn_softc *, int16_t power[]);
90void ar5008_get_pdadcs(struct athn_softc *, uint8_t, struct athn_pier *,
91 struct athn_pier *, int, int, uint8_t, uint8_t *, uint8_t *);
92void ar5008_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *,
93 uint8_t, const struct ar_cal_target_power_leg *, int, uint8_t[]);
94void ar5008_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *,
95 uint8_t, const struct ar_cal_target_power_ht *, int, uint8_t[]);
96int ar9280_set_synth(struct athn_softc *, struct ieee80211_channel *,
97 struct ieee80211_channel *);
98void ar9280_spur_mitigate(struct athn_softc *, struct ieee80211_channel *,
99 struct ieee80211_channel *);
100
101
102int
103ar9285_attach(struct athn_softc *sc)
104{
105 sc->eep_base = AR9285_EEP_START_LOC64;
106 sc->eep_size = sizeof(struct ar9285_eeprom);
107 sc->ngpiopins = (sc->flags & ATHN_FLAG_USB(1 << 1)) ? 16 : 12;
108 sc->led_pin = (sc->flags & ATHN_FLAG_USB(1 << 1)) ? 15 : 1;
109 sc->workaround = AR9285_WA_DEFAULT0x004a050b;
110 sc->ops.setup = ar9285_setup;
111 sc->ops.swap_rom = ar9285_swap_rom;
112 sc->ops.init_from_rom = ar9285_init_from_rom;
113 sc->ops.set_txpower = ar9285_set_txpower;
114 sc->ops.set_synth = ar9280_set_synth;
115 sc->ops.spur_mitigate = ar9280_spur_mitigate;
116 sc->ops.get_spur_chans = ar9285_get_spur_chans;
117#if NATHN_USB1 > 0
118 if (AR_SREV_9271(sc)((sc)->mac_ver == 0x140)) {
119 sc->cca_min_2g = AR9271_PHY_CCA_MIN_GOOD_VAL_2GHZ(-127);
120 sc->cca_max_2g = AR9271_PHY_CCA_MAX_GOOD_VAL_2GHZ(-116);
121 } else
122#endif
123 {
124 sc->cca_min_2g = AR9285_PHY_CCA_MIN_GOOD_VAL_2GHZ(-127);
125 sc->cca_max_2g = AR9285_PHY_CCA_MAX_GOOD_VAL_2GHZ(-108);
126 }
127#if NATHN_USB1 > 0
128 if (AR_SREV_9271(sc)((sc)->mac_ver == 0x140))
129 sc->ini = &ar9271_ini;
130 else
131#endif
132 sc->ini = &ar9285_1_2_ini;
133 sc->serdes = &ar9280_2_0_serdes;
134
135 return (ar5008_attach(sc));
136}
137
138void
139ar9285_setup(struct athn_softc *sc)
140{
141 const struct ar9285_eeprom *eep = sc->eep;
142 uint8_t type;
143
144 /* Select initialization values based on ROM. */
145 type = eep->baseEepHeader.txGainType;
146 DPRINTF(("Tx gain type=0x%x\n", type));
147#if NATHN_USB1 > 0
148 if (AR_SREV_9271(sc)((sc)->mac_ver == 0x140)) {
149 if (type == AR_EEP_TXGAIN_HIGH_POWER1)
150 sc->tx_gain = &ar9271_tx_gain_high_power;
151 else
152 sc->tx_gain = &ar9271_tx_gain;
153 } else
154#endif /* NATHN_USB */
155 if ((AR_READ(sc, AR_AN_SYNTH9)(sc)->ops.read((sc), (0x7868)) & 0x7) == 0x1) { /* XE rev. */
156 if (type == AR_EEP_TXGAIN_HIGH_POWER1)
157 sc->tx_gain = &ar9285_2_0_tx_gain_high_power;
158 else
159 sc->tx_gain = &ar9285_2_0_tx_gain;
160 } else {
161 if (type == AR_EEP_TXGAIN_HIGH_POWER1)
162 sc->tx_gain = &ar9285_1_2_tx_gain_high_power;
163 else
164 sc->tx_gain = &ar9285_1_2_tx_gain;
165 }
166}
167
168void
169ar9285_swap_rom(struct athn_softc *sc)
170{
171 struct ar9285_eeprom *eep = sc->eep;
172 int i;
173
174 eep->modalHeader.antCtrlCommon =
175 swap32(eep->modalHeader.antCtrlCommon)(__uint32_t)(__builtin_constant_p(eep->modalHeader.antCtrlCommon
) ? (__uint32_t)(((__uint32_t)(eep->modalHeader.antCtrlCommon
) & 0xff) << 24 | ((__uint32_t)(eep->modalHeader
.antCtrlCommon) & 0xff00) << 8 | ((__uint32_t)(eep->
modalHeader.antCtrlCommon) & 0xff0000) >> 8 | ((__uint32_t
)(eep->modalHeader.antCtrlCommon) & 0xff000000) >>
24) : __swap32md(eep->modalHeader.antCtrlCommon))
;
176 eep->modalHeader.antCtrlChain =
177 swap32(eep->modalHeader.antCtrlChain)(__uint32_t)(__builtin_constant_p(eep->modalHeader.antCtrlChain
) ? (__uint32_t)(((__uint32_t)(eep->modalHeader.antCtrlChain
) & 0xff) << 24 | ((__uint32_t)(eep->modalHeader
.antCtrlChain) & 0xff00) << 8 | ((__uint32_t)(eep->
modalHeader.antCtrlChain) & 0xff0000) >> 8 | ((__uint32_t
)(eep->modalHeader.antCtrlChain) & 0xff000000) >>
24) : __swap32md(eep->modalHeader.antCtrlChain))
;
178
179 for (i = 0; i < AR_EEPROM_MODAL_SPURS5; i++) {
180 eep->modalHeader.spurChans[i].spurChan =
181 swap16(eep->modalHeader.spurChans[i].spurChan)(__uint16_t)(__builtin_constant_p(eep->modalHeader.spurChans
[i].spurChan) ? (__uint16_t)(((__uint16_t)(eep->modalHeader
.spurChans[i].spurChan) & 0xffU) << 8 | ((__uint16_t
)(eep->modalHeader.spurChans[i].spurChan) & 0xff00U) >>
8) : __swap16md(eep->modalHeader.spurChans[i].spurChan))
;
182 }
183}
184
185const struct ar_spur_chan *
186ar9285_get_spur_chans(struct athn_softc *sc, int is2ghz)
187{
188 const struct ar9285_eeprom *eep = sc->eep;
189
190 KASSERT(is2ghz)((is2ghz) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/ar9285.c"
, 190, "is2ghz"))
;
191 return (eep->modalHeader.spurChans);
192}
193
194void
195ar9285_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
196 struct ieee80211_channel *extc)
197{
198 const struct ar9285_eeprom *eep = sc->eep;
199 const struct ar9285_modal_eep_header *modal = &eep->modalHeader;
200 uint32_t reg, offset = 0x1000;
201 uint8_t ob[5], db1[5], db2[5];
202 uint8_t txRxAtten;
203
204 AR_WRITE(sc, AR_PHY_SWITCH_COM, modal->antCtrlCommon)(sc)->ops.write((sc), (0x9964), (modal->antCtrlCommon));
205 AR_WRITE(sc, AR_PHY_SWITCH_CHAIN_0, modal->antCtrlChain)(sc)->ops.write((sc), (0x9960), (modal->antCtrlChain));
206
207 reg = AR_READ(sc, AR_PHY_TIMING_CTRL4_0)(sc)->ops.read((sc), (0x9920));
208 reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, modal->iqCalI)(((reg) & ~0x000007e0) | (((uint32_t)(modal->iqCalI) <<
5) & 0x000007e0))
;
209 reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, modal->iqCalQ)(((reg) & ~0x0000001f) | (((uint32_t)(modal->iqCalQ) <<
0) & 0x0000001f))
;
210 AR_WRITE(sc, AR_PHY_TIMING_CTRL4_0, reg)(sc)->ops.write((sc), (0x9920), (reg));
211
212 if (sc->eep_rev >= AR_EEP_MINOR_VER_33) {
213 reg = AR_READ(sc, AR_PHY_GAIN_2GHZ)(sc)->ops.read((sc), (0xa20c));
214 reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,(((reg) & ~0x0001f000) | (((uint32_t)(modal->bswMargin
) << 12) & 0x0001f000))
215 modal->bswMargin)(((reg) & ~0x0001f000) | (((uint32_t)(modal->bswMargin
) << 12) & 0x0001f000))
;
216 reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_DB,(((reg) & ~0x0000003f) | (((uint32_t)(modal->bswAtten)
<< 0) & 0x0000003f))
217 modal->bswAtten)(((reg) & ~0x0000003f) | (((uint32_t)(modal->bswAtten)
<< 0) & 0x0000003f))
;
218 reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,(((reg) & ~0x003e0000) | (((uint32_t)(modal->xatten2Margin
) << 17) & 0x003e0000))
219 modal->xatten2Margin)(((reg) & ~0x003e0000) | (((uint32_t)(modal->xatten2Margin
) << 17) & 0x003e0000))
;
220 reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_DB,(((reg) & ~0x00000fc0) | (((uint32_t)(modal->xatten2Db
) << 6) & 0x00000fc0))
221 modal->xatten2Db)(((reg) & ~0x00000fc0) | (((uint32_t)(modal->xatten2Db
) << 6) & 0x00000fc0))
;
222 AR_WRITE(sc, AR_PHY_GAIN_2GHZ, reg)(sc)->ops.write((sc), (0xa20c), (reg));
223
224 /* Duplicate values of chain 0 for chain 1. */
225 reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset)(sc)->ops.read((sc), (0xa20c + offset));
226 reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,(((reg) & ~0x0001f000) | (((uint32_t)(modal->bswMargin
) << 12) & 0x0001f000))
227 modal->bswMargin)(((reg) & ~0x0001f000) | (((uint32_t)(modal->bswMargin
) << 12) & 0x0001f000))
;
228 reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_DB,(((reg) & ~0x0000003f) | (((uint32_t)(modal->bswAtten)
<< 0) & 0x0000003f))
229 modal->bswAtten)(((reg) & ~0x0000003f) | (((uint32_t)(modal->bswAtten)
<< 0) & 0x0000003f))
;
230 reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,(((reg) & ~0x003e0000) | (((uint32_t)(modal->xatten2Margin
) << 17) & 0x003e0000))
231 modal->xatten2Margin)(((reg) & ~0x003e0000) | (((uint32_t)(modal->xatten2Margin
) << 17) & 0x003e0000))
;
232 reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_DB,(((reg) & ~0x00000fc0) | (((uint32_t)(modal->xatten2Db
) << 6) & 0x00000fc0))
233 modal->xatten2Db)(((reg) & ~0x00000fc0) | (((uint32_t)(modal->xatten2Db
) << 6) & 0x00000fc0))
;
234 AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg)(sc)->ops.write((sc), (0xa20c + offset), (reg));
235 }
236 if (sc->eep_rev >= AR_EEP_MINOR_VER_33)
237 txRxAtten = modal->txRxAtten;
238 else /* Workaround for ROM versions < 14.3. */
239 txRxAtten = 23;
240 reg = AR_READ(sc, AR_PHY_RXGAIN)(sc)->ops.read((sc), (0x9848));
241 reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAtten)(((reg) & ~0x00003f80) | (((uint32_t)(txRxAtten) <<
7) & 0x00003f80))
;
242 reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_MARGIN, modal->rxTxMargin)(((reg) & ~0x001fc000) | (((uint32_t)(modal->rxTxMargin
) << 14) & 0x001fc000))
;
243 AR_WRITE(sc, AR_PHY_RXGAIN, reg)(sc)->ops.write((sc), (0x9848), (reg));
244
245 /* Duplicate values of chain 0 for chain 1. */
246 reg = AR_READ(sc, AR_PHY_RXGAIN + offset)(sc)->ops.read((sc), (0x9848 + offset));
247 reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAtten)(((reg) & ~0x00003f80) | (((uint32_t)(txRxAtten) <<
7) & 0x00003f80))
;
248 reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_MARGIN, modal->rxTxMargin)(((reg) & ~0x001fc000) | (((uint32_t)(modal->rxTxMargin
) << 14) & 0x001fc000))
;
249 AR_WRITE(sc, AR_PHY_RXGAIN + offset, reg)(sc)->ops.write((sc), (0x9848 + offset), (reg));
250
251 if (modal->version >= 3) {
252 /* Setup antenna diversity from ROM. */
253 reg = AR_READ(sc, AR_PHY_MULTICHAIN_GAIN_CTL)(sc)->ops.read((sc), (0x99ac));
254 reg = RW(reg, AR9285_PHY_ANT_DIV_CTL_ALL, 0)(((reg) & ~0x7f000000) | (((uint32_t)(0) << 24) &
0x7f000000))
;
255 reg = RW(reg, AR9285_PHY_ANT_DIV_CTL,(((reg) & ~0x01000000) | (((uint32_t)((modal->ob_234 >>
12) & 0x1) << 24) & 0x01000000))
256 (modal->ob_234 >> 12) & 0x1)(((reg) & ~0x01000000) | (((uint32_t)((modal->ob_234 >>
12) & 0x1) << 24) & 0x01000000))
;
257 reg = RW(reg, AR9285_PHY_ANT_DIV_ALT_LNACONF,(((reg) & ~0x06000000) | (((uint32_t)((modal->db1_234 >>
12) & 0x3) << 25) & 0x06000000))
258 (modal->db1_234 >> 12) & 0x3)(((reg) & ~0x06000000) | (((uint32_t)((modal->db1_234 >>
12) & 0x3) << 25) & 0x06000000))
;
259 reg = RW(reg, AR9285_PHY_ANT_DIV_MAIN_LNACONF,(((reg) & ~0x18000000) | (((uint32_t)((modal->db1_234 >>
14) & 0x3) << 27) & 0x18000000))
260 (modal->db1_234 >> 14) & 0x3)(((reg) & ~0x18000000) | (((uint32_t)((modal->db1_234 >>
14) & 0x3) << 27) & 0x18000000))
;
261 reg = RW(reg, AR9285_PHY_ANT_DIV_ALT_GAINTB,(((reg) & ~0x20000000) | (((uint32_t)((modal->ob_234 >>
13) & 0x1) << 29) & 0x20000000))
262 (modal->ob_234 >> 13) & 0x1)(((reg) & ~0x20000000) | (((uint32_t)((modal->ob_234 >>
13) & 0x1) << 29) & 0x20000000))
;
263 reg = RW(reg, AR9285_PHY_ANT_DIV_MAIN_GAINTB,(((reg) & ~0x40000000) | (((uint32_t)((modal->ob_234 >>
14) & 0x1) << 30) & 0x40000000))
264 (modal->ob_234 >> 14) & 0x1)(((reg) & ~0x40000000) | (((uint32_t)((modal->ob_234 >>
14) & 0x1) << 30) & 0x40000000))
;
265 AR_WRITE(sc, AR_PHY_MULTICHAIN_GAIN_CTL, reg)(sc)->ops.write((sc), (0x99ac), (reg));
266 reg = AR_READ(sc, AR_PHY_MULTICHAIN_GAIN_CTL)(sc)->ops.read((sc), (0x99ac)); /* Flush. */
267
268 reg = AR_READ(sc, AR_PHY_CCK_DETECT)(sc)->ops.read((sc), (0xa208));
269 if (modal->ob_234 & (1 << 15))
270 reg |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV0x00002000;
271 else
272 reg &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV0x00002000;
273 AR_WRITE(sc, AR_PHY_CCK_DETECT, reg)(sc)->ops.write((sc), (0xa208), (reg));
274 reg = AR_READ(sc, AR_PHY_CCK_DETECT)(sc)->ops.read((sc), (0xa208)); /* Flush. */
275 }
276 if (modal->version >= 2) {
277 ob [0] = (modal->ob_01 >> 0) & 0xf;
278 ob [1] = (modal->ob_01 >> 4) & 0xf;
279 ob [2] = (modal->ob_234 >> 0) & 0xf;
280 ob [3] = (modal->ob_234 >> 4) & 0xf;
281 ob [4] = (modal->ob_234 >> 8) & 0xf;
282
283 db1[0] = (modal->db1_01 >> 0) & 0xf;
284 db1[1] = (modal->db1_01 >> 4) & 0xf;
285 db1[2] = (modal->db1_234 >> 0) & 0xf;
286 db1[3] = (modal->db1_234 >> 4) & 0xf;
287 db1[4] = (modal->db1_234 >> 8) & 0xf;
288
289 db2[0] = (modal->db2_01 >> 0) & 0xf;
290 db2[1] = (modal->db2_01 >> 4) & 0xf;
291 db2[2] = (modal->db2_234 >> 0) & 0xf;
292 db2[3] = (modal->db2_234 >> 4) & 0xf;
293 db2[4] = (modal->db2_234 >> 8) & 0xf;
294
295 } else if (modal->version == 1) {
296 ob [0] = (modal->ob_01 >> 0) & 0xf;
297 ob [1] = (modal->ob_01 >> 4) & 0xf;
298 /* Field ob_234 does not exist, use ob_01. */
299 ob [2] = ob [3] = ob [4] = ob [1];
300
301 db1[0] = (modal->db1_01 >> 0) & 0xf;
302 db1[1] = (modal->db1_01 >> 4) & 0xf;
303 /* Field db1_234 does not exist, use db1_01. */
304 db1[2] = db1[3] = db1[4] = db1[1];
305
306 db2[0] = (modal->db2_01 >> 0) & 0xf;
307 db2[1] = (modal->db2_01 >> 4) & 0xf;
308 /* Field db2_234 does not exist, use db2_01. */
309 db2[2] = db2[3] = db2[4] = db2[1];
310
311 } else {
312 ob [0] = modal->ob_01;
313 ob [1] = ob [2] = ob [3] = ob [4] = ob [0];
314
315 db1[0] = modal->db1_01;
316 db1[1] = db1[2] = db1[3] = db1[4] = db1[0];
317
318 /* Field db2_01 does not exist, use db1_01. */
319 db2[0] = modal->db1_01;
320 db2[1] = db2[2] = db2[3] = db2[4] = db2[0];
321 }
322#if NATHN_USB1 > 0
323 if (AR_SREV_9271(sc)((sc)->mac_ver == 0x140)) {
324 reg = AR_READ(sc, AR9285_AN_RF2G3)(sc)->ops.read((sc), (0x7828));
325 reg = RW(reg, AR9271_AN_RF2G3_OB_CCK, ob [0])(((reg) & ~0x001c0000) | (((uint32_t)(ob [0]) << 18
) & 0x001c0000))
;
326 reg = RW(reg, AR9271_AN_RF2G3_OB_PSK, ob [1])(((reg) & ~0x00038000) | (((uint32_t)(ob [1]) << 15
) & 0x00038000))
;
327 reg = RW(reg, AR9271_AN_RF2G3_OB_QAM, ob [2])(((reg) & ~0x00007000) | (((uint32_t)(ob [2]) << 12
) & 0x00007000))
;
328 reg = RW(reg, AR9271_AN_RF2G3_DB1, db1[0])(((reg) & ~0x00e00000) | (((uint32_t)(db1[0]) << 21
) & 0x00e00000))
;
329 AR_WRITE(sc, AR9285_AN_RF2G3, reg)(sc)->ops.write((sc), (0x7828), (reg));
330 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
331 DELAY(100)(*delay_func)(100);
332 reg = AR_READ(sc, AR9285_AN_RF2G4)(sc)->ops.read((sc), (0x782c));
333 reg = RW(reg, AR9271_AN_RF2G4_DB2, db2[0])(((reg) & ~0xe0000000) | (((uint32_t)(db2[0]) << 29
) & 0xe0000000))
;
334 AR_WRITE(sc, AR9285_AN_RF2G4, reg)(sc)->ops.write((sc), (0x782c), (reg));
335 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
336 DELAY(100)(*delay_func)(100);
337 } else
338#endif /* ATHN_USB */
339 {
340 reg = AR_READ(sc, AR9285_AN_RF2G3)(sc)->ops.read((sc), (0x7828));
341 reg = RW(reg, AR9285_AN_RF2G3_OB_0, ob [0])(((reg) & ~0x00e00000) | (((uint32_t)(ob [0]) << 21
) & 0x00e00000))
;
342 reg = RW(reg, AR9285_AN_RF2G3_OB_1, ob [1])(((reg) & ~0x001c0000) | (((uint32_t)(ob [1]) << 18
) & 0x001c0000))
;
343 reg = RW(reg, AR9285_AN_RF2G3_OB_2, ob [2])(((reg) & ~0x00038000) | (((uint32_t)(ob [2]) << 15
) & 0x00038000))
;
344 reg = RW(reg, AR9285_AN_RF2G3_OB_3, ob [3])(((reg) & ~0x00007000) | (((uint32_t)(ob [3]) << 12
) & 0x00007000))
;
345 reg = RW(reg, AR9285_AN_RF2G3_OB_4, ob [4])(((reg) & ~0x00000e00) | (((uint32_t)(ob [4]) << 9)
& 0x00000e00))
;
346 reg = RW(reg, AR9285_AN_RF2G3_DB1_0, db1[0])(((reg) & ~0x000001c0) | (((uint32_t)(db1[0]) << 6)
& 0x000001c0))
;
347 reg = RW(reg, AR9285_AN_RF2G3_DB1_1, db1[1])(((reg) & ~0x00000038) | (((uint32_t)(db1[1]) << 3)
& 0x00000038))
;
348 reg = RW(reg, AR9285_AN_RF2G3_DB1_2, db1[2])(((reg) & ~0x00000007) | (((uint32_t)(db1[2]) << 0)
& 0x00000007))
;
349 AR_WRITE(sc, AR9285_AN_RF2G3, reg)(sc)->ops.write((sc), (0x7828), (reg));
350 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
351 DELAY(100)(*delay_func)(100);
352 reg = AR_READ(sc, AR9285_AN_RF2G4)(sc)->ops.read((sc), (0x782c));
353 reg = RW(reg, AR9285_AN_RF2G4_DB1_3, db1[3])(((reg) & ~0xe0000000) | (((uint32_t)(db1[3]) << 29
) & 0xe0000000))
;
354 reg = RW(reg, AR9285_AN_RF2G4_DB1_4, db1[4])(((reg) & ~0x1c000000) | (((uint32_t)(db1[4]) << 26
) & 0x1c000000))
;
355 reg = RW(reg, AR9285_AN_RF2G4_DB2_0, db2[0])(((reg) & ~0x03800000) | (((uint32_t)(db2[0]) << 23
) & 0x03800000))
;
356 reg = RW(reg, AR9285_AN_RF2G4_DB2_1, db2[1])(((reg) & ~0x00700000) | (((uint32_t)(db2[1]) << 20
) & 0x00700000))
;
357 reg = RW(reg, AR9285_AN_RF2G4_DB2_2, db2[2])(((reg) & ~0x000e0000) | (((uint32_t)(db2[2]) << 17
) & 0x000e0000))
;
358 reg = RW(reg, AR9285_AN_RF2G4_DB2_3, db2[3])(((reg) & ~0x0001c000) | (((uint32_t)(db2[3]) << 14
) & 0x0001c000))
;
359 reg = RW(reg, AR9285_AN_RF2G4_DB2_4, db2[4])(((reg) & ~0x00003800) | (((uint32_t)(db2[4]) << 11
) & 0x00003800))
;
360 AR_WRITE(sc, AR9285_AN_RF2G4, reg)(sc)->ops.write((sc), (0x782c), (reg));
361 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
362 DELAY(100)(*delay_func)(100);
363 }
364
365 reg = AR_READ(sc, AR_PHY_SETTLING)(sc)->ops.read((sc), (0x9844));
366 reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->switchSettling)(((reg) & ~0x00003f80) | (((uint32_t)(modal->switchSettling
) << 7) & 0x00003f80))
;
367 AR_WRITE(sc, AR_PHY_SETTLING, reg)(sc)->ops.write((sc), (0x9844), (reg));
368
369 reg = AR_READ(sc, AR_PHY_DESIRED_SZ)(sc)->ops.read((sc), (0x9850));
370 reg = RW(reg, AR_PHY_DESIRED_SZ_ADC, modal->adcDesiredSize)(((reg) & ~0x000000ff) | (((uint32_t)(modal->adcDesiredSize
) << 0) & 0x000000ff))
;
371 AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg)(sc)->ops.write((sc), (0x9850), (reg));
372
373 reg = SM(AR_PHY_RF_CTL4_TX_END_XPAA_OFF, modal->txEndToXpaOff)(((uint32_t)(modal->txEndToXpaOff) << 16) & 0x00ff0000
)
;
374 reg |= SM(AR_PHY_RF_CTL4_TX_END_XPAB_OFF, modal->txEndToXpaOff)(((uint32_t)(modal->txEndToXpaOff) << 24) & 0xff000000
)
;
375 reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAA_ON, modal->txFrameToXpaOn)(((uint32_t)(modal->txFrameToXpaOn) << 0) & 0x000000ff
)
;
376 reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAB_ON, modal->txFrameToXpaOn)(((uint32_t)(modal->txFrameToXpaOn) << 8) & 0x0000ff00
)
;
377 AR_WRITE(sc, AR_PHY_RF_CTL4, reg)(sc)->ops.write((sc), (0x9834), (reg));
378
379 reg = AR_READ(sc, AR_PHY_RF_CTL3)(sc)->ops.read((sc), (0x9828));
380 reg = RW(reg, AR_PHY_TX_END_TO_A2_RX_ON, modal->txEndToRxOn)(((reg) & ~0x00ff0000) | (((uint32_t)(modal->txEndToRxOn
) << 16) & 0x00ff0000))
;
381 AR_WRITE(sc, AR_PHY_RF_CTL3, reg)(sc)->ops.write((sc), (0x9828), (reg));
382
383 reg = AR_READ(sc, AR_PHY_CCA(0))(sc)->ops.read((sc), ((0x9864 + (0) * 0x1000)));
384 reg = RW(reg, AR9280_PHY_CCA_THRESH62, modal->thresh62)(((reg) & ~0x000ff000) | (((uint32_t)(modal->thresh62)
<< 12) & 0x000ff000))
;
385 AR_WRITE(sc, AR_PHY_CCA(0), reg)(sc)->ops.write((sc), ((0x9864 + (0) * 0x1000)), (reg));
386
387 reg = AR_READ(sc, AR_PHY_EXT_CCA0)(sc)->ops.read((sc), (0x99b8));
388 reg = RW(reg, AR_PHY_EXT_CCA0_THRESH62, modal->thresh62)(((reg) & ~0x000000ff) | (((uint32_t)(modal->thresh62)
<< 0) & 0x000000ff))
;
389 AR_WRITE(sc, AR_PHY_EXT_CCA0, reg)(sc)->ops.write((sc), (0x99b8), (reg));
390
391 if (sc->eep_rev >= AR_EEP_MINOR_VER_22) {
392 reg = AR_READ(sc, AR_PHY_RF_CTL2)(sc)->ops.read((sc), (0x9824));
393 reg = RW(reg, AR_PHY_TX_END_PA_ON,(((reg) & ~0x0000ff00) | (((uint32_t)(modal->txFrameToPaOn
) << 8) & 0x0000ff00))
394 modal->txFrameToPaOn)(((reg) & ~0x0000ff00) | (((uint32_t)(modal->txFrameToPaOn
) << 8) & 0x0000ff00))
;
395 reg = RW(reg, AR_PHY_TX_END_DATA_START,(((reg) & ~0x000000ff) | (((uint32_t)(modal->txFrameToDataStart
) << 0) & 0x000000ff))
396 modal->txFrameToDataStart)(((reg) & ~0x000000ff) | (((uint32_t)(modal->txFrameToDataStart
) << 0) & 0x000000ff))
;
397 AR_WRITE(sc, AR_PHY_RF_CTL2, reg)(sc)->ops.write((sc), (0x9824), (reg));
398 }
399 if (sc->eep_rev >= AR_EEP_MINOR_VER_33 && extc != NULL((void *)0)) {
400 reg = AR_READ(sc, AR_PHY_SETTLING)(sc)->ops.read((sc), (0x9844));
401 reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->swSettleHt40)(((reg) & ~0x00003f80) | (((uint32_t)(modal->swSettleHt40
) << 7) & 0x00003f80))
;
402 AR_WRITE(sc, AR_PHY_SETTLING, reg)(sc)->ops.write((sc), (0x9844), (reg));
403 }
404 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
405}
406
407void
408ar9285_pa_calib(struct athn_softc *sc)
409{
410 /* List of registers that need to be saved/restored. */
411 static const uint16_t regs[] = {
412 AR9285_AN_TOP30x786c,
413 AR9285_AN_RXTXBB10x7854,
414 AR9285_AN_RF2G10x7820,
415 AR9285_AN_RF2G20x7824,
416 AR9285_AN_TOP20x7868,
417 AR9285_AN_RF2G80x783c,
418 AR9285_AN_RF2G70x7838
419 };
420 uint32_t svg[7], reg, ccomp_svg;
421 int i;
422
423 /* No PA calibration needed for high power solutions. */
424 if (AR_SREV_9285(sc)((sc)->mac_ver == 0x0c0) &&
425 ((struct ar9285_base_eep_header *)sc->eep)->txGainType ==
426 AR_EEP_TXGAIN_HIGH_POWER1) /* XXX AR9287? */
427 return;
428
429 /* Save registers. */
430 for (i = 0; i < nitems(regs)(sizeof((regs)) / sizeof((regs)[0])); i++)
431 svg[i] = AR_READ(sc, regs[i])(sc)->ops.read((sc), (regs[i]));
432
433 AR_CLRBITS(sc, AR9285_AN_RF2G6, 1)(sc)->ops.write((sc), (0x7834), ((sc)->ops.read((sc), (
0x7834)) & ~(1)))
;
434 AR_SETBITS(sc, AR_PHY(2), 1 << 27)(sc)->ops.write((sc), ((0x9800 + (2) * 4)), ((sc)->ops.
read((sc), ((0x9800 + (2) * 4))) | (1 << 27)))
;
435
436 AR_SETBITS(sc, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC)(sc)->ops.write((sc), (0x786c), ((sc)->ops.read((sc), (
0x786c)) | (0x00800000)))
;
437 AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1)(sc)->ops.write((sc), (0x7854), ((sc)->ops.read((sc), (
0x7854)) | (0x00000020)))
;
438 AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I)(sc)->ops.write((sc), (0x7854), ((sc)->ops.read((sc), (
0x7854)) | (0x00000080)))
;
439 AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF)(sc)->ops.write((sc), (0x7854), ((sc)->ops.read((sc), (
0x7854)) | (0x00000100)))
;
440 AR_CLRBITS(sc, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL)(sc)->ops.write((sc), (0x7824), ((sc)->ops.read((sc), (
0x7824)) & ~(0x00001000)))
;
441 AR_CLRBITS(sc, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB)(sc)->ops.write((sc), (0x7838), ((sc)->ops.read((sc), (
0x7838)) & ~(0x00000002)))
;
442 AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL)(sc)->ops.write((sc), (0x7820), ((sc)->ops.read((sc), (
0x7820)) & ~(0x00000800)))
;
443 /* Power down PA drivers. */
444 AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1)(sc)->ops.write((sc), (0x7820), ((sc)->ops.read((sc), (
0x7820)) & ~(0x02000000)))
;
445 AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2)(sc)->ops.write((sc), (0x7820), ((sc)->ops.read((sc), (
0x7820)) & ~(0x01000000)))
;
446 AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT)(sc)->ops.write((sc), (0x7820), ((sc)->ops.read((sc), (
0x7820)) & ~(0x00800000)))
;
447
448 reg = AR_READ(sc, AR9285_AN_RF2G8)(sc)->ops.read((sc), (0x783c));
449 reg = RW(reg, AR9285_AN_RF2G8_PADRVGN2TAB0, 7)(((reg) & ~0x0001c000) | (((uint32_t)(7) << 14) &
0x0001c000))
;
450 AR_WRITE(sc, AR9285_AN_RF2G8, reg)(sc)->ops.write((sc), (0x783c), (reg));
451
452 reg = AR_READ(sc, AR9285_AN_RF2G7)(sc)->ops.read((sc), (0x7838));
453 reg = RW(reg, AR9285_AN_RF2G7_PADRVGN2TAB0, 0)(((reg) & ~0xe0000000) | (((uint32_t)(0) << 29) &
0xe0000000))
;
454 AR_WRITE(sc, AR9285_AN_RF2G7, reg)(sc)->ops.write((sc), (0x7838), (reg));
455
456 reg = AR_READ(sc, AR9285_AN_RF2G6)(sc)->ops.read((sc), (0x7834));
457 /* Save compensation capacitor value. */
458 ccomp_svg = MS(reg, AR9285_AN_RF2G6_CCOMP)(((uint32_t)(reg) & 0x00007800) >> 11);
459 /* Program compensation capacitor for dynamic PA. */
460 reg = RW(reg, AR9285_AN_RF2G6_CCOMP, 0xf)(((reg) & ~0x00007800) | (((uint32_t)(0xf) << 11) &
0x00007800))
;
461 AR_WRITE(sc, AR9285_AN_RF2G6, reg)(sc)->ops.write((sc), (0x7834), (reg));
462
463 AR_WRITE(sc, AR9285_AN_TOP2, AR9285_AN_TOP2_DEFAULT)(sc)->ops.write((sc), (0x7868), (0xca0358a0));
464 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
465 DELAY(30)(*delay_func)(30);
466
467 /* Clear offsets 6-1. */
468 AR_CLRBITS(sc, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS_6_1)(sc)->ops.write((sc), (0x7834), ((sc)->ops.read((sc), (
0x7834)) & ~(0x03f00000)))
;
469 /* Clear offset 0. */
470 AR_CLRBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP)(sc)->ops.write((sc), (0x7828), ((sc)->ops.read((sc), (
0x7828)) & ~(0x02000000)))
;
471 /* Set offsets 6-1. */
472 for (i = 6; i >= 1; i--) {
473 AR_SETBITS(sc, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS(i))(sc)->ops.write((sc), (0x7834), ((sc)->ops.read((sc), (
0x7834)) | ((1 << (19 + (i))))))
;
474 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
475 DELAY(1)(*delay_func)(1);
476 if (AR_READ(sc, AR9285_AN_RF2G9)(sc)->ops.read((sc), (0x7840)) & AR9285_AN_RXTXBB1_SPARE90x00000001) {
477 AR_SETBITS(sc, AR9285_AN_RF2G6,(sc)->ops.write((sc), (0x7834), ((sc)->ops.read((sc), (
0x7834)) | ((1 << (19 + (i))))))
478 AR9285_AN_RF2G6_OFFS(i))(sc)->ops.write((sc), (0x7834), ((sc)->ops.read((sc), (
0x7834)) | ((1 << (19 + (i))))))
;
479 } else {
480 AR_CLRBITS(sc, AR9285_AN_RF2G6,(sc)->ops.write((sc), (0x7834), ((sc)->ops.read((sc), (
0x7834)) & ~((1 << (19 + (i))))))
481 AR9285_AN_RF2G6_OFFS(i))(sc)->ops.write((sc), (0x7834), ((sc)->ops.read((sc), (
0x7834)) & ~((1 << (19 + (i))))))
;
482 }
483 }
484 /* Set offset 0. */
485 AR_SETBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP)(sc)->ops.write((sc), (0x7828), ((sc)->ops.read((sc), (
0x7828)) | (0x02000000)))
;
486 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
487 DELAY(1)(*delay_func)(1);
488 if (AR_READ(sc, AR9285_AN_RF2G9)(sc)->ops.read((sc), (0x7840)) & AR9285_AN_RXTXBB1_SPARE90x00000001)
489 AR_SETBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP)(sc)->ops.write((sc), (0x7828), ((sc)->ops.read((sc), (
0x7828)) | (0x02000000)))
;
490 else
491 AR_CLRBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP)(sc)->ops.write((sc), (0x7828), ((sc)->ops.read((sc), (
0x7828)) & ~(0x02000000)))
;
492
493 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
494
495 AR_SETBITS(sc, AR9285_AN_RF2G6, 1)(sc)->ops.write((sc), (0x7834), ((sc)->ops.read((sc), (
0x7834)) | (1)))
;
496 AR_CLRBITS(sc, AR_PHY(2), 1 << 27)(sc)->ops.write((sc), ((0x9800 + (2) * 4)), ((sc)->ops.
read((sc), ((0x9800 + (2) * 4))) & ~(1 << 27)))
;
497
498 /* Restore registers. */
499 for (i = 0; i < nitems(regs)(sizeof((regs)) / sizeof((regs)[0])); i++)
500 AR_WRITE(sc, regs[i], svg[i])(sc)->ops.write((sc), (regs[i]), (svg[i]));
501
502 /* Restore compensation capacitor value. */
503 reg = AR_READ(sc, AR9285_AN_RF2G6)(sc)->ops.read((sc), (0x7834));
504 reg = RW(reg, AR9285_AN_RF2G6_CCOMP, ccomp_svg)(((reg) & ~0x00007800) | (((uint32_t)(ccomp_svg) <<
11) & 0x00007800))
;
505 AR_WRITE(sc, AR9285_AN_RF2G6, reg)(sc)->ops.write((sc), (0x7834), (reg));
506 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
507}
508
509void
510ar9271_pa_calib(struct athn_softc *sc)
511{
512#if NATHN_USB1 > 0
513 /* List of registers that need to be saved/restored. */
514 static const uint16_t regs[] = {
515 AR9285_AN_TOP30x786c,
516 AR9285_AN_RXTXBB10x7854,
517 AR9285_AN_RF2G10x7820,
518 AR9285_AN_RF2G20x7824,
519 AR9285_AN_TOP20x7868,
520 AR9285_AN_RF2G80x783c,
521 AR9285_AN_RF2G70x7838
522 };
523 uint32_t svg[7], reg, rf2g3_svg;
524 int i;
525
526 /* Save registers. */
527 for (i = 0; i < nitems(regs)(sizeof((regs)) / sizeof((regs)[0])); i++)
528 svg[i] = AR_READ(sc, regs[i])(sc)->ops.read((sc), (regs[i]));
529
530 AR_CLRBITS(sc, AR9285_AN_RF2G6, 1)(sc)->ops.write((sc), (0x7834), ((sc)->ops.read((sc), (
0x7834)) & ~(1)))
;
531 AR_SETBITS(sc, AR_PHY(2), 1 << 27)(sc)->ops.write((sc), ((0x9800 + (2) * 4)), ((sc)->ops.
read((sc), ((0x9800 + (2) * 4))) | (1 << 27)))
;
532
533 AR_SETBITS(sc, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC)(sc)->ops.write((sc), (0x786c), ((sc)->ops.read((sc), (
0x786c)) | (0x00800000)))
;
534 AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1)(sc)->ops.write((sc), (0x7854), ((sc)->ops.read((sc), (
0x7854)) | (0x00000020)))
;
535 AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I)(sc)->ops.write((sc), (0x7854), ((sc)->ops.read((sc), (
0x7854)) | (0x00000080)))
;
536 AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF)(sc)->ops.write((sc), (0x7854), ((sc)->ops.read((sc), (
0x7854)) | (0x00000100)))
;
537 AR_CLRBITS(sc, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL)(sc)->ops.write((sc), (0x7824), ((sc)->ops.read((sc), (
0x7824)) & ~(0x00001000)))
;
538 AR_CLRBITS(sc, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB)(sc)->ops.write((sc), (0x7838), ((sc)->ops.read((sc), (
0x7838)) & ~(0x00000002)))
;
539 AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL)(sc)->ops.write((sc), (0x7820), ((sc)->ops.read((sc), (
0x7820)) & ~(0x00000800)))
;
540 /* Power down PA drivers. */
541 AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1)(sc)->ops.write((sc), (0x7820), ((sc)->ops.read((sc), (
0x7820)) & ~(0x02000000)))
;
542 AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2)(sc)->ops.write((sc), (0x7820), ((sc)->ops.read((sc), (
0x7820)) & ~(0x01000000)))
;
543 AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT)(sc)->ops.write((sc), (0x7820), ((sc)->ops.read((sc), (
0x7820)) & ~(0x00800000)))
;
544
545 reg = AR_READ(sc, AR9285_AN_RF2G8)(sc)->ops.read((sc), (0x783c));
546 reg = RW(reg, AR9285_AN_RF2G8_PADRVGN2TAB0, 7)(((reg) & ~0x0001c000) | (((uint32_t)(7) << 14) &
0x0001c000))
;
547 AR_WRITE(sc, AR9285_AN_RF2G8, reg)(sc)->ops.write((sc), (0x783c), (reg));
548
549 reg = AR_READ(sc, AR9285_AN_RF2G7)(sc)->ops.read((sc), (0x7838));
550 reg = RW(reg, AR9285_AN_RF2G7_PADRVGN2TAB0, 0)(((reg) & ~0xe0000000) | (((uint32_t)(0) << 29) &
0xe0000000))
;
551 AR_WRITE(sc, AR9285_AN_RF2G7, reg)(sc)->ops.write((sc), (0x7838), (reg));
552
553 /* Save compensation capacitor value. */
554 reg = rf2g3_svg = AR_READ(sc, AR9285_AN_RF2G3)(sc)->ops.read((sc), (0x7828));
555 /* Program compensation capacitor for dynamic PA. */
556 reg = RW(reg, AR9271_AN_RF2G3_CCOMP, 0xfff)(((reg) & ~0x00000fff) | (((uint32_t)(0xfff) << 0) &
0x00000fff))
;
557 AR_WRITE(sc, AR9285_AN_RF2G3, reg)(sc)->ops.write((sc), (0x7828), (reg));
558
559 AR_WRITE(sc, AR9285_AN_TOP2, AR9285_AN_TOP2_DEFAULT)(sc)->ops.write((sc), (0x7868), (0xca0358a0));
560 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
561 DELAY(30)(*delay_func)(30);
562
563 /* Clear offsets 6-0. */
564 AR_CLRBITS(sc, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS_6_0)(sc)->ops.write((sc), (0x7834), ((sc)->ops.read((sc), (
0x7834)) & ~(0x07f00000)))
;
565 /* Set offsets 6-1. */
566 for (i = 6; i >= 1; i--) {
567 reg = AR_READ(sc, AR9285_AN_RF2G6)(sc)->ops.read((sc), (0x7834));
568 reg |= AR9271_AN_RF2G6_OFFS(i)(1 << (20 + (i)));
569 AR_WRITE(sc, AR9285_AN_RF2G6, reg)(sc)->ops.write((sc), (0x7834), (reg));
570 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
571 DELAY(1)(*delay_func)(1);
572 if (!(AR_READ(sc, AR9285_AN_RF2G9)(sc)->ops.read((sc), (0x7840)) & AR9285_AN_RXTXBB1_SPARE90x00000001))
573 reg &= ~AR9271_AN_RF2G6_OFFS(i)(1 << (20 + (i)));
574 AR_WRITE(sc, AR9285_AN_RF2G6, reg)(sc)->ops.write((sc), (0x7834), (reg));
575 }
576 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
577
578 AR_SETBITS(sc, AR9285_AN_RF2G6, 1)(sc)->ops.write((sc), (0x7834), ((sc)->ops.read((sc), (
0x7834)) | (1)))
;
579 AR_CLRBITS(sc, AR_PHY(2), 1 << 27)(sc)->ops.write((sc), ((0x9800 + (2) * 4)), ((sc)->ops.
read((sc), ((0x9800 + (2) * 4))) & ~(1 << 27)))
;
580
581 /* Restore registers. */
582 for (i = 0; i < nitems(regs)(sizeof((regs)) / sizeof((regs)[0])); i++)
583 AR_WRITE(sc, regs[i], svg[i])(sc)->ops.write((sc), (regs[i]), (svg[i]));
584
585 /* Restore compensation capacitor value. */
586 AR_WRITE(sc, AR9285_AN_RF2G3, rf2g3_svg)(sc)->ops.write((sc), (0x7828), (rf2g3_svg));
587 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
588#endif /* NATHN_USB */
589}
590
591/*
592 * Carrier Leakage Calibration.
593 */
594int
595ar9285_cl_cal(struct athn_softc *sc, struct ieee80211_channel *c,
596 struct ieee80211_channel *extc)
597{
598 int ntries;
599
600 AR_SETBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE)(sc)->ops.write((sc), (0xa358), ((sc)->ops.read((sc), (
0xa358)) | (0x00000002)))
;
601 if (0 && extc == NULL((void *)0)) { /* XXX IS_CHAN_HT20!! */
602 AR_SETBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE)(sc)->ops.write((sc), (0xa358), ((sc)->ops.read((sc), (
0xa358)) | (0x00000001)))
;
603 AR_SETBITS(sc, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN)(sc)->ops.write((sc), (0x9804), ((sc)->ops.read((sc), (
0x9804)) | (0x00000004)))
;
604 AR_CLRBITS(sc, AR_PHY_AGC_CONTROL,(sc)->ops.write((sc), (0x9860), ((sc)->ops.read((sc), (
0x9860)) & ~(0x00010000)))
605 AR_PHY_AGC_CONTROL_FLTR_CAL)(sc)->ops.write((sc), (0x9860), ((sc)->ops.read((sc), (
0x9860)) & ~(0x00010000)))
;
606 AR_CLRBITS(sc, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE)(sc)->ops.write((sc), (0xa258), ((sc)->ops.read((sc), (
0xa258)) & ~(0x00400000)))
;
607 AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL)(sc)->ops.write((sc), (0x9860), ((sc)->ops.read((sc), (
0x9860)) | (0x00000001)))
;
608 for (ntries = 0; ntries < 10000; ntries++) {
609 if (!(AR_READ(sc, AR_PHY_AGC_CONTROL)(sc)->ops.read((sc), (0x9860)) &
610 AR_PHY_AGC_CONTROL_CAL0x00000001))
611 break;
612 DELAY(10)(*delay_func)(10);
613 }
614 if (ntries == 10000)
615 return (ETIMEDOUT60);
616 AR_CLRBITS(sc, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN)(sc)->ops.write((sc), (0x9804), ((sc)->ops.read((sc), (
0x9804)) & ~(0x00000004)))
;
617 AR_CLRBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE)(sc)->ops.write((sc), (0xa358), ((sc)->ops.read((sc), (
0xa358)) & ~(0x00000001)))
;
618 AR_CLRBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE)(sc)->ops.write((sc), (0xa358), ((sc)->ops.read((sc), (
0xa358)) & ~(0x00000002)))
;
619 }
620 AR_CLRBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC)(sc)->ops.write((sc), (0x982c), ((sc)->ops.read((sc), (
0x982c)) & ~(0x00008000)))
;
621 AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL)(sc)->ops.write((sc), (0x9860), ((sc)->ops.read((sc), (
0x9860)) | (0x00010000)))
;
622 AR_SETBITS(sc, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE)(sc)->ops.write((sc), (0xa258), ((sc)->ops.read((sc), (
0xa258)) | (0x00400000)))
;
623 AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL)(sc)->ops.write((sc), (0x9860), ((sc)->ops.read((sc), (
0x9860)) | (0x00000001)))
;
624 for (ntries = 0; ntries < 10000; ntries++) {
625 if (!(AR_READ(sc, AR_PHY_AGC_CONTROL)(sc)->ops.read((sc), (0x9860)) &
626 AR_PHY_AGC_CONTROL_CAL0x00000001))
627 break;
628 DELAY(10)(*delay_func)(10);
629 }
630 if (ntries == 10000)
631 return (ETIMEDOUT60);
632 AR_SETBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC)(sc)->ops.write((sc), (0x982c), ((sc)->ops.read((sc), (
0x982c)) | (0x00008000)))
;
633 AR_CLRBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE)(sc)->ops.write((sc), (0xa358), ((sc)->ops.read((sc), (
0xa358)) & ~(0x00000002)))
;
634 AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL)(sc)->ops.write((sc), (0x9860), ((sc)->ops.read((sc), (
0x9860)) & ~(0x00010000)))
;
635 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
636 return (0);
637}
638
639void
640ar9271_load_ani(struct athn_softc *sc)
641{
642#if NATHN_USB1 > 0
643 /* Write ANI registers. */
644 AR_WRITE(sc, AR_PHY_DESIRED_SZ, 0x6d4000e2)(sc)->ops.write((sc), (0x9850), (0x6d4000e2));
645 AR_WRITE(sc, AR_PHY_AGC_CTL1, 0x3139605e)(sc)->ops.write((sc), (0x985c), (0x3139605e));
646 AR_WRITE(sc, AR_PHY_FIND_SIG, 0x7ec84d2e)(sc)->ops.write((sc), (0x9858), (0x7ec84d2e));
647 AR_WRITE(sc, AR_PHY_SFCORR_LOW, 0x06903881)(sc)->ops.write((sc), (0x986c), (0x06903881));
648 AR_WRITE(sc, AR_PHY_SFCORR, 0x5ac640d0)(sc)->ops.write((sc), (0x9868), (0x5ac640d0));
649 AR_WRITE(sc, AR_PHY_CCK_DETECT, 0x803e68c8)(sc)->ops.write((sc), (0xa208), (0x803e68c8));
650 AR_WRITE(sc, AR_PHY_TIMING5, 0xd00a8007)(sc)->ops.write((sc), (0x9924), (0xd00a8007));
651 AR_WRITE(sc, AR_PHY_SFCORR_EXT, 0x05eea6d4)(sc)->ops.write((sc), (0x99c0), (0x05eea6d4));
652 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
653#endif /* NATHN_USB */
654}
655
656int
657ar9285_init_calib(struct athn_softc *sc, struct ieee80211_channel *c,
658 struct ieee80211_channel *extc)
659{
660 uint32_t reg, mask, clcgain, rf2g5_svg;
661 int i, maxgain, nclcs, thresh, error;
662
663 /* Do carrier leakage calibration. */
664 if ((error = ar9285_cl_cal(sc, c, extc)) != 0)
665 return (error);
666
667 /* Workaround for high temperature is not applicable on AR9271. */
668 if (AR_SREV_9271(sc)((sc)->mac_ver == 0x140))
669 return (0);
670
671 mask = 0;
672 nclcs = 0;
673 reg = AR_READ(sc, AR_PHY_TX_PWRCTRL7)(sc)->ops.read((sc), (0xa274));
674 maxgain = MS(reg, AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX)(((uint32_t)(reg) & 0x0007e000) >> 13);
675 for (i = 0; i <= maxgain; i++) {
676 reg = AR_READ(sc, AR_PHY_TX_GAIN_TBL(i))(sc)->ops.read((sc), ((0xa300 + (i) * 4)));
677 clcgain = MS(reg, AR_PHY_TX_GAIN_CLC)(((uint32_t)(reg) & 0x0000001e) >> 1);
678 /* NB: clcgain <= 0xf. */
679 if (!(mask & (1 << clcgain))) {
680 mask |= 1 << clcgain;
681 nclcs++;
682 }
683 }
684 thresh = 0;
685 for (i = 0; i < nclcs; i++) {
686 reg = AR_READ(sc, AR_PHY_CLC_TBL(i))(sc)->ops.read((sc), ((0xa35c + (i) * 4)));
687 if (MS(reg, AR_PHY_CLC_I0)(((uint32_t)(reg) & 0x07ff0000) >> 16) == 0)
688 thresh++;
689 if (MS(reg, AR_PHY_CLC_Q0)(((uint32_t)(reg) & 0x0000ffd0) >> 5) == 0)
690 thresh++;
691 }
692 if (thresh <= AR9285_CL_CAL_REDO_THRESH1)
693 return (0); /* No need to redo. */
694
695 /* Threshold reached, redo carrier leakage calibration. */
696 DPRINTFN(2, ("CLC threshold=%d\n", thresh));
697 rf2g5_svg = reg = AR_READ(sc, AR9285_AN_RF2G5)(sc)->ops.read((sc), (0x7830));
698 if ((AR_READ(sc, AR_AN_SYNTH9)(sc)->ops.read((sc), (0x7868)) & 0x7) == 0x1) /* XE rev. */
699 reg = RW(reg, AR9285_AN_RF2G5_IC50TX, 0x5)(((reg) & ~0x00000700) | (((uint32_t)(0x5) << 8) &
0x00000700))
;
700 else
701 reg = RW(reg, AR9285_AN_RF2G5_IC50TX, 0x4)(((reg) & ~0x00000700) | (((uint32_t)(0x4) << 8) &
0x00000700))
;
702 AR_WRITE(sc, AR9285_AN_RF2G5, reg)(sc)->ops.write((sc), (0x7830), (reg));
703 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
704 error = ar9285_cl_cal(sc, c, extc);
705 AR_WRITE(sc, AR9285_AN_RF2G5, rf2g5_svg)(sc)->ops.write((sc), (0x7830), (rf2g5_svg));
706 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
707 return (error);
708}
709
710void
711ar9285_get_pdadcs(struct athn_softc *sc, struct ieee80211_channel *c,
712 int nxpdgains, uint8_t overlap, uint8_t *boundaries, uint8_t *pdadcs)
713{
714 const struct ar9285_eeprom *eep = sc->eep;
715 const struct ar9285_cal_data_per_freq *pierdata;
716 const uint8_t *pierfreq;
717 struct athn_pier lopier, hipier;
718 uint8_t fbin;
719 int i, lo, hi, npiers;
720
721 pierfreq = eep->calFreqPier2G;
722 pierdata = eep->calPierData2G;
723 npiers = AR9285_NUM_2G_CAL_PIERS3;
724
725 /* Find channel in ROM pier table. */
726 fbin = athn_chan2fbin(c);
727 athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi);
728
729 lopier.fbin = pierfreq[lo];
730 hipier.fbin = pierfreq[hi];
731 for (i = 0; i < nxpdgains; i++) {
732 lopier.pwr[i] = pierdata[lo].pwrPdg[i];
733 lopier.vpd[i] = pierdata[lo].vpdPdg[i];
734 hipier.pwr[i] = pierdata[lo].pwrPdg[i];
735 hipier.vpd[i] = pierdata[lo].vpdPdg[i];
736 }
737 ar5008_get_pdadcs(sc, fbin, &lopier, &hipier, nxpdgains,
738 AR9285_PD_GAIN_ICEPTS5, overlap, boundaries, pdadcs);
739}
740
741void
742ar9285_set_power_calib(struct athn_softc *sc, struct ieee80211_channel *c)
743{
744 const struct ar9285_eeprom *eep = sc->eep;
745 uint8_t boundaries[AR_PD_GAINS_IN_MASK4];
746 uint8_t pdadcs[AR_NUM_PDADC_VALUES128];
747 uint8_t xpdgains[AR9285_NUM_PD_GAINS2];
748 uint8_t overlap;
749 uint32_t reg;
750 int i, nxpdgains;
751
752 if (sc->eep_rev < AR_EEP_MINOR_VER_22) {
753 overlap = MS(AR_READ(sc, AR_PHY_TPCRG5),(((uint32_t)((sc)->ops.read((sc), (0xa26c))) & 0x0000000f
) >> 0)
754 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)(((uint32_t)((sc)->ops.read((sc), (0xa26c))) & 0x0000000f
) >> 0)
;
755 } else
756 overlap = eep->modalHeader.pdGainOverlap;
757
758 nxpdgains = 0;
759 memset(xpdgains, 0, sizeof(xpdgains))__builtin_memset((xpdgains), (0), (sizeof(xpdgains)));
760 for (i = AR9285_PD_GAINS_IN_MASK4 - 1; i >= 0; i--) {
761 if (nxpdgains >= AR9285_NUM_PD_GAINS2)
762 break;
763 if (eep->modalHeader.xpdGain & (1 << i))
764 xpdgains[nxpdgains++] = i;
765 }
766 reg = AR_READ(sc, AR_PHY_TPCRG1)(sc)->ops.read((sc), (0xa258));
767 reg = RW(reg, AR_PHY_TPCRG1_NUM_PD_GAIN, nxpdgains - 1)(((reg) & ~0x0000c000) | (((uint32_t)(nxpdgains - 1) <<
14) & 0x0000c000))
;
768 reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_1, xpdgains[0])(((reg) & ~0x00030000) | (((uint32_t)(xpdgains[0]) <<
16) & 0x00030000))
;
769 reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_2, xpdgains[1])(((reg) & ~0x000c0000) | (((uint32_t)(xpdgains[1]) <<
18) & 0x000c0000))
;
770 AR_WRITE(sc, AR_PHY_TPCRG1, reg)(sc)->ops.write((sc), (0xa258), (reg));
771
772 /* NB: No open loop power control for AR9285. */
773 ar9285_get_pdadcs(sc, c, nxpdgains, overlap, boundaries, pdadcs);
774
775 /* Write boundaries. */
776 reg = SM(AR_PHY_TPCRG5_PD_GAIN_OVERLAP, overlap)(((uint32_t)(overlap) << 0) & 0x0000000f);
777 reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1, boundaries[0])(((uint32_t)(boundaries[0]) << 4) & 0x000003f0);
778 reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2, boundaries[1])(((uint32_t)(boundaries[1]) << 10) & 0x0000fc00);
779 reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3, boundaries[2])(((uint32_t)(boundaries[2]) << 16) & 0x003f0000);
780 reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4, boundaries[3])(((uint32_t)(boundaries[3]) << 22) & 0x0fc00000);
781 AR_WRITE(sc, AR_PHY_TPCRG5, reg)(sc)->ops.write((sc), (0xa26c), (reg));
782
783 /* Write PDADC values. */
784 for (i = 0; i < AR_NUM_PDADC_VALUES128; i += 4) {
785 AR_WRITE(sc, AR_PHY_PDADC_TBL_BASE + i,(sc)->ops.write((sc), (0xa280 + i), (pdadcs[i + 0] <<
0 | pdadcs[i + 1] << 8 | pdadcs[i + 2] << 16 | pdadcs
[i + 3] << 24))
786 pdadcs[i + 0] << 0 |(sc)->ops.write((sc), (0xa280 + i), (pdadcs[i + 0] <<
0 | pdadcs[i + 1] << 8 | pdadcs[i + 2] << 16 | pdadcs
[i + 3] << 24))
787 pdadcs[i + 1] << 8 |(sc)->ops.write((sc), (0xa280 + i), (pdadcs[i + 0] <<
0 | pdadcs[i + 1] << 8 | pdadcs[i + 2] << 16 | pdadcs
[i + 3] << 24))
788 pdadcs[i + 2] << 16 |(sc)->ops.write((sc), (0xa280 + i), (pdadcs[i + 0] <<
0 | pdadcs[i + 1] << 8 | pdadcs[i + 2] << 16 | pdadcs
[i + 3] << 24))
789 pdadcs[i + 3] << 24)(sc)->ops.write((sc), (0xa280 + i), (pdadcs[i + 0] <<
0 | pdadcs[i + 1] << 8 | pdadcs[i + 2] << 16 | pdadcs
[i + 3] << 24))
;
790 }
791 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
792}
793
794void
795ar9285_set_txpower(struct athn_softc *sc, struct ieee80211_channel *c,
796 struct ieee80211_channel *extc)
797{
798 const struct ar9285_eeprom *eep = sc->eep;
799 const struct ar9285_modal_eep_header *modal = &eep->modalHeader;
800 uint8_t tpow_cck[4], tpow_ofdm[4];
801 uint8_t tpow_cck_ext[4], tpow_ofdm_ext[4];
802 uint8_t tpow_ht20[8], tpow_ht40[8];
803 uint8_t ht40inc;
804 int16_t max_ant_gain, power[ATHN_POWER_COUNT68];
805 int i;
806
807 ar9285_set_power_calib(sc, c);
808
809 /* Compute transmit power reduction due to antenna gain. */
810 max_ant_gain = modal->antennaGain;
Value stored to 'max_ant_gain' is never read
811 /* XXX */
812
813 /* Get CCK target powers. */
814 ar5008_get_lg_tpow(sc, c, AR_CTL_11B1, eep->calTargetPowerCck,
815 AR9285_NUM_2G_CCK_TARGET_POWERS3, tpow_cck);
816
817 /* Get OFDM target powers. */
818 ar5008_get_lg_tpow(sc, c, AR_CTL_11G2, eep->calTargetPower2G,
819 AR9285_NUM_2G_20_TARGET_POWERS3, tpow_ofdm);
820
821 /* Get HT-20 target powers. */
822 ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT205, eep->calTargetPower2GHT20,
823 AR9285_NUM_2G_20_TARGET_POWERS3, tpow_ht20);
824
825 if (extc != NULL((void *)0)) {
826 /* Get HT-40 target powers. */
827 ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT407,
828 eep->calTargetPower2GHT40, AR9285_NUM_2G_40_TARGET_POWERS3,
829 tpow_ht40);
830
831 /* Get secondary channel CCK target powers. */
832 ar5008_get_lg_tpow(sc, extc, AR_CTL_11B1,
833 eep->calTargetPowerCck, AR9285_NUM_2G_CCK_TARGET_POWERS3,
834 tpow_cck_ext);
835
836 /* Get secondary channel OFDM target powers. */
837 ar5008_get_lg_tpow(sc, extc, AR_CTL_11G2,
838 eep->calTargetPower2G, AR9285_NUM_2G_20_TARGET_POWERS3,
839 tpow_ofdm_ext);
840 }
841
842 memset(power, 0, sizeof(power))__builtin_memset((power), (0), (sizeof(power)));
843 /* Shuffle target powers across transmit rates. */
844 power[ATHN_POWER_OFDM60 ] =
845 power[ATHN_POWER_OFDM91 ] =
846 power[ATHN_POWER_OFDM122 ] =
847 power[ATHN_POWER_OFDM183 ] =
848 power[ATHN_POWER_OFDM244 ] = tpow_ofdm[0];
849 power[ATHN_POWER_OFDM365 ] = tpow_ofdm[1];
850 power[ATHN_POWER_OFDM486 ] = tpow_ofdm[2];
851 power[ATHN_POWER_OFDM547 ] = tpow_ofdm[3];
852 power[ATHN_POWER_XR15 ] = tpow_ofdm[0];
853 power[ATHN_POWER_CCK1_LP8 ] = tpow_cck[0];
854 power[ATHN_POWER_CCK2_LP9 ] =
855 power[ATHN_POWER_CCK2_SP10 ] = tpow_cck[1];
856 power[ATHN_POWER_CCK55_LP11] =
857 power[ATHN_POWER_CCK55_SP12] = tpow_cck[2];
858 power[ATHN_POWER_CCK11_LP13] =
859 power[ATHN_POWER_CCK11_SP14] = tpow_cck[3];
860 for (i = 0; i < nitems(tpow_ht20)(sizeof((tpow_ht20)) / sizeof((tpow_ht20)[0])); i++)
861 power[ATHN_POWER_HT20(i)(16 + (i))] = tpow_ht20[i];
862 if (extc != NULL((void *)0)) {
863 /* Correct PAR difference between HT40 and HT20/Legacy. */
864 if (sc->eep_rev >= AR_EEP_MINOR_VER_22)
865 ht40inc = modal->ht40PowerIncForPdadc;
866 else
867 ht40inc = AR_HT40_POWER_INC_FOR_PDADC2;
868 for (i = 0; i < nitems(tpow_ht40)(sizeof((tpow_ht40)) / sizeof((tpow_ht40)[0])); i++)
869 power[ATHN_POWER_HT40(i)(40 + (i))] = tpow_ht40[i] + ht40inc;
870 power[ATHN_POWER_OFDM_DUP65] = tpow_ht40[0];
871 power[ATHN_POWER_CCK_DUP64 ] = tpow_ht40[0];
872 power[ATHN_POWER_OFDM_EXT67] = tpow_ofdm_ext[0];
873 power[ATHN_POWER_CCK_EXT66 ] = tpow_cck_ext[0];
874 }
875
876 for (i = 0; i < ATHN_POWER_COUNT68; i++) {
877 power[i] -= AR_PWR_TABLE_OFFSET_DB(-5) * 2; /* In half dB. */
878 if (power[i] > AR_MAX_RATE_POWER63)
879 power[i] = AR_MAX_RATE_POWER63;
880 }
881
882 /* Commit transmit power values to hardware. */
883 ar5008_write_txpower(sc, power);
884}