Bug Summary

File:dev/ic/ar5416.c
Warning:line 557, column 3
Value stored to 'pwr' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ar5416.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/ic/ar5416.c
1/* $OpenBSD: ar5416.c,v 1.23 2022/01/09 05:42:38 jsg Exp $ */
2
3/*-
4 * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
5 * Copyright (c) 2008-2009 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 AR5416, AR5418 and AR9160 chipsets.
23 */
24
25#include "bpfilter.h"
26
27#include <sys/param.h>
28#include <sys/sockio.h>
29#include <sys/mbuf.h>
30#include <sys/kernel.h>
31#include <sys/socket.h>
32#include <sys/systm.h>
33#include <sys/malloc.h>
34#include <sys/queue.h>
35#include <sys/timeout.h>
36#include <sys/conf.h>
37#include <sys/device.h>
38#include <sys/endian.h>
39
40#include <machine/bus.h>
41#include <machine/intr.h>
42
43#if NBPFILTER1 > 0
44#include <net/bpf.h>
45#endif
46#include <net/if.h>
47#include <net/if_media.h>
48
49#include <netinet/in.h>
50#include <netinet/if_ether.h>
51
52#include <net80211/ieee80211_var.h>
53#include <net80211/ieee80211_amrr.h>
54#include <net80211/ieee80211_ra.h>
55#include <net80211/ieee80211_radiotap.h>
56
57#include <dev/ic/athnreg.h>
58#include <dev/ic/athnvar.h>
59
60#include <dev/ic/ar5008reg.h>
61#include <dev/ic/ar5416reg.h>
62
63int ar5416_attach(struct athn_softc *);
64void ar5416_setup(struct athn_softc *);
65void ar5416_swap_rom(struct athn_softc *);
66const struct ar_spur_chan *
67 ar5416_get_spur_chans(struct athn_softc *, int);
68int ar5416_set_synth(struct athn_softc *, struct ieee80211_channel *,
69 struct ieee80211_channel *);
70uint8_t ar5416_reverse_bits(uint8_t, int);
71uint8_t ar5416_get_rf_rev(struct athn_softc *);
72void ar5416_init_from_rom(struct athn_softc *, struct ieee80211_channel *,
73 struct ieee80211_channel *);
74int ar5416_init_calib(struct athn_softc *, struct ieee80211_channel *,
75 struct ieee80211_channel *);
76void ar5416_set_power_calib(struct athn_softc *,
77 struct ieee80211_channel *);
78void ar5416_set_txpower(struct athn_softc *, struct ieee80211_channel *,
79 struct ieee80211_channel *);
80void ar5416_spur_mitigate(struct athn_softc *, struct ieee80211_channel *,
81 struct ieee80211_channel *);
82void ar5416_rw_rfbits(uint32_t *, int, int, uint32_t, int);
83void ar5416_rw_bank6tpc(struct athn_softc *, struct ieee80211_channel *,
84 uint32_t *);
85void ar5416_rf_reset(struct athn_softc *, struct ieee80211_channel *);
86void ar5416_reset_bb_gain(struct athn_softc *, struct ieee80211_channel *);
87void ar5416_force_bias(struct athn_softc *, struct ieee80211_channel *);
88void ar9160_rw_addac(struct athn_softc *, struct ieee80211_channel *,
89 uint32_t *);
90void ar5416_reset_addac(struct athn_softc *, struct ieee80211_channel *);
91void ar5416_get_pdadcs(struct athn_softc *, struct ieee80211_channel *,
92 int, int, uint8_t, uint8_t *, uint8_t *);
93
94/* Extern functions. */
95uint8_t athn_chan2fbin(struct ieee80211_channel *);
96void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *);
97int ar5008_attach(struct athn_softc *);
98void ar5008_write_txpower(struct athn_softc *, int16_t power[]);
99void ar5008_get_pdadcs(struct athn_softc *, uint8_t, struct athn_pier *,
100 struct athn_pier *, int, int, uint8_t, uint8_t *, uint8_t *);
101void ar5008_set_viterbi_mask(struct athn_softc *, int);
102void ar5008_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *,
103 uint8_t, const struct ar_cal_target_power_leg *, int, uint8_t[]);
104void ar5008_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *,
105 uint8_t, const struct ar_cal_target_power_ht *, int, uint8_t[]);
106void ar9280_olpc_get_pdadcs(struct athn_softc *, struct ieee80211_channel *,
107 int, uint8_t *, uint8_t *, uint8_t *);
108
109
110int
111ar5416_attach(struct athn_softc *sc)
112{
113 sc->eep_base = AR5416_EEP_START_LOC256;
114 sc->eep_size = sizeof(struct ar5416_eeprom);
115 sc->ngpiopins = 14;
116 sc->led_pin = 1;
117 sc->workaround = AR5416_WA_DEFAULT0x0000073f;
118 sc->ops.setup = ar5416_setup;
119 sc->ops.swap_rom = ar5416_swap_rom;
120 sc->ops.init_from_rom = ar5416_init_from_rom;
121 sc->ops.set_txpower = ar5416_set_txpower;
122 sc->ops.set_synth = ar5416_set_synth;
123 sc->ops.spur_mitigate = ar5416_spur_mitigate;
124 sc->ops.get_spur_chans = ar5416_get_spur_chans;
125 sc->cca_min_2g = AR5416_PHY_CCA_MIN_GOOD_VAL_2GHZ(-100);
126 sc->cca_max_2g = AR5416_PHY_CCA_MAX_GOOD_VAL_2GHZ(-80);
127 sc->cca_min_5g = AR5416_PHY_CCA_MIN_GOOD_VAL_5GHZ(-110);
128 sc->cca_max_5g = AR5416_PHY_CCA_MAX_GOOD_VAL_5GHZ(-90);
129 if (AR_SREV_9160_10_OR_LATER(sc)((sc)->mac_ver >= 0x040))
130 sc->ini = &ar9160_ini;
131 else
132 sc->ini = &ar5416_ini;
133 sc->serdes = &ar5416_serdes;
134
135 return (ar5008_attach(sc));
136}
137
138void
139ar5416_setup(struct athn_softc *sc)
140{
141 /* Select ADDAC programming. */
142 if (AR_SREV_9160_11(sc)(((sc)->mac_ver == 0x040) && (sc)->mac_rev == 1
)
)
143 sc->addac = &ar9160_1_1_addac;
144 else if (AR_SREV_9160_10_OR_LATER(sc)((sc)->mac_ver >= 0x040))
145 sc->addac = &ar9160_1_0_addac;
146 else if (AR_SREV_5416_22_OR_LATER(sc)((((sc)->mac_ver == 0x00d || (sc)->mac_ver == 0x00c) &&
(sc)->mac_rev >= 2) || (sc)->mac_ver >= 0x014)
)
147 sc->addac = &ar5416_2_2_addac;
148 else
149 sc->addac = &ar5416_2_1_addac;
150}
151
152void
153ar5416_swap_rom(struct athn_softc *sc)
154{
155 struct ar5416_eeprom *eep = sc->eep;
156 struct ar5416_modal_eep_header *modal;
157 int i, j;
158
159 for (i = 0; i < 2; i++) { /* Dual-band. */
160 modal = &eep->modalHeader[i];
161
162 modal->antCtrlCommon = swap32(modal->antCtrlCommon)(__uint32_t)(__builtin_constant_p(modal->antCtrlCommon) ? (
__uint32_t)(((__uint32_t)(modal->antCtrlCommon) & 0xff
) << 24 | ((__uint32_t)(modal->antCtrlCommon) & 0xff00
) << 8 | ((__uint32_t)(modal->antCtrlCommon) & 0xff0000
) >> 8 | ((__uint32_t)(modal->antCtrlCommon) & 0xff000000
) >> 24) : __swap32md(modal->antCtrlCommon))
;
163 for (j = 0; j < AR5416_MAX_CHAINS3; j++) {
164 modal->antCtrlChain[j] =
165 swap32(modal->antCtrlChain[j])(__uint32_t)(__builtin_constant_p(modal->antCtrlChain[j]) ?
(__uint32_t)(((__uint32_t)(modal->antCtrlChain[j]) & 0xff
) << 24 | ((__uint32_t)(modal->antCtrlChain[j]) &
0xff00) << 8 | ((__uint32_t)(modal->antCtrlChain[j]
) & 0xff0000) >> 8 | ((__uint32_t)(modal->antCtrlChain
[j]) & 0xff000000) >> 24) : __swap32md(modal->antCtrlChain
[j]))
;
166 }
167 for (j = 0; j < AR_EEPROM_MODAL_SPURS5; j++) {
168 modal->spurChans[j].spurChan =
169 swap16(modal->spurChans[j].spurChan)(__uint16_t)(__builtin_constant_p(modal->spurChans[j].spurChan
) ? (__uint16_t)(((__uint16_t)(modal->spurChans[j].spurChan
) & 0xffU) << 8 | ((__uint16_t)(modal->spurChans
[j].spurChan) & 0xff00U) >> 8) : __swap16md(modal->
spurChans[j].spurChan))
;
170 }
171 }
172}
173
174const struct ar_spur_chan *
175ar5416_get_spur_chans(struct athn_softc *sc, int is2ghz)
176{
177 const struct ar5416_eeprom *eep = sc->eep;
178
179 return (eep->modalHeader[is2ghz].spurChans);
180}
181
182int
183ar5416_set_synth(struct athn_softc *sc, struct ieee80211_channel *c,
184 struct ieee80211_channel *extc)
185{
186 uint32_t phy, reg;
187 uint32_t freq = c->ic_freq;
188 uint8_t chansel;
189
190 phy = 0;
191 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)) {
192 if (((freq - 2192) % 5) == 0) {
193 chansel = ((freq - 672) * 2 - 3040) / 10;
194 } else if (((freq - 2224) % 5) == 0) {
195 chansel = ((freq - 704) * 2 - 3040) / 10;
196 phy |= AR5416_BMODE_SYNTH0x00000002;
197 } else
198 return (EINVAL22);
199 chansel <<= 2;
200
201 reg = AR_READ(sc, AR_PHY_CCK_TX_CTRL)(sc)->ops.read((sc), (0xa204));
202 if (freq == 2484) /* Channel 14. */
203 reg |= AR_PHY_CCK_TX_CTRL_JAPAN0x00000010;
204 else
205 reg &= ~AR_PHY_CCK_TX_CTRL_JAPAN0x00000010;
206 AR_WRITE(sc, AR_PHY_CCK_TX_CTRL, reg)(sc)->ops.write((sc), (0xa204), (reg));
207
208 /* Fix for orientation sensitivity issue. */
209 if (AR_SREV_5416(sc)((sc)->mac_ver == 0x00d || (sc)->mac_ver == 0x00c))
210 ar5416_force_bias(sc, c);
211 } else {
212 if (freq >= 5120 && (freq % 20) == 0) {
213 chansel = (freq - 4800) / 20;
214 chansel <<= 2;
215 phy |= SM(AR5416_AMODE_REFSEL, 2)(((uint32_t)(2) << 2) & 0x0000000c);
216 } else if ((freq % 10) == 0) {
217 chansel = (freq - 4800) / 10;
218 chansel <<= 1;
219 if (AR_SREV_9160_10_OR_LATER(sc)((sc)->mac_ver >= 0x040))
220 phy |= SM(AR5416_AMODE_REFSEL, 1)(((uint32_t)(1) << 2) & 0x0000000c);
221 else
222 phy |= SM(AR5416_AMODE_REFSEL, 2)(((uint32_t)(2) << 2) & 0x0000000c);
223 } else if ((freq % 5) == 0) {
224 chansel = (freq - 4800) / 5;
225 phy |= SM(AR5416_AMODE_REFSEL, 2)(((uint32_t)(2) << 2) & 0x0000000c);
226 } else
227 return (EINVAL22);
228 }
229 chansel = ar5416_reverse_bits(chansel, 8);
230 phy |= chansel << 8 | 1 << 5 | 1;
231 DPRINTFN(4, ("AR_PHY(0x37)=0x%08x\n", phy));
232 AR_WRITE(sc, AR_PHY(0x37), phy)(sc)->ops.write((sc), ((0x9800 + (0x37) * 4)), (phy));
233 return (0);
234}
235
236void
237ar5416_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
238 struct ieee80211_channel *extc)
239{
240 static const uint32_t chainoffset[] = { 0x0000, 0x2000, 0x1000 };
241 const struct ar5416_eeprom *eep = sc->eep;
242 const struct ar5416_modal_eep_header *modal;
243 uint32_t reg, offset;
244 uint8_t txRxAtten;
245 int i;
246
247 modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)];
248
249 AR_WRITE(sc, AR_PHY_SWITCH_COM, modal->antCtrlCommon)(sc)->ops.write((sc), (0x9964), (modal->antCtrlCommon));
250
251 for (i = 0; i < AR5416_MAX_CHAINS3; i++) {
252 if (AR_SREV_5416_20_OR_LATER(sc)((((sc)->mac_ver == 0x00d || (sc)->mac_ver == 0x00c) &&
(sc)->mac_rev >= 1) || (sc)->mac_ver >= 0x014)
&&
253 (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5))
254 offset = chainoffset[i];
255 else
256 offset = i * 0x1000;
257
258 AR_WRITE(sc, AR_PHY_SWITCH_CHAIN_0 + offset,(sc)->ops.write((sc), (0x9960 + offset), (modal->antCtrlChain
[i]))
259 modal->antCtrlChain[i])(sc)->ops.write((sc), (0x9960 + offset), (modal->antCtrlChain
[i]))
;
260
261 reg = AR_READ(sc, AR_PHY_TIMING_CTRL4_0 + offset)(sc)->ops.read((sc), (0x9920 + offset));
262 reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,(((reg) & ~0x000007e0) | (((uint32_t)(modal->iqCalICh[
i]) << 5) & 0x000007e0))
263 modal->iqCalICh[i])(((reg) & ~0x000007e0) | (((uint32_t)(modal->iqCalICh[
i]) << 5) & 0x000007e0))
;
264 reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,(((reg) & ~0x0000001f) | (((uint32_t)(modal->iqCalQCh[
i]) << 0) & 0x0000001f))
265 modal->iqCalQCh[i])(((reg) & ~0x0000001f) | (((uint32_t)(modal->iqCalQCh[
i]) << 0) & 0x0000001f))
;
266 AR_WRITE(sc, AR_PHY_TIMING_CTRL4_0 + offset, reg)(sc)->ops.write((sc), (0x9920 + offset), (reg));
267
268 if (i > 0 && !AR_SREV_5416_20_OR_LATER(sc)((((sc)->mac_ver == 0x00d || (sc)->mac_ver == 0x00c) &&
(sc)->mac_rev >= 1) || (sc)->mac_ver >= 0x014)
)
269 continue;
270
271 if (sc->eep_rev >= AR_EEP_MINOR_VER_33) {
272 reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset)(sc)->ops.read((sc), (0xa20c + offset));
273 reg = RW(reg, AR_PHY_GAIN_2GHZ_BSW_MARGIN,(((reg) & ~0x00003c00) | (((uint32_t)(modal->bswMargin
[i]) << 10) & 0x00003c00))
274 modal->bswMargin[i])(((reg) & ~0x00003c00) | (((uint32_t)(modal->bswMargin
[i]) << 10) & 0x00003c00))
;
275 reg = RW(reg, AR_PHY_GAIN_2GHZ_BSW_ATTEN,(((reg) & ~0x0000001f) | (((uint32_t)(modal->bswAtten[
i]) << 0) & 0x0000001f))
276 modal->bswAtten[i])(((reg) & ~0x0000001f) | (((uint32_t)(modal->bswAtten[
i]) << 0) & 0x0000001f))
;
277 AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg)(sc)->ops.write((sc), (0xa20c + offset), (reg));
278 }
279 if (sc->eep_rev >= AR_EEP_MINOR_VER_33)
280 txRxAtten = modal->txRxAttenCh[i];
281 else /* Workaround for ROM versions < 14.3. */
282 txRxAtten = IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0) ? 23 : 44;
283 reg = AR_READ(sc, AR_PHY_RXGAIN + offset)(sc)->ops.read((sc), (0x9848 + offset));
284 reg = RW(reg, AR_PHY_RXGAIN_TXRX_ATTEN, txRxAtten)(((reg) & ~0x0003f000) | (((uint32_t)(txRxAtten) <<
12) & 0x0003f000))
;
285 AR_WRITE(sc, AR_PHY_RXGAIN + offset, reg)(sc)->ops.write((sc), (0x9848 + offset), (reg));
286
287 reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset)(sc)->ops.read((sc), (0xa20c + offset));
288 reg = RW(reg, AR_PHY_GAIN_2GHZ_RXTX_MARGIN,(((reg) & ~0x00fc0000) | (((uint32_t)(modal->rxTxMarginCh
[i]) << 18) & 0x00fc0000))
289 modal->rxTxMarginCh[i])(((reg) & ~0x00fc0000) | (((uint32_t)(modal->rxTxMarginCh
[i]) << 18) & 0x00fc0000))
;
290 AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg)(sc)->ops.write((sc), (0xa20c + offset), (reg));
291 }
292 reg = AR_READ(sc, AR_PHY_SETTLING)(sc)->ops.read((sc), (0x9844));
293 reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->switchSettling)(((reg) & ~0x00003f80) | (((uint32_t)(modal->switchSettling
) << 7) & 0x00003f80))
;
294 AR_WRITE(sc, AR_PHY_SETTLING, reg)(sc)->ops.write((sc), (0x9844), (reg));
295
296 reg = AR_READ(sc, AR_PHY_DESIRED_SZ)(sc)->ops.read((sc), (0x9850));
297 reg = RW(reg, AR_PHY_DESIRED_SZ_ADC, modal->adcDesiredSize)(((reg) & ~0x000000ff) | (((uint32_t)(modal->adcDesiredSize
) << 0) & 0x000000ff))
;
298 reg = RW(reg, AR_PHY_DESIRED_SZ_PGA, modal->pgaDesiredSize)(((reg) & ~0x0000ff00) | (((uint32_t)(modal->pgaDesiredSize
) << 8) & 0x0000ff00))
;
299 AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg)(sc)->ops.write((sc), (0x9850), (reg));
300
301 reg = SM(AR_PHY_RF_CTL4_TX_END_XPAA_OFF, modal->txEndToXpaOff)(((uint32_t)(modal->txEndToXpaOff) << 16) & 0x00ff0000
)
;
302 reg |= SM(AR_PHY_RF_CTL4_TX_END_XPAB_OFF, modal->txEndToXpaOff)(((uint32_t)(modal->txEndToXpaOff) << 24) & 0xff000000
)
;
303 reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAA_ON, modal->txFrameToXpaOn)(((uint32_t)(modal->txFrameToXpaOn) << 0) & 0x000000ff
)
;
304 reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAB_ON, modal->txFrameToXpaOn)(((uint32_t)(modal->txFrameToXpaOn) << 8) & 0x0000ff00
)
;
305 AR_WRITE(sc, AR_PHY_RF_CTL4, reg)(sc)->ops.write((sc), (0x9834), (reg));
306
307 reg = AR_READ(sc, AR_PHY_RF_CTL3)(sc)->ops.read((sc), (0x9828));
308 reg = RW(reg, AR_PHY_TX_END_TO_A2_RX_ON, modal->txEndToRxOn)(((reg) & ~0x00ff0000) | (((uint32_t)(modal->txEndToRxOn
) << 16) & 0x00ff0000))
;
309 AR_WRITE(sc, AR_PHY_RF_CTL3, reg)(sc)->ops.write((sc), (0x9828), (reg));
310
311 reg = AR_READ(sc, AR_PHY_CCA(0))(sc)->ops.read((sc), ((0x9864 + (0) * 0x1000)));
312 reg = RW(reg, AR_PHY_CCA_THRESH62, modal->thresh62)(((reg) & ~0x0007f000) | (((uint32_t)(modal->thresh62)
<< 12) & 0x0007f000))
;
313 AR_WRITE(sc, AR_PHY_CCA(0), reg)(sc)->ops.write((sc), ((0x9864 + (0) * 0x1000)), (reg));
314
315 reg = AR_READ(sc, AR_PHY_EXT_CCA(0))(sc)->ops.read((sc), ((0x99bc + (0) * 0x1000)));
316 reg = RW(reg, AR_PHY_EXT_CCA_THRESH62, modal->thresh62)(((reg) & ~0x007f0000) | (((uint32_t)(modal->thresh62)
<< 16) & 0x007f0000))
;
317 AR_WRITE(sc, AR_PHY_EXT_CCA(0), reg)(sc)->ops.write((sc), ((0x99bc + (0) * 0x1000)), (reg));
318
319 if (sc->eep_rev >= AR_EEP_MINOR_VER_22) {
320 reg = AR_READ(sc, AR_PHY_RF_CTL2)(sc)->ops.read((sc), (0x9824));
321 reg = RW(reg, AR_PHY_TX_END_DATA_START,(((reg) & ~0x000000ff) | (((uint32_t)(modal->txFrameToDataStart
) << 0) & 0x000000ff))
322 modal->txFrameToDataStart)(((reg) & ~0x000000ff) | (((uint32_t)(modal->txFrameToDataStart
) << 0) & 0x000000ff))
;
323 reg = RW(reg, AR_PHY_TX_END_PA_ON, modal->txFrameToPaOn)(((reg) & ~0x0000ff00) | (((uint32_t)(modal->txFrameToPaOn
) << 8) & 0x0000ff00))
;
324 AR_WRITE(sc, AR_PHY_RF_CTL2, reg)(sc)->ops.write((sc), (0x9824), (reg));
325 }
326 if (sc->eep_rev >= AR_EEP_MINOR_VER_33 && extc != NULL((void *)0)) {
327 /* Overwrite switch settling with HT-40 value. */
328 reg = AR_READ(sc, AR_PHY_SETTLING)(sc)->ops.read((sc), (0x9844));
329 reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->swSettleHt40)(((reg) & ~0x00003f80) | (((uint32_t)(modal->swSettleHt40
) << 7) & 0x00003f80))
;
330 AR_WRITE(sc, AR_PHY_SETTLING, reg)(sc)->ops.write((sc), (0x9844), (reg));
331 }
332}
333
334int
335ar5416_init_calib(struct athn_softc *sc, struct ieee80211_channel *c,
336 struct ieee80211_channel *extc)
337{
338 int ntries;
339
340 if (AR_SREV_9280_10_OR_LATER(sc)((sc)->mac_ver >= 0x080)) {
341 /* XXX Linux tests AR9287?! */
342 AR_CLRBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC)(sc)->ops.write((sc), (0x982c), ((sc)->ops.read((sc), (
0x982c)) & ~(0x00008000)))
;
343 AR_SETBITS(sc, AR_PHY_AGC_CONTROL,(sc)->ops.write((sc), (0x9860), ((sc)->ops.read((sc), (
0x9860)) | (0x00010000)))
344 AR_PHY_AGC_CONTROL_FLTR_CAL)(sc)->ops.write((sc), (0x9860), ((sc)->ops.read((sc), (
0x9860)) | (0x00010000)))
;
345 }
346 /* Calibrate the AGC. */
347 AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL)(sc)->ops.write((sc), (0x9860), ((sc)->ops.read((sc), (
0x9860)) | (0x00000001)))
;
348 /* Poll for offset calibration completion. */
349 for (ntries = 0; ntries < 10000; ntries++) {
350 if (!(AR_READ(sc, AR_PHY_AGC_CONTROL)(sc)->ops.read((sc), (0x9860)) &
351 AR_PHY_AGC_CONTROL_CAL0x00000001))
352 break;
353 DELAY(10)(*delay_func)(10);
354 }
355 if (ntries == 10000)
356 return (ETIMEDOUT60);
357 if (AR_SREV_9280_10_OR_LATER(sc)((sc)->mac_ver >= 0x080)) {
358 AR_SETBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC)(sc)->ops.write((sc), (0x982c), ((sc)->ops.read((sc), (
0x982c)) | (0x00008000)))
;
359 AR_CLRBITS(sc, AR_PHY_AGC_CONTROL,(sc)->ops.write((sc), (0x9860), ((sc)->ops.read((sc), (
0x9860)) & ~(0x00010000)))
360 AR_PHY_AGC_CONTROL_FLTR_CAL)(sc)->ops.write((sc), (0x9860), ((sc)->ops.read((sc), (
0x9860)) & ~(0x00010000)))
;
361 }
362 return (0);
363}
364
365void
366ar5416_get_pdadcs(struct athn_softc *sc, struct ieee80211_channel *c,
367 int chain, int nxpdgains, uint8_t overlap, uint8_t *boundaries,
368 uint8_t *pdadcs)
369{
370 const struct ar5416_eeprom *eep = sc->eep;
371 const struct ar5416_cal_data_per_freq *pierdata;
372 const uint8_t *pierfreq;
373 struct athn_pier lopier, hipier;
374 int16_t delta;
375 uint8_t fbin, pwroff;
376 int i, lo, hi, npiers;
377
378 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)) {
379 pierfreq = eep->calFreqPier2G;
380 pierdata = eep->calPierData2G[chain];
381 npiers = AR5416_NUM_2G_CAL_PIERS4;
382 } else {
383 pierfreq = eep->calFreqPier5G;
384 pierdata = eep->calPierData5G[chain];
385 npiers = AR5416_NUM_5G_CAL_PIERS8;
386 }
387 /* Find channel in ROM pier table. */
388 fbin = athn_chan2fbin(c);
389 athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi);
390
391 lopier.fbin = pierfreq[lo];
392 hipier.fbin = pierfreq[hi];
393 for (i = 0; i < nxpdgains; i++) {
394 lopier.pwr[i] = pierdata[lo].pwrPdg[i];
395 lopier.vpd[i] = pierdata[lo].vpdPdg[i];
396 hipier.pwr[i] = pierdata[lo].pwrPdg[i];
397 hipier.vpd[i] = pierdata[lo].vpdPdg[i];
398 }
399 ar5008_get_pdadcs(sc, fbin, &lopier, &hipier, nxpdgains,
400 AR5416_PD_GAIN_ICEPTS5, overlap, boundaries, pdadcs);
401
402 if (!AR_SREV_9280_20_OR_LATER(sc)((sc)->mac_ver > 0x080 || (((sc)->mac_ver == 0x080) &&
(sc)->mac_rev >= 1))
)
403 return;
404
405 if (sc->eep_rev >= AR_EEP_MINOR_VER_2121)
406 pwroff = eep->baseEepHeader.pwrTableOffset;
407 else
408 pwroff = AR_PWR_TABLE_OFFSET_DB(-5);
409 delta = (pwroff - AR_PWR_TABLE_OFFSET_DB(-5)) * 2; /* In half dB. */
410
411 /* Change the original gain boundaries setting. */
412 for (i = 0; i < nxpdgains; i++) {
413 /* XXX Possible overflows? */
414 boundaries[i] -= delta;
415 if (boundaries[i] > AR_MAX_RATE_POWER63 - overlap)
416 boundaries[i] = AR_MAX_RATE_POWER63 - overlap;
417 }
418 if (delta != 0) {
419 /* Shift the PDADC table to start at the new offset. */
420 for (i = 0; i < AR_NUM_PDADC_VALUES128; i++)
421 pdadcs[i] = pdadcs[MIN(i + delta,(((i + delta)<(128 - 1))?(i + delta):(128 - 1))
422 AR_NUM_PDADC_VALUES - 1)(((i + delta)<(128 - 1))?(i + delta):(128 - 1))];
423 }
424}
425
426void
427ar5416_set_power_calib(struct athn_softc *sc, struct ieee80211_channel *c)
428{
429 static const uint32_t chainoffset[] = { 0x0000, 0x2000, 0x1000 };
430 const struct ar5416_eeprom *eep = sc->eep;
431 const struct ar5416_modal_eep_header *modal;
432 uint8_t boundaries[AR_PD_GAINS_IN_MASK4];
433 uint8_t pdadcs[AR_NUM_PDADC_VALUES128];
434 uint8_t xpdgains[AR5416_NUM_PD_GAINS4];
435 uint8_t overlap, txgain;
436 uint32_t reg, offset;
437 int i, j, nxpdgains;
438
439 modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)];
440
441 if (sc->eep_rev < AR_EEP_MINOR_VER_22) {
442 overlap = MS(AR_READ(sc, AR_PHY_TPCRG5),(((uint32_t)((sc)->ops.read((sc), (0xa26c))) & 0x0000000f
) >> 0)
443 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)(((uint32_t)((sc)->ops.read((sc), (0xa26c))) & 0x0000000f
) >> 0)
;
444 } else
445 overlap = modal->pdGainOverlap;
446
447 if ((sc->flags & ATHN_FLAG_OLPC(1 << 2)) && IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)) {
448 /* XXX not here. */
449 sc->pdadc =
450 ((const struct ar_cal_data_per_freq_olpc *)
451 eep->calPierData2G[0])->vpdPdg[0][0];
452 }
453
454 nxpdgains = 0;
455 memset(xpdgains, 0, sizeof(xpdgains))__builtin_memset((xpdgains), (0), (sizeof(xpdgains)));
456 for (i = AR5416_PD_GAINS_IN_MASK4 - 1; i >= 0; i--) {
457 if (nxpdgains >= AR5416_NUM_PD_GAINS4)
458 break; /* Can't happen. */
459 if (modal->xpdGain & (1 << i))
460 xpdgains[nxpdgains++] = i;
461 }
462 reg = AR_READ(sc, AR_PHY_TPCRG1)(sc)->ops.read((sc), (0xa258));
463 reg = RW(reg, AR_PHY_TPCRG1_NUM_PD_GAIN, nxpdgains - 1)(((reg) & ~0x0000c000) | (((uint32_t)(nxpdgains - 1) <<
14) & 0x0000c000))
;
464 reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_1, xpdgains[0])(((reg) & ~0x00030000) | (((uint32_t)(xpdgains[0]) <<
16) & 0x00030000))
;
465 reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_2, xpdgains[1])(((reg) & ~0x000c0000) | (((uint32_t)(xpdgains[1]) <<
18) & 0x000c0000))
;
466 reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_3, xpdgains[2])(((reg) & ~0x00300000) | (((uint32_t)(xpdgains[2]) <<
20) & 0x00300000))
;
467 AR_WRITE(sc, AR_PHY_TPCRG1, reg)(sc)->ops.write((sc), (0xa258), (reg));
468
469 for (i = 0; i < AR5416_MAX_CHAINS3; i++) {
470 if (!(sc->txchainmask & (1 << i)))
471 continue;
472
473 if (AR_SREV_5416_20_OR_LATER(sc)((((sc)->mac_ver == 0x00d || (sc)->mac_ver == 0x00c) &&
(sc)->mac_rev >= 1) || (sc)->mac_ver >= 0x014)
&&
474 (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5))
475 offset = chainoffset[i];
476 else
477 offset = i * 0x1000;
478
479 if (sc->flags & ATHN_FLAG_OLPC(1 << 2)) {
480 ar9280_olpc_get_pdadcs(sc, c, i, boundaries,
481 pdadcs, &txgain);
482
483 reg = AR_READ(sc, AR_PHY_TX_PWRCTRL6_0)(sc)->ops.read((sc), (0xa270));
484 reg = RW(reg, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3)(((reg) & ~0x03000000) | (((uint32_t)(3) << 24) &
0x03000000))
;
485 AR_WRITE(sc, AR_PHY_TX_PWRCTRL6_0, reg)(sc)->ops.write((sc), (0xa270), (reg));
486
487 reg = AR_READ(sc, AR_PHY_TX_PWRCTRL6_1)(sc)->ops.read((sc), (0xb270));
488 reg = RW(reg, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3)(((reg) & ~0x03000000) | (((uint32_t)(3) << 24) &
0x03000000))
;
489 AR_WRITE(sc, AR_PHY_TX_PWRCTRL6_1, reg)(sc)->ops.write((sc), (0xb270), (reg));
490
491 reg = AR_READ(sc, AR_PHY_TX_PWRCTRL7)(sc)->ops.read((sc), (0xa274));
492 reg = RW(reg, AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, txgain)(((reg) & ~0x01f80000) | (((uint32_t)(txgain) << 19
) & 0x01f80000))
;
493 AR_WRITE(sc, AR_PHY_TX_PWRCTRL7, reg)(sc)->ops.write((sc), (0xa274), (reg));
494
495 overlap = 6;
496 } else {
497 ar5416_get_pdadcs(sc, c, i, nxpdgains, overlap,
498 boundaries, pdadcs);
499 }
500 /* Write boundaries. */
501 if (i == 0 || AR_SREV_5416_20_OR_LATER(sc)((((sc)->mac_ver == 0x00d || (sc)->mac_ver == 0x00c) &&
(sc)->mac_rev >= 1) || (sc)->mac_ver >= 0x014)
) {
502 reg = SM(AR_PHY_TPCRG5_PD_GAIN_OVERLAP,(((uint32_t)(overlap) << 0) & 0x0000000f)
503 overlap)(((uint32_t)(overlap) << 0) & 0x0000000f);
504 reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1,(((uint32_t)(boundaries[0]) << 4) & 0x000003f0)
505 boundaries[0])(((uint32_t)(boundaries[0]) << 4) & 0x000003f0);
506 reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2,(((uint32_t)(boundaries[1]) << 10) & 0x0000fc00)
507 boundaries[1])(((uint32_t)(boundaries[1]) << 10) & 0x0000fc00);
508 reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3,(((uint32_t)(boundaries[2]) << 16) & 0x003f0000)
509 boundaries[2])(((uint32_t)(boundaries[2]) << 16) & 0x003f0000);
510 reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4,(((uint32_t)(boundaries[3]) << 22) & 0x0fc00000)
511 boundaries[3])(((uint32_t)(boundaries[3]) << 22) & 0x0fc00000);
512 AR_WRITE(sc, AR_PHY_TPCRG5 + offset, reg)(sc)->ops.write((sc), (0xa26c + offset), (reg));
513 }
514 /* Write PDADC values. */
515 for (j = 0; j < AR_NUM_PDADC_VALUES128; j += 4) {
516 AR_WRITE(sc, AR_PHY_PDADC_TBL_BASE + offset + j,(sc)->ops.write((sc), (0xa280 + offset + j), (pdadcs[j + 0
] << 0 | pdadcs[j + 1] << 8 | pdadcs[j + 2] <<
16 | pdadcs[j + 3] << 24))
517 pdadcs[j + 0] << 0 |(sc)->ops.write((sc), (0xa280 + offset + j), (pdadcs[j + 0
] << 0 | pdadcs[j + 1] << 8 | pdadcs[j + 2] <<
16 | pdadcs[j + 3] << 24))
518 pdadcs[j + 1] << 8 |(sc)->ops.write((sc), (0xa280 + offset + j), (pdadcs[j + 0
] << 0 | pdadcs[j + 1] << 8 | pdadcs[j + 2] <<
16 | pdadcs[j + 3] << 24))
519 pdadcs[j + 2] << 16 |(sc)->ops.write((sc), (0xa280 + offset + j), (pdadcs[j + 0
] << 0 | pdadcs[j + 1] << 8 | pdadcs[j + 2] <<
16 | pdadcs[j + 3] << 24))
520 pdadcs[j + 3] << 24)(sc)->ops.write((sc), (0xa280 + offset + j), (pdadcs[j + 0
] << 0 | pdadcs[j + 1] << 8 | pdadcs[j + 2] <<
16 | pdadcs[j + 3] << 24))
;
521 }
522 }
523}
524
525void
526ar5416_set_txpower(struct athn_softc *sc, struct ieee80211_channel *c,
527 struct ieee80211_channel *extc)
528{
529 const struct ar5416_eeprom *eep = sc->eep;
530 const struct ar5416_modal_eep_header *modal;
531 uint8_t tpow_cck[4], tpow_ofdm[4];
532 uint8_t tpow_cck_ext[4], tpow_ofdm_ext[4];
533 uint8_t tpow_ht20[8], tpow_ht40[8];
534 uint8_t ht40inc;
535 int16_t pwr = 0, pwroff, max_ant_gain, power[ATHN_POWER_COUNT68];
536 uint8_t cckinc;
537 int i;
538
539 ar5416_set_power_calib(sc, c);
540
541 modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)];
542
543 /* Compute transmit power reduction due to antenna gain. */
544 max_ant_gain = MAX(modal->antennaGainCh[0], modal->antennaGainCh[1])(((modal->antennaGainCh[0])>(modal->antennaGainCh[1]
))?(modal->antennaGainCh[0]):(modal->antennaGainCh[1]))
;
545 max_ant_gain = MAX(modal->antennaGainCh[2], max_ant_gain)(((modal->antennaGainCh[2])>(max_ant_gain))?(modal->
antennaGainCh[2]):(max_ant_gain))
;
546 /* XXX */
547
548 /*
549 * Reduce scaled power by number of active chains to get per-chain
550 * transmit power level.
551 */
552 if (sc->ntxchains == 2)
553 pwr -= AR_PWR_DECREASE_FOR_2_CHAIN6;
554 else if (sc->ntxchains == 3)
555 pwr -= AR_PWR_DECREASE_FOR_3_CHAIN9;
556 if (pwr < 0)
557 pwr = 0;
Value stored to 'pwr' is never read
558
559 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)) {
560 /* Get CCK target powers. */
561 ar5008_get_lg_tpow(sc, c, AR_CTL_11B1, eep->calTargetPowerCck,
562 AR5416_NUM_2G_CCK_TARGET_POWERS3, tpow_cck);
563
564 /* Get OFDM target powers. */
565 ar5008_get_lg_tpow(sc, c, AR_CTL_11G2, eep->calTargetPower2G,
566 AR5416_NUM_2G_20_TARGET_POWERS4, tpow_ofdm);
567
568 /* Get HT-20 target powers. */
569 ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT205,
570 eep->calTargetPower2GHT20, AR5416_NUM_2G_20_TARGET_POWERS4,
571 tpow_ht20);
572
573 if (extc != NULL((void *)0)) {
574 /* Get HT-40 target powers. */
575 ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT407,
576 eep->calTargetPower2GHT40,
577 AR5416_NUM_2G_40_TARGET_POWERS4, tpow_ht40);
578
579 /* Get secondary channel CCK target powers. */
580 ar5008_get_lg_tpow(sc, extc, AR_CTL_11B1,
581 eep->calTargetPowerCck,
582 AR5416_NUM_2G_CCK_TARGET_POWERS3, tpow_cck_ext);
583
584 /* Get secondary channel OFDM target powers. */
585 ar5008_get_lg_tpow(sc, extc, AR_CTL_11G2,
586 eep->calTargetPower2G,
587 AR5416_NUM_2G_20_TARGET_POWERS4, tpow_ofdm_ext);
588 }
589 } else {
590 /* Get OFDM target powers. */
591 ar5008_get_lg_tpow(sc, c, AR_CTL_11A0, eep->calTargetPower5G,
592 AR5416_NUM_5G_20_TARGET_POWERS8, tpow_ofdm);
593
594 /* Get HT-20 target powers. */
595 ar5008_get_ht_tpow(sc, c, AR_CTL_5GHT206,
596 eep->calTargetPower5GHT20, AR5416_NUM_5G_20_TARGET_POWERS8,
597 tpow_ht20);
598
599 if (extc != NULL((void *)0)) {
600 /* Get HT-40 target powers. */
601 ar5008_get_ht_tpow(sc, c, AR_CTL_5GHT408,
602 eep->calTargetPower5GHT40,
603 AR5416_NUM_5G_40_TARGET_POWERS8, tpow_ht40);
604
605 /* Get secondary channel OFDM target powers. */
606 ar5008_get_lg_tpow(sc, extc, AR_CTL_11A0,
607 eep->calTargetPower5G,
608 AR5416_NUM_5G_20_TARGET_POWERS8, tpow_ofdm_ext);
609 }
610 }
611
612 /* Compute CCK/OFDM delta. */
613 cckinc = (sc->flags & ATHN_FLAG_OLPC(1 << 2)) ? -2 : 0;
614
615 memset(power, 0, sizeof(power))__builtin_memset((power), (0), (sizeof(power)));
616 /* Shuffle target powers across transmit rates. */
617 power[ATHN_POWER_OFDM60 ] =
618 power[ATHN_POWER_OFDM91 ] =
619 power[ATHN_POWER_OFDM122] =
620 power[ATHN_POWER_OFDM183] =
621 power[ATHN_POWER_OFDM244] = tpow_ofdm[0];
622 power[ATHN_POWER_OFDM365] = tpow_ofdm[1];
623 power[ATHN_POWER_OFDM486] = tpow_ofdm[2];
624 power[ATHN_POWER_OFDM547] = tpow_ofdm[3];
625 power[ATHN_POWER_XR15 ] = tpow_ofdm[0];
626 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)) {
627 power[ATHN_POWER_CCK1_LP8 ] = tpow_cck[0] + cckinc;
628 power[ATHN_POWER_CCK2_LP9 ] =
629 power[ATHN_POWER_CCK2_SP10 ] = tpow_cck[1] + cckinc;
630 power[ATHN_POWER_CCK55_LP11] =
631 power[ATHN_POWER_CCK55_SP12] = tpow_cck[2] + cckinc;
632 power[ATHN_POWER_CCK11_LP13] =
633 power[ATHN_POWER_CCK11_SP14] = tpow_cck[3] + cckinc;
634 }
635 for (i = 0; i < nitems(tpow_ht20)(sizeof((tpow_ht20)) / sizeof((tpow_ht20)[0])); i++)
636 power[ATHN_POWER_HT20(i)(16 + (i))] = tpow_ht20[i];
637 if (extc != NULL((void *)0)) {
638 /* Correct PAR difference between HT40 and HT20/Legacy. */
639 if (sc->eep_rev >= AR_EEP_MINOR_VER_22)
640 ht40inc = modal->ht40PowerIncForPdadc;
641 else
642 ht40inc = AR_HT40_POWER_INC_FOR_PDADC2;
643 for (i = 0; i < nitems(tpow_ht40)(sizeof((tpow_ht40)) / sizeof((tpow_ht40)[0])); i++)
644 power[ATHN_POWER_HT40(i)(40 + (i))] = tpow_ht40[i] + ht40inc;
645 power[ATHN_POWER_OFDM_DUP65] = tpow_ht40[0];
646 power[ATHN_POWER_CCK_DUP64 ] = tpow_ht40[0] + cckinc;
647 power[ATHN_POWER_OFDM_EXT67] = tpow_ofdm_ext[0];
648 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0))
649 power[ATHN_POWER_CCK_EXT66] = tpow_cck_ext[0] + cckinc;
650 }
651
652 if (AR_SREV_9280_10_OR_LATER(sc)((sc)->mac_ver >= 0x080)) {
653 if (sc->eep_rev >= AR_EEP_MINOR_VER_2121)
654 pwroff = eep->baseEepHeader.pwrTableOffset;
655 else
656 pwroff = AR_PWR_TABLE_OFFSET_DB(-5);
657 for (i = 0; i < ATHN_POWER_COUNT68; i++)
658 power[i] -= pwroff * 2; /* In half dB. */
659 }
660 for (i = 0; i < ATHN_POWER_COUNT68; i++) {
661 if (power[i] > AR_MAX_RATE_POWER63)
662 power[i] = AR_MAX_RATE_POWER63;
663 }
664
665 /* Write transmit power values to hardware. */
666 ar5008_write_txpower(sc, power);
667
668 /*
669 * Write transmit power subtraction for dynamic chain changing
670 * and per-packet transmit power.
671 */
672 AR_WRITE(sc, AR_PHY_POWER_TX_SUB,(sc)->ops.write((sc), (0xa3c8), ((modal->pwrDecreaseFor3Chain
& 0x3f) << 6 | (modal->pwrDecreaseFor2Chain &
0x3f)))
673 (modal->pwrDecreaseFor3Chain & 0x3f) << 6 |(sc)->ops.write((sc), (0xa3c8), ((modal->pwrDecreaseFor3Chain
& 0x3f) << 6 | (modal->pwrDecreaseFor2Chain &
0x3f)))
674 (modal->pwrDecreaseFor2Chain & 0x3f))(sc)->ops.write((sc), (0xa3c8), ((modal->pwrDecreaseFor3Chain
& 0x3f) << 6 | (modal->pwrDecreaseFor2Chain &
0x3f)))
;
675}
676
677void
678ar5416_spur_mitigate(struct athn_softc *sc, struct ieee80211_channel *c,
679 struct ieee80211_channel *extc)
680{
681 const struct ar_spur_chan *spurchans;
682 int i, spur, bin, spur_delta_phase, spur_freq_sd;
683
684 spurchans = sc->ops.get_spur_chans(sc, IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0));
685 for (i = 0; i < AR_EEPROM_MODAL_SPURS5; i++) {
686 spur = spurchans[i].spurChan;
687 if (spur == AR_NO_SPUR0x8000)
688 return; /* XXX disable if it was enabled! */
689 spur -= c->ic_freq * 10;
690 /* Verify range +/-9.5MHz */
691 if (abs(spur) < 95)
692 break;
693 }
694 if (i == AR_EEPROM_MODAL_SPURS5)
695 return; /* XXX disable if it was enabled! */
696 DPRINTFN(2, ("enabling spur mitigation\n"));
697
698 AR_SETBITS(sc, AR_PHY_TIMING_CTRL4_0,(sc)->ops.write((sc), (0x9920), ((sc)->ops.read((sc), (
0x9920)) | (0x80000000 | 0x40000000 | 0x20000000 | 0x10000000
)))
699 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |(sc)->ops.write((sc), (0x9920), ((sc)->ops.read((sc), (
0x9920)) | (0x80000000 | 0x40000000 | 0x20000000 | 0x10000000
)))
700 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |(sc)->ops.write((sc), (0x9920), ((sc)->ops.read((sc), (
0x9920)) | (0x80000000 | 0x40000000 | 0x20000000 | 0x10000000
)))
701 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |(sc)->ops.write((sc), (0x9920), ((sc)->ops.read((sc), (
0x9920)) | (0x80000000 | 0x40000000 | 0x20000000 | 0x10000000
)))
702 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK)(sc)->ops.write((sc), (0x9920), ((sc)->ops.read((sc), (
0x9920)) | (0x80000000 | 0x40000000 | 0x20000000 | 0x10000000
)))
;
703
704 AR_WRITE(sc, AR_PHY_SPUR_REG,(sc)->ops.write((sc), (0x994c), (0x03fc0000 | 0x00020000 |
0x0001fe00 | 0x00000100 | (((uint32_t)(40) << 0) &
0x0000007f)))
705 AR_PHY_SPUR_REG_MASK_RATE_CNTL |(sc)->ops.write((sc), (0x994c), (0x03fc0000 | 0x00020000 |
0x0001fe00 | 0x00000100 | (((uint32_t)(40) << 0) &
0x0000007f)))
706 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |(sc)->ops.write((sc), (0x994c), (0x03fc0000 | 0x00020000 |
0x0001fe00 | 0x00000100 | (((uint32_t)(40) << 0) &
0x0000007f)))
707 AR_PHY_SPUR_REG_MASK_RATE_SELECT |(sc)->ops.write((sc), (0x994c), (0x03fc0000 | 0x00020000 |
0x0001fe00 | 0x00000100 | (((uint32_t)(40) << 0) &
0x0000007f)))
708 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |(sc)->ops.write((sc), (0x994c), (0x03fc0000 | 0x00020000 |
0x0001fe00 | 0x00000100 | (((uint32_t)(40) << 0) &
0x0000007f)))
709 SM(AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, AR_SPUR_RSSI_THRESH))(sc)->ops.write((sc), (0x994c), (0x03fc0000 | 0x00020000 |
0x0001fe00 | 0x00000100 | (((uint32_t)(40) << 0) &
0x0000007f)))
;
710
711 spur_delta_phase = (spur * 524288) / 100;
712 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0))
713 spur_freq_sd = (spur * 2048) / 440;
714 else
715 spur_freq_sd = (spur * 2048) / 400;
716
717 AR_WRITE(sc, AR_PHY_TIMING11,(sc)->ops.write((sc), (0x99a0), (0x40000000 | (((uint32_t)
(spur_freq_sd) << 20) & 0x3ff00000) | (((uint32_t)(
spur_delta_phase) << 0) & 0x000fffff)))
718 AR_PHY_TIMING11_USE_SPUR_IN_AGC |(sc)->ops.write((sc), (0x99a0), (0x40000000 | (((uint32_t)
(spur_freq_sd) << 20) & 0x3ff00000) | (((uint32_t)(
spur_delta_phase) << 0) & 0x000fffff)))
719 SM(AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd) |(sc)->ops.write((sc), (0x99a0), (0x40000000 | (((uint32_t)
(spur_freq_sd) << 20) & 0x3ff00000) | (((uint32_t)(
spur_delta_phase) << 0) & 0x000fffff)))
720 SM(AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase))(sc)->ops.write((sc), (0x99a0), (0x40000000 | (((uint32_t)
(spur_freq_sd) << 20) & 0x3ff00000) | (((uint32_t)(
spur_delta_phase) << 0) & 0x000fffff)))
;
721
722 bin = spur * 32;
723 ar5008_set_viterbi_mask(sc, bin);
724}
725
726uint8_t
727ar5416_reverse_bits(uint8_t v, int nbits)
728{
729 KASSERT(nbits <= 8)((nbits <= 8) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/ar5416.c"
, 729, "nbits <= 8"))
;
730 v = ((v >> 1) & 0x55) | ((v & 0x55) << 1);
731 v = ((v >> 2) & 0x33) | ((v & 0x33) << 2);
732 v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4);
733 return (v >> (8 - nbits));
734}
735
736uint8_t
737ar5416_get_rf_rev(struct athn_softc *sc)
738{
739 uint8_t rev, reg;
740 int i;
741
742 /* Allow access to analog chips. */
743 AR_WRITE(sc, AR_PHY(0), 0x00000007)(sc)->ops.write((sc), ((0x9800 + (0) * 4)), (0x00000007));
744
745 AR_WRITE(sc, AR_PHY(0x36), 0x00007058)(sc)->ops.write((sc), ((0x9800 + (0x36) * 4)), (0x00007058
))
;
746 for (i = 0; i < 8; i++)
747 AR_WRITE(sc, AR_PHY(0x20), 0x00010000)(sc)->ops.write((sc), ((0x9800 + (0x20) * 4)), (0x00010000
))
;
748 reg = (AR_READ(sc, AR_PHY(256))(sc)->ops.read((sc), ((0x9800 + (256) * 4))) >> 24) & 0xff;
749 reg = (reg & 0xf0) >> 4 | (reg & 0x0f) << 4;
750
751 rev = ar5416_reverse_bits(reg, 8);
752 if ((rev & AR_RADIO_SREV_MAJOR0xf0) == 0)
753 rev = AR_RAD5133_SREV_MAJOR0xc0;
754 return (rev);
755}
756
757/*
758 * Replace bits "off" to "off+nbits-1" in column "col" with the specified
759 * value.
760 */
761void
762ar5416_rw_rfbits(uint32_t *buf, int col, int off, uint32_t val, int nbits)
763{
764 int idx, bit;
765
766 KASSERT(off >= 1 && col < 4 && nbits <= 32)((off >= 1 && col < 4 && nbits <= 32
) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/ic/ar5416.c"
, 766, "off >= 1 && col < 4 && nbits <= 32"
))
;
767
768 off--; /* Starts at 1. */
769 while (nbits-- > 0) {
770 idx = off / 8;
771 bit = off % 8;
772 buf[idx] &= ~(1 << (bit + col * 8));
773 buf[idx] |= ((val >> nbits) & 1) << (bit + col * 8);
774 off++;
775 }
776}
777
778/*
779 * Overwrite db and ob based on ROM settings.
780 */
781void
782ar5416_rw_bank6tpc(struct athn_softc *sc, struct ieee80211_channel *c,
783 uint32_t *rwbank6tpc)
784{
785 const struct ar5416_eeprom *eep = sc->eep;
786 const struct ar5416_modal_eep_header *modal;
787
788 if (IEEE80211_IS_CHAN_5GHZ(c)(((c)->ic_flags & 0x0100) != 0)) {
789 modal = &eep->modalHeader[0];
790 /* 5GHz db in column 0, bits [200-202]. */
791 ar5416_rw_rfbits(rwbank6tpc, 0, 200, modal->db, 3);
792 /* 5GHz ob in column 0, bits [203-205]. */
793 ar5416_rw_rfbits(rwbank6tpc, 0, 203, modal->ob, 3);
794 } else {
795 modal = &eep->modalHeader[1];
796 /* 2GHz db in column 0, bits [194-196]. */
797 ar5416_rw_rfbits(rwbank6tpc, 0, 194, modal->db, 3);
798 /* 2GHz ob in column 0, bits [197-199]. */
799 ar5416_rw_rfbits(rwbank6tpc, 0, 197, modal->ob, 3);
800 }
801}
802
803/*
804 * Program analog RF.
805 */
806void
807ar5416_rf_reset(struct athn_softc *sc, struct ieee80211_channel *c)
808{
809 const uint32_t *bank6tpc;
810 int i;
811
812 /* Bank 0. */
813 AR_WRITE(sc, 0x98b0, 0x1e5795e5)(sc)->ops.write((sc), (0x98b0), (0x1e5795e5));
814 AR_WRITE(sc, 0x98e0, 0x02008020)(sc)->ops.write((sc), (0x98e0), (0x02008020));
815
816 /* Bank 1. */
817 AR_WRITE(sc, 0x98b0, 0x02108421)(sc)->ops.write((sc), (0x98b0), (0x02108421));
818 AR_WRITE(sc, 0x98ec, 0x00000008)(sc)->ops.write((sc), (0x98ec), (0x00000008));
819
820 /* Bank 2. */
821 AR_WRITE(sc, 0x98b0, 0x0e73ff17)(sc)->ops.write((sc), (0x98b0), (0x0e73ff17));
822 AR_WRITE(sc, 0x98e0, 0x00000420)(sc)->ops.write((sc), (0x98e0), (0x00000420));
823
824 /* Bank 3. */
825 if (IEEE80211_IS_CHAN_5GHZ(c)(((c)->ic_flags & 0x0100) != 0))
826 AR_WRITE(sc, 0x98f0, 0x01400018)(sc)->ops.write((sc), (0x98f0), (0x01400018));
827 else
828 AR_WRITE(sc, 0x98f0, 0x01c00018)(sc)->ops.write((sc), (0x98f0), (0x01c00018));
829
830 /* Select the Bank 6 TPC values to use. */
831 if (AR_SREV_9160_10_OR_LATER(sc)((sc)->mac_ver >= 0x040))
832 bank6tpc = ar9160_bank6tpc_vals;
833 else
834 bank6tpc = ar5416_bank6tpc_vals;
835 if (sc->eep_rev >= AR_EEP_MINOR_VER_22) {
836 uint32_t *rwbank6tpc = sc->rwbuf;
837
838 /* Copy values from .rodata to writable buffer. */
839 memcpy(rwbank6tpc, bank6tpc, 32 * sizeof(uint32_t))__builtin_memcpy((rwbank6tpc), (bank6tpc), (32 * sizeof(uint32_t
)))
;
840 ar5416_rw_bank6tpc(sc, c, rwbank6tpc);
841 bank6tpc = rwbank6tpc;
842 }
843 /* Bank 6 TPC. */
844 for (i = 0; i < 32; i++)
845 AR_WRITE(sc, 0x989c, bank6tpc[i])(sc)->ops.write((sc), (0x989c), (bank6tpc[i]));
846 if (IEEE80211_IS_CHAN_5GHZ(c)(((c)->ic_flags & 0x0100) != 0))
847 AR_WRITE(sc, 0x98d0, 0x0000000f)(sc)->ops.write((sc), (0x98d0), (0x0000000f));
848 else
849 AR_WRITE(sc, 0x98d0, 0x0010000f)(sc)->ops.write((sc), (0x98d0), (0x0010000f));
850
851 /* Bank 7. */
852 AR_WRITE(sc, 0x989c, 0x00000500)(sc)->ops.write((sc), (0x989c), (0x00000500));
853 AR_WRITE(sc, 0x989c, 0x00000800)(sc)->ops.write((sc), (0x989c), (0x00000800));
854 AR_WRITE(sc, 0x98cc, 0x0000000e)(sc)->ops.write((sc), (0x98cc), (0x0000000e));
855}
856
857void
858ar5416_reset_bb_gain(struct athn_softc *sc, struct ieee80211_channel *c)
859{
860 const uint32_t *pvals;
861 int i;
862
863 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0))
864 pvals = ar5416_bb_rfgain_vals_2g;
865 else
866 pvals = ar5416_bb_rfgain_vals_5g;
867 for (i = 0; i < 64; i++)
868 AR_WRITE(sc, AR_PHY_BB_RFGAIN(i), pvals[i])(sc)->ops.write((sc), ((0x9a00 + (i) * 4)), (pvals[i]));
869}
870
871/*
872 * Fix orientation sensitivity issue on AR5416/2GHz by increasing
873 * rf_pwd_icsyndiv.
874 */
875void
876ar5416_force_bias(struct athn_softc *sc, struct ieee80211_channel *c)
877{
878 uint32_t *rwbank6 = sc->rwbuf;
879 uint8_t bias;
880 int i;
881
882 KASSERT(IEEE80211_IS_CHAN_2GHZ(c))(((((c)->ic_flags & 0x0080) != 0)) ? (void)0 : __assert
("diagnostic ", "/usr/src/sys/dev/ic/ar5416.c", 882, "IEEE80211_IS_CHAN_2GHZ(c)"
))
;
883
884 /* Copy values from .rodata to writable buffer. */
885 memcpy(rwbank6, ar5416_bank6_vals, sizeof(ar5416_bank6_vals))__builtin_memcpy((rwbank6), (ar5416_bank6_vals), (sizeof(ar5416_bank6_vals
)))
;
886
887 if (c->ic_freq < 2412)
888 bias = 0;
889 else if (c->ic_freq < 2422)
890 bias = 1;
891 else
892 bias = 2;
893 ar5416_reverse_bits(bias, 3);
894
895 /* Overwrite "rf_pwd_icsyndiv" (column 3, bits [181-183].) */
896 ar5416_rw_rfbits(rwbank6, 3, 181, bias, 3);
897
898 /* Write Bank 6. */
899 for (i = 0; i < 32; i++)
900 AR_WRITE(sc, 0x989c, rwbank6[i])(sc)->ops.write((sc), (0x989c), (rwbank6[i]));
901 AR_WRITE(sc, 0x98d0, 0x0010000f)(sc)->ops.write((sc), (0x98d0), (0x0010000f));
902}
903
904/*
905 * Overwrite XPA bias level based on ROM setting.
906 */
907void
908ar9160_rw_addac(struct athn_softc *sc, struct ieee80211_channel *c,
909 uint32_t *addac)
910{
911 struct ar5416_eeprom *eep = sc->eep;
912 struct ar5416_modal_eep_header *modal;
913 uint8_t fbin, bias;
914 int i;
915
916 /* XXX xpaBiasLvlFreq values have not been endian-swapped? */
917
918 /* Get the XPA bias level to use for the specified channel. */
919 modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)];
920 if (modal->xpaBiasLvl == 0xff) {
921 bias = modal->xpaBiasLvlFreq[0] >> 14;
922 fbin = athn_chan2fbin(c);
923 for (i = 1; i < 3; i++) {
924 if (modal->xpaBiasLvlFreq[i] == 0)
925 break;
926 if ((modal->xpaBiasLvlFreq[i] & 0xff) < fbin)
927 break;
928 bias = modal->xpaBiasLvlFreq[i] >> 14;
929 }
930 } else
931 bias = modal->xpaBiasLvl & 0x3;
932
933 bias = ar5416_reverse_bits(bias, 2); /* Put in host bit-order. */
934 DPRINTFN(4, ("bias level=%d\n", bias));
935 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0))
936 ar5416_rw_rfbits(addac, 0, 60, bias, 2);
937 else
938 ar5416_rw_rfbits(addac, 0, 55, bias, 2);
939}
940
941void
942ar5416_reset_addac(struct athn_softc *sc, struct ieee80211_channel *c)
943{
944 const struct athn_addac *addac = sc->addac;
945 const uint32_t *pvals;
946 int i;
947
948 if (AR_SREV_9160(sc)((sc)->mac_ver == 0x040) && sc->eep_rev >= AR_EEP_MINOR_VER_77) {
949 uint32_t *rwaddac = sc->rwbuf;
950
951 /* Copy values from .rodata to writable buffer. */
952 memcpy(rwaddac, addac->vals, addac->nvals * sizeof(uint32_t))__builtin_memcpy((rwaddac), (addac->vals), (addac->nvals
* sizeof(uint32_t)))
;
953 ar9160_rw_addac(sc, c, rwaddac);
954 pvals = rwaddac;
955 } else
956 pvals = addac->vals;
957 for (i = 0; i < addac->nvals; i++)
958 AR_WRITE(sc, 0x989c, pvals[i])(sc)->ops.write((sc), (0x989c), (pvals[i]));
959 AR_WRITE(sc, 0x98cc, 0)(sc)->ops.write((sc), (0x98cc), (0)); /* Finalize. */
960}