ar5212_reset.c revision 185380
1/*
2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2008 Atheros Communications, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 * $Id: ar5212_reset.c,v 1.20 2008/11/27 22:30:00 sam Exp $
18 */
19#include "opt_ah.h"
20
21#ifdef AH_SUPPORT_AR5212
22
23#include "ah.h"
24#include "ah_internal.h"
25#include "ah_devid.h"
26
27#include "ar5212/ar5212.h"
28#include "ar5212/ar5212reg.h"
29#include "ar5212/ar5212phy.h"
30#ifdef AH_SUPPORT_AR5311
31#include "ar5212/ar5311reg.h"
32#endif
33
34#include "ah_eeprom_v3.h"
35
36/* Additional Time delay to wait after activiting the Base band */
37#define BASE_ACTIVATE_DELAY	100	/* 100 usec */
38#define PLL_SETTLE_DELAY	300	/* 300 usec */
39
40static HAL_BOOL ar5212SetResetReg(struct ath_hal *, uint32_t resetMask);
41/* NB: public for 5312 use */
42HAL_BOOL	ar5212IsSpurChannel(struct ath_hal *, HAL_CHANNEL *);
43HAL_BOOL	ar5212ChannelChange(struct ath_hal *, HAL_CHANNEL *);
44int16_t		ar5212GetNf(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
45HAL_BOOL	ar5212SetBoardValues(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
46void		ar5212SetDeltaSlope(struct ath_hal *, HAL_CHANNEL *);
47HAL_BOOL	ar5212SetTransmitPower(struct ath_hal *ah,
48		HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain);
49static HAL_BOOL ar5212SetRateTable(struct ath_hal *,
50		   HAL_CHANNEL *, int16_t tpcScaleReduction, int16_t powerLimit,
51		   HAL_BOOL commit, int16_t *minPower, int16_t *maxPower);
52static void ar5212CorrectGainDelta(struct ath_hal *, int twiceOfdmCckDelta);
53static void ar5212GetTargetPowers(struct ath_hal *, HAL_CHANNEL *,
54		   const TRGT_POWER_INFO *pPowerInfo, uint16_t numChannels,
55		   TRGT_POWER_INFO *pNewPower);
56static uint16_t ar5212GetMaxEdgePower(uint16_t channel,
57		   const RD_EDGES_POWER  *pRdEdgesPower);
58void		ar5212SetRateDurationTable(struct ath_hal *, HAL_CHANNEL *);
59void		ar5212SetIFSTiming(struct ath_hal *, HAL_CHANNEL *);
60
61/* NB: public for RF backend use */
62void		ar5212GetLowerUpperValues(uint16_t value,
63		   uint16_t *pList, uint16_t listSize,
64		   uint16_t *pLowerValue, uint16_t *pUpperValue);
65void		ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32,
66		   uint32_t numBits, uint32_t firstBit, uint32_t column);
67
68static int
69write_common(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
70	HAL_BOOL bChannelChange, int writes)
71{
72#define IS_NO_RESET_TIMER_ADDR(x)                      \
73    ( (((x) >= AR_BEACON) && ((x) <= AR_CFP_DUR)) || \
74      (((x) >= AR_SLEEP1) && ((x) <= AR_SLEEP3)))
75#define	V(r, c)	(ia)->data[((r)*(ia)->cols) + (c)]
76	int r;
77
78	/* Write Common Array Parameters */
79	for (r = 0; r < ia->rows; r++) {
80		uint32_t reg = V(r, 0);
81		/* XXX timer/beacon setup registers? */
82		/* On channel change, don't reset the PCU registers */
83		if (!(bChannelChange && IS_NO_RESET_TIMER_ADDR(reg))) {
84			OS_REG_WRITE(ah, reg, V(r, 1));
85			DMA_YIELD(writes);
86		}
87	}
88	return writes;
89#undef IS_NO_RESET_TIMER_ADDR
90#undef V
91}
92
93#define IS_DISABLE_FAST_ADC_CHAN(x) (((x) == 2462) || ((x) == 2467))
94
95/*
96 * Places the device in and out of reset and then places sane
97 * values in the registers based on EEPROM config, initialization
98 * vectors (as determined by the mode), and station configuration
99 *
100 * bChannelChange is used to preserve DMA/PCU registers across
101 * a HW Reset during channel change.
102 */
103HAL_BOOL
104ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
105	HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status)
106{
107#define	N(a)	(sizeof (a) / sizeof (a[0]))
108#define	FAIL(_code)	do { ecode = _code; goto bad; } while (0)
109	struct ath_hal_5212 *ahp = AH5212(ah);
110	HAL_CHANNEL_INTERNAL *ichan = AH_NULL;
111	const HAL_EEPROM *ee;
112	uint32_t softLedCfg, softLedState;
113	uint32_t saveFrameSeqCount, saveDefAntenna, saveLedState;
114	uint32_t macStaId1, synthDelay, txFrm2TxDStart;
115	uint16_t rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL];
116	int16_t cckOfdmPwrDelta = 0;
117	u_int modesIndex, freqIndex;
118	HAL_STATUS ecode;
119	int i, regWrites;
120	uint32_t testReg, powerVal;
121	int8_t twiceAntennaGain, twiceAntennaReduction;
122	uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow;
123	HAL_BOOL isBmode = AH_FALSE;
124	HAL_BOOL ichan_isBmode = AH_FALSE;
125
126	HALASSERT(ah->ah_magic == AR5212_MAGIC);
127	ee = AH_PRIVATE(ah)->ah_eeprom;
128
129	OS_MARK(ah, AH_MARK_RESET, bChannelChange);
130#define	IS(_c,_f)	(((_c)->channelFlags & _f) || 0)
131	if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan, CHANNEL_5GHZ)) == 0) {
132		HALDEBUG(ah, HAL_DEBUG_ANY,
133		    "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
134		    __func__, chan->channel, chan->channelFlags);
135		FAIL(HAL_EINVAL);
136	}
137	if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK)) == 0) {
138		HALDEBUG(ah, HAL_DEBUG_ANY,
139		    "%s: invalid channel %u/0x%x; not marked as OFDM or CCK\n",
140		    __func__, chan->channel, chan->channelFlags);
141		FAIL(HAL_EINVAL);
142	}
143#undef IS
144
145	/* Bring out of sleep mode */
146	if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
147		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip did not wakeup\n",
148		    __func__);
149		FAIL(HAL_EIO);
150	}
151
152	/*
153	 * Map public channel to private.
154	 */
155	ichan = ath_hal_checkchannel(ah, chan);
156	if (ichan == AH_NULL) {
157		HALDEBUG(ah, HAL_DEBUG_ANY,
158		    "%s: invalid channel %u/0x%x; no mapping\n",
159		    __func__, chan->channel, chan->channelFlags);
160		FAIL(HAL_EINVAL);
161	}
162	switch (opmode) {
163	case HAL_M_STA:
164	case HAL_M_IBSS:
165	case HAL_M_HOSTAP:
166	case HAL_M_MONITOR:
167		break;
168	default:
169		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n",
170		    __func__, opmode);
171		FAIL(HAL_EINVAL);
172		break;
173	}
174	HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3);
175
176	SAVE_CCK(ah, ichan, ichan_isBmode);
177	SAVE_CCK(ah, chan, isBmode);
178
179	/* Preserve certain DMA hardware registers on a channel change */
180	if (bChannelChange) {
181		/*
182		 * On Venice, the TSF is almost preserved across a reset;
183		 * it requires doubling writes to the RESET_TSF
184		 * bit in the AR_BEACON register; it also has the quirk
185		 * of the TSF going back in time on the station (station
186		 * latches onto the last beacon's tsf during a reset 50%
187		 * of the times); the latter is not a problem for adhoc
188		 * stations since as long as the TSF is behind, it will
189		 * get resynchronized on receiving the next beacon; the
190		 * TSF going backwards in time could be a problem for the
191		 * sleep operation (supported on infrastructure stations
192		 * only) - the best and most general fix for this situation
193		 * is to resynchronize the various sleep/beacon timers on
194		 * the receipt of the next beacon i.e. when the TSF itself
195		 * gets resynchronized to the AP's TSF - power save is
196		 * needed to be temporarily disabled until that time
197		 *
198		 * Need to save the sequence number to restore it after
199		 * the reset!
200		 */
201		saveFrameSeqCount = OS_REG_READ(ah, AR_D_SEQNUM);
202	} else
203		saveFrameSeqCount = 0;		/* NB: silence compiler */
204#if 0
205	/*
206	 * XXX disable for now; this appears to sometimes cause OFDM
207	 * XXX timing error floods when ani is enabled and bg scanning
208	 * XXX kicks in
209	 */
210	/* If the channel change is across the same mode - perform a fast channel change */
211	if (IS_2413(ah) || IS_5413(ah)) {
212		/*
213		 * Fast channel change can only be used when:
214		 *  -channel change requested - so it's not the initial reset.
215		 *  -it's not a change to the current channel -
216		 *	often called when switching modes on a channel
217		 *  -the modes of the previous and requested channel are the
218		 *	same
219		 * XXX opmode shouldn't change either?
220		 */
221		if (bChannelChange &&
222		    (AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
223		    (chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) &&
224		    ((chan->channelFlags & CHANNEL_ALL) ==
225		     (AH_PRIVATE(ah)->ah_curchan->channelFlags & CHANNEL_ALL))) {
226			if (ar5212ChannelChange(ah, chan)) {
227				/* If ChannelChange completed - skip the rest of reset */
228				/* XXX ani? */
229				return AH_TRUE;
230			}
231		}
232	}
233#endif
234	/*
235	 * Preserve the antenna on a channel change
236	 */
237	saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
238	if (saveDefAntenna == 0)		/* XXX magic constants */
239		saveDefAntenna = 1;
240
241	/* Save hardware flag before chip reset clears the register */
242	macStaId1 = OS_REG_READ(ah, AR_STA_ID1) &
243		(AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT);
244
245	/* Save led state from pci config register */
246	saveLedState = OS_REG_READ(ah, AR_PCICFG) &
247		(AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE | AR_PCICFG_LEDBLINK |
248		 AR_PCICFG_LEDSLOW);
249	softLedCfg = OS_REG_READ(ah, AR_GPIOCR);
250	softLedState = OS_REG_READ(ah, AR_GPIODO);
251
252	ar5212RestoreClock(ah, opmode);		/* move to refclk operation */
253
254	/*
255	 * Adjust gain parameters before reset if
256	 * there's an outstanding gain updated.
257	 */
258	(void) ar5212GetRfgain(ah);
259
260	if (!ar5212ChipReset(ah, chan)) {
261		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
262		FAIL(HAL_EIO);
263	}
264
265	/* Setup the indices for the next set of register array writes */
266	switch (chan->channelFlags & CHANNEL_ALL) {
267	case CHANNEL_A:
268		modesIndex = 1;
269		freqIndex  = 1;
270		break;
271	case CHANNEL_T:
272		modesIndex = 2;
273		freqIndex  = 1;
274		break;
275	case CHANNEL_B:
276		modesIndex = 3;
277		freqIndex  = 2;
278		break;
279	case CHANNEL_PUREG:
280		modesIndex = 4;
281		freqIndex  = 2;
282		break;
283	case CHANNEL_108G:
284		modesIndex = 5;
285		freqIndex  = 2;
286		break;
287	default:
288		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
289		    __func__, chan->channelFlags);
290		FAIL(HAL_EINVAL);
291	}
292
293	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
294
295	/* Set correct Baseband to analog shift setting to access analog chips. */
296	OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
297
298	regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 0);
299	regWrites = write_common(ah, &ahp->ah_ini_common, bChannelChange,
300		regWrites);
301	ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites);
302
303	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
304
305	if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) {
306		ar5212SetIFSTiming(ah, chan);
307		if (IS_5413(ah)) {
308			/*
309			 * Force window_length for 1/2 and 1/4 rate channels,
310			 * the ini file sets this to zero otherwise.
311			 */
312			OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
313				AR_PHY_FRAME_CTL_WINLEN, 3);
314		}
315	}
316
317	/* Overwrite INI values for revised chipsets */
318	if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) {
319		/* ADC_CTL */
320		OS_REG_WRITE(ah, AR_PHY_ADC_CTL,
321			SM(2, AR_PHY_ADC_CTL_OFF_INBUFGAIN) |
322			SM(2, AR_PHY_ADC_CTL_ON_INBUFGAIN) |
323			AR_PHY_ADC_CTL_OFF_PWDDAC |
324			AR_PHY_ADC_CTL_OFF_PWDADC);
325
326		/* TX_PWR_ADJ */
327		if (chan->channel == 2484) {
328			cckOfdmPwrDelta = SCALE_OC_DELTA(
329			    ee->ee_cckOfdmPwrDelta -
330			    ee->ee_scaledCh14FilterCckDelta);
331		} else {
332			cckOfdmPwrDelta = SCALE_OC_DELTA(
333			    ee->ee_cckOfdmPwrDelta);
334		}
335
336		if (IS_CHAN_G(chan)) {
337		    OS_REG_WRITE(ah, AR_PHY_TXPWRADJ,
338			SM((ee->ee_cckOfdmPwrDelta*-1),
339			    AR_PHY_TXPWRADJ_CCK_GAIN_DELTA) |
340			SM((cckOfdmPwrDelta*-1),
341			    AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX));
342		} else {
343			OS_REG_WRITE(ah, AR_PHY_TXPWRADJ, 0);
344		}
345
346		/* Add barker RSSI thresh enable as disabled */
347		OS_REG_CLR_BIT(ah, AR_PHY_DAG_CTRLCCK,
348			AR_PHY_DAG_CTRLCCK_EN_RSSI_THR);
349		OS_REG_RMW_FIELD(ah, AR_PHY_DAG_CTRLCCK,
350			AR_PHY_DAG_CTRLCCK_RSSI_THR, 2);
351
352		/* Set the mute mask to the correct default */
353		OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F);
354	}
355
356	if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) {
357		/* Clear reg to alllow RX_CLEAR line debug */
358		OS_REG_WRITE(ah, AR_PHY_BLUETOOTH,  0);
359	}
360	if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) {
361#ifdef notyet
362		/* Enable burst prefetch for the data queues */
363		OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... );
364		/* Enable double-buffering */
365		OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS);
366#endif
367	}
368
369	/* Set ADC/DAC select values */
370	OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
371
372	if (IS_5413(ah) || IS_2417(ah)) {
373		uint32_t newReg=1;
374		if (IS_DISABLE_FAST_ADC_CHAN(chan->channel))
375			newReg = 0;
376		/* As it's a clock changing register, only write when the value needs to be changed */
377		if (OS_REG_READ(ah, AR_PHY_FAST_ADC) != newReg)
378			OS_REG_WRITE(ah, AR_PHY_FAST_ADC, newReg);
379	}
380
381	/* Setup the transmit power values. */
382	if (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) {
383		HALDEBUG(ah, HAL_DEBUG_ANY,
384		    "%s: error init'ing transmit power\n", __func__);
385		FAIL(HAL_EIO);
386	}
387
388	/* Write the analog registers */
389	if (!ahp->ah_rfHal->setRfRegs(ah, ichan, modesIndex, rfXpdGain)) {
390		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5212SetRfRegs failed\n",
391		    __func__);
392		FAIL(HAL_EIO);
393	}
394
395	/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
396	if (IS_CHAN_OFDM(chan)) {
397		if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) &&
398		    (!IS_CHAN_B(chan)))
399			ar5212SetSpurMitigation(ah, ichan);
400		ar5212SetDeltaSlope(ah, chan);
401	}
402
403	/* Setup board specific options for EEPROM version 3 */
404	if (!ar5212SetBoardValues(ah, ichan)) {
405		HALDEBUG(ah, HAL_DEBUG_ANY,
406		    "%s: error setting board options\n", __func__);
407		FAIL(HAL_EIO);
408	}
409
410	/* Restore certain DMA hardware registers on a channel change */
411	if (bChannelChange)
412		OS_REG_WRITE(ah, AR_D_SEQNUM, saveFrameSeqCount);
413
414	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
415
416	OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
417	OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
418		| macStaId1
419		| AR_STA_ID1_RTS_USE_DEF
420		| ahp->ah_staId1Defaults
421	);
422	ar5212SetOperatingMode(ah, opmode);
423
424	/* Set Venice BSSID mask according to current state */
425	OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
426	OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
427
428	/* Restore previous led state */
429	OS_REG_WRITE(ah, AR_PCICFG, OS_REG_READ(ah, AR_PCICFG) | saveLedState);
430
431	/* Restore soft Led state to GPIO */
432	OS_REG_WRITE(ah, AR_GPIOCR, softLedCfg);
433	OS_REG_WRITE(ah, AR_GPIODO, softLedState);
434
435	/* Restore previous antenna */
436	OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
437
438	/* then our BSSID */
439	OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
440	OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4));
441
442	/* Restore bmiss rssi & count thresholds */
443	OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr);
444
445	OS_REG_WRITE(ah, AR_ISR, ~0);		/* cleared on write */
446
447	if (!ar5212SetChannel(ah, ichan))
448		FAIL(HAL_EIO);
449
450	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
451
452	ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1);
453
454	ar5212SetRateDurationTable(ah, chan);
455
456	/* Set Tx frame start to tx data start delay */
457	if (IS_RAD5112_ANY(ah) &&
458	    (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) ||
459	     IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) {
460		txFrm2TxDStart =
461			(IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) ?
462					TX_FRAME_D_START_HALF_RATE:
463					TX_FRAME_D_START_QUARTER_RATE;
464		OS_REG_RMW_FIELD(ah, AR_PHY_TX_CTL,
465			AR_PHY_TX_FRAME_TO_TX_DATA_START, txFrm2TxDStart);
466	}
467
468	/*
469	 * Setup fast diversity.
470	 * Fast diversity can be enabled or disabled via regadd.txt.
471	 * Default is enabled.
472	 * For reference,
473	 *    Disable: reg        val
474	 *             0x00009860 0x00009d18 (if 11a / 11g, else no change)
475	 *             0x00009970 0x192bb514
476	 *             0x0000a208 0xd03e4648
477	 *
478	 *    Enable:  0x00009860 0x00009d10 (if 11a / 11g, else no change)
479	 *             0x00009970 0x192fb514
480	 *             0x0000a208 0xd03e6788
481	 */
482
483	/* XXX Setup pre PHY ENABLE EAR additions */
484	/*
485	 * Wait for the frequency synth to settle (synth goes on
486	 * via AR_PHY_ACTIVE_EN).  Read the phy active delay register.
487	 * Value is in 100ns increments.
488	 */
489	synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
490	if (IS_CHAN_CCK(chan)) {
491		synthDelay = (4 * synthDelay) / 22;
492	} else {
493		synthDelay /= 10;
494	}
495
496	/* Activate the PHY (includes baseband activate and synthesizer on) */
497	OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
498
499	/*
500	 * There is an issue if the AP starts the calibration before
501	 * the base band timeout completes.  This could result in the
502	 * rx_clear false triggering.  As a workaround we add delay an
503	 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
504	 * does not happen.
505	 */
506	if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
507		OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);
508	} else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
509		OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);
510	} else {
511		OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
512	}
513
514	/*
515	 * The udelay method is not reliable with notebooks.
516	 * Need to check to see if the baseband is ready
517	 */
518	testReg = OS_REG_READ(ah, AR_PHY_TESTCTRL);
519	/* Selects the Tx hold */
520	OS_REG_WRITE(ah, AR_PHY_TESTCTRL, AR_PHY_TESTCTRL_TXHOLD);
521	i = 0;
522	while ((i++ < 20) &&
523	       (OS_REG_READ(ah, 0x9c24) & 0x10)) /* test if baseband not ready */		OS_DELAY(200);
524	OS_REG_WRITE(ah, AR_PHY_TESTCTRL, testReg);
525
526	/* Calibrate the AGC and start a NF calculation */
527	OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
528		  OS_REG_READ(ah, AR_PHY_AGC_CONTROL)
529		| AR_PHY_AGC_CONTROL_CAL
530		| AR_PHY_AGC_CONTROL_NF);
531
532	if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {
533		/* Start IQ calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
534		OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
535			AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
536			INIT_IQCAL_LOG_COUNT_MAX);
537		OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
538			AR_PHY_TIMING_CTRL4_DO_IQCAL);
539		ahp->ah_bIQCalibration = IQ_CAL_RUNNING;
540	} else
541		ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
542
543	/* Setup compression registers */
544	ar5212SetCompRegs(ah);
545
546	/* Set 1:1 QCU to DCU mapping for all queues */
547	for (i = 0; i < AR_NUM_DCU; i++)
548		OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
549
550	ahp->ah_intrTxqs = 0;
551	for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++)
552		ar5212ResetTxQueue(ah, i);
553
554	/*
555	 * Setup interrupt handling.  Note that ar5212ResetTxQueue
556	 * manipulates the secondary IMR's as queues are enabled
557	 * and disabled.  This is done with RMW ops to insure the
558	 * settings we make here are preserved.
559	 */
560	ahp->ah_maskReg = AR_IMR_TXOK | AR_IMR_TXERR | AR_IMR_TXURN
561			| AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXORN
562			| AR_IMR_HIUERR
563			;
564	if (opmode == HAL_M_HOSTAP)
565		ahp->ah_maskReg |= AR_IMR_MIB;
566	OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
567	/* Enable bus errors that are OR'd to set the HIUERR bit */
568	OS_REG_WRITE(ah, AR_IMR_S2,
569		OS_REG_READ(ah, AR_IMR_S2)
570		| AR_IMR_S2_MCABT | AR_IMR_S2_SSERR | AR_IMR_S2_DPERR);
571
572	if (AH_PRIVATE(ah)->ah_rfkillEnabled)
573		ar5212EnableRfKill(ah);
574
575	if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
576		HALDEBUG(ah, HAL_DEBUG_ANY,
577		    "%s: offset calibration failed to complete in 1ms;"
578		    " noisy environment?\n", __func__);
579	}
580
581	/*
582	 * Set clocks back to 32kHz if they had been using refClk, then
583	 * use an external 32kHz crystal when sleeping, if one exists.
584	 */
585	ar5212SetupClock(ah, opmode);
586
587	/*
588	 * Writing to AR_BEACON will start timers. Hence it should
589	 * be the last register to be written. Do not reset tsf, do
590	 * not enable beacons at this point, but preserve other values
591	 * like beaconInterval.
592	 */
593	OS_REG_WRITE(ah, AR_BEACON,
594		(OS_REG_READ(ah, AR_BEACON) &~ (AR_BEACON_EN | AR_BEACON_RESET_TSF)));
595
596	/* XXX Setup post reset EAR additions */
597
598	/* QoS support */
599	if (AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE ||
600	    (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE &&
601	     AH_PRIVATE(ah)->ah_macRev >= AR_SREV_GRIFFIN_LITE)) {
602		OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa);	/* XXX magic */
603		OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210);	/* XXX magic */
604	}
605
606	/* Turn on NOACK Support for QoS packets */
607	OS_REG_WRITE(ah, AR_NOACK,
608		SM(2, AR_NOACK_2BIT_VALUE) |
609		SM(5, AR_NOACK_BIT_OFFSET) |
610		SM(0, AR_NOACK_BYTE_OFFSET));
611
612	/* Get Antenna Gain reduction */
613	if (IS_CHAN_5GHZ(chan)) {
614		ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_5, &twiceAntennaGain);
615	} else {
616		ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_2, &twiceAntennaGain);
617	}
618	twiceAntennaReduction =
619		ath_hal_getantennareduction(ah, chan, twiceAntennaGain);
620
621	/* TPC for self-generated frames */
622
623	ackTpcPow = MS(ahp->ah_macTPC, AR_TPC_ACK);
624	if ((ackTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)
625		ackTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;
626
627	if (ackTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))
628		ackTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)
629			+ ahp->ah_txPowerIndexOffset;
630
631	ctsTpcPow = MS(ahp->ah_macTPC, AR_TPC_CTS);
632	if ((ctsTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)
633		ctsTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;
634
635	if (ctsTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))
636		ctsTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)
637			+ ahp->ah_txPowerIndexOffset;
638
639	chirpTpcPow = MS(ahp->ah_macTPC, AR_TPC_CHIRP);
640	if ((chirpTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)
641		chirpTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;
642
643	if (chirpTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))
644		chirpTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)
645			+ ahp->ah_txPowerIndexOffset;
646
647	if (ackTpcPow > 63)
648		ackTpcPow = 63;
649	if (ctsTpcPow > 63)
650		ctsTpcPow = 63;
651	if (chirpTpcPow > 63)
652		chirpTpcPow = 63;
653
654	powerVal = SM(ackTpcPow, AR_TPC_ACK) |
655		SM(ctsTpcPow, AR_TPC_CTS) |
656		SM(chirpTpcPow, AR_TPC_CHIRP);
657
658	OS_REG_WRITE(ah, AR_TPC, powerVal);
659
660	/* Restore user-specified settings */
661	if (ahp->ah_miscMode != 0)
662		OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
663	if (ahp->ah_sifstime != (u_int) -1)
664		ar5212SetSifsTime(ah, ahp->ah_sifstime);
665	if (ahp->ah_slottime != (u_int) -1)
666		ar5212SetSlotTime(ah, ahp->ah_slottime);
667	if (ahp->ah_acktimeout != (u_int) -1)
668		ar5212SetAckTimeout(ah, ahp->ah_acktimeout);
669	if (ahp->ah_ctstimeout != (u_int) -1)
670		ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout);
671	if (AH_PRIVATE(ah)->ah_diagreg != 0)
672		OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
673
674	AH_PRIVATE(ah)->ah_opmode = opmode;	/* record operating mode */
675
676	if (bChannelChange) {
677		if (!(ichan->privFlags & CHANNEL_DFS))
678			ichan->privFlags &= ~CHANNEL_INTERFERENCE;
679		chan->channelFlags = ichan->channelFlags;
680		chan->privFlags = ichan->privFlags;
681		chan->maxRegTxPower = ichan->maxRegTxPower;
682		chan->maxTxPower = ichan->maxTxPower;
683		chan->minTxPower = ichan->minTxPower;
684	}
685
686	HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
687
688	RESTORE_CCK(ah, ichan, ichan_isBmode);
689	RESTORE_CCK(ah, chan, isBmode);
690
691	OS_MARK(ah, AH_MARK_RESET_DONE, 0);
692
693	return AH_TRUE;
694bad:
695	if (ichan != AH_NULL)
696		RESTORE_CCK(ah, ichan, ichan_isBmode);
697	RESTORE_CCK(ah, chan, isBmode);
698
699	OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
700	if (*status)
701		*status = ecode;
702	return AH_FALSE;
703#undef FAIL
704#undef N
705}
706
707/*
708 * Call the rf backend to change the channel.
709 */
710HAL_BOOL
711ar5212SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
712{
713	struct ath_hal_5212 *ahp = AH5212(ah);
714
715	/* Change the synth */
716	if (!ahp->ah_rfHal->setChannel(ah, chan))
717		return AH_FALSE;
718	return AH_TRUE;
719}
720
721/*
722 * This channel change evaluates whether the selected hardware can
723 * perform a synthesizer-only channel change (no reset).  If the
724 * TX is not stopped, or the RFBus cannot be granted in the given
725 * time, the function returns false as a reset is necessary
726 */
727HAL_BOOL
728ar5212ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan)
729{
730	uint32_t       ulCount;
731	uint32_t   data, synthDelay, qnum;
732	uint16_t   rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL];
733	HAL_BOOL    txStopped = AH_TRUE;
734	HAL_CHANNEL_INTERNAL *ichan;
735
736	/*
737	 * Map public channel to private.
738	 */
739	ichan = ath_hal_checkchannel(ah, chan);
740
741	/* TX must be stopped or RF Bus grant will not work */
742	for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) {
743		if (ar5212NumTxPending(ah, qnum)) {
744			txStopped = AH_FALSE;
745			break;
746		}
747	}
748	if (!txStopped)
749		return AH_FALSE;
750
751	/* Kill last Baseband Rx Frame */
752	OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST); /* Request analog bus grant */
753	for (ulCount = 0; ulCount < 100; ulCount++) {
754		if (OS_REG_READ(ah, AR_PHY_RFBUS_GNT))
755			break;
756		OS_DELAY(5);
757	}
758	if (ulCount >= 100)
759		return AH_FALSE;
760
761	/* Change the synth */
762	if (!ar5212SetChannel(ah, ichan))
763		return AH_FALSE;
764
765	/*
766	 * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN).
767	 * Read the phy active delay register. Value is in 100ns increments.
768	 */
769	data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
770	if (IS_CHAN_CCK(ichan)) {
771		synthDelay = (4 * data) / 22;
772	} else {
773		synthDelay = data / 10;
774	}
775	OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
776
777	/* Setup the transmit power values. */
778	if (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) {
779		HALDEBUG(ah, HAL_DEBUG_ANY,
780		    "%s: error init'ing transmit power\n", __func__);
781		return AH_FALSE;
782	}
783
784	/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
785	if (IS_CHAN_OFDM(ichan)) {
786		if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) &&
787		    (!IS_CHAN_B(chan)))
788			ar5212SetSpurMitigation(ah, ichan);
789		ar5212SetDeltaSlope(ah, chan);
790	}
791
792	/* Release the RFBus Grant */
793	OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
794
795	/* Start Noise Floor Cal */
796	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
797
798	if (!(ichan->privFlags & CHANNEL_DFS))
799		ichan->privFlags &= ~CHANNEL_INTERFERENCE;
800	chan->channelFlags = ichan->channelFlags;
801	chan->privFlags = ichan->privFlags;
802	chan->maxRegTxPower = ichan->maxRegTxPower;
803	chan->maxTxPower = ichan->maxTxPower;
804	chan->minTxPower = ichan->minTxPower;
805	return AH_TRUE;
806}
807
808void
809ar5212SetOperatingMode(struct ath_hal *ah, int opmode)
810{
811	uint32_t val;
812
813	val = OS_REG_READ(ah, AR_STA_ID1);
814	val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
815	switch (opmode) {
816	case HAL_M_HOSTAP:
817		OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
818					| AR_STA_ID1_KSRCH_MODE);
819		OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
820		break;
821	case HAL_M_IBSS:
822		OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
823					| AR_STA_ID1_KSRCH_MODE);
824		OS_REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
825		break;
826	case HAL_M_STA:
827	case HAL_M_MONITOR:
828		OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
829		break;
830	}
831}
832
833/*
834 * Places the PHY and Radio chips into reset.  A full reset
835 * must be called to leave this state.  The PCI/MAC/PCU are
836 * not placed into reset as we must receive interrupt to
837 * re-enable the hardware.
838 */
839HAL_BOOL
840ar5212PhyDisable(struct ath_hal *ah)
841{
842	return ar5212SetResetReg(ah, AR_RC_BB);
843}
844
845/*
846 * Places all of hardware into reset
847 */
848HAL_BOOL
849ar5212Disable(struct ath_hal *ah)
850{
851	if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
852		return AH_FALSE;
853	/*
854	 * Reset the HW - PCI must be reset after the rest of the
855	 * device has been reset.
856	 */
857	return ar5212SetResetReg(ah, AR_RC_MAC | AR_RC_BB | AR_RC_PCI);
858}
859
860/*
861 * Places the hardware into reset and then pulls it out of reset
862 *
863 * TODO: Only write the PLL if we're changing to or from CCK mode
864 *
865 * WARNING: The order of the PLL and mode registers must be correct.
866 */
867HAL_BOOL
868ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
869{
870
871	OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0);
872
873	/*
874	 * Reset the HW - PCI must be reset after the rest of the
875	 * device has been reset
876	 */
877	if (!ar5212SetResetReg(ah, AR_RC_MAC | AR_RC_BB | AR_RC_PCI))
878		return AH_FALSE;
879
880	/* Bring out of sleep mode (AGAIN) */
881	if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
882		return AH_FALSE;
883
884	/* Clear warm reset register */
885	if (!ar5212SetResetReg(ah, 0))
886		return AH_FALSE;
887
888	/*
889	 * Perform warm reset before the mode/PLL/turbo registers
890	 * are changed in order to deactivate the radio.  Mode changes
891	 * with an active radio can result in corrupted shifts to the
892	 * radio device.
893	 */
894
895	/*
896	 * Set CCK and Turbo modes correctly.
897	 */
898	if (chan != AH_NULL) {		/* NB: can be null during attach */
899		uint32_t rfMode, phyPLL = 0, curPhyPLL, turbo;
900
901		if (IS_5413(ah)) {	/* NB: =>'s 5424 also */
902			rfMode = AR_PHY_MODE_AR5112;
903			if (IS_CHAN_HALF_RATE(chan))
904				rfMode |= AR_PHY_MODE_HALF;
905			else if (IS_CHAN_QUARTER_RATE(chan))
906				rfMode |= AR_PHY_MODE_QUARTER;
907
908			if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
909				phyPLL = AR_PHY_PLL_CTL_44_5112;
910			else
911				phyPLL = AR_PHY_PLL_CTL_40_5413;
912		} else if (IS_RAD5111(ah)) {
913			rfMode = AR_PHY_MODE_AR5111;
914			if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
915				phyPLL = AR_PHY_PLL_CTL_44;
916			else
917				phyPLL = AR_PHY_PLL_CTL_40;
918			if (IS_CHAN_HALF_RATE(chan))
919				phyPLL = AR_PHY_PLL_CTL_HALF;
920			else if (IS_CHAN_QUARTER_RATE(chan))
921				phyPLL = AR_PHY_PLL_CTL_QUARTER;
922		} else {		/* 5112, 2413, 2316, 2317 */
923			rfMode = AR_PHY_MODE_AR5112;
924			if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
925				phyPLL = AR_PHY_PLL_CTL_44_5112;
926			else
927				phyPLL = AR_PHY_PLL_CTL_40_5112;
928			if (IS_CHAN_HALF_RATE(chan))
929				phyPLL |= AR_PHY_PLL_CTL_HALF;
930			else if (IS_CHAN_QUARTER_RATE(chan))
931				phyPLL |= AR_PHY_PLL_CTL_QUARTER;
932		}
933		if (IS_CHAN_OFDM(chan) && (IS_CHAN_CCK(chan) ||
934					   IS_CHAN_G(chan)))
935			rfMode |= AR_PHY_MODE_DYNAMIC;
936		else if (IS_CHAN_OFDM(chan))
937			rfMode |= AR_PHY_MODE_OFDM;
938		else
939			rfMode |= AR_PHY_MODE_CCK;
940		if (IS_CHAN_5GHZ(chan))
941			rfMode |= AR_PHY_MODE_RF5GHZ;
942		else
943			rfMode |= AR_PHY_MODE_RF2GHZ;
944		turbo = IS_CHAN_TURBO(chan) ?
945			(AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT) : 0;
946		curPhyPLL = OS_REG_READ(ah, AR_PHY_PLL_CTL);
947		/*
948		 * PLL, Mode, and Turbo values must be written in the correct
949		 * order to ensure:
950		 * - The PLL cannot be set to 44 unless the CCK or DYNAMIC
951		 *   mode bit is set
952		 * - Turbo cannot be set at the same time as CCK or DYNAMIC
953		 */
954		if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
955			OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
956			OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
957			if (curPhyPLL != phyPLL) {
958				OS_REG_WRITE(ah,  AR_PHY_PLL_CTL,  phyPLL);
959				/* Wait for the PLL to settle */
960				OS_DELAY(PLL_SETTLE_DELAY);
961			}
962		} else {
963			if (curPhyPLL != phyPLL) {
964				OS_REG_WRITE(ah,  AR_PHY_PLL_CTL,  phyPLL);
965				/* Wait for the PLL to settle */
966				OS_DELAY(PLL_SETTLE_DELAY);
967			}
968			OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
969			OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
970		}
971	}
972	return AH_TRUE;
973}
974
975/*
976 * Recalibrate the lower PHY chips to account for temperature/environment
977 * changes.
978 */
979HAL_BOOL
980ar5212PerCalibrationN(struct ath_hal *ah,  HAL_CHANNEL *chan, u_int chainMask,
981	HAL_BOOL longCal, HAL_BOOL *isCalDone)
982{
983#define IQ_CAL_TRIES    10
984	struct ath_hal_5212 *ahp = AH5212(ah);
985	HAL_CHANNEL_INTERNAL *ichan;
986	int32_t qCoff, qCoffDenom;
987	int32_t iqCorrMeas, iCoff, iCoffDenom;
988	uint32_t powerMeasQ, powerMeasI;
989	HAL_BOOL ichan_isBmode = AH_FALSE;
990	HAL_BOOL isBmode = AH_FALSE;
991
992	OS_MARK(ah, AH_MARK_PERCAL, chan->channel);
993	*isCalDone = AH_FALSE;
994	ichan = ath_hal_checkchannel(ah, chan);
995	if (ichan == AH_NULL) {
996		HALDEBUG(ah, HAL_DEBUG_ANY,
997		    "%s: invalid channel %u/0x%x; no mapping\n",
998		    __func__, chan->channel, chan->channelFlags);
999		return AH_FALSE;
1000	}
1001	SAVE_CCK(ah, ichan, ichan_isBmode);
1002	SAVE_CCK(ah, chan, isBmode);
1003
1004	if (ahp->ah_bIQCalibration == IQ_CAL_DONE ||
1005	    ahp->ah_bIQCalibration == IQ_CAL_INACTIVE)
1006		*isCalDone = AH_TRUE;
1007
1008	/* IQ calibration in progress. Check to see if it has finished. */
1009	if (ahp->ah_bIQCalibration == IQ_CAL_RUNNING &&
1010	    !(OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) & AR_PHY_TIMING_CTRL4_DO_IQCAL)) {
1011		int i;
1012
1013		/* IQ Calibration has finished. */
1014		ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
1015		*isCalDone = AH_TRUE;
1016
1017		/* workaround for misgated IQ Cal results */
1018		i = 0;
1019		do {
1020			/* Read calibration results. */
1021			powerMeasI = OS_REG_READ(ah, AR_PHY_IQCAL_RES_PWR_MEAS_I);
1022			powerMeasQ = OS_REG_READ(ah, AR_PHY_IQCAL_RES_PWR_MEAS_Q);
1023			iqCorrMeas = OS_REG_READ(ah, AR_PHY_IQCAL_RES_IQ_CORR_MEAS);
1024			if (powerMeasI && powerMeasQ)
1025				break;
1026			/* Do we really need this??? */
1027			OS_REG_WRITE (ah,  AR_PHY_TIMING_CTRL4,
1028				      OS_REG_READ(ah,  AR_PHY_TIMING_CTRL4) |
1029				      AR_PHY_TIMING_CTRL4_DO_IQCAL);
1030		} while (++i < IQ_CAL_TRIES);
1031
1032		/*
1033		 * Prescale these values to remove 64-bit operation
1034		 * requirement at the loss of a little precision.
1035		 */
1036		iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
1037		qCoffDenom = powerMeasQ / 128;
1038
1039		/* Protect against divide-by-0 and loss of sign bits. */
1040		if (iCoffDenom != 0 && qCoffDenom >= 2) {
1041			iCoff = (int8_t)(-iqCorrMeas) / iCoffDenom;
1042			/* IQCORR_Q_I_COFF is a signed 6 bit number */
1043			if (iCoff < -32) {
1044				iCoff = -32;
1045			} else if (iCoff > 31) {
1046				iCoff = 31;
1047			}
1048
1049			/* IQCORR_Q_Q_COFF is a signed 5 bit number */
1050			qCoff = (powerMeasI / qCoffDenom) - 128;
1051			if (qCoff < -16) {
1052				qCoff = -16;
1053			} else if (qCoff > 15) {
1054				qCoff = 15;
1055			}
1056
1057			HALDEBUG(ah, HAL_DEBUG_PERCAL,
1058			    "****************** MISGATED IQ CAL! *******************\n");
1059			HALDEBUG(ah, HAL_DEBUG_PERCAL,
1060			    "time       = %d, i = %d, \n", OS_GETUPTIME(ah), i);
1061			HALDEBUG(ah, HAL_DEBUG_PERCAL,
1062			    "powerMeasI = 0x%08x\n", powerMeasI);
1063			HALDEBUG(ah, HAL_DEBUG_PERCAL,
1064			    "powerMeasQ = 0x%08x\n", powerMeasQ);
1065			HALDEBUG(ah, HAL_DEBUG_PERCAL,
1066			    "iqCorrMeas = 0x%08x\n", iqCorrMeas);
1067			HALDEBUG(ah, HAL_DEBUG_PERCAL,
1068			    "iCoff      = %d\n", iCoff);
1069			HALDEBUG(ah, HAL_DEBUG_PERCAL,
1070			    "qCoff      = %d\n", qCoff);
1071
1072			/* Write values and enable correction */
1073			OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1074				AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, iCoff);
1075			OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1076				AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff);
1077			OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
1078				AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
1079
1080			ahp->ah_bIQCalibration = IQ_CAL_DONE;
1081			ichan->iqCalValid = AH_TRUE;
1082			ichan->iCoff = iCoff;
1083			ichan->qCoff = qCoff;
1084		}
1085	} else if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration == IQ_CAL_DONE &&
1086	    !ichan->iqCalValid) {
1087		/*
1088		 * Start IQ calibration if configured channel has changed.
1089		 * Use a magic number of 15 based on default value.
1090		 */
1091		OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1092			AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
1093			INIT_IQCAL_LOG_COUNT_MAX);
1094		OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
1095			AR_PHY_TIMING_CTRL4_DO_IQCAL);
1096		ahp->ah_bIQCalibration = IQ_CAL_RUNNING;
1097	}
1098	/* XXX EAR */
1099
1100	if (longCal) {
1101		/* Check noise floor results */
1102		ar5212GetNf(ah, ichan);
1103
1104		if ((ichan->channelFlags & CHANNEL_CW_INT) == 0) {
1105			/* Perform cal for 5Ghz channels and any OFDM on 5112 */
1106			if (IS_CHAN_5GHZ(chan) ||
1107			    (IS_RAD5112(ah) && IS_CHAN_OFDM(chan)))
1108				ar5212RequestRfgain(ah);
1109		} else {
1110			/* report up and clear internal state */
1111			chan->channelFlags |= CHANNEL_CW_INT;
1112			ichan->channelFlags &= ~CHANNEL_CW_INT;
1113		}
1114	}
1115	RESTORE_CCK(ah, ichan, ichan_isBmode);
1116	RESTORE_CCK(ah, chan, isBmode);
1117
1118	return AH_TRUE;
1119#undef IQ_CAL_TRIES
1120}
1121
1122HAL_BOOL
1123ar5212PerCalibration(struct ath_hal *ah,  HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
1124{
1125	return ar5212PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone);
1126}
1127
1128HAL_BOOL
1129ar5212ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
1130{
1131	/* XXX */
1132	return AH_TRUE;
1133}
1134
1135/*
1136 * Write the given reset bit mask into the reset register
1137 */
1138static HAL_BOOL
1139ar5212SetResetReg(struct ath_hal *ah, uint32_t resetMask)
1140{
1141	uint32_t mask = resetMask ? resetMask : ~0;
1142	HAL_BOOL rt;
1143
1144	/* XXX ar5212MacStop & co. */
1145
1146	if (IS_PCIE(ah)) {
1147		resetMask &= ~AR_RC_PCI;
1148	}
1149
1150	(void) OS_REG_READ(ah, AR_RXDP);/* flush any pending MMR writes */
1151	OS_REG_WRITE(ah, AR_RC, resetMask);
1152	OS_DELAY(15);			/* need to wait at least 128 clocks
1153					   when reseting PCI before read */
1154	mask &= (AR_RC_MAC | AR_RC_BB);
1155	resetMask &= (AR_RC_MAC | AR_RC_BB);
1156	rt = ath_hal_wait(ah, AR_RC, mask, resetMask);
1157        if ((resetMask & AR_RC_MAC) == 0) {
1158		if (isBigEndian()) {
1159			/*
1160			 * Set CFG, little-endian for register
1161			 * and descriptor accesses.
1162			 */
1163			mask = INIT_CONFIG_STATUS | AR_CFG_SWRD | AR_CFG_SWRG;
1164#ifndef AH_NEED_DESC_SWAP
1165			mask |= AR_CFG_SWTD;
1166#endif
1167			OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask));
1168		} else
1169			OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS);
1170		if (ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
1171			(void) OS_REG_READ(ah, AR_ISR_RAC);
1172	}
1173
1174	/* track PHY power state so we don't try to r/w BB registers */
1175	AH5212(ah)->ah_phyPowerOn = ((resetMask & AR_RC_BB) == 0);
1176	return rt;
1177}
1178
1179int16_t
1180ar5212GetNoiseFloor(struct ath_hal *ah)
1181{
1182	int16_t nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff;
1183	if (nf & 0x100)
1184		nf = 0 - ((nf ^ 0x1ff) + 1);
1185	return nf;
1186}
1187
1188static HAL_BOOL
1189getNoiseFloorThresh(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *chan,
1190	int16_t *nft)
1191{
1192	const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1193
1194	HALASSERT(ah->ah_magic == AR5212_MAGIC);
1195
1196	switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
1197	case CHANNEL_A:
1198		*nft = ee->ee_noiseFloorThresh[headerInfo11A];
1199		break;
1200	case CHANNEL_B:
1201		*nft = ee->ee_noiseFloorThresh[headerInfo11B];
1202		break;
1203	case CHANNEL_PUREG:
1204		*nft = ee->ee_noiseFloorThresh[headerInfo11G];
1205		break;
1206	default:
1207		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
1208		    __func__, chan->channelFlags);
1209		return AH_FALSE;
1210	}
1211	return AH_TRUE;
1212}
1213
1214/*
1215 * Setup the noise floor cal history buffer.
1216 */
1217void
1218ar5212InitNfCalHistBuffer(struct ath_hal *ah)
1219{
1220	struct ath_hal_5212 *ahp = AH5212(ah);
1221	int i;
1222
1223	ahp->ah_nfCalHist.first_run = 1;
1224	ahp->ah_nfCalHist.currIndex = 0;
1225	ahp->ah_nfCalHist.privNF = AR5212_CCA_MAX_GOOD_VALUE;
1226	ahp->ah_nfCalHist.invalidNFcount = AR512_NF_CAL_HIST_MAX;
1227	for (i = 0; i < AR512_NF_CAL_HIST_MAX; i ++)
1228		ahp->ah_nfCalHist.nfCalBuffer[i] = AR5212_CCA_MAX_GOOD_VALUE;
1229}
1230
1231/*
1232 * Add a noise floor value to the ring buffer.
1233 */
1234static __inline void
1235updateNFHistBuff(struct ar5212NfCalHist *h, int16_t nf)
1236{
1237 	h->nfCalBuffer[h->currIndex] = nf;
1238     	if (++h->currIndex >= AR512_NF_CAL_HIST_MAX)
1239		h->currIndex = 0;
1240}
1241
1242/*
1243 * Return the median noise floor value in the ring buffer.
1244 */
1245int16_t
1246ar5212GetNfHistMid(const int16_t calData[AR512_NF_CAL_HIST_MAX])
1247{
1248	int16_t sort[AR512_NF_CAL_HIST_MAX];
1249	int i, j;
1250
1251	OS_MEMCPY(sort, calData, AR512_NF_CAL_HIST_MAX*sizeof(int16_t));
1252	for (i = 0; i < AR512_NF_CAL_HIST_MAX-1; i ++) {
1253		for (j = 1; j < AR512_NF_CAL_HIST_MAX-i; j ++) {
1254			if (sort[j] > sort[j-1]) {
1255				int16_t nf = sort[j];
1256				sort[j] = sort[j-1];
1257				sort[j-1] = nf;
1258			}
1259		}
1260	}
1261	return sort[(AR512_NF_CAL_HIST_MAX-1)>>1];
1262}
1263
1264/*
1265 * Read the NF and check it against the noise floor threshhold
1266 */
1267int16_t
1268ar5212GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
1269{
1270	struct ath_hal_5212 *ahp = AH5212(ah);
1271	struct ar5212NfCalHist *h = &ahp->ah_nfCalHist;
1272	int16_t nf, nfThresh;
1273 	int32_t val;
1274
1275	if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
1276		HALDEBUG(ah, HAL_DEBUG_ANY,
1277		    "%s: NF did not complete in calibration window\n", __func__);
1278		chan->rawNoiseFloor = h->privNF;	/* most recent value */
1279		return chan->rawNoiseFloor;
1280	}
1281
1282	/*
1283	 * Finished NF cal, check against threshold.
1284	 */
1285	nf = ar5212GetNoiseFloor(ah);
1286	if (getNoiseFloorThresh(ah, chan, &nfThresh)) {
1287		if (nf > nfThresh) {
1288			HALDEBUG(ah, HAL_DEBUG_ANY,
1289			    "%s: noise floor failed detected; detected %u, "
1290			    "threshold %u\n", __func__, nf, nfThresh);
1291			/*
1292			 * NB: Don't discriminate 2.4 vs 5Ghz, if this
1293			 *     happens it indicates a problem regardless
1294			 *     of the band.
1295			 */
1296			chan->channelFlags |= CHANNEL_CW_INT;
1297			nf = 0;
1298		}
1299	} else
1300		nf = 0;
1301
1302	/*
1303	 * Pass through histogram and write median value as
1304	 * calculated from the accrued window.  We require a
1305	 * full window of in-range values to be seen before we
1306	 * start using the history.
1307	 */
1308	updateNFHistBuff(h, nf);
1309	if (h->first_run) {
1310		if (nf < AR5212_CCA_MIN_BAD_VALUE ||
1311		    nf > AR5212_CCA_MAX_HIGH_VALUE) {
1312			nf = AR5212_CCA_MAX_GOOD_VALUE;
1313			h->invalidNFcount = AR512_NF_CAL_HIST_MAX;
1314		} else if (--(h->invalidNFcount) == 0) {
1315			h->first_run = 0;
1316			h->privNF = nf = ar5212GetNfHistMid(h->nfCalBuffer);
1317		} else {
1318			nf = AR5212_CCA_MAX_GOOD_VALUE;
1319		}
1320	} else {
1321		h->privNF = nf = ar5212GetNfHistMid(h->nfCalBuffer);
1322	}
1323
1324	val = OS_REG_READ(ah, AR_PHY(25));
1325	val &= 0xFFFFFE00;
1326	val |= (((uint32_t)nf << 1) & 0x1FF);
1327	OS_REG_WRITE(ah, AR_PHY(25), val);
1328	OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
1329	OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1330	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1331
1332	if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF, 0)) {
1333#ifdef AH_DEBUG
1334		ath_hal_printf(ah, "%s: AGC not ready AGC_CONTROL 0x%x\n",
1335		    __func__, OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
1336#endif
1337	}
1338
1339	/*
1340	 * Now load a high maxCCAPower value again so that we're
1341	 * not capped by the median we just loaded
1342	 */
1343	val &= 0xFFFFFE00;
1344	val |= (((uint32_t)(-50) << 1) & 0x1FF);
1345	OS_REG_WRITE(ah, AR_PHY(25), val);
1346	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
1347	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1348	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1349
1350	return (chan->rawNoiseFloor = nf);
1351}
1352
1353/*
1354 * Set up compression configuration registers
1355 */
1356void
1357ar5212SetCompRegs(struct ath_hal *ah)
1358{
1359	struct ath_hal_5212 *ahp = AH5212(ah);
1360	int i;
1361
1362        /* Check if h/w supports compression */
1363	if (!AH_PRIVATE(ah)->ah_caps.halCompressSupport)
1364		return;
1365
1366	OS_REG_WRITE(ah, AR_DCCFG, 1);
1367
1368	OS_REG_WRITE(ah, AR_CCFG,
1369		(AR_COMPRESSION_WINDOW_SIZE >> 8) & AR_CCFG_WIN_M);
1370
1371	OS_REG_WRITE(ah, AR_CCFG,
1372		OS_REG_READ(ah, AR_CCFG) | AR_CCFG_MIB_INT_EN);
1373	OS_REG_WRITE(ah, AR_CCUCFG,
1374		AR_CCUCFG_RESET_VAL | AR_CCUCFG_CATCHUP_EN);
1375
1376	OS_REG_WRITE(ah, AR_CPCOVF, 0);
1377
1378	/* reset decompression mask */
1379	for (i = 0; i < HAL_DECOMP_MASK_SIZE; i++) {
1380		OS_REG_WRITE(ah, AR_DCM_A, i);
1381		OS_REG_WRITE(ah, AR_DCM_D, ahp->ah_decompMask[i]);
1382	}
1383}
1384
1385HAL_BOOL
1386ar5212SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
1387	const HAL_CHANNEL_INTERNAL *chan)
1388{
1389#define	ANT_SWITCH_TABLE1	AR_PHY(88)
1390#define	ANT_SWITCH_TABLE2	AR_PHY(89)
1391	struct ath_hal_5212 *ahp = AH5212(ah);
1392	const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1393	uint32_t antSwitchA, antSwitchB;
1394	int ix;
1395	HAL_BOOL isBmode = AH_FALSE;
1396	/* NB: need local copy for SAVE/RESTORE 'cuz chan is const */
1397	HAL_CHANNEL_INTERNAL ichan = *chan;
1398
1399	HALASSERT(ah->ah_magic == AR5212_MAGIC);
1400	HALASSERT(ahp->ah_phyPowerOn);
1401
1402	SAVE_CCK(ah, &ichan, isBmode);
1403	switch (ichan.channelFlags & CHANNEL_ALL_NOTURBO) {
1404	case CHANNEL_A:		ix = 0; break;
1405	case CHANNEL_B:		ix = 1; break;
1406	case CHANNEL_PUREG:	ix = 2; break;
1407	default:
1408		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
1409		    __func__, ichan.channelFlags);
1410		RESTORE_CCK(ah, &ichan, isBmode);
1411		return AH_FALSE;
1412	}
1413	RESTORE_CCK(ah, &ichan, isBmode);
1414
1415	antSwitchA =  ee->ee_antennaControl[1][ix]
1416		   | (ee->ee_antennaControl[2][ix] << 6)
1417		   | (ee->ee_antennaControl[3][ix] << 12)
1418		   | (ee->ee_antennaControl[4][ix] << 18)
1419		   | (ee->ee_antennaControl[5][ix] << 24)
1420		   ;
1421	antSwitchB =  ee->ee_antennaControl[6][ix]
1422		   | (ee->ee_antennaControl[7][ix] << 6)
1423		   | (ee->ee_antennaControl[8][ix] << 12)
1424		   | (ee->ee_antennaControl[9][ix] << 18)
1425		   | (ee->ee_antennaControl[10][ix] << 24)
1426		   ;
1427	/*
1428	 * For fixed antenna, give the same setting for both switch banks
1429	 */
1430	switch (settings) {
1431	case HAL_ANT_FIXED_A:
1432		antSwitchB = antSwitchA;
1433		break;
1434	case HAL_ANT_FIXED_B:
1435		antSwitchA = antSwitchB;
1436		break;
1437	case HAL_ANT_VARIABLE:
1438		break;
1439	default:
1440		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad antenna setting %u\n",
1441		    __func__, settings);
1442		return AH_FALSE;
1443	}
1444	if (antSwitchB == antSwitchA) {
1445		HALDEBUG(ah, HAL_DEBUG_RFPARAM,
1446		    "%s: Setting fast diversity off.\n", __func__);
1447		OS_REG_CLR_BIT(ah,AR_PHY_CCK_DETECT,
1448			       AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
1449		ahp->ah_diversity = AH_FALSE;
1450	} else {
1451		HALDEBUG(ah, HAL_DEBUG_RFPARAM,
1452		    "%s: Setting fast diversity on.\n", __func__);
1453		OS_REG_SET_BIT(ah,AR_PHY_CCK_DETECT,
1454			       AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
1455		ahp->ah_diversity = AH_TRUE;
1456	}
1457	ahp->ah_antControl = settings;
1458
1459	OS_REG_WRITE(ah, ANT_SWITCH_TABLE1, antSwitchA);
1460	OS_REG_WRITE(ah, ANT_SWITCH_TABLE2, antSwitchB);
1461
1462	return AH_TRUE;
1463#undef ANT_SWITCH_TABLE2
1464#undef ANT_SWITCH_TABLE1
1465}
1466
1467HAL_BOOL
1468ar5212IsSpurChannel(struct ath_hal *ah, HAL_CHANNEL *chan)
1469{
1470    uint32_t clockFreq =
1471	((IS_5413(ah) || IS_RAD5112_ANY(ah) || IS_2417(ah)) ? 40 : 32);
1472    return ( ((chan->channel % clockFreq) != 0)
1473          && (((chan->channel % clockFreq) < 10)
1474         || (((chan->channel) % clockFreq) > 22)) );
1475}
1476
1477/*
1478 * Read EEPROM header info and program the device for correct operation
1479 * given the channel value.
1480 */
1481HAL_BOOL
1482ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
1483{
1484#define NO_FALSE_DETECT_BACKOFF   2
1485#define CB22_FALSE_DETECT_BACKOFF 6
1486#define	AR_PHY_BIS(_ah, _reg, _mask, _val) \
1487	OS_REG_WRITE(_ah, AR_PHY(_reg), \
1488		(OS_REG_READ(_ah, AR_PHY(_reg)) & _mask) | (_val));
1489	struct ath_hal_5212 *ahp = AH5212(ah);
1490	const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1491	int arrayMode, falseDectectBackoff;
1492	int is2GHz = IS_CHAN_2GHZ(chan);
1493	int8_t adcDesiredSize, pgaDesiredSize;
1494	uint16_t switchSettling, txrxAtten, rxtxMargin;
1495	int iCoff, qCoff;
1496
1497	HALASSERT(ah->ah_magic == AR5212_MAGIC);
1498
1499	switch (chan->channelFlags & CHANNEL_ALL) {
1500	case CHANNEL_A:
1501	case CHANNEL_T:
1502		arrayMode = headerInfo11A;
1503		if (!IS_RAD5112_ANY(ah) && !IS_2413(ah) && !IS_5413(ah))
1504			OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
1505				AR_PHY_FRAME_CTL_TX_CLIP,
1506				ahp->ah_gainValues.currStep->paramVal[GP_TXCLIP]);
1507		break;
1508	case CHANNEL_B:
1509		arrayMode = headerInfo11B;
1510		break;
1511	case CHANNEL_G:
1512	case CHANNEL_108G:
1513		arrayMode = headerInfo11G;
1514		break;
1515	default:
1516		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
1517		    __func__, chan->channelFlags);
1518		return AH_FALSE;
1519	}
1520
1521	/* Set the antenna register(s) correctly for the chip revision */
1522	AR_PHY_BIS(ah, 68, 0xFFFFFC06,
1523		(ee->ee_antennaControl[0][arrayMode] << 4) | 0x1);
1524
1525	ar5212SetAntennaSwitchInternal(ah, ahp->ah_antControl, chan);
1526
1527	/* Set the Noise Floor Thresh on ar5211 devices */
1528	OS_REG_WRITE(ah, AR_PHY(90),
1529		(ee->ee_noiseFloorThresh[arrayMode] & 0x1FF)
1530		| (1 << 9));
1531
1532	if (ee->ee_version >= AR_EEPROM_VER5_0 && IS_CHAN_TURBO(chan)) {
1533		switchSettling = ee->ee_switchSettlingTurbo[is2GHz];
1534		adcDesiredSize = ee->ee_adcDesiredSizeTurbo[is2GHz];
1535		pgaDesiredSize = ee->ee_pgaDesiredSizeTurbo[is2GHz];
1536		txrxAtten = ee->ee_txrxAttenTurbo[is2GHz];
1537		rxtxMargin = ee->ee_rxtxMarginTurbo[is2GHz];
1538	} else {
1539		switchSettling = ee->ee_switchSettling[arrayMode];
1540		adcDesiredSize = ee->ee_adcDesiredSize[arrayMode];
1541		pgaDesiredSize = ee->ee_pgaDesiredSize[is2GHz];
1542		txrxAtten = ee->ee_txrxAtten[is2GHz];
1543		rxtxMargin = ee->ee_rxtxMargin[is2GHz];
1544	}
1545
1546	OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING,
1547			 AR_PHY_SETTLING_SWITCH, switchSettling);
1548	OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
1549			 AR_PHY_DESIRED_SZ_ADC, adcDesiredSize);
1550	OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
1551			 AR_PHY_DESIRED_SZ_PGA, pgaDesiredSize);
1552	OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
1553			 AR_PHY_RXGAIN_TXRX_ATTEN, txrxAtten);
1554	OS_REG_WRITE(ah, AR_PHY(13),
1555		(ee->ee_txEndToXPAOff[arrayMode] << 24)
1556		| (ee->ee_txEndToXPAOff[arrayMode] << 16)
1557		| (ee->ee_txFrameToXPAOn[arrayMode] << 8)
1558		| ee->ee_txFrameToXPAOn[arrayMode]);
1559	AR_PHY_BIS(ah, 10, 0xFFFF00FF,
1560		ee->ee_txEndToXLNAOn[arrayMode] << 8);
1561	AR_PHY_BIS(ah, 25, 0xFFF80FFF,
1562		(ee->ee_thresh62[arrayMode] << 12) & 0x7F000);
1563
1564	/*
1565	 * False detect backoff - suspected 32 MHz spur causes false
1566	 * detects in OFDM, causing Tx Hangs.  Decrease weak signal
1567	 * sensitivity for this card.
1568	 */
1569	falseDectectBackoff = NO_FALSE_DETECT_BACKOFF;
1570	if (ee->ee_version < AR_EEPROM_VER3_3) {
1571		/* XXX magic number */
1572		if (AH_PRIVATE(ah)->ah_subvendorid == 0x1022 &&
1573		    IS_CHAN_OFDM(chan))
1574			falseDectectBackoff += CB22_FALSE_DETECT_BACKOFF;
1575	} else {
1576		if (ar5212IsSpurChannel(ah, (HAL_CHANNEL *)chan)) {
1577			falseDectectBackoff += ee->ee_falseDetectBackoff[arrayMode];
1578		}
1579	}
1580	AR_PHY_BIS(ah, 73, 0xFFFFFF01, (falseDectectBackoff << 1) & 0xFE);
1581
1582	if (chan->iqCalValid) {
1583		iCoff = chan->iCoff;
1584		qCoff = chan->qCoff;
1585	} else {
1586		iCoff = ee->ee_iqCalI[is2GHz];
1587		qCoff = ee->ee_iqCalQ[is2GHz];
1588	}
1589
1590	/* write previous IQ results */
1591	OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1592		AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, iCoff);
1593	OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1594		AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff);
1595	OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
1596		AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
1597
1598	if (ee->ee_version >= AR_EEPROM_VER4_1) {
1599		if (!IS_CHAN_108G(chan) || ee->ee_version >= AR_EEPROM_VER5_0)
1600			OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
1601				AR_PHY_GAIN_2GHZ_RXTX_MARGIN, rxtxMargin);
1602	}
1603	if (ee->ee_version >= AR_EEPROM_VER5_1) {
1604		/* for now always disabled */
1605		OS_REG_WRITE(ah,  AR_PHY_HEAVY_CLIP_ENABLE,  0);
1606	}
1607
1608	return AH_TRUE;
1609#undef AR_PHY_BIS
1610#undef NO_FALSE_DETECT_BACKOFF
1611#undef CB22_FALSE_DETECT_BACKOFF
1612}
1613
1614/*
1615 * Apply Spur Immunity to Boards that require it.
1616 * Applies only to OFDM RX operation.
1617 */
1618
1619void
1620ar5212SetSpurMitigation(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
1621{
1622	uint32_t pilotMask[2] = {0, 0}, binMagMask[4] = {0, 0, 0 , 0};
1623	uint16_t i, finalSpur, curChanAsSpur, binWidth = 0, spurDetectWidth, spurChan;
1624	int32_t spurDeltaPhase = 0, spurFreqSd = 0, spurOffset, binOffsetNumT16, curBinOffset;
1625	int16_t numBinOffsets;
1626	static const uint16_t magMapFor4[4] = {1, 2, 2, 1};
1627	static const uint16_t magMapFor3[3] = {1, 2, 1};
1628	const uint16_t *pMagMap;
1629	HAL_BOOL is2GHz = IS_CHAN_2GHZ(ichan);
1630	uint32_t val;
1631
1632#define CHAN_TO_SPUR(_f, _freq)   ( ((_freq) - ((_f) ? 2300 : 4900)) * 10 )
1633	if (IS_2417(ah)) {
1634		HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: no spur mitigation\n",
1635		    __func__);
1636		return;
1637	}
1638
1639	curChanAsSpur = CHAN_TO_SPUR(is2GHz, ichan->channel);
1640
1641	if (ichan->mainSpur) {
1642		/* Pull out the saved spur value */
1643		finalSpur = ichan->mainSpur;
1644	} else {
1645		/*
1646		 * Check if spur immunity should be performed for this channel
1647		 * Should only be performed once per channel and then saved
1648		 */
1649		finalSpur = AR_NO_SPUR;
1650		spurDetectWidth = HAL_SPUR_CHAN_WIDTH;
1651		if (IS_CHAN_TURBO(ichan))
1652			spurDetectWidth *= 2;
1653
1654		/* Decide if any spur affects the current channel */
1655		for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
1656			spurChan = ath_hal_getSpurChan(ah, i, is2GHz);
1657			if (spurChan == AR_NO_SPUR) {
1658				break;
1659			}
1660			if ((curChanAsSpur - spurDetectWidth <= (spurChan & HAL_SPUR_VAL_MASK)) &&
1661			    (curChanAsSpur + spurDetectWidth >= (spurChan & HAL_SPUR_VAL_MASK))) {
1662				finalSpur = spurChan & HAL_SPUR_VAL_MASK;
1663				break;
1664			}
1665		}
1666		/* Save detected spur (or no spur) for this channel */
1667		ichan->mainSpur = finalSpur;
1668	}
1669
1670	/* Write spur immunity data */
1671	if (finalSpur == AR_NO_SPUR) {
1672		/* Disable Spur Immunity Regs if they appear set */
1673		if (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) & AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER) {
1674			/* Clear Spur Delta Phase, Spur Freq, and enable bits */
1675			OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_RATE, 0);
1676			val = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4);
1677			val &= ~(AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
1678				 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
1679				 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
1680			OS_REG_WRITE(ah, AR_PHY_MASK_CTL, val);
1681			OS_REG_WRITE(ah, AR_PHY_TIMING11, 0);
1682
1683			/* Clear pilot masks */
1684			OS_REG_WRITE(ah, AR_PHY_TIMING7, 0);
1685			OS_REG_RMW_FIELD(ah, AR_PHY_TIMING8, AR_PHY_TIMING8_PILOT_MASK_2, 0);
1686			OS_REG_WRITE(ah, AR_PHY_TIMING9, 0);
1687			OS_REG_RMW_FIELD(ah, AR_PHY_TIMING10, AR_PHY_TIMING10_PILOT_MASK_2, 0);
1688
1689			/* Clear magnitude masks */
1690			OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, 0);
1691			OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, 0);
1692			OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, 0);
1693			OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_MASK_4, 0);
1694			OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, 0);
1695			OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, 0);
1696			OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, 0);
1697			OS_REG_RMW_FIELD(ah, AR_PHY_BIN_MASK2_4, AR_PHY_BIN_MASK2_4_MASK_4, 0);
1698		}
1699	} else {
1700		spurOffset = finalSpur - curChanAsSpur;
1701		/*
1702		 * Spur calculations:
1703		 * spurDeltaPhase is (spurOffsetIn100KHz / chipFrequencyIn100KHz) << 21
1704		 * spurFreqSd is (spurOffsetIn100KHz / sampleFrequencyIn100KHz) << 11
1705		 */
1706		switch (ichan->channelFlags & CHANNEL_ALL) {
1707		case CHANNEL_A: /* Chip Frequency & sampleFrequency are 40 MHz */
1708			spurDeltaPhase = (spurOffset << 17) / 25;
1709			spurFreqSd = spurDeltaPhase >> 10;
1710			binWidth = HAL_BIN_WIDTH_BASE_100HZ;
1711			break;
1712		case CHANNEL_G: /* Chip Frequency is 44MHz, sampleFrequency is 40 MHz */
1713			spurFreqSd = (spurOffset << 8) / 55;
1714			spurDeltaPhase = (spurOffset << 17) / 25;
1715			binWidth = HAL_BIN_WIDTH_BASE_100HZ;
1716			break;
1717		case CHANNEL_T: /* Chip Frequency & sampleFrequency are 80 MHz */
1718		case CHANNEL_108G:
1719			spurDeltaPhase = (spurOffset << 16) / 25;
1720			spurFreqSd = spurDeltaPhase >> 10;
1721			binWidth = HAL_BIN_WIDTH_TURBO_100HZ;
1722			break;
1723		}
1724
1725		/* Compute Pilot Mask */
1726		binOffsetNumT16 = ((spurOffset * 1000) << 4) / binWidth;
1727		/* The spur is on a bin if it's remainder at times 16 is 0 */
1728		if (binOffsetNumT16 & 0xF) {
1729			numBinOffsets = 4;
1730			pMagMap = magMapFor4;
1731		} else {
1732			numBinOffsets = 3;
1733			pMagMap = magMapFor3;
1734		}
1735		for (i = 0; i < numBinOffsets; i++) {
1736			if ((binOffsetNumT16 >> 4) > HAL_MAX_BINS_ALLOWED) {
1737				HALDEBUG(ah, HAL_DEBUG_ANY,
1738				    "Too man bins in spur mitigation\n");
1739				return;
1740			}
1741
1742			/* Get Pilot Mask values */
1743			curBinOffset = (binOffsetNumT16 >> 4) + i + 25;
1744			if ((curBinOffset >= 0) && (curBinOffset <= 32)) {
1745				if (curBinOffset <= 25)
1746					pilotMask[0] |= 1 << curBinOffset;
1747				else if (curBinOffset >= 27)
1748					pilotMask[0] |= 1 << (curBinOffset - 1);
1749			} else if ((curBinOffset >= 33) && (curBinOffset <= 52))
1750				pilotMask[1] |= 1 << (curBinOffset - 33);
1751
1752			/* Get viterbi values */
1753			if ((curBinOffset >= -1) && (curBinOffset <= 14))
1754				binMagMask[0] |= pMagMap[i] << (curBinOffset + 1) * 2;
1755			else if ((curBinOffset >= 15) && (curBinOffset <= 30))
1756				binMagMask[1] |= pMagMap[i] << (curBinOffset - 15) * 2;
1757			else if ((curBinOffset >= 31) && (curBinOffset <= 46))
1758				binMagMask[2] |= pMagMap[i] << (curBinOffset -31) * 2;
1759			else if((curBinOffset >= 47) && (curBinOffset <= 53))
1760				binMagMask[3] |= pMagMap[i] << (curBinOffset -47) * 2;
1761		}
1762
1763		/* Write Spur Delta Phase, Spur Freq, and enable bits */
1764		OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_RATE, 0xFF);
1765		val = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4);
1766		val |= (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
1767			AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
1768			AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
1769		OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4, val);
1770		OS_REG_WRITE(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_IN_AGC |
1771			     SM(spurFreqSd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
1772			     SM(spurDeltaPhase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
1773
1774		/* Write pilot masks */
1775		OS_REG_WRITE(ah, AR_PHY_TIMING7, pilotMask[0]);
1776		OS_REG_RMW_FIELD(ah, AR_PHY_TIMING8, AR_PHY_TIMING8_PILOT_MASK_2, pilotMask[1]);
1777		OS_REG_WRITE(ah, AR_PHY_TIMING9, pilotMask[0]);
1778		OS_REG_RMW_FIELD(ah, AR_PHY_TIMING10, AR_PHY_TIMING10_PILOT_MASK_2, pilotMask[1]);
1779
1780		/* Write magnitude masks */
1781		OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, binMagMask[0]);
1782		OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, binMagMask[1]);
1783		OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, binMagMask[2]);
1784		OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_MASK_4, binMagMask[3]);
1785		OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, binMagMask[0]);
1786		OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, binMagMask[1]);
1787		OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, binMagMask[2]);
1788		OS_REG_RMW_FIELD(ah, AR_PHY_BIN_MASK2_4, AR_PHY_BIN_MASK2_4_MASK_4, binMagMask[3]);
1789	}
1790#undef CHAN_TO_SPUR
1791}
1792
1793
1794/*
1795 * Delta slope coefficient computation.
1796 * Required for OFDM operation.
1797 */
1798void
1799ar5212SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL *chan)
1800{
1801#define COEF_SCALE_S 24
1802#define INIT_CLOCKMHZSCALED	0x64000000
1803	unsigned long coef_scaled, coef_exp, coef_man, ds_coef_exp, ds_coef_man;
1804	unsigned long clockMhzScaled = INIT_CLOCKMHZSCALED;
1805
1806	if (IS_CHAN_TURBO(chan))
1807		clockMhzScaled *= 2;
1808	/* half and quarter rate can divide the scaled clock by 2 or 4 respectively */
1809	/* scale for selected channel bandwidth */
1810	if (IS_CHAN_HALF_RATE(chan)) {
1811		clockMhzScaled = clockMhzScaled >> 1;
1812	} else if (IS_CHAN_QUARTER_RATE(chan)) {
1813		clockMhzScaled = clockMhzScaled >> 2;
1814	}
1815
1816	/*
1817	 * ALGO -> coef = 1e8/fcarrier*fclock/40;
1818	 * scaled coef to provide precision for this floating calculation
1819	 */
1820	coef_scaled = clockMhzScaled / chan->channel;
1821
1822	/*
1823	 * ALGO -> coef_exp = 14-floor(log2(coef));
1824	 * floor(log2(x)) is the highest set bit position
1825	 */
1826	for (coef_exp = 31; coef_exp > 0; coef_exp--)
1827		if ((coef_scaled >> coef_exp) & 0x1)
1828			break;
1829	/* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */
1830	HALASSERT(coef_exp);
1831	coef_exp = 14 - (coef_exp - COEF_SCALE_S);
1832
1833	/*
1834	 * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5);
1835	 * The coefficient is already shifted up for scaling
1836	 */
1837	coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
1838	ds_coef_man = coef_man >> (COEF_SCALE_S - coef_exp);
1839	ds_coef_exp = coef_exp - 16;
1840
1841	OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3,
1842		AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
1843	OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3,
1844		AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
1845#undef INIT_CLOCKMHZSCALED
1846#undef COEF_SCALE_S
1847}
1848
1849/*
1850 * Set a limit on the overall output power.  Used for dynamic
1851 * transmit power control and the like.
1852 *
1853 * NB: limit is in units of 0.5 dbM.
1854 */
1855HAL_BOOL
1856ar5212SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
1857{
1858	uint16_t dummyXpdGains[2];
1859	HAL_BOOL ret, isBmode = AH_FALSE;
1860
1861	SAVE_CCK(ah, AH_PRIVATE(ah)->ah_curchan, isBmode);
1862	AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);
1863	ret = ar5212SetTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan,
1864			dummyXpdGains);
1865	RESTORE_CCK(ah, AH_PRIVATE(ah)->ah_curchan, isBmode);
1866	return ret;
1867}
1868
1869/*
1870 * Set the transmit power in the baseband for the given
1871 * operating channel and mode.
1872 */
1873HAL_BOOL
1874ar5212SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
1875	uint16_t *rfXpdGain)
1876{
1877#define	POW_OFDM(_r, _s)	(((0 & 1)<< ((_s)+6)) | (((_r) & 0x3f) << (_s)))
1878#define	POW_CCK(_r, _s)		(((_r) & 0x3f) << (_s))
1879#define	N(a)			(sizeof (a) / sizeof (a[0]))
1880	static const uint16_t tpcScaleReductionTable[5] =
1881		{ 0, 3, 6, 9, MAX_RATE_POWER };
1882	struct ath_hal_5212 *ahp = AH5212(ah);
1883	const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1884	int16_t minPower, maxPower, tpcInDb, powerLimit;
1885	int i;
1886
1887	HALASSERT(ah->ah_magic == AR5212_MAGIC);
1888
1889	OS_MEMZERO(ahp->ah_pcdacTable, ahp->ah_pcdacTableSize);
1890	OS_MEMZERO(ahp->ah_ratesArray, sizeof(ahp->ah_ratesArray));
1891
1892	powerLimit = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit);
1893	if (powerLimit >= MAX_RATE_POWER || powerLimit == 0)
1894		tpcInDb = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale];
1895	else
1896		tpcInDb = 0;
1897	if (!ar5212SetRateTable(ah, (HAL_CHANNEL *) chan, tpcInDb, powerLimit,
1898				AH_TRUE, &minPower, &maxPower)) {
1899		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set rate table\n",
1900		    __func__);
1901		return AH_FALSE;
1902	}
1903	if (!ahp->ah_rfHal->setPowerTable(ah,
1904		&minPower, &maxPower, chan, rfXpdGain)) {
1905		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n",
1906		    __func__);
1907		return AH_FALSE;
1908	}
1909
1910	/*
1911	 * Adjust XR power/rate up by 2 dB to account for greater peak
1912	 * to avg ratio - except in newer avg power designs
1913	 */
1914	if (!IS_2413(ah) && !IS_5413(ah))
1915		ahp->ah_ratesArray[15] += 4;
1916	/*
1917	 * txPowerIndexOffset is set by the SetPowerTable() call -
1918	 *  adjust the rate table
1919	 */
1920	for (i = 0; i < N(ahp->ah_ratesArray); i++) {
1921		ahp->ah_ratesArray[i] += ahp->ah_txPowerIndexOffset;
1922		if (ahp->ah_ratesArray[i] > 63)
1923			ahp->ah_ratesArray[i] = 63;
1924	}
1925
1926	if (ee->ee_eepMap < 2) {
1927		/*
1928		 * Correct gain deltas for 5212 G operation -
1929		 * Removed with revised chipset
1930		 */
1931		if (AH_PRIVATE(ah)->ah_phyRev < AR_PHY_CHIP_ID_REV_2 &&
1932		    IS_CHAN_G(chan)) {
1933			uint16_t cckOfdmPwrDelta;
1934
1935			if (chan->channel == 2484)
1936				cckOfdmPwrDelta = SCALE_OC_DELTA(
1937					ee->ee_cckOfdmPwrDelta -
1938					ee->ee_scaledCh14FilterCckDelta);
1939			else
1940				cckOfdmPwrDelta = SCALE_OC_DELTA(
1941					ee->ee_cckOfdmPwrDelta);
1942			ar5212CorrectGainDelta(ah, cckOfdmPwrDelta);
1943		}
1944		/*
1945		 * Finally, write the power values into the
1946		 * baseband power table
1947		 */
1948		for (i = 0; i < (PWR_TABLE_SIZE/2); i++) {
1949			OS_REG_WRITE(ah, AR_PHY_PCDAC_TX_POWER(i),
1950				 ((((ahp->ah_pcdacTable[2*i + 1] << 8) | 0xff) & 0xffff) << 16)
1951				| (((ahp->ah_pcdacTable[2*i]     << 8) | 0xff) & 0xffff)
1952			);
1953		}
1954	}
1955
1956	/* Write the OFDM power per rate set */
1957	OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
1958		POW_OFDM(ahp->ah_ratesArray[3], 24)
1959	      | POW_OFDM(ahp->ah_ratesArray[2], 16)
1960	      | POW_OFDM(ahp->ah_ratesArray[1],  8)
1961	      | POW_OFDM(ahp->ah_ratesArray[0],  0)
1962	);
1963	OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
1964		POW_OFDM(ahp->ah_ratesArray[7], 24)
1965	      | POW_OFDM(ahp->ah_ratesArray[6], 16)
1966	      | POW_OFDM(ahp->ah_ratesArray[5],  8)
1967	      | POW_OFDM(ahp->ah_ratesArray[4],  0)
1968	);
1969
1970	/* Write the CCK power per rate set */
1971	OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1972		POW_CCK(ahp->ah_ratesArray[10], 24)
1973	      | POW_CCK(ahp->ah_ratesArray[9],  16)
1974	      | POW_CCK(ahp->ah_ratesArray[15],  8)	/* XR target power */
1975	      | POW_CCK(ahp->ah_ratesArray[8],   0)
1976	);
1977	OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1978		POW_CCK(ahp->ah_ratesArray[14], 24)
1979	      | POW_CCK(ahp->ah_ratesArray[13], 16)
1980	      | POW_CCK(ahp->ah_ratesArray[12],  8)
1981	      | POW_CCK(ahp->ah_ratesArray[11],  0)
1982	);
1983
1984	/*
1985	 * Set max power to 30 dBm and, optionally,
1986	 * enable TPC in tx descriptors.
1987	 */
1988	OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER |
1989		(ahp->ah_tpcEnabled ? AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE : 0));
1990
1991	return AH_TRUE;
1992#undef N
1993#undef POW_CCK
1994#undef POW_OFDM
1995}
1996
1997/*
1998 * Sets the transmit power in the baseband for the given
1999 * operating channel and mode.
2000 */
2001static HAL_BOOL
2002ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
2003		   int16_t tpcScaleReduction, int16_t powerLimit, HAL_BOOL commit,
2004                   int16_t *pMinPower, int16_t *pMaxPower)
2005{
2006	struct ath_hal_5212 *ahp = AH5212(ah);
2007	const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
2008	uint16_t *rpow = ahp->ah_ratesArray;
2009	uint16_t twiceMaxEdgePower = MAX_RATE_POWER;
2010	uint16_t twiceMaxEdgePowerCck = MAX_RATE_POWER;
2011	uint16_t twiceMaxRDPower = MAX_RATE_POWER;
2012	int i;
2013	uint8_t cfgCtl;
2014	int8_t twiceAntennaGain, twiceAntennaReduction;
2015	const RD_EDGES_POWER *rep;
2016	TRGT_POWER_INFO targetPowerOfdm, targetPowerCck;
2017	int16_t scaledPower, maxAvailPower = 0;
2018	int16_t r13, r9, r7, r0;
2019
2020	HALASSERT(ah->ah_magic == AR5212_MAGIC);
2021
2022	twiceMaxRDPower = chan->maxRegTxPower * 2;
2023	*pMaxPower = -MAX_RATE_POWER;
2024	*pMinPower = MAX_RATE_POWER;
2025
2026	/* Get conformance test limit maximum for this channel */
2027	cfgCtl = ath_hal_getctl(ah, chan);
2028	for (i = 0; i < ee->ee_numCtls; i++) {
2029		uint16_t twiceMinEdgePower;
2030
2031		if (ee->ee_ctl[i] == 0)
2032			continue;
2033		if (ee->ee_ctl[i] == cfgCtl ||
2034		    cfgCtl == ((ee->ee_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) {
2035			rep = &ee->ee_rdEdgesPower[i * NUM_EDGES];
2036			twiceMinEdgePower = ar5212GetMaxEdgePower(chan->channel, rep);
2037			if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
2038				/* Find the minimum of all CTL edge powers that apply to this channel */
2039				twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower);
2040			} else {
2041				twiceMaxEdgePower = twiceMinEdgePower;
2042				break;
2043			}
2044		}
2045	}
2046
2047	if (IS_CHAN_G(chan)) {
2048		/* Check for a CCK CTL for 11G CCK powers */
2049		cfgCtl = (cfgCtl & ~CTL_MODE_M) | CTL_11B;
2050		for (i = 0; i < ee->ee_numCtls; i++) {
2051			uint16_t twiceMinEdgePowerCck;
2052
2053			if (ee->ee_ctl[i] == 0)
2054				continue;
2055			if (ee->ee_ctl[i] == cfgCtl ||
2056			    cfgCtl == ((ee->ee_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) {
2057				rep = &ee->ee_rdEdgesPower[i * NUM_EDGES];
2058				twiceMinEdgePowerCck = ar5212GetMaxEdgePower(chan->channel, rep);
2059				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
2060					/* Find the minimum of all CTL edge powers that apply to this channel */
2061					twiceMaxEdgePowerCck = AH_MIN(twiceMaxEdgePowerCck, twiceMinEdgePowerCck);
2062				} else {
2063					twiceMaxEdgePowerCck = twiceMinEdgePowerCck;
2064					break;
2065				}
2066			}
2067		}
2068	} else {
2069		/* Set the 11B cck edge power to the one found before */
2070		twiceMaxEdgePowerCck = twiceMaxEdgePower;
2071	}
2072
2073	/* Get Antenna Gain reduction */
2074	if (IS_CHAN_5GHZ(chan)) {
2075		ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_5, &twiceAntennaGain);
2076	} else {
2077		ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_2, &twiceAntennaGain);
2078	}
2079	twiceAntennaReduction =
2080		ath_hal_getantennareduction(ah, chan, twiceAntennaGain);
2081
2082	if (IS_CHAN_OFDM(chan)) {
2083		/* Get final OFDM target powers */
2084		if (IS_CHAN_2GHZ(chan)) {
2085			ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11g,
2086				ee->ee_numTargetPwr_11g, &targetPowerOfdm);
2087		} else {
2088			ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11a,
2089				ee->ee_numTargetPwr_11a, &targetPowerOfdm);
2090		}
2091
2092		/* Get Maximum OFDM power */
2093		/* Minimum of target and edge powers */
2094		scaledPower = AH_MIN(twiceMaxEdgePower,
2095				twiceMaxRDPower - twiceAntennaReduction);
2096
2097		/*
2098		 * If turbo is set, reduce power to keep power
2099		 * consumption under 2 Watts.  Note that we always do
2100		 * this unless specially configured.  Then we limit
2101		 * power only for non-AP operation.
2102		 */
2103		if (IS_CHAN_TURBO(chan)
2104#ifdef AH_ENABLE_AP_SUPPORT
2105		    && AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP
2106#endif
2107		) {
2108			/*
2109			 * If turbo is set, reduce power to keep power
2110			 * consumption under 2 Watts
2111			 */
2112			if (ee->ee_version >= AR_EEPROM_VER3_1)
2113				scaledPower = AH_MIN(scaledPower,
2114					ee->ee_turbo2WMaxPower5);
2115			/*
2116			 * EEPROM version 4.0 added an additional
2117			 * constraint on 2.4GHz channels.
2118			 */
2119			if (ee->ee_version >= AR_EEPROM_VER4_0 &&
2120			    IS_CHAN_2GHZ(chan))
2121				scaledPower = AH_MIN(scaledPower,
2122					ee->ee_turbo2WMaxPower2);
2123		}
2124
2125		maxAvailPower = AH_MIN(scaledPower,
2126					targetPowerOfdm.twicePwr6_24);
2127
2128		/* Reduce power by max regulatory domain allowed restrictions */
2129		scaledPower = maxAvailPower - (tpcScaleReduction * 2);
2130		scaledPower = (scaledPower < 0) ? 0 : scaledPower;
2131		scaledPower = AH_MIN(scaledPower, powerLimit);
2132
2133		if (commit) {
2134			/* Set OFDM rates 9, 12, 18, 24 */
2135			r0 = rpow[0] = rpow[1] = rpow[2] = rpow[3] = rpow[4] = scaledPower;
2136
2137			/* Set OFDM rates 36, 48, 54, XR */
2138			rpow[5] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr36);
2139			rpow[6] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr48);
2140			r7 = rpow[7] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr54);
2141
2142			if (ee->ee_version >= AR_EEPROM_VER4_0) {
2143				/* Setup XR target power from EEPROM */
2144				rpow[15] = AH_MIN(scaledPower, IS_CHAN_2GHZ(chan) ?
2145						  ee->ee_xrTargetPower2 : ee->ee_xrTargetPower5);
2146			} else {
2147				/* XR uses 6mb power */
2148				rpow[15] = rpow[0];
2149			}
2150			ahp->ah_ofdmTxPower = *pMaxPower;
2151
2152		} else {
2153			r0 = scaledPower;
2154			r7 = AH_MIN(r0, targetPowerOfdm.twicePwr54);
2155		}
2156		*pMinPower = r7;
2157		*pMaxPower = r0;
2158
2159		HALDEBUG(ah, HAL_DEBUG_RFPARAM,
2160		    "%s: MaxRD: %d TurboMax: %d MaxCTL: %d "
2161		    "TPC_Reduction %d chan=%d (0x%x) maxAvailPower=%d pwr6_24=%d, maxPower=%d\n",
2162		    __func__, twiceMaxRDPower, ee->ee_turbo2WMaxPower5,
2163		    twiceMaxEdgePower, tpcScaleReduction * 2,
2164		    chan->channel, chan->channelFlags,
2165		    maxAvailPower, targetPowerOfdm.twicePwr6_24, *pMaxPower);
2166	}
2167
2168	if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
2169		/* Get final CCK target powers */
2170		ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11b,
2171			ee->ee_numTargetPwr_11b, &targetPowerCck);
2172
2173		/* Reduce power by max regulatory domain allowed restrictions */
2174		scaledPower = AH_MIN(twiceMaxEdgePowerCck,
2175			twiceMaxRDPower - twiceAntennaReduction);
2176		if (maxAvailPower < AH_MIN(scaledPower, targetPowerCck.twicePwr6_24))
2177			maxAvailPower = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24);
2178
2179		/* Reduce power by user selection */
2180		scaledPower = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24) - (tpcScaleReduction * 2);
2181		scaledPower = (scaledPower < 0) ? 0 : scaledPower;
2182		scaledPower = AH_MIN(scaledPower, powerLimit);
2183
2184		if (commit) {
2185			/* Set CCK rates 2L, 2S, 5.5L, 5.5S, 11L, 11S */
2186			rpow[8]  = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24);
2187			r9 = rpow[9]  = AH_MIN(scaledPower, targetPowerCck.twicePwr36);
2188			rpow[10] = rpow[9];
2189			rpow[11] = AH_MIN(scaledPower, targetPowerCck.twicePwr48);
2190			rpow[12] = rpow[11];
2191			r13 = rpow[13] = AH_MIN(scaledPower, targetPowerCck.twicePwr54);
2192			rpow[14] = rpow[13];
2193		} else {
2194			r9 = AH_MIN(scaledPower, targetPowerCck.twicePwr36);
2195			r13 = AH_MIN(scaledPower, targetPowerCck.twicePwr54);
2196		}
2197
2198		/* Set min/max power based off OFDM values or initialization */
2199		if (r13 < *pMinPower)
2200			*pMinPower = r13;
2201		if (r9 > *pMaxPower)
2202			*pMaxPower = r9;
2203
2204		HALDEBUG(ah, HAL_DEBUG_RFPARAM,
2205		    "%s: cck: MaxRD: %d MaxCTL: %d "
2206		    "TPC_Reduction %d chan=%d (0x%x) maxAvailPower=%d pwr6_24=%d, maxPower=%d\n",
2207		    __func__, twiceMaxRDPower, twiceMaxEdgePowerCck,
2208		    tpcScaleReduction * 2, chan->channel, chan->channelFlags,
2209		    maxAvailPower, targetPowerCck.twicePwr6_24, *pMaxPower);
2210	}
2211	if (commit) {
2212		ahp->ah_tx6PowerInHalfDbm = *pMaxPower;
2213		AH_PRIVATE(ah)->ah_maxPowerLevel = ahp->ah_tx6PowerInHalfDbm;
2214	}
2215	return AH_TRUE;
2216}
2217
2218HAL_BOOL
2219ar5212GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans)
2220{
2221	struct ath_hal_5212 *ahp = AH5212(ah);
2222	static const uint16_t tpcScaleReductionTable[5] =
2223		{ 0, 3, 6, 9, MAX_RATE_POWER };
2224	int16_t minPower, maxPower, tpcInDb, powerLimit;
2225	HAL_CHANNEL *chan;
2226	int i;
2227
2228	/*
2229	 * Get Pier table max and min powers.
2230	 */
2231	for (i = 0; i < nchans; i++) {
2232		chan = &chans[i];
2233		if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) {
2234			/* NB: rf code returns 1/4 dBm units, convert */
2235			chan->maxTxPower = maxPower / 2;
2236			chan->minTxPower = minPower / 2;
2237		} else {
2238			HALDEBUG(ah, HAL_DEBUG_ANY,
2239			    "%s: no min/max power for %u/0x%x\n",
2240			    __func__, chan->channel, chan->channelFlags);
2241			chan->maxTxPower = MAX_RATE_POWER;
2242			chan->minTxPower = 0;
2243		}
2244	}
2245	/*
2246	 * Now adjust to reflect any global scale and/or CTL's.
2247	 * (XXX is that correct?)
2248	 */
2249	powerLimit = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit);
2250	if (powerLimit >= MAX_RATE_POWER || powerLimit == 0)
2251		tpcInDb = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale];
2252	else
2253		tpcInDb = 0;
2254	for (i=0; i<nchans; i++) {
2255		chan = &chans[i];
2256		if (!ar5212SetRateTable(ah, (HAL_CHANNEL *) chan, tpcInDb, powerLimit,
2257					AH_FALSE, &minPower, &maxPower)) {
2258			HALDEBUG(ah, HAL_DEBUG_ANY,
2259			    "%s: unable to find max/min power\n",__func__);
2260			return AH_FALSE;
2261		}
2262		if (maxPower < chan->maxTxPower)
2263			chan->maxTxPower = maxPower;
2264		if (minPower < chan->minTxPower)
2265			chan->minTxPower = minPower;
2266	}
2267#ifdef AH_DEBUG
2268	for (i=0; i<nchans; i++) {
2269		HALDEBUG(ah, HAL_DEBUG_RESET,
2270		    "Chan %d: MaxPow = %d MinPow = %d\n",
2271		    chans[i].channel,chans[i].maxTxPower, chans[i].minTxPower);
2272	}
2273#endif
2274	return AH_TRUE;
2275}
2276
2277/*
2278 * Correct for the gain-delta between ofdm and cck mode target
2279 * powers. Write the results to the rate table and the power table.
2280 *
2281 *   Conventions :
2282 *   1. rpow[ii] is the integer value of 2*(desired power
2283 *    for the rate ii in dBm) to provide 0.5dB resolution. rate
2284 *    mapping is as following :
2285 *     [0..7]  --> ofdm 6, 9, .. 48, 54
2286 *     [8..14] --> cck 1L, 2L, 2S, .. 11L, 11S
2287 *     [15]    --> XR (all rates get the same power)
2288 *   2. powv[ii]  is the pcdac corresponding to ii/2 dBm.
2289 */
2290static void
2291ar5212CorrectGainDelta(struct ath_hal *ah, int twiceOfdmCckDelta)
2292{
2293#define	N(_a)	(sizeof(_a) / sizeof(_a[0]))
2294	struct ath_hal_5212 *ahp = AH5212(ah);
2295	const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
2296	int16_t ratesIndex[N(ahp->ah_ratesArray)];
2297	uint16_t ii, jj, iter;
2298	int32_t cckIndex;
2299	int16_t gainDeltaAdjust;
2300
2301	HALASSERT(ah->ah_magic == AR5212_MAGIC);
2302
2303	gainDeltaAdjust = ee->ee_cckOfdmGainDelta;
2304
2305	/* make a local copy of desired powers as initial indices */
2306	OS_MEMCPY(ratesIndex, ahp->ah_ratesArray, sizeof(ratesIndex));
2307
2308	/* fix only the CCK indices */
2309	for (ii = 8; ii < 15; ii++) {
2310		/* apply a gain_delta correction of -15 for CCK */
2311		ratesIndex[ii] -= gainDeltaAdjust;
2312
2313		/* Now check for contention with all ofdm target powers */
2314		jj = 0;
2315		iter = 0;
2316		/* indicates not all ofdm rates checked forcontention yet */
2317		while (jj < 16) {
2318			if (ratesIndex[ii] < 0)
2319				ratesIndex[ii] = 0;
2320			if (jj == 8) {		/* skip CCK rates */
2321				jj = 15;
2322				continue;
2323			}
2324			if (ratesIndex[ii] == ahp->ah_ratesArray[jj]) {
2325				if (ahp->ah_ratesArray[jj] == 0)
2326					ratesIndex[ii]++;
2327				else if (iter > 50) {
2328					/*
2329					 * To avoid pathological case of of
2330					 * dm target powers 0 and 0.5dBm
2331					 */
2332					ratesIndex[ii]++;
2333				} else
2334					ratesIndex[ii]--;
2335				/* check with all rates again */
2336				jj = 0;
2337				iter++;
2338			} else
2339				jj++;
2340		}
2341		if (ratesIndex[ii] >= PWR_TABLE_SIZE)
2342			ratesIndex[ii] = PWR_TABLE_SIZE -1;
2343		cckIndex = ahp->ah_ratesArray[ii] - twiceOfdmCckDelta;
2344		if (cckIndex < 0)
2345			cckIndex = 0;
2346
2347		/*
2348		 * Validate that the indexes for the powv are not
2349		 * out of bounds.
2350		 */
2351		HALASSERT(cckIndex < PWR_TABLE_SIZE);
2352		HALASSERT(ratesIndex[ii] < PWR_TABLE_SIZE);
2353		ahp->ah_pcdacTable[ratesIndex[ii]] =
2354			ahp->ah_pcdacTable[cckIndex];
2355	}
2356	/* Override rate per power table with new values */
2357	for (ii = 8; ii < 15; ii++)
2358		ahp->ah_ratesArray[ii] = ratesIndex[ii];
2359#undef N
2360}
2361
2362/*
2363 * Find the maximum conformance test limit for the given channel and CTL info
2364 */
2365static uint16_t
2366ar5212GetMaxEdgePower(uint16_t channel, const RD_EDGES_POWER *pRdEdgesPower)
2367{
2368	/* temp array for holding edge channels */
2369	uint16_t tempChannelList[NUM_EDGES];
2370	uint16_t clo, chi, twiceMaxEdgePower;
2371	int i, numEdges;
2372
2373	/* Get the edge power */
2374	for (i = 0; i < NUM_EDGES; i++) {
2375		if (pRdEdgesPower[i].rdEdge == 0)
2376			break;
2377		tempChannelList[i] = pRdEdgesPower[i].rdEdge;
2378	}
2379	numEdges = i;
2380
2381	ar5212GetLowerUpperValues(channel, tempChannelList,
2382		numEdges, &clo, &chi);
2383	/* Get the index for the lower channel */
2384	for (i = 0; i < numEdges && clo != tempChannelList[i]; i++)
2385		;
2386	/* Is lower channel ever outside the rdEdge? */
2387	HALASSERT(i != numEdges);
2388
2389	if ((clo == chi && clo == channel) || (pRdEdgesPower[i].flag)) {
2390		/*
2391		 * If there's an exact channel match or an inband flag set
2392		 * on the lower channel use the given rdEdgePower
2393		 */
2394		twiceMaxEdgePower = pRdEdgesPower[i].twice_rdEdgePower;
2395		HALASSERT(twiceMaxEdgePower > 0);
2396	} else
2397		twiceMaxEdgePower = MAX_RATE_POWER;
2398	return twiceMaxEdgePower;
2399}
2400
2401/*
2402 * Returns interpolated or the scaled up interpolated value
2403 */
2404static uint16_t
2405interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
2406	uint16_t targetLeft, uint16_t targetRight)
2407{
2408	uint16_t rv;
2409	int16_t lRatio;
2410
2411	/* to get an accurate ratio, always scale, if want to scale, then don't scale back down */
2412	if ((targetLeft * targetRight) == 0)
2413		return 0;
2414
2415	if (srcRight != srcLeft) {
2416		/*
2417		 * Note the ratio always need to be scaled,
2418		 * since it will be a fraction.
2419		 */
2420		lRatio = (target - srcLeft) * EEP_SCALE / (srcRight - srcLeft);
2421		if (lRatio < 0) {
2422		    /* Return as Left target if value would be negative */
2423		    rv = targetLeft;
2424		} else if (lRatio > EEP_SCALE) {
2425		    /* Return as Right target if Ratio is greater than 100% (SCALE) */
2426		    rv = targetRight;
2427		} else {
2428			rv = (lRatio * targetRight + (EEP_SCALE - lRatio) *
2429					targetLeft) / EEP_SCALE;
2430		}
2431	} else {
2432		rv = targetLeft;
2433	}
2434	return rv;
2435}
2436
2437/*
2438 * Return the four rates of target power for the given target power table
2439 * channel, and number of channels
2440 */
2441static void
2442ar5212GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL *chan,
2443	const TRGT_POWER_INFO *powInfo,
2444	uint16_t numChannels, TRGT_POWER_INFO *pNewPower)
2445{
2446	/* temp array for holding target power channels */
2447	uint16_t tempChannelList[NUM_TEST_FREQUENCIES];
2448	uint16_t clo, chi, ixlo, ixhi;
2449	int i;
2450
2451	/* Copy the target powers into the temp channel list */
2452	for (i = 0; i < numChannels; i++)
2453		tempChannelList[i] = powInfo[i].testChannel;
2454
2455	ar5212GetLowerUpperValues(chan->channel, tempChannelList,
2456		numChannels, &clo, &chi);
2457
2458	/* Get the indices for the channel */
2459	ixlo = ixhi = 0;
2460	for (i = 0; i < numChannels; i++) {
2461		if (clo == tempChannelList[i]) {
2462			ixlo = i;
2463		}
2464		if (chi == tempChannelList[i]) {
2465			ixhi = i;
2466			break;
2467		}
2468	}
2469
2470	/*
2471	 * Get the lower and upper channels, target powers,
2472	 * and interpolate between them.
2473	 */
2474	pNewPower->twicePwr6_24 = interpolate(chan->channel, clo, chi,
2475		powInfo[ixlo].twicePwr6_24, powInfo[ixhi].twicePwr6_24);
2476	pNewPower->twicePwr36 = interpolate(chan->channel, clo, chi,
2477		powInfo[ixlo].twicePwr36, powInfo[ixhi].twicePwr36);
2478	pNewPower->twicePwr48 = interpolate(chan->channel, clo, chi,
2479		powInfo[ixlo].twicePwr48, powInfo[ixhi].twicePwr48);
2480	pNewPower->twicePwr54 = interpolate(chan->channel, clo, chi,
2481		powInfo[ixlo].twicePwr54, powInfo[ixhi].twicePwr54);
2482}
2483
2484/*
2485 * Search a list for a specified value v that is within
2486 * EEP_DELTA of the search values.  Return the closest
2487 * values in the list above and below the desired value.
2488 * EEP_DELTA is a factional value; everything is scaled
2489 * so only integer arithmetic is used.
2490 *
2491 * NB: the input list is assumed to be sorted in ascending order
2492 */
2493void
2494ar5212GetLowerUpperValues(uint16_t v, uint16_t *lp, uint16_t listSize,
2495                          uint16_t *vlo, uint16_t *vhi)
2496{
2497	uint32_t target = v * EEP_SCALE;
2498	uint16_t *ep = lp+listSize;
2499
2500	/*
2501	 * Check first and last elements for out-of-bounds conditions.
2502	 */
2503	if (target < (uint32_t)(lp[0] * EEP_SCALE - EEP_DELTA)) {
2504		*vlo = *vhi = lp[0];
2505		return;
2506	}
2507	if (target > (uint32_t)(ep[-1] * EEP_SCALE + EEP_DELTA)) {
2508		*vlo = *vhi = ep[-1];
2509		return;
2510	}
2511
2512	/* look for value being near or between 2 values in list */
2513	for (; lp < ep; lp++) {
2514		/*
2515		 * If value is close to the current value of the list
2516		 * then target is not between values, it is one of the values
2517		 */
2518		if (abs(lp[0] * EEP_SCALE - target) < EEP_DELTA) {
2519			*vlo = *vhi = lp[0];
2520			return;
2521		}
2522		/*
2523		 * Look for value being between current value and next value
2524		 * if so return these 2 values
2525		 */
2526		if (target < (uint32_t)(lp[1] * EEP_SCALE - EEP_DELTA)) {
2527			*vlo = lp[0];
2528			*vhi = lp[1];
2529			return;
2530		}
2531	}
2532	HALASSERT(AH_FALSE);		/* should not reach here */
2533}
2534
2535/*
2536 * Perform analog "swizzling" of parameters into their location
2537 *
2538 * NB: used by RF backends
2539 */
2540void
2541ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32, uint32_t numBits,
2542                     uint32_t firstBit, uint32_t column)
2543{
2544#define	MAX_ANALOG_START	319		/* XXX */
2545	uint32_t tmp32, mask, arrayEntry, lastBit;
2546	int32_t bitPosition, bitsLeft;
2547
2548	HALASSERT(column <= 3);
2549	HALASSERT(numBits <= 32);
2550	HALASSERT(firstBit + numBits <= MAX_ANALOG_START);
2551
2552	tmp32 = ath_hal_reverseBits(reg32, numBits);
2553	arrayEntry = (firstBit - 1) / 8;
2554	bitPosition = (firstBit - 1) % 8;
2555	bitsLeft = numBits;
2556	while (bitsLeft > 0) {
2557		lastBit = (bitPosition + bitsLeft > 8) ?
2558			8 : bitPosition + bitsLeft;
2559		mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
2560			(column * 8);
2561		rfBuf[arrayEntry] &= ~mask;
2562		rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
2563			(column * 8)) & mask;
2564		bitsLeft -= 8 - bitPosition;
2565		tmp32 = tmp32 >> (8 - bitPosition);
2566		bitPosition = 0;
2567		arrayEntry++;
2568	}
2569#undef MAX_ANALOG_START
2570}
2571
2572/*
2573 * Sets the rate to duration values in MAC - used for multi-
2574 * rate retry.
2575 * The rate duration table needs to cover all valid rate codes;
2576 * the 11g table covers all ofdm rates, while the 11b table
2577 * covers all cck rates => all valid rates get covered between
2578 * these two mode's ratetables!
2579 * But if we're turbo, the ofdm phy is replaced by the turbo phy
2580 * and cck is not valid with turbo => all rates get covered
2581 * by the turbo ratetable only
2582 */
2583void
2584ar5212SetRateDurationTable(struct ath_hal *ah, HAL_CHANNEL *chan)
2585{
2586	const HAL_RATE_TABLE *rt;
2587	int i;
2588
2589	/* NB: band doesn't matter for 1/2 and 1/4 rate */
2590	if (IS_CHAN_HALF_RATE(chan)) {
2591		rt = ar5212GetRateTable(ah, HAL_MODE_11A_HALF_RATE);
2592	} else if (IS_CHAN_QUARTER_RATE(chan)) {
2593		rt = ar5212GetRateTable(ah, HAL_MODE_11A_QUARTER_RATE);
2594	} else {
2595		rt = ar5212GetRateTable(ah,
2596			IS_CHAN_TURBO(chan) ? HAL_MODE_TURBO : HAL_MODE_11G);
2597	}
2598
2599	for (i = 0; i < rt->rateCount; ++i)
2600		OS_REG_WRITE(ah,
2601			AR_RATE_DURATION(rt->info[i].rateCode),
2602			ath_hal_computetxtime(ah, rt,
2603				WLAN_CTRL_FRAME_SIZE,
2604				rt->info[i].controlRate, AH_FALSE));
2605	if (!IS_CHAN_TURBO(chan)) {
2606		/* 11g Table is used to cover the CCK rates. */
2607		rt = ar5212GetRateTable(ah, HAL_MODE_11G);
2608		for (i = 0; i < rt->rateCount; ++i) {
2609			uint32_t reg = AR_RATE_DURATION(rt->info[i].rateCode);
2610
2611			if (rt->info[i].phy != IEEE80211_T_CCK)
2612				continue;
2613
2614			OS_REG_WRITE(ah, reg,
2615				ath_hal_computetxtime(ah, rt,
2616					WLAN_CTRL_FRAME_SIZE,
2617					rt->info[i].controlRate, AH_FALSE));
2618			/* cck rates have short preamble option also */
2619			if (rt->info[i].shortPreamble) {
2620				reg += rt->info[i].shortPreamble << 2;
2621				OS_REG_WRITE(ah, reg,
2622					ath_hal_computetxtime(ah, rt,
2623						WLAN_CTRL_FRAME_SIZE,
2624						rt->info[i].controlRate,
2625						AH_TRUE));
2626			}
2627		}
2628	}
2629}
2630
2631/* Adjust various register settings based on half/quarter rate clock setting.
2632 * This includes: +USEC, TX/RX latency,
2633 *                + IFS params: slot, eifs, misc etc.
2634 */
2635void
2636ar5212SetIFSTiming(struct ath_hal *ah, HAL_CHANNEL *chan)
2637{
2638	uint32_t txLat, rxLat, usec, slot, refClock, eifs, init_usec;
2639
2640	HALASSERT(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan));
2641
2642	refClock = OS_REG_READ(ah, AR_USEC) & AR_USEC_USEC32;
2643	if (IS_CHAN_HALF_RATE(chan)) {
2644		slot = IFS_SLOT_HALF_RATE;
2645		rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S;
2646		txLat = TX_HALF_RATE_LATENCY << AR5212_USEC_TX_LAT_S;
2647		usec = HALF_RATE_USEC;
2648		eifs = IFS_EIFS_HALF_RATE;
2649		init_usec = INIT_USEC >> 1;
2650	} else { /* quarter rate */
2651		slot = IFS_SLOT_QUARTER_RATE;
2652		rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S;
2653		txLat = TX_QUARTER_RATE_LATENCY << AR5212_USEC_TX_LAT_S;
2654		usec = QUARTER_RATE_USEC;
2655		eifs = IFS_EIFS_QUARTER_RATE;
2656		init_usec = INIT_USEC >> 2;
2657	}
2658
2659	OS_REG_WRITE(ah, AR_USEC, (usec | refClock | txLat | rxLat));
2660	OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot);
2661	OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs);
2662	OS_REG_RMW_FIELD(ah, AR_D_GBL_IFS_MISC,
2663				AR_D_GBL_IFS_MISC_USEC_DURATION, init_usec);
2664}
2665#endif /* AH_SUPPORT_AR5212 */
2666