ar5416_reset.c revision 227741
1/*
2 * Copyright (c) 2002-2009 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 * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c 227741 2011-11-19 21:12:35Z adrian $
18 */
19#include "opt_ah.h"
20
21#include "ah.h"
22#include "ah_internal.h"
23#include "ah_devid.h"
24
25#include "ah_eeprom_v14.h"
26
27#include "ar5416/ar5416.h"
28#include "ar5416/ar5416reg.h"
29#include "ar5416/ar5416phy.h"
30
31/* Eeprom versioning macros. Returns true if the version is equal or newer than the ver specified */
32#define	EEP_MINOR(_ah) \
33	(AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK)
34#define IS_EEP_MINOR_V2(_ah)	(EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_2)
35#define IS_EEP_MINOR_V3(_ah)	(EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_3)
36
37/* Additional Time delay to wait after activiting the Base band */
38#define BASE_ACTIVATE_DELAY	100	/* 100 usec */
39#define PLL_SETTLE_DELAY	300	/* 300 usec */
40#define RTC_PLL_SETTLE_DELAY    1000    /* 1 ms     */
41
42static void ar5416InitDMA(struct ath_hal *ah);
43static void ar5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *);
44static void ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode);
45static void ar5416InitQoS(struct ath_hal *ah);
46static void ar5416InitUserSettings(struct ath_hal *ah);
47static void ar5416UpdateChainMasks(struct ath_hal *ah, HAL_BOOL is_ht);
48static void ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *);
49
50#if 0
51static HAL_BOOL	ar5416ChannelChange(struct ath_hal *, const struct ieee80211_channel *);
52#endif
53static void ar5416SetDeltaSlope(struct ath_hal *, const struct ieee80211_channel *);
54
55static HAL_BOOL ar5416SetResetPowerOn(struct ath_hal *ah);
56static HAL_BOOL ar5416SetReset(struct ath_hal *ah, int type);
57static HAL_BOOL ar5416SetPowerPerRateTable(struct ath_hal *ah,
58	struct ar5416eeprom *pEepData,
59	const struct ieee80211_channel *chan, int16_t *ratesArray,
60	uint16_t cfgCtl, uint16_t AntennaReduction,
61	uint16_t twiceMaxRegulatoryPower,
62	uint16_t powerLimit);
63static void ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan);
64static void ar5416MarkPhyInactive(struct ath_hal *ah);
65
66/*
67 * Places the device in and out of reset and then places sane
68 * values in the registers based on EEPROM config, initialization
69 * vectors (as determined by the mode), and station configuration
70 *
71 * bChannelChange is used to preserve DMA/PCU registers across
72 * a HW Reset during channel change.
73 */
74HAL_BOOL
75ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
76	struct ieee80211_channel *chan,
77	HAL_BOOL bChannelChange, HAL_STATUS *status)
78{
79#define	N(a)	(sizeof (a) / sizeof (a[0]))
80#define	FAIL(_code)	do { ecode = _code; goto bad; } while (0)
81	struct ath_hal_5212 *ahp = AH5212(ah);
82	HAL_CHANNEL_INTERNAL *ichan;
83	uint32_t saveDefAntenna, saveLedState;
84	uint32_t macStaId1;
85	uint16_t rfXpdGain[2];
86	HAL_STATUS ecode;
87	uint32_t powerVal, rssiThrReg;
88	uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow;
89	int i;
90	uint64_t tsf = 0;
91
92	OS_MARK(ah, AH_MARK_RESET, bChannelChange);
93
94	/* Bring out of sleep mode */
95	if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
96		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip did not wakeup\n",
97		    __func__);
98		FAIL(HAL_EIO);
99	}
100
101	/*
102	 * Map public channel to private.
103	 */
104	ichan = ath_hal_checkchannel(ah, chan);
105	if (ichan == AH_NULL)
106		FAIL(HAL_EINVAL);
107	switch (opmode) {
108	case HAL_M_STA:
109	case HAL_M_IBSS:
110	case HAL_M_HOSTAP:
111	case HAL_M_MONITOR:
112		break;
113	default:
114		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n",
115		    __func__, opmode);
116		FAIL(HAL_EINVAL);
117		break;
118	}
119	HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1);
120
121	/* XXX Turn on fast channel change for 5416 */
122	/*
123	 * Preserve the bmiss rssi threshold and count threshold
124	 * across resets
125	 */
126	rssiThrReg = OS_REG_READ(ah, AR_RSSI_THR);
127	/* If reg is zero, first time thru set to default val */
128	if (rssiThrReg == 0)
129		rssiThrReg = INIT_RSSI_THR;
130
131	/*
132	 * Preserve the antenna on a channel change
133	 */
134	saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
135	if (saveDefAntenna == 0)		/* XXX magic constants */
136		saveDefAntenna = 1;
137
138	/* Save hardware flag before chip reset clears the register */
139	macStaId1 = OS_REG_READ(ah, AR_STA_ID1) &
140		(AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT);
141
142	/* Save led state from pci config register */
143	saveLedState = OS_REG_READ(ah, AR_MAC_LED) &
144		(AR_MAC_LED_ASSOC | AR_MAC_LED_MODE |
145		 AR_MAC_LED_BLINK_THRESH_SEL | AR_MAC_LED_BLINK_SLOW);
146
147	/* For chips on which the RTC reset is done, save TSF before it gets cleared */
148	if (AR_SREV_HOWL(ah) ||
149	    (AR_SREV_MERLIN(ah) &&
150	     ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) ||
151	    (ah->ah_config.ah_force_full_reset))
152		tsf = ar5416GetTsf64(ah);
153
154	/* Mark PHY as inactive; marked active in ar5416InitBB() */
155	ar5416MarkPhyInactive(ah);
156
157	if (!ar5416ChipReset(ah, chan)) {
158		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
159		FAIL(HAL_EIO);
160	}
161
162	/* Restore TSF */
163	if (tsf)
164		ar5416SetTsf64(ah, tsf);
165
166	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
167	if (AR_SREV_MERLIN_10_OR_LATER(ah))
168		OS_REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
169
170	AH5416(ah)->ah_writeIni(ah, chan);
171
172	if(AR_SREV_KIWI_13_OR_LATER(ah) ) {
173		/* Enable ASYNC FIFO */
174		OS_REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
175		    AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
176		OS_REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
177		OS_REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
178		    AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
179		OS_REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
180		    AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
181	}
182
183	/* Override ini values (that can be overriden in this fashion) */
184	ar5416OverrideIni(ah, chan);
185
186	/* Setup 11n MAC/Phy mode registers */
187	ar5416Set11nRegs(ah, chan);
188
189	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
190
191	/*
192	 * Some AR91xx SoC devices frequently fail to accept TSF writes
193	 * right after the chip reset. When that happens, write a new
194	 * value after the initvals have been applied, with an offset
195	 * based on measured time difference
196	 */
197	if (AR_SREV_HOWL(ah) && (ar5416GetTsf64(ah) < tsf)) {
198		tsf += 1500;
199		ar5416SetTsf64(ah, tsf);
200	}
201
202	HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_DAG_CTRLCCK=0x%x\n",
203		__func__, OS_REG_READ(ah,AR_PHY_DAG_CTRLCCK));
204	HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_ADC_CTL=0x%x\n",
205		__func__, OS_REG_READ(ah,AR_PHY_ADC_CTL));
206
207	/*
208	 * Setup ah_tx_chainmask / ah_rx_chainmask before we fiddle
209	 * with enabling the TX/RX radio chains.
210	 */
211	ar5416UpdateChainMasks(ah, IEEE80211_IS_CHAN_HT(chan));
212	/*
213	 * This routine swaps the analog chains - it should be done
214	 * before any radio register twiddling is done.
215	 */
216	ar5416InitChainMasks(ah);
217
218	/* Setup the open-loop power calibration if required */
219	if (ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) {
220		AH5416(ah)->ah_olcInit(ah);
221		AH5416(ah)->ah_olcTempCompensation(ah);
222	}
223
224	/* Setup the transmit power values. */
225	if (!ah->ah_setTxPower(ah, chan, rfXpdGain)) {
226		HALDEBUG(ah, HAL_DEBUG_ANY,
227		    "%s: error init'ing transmit power\n", __func__);
228		FAIL(HAL_EIO);
229	}
230
231	/* Write the analog registers */
232	if (!ahp->ah_rfHal->setRfRegs(ah, chan,
233	    IEEE80211_IS_CHAN_2GHZ(chan) ? 2: 1, rfXpdGain)) {
234		HALDEBUG(ah, HAL_DEBUG_ANY,
235		    "%s: ar5212SetRfRegs failed\n", __func__);
236		FAIL(HAL_EIO);
237	}
238
239	/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
240	if (IEEE80211_IS_CHAN_OFDM(chan)|| IEEE80211_IS_CHAN_HT(chan))
241		ar5416SetDeltaSlope(ah, chan);
242
243	AH5416(ah)->ah_spurMitigate(ah, chan);
244
245	/* Setup board specific options for EEPROM version 3 */
246	if (!ah->ah_setBoardValues(ah, chan)) {
247		HALDEBUG(ah, HAL_DEBUG_ANY,
248		    "%s: error setting board options\n", __func__);
249		FAIL(HAL_EIO);
250	}
251
252	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
253
254	OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
255	OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
256		| macStaId1
257		| AR_STA_ID1_RTS_USE_DEF
258		| ahp->ah_staId1Defaults
259	);
260	ar5212SetOperatingMode(ah, opmode);
261
262	/* Set Venice BSSID mask according to current state */
263	OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
264	OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
265
266	/* Restore previous led state */
267	if (AR_SREV_HOWL(ah))
268		OS_REG_WRITE(ah, AR_MAC_LED,
269		    AR_MAC_LED_ASSOC_ACTIVE | AR_CFG_SCLK_32KHZ);
270	else
271		OS_REG_WRITE(ah, AR_MAC_LED, OS_REG_READ(ah, AR_MAC_LED) |
272		    saveLedState);
273
274        /* Start TSF2 for generic timer 8-15 */
275#ifdef	NOTYET
276	if (AR_SREV_KIWI(ah))
277		ar5416StartTsf2(ah);
278#endif
279
280	/* Restore previous antenna */
281	OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
282
283	/* then our BSSID and associate id */
284	OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
285	OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4) |
286	    (ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S);
287
288	/* Restore bmiss rssi & count thresholds */
289	OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr);
290
291	OS_REG_WRITE(ah, AR_ISR, ~0);		/* cleared on write */
292
293	/* Restore bmiss rssi & count thresholds */
294	OS_REG_WRITE(ah, AR_RSSI_THR, rssiThrReg);
295
296	if (!ar5212SetChannel(ah, chan))
297		FAIL(HAL_EIO);
298
299	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
300
301	/* Set 1:1 QCU to DCU mapping for all queues */
302	for (i = 0; i < AR_NUM_DCU; i++)
303		OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
304
305	ahp->ah_intrTxqs = 0;
306	for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++)
307		ah->ah_resetTxQueue(ah, i);
308
309	ar5416InitIMR(ah, opmode);
310	ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1);
311	ar5416InitQoS(ah);
312	/* This may override the AR_DIAG_SW register */
313	ar5416InitUserSettings(ah);
314
315	if (AR_SREV_KIWI_13_OR_LATER(ah)) {
316		/*
317		 * Enable ASYNC FIFO
318		 *
319		 * If Async FIFO is enabled, the following counters change
320		 * as MAC now runs at 117 Mhz instead of 88/44MHz when
321		 * async FIFO is disabled.
322		 *
323		 * Overwrite the delay/timeouts initialized in ProcessIni()
324		 * above.
325		 */
326		OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
327		    AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
328		OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
329		    AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
330		OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
331		    AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
332
333		OS_REG_WRITE(ah, AR_TIME_OUT,
334		    AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
335		OS_REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
336
337		OS_REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
338		    AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
339		OS_REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
340		    AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
341	}
342
343	if (AR_SREV_KIWI_13_OR_LATER(ah)) {
344		/* Enable AGGWEP to accelerate encryption engine */
345		OS_REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
346		    AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
347	}
348
349
350	/*
351	 * disable seq number generation in hw
352	 */
353	 OS_REG_WRITE(ah, AR_STA_ID1,
354	     OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
355
356	ar5416InitDMA(ah);
357
358	/*
359	 * program OBS bus to see MAC interrupts
360	 */
361	OS_REG_WRITE(ah, AR_OBS, 8);
362
363	/*
364	 * Disable the "general" TX/RX mitigation timers.
365	 */
366	OS_REG_WRITE(ah, AR_MIRT, 0);
367
368#ifdef	AH_AR5416_INTERRUPT_MITIGATION
369	/*
370	 * This initialises the RX interrupt mitigation timers.
371	 *
372	 * The mitigation timers begin at idle and are triggered
373	 * upon the RXOK of a single frame (or sub-frame, for A-MPDU.)
374	 * Then, the RX mitigation interrupt will fire:
375	 *
376	 * + 250uS after the last RX'ed frame, or
377	 * + 700uS after the first RX'ed frame
378	 *
379	 * Thus, the LAST field dictates the extra latency
380	 * induced by the RX mitigation method and the FIRST
381	 * field dictates how long to delay before firing an
382	 * RX mitigation interrupt.
383	 *
384	 * Please note this only seems to be for RXOK frames;
385	 * not CRC or PHY error frames.
386	 *
387	 */
388	OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 250);
389	OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 700);
390#endif
391	ar5416InitBB(ah, chan);
392
393	/* Setup compression registers */
394	ar5212SetCompRegs(ah);		/* XXX not needed? */
395
396	/*
397	 * 5416 baseband will check the per rate power table
398	 * and select the lower of the two
399	 */
400	ackTpcPow = 63;
401	ctsTpcPow = 63;
402	chirpTpcPow = 63;
403	powerVal = SM(ackTpcPow, AR_TPC_ACK) |
404		SM(ctsTpcPow, AR_TPC_CTS) |
405		SM(chirpTpcPow, AR_TPC_CHIRP);
406	OS_REG_WRITE(ah, AR_TPC, powerVal);
407
408	if (!ar5416InitCal(ah, chan))
409		FAIL(HAL_ESELFTEST);
410
411	ar5416RestoreChainMask(ah);
412
413	AH_PRIVATE(ah)->ah_opmode = opmode;	/* record operating mode */
414
415	if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
416		chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
417
418	if (AR_SREV_HOWL(ah)) {
419		/*
420		 * Enable the MBSSID block-ack fix for HOWL.
421		 * This feature is only supported on Howl 1.4, but it is safe to
422		 * set bit 22 of STA_ID1 on other Howl revisions (1.1, 1.2, 1.3),
423		 * since bit 22 is unused in those Howl revisions.
424		 */
425		unsigned int reg;
426		reg = (OS_REG_READ(ah, AR_STA_ID1) | (1<<22));
427		OS_REG_WRITE(ah,AR_STA_ID1, reg);
428		ath_hal_printf(ah, "MBSSID Set bit 22 of AR_STA_ID 0x%x\n", reg);
429	}
430
431	HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
432
433	OS_MARK(ah, AH_MARK_RESET_DONE, 0);
434
435	return AH_TRUE;
436bad:
437	OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
438	if (status != AH_NULL)
439		*status = ecode;
440	return AH_FALSE;
441#undef FAIL
442#undef N
443}
444
445#if 0
446/*
447 * This channel change evaluates whether the selected hardware can
448 * perform a synthesizer-only channel change (no reset).  If the
449 * TX is not stopped, or the RFBus cannot be granted in the given
450 * time, the function returns false as a reset is necessary
451 */
452HAL_BOOL
453ar5416ChannelChange(struct ath_hal *ah, const structu ieee80211_channel *chan)
454{
455	uint32_t       ulCount;
456	uint32_t   data, synthDelay, qnum;
457	uint16_t   rfXpdGain[4];
458	struct ath_hal_5212 *ahp = AH5212(ah);
459	HAL_CHANNEL_INTERNAL *ichan;
460
461	/*
462	 * Map public channel to private.
463	 */
464	ichan = ath_hal_checkchannel(ah, chan);
465
466	/* TX must be stopped or RF Bus grant will not work */
467	for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) {
468		if (ar5212NumTxPending(ah, qnum)) {
469			HALDEBUG(ah, HAL_DEBUG_ANY,
470			    "%s: frames pending on queue %d\n", __func__, qnum);
471			return AH_FALSE;
472		}
473	}
474
475	/*
476	 * Kill last Baseband Rx Frame - Request analog bus grant
477	 */
478	OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST);
479	if (!ath_hal_wait(ah, AR_PHY_RFBUS_GNT, AR_PHY_RFBUS_GRANT_EN, AR_PHY_RFBUS_GRANT_EN)) {
480		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: could not kill baseband rx\n",
481		    __func__);
482		return AH_FALSE;
483	}
484
485	ar5416Set11nRegs(ah, chan);	/* NB: setup 5416-specific regs */
486
487	/* Change the synth */
488	if (!ar5212SetChannel(ah, chan))
489		return AH_FALSE;
490
491	/* Setup the transmit power values. */
492	if (!ah->ah_setTxPower(ah, chan, rfXpdGain)) {
493		HALDEBUG(ah, HAL_DEBUG_ANY,
494		    "%s: error init'ing transmit power\n", __func__);
495		return AH_FALSE;
496	}
497
498	/*
499	 * Wait for the frequency synth to settle (synth goes on
500	 * via PHY_ACTIVE_EN).  Read the phy active delay register.
501	 * Value is in 100ns increments.
502	 */
503	data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
504	if (IS_CHAN_CCK(ichan)) {
505		synthDelay = (4 * data) / 22;
506	} else {
507		synthDelay = data / 10;
508	}
509
510	OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
511
512	/* Release the RFBus Grant */
513	OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
514
515	/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
516	if (IEEE80211_IS_CHAN_OFDM(ichan)|| IEEE80211_IS_CHAN_HT(chan)) {
517		HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3);
518		ar5212SetSpurMitigation(ah, chan);
519		ar5416SetDeltaSlope(ah, chan);
520	}
521
522	/* XXX spur mitigation for Melin */
523
524	if (!IEEE80211_IS_CHAN_DFS(chan))
525		chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
526
527	ichan->channel_time = 0;
528	ichan->tsf_last = ar5416GetTsf64(ah);
529	ar5212TxEnable(ah, AH_TRUE);
530	return AH_TRUE;
531}
532#endif
533
534static void
535ar5416InitDMA(struct ath_hal *ah)
536{
537	struct ath_hal_5212 *ahp = AH5212(ah);
538
539	/*
540	 * set AHB_MODE not to do cacheline prefetches
541	 */
542	OS_REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN);
543
544	/*
545	 * let mac dma reads be in 128 byte chunks
546	 */
547	OS_REG_WRITE(ah, AR_TXCFG,
548		(OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK) | AR_TXCFG_DMASZ_128B);
549
550	/*
551	 * let mac dma writes be in 128 byte chunks
552	 */
553	OS_REG_WRITE(ah, AR_RXCFG,
554		(OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK) | AR_RXCFG_DMASZ_128B);
555
556	/* restore TX trigger level */
557	OS_REG_WRITE(ah, AR_TXCFG,
558		(OS_REG_READ(ah, AR_TXCFG) &~ AR_FTRIG) |
559		    SM(ahp->ah_txTrigLev, AR_FTRIG));
560
561	/*
562	 * Setup receive FIFO threshold to hold off TX activities
563	 */
564	OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
565
566	/*
567	 * reduce the number of usable entries in PCU TXBUF to avoid
568	 * wrap around.
569	 */
570	if (AR_SREV_KITE(ah))
571		/*
572		 * For AR9285 the number of Fifos are reduced to half.
573		 * So set the usable tx buf size also to half to
574		 * avoid data/delimiter underruns
575		 */
576		OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
577	else
578		OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE);
579}
580
581static void
582ar5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *chan)
583{
584	uint32_t synthDelay;
585
586	/*
587	 * Wait for the frequency synth to settle (synth goes on
588	 * via AR_PHY_ACTIVE_EN).  Read the phy active delay register.
589	 * Value is in 100ns increments.
590	  */
591	synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
592	if (IEEE80211_IS_CHAN_CCK(chan)) {
593		synthDelay = (4 * synthDelay) / 22;
594	} else {
595		synthDelay /= 10;
596	}
597
598	/* Turn on PLL on 5416 */
599	HALDEBUG(ah, HAL_DEBUG_RESET, "%s %s channel\n",
600	    __func__, IEEE80211_IS_CHAN_5GHZ(chan) ? "5GHz" : "2GHz");
601
602	/* Activate the PHY (includes baseband activate and synthesizer on) */
603	OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
604
605	/*
606	 * If the AP starts the calibration before the base band timeout
607	 * completes  we could get rx_clear false triggering.  Add an
608	 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
609	 * does not happen.
610	 */
611	if (IEEE80211_IS_CHAN_HALF(chan)) {
612		OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);
613	} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
614		OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);
615	} else {
616		OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
617	}
618}
619
620static void
621ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode)
622{
623	struct ath_hal_5212 *ahp = AH5212(ah);
624
625	/*
626	 * Setup interrupt handling.  Note that ar5212ResetTxQueue
627	 * manipulates the secondary IMR's as queues are enabled
628	 * and disabled.  This is done with RMW ops to insure the
629	 * settings we make here are preserved.
630	 */
631        ahp->ah_maskReg = AR_IMR_TXERR | AR_IMR_TXURN
632			| AR_IMR_RXERR | AR_IMR_RXORN
633                        | AR_IMR_BCNMISC;
634
635#ifdef	AH_AR5416_INTERRUPT_MITIGATION
636	ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
637#else
638	ahp->ah_maskReg |= AR_IMR_RXOK;
639#endif
640	ahp->ah_maskReg |= AR_IMR_TXOK;
641
642	if (opmode == HAL_M_HOSTAP)
643		ahp->ah_maskReg |= AR_IMR_MIB;
644	OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
645
646#ifdef  ADRIAN_NOTYET
647	/* This is straight from ath9k */
648	if (! AR_SREV_HOWL(ah)) {
649		OS_REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
650		OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
651		OS_REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
652	}
653#endif
654
655	/* Enable bus errors that are OR'd to set the HIUERR bit */
656#if 0
657	OS_REG_WRITE(ah, AR_IMR_S2,
658	    	OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT | AR_IMR_S2_CST);
659#endif
660}
661
662static void
663ar5416InitQoS(struct ath_hal *ah)
664{
665	/* QoS support */
666	OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa);	/* XXX magic */
667	OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210);	/* XXX magic */
668
669	/* Turn on NOACK Support for QoS packets */
670	OS_REG_WRITE(ah, AR_NOACK,
671		SM(2, AR_NOACK_2BIT_VALUE) |
672		SM(5, AR_NOACK_BIT_OFFSET) |
673		SM(0, AR_NOACK_BYTE_OFFSET));
674
675    	/*
676    	 * initialize TXOP for all TIDs
677    	 */
678	OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
679	OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
680	OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
681	OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
682	OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
683}
684
685static void
686ar5416InitUserSettings(struct ath_hal *ah)
687{
688	struct ath_hal_5212 *ahp = AH5212(ah);
689
690	/* Restore user-specified settings */
691	if (ahp->ah_miscMode != 0)
692		OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode);
693	if (ahp->ah_sifstime != (u_int) -1)
694		ar5212SetSifsTime(ah, ahp->ah_sifstime);
695	if (ahp->ah_slottime != (u_int) -1)
696		ar5212SetSlotTime(ah, ahp->ah_slottime);
697	if (ahp->ah_acktimeout != (u_int) -1)
698		ar5212SetAckTimeout(ah, ahp->ah_acktimeout);
699	if (ahp->ah_ctstimeout != (u_int) -1)
700		ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout);
701	if (AH_PRIVATE(ah)->ah_diagreg != 0)
702		OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
703	if (AH5416(ah)->ah_globaltxtimeout != (u_int) -1)
704        	ar5416SetGlobalTxTimeout(ah, AH5416(ah)->ah_globaltxtimeout);
705}
706
707static void
708ar5416SetRfMode(struct ath_hal *ah, const struct ieee80211_channel *chan)
709{
710	uint32_t rfMode;
711
712	if (chan == AH_NULL)
713		return;
714
715	/* treat channel B as channel G , no  B mode suport in owl */
716	rfMode = IEEE80211_IS_CHAN_CCK(chan) ?
717	    AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
718
719	if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
720		/* phy mode bits for 5GHz channels require Fast Clock */
721		rfMode |= AR_PHY_MODE_DYNAMIC
722		       |  AR_PHY_MODE_DYN_CCK_DISABLE;
723	} else if (!AR_SREV_MERLIN_10_OR_LATER(ah)) {
724		rfMode |= IEEE80211_IS_CHAN_5GHZ(chan) ?
725			AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
726	}
727
728	/*
729	 * Set half/quarter mode flags if required.
730	 *
731	 * This doesn't change the IFS timings at all; that needs to
732	 * be done as part of the MAC setup.  Similarly, the PLL
733	 * configuration also needs some changes for the half/quarter
734	 * rate clock.
735	 */
736	if (IEEE80211_IS_CHAN_HALF(chan))
737		rfMode |= AR_PHY_MODE_HALF;
738	else if (IEEE80211_IS_CHAN_QUARTER(chan))
739		rfMode |= AR_PHY_MODE_QUARTER;
740
741	OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
742}
743
744/*
745 * Places the hardware into reset and then pulls it out of reset
746 */
747HAL_BOOL
748ar5416ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
749{
750	OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
751	/*
752	 * Warm reset is optimistic for open-loop TX power control.
753	 */
754	if (AR_SREV_MERLIN(ah) &&
755	    ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) {
756		if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON))
757			return AH_FALSE;
758	} else if (ah->ah_config.ah_force_full_reset) {
759		if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON))
760			return AH_FALSE;
761	} else {
762		if (!ar5416SetResetReg(ah, HAL_RESET_WARM))
763			return AH_FALSE;
764	}
765
766	/* Bring out of sleep mode (AGAIN) */
767	if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
768	       return AH_FALSE;
769
770#ifdef notyet
771	ahp->ah_chipFullSleep = AH_FALSE;
772#endif
773
774	AH5416(ah)->ah_initPLL(ah, chan);
775
776	/*
777	 * Perform warm reset before the mode/PLL/turbo registers
778	 * are changed in order to deactivate the radio.  Mode changes
779	 * with an active radio can result in corrupted shifts to the
780	 * radio device.
781	 */
782	ar5416SetRfMode(ah, chan);
783
784	return AH_TRUE;
785}
786
787/*
788 * Delta slope coefficient computation.
789 * Required for OFDM operation.
790 */
791static void
792ar5416GetDeltaSlopeValues(struct ath_hal *ah, uint32_t coef_scaled,
793                          uint32_t *coef_mantissa, uint32_t *coef_exponent)
794{
795#define COEF_SCALE_S 24
796    uint32_t coef_exp, coef_man;
797    /*
798     * ALGO -> coef_exp = 14-floor(log2(coef));
799     * floor(log2(x)) is the highest set bit position
800     */
801    for (coef_exp = 31; coef_exp > 0; coef_exp--)
802            if ((coef_scaled >> coef_exp) & 0x1)
803                    break;
804    /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */
805    HALASSERT(coef_exp);
806    coef_exp = 14 - (coef_exp - COEF_SCALE_S);
807
808    /*
809     * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5);
810     * The coefficient is already shifted up for scaling
811     */
812    coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
813
814    *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
815    *coef_exponent = coef_exp - 16;
816
817#undef COEF_SCALE_S
818}
819
820void
821ar5416SetDeltaSlope(struct ath_hal *ah, const struct ieee80211_channel *chan)
822{
823#define INIT_CLOCKMHZSCALED	0x64000000
824	uint32_t coef_scaled, ds_coef_exp, ds_coef_man;
825	uint32_t clockMhzScaled;
826
827	CHAN_CENTERS centers;
828
829	/* half and quarter rate can divide the scaled clock by 2 or 4 respectively */
830	/* scale for selected channel bandwidth */
831	clockMhzScaled = INIT_CLOCKMHZSCALED;
832	if (IEEE80211_IS_CHAN_TURBO(chan))
833		clockMhzScaled <<= 1;
834	else if (IEEE80211_IS_CHAN_HALF(chan))
835		clockMhzScaled >>= 1;
836	else if (IEEE80211_IS_CHAN_QUARTER(chan))
837		clockMhzScaled >>= 2;
838
839	/*
840	 * ALGO -> coef = 1e8/fcarrier*fclock/40;
841	 * scaled coef to provide precision for this floating calculation
842	 */
843	ar5416GetChannelCenters(ah, chan, &centers);
844	coef_scaled = clockMhzScaled / centers.synth_center;
845
846 	ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
847
848	OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3,
849		AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
850	OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3,
851		AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
852
853        /*
854         * For Short GI,
855         * scaled coeff is 9/10 that of normal coeff
856         */
857        coef_scaled = (9 * coef_scaled)/10;
858
859        ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
860
861        /* for short gi */
862        OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI,
863                AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
864        OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI,
865                AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
866#undef INIT_CLOCKMHZSCALED
867}
868
869/*
870 * Set a limit on the overall output power.  Used for dynamic
871 * transmit power control and the like.
872 *
873 * NB: limit is in units of 0.5 dbM.
874 */
875HAL_BOOL
876ar5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
877{
878	uint16_t dummyXpdGains[2];
879
880	AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);
881	return ah->ah_setTxPower(ah, AH_PRIVATE(ah)->ah_curchan,
882			dummyXpdGains);
883}
884
885HAL_BOOL
886ar5416GetChipPowerLimits(struct ath_hal *ah,
887	struct ieee80211_channel *chan)
888{
889	struct ath_hal_5212 *ahp = AH5212(ah);
890	int16_t minPower, maxPower;
891
892	/*
893	 * Get Pier table max and min powers.
894	 */
895	if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) {
896		/* NB: rf code returns 1/4 dBm units, convert */
897		chan->ic_maxpower = maxPower / 2;
898		chan->ic_minpower = minPower / 2;
899	} else {
900		HALDEBUG(ah, HAL_DEBUG_ANY,
901		    "%s: no min/max power for %u/0x%x\n",
902		    __func__, chan->ic_freq, chan->ic_flags);
903		chan->ic_maxpower = AR5416_MAX_RATE_POWER;
904		chan->ic_minpower = 0;
905	}
906	HALDEBUG(ah, HAL_DEBUG_RESET,
907	    "Chan %d: MaxPow = %d MinPow = %d\n",
908	    chan->ic_freq, chan->ic_maxpower, chan->ic_minpower);
909	return AH_TRUE;
910}
911
912/**************************************************************
913 * ar5416WriteTxPowerRateRegisters
914 *
915 * Write the TX power rate registers from the raw values given
916 * in ratesArray[].
917 *
918 * The CCK and HT40 rate registers are only written if needed.
919 * HT20 and 11g/11a OFDM rate registers are always written.
920 *
921 * The values written are raw values which should be written
922 * to the registers - so it's up to the caller to pre-adjust
923 * them (eg CCK power offset value, or Merlin TX power offset,
924 * etc.)
925 */
926void
927ar5416WriteTxPowerRateRegisters(struct ath_hal *ah,
928    const struct ieee80211_channel *chan, const int16_t ratesArray[])
929{
930#define POW_SM(_r, _s)     (((_r) & 0x3f) << (_s))
931
932    /* Write the OFDM power per rate set */
933    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
934        POW_SM(ratesArray[rate18mb], 24)
935          | POW_SM(ratesArray[rate12mb], 16)
936          | POW_SM(ratesArray[rate9mb], 8)
937          | POW_SM(ratesArray[rate6mb], 0)
938    );
939    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
940        POW_SM(ratesArray[rate54mb], 24)
941          | POW_SM(ratesArray[rate48mb], 16)
942          | POW_SM(ratesArray[rate36mb], 8)
943          | POW_SM(ratesArray[rate24mb], 0)
944    );
945
946    if (IEEE80211_IS_CHAN_2GHZ(chan)) {
947        /* Write the CCK power per rate set */
948        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
949            POW_SM(ratesArray[rate2s], 24)
950              | POW_SM(ratesArray[rate2l],  16)
951              | POW_SM(ratesArray[rateXr],  8) /* XR target power */
952              | POW_SM(ratesArray[rate1l],   0)
953        );
954        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
955            POW_SM(ratesArray[rate11s], 24)
956              | POW_SM(ratesArray[rate11l], 16)
957              | POW_SM(ratesArray[rate5_5s], 8)
958              | POW_SM(ratesArray[rate5_5l], 0)
959        );
960    HALDEBUG(ah, HAL_DEBUG_RESET,
961	"%s AR_PHY_POWER_TX_RATE3=0x%x AR_PHY_POWER_TX_RATE4=0x%x\n",
962	    __func__, OS_REG_READ(ah,AR_PHY_POWER_TX_RATE3),
963	    OS_REG_READ(ah,AR_PHY_POWER_TX_RATE4));
964    }
965
966    /* Write the HT20 power per rate set */
967    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
968        POW_SM(ratesArray[rateHt20_3], 24)
969          | POW_SM(ratesArray[rateHt20_2], 16)
970          | POW_SM(ratesArray[rateHt20_1], 8)
971          | POW_SM(ratesArray[rateHt20_0], 0)
972    );
973    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
974        POW_SM(ratesArray[rateHt20_7], 24)
975          | POW_SM(ratesArray[rateHt20_6], 16)
976          | POW_SM(ratesArray[rateHt20_5], 8)
977          | POW_SM(ratesArray[rateHt20_4], 0)
978    );
979
980    if (IEEE80211_IS_CHAN_HT40(chan)) {
981        /* Write the HT40 power per rate set */
982        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
983            POW_SM(ratesArray[rateHt40_3], 24)
984              | POW_SM(ratesArray[rateHt40_2], 16)
985              | POW_SM(ratesArray[rateHt40_1], 8)
986              | POW_SM(ratesArray[rateHt40_0], 0)
987        );
988        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
989            POW_SM(ratesArray[rateHt40_7], 24)
990              | POW_SM(ratesArray[rateHt40_6], 16)
991              | POW_SM(ratesArray[rateHt40_5], 8)
992              | POW_SM(ratesArray[rateHt40_4], 0)
993        );
994        /* Write the Dup/Ext 40 power per rate set */
995        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
996            POW_SM(ratesArray[rateExtOfdm], 24)
997              | POW_SM(ratesArray[rateExtCck], 16)
998              | POW_SM(ratesArray[rateDupOfdm], 8)
999              | POW_SM(ratesArray[rateDupCck], 0)
1000        );
1001    }
1002}
1003
1004
1005/**************************************************************
1006 * ar5416SetTransmitPower
1007 *
1008 * Set the transmit power in the baseband for the given
1009 * operating channel and mode.
1010 */
1011HAL_BOOL
1012ar5416SetTransmitPower(struct ath_hal *ah,
1013	const struct ieee80211_channel *chan, uint16_t *rfXpdGain)
1014{
1015#define N(a)            (sizeof (a) / sizeof (a[0]))
1016
1017    MODAL_EEP_HEADER	*pModal;
1018    struct ath_hal_5212 *ahp = AH5212(ah);
1019    int16_t		ratesArray[Ar5416RateSize];
1020    int16_t		txPowerIndexOffset = 0;
1021    uint8_t		ht40PowerIncForPdadc = 2;
1022    int			i;
1023
1024    uint16_t		cfgCtl;
1025    uint16_t		powerLimit;
1026    uint16_t		twiceAntennaReduction;
1027    uint16_t		twiceMaxRegulatoryPower;
1028    int16_t		maxPower;
1029    HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom;
1030    struct ar5416eeprom	*pEepData = &ee->ee_base;
1031
1032    HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1);
1033
1034    /* Setup info for the actual eeprom */
1035    OS_MEMZERO(ratesArray, sizeof(ratesArray));
1036    cfgCtl = ath_hal_getctl(ah, chan);
1037    powerLimit = chan->ic_maxregpower * 2;
1038    twiceAntennaReduction = chan->ic_maxantgain;
1039    twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit);
1040    pModal = &pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)];
1041    HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n",
1042	__func__,chan->ic_freq, cfgCtl );
1043
1044    if (IS_EEP_MINOR_V2(ah)) {
1045        ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
1046    }
1047
1048    if (!ar5416SetPowerPerRateTable(ah, pEepData,  chan,
1049                                    &ratesArray[0],cfgCtl,
1050                                    twiceAntennaReduction,
1051				    twiceMaxRegulatoryPower, powerLimit)) {
1052        HALDEBUG(ah, HAL_DEBUG_ANY,
1053	    "%s: unable to set tx power per rate table\n", __func__);
1054        return AH_FALSE;
1055    }
1056
1057    if (!AH5416(ah)->ah_setPowerCalTable(ah,  pEepData, chan, &txPowerIndexOffset)) {
1058        HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n",
1059	    __func__);
1060        return AH_FALSE;
1061    }
1062
1063    maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]);
1064
1065    if (IEEE80211_IS_CHAN_2GHZ(chan)) {
1066        maxPower = AH_MAX(maxPower, ratesArray[rate1l]);
1067    }
1068
1069    if (IEEE80211_IS_CHAN_HT40(chan)) {
1070        maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]);
1071    }
1072
1073    ahp->ah_tx6PowerInHalfDbm = maxPower;
1074    AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower;
1075    ahp->ah_txPowerIndexOffset = txPowerIndexOffset;
1076
1077    /*
1078     * txPowerIndexOffset is set by the SetPowerTable() call -
1079     *  adjust the rate table (0 offset if rates EEPROM not loaded)
1080     */
1081    for (i = 0; i < N(ratesArray); i++) {
1082        ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
1083        if (ratesArray[i] > AR5416_MAX_RATE_POWER)
1084            ratesArray[i] = AR5416_MAX_RATE_POWER;
1085    }
1086
1087#ifdef AH_EEPROM_DUMP
1088    /*
1089     * Dump the rate array whilst it represents the intended dBm*2
1090     * values versus what's being adjusted before being programmed
1091     * in. Keep this in mind if you code up this function and enable
1092     * this debugging; the values won't necessarily be what's being
1093     * programmed into the hardware.
1094     */
1095    ar5416PrintPowerPerRate(ah, ratesArray);
1096#endif
1097
1098    /*
1099     * Merlin and later have a power offset, so subtract
1100     * pwr_table_offset * 2 from each value. The default
1101     * power offset is -5 dBm - ie, a register value of 0
1102     * equates to a TX power of -5 dBm.
1103     */
1104    if (AR_SREV_MERLIN_20_OR_LATER(ah)) {
1105        int8_t pwr_table_offset;
1106
1107	(void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET,
1108	    &pwr_table_offset);
1109	/* Underflow power gets clamped at raw value 0 */
1110	/* Overflow power gets camped at AR5416_MAX_RATE_POWER */
1111	for (i = 0; i < N(ratesArray); i++) {
1112		/*
1113		 * + pwr_table_offset is in dBm
1114		 * + ratesArray is in 1/2 dBm
1115		 */
1116		ratesArray[i] -= (pwr_table_offset * 2);
1117		if (ratesArray[i] < 0)
1118			ratesArray[i] = 0;
1119		else if (ratesArray[i] > AR5416_MAX_RATE_POWER)
1120		    ratesArray[i] = AR5416_MAX_RATE_POWER;
1121	}
1122    }
1123
1124    /*
1125     * Adjust rates for OLC where needed
1126     *
1127     * The following CCK rates need adjusting when doing 2.4ghz
1128     * CCK transmission.
1129     *
1130     * + rate2s, rate2l, rate1l, rate11s, rate11l, rate5_5s, rate5_5l
1131     * + rateExtCck, rateDupCck
1132     *
1133     * They're adjusted here regardless. The hardware then gets
1134     * programmed as needed. 5GHz operation doesn't program in CCK
1135     * rates for legacy mode but they seem to be initialised for
1136     * HT40 regardless of channel type.
1137     */
1138    if (AR_SREV_MERLIN_20_OR_LATER(ah) &&
1139	    ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) {
1140        int adj[] = {
1141	              rate2s, rate2l, rate1l, rate11s, rate11l,
1142	              rate5_5s, rate5_5l, rateExtCck, rateDupCck
1143		    };
1144        int cck_ofdm_delta = 2;
1145	int i;
1146	for (i = 0; i < N(adj); i++) {
1147            ratesArray[adj[i]] -= cck_ofdm_delta;
1148	    if (ratesArray[adj[i]] < 0)
1149	        ratesArray[adj[i]] = 0;
1150        }
1151    }
1152
1153    /*
1154     * Adjust the HT40 power to meet the correct target TX power
1155     * for 40MHz mode, based on TX power curves that are established
1156     * for 20MHz mode.
1157     *
1158     * XXX handle overflow/too high power level?
1159     */
1160    if (IEEE80211_IS_CHAN_HT40(chan)) {
1161	ratesArray[rateHt40_0] += ht40PowerIncForPdadc;
1162	ratesArray[rateHt40_1] += ht40PowerIncForPdadc;
1163	ratesArray[rateHt40_2] += ht40PowerIncForPdadc;
1164	ratesArray[rateHt40_3] += ht40PowerIncForPdadc;
1165	ratesArray[rateHt40_4] += ht40PowerIncForPdadc;
1166	ratesArray[rateHt40_5] += ht40PowerIncForPdadc;
1167	ratesArray[rateHt40_6] += ht40PowerIncForPdadc;
1168	ratesArray[rateHt40_7] += ht40PowerIncForPdadc;
1169    }
1170
1171    /* Write the TX power rate registers */
1172    ar5416WriteTxPowerRateRegisters(ah, chan, ratesArray);
1173
1174    /* Write the Power subtraction for dynamic chain changing, for per-packet powertx */
1175    OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
1176        POW_SM(pModal->pwrDecreaseFor3Chain, 6)
1177          | POW_SM(pModal->pwrDecreaseFor2Chain, 0)
1178    );
1179    return AH_TRUE;
1180#undef POW_SM
1181#undef N
1182}
1183
1184/*
1185 * Exported call to check for a recent gain reading and return
1186 * the current state of the thermal calibration gain engine.
1187 */
1188HAL_RFGAIN
1189ar5416GetRfgain(struct ath_hal *ah)
1190{
1191	return HAL_RFGAIN_INACTIVE;
1192}
1193
1194/*
1195 * Places all of hardware into reset
1196 */
1197HAL_BOOL
1198ar5416Disable(struct ath_hal *ah)
1199{
1200	if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
1201		return AH_FALSE;
1202	if (! ar5416SetResetReg(ah, HAL_RESET_COLD))
1203		return AH_FALSE;
1204
1205	AH5416(ah)->ah_initPLL(ah, AH_NULL);
1206	return AH_TRUE;
1207}
1208
1209/*
1210 * Places the PHY and Radio chips into reset.  A full reset
1211 * must be called to leave this state.  The PCI/MAC/PCU are
1212 * not placed into reset as we must receive interrupt to
1213 * re-enable the hardware.
1214 */
1215HAL_BOOL
1216ar5416PhyDisable(struct ath_hal *ah)
1217{
1218	if (! ar5416SetResetReg(ah, HAL_RESET_WARM))
1219		return AH_FALSE;
1220
1221	AH5416(ah)->ah_initPLL(ah, AH_NULL);
1222	return AH_TRUE;
1223}
1224
1225/*
1226 * Write the given reset bit mask into the reset register
1227 */
1228HAL_BOOL
1229ar5416SetResetReg(struct ath_hal *ah, uint32_t type)
1230{
1231	/*
1232	 * Set force wake
1233	 */
1234	OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1235	    AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1236
1237	switch (type) {
1238	case HAL_RESET_POWER_ON:
1239		return ar5416SetResetPowerOn(ah);
1240	case HAL_RESET_WARM:
1241	case HAL_RESET_COLD:
1242		return ar5416SetReset(ah, type);
1243	default:
1244		HALASSERT(AH_FALSE);
1245		return AH_FALSE;
1246	}
1247}
1248
1249static HAL_BOOL
1250ar5416SetResetPowerOn(struct ath_hal *ah)
1251{
1252    /* Power On Reset (Hard Reset) */
1253
1254    /*
1255     * Set force wake
1256     *
1257     * If the MAC was running, previously calling
1258     * reset will wake up the MAC but it may go back to sleep
1259     * before we can start polling.
1260     * Set force wake  stops that
1261     * This must be called before initiating a hard reset.
1262     */
1263    OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1264            AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1265
1266    /*
1267     * PowerOn reset can be used in open loop power control or failure recovery.
1268     * If we do RTC reset while DMA is still running, hardware may corrupt memory.
1269     * Therefore, we need to reset AHB first to stop DMA.
1270     */
1271    if (! AR_SREV_HOWL(ah))
1272    	OS_REG_WRITE(ah, AR_RC, AR_RC_AHB);
1273    /*
1274     * RTC reset and clear
1275     */
1276    OS_REG_WRITE(ah, AR_RTC_RESET, 0);
1277    OS_DELAY(20);
1278
1279    if (! AR_SREV_HOWL(ah))
1280    	OS_REG_WRITE(ah, AR_RC, 0);
1281
1282    OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1283
1284    /*
1285     * Poll till RTC is ON
1286     */
1287    if (!ath_hal_wait(ah, AR_RTC_STATUS, AR_RTC_PM_STATUS_M, AR_RTC_STATUS_ON)) {
1288        HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC not waking up\n", __func__);
1289        return AH_FALSE;
1290    }
1291
1292    return ar5416SetReset(ah, HAL_RESET_COLD);
1293}
1294
1295static HAL_BOOL
1296ar5416SetReset(struct ath_hal *ah, int type)
1297{
1298    uint32_t tmpReg, mask;
1299    uint32_t rst_flags;
1300
1301#ifdef	AH_SUPPORT_AR9130	/* Because of the AR9130 specific registers */
1302    if (AR_SREV_HOWL(ah)) {
1303        HALDEBUG(ah, HAL_DEBUG_ANY, "[ath] HOWL: Fiddling with derived clk!\n");
1304        uint32_t val = OS_REG_READ(ah, AR_RTC_DERIVED_CLK);
1305        val &= ~AR_RTC_DERIVED_CLK_PERIOD;
1306        val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD);
1307        OS_REG_WRITE(ah, AR_RTC_DERIVED_CLK, val);
1308        (void) OS_REG_READ(ah, AR_RTC_DERIVED_CLK);
1309    }
1310#endif	/* AH_SUPPORT_AR9130 */
1311
1312    /*
1313     * Force wake
1314     */
1315    OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1316	AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1317
1318#ifdef	AH_SUPPORT_AR9130
1319    if (AR_SREV_HOWL(ah)) {
1320        rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
1321          AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
1322    } else {
1323#endif	/* AH_SUPPORT_AR9130 */
1324        /*
1325         * Reset AHB
1326         *
1327         * (In case the last interrupt source was a bus timeout.)
1328         * XXX TODO: this is not the way to do it! It should be recorded
1329         * XXX by the interrupt handler and passed _into_ the
1330         * XXX reset path routine so this occurs.
1331         */
1332        tmpReg = OS_REG_READ(ah, AR_INTR_SYNC_CAUSE);
1333        if (tmpReg & (AR_INTR_SYNC_LOCAL_TIMEOUT|AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1334            OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
1335            OS_REG_WRITE(ah, AR_RC, AR_RC_AHB|AR_RC_HOSTIF);
1336        } else {
1337	    OS_REG_WRITE(ah, AR_RC, AR_RC_AHB);
1338        }
1339        rst_flags = AR_RTC_RC_MAC_WARM;
1340        if (type == HAL_RESET_COLD)
1341            rst_flags |= AR_RTC_RC_MAC_COLD;
1342#ifdef	AH_SUPPORT_AR9130
1343    }
1344#endif	/* AH_SUPPORT_AR9130 */
1345
1346    OS_REG_WRITE(ah, AR_RTC_RC, rst_flags);
1347
1348    if (AR_SREV_HOWL(ah))
1349        OS_DELAY(10000);
1350    else
1351        OS_DELAY(100);
1352
1353    /*
1354     * Clear resets and force wakeup
1355     */
1356    OS_REG_WRITE(ah, AR_RTC_RC, 0);
1357    if (!ath_hal_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) {
1358        HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC stuck in MAC reset\n", __func__);
1359        return AH_FALSE;
1360    }
1361
1362    /* Clear AHB reset */
1363    if (! AR_SREV_HOWL(ah))
1364        OS_REG_WRITE(ah, AR_RC, 0);
1365
1366    if (AR_SREV_HOWL(ah))
1367        OS_DELAY(50);
1368
1369    if (AR_SREV_HOWL(ah)) {
1370                uint32_t mask;
1371                mask = OS_REG_READ(ah, AR_CFG);
1372                if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
1373                        HALDEBUG(ah, HAL_DEBUG_RESET,
1374                                "CFG Byte Swap Set 0x%x\n", mask);
1375                } else {
1376                        mask =
1377                                INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
1378                        OS_REG_WRITE(ah, AR_CFG, mask);
1379                        HALDEBUG(ah, HAL_DEBUG_RESET,
1380                                "Setting CFG 0x%x\n", OS_REG_READ(ah, AR_CFG));
1381                }
1382    } else {
1383	if (type == HAL_RESET_COLD) {
1384		if (isBigEndian()) {
1385			/*
1386			 * Set CFG, little-endian for register
1387			 * and descriptor accesses.
1388			 */
1389			mask = INIT_CONFIG_STATUS | AR_CFG_SWRD | AR_CFG_SWRG;
1390#ifndef AH_NEED_DESC_SWAP
1391			mask |= AR_CFG_SWTD;
1392#endif
1393			HALDEBUG(ah, HAL_DEBUG_RESET,
1394			    "%s Applying descriptor swap\n", __func__);
1395			OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask));
1396		} else
1397			OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS);
1398	}
1399    }
1400
1401    return AH_TRUE;
1402}
1403
1404void
1405ar5416InitChainMasks(struct ath_hal *ah)
1406{
1407	int rx_chainmask = AH5416(ah)->ah_rx_chainmask;
1408
1409	/* Flip this for this chainmask regardless of chip */
1410	if (rx_chainmask == 0x5)
1411		OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
1412
1413	/*
1414	 * Workaround for OWL 1.0 calibration failure; enable multi-chain;
1415	 * then set true mask after calibration.
1416	 */
1417	if (IS_5416V1(ah) && (rx_chainmask == 0x5 || rx_chainmask == 0x3)) {
1418		OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
1419		OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
1420	} else {
1421		OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, AH5416(ah)->ah_rx_chainmask);
1422		OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, AH5416(ah)->ah_rx_chainmask);
1423	}
1424	OS_REG_WRITE(ah, AR_SELFGEN_MASK, AH5416(ah)->ah_tx_chainmask);
1425
1426	if (AH5416(ah)->ah_tx_chainmask == 0x5)
1427		OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
1428
1429	if (AR_SREV_HOWL(ah)) {
1430		OS_REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
1431		OS_REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
1432	}
1433}
1434
1435/*
1436 * Work-around for Owl 1.0 calibration failure.
1437 *
1438 * ar5416InitChainMasks sets the RX chainmask to 0x7 if it's Owl 1.0
1439 * due to init calibration failures. ar5416RestoreChainMask restores
1440 * these registers to the correct setting.
1441 */
1442void
1443ar5416RestoreChainMask(struct ath_hal *ah)
1444{
1445	int rx_chainmask = AH5416(ah)->ah_rx_chainmask;
1446
1447	if (IS_5416V1(ah) && (rx_chainmask == 0x5 || rx_chainmask == 0x3)) {
1448		OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
1449		OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
1450	}
1451}
1452
1453/*
1454 * Update the chainmask based on the current channel configuration.
1455 *
1456 * XXX ath9k checks bluetooth co-existence here
1457 * XXX ath9k checks whether the current state is "off-channel".
1458 * XXX ath9k sticks the hardware into 1x1 mode for legacy;
1459 *     we're going to leave multi-RX on for multi-path cancellation.
1460 */
1461static void
1462ar5416UpdateChainMasks(struct ath_hal *ah, HAL_BOOL is_ht)
1463{
1464	struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
1465	HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;
1466
1467	if (is_ht) {
1468		AH5416(ah)->ah_tx_chainmask = pCap->halTxChainMask;
1469	} else {
1470		AH5416(ah)->ah_tx_chainmask = 1;
1471	}
1472	AH5416(ah)->ah_rx_chainmask = pCap->halRxChainMask;
1473	HALDEBUG(ah, HAL_DEBUG_RESET, "TX chainmask: 0x%x; RX chainmask: 0x%x\n",
1474	    AH5416(ah)->ah_tx_chainmask,
1475	    AH5416(ah)->ah_rx_chainmask);
1476}
1477
1478void
1479ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan)
1480{
1481	uint32_t pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
1482	if (chan != AH_NULL) {
1483		if (IEEE80211_IS_CHAN_HALF(chan))
1484			pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1485		else if (IEEE80211_IS_CHAN_QUARTER(chan))
1486			pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1487
1488		if (IEEE80211_IS_CHAN_5GHZ(chan))
1489			pll |= SM(0xa, AR_RTC_PLL_DIV);
1490		else
1491			pll |= SM(0xb, AR_RTC_PLL_DIV);
1492	} else
1493		pll |= SM(0xb, AR_RTC_PLL_DIV);
1494
1495	OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
1496
1497	/* TODO:
1498	* For multi-band owl, switch between bands by reiniting the PLL.
1499	*/
1500
1501	OS_DELAY(RTC_PLL_SETTLE_DELAY);
1502
1503	OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_SLEEP_DERIVED_CLK);
1504}
1505
1506static void
1507ar5416SetDefGainValues(struct ath_hal *ah,
1508    const MODAL_EEP_HEADER *pModal,
1509    const struct ar5416eeprom *eep,
1510    uint8_t txRxAttenLocal, int regChainOffset, int i)
1511{
1512	if (IS_EEP_MINOR_V3(ah)) {
1513		txRxAttenLocal = pModal->txRxAttenCh[i];
1514
1515		if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
1516			OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1517			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
1518			      pModal->bswMargin[i]);
1519			OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1520			      AR_PHY_GAIN_2GHZ_XATTEN1_DB,
1521			      pModal->bswAtten[i]);
1522			OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1523			      AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
1524			      pModal->xatten2Margin[i]);
1525			OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1526			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
1527			      pModal->xatten2Db[i]);
1528		} else {
1529			OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1530			      AR_PHY_GAIN_2GHZ_BSW_MARGIN,
1531			      pModal->bswMargin[i]);
1532			OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1533			      AR_PHY_GAIN_2GHZ_BSW_ATTEN,
1534			      pModal->bswAtten[i]);
1535		}
1536	}
1537
1538	if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
1539		OS_REG_RMW_FIELD(ah,
1540		      AR_PHY_RXGAIN + regChainOffset,
1541		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
1542		OS_REG_RMW_FIELD(ah,
1543		      AR_PHY_RXGAIN + regChainOffset,
1544		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
1545	} else {
1546		OS_REG_RMW_FIELD(ah,
1547			  AR_PHY_RXGAIN + regChainOffset,
1548			  AR_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
1549		OS_REG_RMW_FIELD(ah,
1550			  AR_PHY_GAIN_2GHZ + regChainOffset,
1551			  AR_PHY_GAIN_2GHZ_RXTX_MARGIN, pModal->rxTxMarginCh[i]);
1552	}
1553}
1554
1555/*
1556 * Get the register chain offset for the given chain.
1557 *
1558 * Take into account the register chain swapping with AR5416 v2.0.
1559 *
1560 * XXX make sure that the reg chain swapping is only done for
1561 * XXX AR5416 v2.0 or greater, and not later chips?
1562 */
1563int
1564ar5416GetRegChainOffset(struct ath_hal *ah, int i)
1565{
1566	int regChainOffset;
1567
1568	if (AR_SREV_5416_V20_OR_LATER(ah) &&
1569	    (AH5416(ah)->ah_rx_chainmask == 0x5 ||
1570	    AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) {
1571		/* Regs are swapped from chain 2 to 1 for 5416 2_0 with
1572		 * only chains 0 and 2 populated
1573		 */
1574		regChainOffset = (i == 1) ? 0x2000 : 0x1000;
1575	} else {
1576		regChainOffset = i * 0x1000;
1577	}
1578
1579	return regChainOffset;
1580}
1581
1582/*
1583 * Read EEPROM header info and program the device for correct operation
1584 * given the channel value.
1585 */
1586HAL_BOOL
1587ar5416SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan)
1588{
1589    const HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom;
1590    const struct ar5416eeprom *eep = &ee->ee_base;
1591    const MODAL_EEP_HEADER *pModal;
1592    int			i, regChainOffset;
1593    uint8_t		txRxAttenLocal;    /* workaround for eeprom versions <= 14.2 */
1594
1595    HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1);
1596    pModal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)];
1597
1598    /* NB: workaround for eeprom versions <= 14.2 */
1599    txRxAttenLocal = IEEE80211_IS_CHAN_2GHZ(chan) ? 23 : 44;
1600
1601    OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
1602    for (i = 0; i < AR5416_MAX_CHAINS; i++) {
1603	   if (AR_SREV_MERLIN(ah)) {
1604		if (i >= 2) break;
1605	   }
1606	regChainOffset = ar5416GetRegChainOffset(ah, i);
1607
1608        OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, pModal->antCtrlChain[i]);
1609
1610        OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4 + regChainOffset,
1611        	(OS_REG_READ(ah, AR_PHY_TIMING_CTRL4 + regChainOffset) &
1612        	~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
1613        	SM(pModal->iqCalICh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
1614        	SM(pModal->iqCalQCh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
1615
1616        /*
1617         * Large signal upgrade,
1618	 * If 14.3 or later EEPROM, use
1619	 * txRxAttenLocal = pModal->txRxAttenCh[i]
1620	 * else txRxAttenLocal is fixed value above.
1621         */
1622
1623        if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah))
1624	    ar5416SetDefGainValues(ah, pModal, eep, txRxAttenLocal, regChainOffset, i);
1625
1626    }
1627
1628	if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
1629                if (IEEE80211_IS_CHAN_2GHZ(chan)) {
1630                        OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH0, AR_AN_RF2G1_CH0_OB, pModal->ob);
1631                        OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH0, AR_AN_RF2G1_CH0_DB, pModal->db);
1632                        OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH1, AR_AN_RF2G1_CH1_OB, pModal->ob_ch1);
1633                        OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH1, AR_AN_RF2G1_CH1_DB, pModal->db_ch1);
1634                } else {
1635                        OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH0, AR_AN_RF5G1_CH0_OB5, pModal->ob);
1636                        OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH0, AR_AN_RF5G1_CH0_DB5, pModal->db);
1637                        OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH1, AR_AN_RF5G1_CH1_OB5, pModal->ob_ch1);
1638                        OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH1, AR_AN_RF5G1_CH1_DB5, pModal->db_ch1);
1639                }
1640                OS_A_REG_RMW_FIELD(ah, AR_AN_TOP2, AR_AN_TOP2_XPABIAS_LVL, pModal->xpaBiasLvl);
1641                OS_A_REG_RMW_FIELD(ah, AR_AN_TOP2, AR_AN_TOP2_LOCALBIAS,
1642		    !!(pModal->flagBits & AR5416_EEP_FLAG_LOCALBIAS));
1643                OS_A_REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
1644		    !!(pModal->flagBits & AR5416_EEP_FLAG_FORCEXPAON));
1645        }
1646
1647    OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->switchSettling);
1648    OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize);
1649
1650    if (! AR_SREV_MERLIN_10_OR_LATER(ah))
1651    	OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_PGA, pModal->pgaDesiredSize);
1652
1653    OS_REG_WRITE(ah, AR_PHY_RF_CTL4,
1654        SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
1655        | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
1656        | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)
1657        | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
1658
1659    OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
1660	pModal->txEndToRxOn);
1661
1662    if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
1663	OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
1664	    pModal->thresh62);
1665	OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
1666	    pModal->thresh62);
1667    } else {
1668	OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
1669	    pModal->thresh62);
1670	OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, AR_PHY_EXT_CCA_THRESH62,
1671	    pModal->thresh62);
1672    }
1673
1674    /* Minor Version Specific application */
1675    if (IS_EEP_MINOR_V2(ah)) {
1676        OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_FRAME_TO_DATA_START,
1677	    pModal->txFrameToDataStart);
1678        OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_FRAME_TO_PA_ON,
1679	    pModal->txFrameToPaOn);
1680    }
1681
1682    if (IS_EEP_MINOR_V3(ah) && IEEE80211_IS_CHAN_HT40(chan))
1683		/* Overwrite switch settling with HT40 value */
1684		OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
1685		    pModal->swSettleHt40);
1686
1687    if (AR_SREV_MERLIN_20_OR_LATER(ah) && EEP_MINOR(ah) >= AR5416_EEP_MINOR_VER_19)
1688         OS_REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL, AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, pModal->miscBits);
1689
1690        if (AR_SREV_MERLIN_20(ah) && EEP_MINOR(ah) >= AR5416_EEP_MINOR_VER_20) {
1691                if (IEEE80211_IS_CHAN_2GHZ(chan))
1692                        OS_A_REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
1693			    eep->baseEepHeader.dacLpMode);
1694                else if (eep->baseEepHeader.dacHiPwrMode_5G)
1695                        OS_A_REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
1696                else
1697                        OS_A_REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
1698			    eep->baseEepHeader.dacLpMode);
1699
1700		OS_DELAY(100);
1701
1702                OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
1703		    pModal->miscBits >> 2);
1704                OS_REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9, AR_PHY_TX_DESIRED_SCALE_CCK,
1705		    eep->baseEepHeader.desiredScaleCCK);
1706        }
1707
1708    return AH_TRUE;
1709}
1710
1711/*
1712 * Helper functions common for AP/CB/XB
1713 */
1714
1715/*
1716 * Set the target power array "ratesArray" from the
1717 * given set of target powers.
1718 *
1719 * This is used by the various chipset/EEPROM TX power
1720 * setup routines.
1721 */
1722void
1723ar5416SetRatesArrayFromTargetPower(struct ath_hal *ah,
1724    const struct ieee80211_channel *chan,
1725    int16_t *ratesArray,
1726    const CAL_TARGET_POWER_LEG *targetPowerCck,
1727    const CAL_TARGET_POWER_LEG *targetPowerCckExt,
1728    const CAL_TARGET_POWER_LEG *targetPowerOfdm,
1729    const CAL_TARGET_POWER_LEG *targetPowerOfdmExt,
1730    const CAL_TARGET_POWER_HT *targetPowerHt20,
1731    const CAL_TARGET_POWER_HT *targetPowerHt40)
1732{
1733#define	N(a)	(sizeof(a)/sizeof(a[0]))
1734	int i;
1735
1736	/* Blank the rates array, to be consistent */
1737	for (i = 0; i < Ar5416RateSize; i++)
1738		ratesArray[i] = 0;
1739
1740	/* Set rates Array from collected data */
1741	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
1742	    ratesArray[rate18mb] = ratesArray[rate24mb] = targetPowerOfdm->tPow2x[0];
1743	ratesArray[rate36mb] = targetPowerOfdm->tPow2x[1];
1744	ratesArray[rate48mb] = targetPowerOfdm->tPow2x[2];
1745	ratesArray[rate54mb] = targetPowerOfdm->tPow2x[3];
1746	ratesArray[rateXr] = targetPowerOfdm->tPow2x[0];
1747
1748	for (i = 0; i < N(targetPowerHt20->tPow2x); i++) {
1749		ratesArray[rateHt20_0 + i] = targetPowerHt20->tPow2x[i];
1750	}
1751
1752	if (IEEE80211_IS_CHAN_2GHZ(chan)) {
1753		ratesArray[rate1l]  = targetPowerCck->tPow2x[0];
1754		ratesArray[rate2s] = ratesArray[rate2l]  = targetPowerCck->tPow2x[1];
1755		ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck->tPow2x[2];
1756		ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck->tPow2x[3];
1757	}
1758	if (IEEE80211_IS_CHAN_HT40(chan)) {
1759		for (i = 0; i < N(targetPowerHt40->tPow2x); i++) {
1760			ratesArray[rateHt40_0 + i] = targetPowerHt40->tPow2x[i];
1761		}
1762		ratesArray[rateDupOfdm] = targetPowerHt40->tPow2x[0];
1763		ratesArray[rateDupCck]  = targetPowerHt40->tPow2x[0];
1764		ratesArray[rateExtOfdm] = targetPowerOfdmExt->tPow2x[0];
1765		if (IEEE80211_IS_CHAN_2GHZ(chan)) {
1766			ratesArray[rateExtCck]  = targetPowerCckExt->tPow2x[0];
1767		}
1768	}
1769#undef	N
1770}
1771
1772/*
1773 * ar5416SetPowerPerRateTable
1774 *
1775 * Sets the transmit power in the baseband for the given
1776 * operating channel and mode.
1777 */
1778static HAL_BOOL
1779ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
1780                           const struct ieee80211_channel *chan,
1781                           int16_t *ratesArray, uint16_t cfgCtl,
1782                           uint16_t AntennaReduction,
1783                           uint16_t twiceMaxRegulatoryPower,
1784                           uint16_t powerLimit)
1785{
1786#define	N(a)	(sizeof(a)/sizeof(a[0]))
1787/* Local defines to distinguish between extension and control CTL's */
1788#define EXT_ADDITIVE (0x8000)
1789#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
1790#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
1791#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
1792
1793	uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1794	int i;
1795	int16_t  twiceLargestAntenna;
1796	CAL_CTL_DATA *rep;
1797	CAL_TARGET_POWER_LEG targetPowerOfdm, targetPowerCck = {0, {0, 0, 0, 0}};
1798	CAL_TARGET_POWER_LEG targetPowerOfdmExt = {0, {0, 0, 0, 0}}, targetPowerCckExt = {0, {0, 0, 0, 0}};
1799	CAL_TARGET_POWER_HT  targetPowerHt20, targetPowerHt40 = {0, {0, 0, 0, 0}};
1800	int16_t scaledPower, minCtlPower;
1801
1802#define SUB_NUM_CTL_MODES_AT_5G_40 2   /* excluding HT40, EXT-OFDM */
1803#define SUB_NUM_CTL_MODES_AT_2G_40 3   /* excluding HT40, EXT-OFDM, EXT-CCK */
1804	static const uint16_t ctlModesFor11a[] = {
1805	   CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
1806	};
1807	static const uint16_t ctlModesFor11g[] = {
1808	   CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
1809	};
1810	const uint16_t *pCtlMode;
1811	uint16_t numCtlModes, ctlMode, freq;
1812	CHAN_CENTERS centers;
1813
1814	ar5416GetChannelCenters(ah,  chan, &centers);
1815
1816	/* Compute TxPower reduction due to Antenna Gain */
1817
1818	twiceLargestAntenna = AH_MAX(AH_MAX(
1819	    pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[0],
1820	    pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[1]),
1821	    pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
1822#if 0
1823	/* Turn it back on if we need to calculate per chain antenna gain reduction */
1824	/* Use only if the expected gain > 6dbi */
1825	/* Chain 0 is always used */
1826	twiceLargestAntenna = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[0];
1827
1828	/* Look at antenna gains of Chains 1 and 2 if the TX mask is set */
1829	if (ahp->ah_tx_chainmask & 0x2)
1830		twiceLargestAntenna = AH_MAX(twiceLargestAntenna,
1831			pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
1832
1833	if (ahp->ah_tx_chainmask & 0x4)
1834		twiceLargestAntenna = AH_MAX(twiceLargestAntenna,
1835			pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
1836#endif
1837	twiceLargestAntenna = (int16_t)AH_MIN((AntennaReduction) - twiceLargestAntenna, 0);
1838
1839	/* XXX setup for 5212 use (really used?) */
1840	ath_hal_eepromSet(ah,
1841	    IEEE80211_IS_CHAN_2GHZ(chan) ? AR_EEP_ANTGAINMAX_2 : AR_EEP_ANTGAINMAX_5,
1842	    twiceLargestAntenna);
1843
1844	/*
1845	 * scaledPower is the minimum of the user input power level and
1846	 * the regulatory allowed power level
1847	 */
1848	scaledPower = AH_MIN(powerLimit, twiceMaxRegulatoryPower + twiceLargestAntenna);
1849
1850	/* Reduce scaled Power by number of chains active to get to per chain tx power level */
1851	/* TODO: better value than these? */
1852	switch (owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask)) {
1853	case 1:
1854		break;
1855	case 2:
1856		scaledPower -= pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain;
1857		break;
1858	case 3:
1859		scaledPower -= pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain;
1860		break;
1861	default:
1862		return AH_FALSE; /* Unsupported number of chains */
1863	}
1864
1865	scaledPower = AH_MAX(0, scaledPower);
1866
1867	/* Get target powers from EEPROM - our baseline for TX Power */
1868	if (IEEE80211_IS_CHAN_2GHZ(chan)) {
1869		/* Setup for CTL modes */
1870		numCtlModes = N(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; /* CTL_11B, CTL_11G, CTL_2GHT20 */
1871		pCtlMode = ctlModesFor11g;
1872
1873		ar5416GetTargetPowersLeg(ah,  chan, pEepData->calTargetPowerCck,
1874				AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCck, 4, AH_FALSE);
1875		ar5416GetTargetPowersLeg(ah,  chan, pEepData->calTargetPower2G,
1876				AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE);
1877		ar5416GetTargetPowers(ah,  chan, pEepData->calTargetPower2GHT20,
1878				AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE);
1879
1880		if (IEEE80211_IS_CHAN_HT40(chan)) {
1881			numCtlModes = N(ctlModesFor11g);    /* All 2G CTL's */
1882
1883			ar5416GetTargetPowers(ah,  chan, pEepData->calTargetPower2GHT40,
1884				AR5416_NUM_2G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE);
1885			/* Get target powers for extension channels */
1886			ar5416GetTargetPowersLeg(ah,  chan, pEepData->calTargetPowerCck,
1887				AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCckExt, 4, AH_TRUE);
1888			ar5416GetTargetPowersLeg(ah,  chan, pEepData->calTargetPower2G,
1889				AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE);
1890		}
1891	} else {
1892		/* Setup for CTL modes */
1893		numCtlModes = N(ctlModesFor11a) - SUB_NUM_CTL_MODES_AT_5G_40; /* CTL_11A, CTL_5GHT20 */
1894		pCtlMode = ctlModesFor11a;
1895
1896		ar5416GetTargetPowersLeg(ah,  chan, pEepData->calTargetPower5G,
1897				AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE);
1898		ar5416GetTargetPowers(ah,  chan, pEepData->calTargetPower5GHT20,
1899				AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE);
1900
1901		if (IEEE80211_IS_CHAN_HT40(chan)) {
1902			numCtlModes = N(ctlModesFor11a); /* All 5G CTL's */
1903
1904			ar5416GetTargetPowers(ah,  chan, pEepData->calTargetPower5GHT40,
1905				AR5416_NUM_5G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE);
1906			ar5416GetTargetPowersLeg(ah,  chan, pEepData->calTargetPower5G,
1907				AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE);
1908		}
1909	}
1910
1911	/*
1912	 * For MIMO, need to apply regulatory caps individually across dynamically
1913	 * running modes: CCK, OFDM, HT20, HT40
1914	 *
1915	 * The outer loop walks through each possible applicable runtime mode.
1916	 * The inner loop walks through each ctlIndex entry in EEPROM.
1917	 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
1918	 *
1919	 */
1920	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
1921		HAL_BOOL isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
1922		    (pCtlMode[ctlMode] == CTL_2GHT40);
1923		if (isHt40CtlMode) {
1924			freq = centers.ctl_center;
1925		} else if (pCtlMode[ctlMode] & EXT_ADDITIVE) {
1926			freq = centers.ext_center;
1927		} else {
1928			freq = centers.ctl_center;
1929		}
1930
1931		/* walk through each CTL index stored in EEPROM */
1932		for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
1933			uint16_t twiceMinEdgePower;
1934
1935			/* compare test group from regulatory channel list with test mode from pCtlMode list */
1936			if ((((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == pEepData->ctlIndex[i]) ||
1937				(((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1938				 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
1939				rep = &(pEepData->ctlData[i]);
1940				twiceMinEdgePower = ar5416GetMaxEdgePower(freq,
1941							rep->ctlEdges[owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask) - 1],
1942							IEEE80211_IS_CHAN_2GHZ(chan));
1943				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
1944					/* Find the minimum of all CTL edge powers that apply to this channel */
1945					twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower);
1946				} else {
1947					/* specific */
1948					twiceMaxEdgePower = twiceMinEdgePower;
1949					break;
1950				}
1951			}
1952		}
1953		minCtlPower = (uint8_t)AH_MIN(twiceMaxEdgePower, scaledPower);
1954		/* Apply ctl mode to correct target power set */
1955		switch(pCtlMode[ctlMode]) {
1956		case CTL_11B:
1957			for (i = 0; i < N(targetPowerCck.tPow2x); i++) {
1958				targetPowerCck.tPow2x[i] = (uint8_t)AH_MIN(targetPowerCck.tPow2x[i], minCtlPower);
1959			}
1960			break;
1961		case CTL_11A:
1962		case CTL_11G:
1963			for (i = 0; i < N(targetPowerOfdm.tPow2x); i++) {
1964				targetPowerOfdm.tPow2x[i] = (uint8_t)AH_MIN(targetPowerOfdm.tPow2x[i], minCtlPower);
1965			}
1966			break;
1967		case CTL_5GHT20:
1968		case CTL_2GHT20:
1969			for (i = 0; i < N(targetPowerHt20.tPow2x); i++) {
1970				targetPowerHt20.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt20.tPow2x[i], minCtlPower);
1971			}
1972			break;
1973		case CTL_11B_EXT:
1974			targetPowerCckExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerCckExt.tPow2x[0], minCtlPower);
1975			break;
1976		case CTL_11A_EXT:
1977		case CTL_11G_EXT:
1978			targetPowerOfdmExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerOfdmExt.tPow2x[0], minCtlPower);
1979			break;
1980		case CTL_5GHT40:
1981		case CTL_2GHT40:
1982			for (i = 0; i < N(targetPowerHt40.tPow2x); i++) {
1983				targetPowerHt40.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt40.tPow2x[i], minCtlPower);
1984			}
1985			break;
1986		default:
1987			return AH_FALSE;
1988			break;
1989		}
1990	} /* end ctl mode checking */
1991
1992	/* Set rates Array from collected data */
1993	ar5416SetRatesArrayFromTargetPower(ah, chan, ratesArray,
1994	    &targetPowerCck,
1995	    &targetPowerCckExt,
1996	    &targetPowerOfdm,
1997	    &targetPowerOfdmExt,
1998	    &targetPowerHt20,
1999	    &targetPowerHt40);
2000	return AH_TRUE;
2001#undef EXT_ADDITIVE
2002#undef CTL_11A_EXT
2003#undef CTL_11G_EXT
2004#undef CTL_11B_EXT
2005#undef SUB_NUM_CTL_MODES_AT_5G_40
2006#undef SUB_NUM_CTL_MODES_AT_2G_40
2007#undef N
2008}
2009
2010/**************************************************************************
2011 * fbin2freq
2012 *
2013 * Get channel value from binary representation held in eeprom
2014 * RETURNS: the frequency in MHz
2015 */
2016static uint16_t
2017fbin2freq(uint8_t fbin, HAL_BOOL is2GHz)
2018{
2019    /*
2020     * Reserved value 0xFF provides an empty definition both as
2021     * an fbin and as a frequency - do not convert
2022     */
2023    if (fbin == AR5416_BCHAN_UNUSED) {
2024        return fbin;
2025    }
2026
2027    return (uint16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
2028}
2029
2030/*
2031 * ar5416GetMaxEdgePower
2032 *
2033 * Find the maximum conformance test limit for the given channel and CTL info
2034 */
2035uint16_t
2036ar5416GetMaxEdgePower(uint16_t freq, CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz)
2037{
2038    uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
2039    int      i;
2040
2041    /* Get the edge power */
2042    for (i = 0; (i < AR5416_NUM_BAND_EDGES) && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED) ; i++) {
2043        /*
2044         * If there's an exact channel match or an inband flag set
2045         * on the lower channel use the given rdEdgePower
2046         */
2047        if (freq == fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
2048            twiceMaxEdgePower = MS(pRdEdgesPower[i].tPowerFlag, CAL_CTL_EDGES_POWER);
2049            break;
2050        } else if ((i > 0) && (freq < fbin2freq(pRdEdgesPower[i].bChannel, is2GHz))) {
2051            if (fbin2freq(pRdEdgesPower[i - 1].bChannel, is2GHz) < freq && (pRdEdgesPower[i - 1].tPowerFlag & CAL_CTL_EDGES_FLAG) != 0) {
2052                twiceMaxEdgePower = MS(pRdEdgesPower[i - 1].tPowerFlag, CAL_CTL_EDGES_POWER);
2053            }
2054            /* Leave loop - no more affecting edges possible in this monotonic increasing list */
2055            break;
2056        }
2057    }
2058    HALASSERT(twiceMaxEdgePower > 0);
2059    return twiceMaxEdgePower;
2060}
2061
2062/**************************************************************
2063 * ar5416GetTargetPowers
2064 *
2065 * Return the rates of target power for the given target power table
2066 * channel, and number of channels
2067 */
2068void
2069ar5416GetTargetPowers(struct ath_hal *ah,  const struct ieee80211_channel *chan,
2070                      CAL_TARGET_POWER_HT *powInfo, uint16_t numChannels,
2071                      CAL_TARGET_POWER_HT *pNewPower, uint16_t numRates,
2072                      HAL_BOOL isHt40Target)
2073{
2074    uint16_t clo, chi;
2075    int i;
2076    int matchIndex = -1, lowIndex = -1;
2077    uint16_t freq;
2078    CHAN_CENTERS centers;
2079
2080    ar5416GetChannelCenters(ah,  chan, &centers);
2081    freq = isHt40Target ? centers.synth_center : centers.ctl_center;
2082
2083    /* Copy the target powers into the temp channel list */
2084    if (freq <= fbin2freq(powInfo[0].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) {
2085        matchIndex = 0;
2086    } else {
2087        for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
2088            if (freq == fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) {
2089                matchIndex = i;
2090                break;
2091            } else if ((freq < fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) &&
2092                       (freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))))
2093            {
2094                lowIndex = i - 1;
2095                break;
2096            }
2097        }
2098        if ((matchIndex == -1) && (lowIndex == -1)) {
2099            HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)));
2100            matchIndex = i - 1;
2101        }
2102    }
2103
2104    if (matchIndex != -1) {
2105        OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower));
2106    } else {
2107        HALASSERT(lowIndex != -1);
2108        /*
2109         * Get the lower and upper channels, target powers,
2110         * and interpolate between them.
2111         */
2112        clo = fbin2freq(powInfo[lowIndex].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
2113        chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
2114
2115        for (i = 0; i < numRates; i++) {
2116            pNewPower->tPow2x[i] = (uint8_t)ath_ee_interpolate(freq, clo, chi,
2117                                   powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]);
2118        }
2119    }
2120}
2121/**************************************************************
2122 * ar5416GetTargetPowersLeg
2123 *
2124 * Return the four rates of target power for the given target power table
2125 * channel, and number of channels
2126 */
2127void
2128ar5416GetTargetPowersLeg(struct ath_hal *ah,
2129                         const struct ieee80211_channel *chan,
2130                         CAL_TARGET_POWER_LEG *powInfo, uint16_t numChannels,
2131                         CAL_TARGET_POWER_LEG *pNewPower, uint16_t numRates,
2132			 HAL_BOOL isExtTarget)
2133{
2134    uint16_t clo, chi;
2135    int i;
2136    int matchIndex = -1, lowIndex = -1;
2137    uint16_t freq;
2138    CHAN_CENTERS centers;
2139
2140    ar5416GetChannelCenters(ah,  chan, &centers);
2141    freq = (isExtTarget) ? centers.ext_center :centers.ctl_center;
2142
2143    /* Copy the target powers into the temp channel list */
2144    if (freq <= fbin2freq(powInfo[0].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) {
2145        matchIndex = 0;
2146    } else {
2147        for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
2148            if (freq == fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) {
2149                matchIndex = i;
2150                break;
2151            } else if ((freq < fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) &&
2152                       (freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))))
2153            {
2154                lowIndex = i - 1;
2155                break;
2156            }
2157        }
2158        if ((matchIndex == -1) && (lowIndex == -1)) {
2159            HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)));
2160            matchIndex = i - 1;
2161        }
2162    }
2163
2164    if (matchIndex != -1) {
2165        OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower));
2166    } else {
2167        HALASSERT(lowIndex != -1);
2168        /*
2169         * Get the lower and upper channels, target powers,
2170         * and interpolate between them.
2171         */
2172        clo = fbin2freq(powInfo[lowIndex].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
2173        chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
2174
2175        for (i = 0; i < numRates; i++) {
2176            pNewPower->tPow2x[i] = (uint8_t)ath_ee_interpolate(freq, clo, chi,
2177                                   powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]);
2178        }
2179    }
2180}
2181
2182/*
2183 * Set the gain boundaries for the given radio chain.
2184 *
2185 * The gain boundaries tell the hardware at what point in the
2186 * PDADC array to "switch over" from one PD gain setting
2187 * to another. There's also a gain overlap between two
2188 * PDADC array gain curves where there's valid PD values
2189 * for 2 gain settings.
2190 *
2191 * The hardware uses the gain overlap and gain boundaries
2192 * to determine which gain curve to use for the given
2193 * target TX power.
2194 */
2195void
2196ar5416SetGainBoundariesClosedLoop(struct ath_hal *ah, int i,
2197    uint16_t pdGainOverlap_t2, uint16_t gainBoundaries[])
2198{
2199	int regChainOffset;
2200
2201	regChainOffset = ar5416GetRegChainOffset(ah, i);
2202
2203	HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: chain %d: gainOverlap_t2: %d,"
2204	    " gainBoundaries: %d, %d, %d, %d\n", __func__, i, pdGainOverlap_t2,
2205	    gainBoundaries[0], gainBoundaries[1], gainBoundaries[2],
2206	    gainBoundaries[3]);
2207	OS_REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
2208	    SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
2209	    SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)  |
2210	    SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)  |
2211	    SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)  |
2212	    SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
2213}
2214
2215/*
2216 * Get the gain values and the number of gain levels given
2217 * in xpdMask.
2218 *
2219 * The EEPROM xpdMask determines which power detector gain
2220 * levels were used during calibration. Each of these mask
2221 * bits maps to a fixed gain level in hardware.
2222 */
2223uint16_t
2224ar5416GetXpdGainValues(struct ath_hal *ah, uint16_t xpdMask,
2225    uint16_t xpdGainValues[])
2226{
2227    int i;
2228    uint16_t numXpdGain = 0;
2229
2230    for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
2231        if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
2232            if (numXpdGain >= AR5416_NUM_PD_GAINS) {
2233                HALASSERT(0);
2234                break;
2235            }
2236            xpdGainValues[numXpdGain] = (uint16_t)(AR5416_PD_GAINS_IN_MASK - i);
2237            numXpdGain++;
2238        }
2239    }
2240    return numXpdGain;
2241}
2242
2243/*
2244 * Write the detector gain and biases.
2245 *
2246 * There are four power detector gain levels. The xpdMask in the EEPROM
2247 * determines which power detector gain levels have TX power calibration
2248 * data associated with them. This function writes the number of
2249 * PD gain levels and their values into the hardware.
2250 *
2251 * This is valid for all TX chains - the calibration data itself however
2252 * will likely differ per-chain.
2253 */
2254void
2255ar5416WriteDetectorGainBiases(struct ath_hal *ah, uint16_t numXpdGain,
2256    uint16_t xpdGainValues[])
2257{
2258    HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: numXpdGain: %d,"
2259      " xpdGainValues: %d, %d, %d\n", __func__, numXpdGain,
2260      xpdGainValues[0], xpdGainValues[1], xpdGainValues[2]);
2261
2262    OS_REG_WRITE(ah, AR_PHY_TPCRG1, (OS_REG_READ(ah, AR_PHY_TPCRG1) &
2263    	~(AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 |
2264	AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3)) |
2265	SM(numXpdGain - 1, AR_PHY_TPCRG1_NUM_PD_GAIN) |
2266	SM(xpdGainValues[0], AR_PHY_TPCRG1_PD_GAIN_1 ) |
2267	SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) |
2268	SM(xpdGainValues[2],  AR_PHY_TPCRG1_PD_GAIN_3));
2269}
2270
2271/*
2272 * Write the PDADC array to the given radio chain i.
2273 *
2274 * The 32 PDADC registers are written without any care about
2275 * their contents - so if various chips treat values as "special",
2276 * this routine will not care.
2277 */
2278void
2279ar5416WritePdadcValues(struct ath_hal *ah, int i, uint8_t pdadcValues[])
2280{
2281	int regOffset, regChainOffset;
2282	int j;
2283	int reg32;
2284
2285	regChainOffset = ar5416GetRegChainOffset(ah, i);
2286	regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
2287
2288	for (j = 0; j < 32; j++) {
2289		reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0)  |
2290		    ((pdadcValues[4*j + 1] & 0xFF) << 8)  |
2291		    ((pdadcValues[4*j + 2] & 0xFF) << 16) |
2292		    ((pdadcValues[4*j + 3] & 0xFF) << 24) ;
2293		OS_REG_WRITE(ah, regOffset, reg32);
2294		HALDEBUG(ah, HAL_DEBUG_EEPROM, "PDADC: Chain %d |"
2295		    " PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d"
2296		    " Value %3d | PDADC %3d Value %3d |\n",
2297		    i,
2298		    4*j, pdadcValues[4*j],
2299		    4*j+1, pdadcValues[4*j + 1],
2300		    4*j+2, pdadcValues[4*j + 2],
2301		    4*j+3, pdadcValues[4*j + 3]);
2302		regOffset += 4;
2303	}
2304}
2305
2306/**************************************************************
2307 * ar5416SetPowerCalTable
2308 *
2309 * Pull the PDADC piers from cal data and interpolate them across the given
2310 * points as well as from the nearest pier(s) to get a power detector
2311 * linear voltage to power level table.
2312 */
2313HAL_BOOL
2314ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
2315	const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset)
2316{
2317    CAL_DATA_PER_FREQ *pRawDataset;
2318    uint8_t  *pCalBChans = AH_NULL;
2319    uint16_t pdGainOverlap_t2;
2320    static uint8_t  pdadcValues[AR5416_NUM_PDADC_VALUES];
2321    uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
2322    uint16_t numPiers, i;
2323    int16_t  tMinCalPower;
2324    uint16_t numXpdGain, xpdMask;
2325    uint16_t xpdGainValues[AR5416_NUM_PD_GAINS];
2326    uint32_t regChainOffset;
2327
2328    OS_MEMZERO(xpdGainValues, sizeof(xpdGainValues));
2329
2330    xpdMask = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].xpdGain;
2331
2332    if (IS_EEP_MINOR_V2(ah)) {
2333        pdGainOverlap_t2 = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pdGainOverlap;
2334    } else {
2335    	pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
2336    }
2337
2338    if (IEEE80211_IS_CHAN_2GHZ(chan)) {
2339        pCalBChans = pEepData->calFreqPier2G;
2340        numPiers = AR5416_NUM_2G_CAL_PIERS;
2341    } else {
2342        pCalBChans = pEepData->calFreqPier5G;
2343        numPiers = AR5416_NUM_5G_CAL_PIERS;
2344    }
2345
2346    /* Calculate the value of xpdgains from the xpdGain Mask */
2347    numXpdGain = ar5416GetXpdGainValues(ah, xpdMask, xpdGainValues);
2348
2349    /* Write the detector gain biases and their number */
2350    ar5416WriteDetectorGainBiases(ah, numXpdGain, xpdGainValues);
2351
2352    for (i = 0; i < AR5416_MAX_CHAINS; i++) {
2353	regChainOffset = ar5416GetRegChainOffset(ah, i);
2354
2355        if (pEepData->baseEepHeader.txMask & (1 << i)) {
2356            if (IEEE80211_IS_CHAN_2GHZ(chan)) {
2357                pRawDataset = pEepData->calPierData2G[i];
2358            } else {
2359                pRawDataset = pEepData->calPierData5G[i];
2360            }
2361
2362            /* Fetch the gain boundaries and the PDADC values */
2363	    ar5416GetGainBoundariesAndPdadcs(ah,  chan, pRawDataset,
2364                                             pCalBChans, numPiers,
2365                                             pdGainOverlap_t2,
2366                                             &tMinCalPower, gainBoundaries,
2367                                             pdadcValues, numXpdGain);
2368
2369            if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
2370		ar5416SetGainBoundariesClosedLoop(ah, i, pdGainOverlap_t2,
2371		  gainBoundaries);
2372            }
2373
2374            /* Write the power values into the baseband power table */
2375	    ar5416WritePdadcValues(ah, i, pdadcValues);
2376        }
2377    }
2378    *pTxPowerIndexOffset = 0;
2379
2380    return AH_TRUE;
2381}
2382
2383/**************************************************************
2384 * ar5416GetGainBoundariesAndPdadcs
2385 *
2386 * Uses the data points read from EEPROM to reconstruct the pdadc power table
2387 * Called by ar5416SetPowerCalTable only.
2388 */
2389void
2390ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
2391                                 const struct ieee80211_channel *chan,
2392				 CAL_DATA_PER_FREQ *pRawDataSet,
2393                                 uint8_t * bChans,  uint16_t availPiers,
2394                                 uint16_t tPdGainOverlap, int16_t *pMinCalPower, uint16_t * pPdGainBoundaries,
2395                                 uint8_t * pPDADCValues, uint16_t numXpdGains)
2396{
2397
2398    int       i, j, k;
2399    int16_t   ss;         /* potentially -ve index for taking care of pdGainOverlap */
2400    uint16_t  idxL, idxR, numPiers; /* Pier indexes */
2401
2402    /* filled out Vpd table for all pdGains (chanL) */
2403    static uint8_t   vpdTableL[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB];
2404
2405    /* filled out Vpd table for all pdGains (chanR) */
2406    static uint8_t   vpdTableR[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB];
2407
2408    /* filled out Vpd table for all pdGains (interpolated) */
2409    static uint8_t   vpdTableI[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB];
2410
2411    uint8_t   *pVpdL, *pVpdR, *pPwrL, *pPwrR;
2412    uint8_t   minPwrT4[AR5416_NUM_PD_GAINS];
2413    uint8_t   maxPwrT4[AR5416_NUM_PD_GAINS];
2414    int16_t   vpdStep;
2415    int16_t   tmpVal;
2416    uint16_t  sizeCurrVpdTable, maxIndex, tgtIndex;
2417    HAL_BOOL    match;
2418    int16_t  minDelta = 0;
2419    CHAN_CENTERS centers;
2420
2421    ar5416GetChannelCenters(ah, chan, &centers);
2422
2423    /* Trim numPiers for the number of populated channel Piers */
2424    for (numPiers = 0; numPiers < availPiers; numPiers++) {
2425        if (bChans[numPiers] == AR5416_BCHAN_UNUSED) {
2426            break;
2427        }
2428    }
2429
2430    /* Find pier indexes around the current channel */
2431    match = ath_ee_getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center,
2432	IEEE80211_IS_CHAN_2GHZ(chan)), bChans, numPiers, &idxL, &idxR);
2433
2434    if (match) {
2435        /* Directly fill both vpd tables from the matching index */
2436        for (i = 0; i < numXpdGains; i++) {
2437            minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
2438            maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
2439            ath_ee_FillVpdTable(minPwrT4[i], maxPwrT4[i], pRawDataSet[idxL].pwrPdg[i],
2440                               pRawDataSet[idxL].vpdPdg[i], AR5416_PD_GAIN_ICEPTS, vpdTableI[i]);
2441        }
2442    } else {
2443        for (i = 0; i < numXpdGains; i++) {
2444            pVpdL = pRawDataSet[idxL].vpdPdg[i];
2445            pPwrL = pRawDataSet[idxL].pwrPdg[i];
2446            pVpdR = pRawDataSet[idxR].vpdPdg[i];
2447            pPwrR = pRawDataSet[idxR].pwrPdg[i];
2448
2449            /* Start Vpd interpolation from the max of the minimum powers */
2450            minPwrT4[i] = AH_MAX(pPwrL[0], pPwrR[0]);
2451
2452            /* End Vpd interpolation from the min of the max powers */
2453            maxPwrT4[i] = AH_MIN(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
2454            HALASSERT(maxPwrT4[i] > minPwrT4[i]);
2455
2456            /* Fill pier Vpds */
2457            ath_ee_FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, AR5416_PD_GAIN_ICEPTS, vpdTableL[i]);
2458            ath_ee_FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, AR5416_PD_GAIN_ICEPTS, vpdTableR[i]);
2459
2460            /* Interpolate the final vpd */
2461            for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
2462                vpdTableI[i][j] = (uint8_t)(ath_ee_interpolate((uint16_t)FREQ2FBIN(centers.synth_center,
2463		    IEEE80211_IS_CHAN_2GHZ(chan)),
2464                    bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j]));
2465            }
2466        }
2467    }
2468    *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
2469
2470    k = 0; /* index for the final table */
2471    for (i = 0; i < numXpdGains; i++) {
2472        if (i == (numXpdGains - 1)) {
2473            pPdGainBoundaries[i] = (uint16_t)(maxPwrT4[i] / 2);
2474        } else {
2475            pPdGainBoundaries[i] = (uint16_t)((maxPwrT4[i] + minPwrT4[i+1]) / 4);
2476        }
2477
2478        pPdGainBoundaries[i] = (uint16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
2479
2480	/* NB: only applies to owl 1.0 */
2481        if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah) ) {
2482	    /*
2483             * fix the gain delta, but get a delta that can be applied to min to
2484             * keep the upper power values accurate, don't think max needs to
2485             * be adjusted because should not be at that area of the table?
2486	     */
2487            minDelta = pPdGainBoundaries[0] - 23;
2488            pPdGainBoundaries[0] = 23;
2489        }
2490        else {
2491            minDelta = 0;
2492        }
2493
2494        /* Find starting index for this pdGain */
2495        if (i == 0) {
2496            if (AR_SREV_MERLIN_10_OR_LATER(ah))
2497                ss = (int16_t)(0 - (minPwrT4[i] / 2));
2498            else
2499                ss = 0; /* for the first pdGain, start from index 0 */
2500        } else {
2501	    /* need overlap entries extrapolated below. */
2502            ss = (int16_t)((pPdGainBoundaries[i-1] - (minPwrT4[i] / 2)) - tPdGainOverlap + 1 + minDelta);
2503        }
2504        vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
2505        vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
2506        /*
2507         *-ve ss indicates need to extrapolate data below for this pdGain
2508         */
2509        while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2510            tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
2511            pPDADCValues[k++] = (uint8_t)((tmpVal < 0) ? 0 : tmpVal);
2512            ss++;
2513        }
2514
2515        sizeCurrVpdTable = (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 +1);
2516        tgtIndex = (uint8_t)(pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2));
2517        maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
2518
2519        while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2520            pPDADCValues[k++] = vpdTableI[i][ss++];
2521        }
2522
2523        vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - vpdTableI[i][sizeCurrVpdTable - 2]);
2524        vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
2525        /*
2526         * for last gain, pdGainBoundary == Pmax_t2, so will
2527         * have to extrapolate
2528         */
2529        if (tgtIndex >= maxIndex) {  /* need to extrapolate above */
2530            while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2531                tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
2532                          (ss - maxIndex +1) * vpdStep));
2533                pPDADCValues[k++] = (uint8_t)((tmpVal > 255) ? 255 : tmpVal);
2534                ss++;
2535            }
2536        }               /* extrapolated above */
2537    }                   /* for all pdGainUsed */
2538
2539    /* Fill out pdGainBoundaries - only up to 2 allowed here, but hardware allows up to 4 */
2540    while (i < AR5416_PD_GAINS_IN_MASK) {
2541        pPdGainBoundaries[i] = pPdGainBoundaries[i-1];
2542        i++;
2543    }
2544
2545    while (k < AR5416_NUM_PDADC_VALUES) {
2546        pPDADCValues[k] = pPDADCValues[k-1];
2547        k++;
2548    }
2549    return;
2550}
2551
2552/*
2553 * The linux ath9k driver and (from what I've been told) the reference
2554 * Atheros driver enables the 11n PHY by default whether or not it's
2555 * configured.
2556 */
2557static void
2558ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan)
2559{
2560	uint32_t phymode;
2561	uint32_t enableDacFifo = 0;
2562	HAL_HT_MACMODE macmode;		/* MAC - 20/40 mode */
2563
2564	if (AR_SREV_KITE_10_OR_LATER(ah))
2565		enableDacFifo = (OS_REG_READ(ah, AR_PHY_TURBO) & AR_PHY_FC_ENABLE_DAC_FIFO);
2566
2567	/* Enable 11n HT, 20 MHz */
2568	phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
2569		| AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
2570
2571	/* Configure baseband for dynamic 20/40 operation */
2572	if (IEEE80211_IS_CHAN_HT40(chan)) {
2573		phymode |= AR_PHY_FC_DYN2040_EN;
2574
2575		/* Configure control (primary) channel at +-10MHz */
2576		if (IEEE80211_IS_CHAN_HT40U(chan))
2577			phymode |= AR_PHY_FC_DYN2040_PRI_CH;
2578#if 0
2579		/* Configure 20/25 spacing */
2580		if (ht->ht_extprotspacing == HAL_HT_EXTPROTSPACING_25)
2581			phymode |= AR_PHY_FC_DYN2040_EXT_CH;
2582#endif
2583		macmode = HAL_HT_MACMODE_2040;
2584	} else
2585		macmode = HAL_HT_MACMODE_20;
2586	OS_REG_WRITE(ah, AR_PHY_TURBO, phymode);
2587
2588	/* Configure MAC for 20/40 operation */
2589	ar5416Set11nMac2040(ah, macmode);
2590
2591	/* global transmit timeout (25 TUs default)*/
2592	/* XXX - put this elsewhere??? */
2593	OS_REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S) ;
2594
2595	/* carrier sense timeout */
2596	OS_REG_SET_BIT(ah, AR_GTTM, AR_GTTM_CST_USEC);
2597	OS_REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
2598}
2599
2600void
2601ar5416GetChannelCenters(struct ath_hal *ah,
2602	const struct ieee80211_channel *chan, CHAN_CENTERS *centers)
2603{
2604	uint16_t freq = ath_hal_gethwchannel(ah, chan);
2605
2606	centers->ctl_center = freq;
2607	centers->synth_center = freq;
2608	/*
2609	 * In 20/40 phy mode, the center frequency is
2610	 * "between" the control and extension channels.
2611	 */
2612	if (IEEE80211_IS_CHAN_HT40U(chan)) {
2613		centers->synth_center += HT40_CHANNEL_CENTER_SHIFT;
2614		centers->ext_center =
2615		    centers->synth_center + HT40_CHANNEL_CENTER_SHIFT;
2616	} else if (IEEE80211_IS_CHAN_HT40D(chan)) {
2617		centers->synth_center -= HT40_CHANNEL_CENTER_SHIFT;
2618		centers->ext_center =
2619		    centers->synth_center - HT40_CHANNEL_CENTER_SHIFT;
2620	} else {
2621		centers->ext_center = freq;
2622	}
2623}
2624
2625/*
2626 * Override the INI vals being programmed.
2627 */
2628static void
2629ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
2630{
2631	uint32_t val;
2632
2633	/*
2634	 * Set the RX_ABORT and RX_DIS and clear if off only after
2635	 * RXE is set for MAC. This prevents frames with corrupted
2636	 * descriptor status.
2637	 */
2638	OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
2639
2640	if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
2641		val = OS_REG_READ(ah, AR_PCU_MISC_MODE2);
2642		val &= (~AR_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE);
2643		if (!AR_SREV_9271(ah))
2644			val &= ~AR_PCU_MISC_MODE2_HWWAR1;
2645
2646		if (AR_SREV_KIWI_10_OR_LATER(ah))
2647			val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
2648
2649		OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
2650	}
2651
2652	/*
2653	 * Disable RIFS search on some chips to avoid baseband
2654	 * hang issues.
2655	 */
2656	if (AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah))
2657		(void) ar5416SetRifsDelay(ah, chan, AH_FALSE);
2658
2659        if (!AR_SREV_5416_V20_OR_LATER(ah) || AR_SREV_MERLIN(ah))
2660		return;
2661
2662	/*
2663	 * Disable BB clock gating
2664	 * Necessary to avoid issues on AR5416 2.0
2665	 */
2666	OS_REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
2667}
2668
2669struct ini {
2670	uint32_t        *data;          /* NB: !const */
2671	int             rows, cols;
2672};
2673
2674/*
2675 * Override XPA bias level based on operating frequency.
2676 * This is a v14 EEPROM specific thing for the AR9160.
2677 */
2678void
2679ar5416EepromSetAddac(struct ath_hal *ah, const struct ieee80211_channel *chan)
2680{
2681#define	XPA_LVL_FREQ(cnt)	(pModal->xpaBiasLvlFreq[cnt])
2682	MODAL_EEP_HEADER	*pModal;
2683	HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom;
2684	struct ar5416eeprom	*eep = &ee->ee_base;
2685	uint8_t biaslevel;
2686
2687	if (! AR_SREV_SOWL(ah))
2688		return;
2689
2690        if (EEP_MINOR(ah) < AR5416_EEP_MINOR_VER_7)
2691                return;
2692
2693	pModal = &(eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)]);
2694
2695	if (pModal->xpaBiasLvl != 0xff)
2696		biaslevel = pModal->xpaBiasLvl;
2697	else {
2698		uint16_t resetFreqBin, freqBin, freqCount = 0;
2699		CHAN_CENTERS centers;
2700
2701		ar5416GetChannelCenters(ah, chan, &centers);
2702
2703		resetFreqBin = FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan));
2704		freqBin = XPA_LVL_FREQ(0) & 0xff;
2705		biaslevel = (uint8_t) (XPA_LVL_FREQ(0) >> 14);
2706
2707		freqCount++;
2708
2709		while (freqCount < 3) {
2710			if (XPA_LVL_FREQ(freqCount) == 0x0)
2711			break;
2712
2713			freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
2714			if (resetFreqBin >= freqBin)
2715				biaslevel = (uint8_t)(XPA_LVL_FREQ(freqCount) >> 14);
2716			else
2717				break;
2718			freqCount++;
2719		}
2720	}
2721
2722	HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: overriding XPA bias level = %d\n",
2723	    __func__, biaslevel);
2724
2725	/*
2726	 * This is a dirty workaround for the const initval data,
2727	 * which will upset multiple AR9160's on the same board.
2728	 *
2729	 * The HAL should likely just have a private copy of the addac
2730	 * data per instance.
2731	 */
2732	if (IEEE80211_IS_CHAN_2GHZ(chan))
2733                HAL_INI_VAL((struct ini *) &AH5416(ah)->ah_ini_addac, 7, 1) =
2734		    (HAL_INI_VAL(&AH5416(ah)->ah_ini_addac, 7, 1) & (~0x18)) | biaslevel << 3;
2735        else
2736                HAL_INI_VAL((struct ini *) &AH5416(ah)->ah_ini_addac, 6, 1) =
2737		    (HAL_INI_VAL(&AH5416(ah)->ah_ini_addac, 6, 1) & (~0xc0)) | biaslevel << 6;
2738#undef XPA_LVL_FREQ
2739}
2740
2741static void
2742ar5416MarkPhyInactive(struct ath_hal *ah)
2743{
2744	OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
2745}
2746