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