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