Bug Summary

File:dev/ic/ar9380.c
Warning:line 758, column 30
Assigned value is garbage or undefined

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 ar9380.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/ar9380.c
1/* $OpenBSD: ar9380.c,v 1.28 2022/01/09 05:42:38 jsg Exp $ */
2
3/*-
4 * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr>
5 * Copyright (c) 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 AR9380 and AR9485 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/conf.h>
36#include <sys/device.h>
37#include <sys/endian.h>
38
39#include <machine/bus.h>
40
41#if NBPFILTER1 > 0
42#include <net/bpf.h>
43#endif
44#include <net/if.h>
45#include <net/if_media.h>
46
47#include <netinet/in.h>
48#include <netinet/if_ether.h>
49
50#include <net80211/ieee80211_var.h>
51#include <net80211/ieee80211_amrr.h>
52#include <net80211/ieee80211_ra.h>
53#include <net80211/ieee80211_radiotap.h>
54
55#include <dev/ic/athnreg.h>
56#include <dev/ic/athnvar.h>
57
58#include <dev/ic/ar9003reg.h>
59#include <dev/ic/ar9380reg.h>
60
61int ar9380_attach(struct athn_softc *);
62void ar9380_setup(struct athn_softc *);
63const uint8_t *ar9380_get_rom_template(struct athn_softc *, uint8_t);
64void ar9380_swap_rom(struct athn_softc *);
65int ar9380_set_synth(struct athn_softc *, struct ieee80211_channel *,
66 struct ieee80211_channel *);
67void ar9380_get_paprd_masks(struct athn_softc *, struct ieee80211_channel *,
68 uint32_t *, uint32_t *);
69void ar9380_init_from_rom(struct athn_softc *, struct ieee80211_channel *,
70 struct ieee80211_channel *);
71void ar9380_init_swreg(struct athn_softc *);
72int ar9485_pmu_write(struct athn_softc *, uint32_t, uint32_t);
73void ar9485_init_swreg(struct athn_softc *);
74void ar9380_spur_mitigate_cck(struct athn_softc *,
75 struct ieee80211_channel *, struct ieee80211_channel *);
76void ar9380_spur_mitigate_ofdm(struct athn_softc *,
77 struct ieee80211_channel *, struct ieee80211_channel *);
78void ar9380_spur_mitigate(struct athn_softc *, struct ieee80211_channel *,
79 struct ieee80211_channel *);
80void ar9380_set_txpower(struct athn_softc *, struct ieee80211_channel *,
81 struct ieee80211_channel *);
82void ar9380_get_correction(struct athn_softc *, struct ieee80211_channel *,
83 int, int *, int *);
84void ar9380_set_correction(struct athn_softc *, struct ieee80211_channel *);
85
86/* Extern functions. */
87int athn_interpolate(int, int, int, int, int);
88uint8_t athn_chan2fbin(struct ieee80211_channel *);
89void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *);
90int ar9003_attach(struct athn_softc *);
91void ar9003_write_txpower(struct athn_softc *, int16_t power[]);
92void ar9003_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *,
93 uint8_t, const uint8_t *, const struct ar_cal_target_power_leg *,
94 int, uint8_t[]);
95void ar9003_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *,
96 uint8_t, const uint8_t *, const struct ar_cal_target_power_ht *,
97 int, uint8_t[]);
98
99
100int
101ar9380_attach(struct athn_softc *sc)
102{
103 sc->ngpiopins = 17;
104 sc->ops.setup = ar9380_setup;
105 sc->ops.get_rom_template = ar9380_get_rom_template;
106 sc->ops.swap_rom = ar9380_swap_rom;
107 sc->ops.init_from_rom = ar9380_init_from_rom;
108 sc->ops.set_txpower = ar9380_set_txpower;
109 sc->ops.set_synth = ar9380_set_synth;
110 sc->ops.spur_mitigate = ar9380_spur_mitigate;
111 sc->ops.get_paprd_masks = ar9380_get_paprd_masks;
112 sc->cca_min_2g = AR9380_PHY_CCA_MIN_GOOD_VAL_2GHZ(-125);
113 sc->cca_max_2g = AR9380_PHY_CCA_MAX_GOOD_VAL_2GHZ( -95);
114 sc->cca_min_5g = AR9380_PHY_CCA_MIN_GOOD_VAL_5GHZ(-125);
115 sc->cca_max_5g = AR9380_PHY_CCA_MAX_GOOD_VAL_5GHZ(-100);
116 if (AR_SREV_9485(sc)((sc)->mac_ver == 0x240)) {
117 sc->ini = &ar9485_1_1_ini;
118 sc->serdes = &ar9485_1_1_serdes;
119 } else {
120 sc->ini = &ar9380_2_2_ini;
121 sc->serdes = &ar9380_2_2_serdes;
122 }
123
124 return (ar9003_attach(sc));
125}
126
127void
128ar9380_setup(struct athn_softc *sc)
129{
130 struct ieee80211com *ic = &sc->sc_ic;
131 struct ar9380_eeprom *eep = sc->eep;
132 struct ar9380_base_eep_hdr *base = &eep->baseEepHeader;
133 uint8_t type;
134
135 if (base->opFlags & AR_OPFLAGS_11A0x01)
136 sc->flags |= ATHN_FLAG_11A(1 << 9);
137 if (base->opFlags & AR_OPFLAGS_11G0x02)
138 sc->flags |= ATHN_FLAG_11G(1 << 10);
139 if (base->opFlags & AR_OPFLAGS_11N0x3c)
140 sc->flags |= ATHN_FLAG_11N(1 << 11);
141
142 IEEE80211_ADDR_COPY(ic->ic_myaddr, eep->macAddr)__builtin_memcpy((ic->ic_myaddr), (eep->macAddr), (6));
143 sc->led_pin = base->wlanLedGpio;
144
145 /* Check if we have a hardware radio switch. */
146 if (base->rfSilent & AR_EEP_RFSILENT_ENABLED0x0001) {
147 sc->flags |= ATHN_FLAG_RFSILENT(1 << 5);
148 /* Get GPIO pin used by hardware radio switch. */
149 sc->rfsilent_pin = MS(base->rfSilent,(((uint32_t)(base->rfSilent) & 0x001c) >> 2)
150 AR_EEP_RFSILENT_GPIO_SEL)(((uint32_t)(base->rfSilent) & 0x001c) >> 2);
151 /* Get polarity of hardware radio switch. */
152 if (base->rfSilent & AR_EEP_RFSILENT_POLARITY0x0002)
153 sc->flags |= ATHN_FLAG_RFSILENT_REVERSED(1 << 6);
154 }
155
156 /* Set the number of HW key cache entries. */
157 sc->kc_entries = AR_KEYTABLE_SIZE128;
158
159 sc->txchainmask = MS(base->txrxMask, AR_EEP_TX_MASK)(((uint32_t)(base->txrxMask) & 0xf0) >> 4);
160 sc->rxchainmask = MS(base->txrxMask, AR_EEP_RX_MASK)(((uint32_t)(base->txrxMask) & 0x0f) >> 0);
161
162 /* Fast PLL clock is always supported. */
163 sc->flags |= ATHN_FLAG_FAST_PLL_CLOCK(1 << 4);
164
165 /* Enable PA predistortion if supported. */
166 if (base->featureEnable & AR_EEP_PAPRD0x20)
167 sc->flags |= ATHN_FLAG_PAPRD(1 << 3);
168 /*
169 * Some 3-stream chips may exceed the PCIe power requirements,
170 * requiring to reduce the number of Tx chains in some cases.
171 */
172 if ((base->miscConfiguration & AR_EEP_CHAIN_MASK_REDUCE0x08) &&
173 sc->txchainmask == 0x7)
174 sc->flags |= ATHN_FLAG_3TREDUCE_CHAIN(1 << 14);
175
176 /* Select initialization values based on ROM. */
177 type = MS(eep->baseEepHeader.txrxgain, AR_EEP_RX_GAIN)(((uint32_t)(eep->baseEepHeader.txrxgain) & 0x0f) >>
0)
;
178 if (!AR_SREV_9485(sc)((sc)->mac_ver == 0x240)) {
179 if (type == AR_EEP_RX_GAIN_WO_XLNA1)
180 sc->rx_gain = &ar9380_2_2_rx_gain_wo_xlna;
181 else
182 sc->rx_gain = &ar9380_2_2_rx_gain;
183 } else
184 sc->rx_gain = &ar9485_1_1_rx_gain;
185
186 /* Select initialization values based on ROM. */
187 type = MS(eep->baseEepHeader.txrxgain, AR_EEP_TX_GAIN)(((uint32_t)(eep->baseEepHeader.txrxgain) & 0xf0) >>
4)
;
188 if (!AR_SREV_9485(sc)((sc)->mac_ver == 0x240)) {
189 if (type == AR_EEP_TX_GAIN_HIGH_OB_DB1)
190 sc->tx_gain = &ar9380_2_2_tx_gain_high_ob_db;
191 else if (type == AR_EEP_TX_GAIN_LOW_OB_DB2)
192 sc->tx_gain = &ar9380_2_2_tx_gain_low_ob_db;
193 else if (type == AR_EEP_TX_GAIN_HIGH_POWER3)
194 sc->tx_gain = &ar9380_2_2_tx_gain_high_power;
195 else
196 sc->tx_gain = &ar9380_2_2_tx_gain;
197 } else
198 sc->tx_gain = &ar9485_1_1_tx_gain;
199}
200
201const uint8_t *
202ar9380_get_rom_template(struct athn_softc *sc, uint8_t ref)
203{
204 int i;
205
206 /* Retrieve template ROM image for given reference. */
207 for (i = 0; i < nitems(ar9380_rom_templates)(sizeof((ar9380_rom_templates)) / sizeof((ar9380_rom_templates
)[0]))
; i++)
208 if (ar9380_rom_templates[i][1] == ref)
209 return (ar9380_rom_templates[i]);
210 return (NULL((void *)0));
211}
212
213void
214ar9380_swap_rom(struct athn_softc *sc)
215{
216#if BYTE_ORDER1234 == BIG_ENDIAN4321
217 struct ar9380_eeprom *eep = sc->eep;
218 struct ar9380_base_eep_hdr *base = &eep->baseEepHeader;
219 struct ar9380_modal_eep_header *modal;
220 int i;
221
222 base->regDmn[0] = swap16(base->regDmn[0])(__uint16_t)(__builtin_constant_p(base->regDmn[0]) ? (__uint16_t
)(((__uint16_t)(base->regDmn[0]) & 0xffU) << 8 |
((__uint16_t)(base->regDmn[0]) & 0xff00U) >> 8)
: __swap16md(base->regDmn[0]))
;
223 base->regDmn[1] = swap16(base->regDmn[1])(__uint16_t)(__builtin_constant_p(base->regDmn[1]) ? (__uint16_t
)(((__uint16_t)(base->regDmn[1]) & 0xffU) << 8 |
((__uint16_t)(base->regDmn[1]) & 0xff00U) >> 8)
: __swap16md(base->regDmn[1]))
;
224 base->swreg = swap32(base->swreg)(__uint32_t)(__builtin_constant_p(base->swreg) ? (__uint32_t
)(((__uint32_t)(base->swreg) & 0xff) << 24 | ((__uint32_t
)(base->swreg) & 0xff00) << 8 | ((__uint32_t)(base
->swreg) & 0xff0000) >> 8 | ((__uint32_t)(base->
swreg) & 0xff000000) >> 24) : __swap32md(base->swreg
))
;
225
226 modal = &eep->modalHeader2G;
227 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))
;
228 modal->antCtrlCommon2 = swap32(modal->antCtrlCommon2)(__uint32_t)(__builtin_constant_p(modal->antCtrlCommon2) ?
(__uint32_t)(((__uint32_t)(modal->antCtrlCommon2) & 0xff
) << 24 | ((__uint32_t)(modal->antCtrlCommon2) &
0xff00) << 8 | ((__uint32_t)(modal->antCtrlCommon2)
& 0xff0000) >> 8 | ((__uint32_t)(modal->antCtrlCommon2
) & 0xff000000) >> 24) : __swap32md(modal->antCtrlCommon2
))
;
229 modal->papdRateMaskHt20 = swap32(modal->papdRateMaskHt20)(__uint32_t)(__builtin_constant_p(modal->papdRateMaskHt20)
? (__uint32_t)(((__uint32_t)(modal->papdRateMaskHt20) &
0xff) << 24 | ((__uint32_t)(modal->papdRateMaskHt20
) & 0xff00) << 8 | ((__uint32_t)(modal->papdRateMaskHt20
) & 0xff0000) >> 8 | ((__uint32_t)(modal->papdRateMaskHt20
) & 0xff000000) >> 24) : __swap32md(modal->papdRateMaskHt20
))
;
230 modal->papdRateMaskHt40 = swap32(modal->papdRateMaskHt40)(__uint32_t)(__builtin_constant_p(modal->papdRateMaskHt40)
? (__uint32_t)(((__uint32_t)(modal->papdRateMaskHt40) &
0xff) << 24 | ((__uint32_t)(modal->papdRateMaskHt40
) & 0xff00) << 8 | ((__uint32_t)(modal->papdRateMaskHt40
) & 0xff0000) >> 8 | ((__uint32_t)(modal->papdRateMaskHt40
) & 0xff000000) >> 24) : __swap32md(modal->papdRateMaskHt40
))
;
231 for (i = 0; i < AR9380_MAX_CHAINS3; i++)
232 modal->antCtrlChain[i] = swap16(modal->antCtrlChain[i])(__uint16_t)(__builtin_constant_p(modal->antCtrlChain[i]) ?
(__uint16_t)(((__uint16_t)(modal->antCtrlChain[i]) & 0xffU
) << 8 | ((__uint16_t)(modal->antCtrlChain[i]) &
0xff00U) >> 8) : __swap16md(modal->antCtrlChain[i])
)
;
233
234 modal = &eep->modalHeader5G;
235 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))
;
236 modal->antCtrlCommon2 = swap32(modal->antCtrlCommon2)(__uint32_t)(__builtin_constant_p(modal->antCtrlCommon2) ?
(__uint32_t)(((__uint32_t)(modal->antCtrlCommon2) & 0xff
) << 24 | ((__uint32_t)(modal->antCtrlCommon2) &
0xff00) << 8 | ((__uint32_t)(modal->antCtrlCommon2)
& 0xff0000) >> 8 | ((__uint32_t)(modal->antCtrlCommon2
) & 0xff000000) >> 24) : __swap32md(modal->antCtrlCommon2
))
;
237 modal->papdRateMaskHt20 = swap32(modal->papdRateMaskHt20)(__uint32_t)(__builtin_constant_p(modal->papdRateMaskHt20)
? (__uint32_t)(((__uint32_t)(modal->papdRateMaskHt20) &
0xff) << 24 | ((__uint32_t)(modal->papdRateMaskHt20
) & 0xff00) << 8 | ((__uint32_t)(modal->papdRateMaskHt20
) & 0xff0000) >> 8 | ((__uint32_t)(modal->papdRateMaskHt20
) & 0xff000000) >> 24) : __swap32md(modal->papdRateMaskHt20
))
;
238 modal->papdRateMaskHt40 = swap32(modal->papdRateMaskHt40)(__uint32_t)(__builtin_constant_p(modal->papdRateMaskHt40)
? (__uint32_t)(((__uint32_t)(modal->papdRateMaskHt40) &
0xff) << 24 | ((__uint32_t)(modal->papdRateMaskHt40
) & 0xff00) << 8 | ((__uint32_t)(modal->papdRateMaskHt40
) & 0xff0000) >> 8 | ((__uint32_t)(modal->papdRateMaskHt40
) & 0xff000000) >> 24) : __swap32md(modal->papdRateMaskHt40
))
;
239 for (i = 0; i < AR9380_MAX_CHAINS3; i++)
240 modal->antCtrlChain[i] = swap16(modal->antCtrlChain[i])(__uint16_t)(__builtin_constant_p(modal->antCtrlChain[i]) ?
(__uint16_t)(((__uint16_t)(modal->antCtrlChain[i]) & 0xffU
) << 8 | ((__uint16_t)(modal->antCtrlChain[i]) &
0xff00U) >> 8) : __swap16md(modal->antCtrlChain[i])
)
;
241#endif
242}
243
244void
245ar9380_get_paprd_masks(struct athn_softc *sc, struct ieee80211_channel *c,
246 uint32_t *ht20mask, uint32_t *ht40mask)
247{
248 const struct ar9380_eeprom *eep = sc->eep;
249 const struct ar9380_modal_eep_header *modal;
250
251 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0))
252 modal = &eep->modalHeader2G;
253 else
254 modal = &eep->modalHeader5G;
255 *ht20mask = modal->papdRateMaskHt20;
256 *ht40mask = modal->papdRateMaskHt40;
257}
258
259int
260ar9380_set_synth(struct athn_softc *sc, struct ieee80211_channel *c,
261 struct ieee80211_channel *extc)
262{
263 uint32_t freq = c->ic_freq;
264 uint32_t chansel, phy;
265
266 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)) {
267 if (AR_SREV_9485(sc)((sc)->mac_ver == 0x240))
268 chansel = ((freq << 16) - 215) / 15;
269 else
270 chansel = (freq << 16) / 15;
271 AR_WRITE(sc, AR_PHY_SYNTH_CONTROL, AR9380_BMODE)(sc)->ops.write((sc), (0x0a340), (0x20000000));
272 } else {
273 chansel = (freq << 15) / 15;
274 chansel >>= 1;
275 AR_WRITE(sc, AR_PHY_SYNTH_CONTROL, 0)(sc)->ops.write((sc), (0x0a340), (0));
276 }
277
278 /* Enable Long Shift Select for synthesizer. */
279 AR_SETBITS(sc, AR_PHY_65NM_CH0_SYNTH4,(sc)->ops.write((sc), (0x1608c), ((sc)->ops.read((sc), (
0x1608c)) | (0x00000002)))
280 AR_PHY_SYNTH4_LONG_SHIFT_SELECT)(sc)->ops.write((sc), (0x1608c), ((sc)->ops.read((sc), (
0x1608c)) | (0x00000002)))
;
281 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
282
283 /* Program synthesizer. */
284 phy = (chansel << 2) | AR9380_FRACMODE0x40000000;
285 DPRINTFN(4, ("AR_PHY_65NM_CH0_SYNTH7=0x%08x\n", phy));
286 AR_WRITE(sc, AR_PHY_65NM_CH0_SYNTH7, phy)(sc)->ops.write((sc), (0x16098), (phy));
287 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
288 /* Toggle Load Synth Channel bit. */
289 AR_WRITE(sc, AR_PHY_65NM_CH0_SYNTH7, phy | AR9380_LOAD_SYNTH)(sc)->ops.write((sc), (0x16098), (phy | 0x80000000));
290 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
291 return (0);
292}
293
294void
295ar9380_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
296 struct ieee80211_channel *extc)
297{
298 const struct ar9380_eeprom *eep = sc->eep;
299 const struct ar9380_modal_eep_header *modal;
300 uint8_t db, margin, ant_div_ctrl;
301 uint32_t reg;
302 int i, maxchains;
303
304 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0))
305 modal = &eep->modalHeader2G;
306 else
307 modal = &eep->modalHeader5G;
308
309 /* Apply XPA bias level. */
310 if (AR_SREV_9485(sc)((sc)->mac_ver == 0x240)) {
311 reg = AR_READ(sc, AR9485_PHY_65NM_CH0_TOP2)(sc)->ops.read((sc), (0x16284));
312 reg = RW(reg, AR9485_PHY_65NM_CH0_TOP2_XPABIASLVL,(((reg) & ~0x0000f000) | (((uint32_t)(modal->xpaBiasLvl
) << 12) & 0x0000f000))
313 modal->xpaBiasLvl)(((reg) & ~0x0000f000) | (((uint32_t)(modal->xpaBiasLvl
) << 12) & 0x0000f000))
;
314 AR_WRITE(sc, AR9485_PHY_65NM_CH0_TOP2, reg)(sc)->ops.write((sc), (0x16284), (reg));
315 } else {
316 reg = AR_READ(sc, AR_PHY_65NM_CH0_TOP)(sc)->ops.read((sc), (0x16288));
317 reg = RW(reg, AR_PHY_65NM_CH0_TOP_XPABIASLVL,(((reg) & ~0x00000300) | (((uint32_t)(modal->xpaBiasLvl
& 0x3) << 8) & 0x00000300))
318 modal->xpaBiasLvl & 0x3)(((reg) & ~0x00000300) | (((uint32_t)(modal->xpaBiasLvl
& 0x3) << 8) & 0x00000300))
;
319 AR_WRITE(sc, AR_PHY_65NM_CH0_TOP, reg)(sc)->ops.write((sc), (0x16288), (reg));
320 reg = AR_READ(sc, AR_PHY_65NM_CH0_THERM)(sc)->ops.read((sc), (0x16290));
321 reg = RW(reg, AR_PHY_65NM_CH0_THERM_XPABIASLVL_MSB,(((reg) & ~0x00000003) | (((uint32_t)(modal->xpaBiasLvl
>> 2) << 0) & 0x00000003))
322 modal->xpaBiasLvl >> 2)(((reg) & ~0x00000003) | (((uint32_t)(modal->xpaBiasLvl
>> 2) << 0) & 0x00000003))
;
323 reg |= AR_PHY_65NM_CH0_THERM_XPASHORT2GND0x00000004;
324 AR_WRITE(sc, AR_PHY_65NM_CH0_THERM, reg)(sc)->ops.write((sc), (0x16290), (reg));
325 }
326
327 /* Apply antenna control. */
328 reg = AR_READ(sc, AR_PHY_SWITCH_COM)(sc)->ops.read((sc), (0x0a288));
329 reg = RW(reg, AR_SWITCH_TABLE_COM_ALL, modal->antCtrlCommon)(((reg) & ~0x0000ffff) | (((uint32_t)(modal->antCtrlCommon
) << 0) & 0x0000ffff))
;
330 AR_WRITE(sc, AR_PHY_SWITCH_COM, reg)(sc)->ops.write((sc), (0x0a288), (reg));
331 reg = AR_READ(sc, AR_PHY_SWITCH_COM_2)(sc)->ops.read((sc), (0x0a28c));
332 reg = RW(reg, AR_SWITCH_TABLE_COM_2_ALL, modal->antCtrlCommon2)(((reg) & ~0x00ffffff) | (((uint32_t)(modal->antCtrlCommon2
) << 0) & 0x00ffffff))
;
333 AR_WRITE(sc, AR_PHY_SWITCH_COM_2, reg)(sc)->ops.write((sc), (0x0a28c), (reg));
334
335 maxchains = AR_SREV_9485(sc)((sc)->mac_ver == 0x240) ? 1 : AR9380_MAX_CHAINS3;
336 for (i = 0; i < maxchains; i++) {
337 reg = AR_READ(sc, AR_PHY_SWITCH_CHAIN(i))(sc)->ops.read((sc), ((0x0a284 + (i) * 0x1000)));
338 reg = RW(reg, AR_SWITCH_TABLE_ALL, modal->antCtrlChain[i])(((reg) & ~0x00000fff) | (((uint32_t)(modal->antCtrlChain
[i]) << 0) & 0x00000fff))
;
339 AR_WRITE(sc, AR_PHY_SWITCH_CHAIN(i), reg)(sc)->ops.write((sc), ((0x0a284 + (i) * 0x1000)), (reg));
340 }
341
342 if (AR_SREV_9485(sc)((sc)->mac_ver == 0x240)) {
343 ant_div_ctrl = eep->base_ext1.ant_div_control;
344 reg = AR_READ(sc, AR_PHY_MC_GAIN_CTRL)(sc)->ops.read((sc), (0x09e28));
345 reg = RW(reg, AR_PHY_MC_GAIN_CTRL_ANT_DIV_CTRL_ALL,(((reg) & ~0x7e000000) | (((uint32_t)((((uint32_t)(ant_div_ctrl
) & 0x3f) >> 0)) << 25) & 0x7e000000))
346 MS(ant_div_ctrl, AR_EEP_ANT_DIV_CTRL_ALL))(((reg) & ~0x7e000000) | (((uint32_t)((((uint32_t)(ant_div_ctrl
) & 0x3f) >> 0)) << 25) & 0x7e000000))
;
347 if (ant_div_ctrl & AR_EEP_ANT_DIV_CTRL_ANT_DIV0x40)
348 reg |= AR_PHY_MC_GAIN_CTRL_ENABLE_ANT_DIV0x01000000;
349 else
350 reg &= ~AR_PHY_MC_GAIN_CTRL_ENABLE_ANT_DIV0x01000000;
351 AR_WRITE(sc, AR_PHY_MC_GAIN_CTRL, reg)(sc)->ops.write((sc), (0x09e28), (reg));
352 reg = AR_READ(sc, AR_PHY_CCK_DETECT)(sc)->ops.read((sc), (0x09fc0));
353 if (ant_div_ctrl & AR_EEP_ANT_DIV_CTRL_FAST_DIV0x80)
354 reg |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV0x00002000;
355 else
356 reg &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV0x00002000;
357 AR_WRITE(sc, AR_PHY_CCK_DETECT, reg)(sc)->ops.write((sc), (0x09fc0), (reg));
358 }
359
360 if (eep->baseEepHeader.miscConfiguration & AR_EEP_DRIVE_STRENGTH0x01) {
361 /* Apply drive strength. */
362 reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS1)(sc)->ops.read((sc), (0x160c0));
363 reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_0, 5)(((reg) & ~0x000001c0) | (((uint32_t)(5) << 6) &
0x000001c0))
;
364 reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_1, 5)(((reg) & ~0x00000e00) | (((uint32_t)(5) << 9) &
0x00000e00))
;
365 reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_2, 5)(((reg) & ~0x00007000) | (((uint32_t)(5) << 12) &
0x00007000))
;
366 reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_3, 5)(((reg) & ~0x00038000) | (((uint32_t)(5) << 15) &
0x00038000))
;
367 reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_4, 5)(((reg) & ~0x001c0000) | (((uint32_t)(5) << 18) &
0x001c0000))
;
368 reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_5, 5)(((reg) & ~0x00e00000) | (((uint32_t)(5) << 21) &
0x00e00000))
;
369 AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS1, reg)(sc)->ops.write((sc), (0x160c0), (reg));
370
371 reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS2)(sc)->ops.read((sc), (0x160c4));
372 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_0, 5)(((reg) & ~0x000000e0) | (((uint32_t)(5) << 5) &
0x000000e0))
;
373 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_1, 5)(((reg) & ~0x00000700) | (((uint32_t)(5) << 8) &
0x00000700))
;
374 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_2, 5)(((reg) & ~0x00003800) | (((uint32_t)(5) << 11) &
0x00003800))
;
375 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_3, 5)(((reg) & ~0x0001c000) | (((uint32_t)(5) << 14) &
0x0001c000))
;
376 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_4, 5)(((reg) & ~0x000e0000) | (((uint32_t)(5) << 17) &
0x000e0000))
;
377 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_5, 5)(((reg) & ~0x00700000) | (((uint32_t)(5) << 20) &
0x00700000))
;
378 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_6, 5)(((reg) & ~0x03800000) | (((uint32_t)(5) << 23) &
0x03800000))
;
379 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_7, 5)(((reg) & ~0x1c000000) | (((uint32_t)(5) << 26) &
0x1c000000))
;
380 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_8, 5)(((reg) & ~0xe0000000) | (((uint32_t)(5) << 29) &
0xe0000000))
;
381 AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS2, reg)(sc)->ops.write((sc), (0x160c4), (reg));
382
383 reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS4)(sc)->ops.read((sc), (0x160cc));
384 reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_0, 5)(((reg) & ~0x03800000) | (((uint32_t)(5) << 23) &
0x03800000))
;
385 reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_1, 5)(((reg) & ~0x1c000000) | (((uint32_t)(5) << 26) &
0x1c000000))
;
386 reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_2, 5)(((reg) & ~0xe0000000) | (((uint32_t)(5) << 29) &
0xe0000000))
;
387 AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS4, reg)(sc)->ops.write((sc), (0x160cc), (reg));
388 }
389
390 /* Apply attenuation settings. */
391 maxchains = AR_SREV_9485(sc)((sc)->mac_ver == 0x240) ? 1 : AR9380_MAX_CHAINS3;
392 for (i = 0; i < maxchains; i++) {
393 if (IEEE80211_IS_CHAN_5GHZ(c)(((c)->ic_flags & 0x0100) != 0) &&
394 eep->base_ext2.xatten1DBLow[i] != 0) {
395 if (c->ic_freq <= 5500) {
396 db = athn_interpolate(c->ic_freq,
397 5180, eep->base_ext2.xatten1DBLow[i],
398 5500, modal->xatten1DB[i]);
399 } else {
400 db = athn_interpolate(c->ic_freq,
401 5500, modal->xatten1DB[i],
402 5785, eep->base_ext2.xatten1DBHigh[i]);
403 }
404 } else
405 db = modal->xatten1DB[i];
406 if (IEEE80211_IS_CHAN_5GHZ(c)(((c)->ic_flags & 0x0100) != 0) &&
407 eep->base_ext2.xatten1MarginLow[i] != 0) {
408 if (c->ic_freq <= 5500) {
409 margin = athn_interpolate(c->ic_freq,
410 5180, eep->base_ext2.xatten1MarginLow[i],
411 5500, modal->xatten1Margin[i]);
412 } else {
413 margin = athn_interpolate(c->ic_freq,
414 5500, modal->xatten1Margin[i],
415 5785, eep->base_ext2.xatten1MarginHigh[i]);
416 }
417 } else
418 margin = modal->xatten1Margin[i];
419 reg = AR_READ(sc, AR_PHY_EXT_ATTEN_CTL(i))(sc)->ops.read((sc), ((0x09e18 + (i) * 0x1000)));
420 reg = RW(reg, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, db)(((reg) & ~0x0000003f) | (((uint32_t)(db) << 0) &
0x0000003f))
;
421 reg = RW(reg, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, margin)(((reg) & ~0x0001f000) | (((uint32_t)(margin) << 12
) & 0x0001f000))
;
422 AR_WRITE(sc, AR_PHY_EXT_ATTEN_CTL(i), reg)(sc)->ops.write((sc), ((0x09e18 + (i) * 0x1000)), (reg));
423 }
424
425 /* Initialize switching regulator. */
426 if (AR_SREV_9485(sc)((sc)->mac_ver == 0x240))
427 ar9485_init_swreg(sc);
428 else
429 ar9380_init_swreg(sc);
430
431 /* Apply tuning capabilities. */
432 if (AR_SREV_9485(sc)((sc)->mac_ver == 0x240) &&
433 (eep->baseEepHeader.featureEnable & AR_EEP_TUNING_CAPS0x40)) {
434 reg = AR_READ(sc, AR9485_PHY_CH0_XTAL)(sc)->ops.read((sc), (0x16290));
435 reg = RW(reg, AR9485_PHY_CH0_XTAL_CAPINDAC,(((reg) & ~0x7f000000) | (((uint32_t)(eep->baseEepHeader
.params_for_tuning_caps[0]) << 24) & 0x7f000000))
436 eep->baseEepHeader.params_for_tuning_caps[0])(((reg) & ~0x7f000000) | (((uint32_t)(eep->baseEepHeader
.params_for_tuning_caps[0]) << 24) & 0x7f000000))
;
437 reg = RW(reg, AR9485_PHY_CH0_XTAL_CAPOUTDAC,(((reg) & ~0x00fe0000) | (((uint32_t)(eep->baseEepHeader
.params_for_tuning_caps[0]) << 17) & 0x00fe0000))
438 eep->baseEepHeader.params_for_tuning_caps[0])(((reg) & ~0x00fe0000) | (((uint32_t)(eep->baseEepHeader
.params_for_tuning_caps[0]) << 17) & 0x00fe0000))
;
439 AR_WRITE(sc, AR9485_PHY_CH0_XTAL, reg)(sc)->ops.write((sc), (0x16290), (reg));
440 }
441 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
442}
443
444void
445ar9380_init_swreg(struct athn_softc *sc)
446{
447 const struct ar9380_eeprom *eep = sc->eep;
448
449 if (eep->baseEepHeader.featureEnable & AR_EEP_INTERNAL_REGULATOR0x10) {
450 /* Internal regulator is ON. */
451 AR_CLRBITS(sc, AR_RTC_REG_CONTROL1,(sc)->ops.write((sc), (0x700c), ((sc)->ops.read((sc), (
0x700c)) & ~(0x00000001)))
452 AR_RTC_REG_CONTROL1_SWREG_PROGRAM)(sc)->ops.write((sc), (0x700c), ((sc)->ops.read((sc), (
0x700c)) & ~(0x00000001)))
;
453 AR_WRITE(sc, AR_RTC_REG_CONTROL0, eep->baseEepHeader.swreg)(sc)->ops.write((sc), (0x7008), (eep->baseEepHeader.swreg
))
;
454 AR_SETBITS(sc, AR_RTC_REG_CONTROL1,(sc)->ops.write((sc), (0x700c), ((sc)->ops.read((sc), (
0x700c)) | (0x00000001)))
455 AR_RTC_REG_CONTROL1_SWREG_PROGRAM)(sc)->ops.write((sc), (0x700c), ((sc)->ops.read((sc), (
0x700c)) | (0x00000001)))
;
456 } else
457 AR_SETBITS(sc, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_SWREG_PRD)(sc)->ops.write((sc), (0x7048), ((sc)->ops.read((sc), (
0x7048)) | (0x00000004)))
;
458 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
459}
460
461int
462ar9485_pmu_write(struct athn_softc *sc, uint32_t addr, uint32_t val)
463{
464 int ntries;
465
466 AR_WRITE(sc, addr, val)(sc)->ops.write((sc), (addr), (val));
467 /* Wait for write to complete. */
468 for (ntries = 0; ntries < 100; ntries++) {
469 if (AR_READ(sc, addr)(sc)->ops.read((sc), (addr)) == val)
470 return (0);
471 AR_WRITE(sc, addr, val)(sc)->ops.write((sc), (addr), (val)); /* Insist. */
472 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
473 DELAY(10)(*delay_func)(10);
474 }
475 return (ETIMEDOUT60);
476}
477
478#define ar9486_pmu_readAR_READ AR_READ
479
480void
481ar9485_init_swreg(struct athn_softc *sc)
482{
483 const struct ar9380_eeprom *eep = sc->eep;
484 uint32_t reg;
485
486 ar9485_pmu_write(sc, AR_PHY_PMU20x16c44,
487 ar9486_pmu_read(sc, AR_PHY_PMU2)(sc)->ops.read((sc), (0x16c44)) & ~AR_PHY_PMU2_PGM0x00200000);
488
489 if (eep->baseEepHeader.featureEnable & AR_EEP_INTERNAL_REGULATOR0x10) {
490 ar9485_pmu_write(sc, AR_PHY_PMU10x16c40, 0x131dc17a);
491
492 reg = ar9486_pmu_read(sc, AR_PHY_PMU2)(sc)->ops.read((sc), (0x16c44));
493 reg = (reg & ~0xffc00000) | 0x10000000;
494 ar9485_pmu_write(sc, AR_PHY_PMU20x16c44, reg);
495 } else {
496 ar9485_pmu_write(sc, AR_PHY_PMU10x16c40,
497 ar9486_pmu_read(sc, AR_PHY_PMU1)(sc)->ops.read((sc), (0x16c40)) | AR_PHY_PMU1_PWD0x00000001);
498 }
499
500 ar9485_pmu_write(sc, AR_PHY_PMU20x16c44,
501 ar9486_pmu_read(sc, AR_PHY_PMU2)(sc)->ops.read((sc), (0x16c44)) | AR_PHY_PMU2_PGM0x00200000);
502}
503
504void
505ar9380_spur_mitigate_cck(struct athn_softc *sc, struct ieee80211_channel *c,
506 struct ieee80211_channel *extc)
507{
508 /* NB: It is safe to call this function for 5GHz channels. */
509 static const int16_t freqs[] = { 2420, 2440, 2464, 2480 };
510 int i, spur, freq;
511 uint32_t reg;
512
513 for (i = 0; i < nitems(freqs)(sizeof((freqs)) / sizeof((freqs)[0])); i++) {
514 spur = freqs[i] - c->ic_freq;
515 if (abs(spur) < 10) /* +/- 10MHz range. */
516 break;
517 }
518 if (i == nitems(freqs)(sizeof((freqs)) / sizeof((freqs)[0]))) {
519 /* Disable CCK spur mitigation. */
520 reg = AR_READ(sc, AR_PHY_AGC_CONTROL)(sc)->ops.read((sc), (0x0a2c4));
521 reg = RW(reg, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5)(((reg) & ~0x000003c0) | (((uint32_t)(0x5) << 6) &
0x000003c0))
;
522 AR_WRITE(sc, AR_PHY_AGC_CONTROL, reg)(sc)->ops.write((sc), (0x0a2c4), (reg));
523 reg = AR_READ(sc, AR_PHY_CCK_SPUR_MIT)(sc)->ops.read((sc), (0x09fcc));
524 reg = RW(reg, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0)(((reg) & ~0x1ffffe00) | (((uint32_t)(0) << 9) &
0x1ffffe00))
;
525 reg &= ~AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT0x00000001;
526 AR_WRITE(sc, AR_PHY_CCK_SPUR_MIT, reg)(sc)->ops.write((sc), (0x09fcc), (reg));
527 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
528 return;
529 }
530 freq = (spur * 524288) / 11;
531
532 reg = AR_READ(sc, AR_PHY_AGC_CONTROL)(sc)->ops.read((sc), (0x0a2c4));
533 reg = RW(reg, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7)(((reg) & ~0x000003c0) | (((uint32_t)(0x7) << 6) &
0x000003c0))
;
534 AR_WRITE(sc, AR_PHY_AGC_CONTROL, reg)(sc)->ops.write((sc), (0x0a2c4), (reg));
535
536 reg = AR_READ(sc, AR_PHY_CCK_SPUR_MIT)(sc)->ops.read((sc), (0x09fcc));
537 reg = RW(reg, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, freq)(((reg) & ~0x1ffffe00) | (((uint32_t)(freq) << 9) &
0x1ffffe00))
;
538 reg = RW(reg, AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f)(((reg) & ~0x000001fe) | (((uint32_t)(0x7f) << 1) &
0x000001fe))
;
539 reg = RW(reg, AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE, 0x2)(((reg) & ~0x60000000) | (((uint32_t)(0x2) << 29) &
0x60000000))
;
540 reg |= AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT0x00000001;
541 AR_WRITE(sc, AR_PHY_CCK_SPUR_MIT, reg)(sc)->ops.write((sc), (0x09fcc), (reg));
542 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
543}
544
545void
546ar9380_spur_mitigate_ofdm(struct athn_softc *sc, struct ieee80211_channel *c,
547 struct ieee80211_channel *extc)
548{
549 const struct ar9380_eeprom *eep = sc->eep;
550 const uint8_t *spurchans;
551 uint32_t reg;
552 int idx, spur_delta_phase, spur_off, range, i;
553 int freq, spur, spur_freq_sd, spur_subchannel_sd;
554
555 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0))
556 spurchans = eep->modalHeader2G.spurChans;
557 else
558 spurchans = eep->modalHeader5G.spurChans;
559 if (spurchans[0] == 0)
560 return;
561
562 /* Disable OFDM spur mitigation. */
563 AR_CLRBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER)(sc)->ops.write((sc), (0x0980c), ((sc)->ops.read((sc), (
0x0980c)) & ~(0x40000000)))
;
564
565 reg = AR_READ(sc, AR_PHY_TIMING11)(sc)->ops.read((sc), (0x09818));
566 reg = RW(reg, AR_PHY_TIMING11_SPUR_FREQ_SD, 0)(((reg) & ~0x3ff00000) | (((uint32_t)(0) << 20) &
0x3ff00000))
;
567 reg = RW(reg, AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0)(((reg) & ~0x000fffff) | (((uint32_t)(0) << 0) &
0x000fffff))
;
568 reg &= ~AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC0x40000000;
569 reg &= ~AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR0x80000000;
570 AR_WRITE(sc, AR_PHY_TIMING11, reg)(sc)->ops.write((sc), (0x09818), (reg));
571
572 AR_CLRBITS(sc, AR_PHY_SFCORR_EXT,(sc)->ops.write((sc), (0x0982c), ((sc)->ops.read((sc), (
0x0982c)) & ~(0x10000000)))
573 AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD)(sc)->ops.write((sc), (0x0982c), ((sc)->ops.read((sc), (
0x0982c)) & ~(0x10000000)))
;
574
575 AR_CLRBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI)(sc)->ops.write((sc), (0x0980c), ((sc)->ops.read((sc), (
0x0980c)) & ~(0x80000000)))
;
576
577 reg = AR_READ(sc, AR_PHY_SPUR_REG)(sc)->ops.read((sc), (0x0981c));
578 reg = RW(reg, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0)(((reg) & ~0x03fc0000) | (((uint32_t)(0) << 18) &
0x03fc0000))
;
579 reg &= ~AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI0x00000100;
580 reg &= ~AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT0x04000000;
581 reg &= ~AR_PHY_SPUR_REG_ENABLE_MASK_PPM0x00020000;
582 AR_WRITE(sc, AR_PHY_SPUR_REG, reg)(sc)->ops.write((sc), (0x0981c), (reg));
583 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
584
585 freq = c->ic_freq;
586 if (extc != NULL((void *)0)) {
587 range = 19; /* +/- 19MHz range. */
588 if (AR_READ(sc, AR_PHY_GEN_CTRL)(sc)->ops.read((sc), (0x0a204)) & AR_PHY_GC_DYN2040_PRI_CH0x00000010)
589 freq += 10;
590 else
591 freq -= 10;
592 } else
593 range = 10; /* +/- 10MHz range. */
594 for (i = 0; i < AR9380_EEPROM_MODAL_SPURS5; i++) {
595 spur = spurchans[i];
596 if (spur == 0)
597 return;
598 /* Convert to frequency. */
599 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0))
600 spur = 2300 + spur;
601 else
602 spur = 4900 + (spur * 5);
603 spur -= freq;
604 if (abs(spur) < range)
605 break;
606 }
607 if (i == AR9380_EEPROM_MODAL_SPURS5)
608 return;
609
610 /* Enable OFDM spur mitigation. */
611 if (extc != NULL((void *)0)) {
612 spur_delta_phase = (spur * 131072) / 5;
613 reg = AR_READ(sc, AR_PHY_GEN_CTRL)(sc)->ops.read((sc), (0x0a204));
614 if (spur < 0) {
615 spur_subchannel_sd =
616 (reg & AR_PHY_GC_DYN2040_PRI_CH0x00000010) == 0;
617 spur_off = spur + 10;
618 } else {
619 spur_subchannel_sd =
620 (reg & AR_PHY_GC_DYN2040_PRI_CH0x00000010) != 0;
621 spur_off = spur - 10;
622 }
623 } else {
624 spur_delta_phase = (spur * 262144) / 5;
625 spur_subchannel_sd = 0;
626 spur_off = spur;
627 }
628 spur_freq_sd = (spur_off * 512) / 11;
629
630 AR_SETBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER)(sc)->ops.write((sc), (0x0980c), ((sc)->ops.read((sc), (
0x0980c)) | (0x40000000)))
;
631
632 reg = AR_READ(sc, AR_PHY_TIMING11)(sc)->ops.read((sc), (0x09818));
633 reg = RW(reg, AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd)(((reg) & ~0x3ff00000) | (((uint32_t)(spur_freq_sd) <<
20) & 0x3ff00000))
;
634 reg = RW(reg, AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase)(((reg) & ~0x000fffff) | (((uint32_t)(spur_delta_phase) <<
0) & 0x000fffff))
;
635 reg |= AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC0x40000000;
636 reg |= AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR0x80000000;
637 AR_WRITE(sc, AR_PHY_TIMING11, reg)(sc)->ops.write((sc), (0x09818), (reg));
638
639 reg = AR_READ(sc, AR_PHY_SFCORR_EXT)(sc)->ops.read((sc), (0x0982c));
640 if (spur_subchannel_sd)
641 reg |= AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD0x10000000;
642 else
643 reg &= ~AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD0x10000000;
644 AR_WRITE(sc, AR_PHY_SFCORR_EXT, reg)(sc)->ops.write((sc), (0x0982c), (reg));
645
646 AR_SETBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI)(sc)->ops.write((sc), (0x0980c), ((sc)->ops.read((sc), (
0x0980c)) | (0x80000000)))
;
647
648 reg = AR_READ(sc, AR_PHY_SPUR_REG)(sc)->ops.read((sc), (0x0981c));
649 reg = RW(reg, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff)(((reg) & ~0x03fc0000) | (((uint32_t)(0xff) << 18) &
0x03fc0000))
;
650 reg = RW(reg, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34)(((reg) & ~0x000000ff) | (((uint32_t)(34) << 0) &
0x000000ff))
;
651 reg |= AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI0x00000100;
652 if (AR_READ(sc, AR_PHY_MODE)(sc)->ops.read((sc), (0x0a208)) & AR_PHY_MODE_DYNAMIC0x00000004)
653 reg |= AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT0x04000000;
654 reg |= AR_PHY_SPUR_REG_ENABLE_MASK_PPM0x00020000;
655 AR_WRITE(sc, AR_PHY_SPUR_REG, reg)(sc)->ops.write((sc), (0x0981c), (reg));
656
657 idx = (spur * 16) / 5;
658 if (idx < 0)
659 idx--;
660
661 /* Write pilot mask. */
662 AR_SETBITS(sc, AR_PHY_TIMING4,(sc)->ops.write((sc), (0x0980c), ((sc)->ops.read((sc), (
0x0980c)) | (0x10000000 | 0x20000000)))
663 AR_PHY_TIMING4_ENABLE_PILOT_MASK |(sc)->ops.write((sc), (0x0980c), ((sc)->ops.read((sc), (
0x0980c)) | (0x10000000 | 0x20000000)))
664 AR_PHY_TIMING4_ENABLE_CHAN_MASK)(sc)->ops.write((sc), (0x0980c), ((sc)->ops.read((sc), (
0x0980c)) | (0x10000000 | 0x20000000)))
;
665
666 reg = AR_READ(sc, AR_PHY_PILOT_SPUR_MASK)(sc)->ops.read((sc), (0x09c0c));
667 reg = RW(reg, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, idx)(((reg) & ~0x00000fe0) | (((uint32_t)(idx) << 5) &
0x00000fe0))
;
668 reg = RW(reg, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0x0c)(((reg) & ~0x0000001f) | (((uint32_t)(0x0c) << 0) &
0x0000001f))
;
669 AR_WRITE(sc, AR_PHY_PILOT_SPUR_MASK, reg)(sc)->ops.write((sc), (0x09c0c), (reg));
670
671 reg = AR_READ(sc, AR_PHY_SPUR_MASK_A)(sc)->ops.read((sc), (0x0a220));
672 reg = RW(reg, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, idx)(((reg) & ~0x0001fc00) | (((uint32_t)(idx) << 10) &
0x0001fc00))
;
673 reg = RW(reg, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0)(((reg) & ~0x000003ff) | (((uint32_t)(0xa0) << 0) &
0x000003ff))
;
674 AR_WRITE(sc, AR_PHY_SPUR_MASK_A, reg)(sc)->ops.write((sc), (0x0a220), (reg));
675
676 reg = AR_READ(sc, AR_PHY_CHAN_SPUR_MASK)(sc)->ops.read((sc), (0x09c10));
677 reg = RW(reg, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, idx)(((reg) & ~0x00000fe0) | (((uint32_t)(idx) << 5) &
0x00000fe0))
;
678 reg = RW(reg, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0x0c)(((reg) & ~0x0000001f) | (((uint32_t)(0x0c) << 0) &
0x0000001f))
;
679 AR_WRITE(sc, AR_PHY_CHAN_SPUR_MASK, reg)(sc)->ops.write((sc), (0x09c10), (reg));
680 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
681}
682
683void
684ar9380_spur_mitigate(struct athn_softc *sc, struct ieee80211_channel *c,
685 struct ieee80211_channel *extc)
686{
687 /* NB: We call spur_mitigate_cck for 5GHz too, just to disable it. */
688 ar9380_spur_mitigate_cck(sc, c, extc);
689 ar9380_spur_mitigate_ofdm(sc, c, extc);
690}
691
692void
693ar9380_set_txpower(struct athn_softc *sc, struct ieee80211_channel *c,
694 struct ieee80211_channel *extc)
695{
696 const struct ar9380_eeprom *eep = sc->eep;
697 uint8_t tpow_cck[4], tpow_ofdm[4];
698 uint8_t tpow_ht20[14], tpow_ht40[14];
699 int16_t power[ATHN_POWER_COUNT68];
700
701 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)) {
1
Assuming the condition is false
2
Taking false branch
702 /* Get CCK target powers. */
703 ar9003_get_lg_tpow(sc, c, AR_CTL_11B1,
704 eep->calTargetFbinCck, eep->calTargetPowerCck,
705 AR9380_NUM_2G_CCK_TARGET_POWERS2, tpow_cck);
706
707 /* Get OFDM target powers. */
708 ar9003_get_lg_tpow(sc, c, AR_CTL_11G2,
709 eep->calTargetFbin2G, eep->calTargetPower2G,
710 AR9380_NUM_2G_20_TARGET_POWERS3, tpow_ofdm);
711
712 /* Get HT-20 target powers. */
713 ar9003_get_ht_tpow(sc, c, AR_CTL_2GHT205,
714 eep->calTargetFbin2GHT20, eep->calTargetPower2GHT20,
715 AR9380_NUM_2G_20_TARGET_POWERS3, tpow_ht20);
716
717 if (extc != NULL((void *)0)) {
718 /* Get HT-40 target powers. */
719 ar9003_get_ht_tpow(sc, c, AR_CTL_2GHT407,
720 eep->calTargetFbin2GHT40,
721 eep->calTargetPower2GHT40,
722 AR9380_NUM_2G_40_TARGET_POWERS3, tpow_ht40);
723 }
724 } else {
725 /* Get OFDM target powers. */
726 ar9003_get_lg_tpow(sc, c, AR_CTL_11A0,
727 eep->calTargetFbin5G, eep->calTargetPower5G,
728 AR9380_NUM_5G_20_TARGET_POWERS8, tpow_ofdm);
729
730 /* Get HT-20 target powers. */
731 ar9003_get_ht_tpow(sc, c, AR_CTL_5GHT206,
732 eep->calTargetFbin5GHT20, eep->calTargetPower5GHT20,
733 AR9380_NUM_5G_20_TARGET_POWERS8, tpow_ht20);
734
735 if (extc != NULL((void *)0)) {
3
Assuming 'extc' is equal to NULL
4
Taking false branch
736 /* Get HT-40 target powers. */
737 ar9003_get_ht_tpow(sc, c, AR_CTL_5GHT408,
738 eep->calTargetFbin5GHT40,
739 eep->calTargetPower5GHT40,
740 AR9380_NUM_5G_40_TARGET_POWERS8, tpow_ht40);
741 }
742 }
743
744 memset(power, 0, sizeof(power))__builtin_memset((power), (0), (sizeof(power)));
745 /* Shuffle target powers across transmit rates. */
746 power[ATHN_POWER_OFDM60 ] =
747 power[ATHN_POWER_OFDM91 ] =
748 power[ATHN_POWER_OFDM122] =
749 power[ATHN_POWER_OFDM183] =
750 power[ATHN_POWER_OFDM244] = tpow_ofdm[0];
751 power[ATHN_POWER_OFDM365] = tpow_ofdm[1];
752 power[ATHN_POWER_OFDM486] = tpow_ofdm[2];
753 power[ATHN_POWER_OFDM547] = tpow_ofdm[3];
754 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)) {
5
Assuming the condition is true
6
Taking true branch
755 power[ATHN_POWER_CCK1_LP8 ] =
756 power[ATHN_POWER_CCK2_LP9 ] =
757 power[ATHN_POWER_CCK2_SP10 ] =
758 power[ATHN_POWER_CCK55_LP11] = tpow_cck[0];
7
Assigned value is garbage or undefined
759 power[ATHN_POWER_CCK55_SP12] = tpow_cck[1];
760 power[ATHN_POWER_CCK11_LP13] = tpow_cck[2];
761 power[ATHN_POWER_CCK11_SP14] = tpow_cck[3];
762 }
763 /* Next entry covers MCS0, MCS8 and MCS16. */
764 power[ATHN_POWER_HT20( 0)(16 + (0))] = tpow_ht20[ 0];
765 /* Next entry covers MCS1-3, MCS9-11 and MCS17-19. */
766 power[ATHN_POWER_HT20( 1)(16 + (1))] = tpow_ht20[ 1];
767 power[ATHN_POWER_HT20( 4)(16 + (4))] = tpow_ht20[ 2];
768 power[ATHN_POWER_HT20( 5)(16 + (5))] = tpow_ht20[ 3];
769 power[ATHN_POWER_HT20( 6)(16 + (6))] = tpow_ht20[ 4];
770 power[ATHN_POWER_HT20( 7)(16 + (7))] = tpow_ht20[ 5];
771 power[ATHN_POWER_HT20(12)(16 + (12))] = tpow_ht20[ 6];
772 power[ATHN_POWER_HT20(13)(16 + (13))] = tpow_ht20[ 7];
773 power[ATHN_POWER_HT20(14)(16 + (14))] = tpow_ht20[ 8];
774 power[ATHN_POWER_HT20(15)(16 + (15))] = tpow_ht20[ 9];
775 power[ATHN_POWER_HT20(20)(16 + (20))] = tpow_ht20[10];
776 power[ATHN_POWER_HT20(21)(16 + (21))] = tpow_ht20[11];
777 power[ATHN_POWER_HT20(22)(16 + (22))] = tpow_ht20[12];
778 power[ATHN_POWER_HT20(23)(16 + (23))] = tpow_ht20[13];
779 if (extc != NULL((void *)0)) {
780 /* Next entry covers MCS0, MCS8 and MCS16. */
781 power[ATHN_POWER_HT40( 0)(40 + (0))] = tpow_ht40[ 0];
782 /* Next entry covers MCS1-3, MCS9-11 and MCS17-19. */
783 power[ATHN_POWER_HT40( 1)(40 + (1))] = tpow_ht40[ 1];
784 power[ATHN_POWER_HT40( 4)(40 + (4))] = tpow_ht40[ 2];
785 power[ATHN_POWER_HT40( 5)(40 + (5))] = tpow_ht40[ 3];
786 power[ATHN_POWER_HT40( 6)(40 + (6))] = tpow_ht40[ 4];
787 power[ATHN_POWER_HT40( 7)(40 + (7))] = tpow_ht40[ 5];
788 power[ATHN_POWER_HT40(12)(40 + (12))] = tpow_ht40[ 6];
789 power[ATHN_POWER_HT40(13)(40 + (13))] = tpow_ht40[ 7];
790 power[ATHN_POWER_HT40(14)(40 + (14))] = tpow_ht40[ 8];
791 power[ATHN_POWER_HT40(15)(40 + (15))] = tpow_ht40[ 9];
792 power[ATHN_POWER_HT40(20)(40 + (20))] = tpow_ht40[10];
793 power[ATHN_POWER_HT40(21)(40 + (21))] = tpow_ht40[11];
794 power[ATHN_POWER_HT40(22)(40 + (22))] = tpow_ht40[12];
795 power[ATHN_POWER_HT40(23)(40 + (23))] = tpow_ht40[13];
796 }
797
798 /* Write transmit power values to hardware. */
799 ar9003_write_txpower(sc, power);
800
801 /* Apply transmit power correction. */
802 ar9380_set_correction(sc, c);
803}
804
805void
806ar9380_get_correction(struct athn_softc *sc, struct ieee80211_channel *c,
807 int chain, int *corr, int *temp)
808{
809 const struct ar9380_eeprom *eep = sc->eep;
810 const struct ar9380_cal_data_per_freq_op_loop *pierdata;
811 const uint8_t *pierfreq;
812 uint8_t fbin;
813 int lo, hi, npiers;
814
815 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0)) {
816 pierfreq = eep->calFreqPier2G;
817 pierdata = eep->calPierData2G[chain];
818 npiers = AR9380_NUM_2G_CAL_PIERS3;
819 } else {
820 pierfreq = eep->calFreqPier5G;
821 pierdata = eep->calPierData5G[chain];
822 npiers = AR9380_NUM_5G_CAL_PIERS8;
823 }
824 /* Find channel in ROM pier table. */
825 fbin = athn_chan2fbin(c);
826 athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi);
827
828 *corr = athn_interpolate(fbin,
829 pierfreq[lo], pierdata[lo].refPower,
830 pierfreq[hi], pierdata[hi].refPower);
831 *temp = athn_interpolate(fbin,
832 pierfreq[lo], pierdata[lo].tempMeas,
833 pierfreq[hi], pierdata[hi].tempMeas);
834}
835
836void
837ar9380_set_correction(struct athn_softc *sc, struct ieee80211_channel *c)
838{
839 const struct ar9380_eeprom *eep = sc->eep;
840 const struct ar9380_modal_eep_header *modal;
841 uint32_t reg;
842 int8_t slope;
843 int i, corr, temp, temp0;
844
845 if (IEEE80211_IS_CHAN_2GHZ(c)(((c)->ic_flags & 0x0080) != 0))
846 modal = &eep->modalHeader2G;
847 else
848 modal = &eep->modalHeader5G;
849
850 for (i = 0; i < AR9380_MAX_CHAINS3; i++) {
851 ar9380_get_correction(sc, c, i, &corr, &temp);
852 if (i == 0)
853 temp0 = temp;
854
855 reg = AR_READ(sc, AR_PHY_TPC_11_B(i))(sc)->ops.read((sc), ((0x0a420 + (i) * 0x1000)));
856 reg = RW(reg, AR_PHY_TPC_11_OLPC_GAIN_DELTA, corr)(((reg) & ~0x00ff0000) | (((uint32_t)(corr) << 16) &
0x00ff0000))
;
857 AR_WRITE(sc, AR_PHY_TPC_11_B(i), reg)(sc)->ops.write((sc), ((0x0a420 + (i) * 0x1000)), (reg));
858
859 /* Enable open loop power control. */
860 reg = AR_READ(sc, AR_PHY_TPC_6_B(i))(sc)->ops.read((sc), ((0x0a40c + (i) * 0x1000)));
861 reg = RW(reg, AR_PHY_TPC_6_ERROR_EST_MODE, 3)(((reg) & ~0x03000000) | (((uint32_t)(3) << 24) &
0x03000000))
;
862 AR_WRITE(sc, AR_PHY_TPC_6_B(i), reg)(sc)->ops.write((sc), ((0x0a40c + (i) * 0x1000)), (reg));
863 }
864
865 /* Enable temperature compensation. */
866 if (IEEE80211_IS_CHAN_5GHZ(c)(((c)->ic_flags & 0x0100) != 0) &&
867 eep->base_ext2.tempSlopeLow != 0) {
868 if (c->ic_freq <= 5500) {
869 slope = athn_interpolate(c->ic_freq,
870 5180, eep->base_ext2.tempSlopeLow,
871 5500, modal->tempSlope);
872 } else {
873 slope = athn_interpolate(c->ic_freq,
874 5500, modal->tempSlope,
875 5785, eep->base_ext2.tempSlopeHigh);
876 }
877 } else
878 slope = modal->tempSlope;
879
880 reg = AR_READ(sc, AR_PHY_TPC_19)(sc)->ops.read((sc), (0x0a440));
881 reg = RW(reg, AR_PHY_TPC_19_ALPHA_THERM, slope)(((reg) & ~0x000000ff) | (((uint32_t)(slope) << 0) &
0x000000ff))
;
882 AR_WRITE(sc, AR_PHY_TPC_19, reg)(sc)->ops.write((sc), (0x0a440), (reg));
883
884 reg = AR_READ(sc, AR_PHY_TPC_18)(sc)->ops.read((sc), (0x0a43c));
885 reg = RW(reg, AR_PHY_TPC_18_THERM_CAL, temp0)(((reg) & ~0x000000ff) | (((uint32_t)(temp0) << 0) &
0x000000ff))
;
886 AR_WRITE(sc, AR_PHY_TPC_18, reg)(sc)->ops.write((sc), (0x0a43c), (reg));
887 AR_WRITE_BARRIER(sc)(sc)->ops.write_barrier((sc));
888}