xref: /openbsd/sys/dev/ic/ar5416.c (revision cca36db2)
1 /*	$OpenBSD: ar5416.c,v 1.11 2010/08/12 16:34:53 damien 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 
39 #include <machine/bus.h>
40 #include <machine/endian.h>
41 #include <machine/intr.h>
42 
43 #if NBPFILTER > 0
44 #include <net/bpf.h>
45 #endif
46 #include <net/if.h>
47 #include <net/if_arp.h>
48 #include <net/if_dl.h>
49 #include <net/if_media.h>
50 #include <net/if_types.h>
51 
52 #include <netinet/in.h>
53 #include <netinet/in_systm.h>
54 #include <netinet/in_var.h>
55 #include <netinet/if_ether.h>
56 #include <netinet/ip.h>
57 
58 #include <net80211/ieee80211_var.h>
59 #include <net80211/ieee80211_amrr.h>
60 #include <net80211/ieee80211_radiotap.h>
61 
62 #include <dev/ic/athnreg.h>
63 #include <dev/ic/athnvar.h>
64 
65 #include <dev/ic/ar5008reg.h>
66 #include <dev/ic/ar5416reg.h>
67 
68 int	ar5416_attach(struct athn_softc *);
69 void	ar5416_setup(struct athn_softc *);
70 void	ar5416_swap_rom(struct athn_softc *);
71 const struct ar_spur_chan *
72 	ar5416_get_spur_chans(struct athn_softc *, int);
73 int	ar5416_set_synth(struct athn_softc *, struct ieee80211_channel *,
74 	    struct ieee80211_channel *);
75 uint8_t	ar5416_reverse_bits(uint8_t, int);
76 uint8_t	ar5416_get_rf_rev(struct athn_softc *);
77 void	ar5416_init_from_rom(struct athn_softc *, struct ieee80211_channel *,
78 	    struct ieee80211_channel *);
79 int	ar5416_init_calib(struct athn_softc *, struct ieee80211_channel *,
80 	    struct ieee80211_channel *);
81 void	ar5416_set_power_calib(struct athn_softc *,
82 	    struct ieee80211_channel *);
83 void	ar5416_set_txpower(struct athn_softc *, struct ieee80211_channel *,
84 	    struct ieee80211_channel *);
85 void	ar5416_spur_mitigate(struct athn_softc *, struct ieee80211_channel *,
86 	    struct ieee80211_channel *);
87 void	ar5416_rw_rfbits(uint32_t *, int, int, uint32_t, int);
88 void	ar5416_rw_bank6tpc(struct athn_softc *, struct ieee80211_channel *,
89 	    uint32_t *);
90 void	ar5416_rf_reset(struct athn_softc *, struct ieee80211_channel *);
91 void	ar5416_reset_bb_gain(struct athn_softc *, struct ieee80211_channel *);
92 void	ar5416_force_bias(struct athn_softc *, struct ieee80211_channel *);
93 void	ar9160_rw_addac(struct athn_softc *, struct ieee80211_channel *,
94 	    uint32_t *);
95 void	ar5416_reset_addac(struct athn_softc *, struct ieee80211_channel *);
96 void	ar5416_get_pdadcs(struct athn_softc *, struct ieee80211_channel *,
97 	    int, int, uint8_t, uint8_t *, uint8_t *);
98 
99 /* Extern functions. */
100 uint8_t	athn_chan2fbin(struct ieee80211_channel *);
101 void	athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *);
102 int	ar5008_attach(struct athn_softc *);
103 void	ar5008_write_txpower(struct athn_softc *, int16_t power[]);
104 void	ar5008_get_pdadcs(struct athn_softc *, uint8_t, struct athn_pier *,
105 	    struct athn_pier *, int, int, uint8_t, uint8_t *, uint8_t *);
106 void	ar5008_set_viterbi_mask(struct athn_softc *, int);
107 void	ar5008_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *,
108 	    uint8_t, const struct ar_cal_target_power_leg *, int, uint8_t[]);
109 void	ar5008_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *,
110 	    uint8_t, const struct ar_cal_target_power_ht *, int, uint8_t[]);
111 void	ar9280_olpc_get_pdadcs(struct athn_softc *, struct ieee80211_channel *,
112 	    int, uint8_t *, uint8_t *, uint8_t *);
113 
114 
115 int
116 ar5416_attach(struct athn_softc *sc)
117 {
118 	sc->eep_base = AR5416_EEP_START_LOC;
119 	sc->eep_size = sizeof(struct ar5416_eeprom);
120 	sc->def_nf = AR5416_PHY_CCA_MAX_GOOD_VALUE;
121 	sc->ngpiopins = 14;
122 	sc->led_pin = 1;
123 	sc->workaround = AR5416_WA_DEFAULT;
124 	sc->ops.setup = ar5416_setup;
125 	sc->ops.swap_rom = ar5416_swap_rom;
126 	sc->ops.init_from_rom = ar5416_init_from_rom;
127 	sc->ops.set_txpower = ar5416_set_txpower;
128 	sc->ops.set_synth = ar5416_set_synth;
129 	sc->ops.spur_mitigate = ar5416_spur_mitigate;
130 	sc->ops.get_spur_chans = ar5416_get_spur_chans;
131 	if (AR_SREV_9160_10_OR_LATER(sc))
132 		sc->ini = &ar9160_ini;
133 	else
134 		sc->ini = &ar5416_ini;
135 	sc->serdes = ar5416_serdes;
136 
137 	return (ar5008_attach(sc));
138 }
139 
140 void
141 ar5416_setup(struct athn_softc *sc)
142 {
143 	/* Select ADDAC programming. */
144 	if (AR_SREV_9160_11(sc))
145 		sc->addac = &ar9160_1_1_addac;
146 	else if (AR_SREV_9160_10_OR_LATER(sc))
147 		sc->addac = &ar9160_1_0_addac;
148 	else if (AR_SREV_5416_22_OR_LATER(sc))
149 		sc->addac = &ar5416_2_2_addac;
150 	else
151 		sc->addac = &ar5416_2_1_addac;
152 }
153 
154 void
155 ar5416_swap_rom(struct athn_softc *sc)
156 {
157 	struct ar5416_eeprom *eep = sc->eep;
158 	struct ar5416_modal_eep_header *modal;
159 	int i, j;
160 
161 	for (i = 0; i < 2; i++) {	/* Dual-band. */
162 		modal = &eep->modalHeader[i];
163 
164 		modal->antCtrlCommon = swap32(modal->antCtrlCommon);
165 		for (j = 0; j < AR5416_MAX_CHAINS; j++) {
166 			modal->antCtrlChain[j] =
167 			    swap32(modal->antCtrlChain[j]);
168 		}
169 		for (j = 0; j < AR_EEPROM_MODAL_SPURS; j++) {
170 			modal->spurChans[j].spurChan =
171 			    swap16(modal->spurChans[j].spurChan);
172 		}
173 	}
174 }
175 
176 const struct ar_spur_chan *
177 ar5416_get_spur_chans(struct athn_softc *sc, int is2ghz)
178 {
179 	const struct ar5416_eeprom *eep = sc->eep;
180 
181 	return (eep->modalHeader[is2ghz].spurChans);
182 }
183 
184 int
185 ar5416_set_synth(struct athn_softc *sc, struct ieee80211_channel *c,
186     struct ieee80211_channel *extc)
187 {
188 	uint32_t phy, reg;
189 	uint32_t freq = c->ic_freq;
190 	uint8_t chansel;
191 
192 	phy = 0;
193 	if (IEEE80211_IS_CHAN_2GHZ(c)) {
194 		if (((freq - 2192) % 5) == 0) {
195 			chansel = ((freq - 672) * 2 - 3040) / 10;
196 		} else if (((freq - 2224) % 5) == 0) {
197 			chansel = ((freq - 704) * 2 - 3040) / 10;
198 			phy |= AR5416_BMODE_SYNTH;
199 		} else
200 			return (EINVAL);
201 		chansel <<= 2;
202 
203 		reg = AR_READ(sc, AR_PHY_CCK_TX_CTRL);
204 		if (freq == 2484)	/* Channel 14. */
205 			reg |= AR_PHY_CCK_TX_CTRL_JAPAN;
206 		else
207 			reg &= ~AR_PHY_CCK_TX_CTRL_JAPAN;
208 		AR_WRITE(sc, AR_PHY_CCK_TX_CTRL, reg);
209 
210 		/* Fix for orientation sensitivity issue. */
211 		if (AR_SREV_5416(sc))
212 			ar5416_force_bias(sc, c);
213 	} else {
214 		if (freq >= 5120 && (freq % 20) == 0) {
215 			chansel = (freq - 4800) / 20;
216 			chansel <<= 2;
217 			phy |= SM(AR5416_AMODE_REFSEL, 2);
218 		} else if ((freq % 10) == 0) {
219 			chansel = (freq - 4800) / 10;
220 			chansel <<= 1;
221 			if (AR_SREV_9160_10_OR_LATER(sc))
222 				phy |= SM(AR5416_AMODE_REFSEL, 1);
223 			else
224 				phy |= SM(AR5416_AMODE_REFSEL, 2);
225 		} else if ((freq % 5) == 0) {
226 			chansel = (freq - 4800) / 5;
227 			phy |= SM(AR5416_AMODE_REFSEL, 2);
228 		} else
229 			return (EINVAL);
230 	}
231 	chansel = ar5416_reverse_bits(chansel, 8);
232 	phy |= chansel << 8 | 1 << 5 | 1;
233 	DPRINTFN(4, ("AR_PHY(0x37)=0x%08x\n", phy));
234 	AR_WRITE(sc, AR_PHY(0x37), phy);
235 	return (0);
236 }
237 
238 void
239 ar5416_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
240     struct ieee80211_channel *extc)
241 {
242 	static const uint32_t chainoffset[] = { 0x0000, 0x2000, 0x1000 };
243 	const struct ar5416_eeprom *eep = sc->eep;
244 	const struct ar5416_modal_eep_header *modal;
245 	uint32_t reg, offset;
246 	uint8_t txRxAtten;
247 	int i;
248 
249 	modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)];
250 
251 	AR_WRITE(sc, AR_PHY_SWITCH_COM, modal->antCtrlCommon);
252 
253 	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
254 		if (AR_SREV_5416_20_OR_LATER(sc) &&
255 		    (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5))
256 			offset = chainoffset[i];
257 		else
258 			offset = i * 0x1000;
259 
260 		AR_WRITE(sc, AR_PHY_SWITCH_CHAIN_0 + offset,
261 		    modal->antCtrlChain[i]);
262 
263 		reg = AR_READ(sc, AR_PHY_TIMING_CTRL4_0 + offset);
264 		reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
265 		    modal->iqCalICh[i]);
266 		reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
267 		    modal->iqCalQCh[i]);
268 		AR_WRITE(sc, AR_PHY_TIMING_CTRL4_0 + offset, reg);
269 
270 		if (i > 0 && !AR_SREV_5416_20_OR_LATER(sc))
271 			continue;
272 
273 		if (sc->eep_rev >= AR_EEP_MINOR_VER_3) {
274 			reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset);
275 			reg = RW(reg, AR_PHY_GAIN_2GHZ_BSW_MARGIN,
276 			    modal->bswMargin[i]);
277 			reg = RW(reg, AR_PHY_GAIN_2GHZ_BSW_ATTEN,
278 			    modal->bswAtten[i]);
279 			AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg);
280 		}
281 		if (sc->eep_rev >= AR_EEP_MINOR_VER_3)
282 			txRxAtten = modal->txRxAttenCh[i];
283 		else	/* Workaround for ROM versions < 14.3. */
284 			txRxAtten = IEEE80211_IS_CHAN_2GHZ(c) ? 23 : 44;
285 		reg = AR_READ(sc, AR_PHY_RXGAIN + offset);
286 		reg = RW(reg, AR_PHY_RXGAIN_TXRX_ATTEN, txRxAtten);
287 		AR_WRITE(sc, AR_PHY_RXGAIN + offset, reg);
288 
289 		reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset);
290 		reg = RW(reg, AR_PHY_GAIN_2GHZ_RXTX_MARGIN,
291 		    modal->rxTxMarginCh[i]);
292 		AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg);
293 	}
294 	reg = AR_READ(sc, AR_PHY_SETTLING);
295 	reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->switchSettling);
296 	AR_WRITE(sc, AR_PHY_SETTLING, reg);
297 
298 	reg = AR_READ(sc, AR_PHY_DESIRED_SZ);
299 	reg = RW(reg, AR_PHY_DESIRED_SZ_ADC, modal->adcDesiredSize);
300 	reg = RW(reg, AR_PHY_DESIRED_SZ_PGA, modal->pgaDesiredSize);
301 	AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg);
302 
303 	reg =  SM(AR_PHY_RF_CTL4_TX_END_XPAA_OFF, modal->txEndToXpaOff);
304 	reg |= SM(AR_PHY_RF_CTL4_TX_END_XPAB_OFF, modal->txEndToXpaOff);
305 	reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAA_ON, modal->txFrameToXpaOn);
306 	reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAB_ON, modal->txFrameToXpaOn);
307 	AR_WRITE(sc, AR_PHY_RF_CTL4, reg);
308 
309 	reg = AR_READ(sc, AR_PHY_RF_CTL3);
310 	reg = RW(reg, AR_PHY_TX_END_TO_A2_RX_ON, modal->txEndToRxOn);
311 	AR_WRITE(sc, AR_PHY_RF_CTL3, reg);
312 
313 	reg = AR_READ(sc, AR_PHY_CCA(0));
314 	reg = RW(reg, AR_PHY_CCA_THRESH62, modal->thresh62);
315 	AR_WRITE(sc, AR_PHY_CCA(0), reg);
316 
317 	reg = AR_READ(sc, AR_PHY_EXT_CCA(0));
318 	reg = RW(reg, AR_PHY_EXT_CCA_THRESH62, modal->thresh62);
319 	AR_WRITE(sc, AR_PHY_EXT_CCA(0), reg);
320 
321 	if (sc->eep_rev >= AR_EEP_MINOR_VER_2) {
322 		reg = AR_READ(sc, AR_PHY_RF_CTL2);
323 		reg = RW(reg, AR_PHY_TX_END_DATA_START,
324 		    modal->txFrameToDataStart);
325 		reg = RW(reg, AR_PHY_TX_END_PA_ON, modal->txFrameToPaOn);
326 		AR_WRITE(sc, AR_PHY_RF_CTL2, reg);
327 	}
328 #ifndef IEEE80211_NO_HT
329 	if (sc->eep_rev >= AR_EEP_MINOR_VER_3 && extc != NULL) {
330 		/* Overwrite switch settling with HT-40 value. */
331 		reg = AR_READ(sc, AR_PHY_SETTLING);
332 		reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->swSettleHt40);
333 		AR_WRITE(sc, AR_PHY_SETTLING, reg);
334 	}
335 #endif
336 }
337 
338 int
339 ar5416_init_calib(struct athn_softc *sc, struct ieee80211_channel *c,
340     struct ieee80211_channel *extc)
341 {
342 	int ntries;
343 
344 	if (AR_SREV_9280_10_OR_LATER(sc)) {
345 		/* XXX Linux tests AR9287?! */
346 		AR_CLRBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
347 		AR_SETBITS(sc, AR_PHY_AGC_CONTROL,
348 		    AR_PHY_AGC_CONTROL_FLTR_CAL);
349 	}
350 	/* Calibrate the AGC. */
351 	AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
352 	/* Poll for offset calibration completion. */
353 	for (ntries = 0; ntries < 10000; ntries++) {
354 		if (!(AR_READ(sc, AR_PHY_AGC_CONTROL) &
355 		    AR_PHY_AGC_CONTROL_CAL))
356 			break;
357 		DELAY(10);
358 	}
359 	if (ntries == 10000)
360 		return (ETIMEDOUT);
361 	if (AR_SREV_9280_10_OR_LATER(sc)) {
362 		AR_SETBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
363 		AR_CLRBITS(sc, AR_PHY_AGC_CONTROL,
364 		    AR_PHY_AGC_CONTROL_FLTR_CAL);
365 	}
366 	return (0);
367 }
368 
369 void
370 ar5416_get_pdadcs(struct athn_softc *sc, struct ieee80211_channel *c,
371     int chain, int nxpdgains, uint8_t overlap, uint8_t *boundaries,
372     uint8_t *pdadcs)
373 {
374 	const struct ar5416_eeprom *eep = sc->eep;
375 	const struct ar5416_cal_data_per_freq *pierdata;
376 	const uint8_t *pierfreq;
377 	struct athn_pier lopier, hipier;
378 	int16_t delta;
379 	uint8_t fbin, pwroff;
380 	int i, lo, hi, npiers;
381 
382 	if (IEEE80211_IS_CHAN_2GHZ(c)) {
383 		pierfreq = eep->calFreqPier2G;
384 		pierdata = eep->calPierData2G[chain];
385 		npiers = AR5416_NUM_2G_CAL_PIERS;
386 	} else {
387 		pierfreq = eep->calFreqPier5G;
388 		pierdata = eep->calPierData5G[chain];
389 		npiers = AR5416_NUM_5G_CAL_PIERS;
390 	}
391 	/* Find channel in ROM pier table. */
392 	fbin = athn_chan2fbin(c);
393 	athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi);
394 
395 	lopier.fbin = pierfreq[lo];
396 	hipier.fbin = pierfreq[hi];
397 	for (i = 0; i < nxpdgains; i++) {
398 		lopier.pwr[i] = pierdata[lo].pwrPdg[i];
399 		lopier.vpd[i] = pierdata[lo].vpdPdg[i];
400 		hipier.pwr[i] = pierdata[lo].pwrPdg[i];
401 		hipier.vpd[i] = pierdata[lo].vpdPdg[i];
402 	}
403 	ar5008_get_pdadcs(sc, fbin, &lopier, &hipier, nxpdgains,
404 	    AR5416_PD_GAIN_ICEPTS, overlap, boundaries, pdadcs);
405 
406 	if (!AR_SREV_9280_20_OR_LATER(sc))
407 		return;
408 
409 	if (sc->eep_rev >= AR_EEP_MINOR_VER_21)
410 		pwroff = eep->baseEepHeader.pwrTableOffset;
411 	else
412 		pwroff = AR_PWR_TABLE_OFFSET_DB;
413 	delta = (pwroff - AR_PWR_TABLE_OFFSET_DB) * 2;	/* In half dB. */
414 
415 	/* Change the original gain boundaries setting. */
416 	for (i = 0; i < nxpdgains; i++) {
417 		/* XXX Possible overflows? */
418 		boundaries[i] -= delta;
419 		if (boundaries[i] > AR_MAX_RATE_POWER - overlap)
420 			boundaries[i] = AR_MAX_RATE_POWER - overlap;
421 	}
422 	if (delta != 0) {
423 		/* Shift the PDADC table to start at the new offset. */
424 		for (i = 0; i < AR_NUM_PDADC_VALUES; i++)
425 			pdadcs[i] = pdadcs[MIN(i + delta,
426 			    AR_NUM_PDADC_VALUES - 1)];
427 	}
428 }
429 
430 void
431 ar5416_set_power_calib(struct athn_softc *sc, struct ieee80211_channel *c)
432 {
433 	static const uint32_t chainoffset[] = { 0x0000, 0x2000, 0x1000 };
434 	const struct ar5416_eeprom *eep = sc->eep;
435 	const struct ar5416_modal_eep_header *modal;
436 	uint8_t boundaries[AR_PD_GAINS_IN_MASK];
437 	uint8_t pdadcs[AR_NUM_PDADC_VALUES];
438 	uint8_t xpdgains[AR5416_NUM_PD_GAINS];
439 	uint8_t overlap, txgain;
440 	uint32_t reg, offset;
441 	int i, j, nxpdgains;
442 
443 	modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)];
444 
445 	if (sc->eep_rev < AR_EEP_MINOR_VER_2) {
446 		overlap = MS(AR_READ(sc, AR_PHY_TPCRG5),
447 		    AR_PHY_TPCRG5_PD_GAIN_OVERLAP);
448 	} else
449 		overlap = modal->pdGainOverlap;
450 
451 	if ((sc->flags & ATHN_FLAG_OLPC) && IEEE80211_IS_CHAN_2GHZ(c)) {
452 		/* XXX not here. */
453 		sc->pdadc =
454 		    ((const struct ar_cal_data_per_freq_olpc *)
455 		     eep->calPierData2G[0])->vpdPdg[0][0];
456 	}
457 
458 	nxpdgains = 0;
459 	memset(xpdgains, 0, sizeof(xpdgains));
460 	for (i = AR5416_PD_GAINS_IN_MASK - 1; i >= 0; i--) {
461 		if (nxpdgains >= AR5416_NUM_PD_GAINS)
462 			break;	/* Can't happen. */
463 		if (modal->xpdGain & (1 << i))
464 			xpdgains[nxpdgains++] = i;
465 	}
466 	reg = AR_READ(sc, AR_PHY_TPCRG1);
467 	reg = RW(reg, AR_PHY_TPCRG1_NUM_PD_GAIN, nxpdgains - 1);
468 	reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_1, xpdgains[0]);
469 	reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_2, xpdgains[1]);
470 	reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_3, xpdgains[2]);
471 	AR_WRITE(sc, AR_PHY_TPCRG1, reg);
472 
473 	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
474 		if (!(sc->txchainmask & (1 << i)))
475 			continue;
476 
477 		if (AR_SREV_5416_20_OR_LATER(sc) &&
478 		    (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5))
479 			offset = chainoffset[i];
480 		else
481 			offset = i * 0x1000;
482 
483 		if (sc->flags & ATHN_FLAG_OLPC) {
484 			ar9280_olpc_get_pdadcs(sc, c, i, boundaries,
485 			    pdadcs, &txgain);
486 
487 			reg = AR_READ(sc, AR_PHY_TX_PWRCTRL6_0);
488 			reg = RW(reg, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
489 			AR_WRITE(sc, AR_PHY_TX_PWRCTRL6_0, reg);
490 
491 			reg = AR_READ(sc, AR_PHY_TX_PWRCTRL6_1);
492 			reg = RW(reg, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
493 			AR_WRITE(sc, AR_PHY_TX_PWRCTRL6_1, reg);
494 
495 			reg = AR_READ(sc, AR_PHY_TX_PWRCTRL7);
496 			reg = RW(reg, AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, txgain);
497 			AR_WRITE(sc, AR_PHY_TX_PWRCTRL7, reg);
498 
499 			overlap = 6;
500 		} else {
501 			ar5416_get_pdadcs(sc, c, i, nxpdgains, overlap,
502 			    boundaries, pdadcs);
503 		}
504 		/* Write boundaries. */
505 		if (i == 0 || AR_SREV_5416_20_OR_LATER(sc)) {
506 			reg  = SM(AR_PHY_TPCRG5_PD_GAIN_OVERLAP,
507 			    overlap);
508 			reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1,
509 			    boundaries[0]);
510 			reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2,
511 			    boundaries[1]);
512 			reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3,
513 			    boundaries[2]);
514 			reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4,
515 			    boundaries[3]);
516 			AR_WRITE(sc, AR_PHY_TPCRG5 + offset, reg);
517 		}
518 		/* Write PDADC values. */
519 		for (j = 0; j < AR_NUM_PDADC_VALUES; j += 4) {
520 			AR_WRITE(sc, AR_PHY_PDADC_TBL_BASE + offset + j,
521 			    pdadcs[j + 0] <<  0 |
522 			    pdadcs[j + 1] <<  8 |
523 			    pdadcs[j + 2] << 16 |
524 			    pdadcs[j + 3] << 24);
525 		}
526 	}
527 }
528 
529 void
530 ar5416_set_txpower(struct athn_softc *sc, struct ieee80211_channel *c,
531     struct ieee80211_channel *extc)
532 {
533 	const struct ar5416_eeprom *eep = sc->eep;
534 	const struct ar5416_modal_eep_header *modal;
535 	uint8_t tpow_cck[4], tpow_ofdm[4];
536 #ifndef IEEE80211_NO_HT
537 	uint8_t tpow_cck_ext[4], tpow_ofdm_ext[4];
538 	uint8_t tpow_ht20[8], tpow_ht40[8];
539 	uint8_t ht40inc;
540 #endif
541 	int16_t pwr = 0, pwroff, max_ant_gain, power[ATHN_POWER_COUNT];
542 	uint8_t cckinc;
543 	int i;
544 
545 	ar5416_set_power_calib(sc, c);
546 
547 	modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)];
548 
549 	/* Compute transmit power reduction due to antenna gain. */
550 	max_ant_gain = MAX(modal->antennaGainCh[0], modal->antennaGainCh[1]);
551 	max_ant_gain = MAX(modal->antennaGainCh[2], max_ant_gain);
552 	/* XXX */
553 
554 	/*
555 	 * Reduce scaled power by number of active chains to get per-chain
556 	 * transmit power level.
557 	 */
558 	if (sc->ntxchains == 2)
559 		pwr -= AR_PWR_DECREASE_FOR_2_CHAIN;
560 	else if (sc->ntxchains == 3)
561 		pwr -= AR_PWR_DECREASE_FOR_3_CHAIN;
562 	if (pwr < 0)
563 		pwr = 0;
564 
565 	if (IEEE80211_IS_CHAN_2GHZ(c)) {
566 		/* Get CCK target powers. */
567 		ar5008_get_lg_tpow(sc, c, AR_CTL_11B, eep->calTargetPowerCck,
568 		    AR5416_NUM_2G_CCK_TARGET_POWERS, tpow_cck);
569 
570 		/* Get OFDM target powers. */
571 		ar5008_get_lg_tpow(sc, c, AR_CTL_11G, eep->calTargetPower2G,
572 		    AR5416_NUM_2G_20_TARGET_POWERS, tpow_ofdm);
573 
574 #ifndef IEEE80211_NO_HT
575 		/* Get HT-20 target powers. */
576 		ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT20,
577 		    eep->calTargetPower2GHT20, AR5416_NUM_2G_20_TARGET_POWERS,
578 		    tpow_ht20);
579 
580 		if (extc != NULL) {
581 			/* Get HT-40 target powers. */
582 			ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT40,
583 			    eep->calTargetPower2GHT40,
584 			    AR5416_NUM_2G_40_TARGET_POWERS, tpow_ht40);
585 
586 			/* Get secondary channel CCK target powers. */
587 			ar5008_get_lg_tpow(sc, extc, AR_CTL_11B,
588 			    eep->calTargetPowerCck,
589 			    AR5416_NUM_2G_CCK_TARGET_POWERS, tpow_cck_ext);
590 
591 			/* Get secondary channel OFDM target powers. */
592 			ar5008_get_lg_tpow(sc, extc, AR_CTL_11G,
593 			    eep->calTargetPower2G,
594 			    AR5416_NUM_2G_20_TARGET_POWERS, tpow_ofdm_ext);
595 		}
596 #endif
597 	} else {
598 		/* Get OFDM target powers. */
599 		ar5008_get_lg_tpow(sc, c, AR_CTL_11A, eep->calTargetPower5G,
600 		    AR5416_NUM_5G_20_TARGET_POWERS, tpow_ofdm);
601 
602 #ifndef IEEE80211_NO_HT
603 		/* Get HT-20 target powers. */
604 		ar5008_get_ht_tpow(sc, c, AR_CTL_5GHT20,
605 		    eep->calTargetPower5GHT20, AR5416_NUM_5G_20_TARGET_POWERS,
606 		    tpow_ht20);
607 
608 		if (extc != NULL) {
609 			/* Get HT-40 target powers. */
610 			ar5008_get_ht_tpow(sc, c, AR_CTL_5GHT40,
611 			    eep->calTargetPower5GHT40,
612 			    AR5416_NUM_5G_40_TARGET_POWERS, tpow_ht40);
613 
614 			/* Get secondary channel OFDM target powers. */
615 			ar5008_get_lg_tpow(sc, extc, AR_CTL_11A,
616 			    eep->calTargetPower5G,
617 			    AR5416_NUM_5G_20_TARGET_POWERS, tpow_ofdm_ext);
618 		}
619 #endif
620 	}
621 
622 	/* Compute CCK/OFDM delta. */
623 	cckinc = (sc->flags & ATHN_FLAG_OLPC) ? -2 : 0;
624 
625 	memset(power, 0, sizeof(power));
626 	/* Shuffle target powers accross transmit rates. */
627 	power[ATHN_POWER_OFDM6 ] =
628 	power[ATHN_POWER_OFDM9 ] =
629 	power[ATHN_POWER_OFDM12] =
630 	power[ATHN_POWER_OFDM18] =
631 	power[ATHN_POWER_OFDM24] = tpow_ofdm[0];
632 	power[ATHN_POWER_OFDM36] = tpow_ofdm[1];
633 	power[ATHN_POWER_OFDM48] = tpow_ofdm[2];
634 	power[ATHN_POWER_OFDM54] = tpow_ofdm[3];
635 	power[ATHN_POWER_XR    ] = tpow_ofdm[0];
636 	if (IEEE80211_IS_CHAN_2GHZ(c)) {
637 		power[ATHN_POWER_CCK1_LP ] = tpow_cck[0] + cckinc;
638 		power[ATHN_POWER_CCK2_LP ] =
639 		power[ATHN_POWER_CCK2_SP ] = tpow_cck[1] + cckinc;
640 		power[ATHN_POWER_CCK55_LP] =
641 		power[ATHN_POWER_CCK55_SP] = tpow_cck[2] + cckinc;
642 		power[ATHN_POWER_CCK11_LP] =
643 		power[ATHN_POWER_CCK11_SP] = tpow_cck[3] + cckinc;
644 	}
645 #ifndef IEEE80211_NO_HT
646 	for (i = 0; i < nitems(tpow_ht20); i++)
647 		power[ATHN_POWER_HT20(i)] = tpow_ht20[i];
648 	if (extc != NULL) {
649 		/* Correct PAR difference between HT40 and HT20/Legacy. */
650 		if (sc->eep_rev >= AR_EEP_MINOR_VER_2)
651 			ht40inc = modal->ht40PowerIncForPdadc;
652 		else
653 			ht40inc = AR_HT40_POWER_INC_FOR_PDADC;
654 		for (i = 0; i < nitems(tpow_ht40); i++)
655 			power[ATHN_POWER_HT40(i)] = tpow_ht40[i] + ht40inc;
656 		power[ATHN_POWER_OFDM_DUP] = tpow_ht40[0];
657 		power[ATHN_POWER_CCK_DUP ] = tpow_ht40[0] + cckinc;
658 		power[ATHN_POWER_OFDM_EXT] = tpow_ofdm_ext[0];
659 		if (IEEE80211_IS_CHAN_2GHZ(c))
660 			power[ATHN_POWER_CCK_EXT] = tpow_cck_ext[0] + cckinc;
661 	}
662 #endif
663 
664 	if (AR_SREV_9280_10_OR_LATER(sc)) {
665 		if (sc->eep_rev >= AR_EEP_MINOR_VER_21)
666 			pwroff = eep->baseEepHeader.pwrTableOffset;
667 		else
668 			pwroff = AR_PWR_TABLE_OFFSET_DB;
669 		for (i = 0; i < ATHN_POWER_COUNT; i++)
670 			power[i] -= pwroff * 2;	/* In half dB. */
671 	}
672 	for (i = 0; i < ATHN_POWER_COUNT; i++) {
673 		if (power[i] > AR_MAX_RATE_POWER)
674 			power[i] = AR_MAX_RATE_POWER;
675 	}
676 
677 	/* Write transmit power values to hardware. */
678 	ar5008_write_txpower(sc, power);
679 
680 	/*
681 	 * Write transmit power substraction for dynamic chain changing
682 	 * and per-packet transmit power.
683 	 */
684 	AR_WRITE(sc, AR_PHY_POWER_TX_SUB,
685 	    (modal->pwrDecreaseFor3Chain & 0x3f) << 6 |
686 	    (modal->pwrDecreaseFor2Chain & 0x3f));
687 }
688 
689 void
690 ar5416_spur_mitigate(struct athn_softc *sc, struct ieee80211_channel *c,
691     struct ieee80211_channel *extc)
692 {
693 	const struct ar_spur_chan *spurchans;
694 	int i, spur, bin, spur_delta_phase, spur_freq_sd;
695 
696 	spurchans = sc->ops.get_spur_chans(sc, IEEE80211_IS_CHAN_2GHZ(c));
697 	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
698 		spur = spurchans[i].spurChan;
699 		if (spur == AR_NO_SPUR)
700 			return; /* XXX disable if it was enabled! */
701 		spur -= c->ic_freq * 10;
702 		/* Verify range +/-9.5MHz */
703 		if (abs(spur) < 95)
704 			break;
705 	}
706 	if (i == AR_EEPROM_MODAL_SPURS)
707 		return; /* XXX disable if it was enabled! */
708 	DPRINTFN(2, ("enabling spur mitigation\n"));
709 
710 	AR_SETBITS(sc, AR_PHY_TIMING_CTRL4_0,
711 	    AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
712 	    AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
713 	    AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
714 	    AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
715 
716 	AR_WRITE(sc, AR_PHY_SPUR_REG,
717 	    AR_PHY_SPUR_REG_MASK_RATE_CNTL |
718 	    AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
719 	    AR_PHY_SPUR_REG_MASK_RATE_SELECT |
720 	    AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
721 	    SM(AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, AR_SPUR_RSSI_THRESH));
722 
723 	spur_delta_phase = (spur * 524288) / 100;
724 	if (IEEE80211_IS_CHAN_2GHZ(c))
725 		spur_freq_sd = (spur * 2048) / 440;
726 	else
727 		spur_freq_sd = (spur * 2048) / 400;
728 
729 	AR_WRITE(sc, AR_PHY_TIMING11,
730 	    AR_PHY_TIMING11_USE_SPUR_IN_AGC |
731 	    SM(AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd) |
732 	    SM(AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase));
733 
734 	bin = spur * 32;
735 	ar5008_set_viterbi_mask(sc, bin);
736 }
737 
738 uint8_t
739 ar5416_reverse_bits(uint8_t v, int nbits)
740 {
741 	KASSERT(nbits <= 8);
742 	v = ((v >> 1) & 0x55) | ((v & 0x55) << 1);
743 	v = ((v >> 2) & 0x33) | ((v & 0x33) << 2);
744 	v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4);
745 	return (v >> (8 - nbits));
746 }
747 
748 uint8_t
749 ar5416_get_rf_rev(struct athn_softc *sc)
750 {
751 	uint8_t rev, reg;
752 	int i;
753 
754 	/* Allow access to analog chips. */
755 	AR_WRITE(sc, AR_PHY(0), 0x00000007);
756 
757 	AR_WRITE(sc, AR_PHY(0x36), 0x00007058);
758 	for (i = 0; i < 8; i++)
759 		AR_WRITE(sc, AR_PHY(0x20), 0x00010000);
760 	reg = (AR_READ(sc, AR_PHY(256)) >> 24) & 0xff;
761 	reg = (reg & 0xf0) >> 4 | (reg & 0x0f) << 4;
762 
763 	rev = ar5416_reverse_bits(reg, 8);
764 	if ((rev & AR_RADIO_SREV_MAJOR) == 0)
765 		rev = AR_RAD5133_SREV_MAJOR;
766 	return (rev);
767 }
768 
769 /*
770  * Replace bits "off" to "off+nbits-1" in column "col" with the specified
771  * value.
772  */
773 void
774 ar5416_rw_rfbits(uint32_t *buf, int col, int off, uint32_t val, int nbits)
775 {
776 	int idx, bit;
777 
778 	KASSERT(off >= 1 && col < 4 && nbits <= 32);
779 
780 	off--;	/* Starts at 1. */
781 	while (nbits-- > 0) {
782 		idx = off / 8;
783 		bit = off % 8;
784 		buf[idx] &= ~(1 << (bit + col * 8));
785 		buf[idx] |= ((val >> nbits) & 1) << (bit + col * 8);
786 		off++;
787 	}
788 }
789 
790 /*
791  * Overwrite db and ob based on ROM settings.
792  */
793 void
794 ar5416_rw_bank6tpc(struct athn_softc *sc, struct ieee80211_channel *c,
795     uint32_t *rwbank6tpc)
796 {
797 	const struct ar5416_eeprom *eep = sc->eep;
798 	const struct ar5416_modal_eep_header *modal;
799 
800 	if (IEEE80211_IS_CHAN_5GHZ(c)) {
801 		modal = &eep->modalHeader[0];
802 		/* 5GHz db in column 0, bits [200-202]. */
803 		ar5416_rw_rfbits(rwbank6tpc, 0, 200, modal->db, 3);
804 		/* 5GHz ob in column 0, bits [203-205]. */
805 		ar5416_rw_rfbits(rwbank6tpc, 0, 203, modal->ob, 3);
806 	} else {
807 		modal = &eep->modalHeader[1];
808 		/* 2GHz db in column 0, bits [194-196]. */
809 		ar5416_rw_rfbits(rwbank6tpc, 0, 194, modal->db, 3);
810 		/* 2GHz ob in column 0, bits [197-199]. */
811 		ar5416_rw_rfbits(rwbank6tpc, 0, 197, modal->ob, 3);
812 	}
813 }
814 
815 /*
816  * Program analog RF.
817  */
818 void
819 ar5416_rf_reset(struct athn_softc *sc, struct ieee80211_channel *c)
820 {
821 	const uint32_t *bank6tpc;
822 	int i;
823 
824 	/* Bank 0. */
825 	AR_WRITE(sc, 0x98b0, 0x1e5795e5);
826 	AR_WRITE(sc, 0x98e0, 0x02008020);
827 
828 	/* Bank 1. */
829 	AR_WRITE(sc, 0x98b0, 0x02108421);
830 	AR_WRITE(sc, 0x98ec, 0x00000008);
831 
832 	/* Bank 2. */
833 	AR_WRITE(sc, 0x98b0, 0x0e73ff17);
834 	AR_WRITE(sc, 0x98e0, 0x00000420);
835 
836 	/* Bank 3. */
837 	if (IEEE80211_IS_CHAN_5GHZ(c))
838 		AR_WRITE(sc, 0x98f0, 0x01400018);
839 	else
840 		AR_WRITE(sc, 0x98f0, 0x01c00018);
841 
842 	/* Select the Bank 6 TPC values to use. */
843 	if (AR_SREV_9160_10_OR_LATER(sc))
844 		bank6tpc = ar9160_bank6tpc_vals;
845 	else
846 		bank6tpc = ar5416_bank6tpc_vals;
847 	if (sc->eep_rev >= AR_EEP_MINOR_VER_2) {
848 		uint32_t *rwbank6tpc = sc->rwbuf;
849 
850 		/* Copy values from .rodata to writable buffer. */
851 		memcpy(rwbank6tpc, bank6tpc, 32 * sizeof(uint32_t));
852 		ar5416_rw_bank6tpc(sc, c, rwbank6tpc);
853 		bank6tpc = rwbank6tpc;
854 	}
855 	/* Bank 6 TPC. */
856 	for (i = 0; i < 32; i++)
857 		AR_WRITE(sc, 0x989c, bank6tpc[i]);
858 	if (IEEE80211_IS_CHAN_5GHZ(c))
859 		AR_WRITE(sc, 0x98d0, 0x0000000f);
860 	else
861 		AR_WRITE(sc, 0x98d0, 0x0010000f);
862 
863 	/* Bank 7. */
864 	AR_WRITE(sc, 0x989c, 0x00000500);
865 	AR_WRITE(sc, 0x989c, 0x00000800);
866 	AR_WRITE(sc, 0x98cc, 0x0000000e);
867 }
868 
869 void
870 ar5416_reset_bb_gain(struct athn_softc *sc, struct ieee80211_channel *c)
871 {
872 	const uint32_t *pvals;
873 	int i;
874 
875 	if (IEEE80211_IS_CHAN_2GHZ(c))
876 		pvals = ar5416_bb_rfgain_vals_2g;
877 	else
878 		pvals = ar5416_bb_rfgain_vals_5g;
879 	for (i = 0; i < 64; i++)
880 		AR_WRITE(sc, AR_PHY_BB_RFGAIN(i), pvals[i]);
881 }
882 
883 /*
884  * Fix orientation sensitivity issue on AR5416/2GHz by increasing
885  * rf_pwd_icsyndiv.
886  */
887 void
888 ar5416_force_bias(struct athn_softc *sc, struct ieee80211_channel *c)
889 {
890 	uint32_t *rwbank6 = sc->rwbuf;
891 	uint8_t bias;
892 	int i;
893 
894 	KASSERT(IEEE80211_IS_CHAN_2GHZ(c));
895 
896 	/* Copy values from .rodata to writable buffer. */
897 	memcpy(rwbank6, ar5416_bank6_vals, sizeof(ar5416_bank6_vals));
898 
899 	if (c->ic_freq < 2412)
900 		bias = 0;
901 	else if (c->ic_freq < 2422)
902 		bias = 1;
903 	else
904 		bias = 2;
905 	ar5416_reverse_bits(bias, 3);
906 
907 	/* Overwrite "rf_pwd_icsyndiv" (column 3, bits [181-183].) */
908 	ar5416_rw_rfbits(rwbank6, 3, 181, bias, 3);
909 
910 	/* Write Bank 6. */
911 	for (i = 0; i < 32; i++)
912 		AR_WRITE(sc, 0x989c, rwbank6[i]);
913 	AR_WRITE(sc, 0x98d0, 0x0010000f);
914 }
915 
916 /*
917  * Overwrite XPA bias level based on ROM setting.
918  */
919 void
920 ar9160_rw_addac(struct athn_softc *sc, struct ieee80211_channel *c,
921     uint32_t *addac)
922 {
923 	struct ar5416_eeprom *eep = sc->eep;
924 	struct ar5416_modal_eep_header *modal;
925 	uint8_t fbin, bias;
926 	int i;
927 
928 	/* XXX xpaBiasLvlFreq values have not been endian-swapped? */
929 
930 	/* Get the XPA bias level to use for the specified channel. */
931 	modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)];
932 	if (modal->xpaBiasLvl == 0xff) {
933 		bias = modal->xpaBiasLvlFreq[0] >> 14;
934 		fbin = athn_chan2fbin(c);
935 		for (i = 1; i < 3; i++) {
936 			if (modal->xpaBiasLvlFreq[i] == 0)
937 				break;
938 			if ((modal->xpaBiasLvlFreq[i] & 0xff) < fbin)
939 				break;
940 			bias = modal->xpaBiasLvlFreq[i] >> 14;
941 		}
942 	} else
943 		bias = modal->xpaBiasLvl & 0x3;
944 
945 	bias = ar5416_reverse_bits(bias, 2);	/* Put in host bit-order. */
946 	DPRINTFN(4, ("bias level=%d\n", bias));
947 	if (IEEE80211_IS_CHAN_2GHZ(c))
948 		ar5416_rw_rfbits(addac, 0, 60, bias, 2);
949 	else
950 		ar5416_rw_rfbits(addac, 0, 55, bias, 2);
951 }
952 
953 void
954 ar5416_reset_addac(struct athn_softc *sc, struct ieee80211_channel *c)
955 {
956 	const struct athn_addac *addac = sc->addac;
957 	const uint32_t *pvals;
958 	int i;
959 
960 	if (AR_SREV_9160(sc) && sc->eep_rev >= AR_EEP_MINOR_VER_7) {
961 		uint32_t *rwaddac = sc->rwbuf;
962 
963 		/* Copy values from .rodata to writable buffer. */
964 		memcpy(rwaddac, addac->vals, addac->nvals * sizeof(uint32_t));
965 		ar9160_rw_addac(sc, c, rwaddac);
966 		pvals = rwaddac;
967 	} else
968 		pvals = addac->vals;
969 	for (i = 0; i < addac->nvals; i++)
970 		AR_WRITE(sc, 0x989c, pvals[i]);
971 	AR_WRITE(sc, 0x98cc, 0);	/* Finalize. */
972 }
973