ar5416_reset.c revision 203159
121308Sache/*
221308Sache * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
321308Sache * Copyright (c) 2002-2008 Atheros Communications, Inc.
421308Sache *
521308Sache * Permission to use, copy, modify, and/or distribute this software for any
621308Sache * purpose with or without fee is hereby granted, provided that the above
721308Sache * copyright notice and this permission notice appear in all copies.
821308Sache *
921308Sache * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1058310Sache * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1121308Sache * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1221308Sache * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1321308Sache * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1421308Sache * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1521308Sache * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1621308Sache *
1721308Sache * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c 203159 2010-01-29 10:10:14Z rpaulo $
1821308Sache */
1921308Sache#include "opt_ah.h"
2021308Sache
2158310Sache#include "ah.h"
2221308Sache#include "ah_internal.h"
2321308Sache#include "ah_devid.h"
2421308Sache
2521308Sache#include "ah_eeprom_v14.h"
2621308Sache#include "ah_eeprom_v4k.h"
2721308Sache
2821308Sache#include "ar5416/ar5416.h"
2921308Sache#include "ar5416/ar5416reg.h"
3021308Sache#include "ar5416/ar5416phy.h"
3121308Sache
3221308Sache/* Eeprom versioning macros. Returns true if the version is equal or newer than the ver specified */
3321308Sache#define	EEP_MINOR(_ah) \
3421308Sache	(AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK)
3521308Sache#define IS_EEP_MINOR_V2(_ah)	(EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_2)
3675406Sache#define IS_EEP_MINOR_V3(_ah)	(EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_3)
3775406Sache
3875406Sache/* Additional Time delay to wait after activiting the Base band */
3975406Sache#define BASE_ACTIVATE_DELAY	100	/* 100 usec */
4075406Sache#define PLL_SETTLE_DELAY	300	/* 300 usec */
4175406Sache#define RTC_PLL_SETTLE_DELAY    1000    /* 1 ms     */
4275406Sache
4375406Sachestatic void ar5416InitDMA(struct ath_hal *ah);
4475406Sachestatic void ar5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *);
4575406Sachestatic void ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode);
4675406Sachestatic void ar5416InitQoS(struct ath_hal *ah);
4775406Sachestatic void ar5416InitUserSettings(struct ath_hal *ah);
4875406Sache
4975406Sachestatic HAL_BOOL ar5416SetTransmitPower(struct ath_hal *ah,
5075406Sache	const struct ieee80211_channel *chan, uint16_t *rfXpdGain);
5175406Sache
5275406Sache#if 0
5375406Sachestatic HAL_BOOL	ar5416ChannelChange(struct ath_hal *, const struct ieee80211_channel *);
5475406Sache#endif
5575406Sachestatic void ar5416SetDeltaSlope(struct ath_hal *, const struct ieee80211_channel *);
5675406Sache
5775406Sachestatic HAL_BOOL ar5416SetResetPowerOn(struct ath_hal *ah);
5875406Sachestatic HAL_BOOL ar5416SetReset(struct ath_hal *ah, int type);
5975406Sachestatic void ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan);
6075406Sachestatic HAL_BOOL ar5416SetBoardValues(struct ath_hal *, const struct ieee80211_channel *);
6175406Sachestatic HAL_BOOL ar5416SetPowerPerRateTable(struct ath_hal *ah,
6275406Sache	struct ar5416eeprom *pEepData,
6321308Sache	struct ar5416eeprom_4k *pEepData4k,
6475406Sache	const struct ieee80211_channel *chan, int16_t *ratesArray,
6575406Sache	uint16_t cfgCtl, uint16_t AntennaReduction,
6675406Sache	uint16_t twiceMaxRegulatoryPower,
6775406Sache	uint16_t powerLimit);
6875406Sachestatic HAL_BOOL ar5416SetPowerCalTable(struct ath_hal *ah,
6921308Sache	struct ar5416eeprom *pEepData,
7021308Sache	struct ar5416eeprom_4k *pEepData4k,
7175406Sache	const struct ieee80211_channel *chan,
7275406Sache	int16_t *pTxPowerIndexOffset);
7375406Sachestatic uint16_t ar5416GetMaxEdgePower(struct ath_hal *ah, uint16_t freq,
7475406Sache	CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz);
7575406Sachestatic void ar5416GetTargetPowers(struct ath_hal *ah,
7675406Sache	const struct ieee80211_channel *chan, CAL_TARGET_POWER_HT *powInfo,
7775406Sache	uint16_t numChannels, CAL_TARGET_POWER_HT *pNewPower,
7875406Sache	uint16_t numRates, HAL_BOOL isHt40Target);
7975406Sachestatic void ar5416GetTargetPowersLeg(struct ath_hal *ah,
8075406Sache	const struct ieee80211_channel *chan, CAL_TARGET_POWER_LEG *powInfo,
8175406Sache	uint16_t numChannels, CAL_TARGET_POWER_LEG *pNewPower,
8275406Sache	uint16_t numRates, HAL_BOOL isExtTarget);
8375406Sache
8475406Sachestatic int16_t interpolate(uint16_t target, uint16_t srcLeft,
8575406Sache	uint16_t srcRight, int16_t targetLeft, int16_t targetRight);
8675406Sachestatic void ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan);
8721308Sachestatic void ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
8821308Sache	const struct ieee80211_channel *chan, CAL_DATA_PER_FREQ *pRawDataSet,
8975406Sache	CAL_DATA_PER_FREQ_4K *pRawDataSet4k,
9075406Sache	uint8_t * bChans, uint16_t availPiers,
9175406Sache	uint16_t tPdGainOverlap, int16_t *pMinCalPower,
9275406Sache	uint16_t * pPdGainBoundaries, uint8_t * pPDADCValues,
9375406Sache	uint16_t numXpdGains);
9475406Sachestatic HAL_BOOL getLowerUpperIndex(uint8_t target, uint8_t *pList,
9575406Sache	uint16_t listSize,  uint16_t *indexL, uint16_t *indexR);
9675406Sachestatic HAL_BOOL ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax,
9775406Sache	uint8_t *pPwrList, uint8_t *pVpdList,
9875406Sache	uint16_t numIntercepts, uint8_t *pRetVpdList);
9921308Sache
10021308Sache/*
10175406Sache * Places the device in and out of reset and then places sane
10275406Sache * values in the registers based on EEPROM config, initialization
10375406Sache * vectors (as determined by the mode), and station configuration
10475406Sache *
10575406Sache * bChannelChange is used to preserve DMA/PCU registers across
10675406Sache * a HW Reset during channel change.
10775406Sache */
10821308SacheHAL_BOOL
10921308Sachear5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
11075406Sache	struct ieee80211_channel *chan,
11175406Sache	HAL_BOOL bChannelChange, HAL_STATUS *status)
11275406Sache{
11375406Sache#define	N(a)	(sizeof (a) / sizeof (a[0]))
11475406Sache#define	FAIL(_code)	do { ecode = _code; goto bad; } while (0)
11575406Sache	struct ath_hal_5212 *ahp = AH5212(ah);
11675406Sache	HAL_CHANNEL_INTERNAL *ichan;
11775406Sache	uint32_t saveDefAntenna, saveLedState;
11875406Sache	uint32_t macStaId1;
11975406Sache	uint16_t rfXpdGain[2];
12075406Sache	HAL_STATUS ecode;
12175406Sache	uint32_t powerVal, rssiThrReg;
12275406Sache	uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow;
12375406Sache	int i;
12475406Sache
12575406Sache	OS_MARK(ah, AH_MARK_RESET, bChannelChange);
12675406Sache
12775406Sache	/* Bring out of sleep mode */
12875406Sache	if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
12975406Sache		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip did not wakeup\n",
13075406Sache		    __func__);
13175406Sache		FAIL(HAL_EIO);
13275406Sache	}
13375406Sache
13475406Sache	/*
13575406Sache	 * Map public channel to private.
13621308Sache	 */
13721308Sache	ichan = ath_hal_checkchannel(ah, chan);
13875406Sache	if (ichan == AH_NULL)
13975406Sache		FAIL(HAL_EINVAL);
14075406Sache	switch (opmode) {
14175406Sache	case HAL_M_STA:
14275406Sache	case HAL_M_IBSS:
14375406Sache	case HAL_M_HOSTAP:
14421308Sache	case HAL_M_MONITOR:
14521308Sache		break;
14675406Sache	default:
14775406Sache		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n",
14875406Sache		    __func__, opmode);
14975406Sache		FAIL(HAL_EINVAL);
15075406Sache		break;
15175406Sache	}
15275406Sache	HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1);
15375406Sache
15475406Sache	/* XXX Turn on fast channel change for 5416 */
15575406Sache	/*
15675406Sache	 * Preserve the bmiss rssi threshold and count threshold
15775406Sache	 * across resets
15875406Sache	 */
15975406Sache	rssiThrReg = OS_REG_READ(ah, AR_RSSI_THR);
16075406Sache	/* If reg is zero, first time thru set to default val */
16175406Sache	if (rssiThrReg == 0)
16275406Sache		rssiThrReg = INIT_RSSI_THR;
16375406Sache
16475406Sache	/*
16575406Sache	 * Preserve the antenna on a channel change
16675406Sache	 */
16775406Sache	saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
16875406Sache	if (saveDefAntenna == 0)		/* XXX magic constants */
16975406Sache		saveDefAntenna = 1;
17075406Sache
17175406Sache	/* Save hardware flag before chip reset clears the register */
17221308Sache	macStaId1 = OS_REG_READ(ah, AR_STA_ID1) &
17321308Sache		(AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT);
17475406Sache
17575406Sache	/* Save led state from pci config register */
17675406Sache	saveLedState = OS_REG_READ(ah, AR_MAC_LED) &
17775406Sache		(AR_MAC_LED_ASSOC | AR_MAC_LED_MODE |
17875406Sache		 AR_MAC_LED_BLINK_THRESH_SEL | AR_MAC_LED_BLINK_SLOW);
17921308Sache
18021308Sache	if (!ar5416ChipReset(ah, chan)) {
18121308Sache		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
18275406Sache		FAIL(HAL_EIO);
18375406Sache	}
18475406Sache
18575406Sache	/* Restore bmiss rssi & count thresholds */
18675406Sache	OS_REG_WRITE(ah, AR_RSSI_THR, rssiThrReg);
18775406Sache
18875406Sache	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
18975406Sache
19075406Sache	AH5416(ah)->ah_writeIni(ah, chan);
19175406Sache
19275406Sache	/* Setup 11n MAC/Phy mode registers */
19375406Sache	ar5416Set11nRegs(ah, chan);
19475406Sache
19575406Sache	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
19675406Sache
19775406Sache	HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_DAG_CTRLCCK=0x%x\n",
19875406Sache		__func__, OS_REG_READ(ah,AR_PHY_DAG_CTRLCCK));
19975406Sache	HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_ADC_CTL=0x%x\n",
20075406Sache		__func__, OS_REG_READ(ah,AR_PHY_ADC_CTL));
20175406Sache
20275406Sache	/* Set the mute mask to the correct default */
20375406Sache	if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2)
20475406Sache		OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F);
20575406Sache
20675406Sache	if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) {
20775406Sache		/* Clear reg to alllow RX_CLEAR line debug */
20875406Sache		OS_REG_WRITE(ah, AR_PHY_BLUETOOTH,  0);
20975406Sache	}
21075406Sache	if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) {
21175406Sache#ifdef notyet
21275406Sache		/* Enable burst prefetch for the data queues */
21375406Sache		OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... );
21475406Sache		/* Enable double-buffering */
21575406Sache		OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS);
21675406Sache#endif
21775406Sache	}
21875406Sache
21975406Sache	/* Set ADC/DAC select values */
22075406Sache	OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
22175406Sache
22275406Sache	if (AH5416(ah)->ah_rx_chainmask == 0x5 ||
22375406Sache	    AH5416(ah)->ah_tx_chainmask == 0x5)
22475406Sache		OS_REG_WRITE(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
22575406Sache	/* Setup Chain Masks */
22675406Sache	OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, AH5416(ah)->ah_rx_chainmask);
22775406Sache	OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, AH5416(ah)->ah_rx_chainmask);
22875406Sache	OS_REG_WRITE(ah, AR_SELFGEN_MASK, AH5416(ah)->ah_tx_chainmask);
22975406Sache
23075406Sache	/* Setup the transmit power values. */
23175406Sache	if (!ar5416SetTransmitPower(ah, chan, rfXpdGain)) {
23275406Sache		HALDEBUG(ah, HAL_DEBUG_ANY,
23375406Sache		    "%s: error init'ing transmit power\n", __func__);
23475406Sache		FAIL(HAL_EIO);
23575406Sache	}
23675406Sache
23775406Sache	/* Write the analog registers */
23875406Sache	if (!ahp->ah_rfHal->setRfRegs(ah, chan,
23975406Sache	    IEEE80211_IS_CHAN_2GHZ(chan) ? 2: 1, rfXpdGain)) {
24075406Sache		HALDEBUG(ah, HAL_DEBUG_ANY,
24175406Sache		    "%s: ar5212SetRfRegs failed\n", __func__);
24275406Sache		FAIL(HAL_EIO);
24375406Sache	}
24475406Sache
24575406Sache	/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
24675406Sache	if (IEEE80211_IS_CHAN_OFDM(chan)|| IEEE80211_IS_CHAN_HT(chan))
24775406Sache		ar5416SetDeltaSlope(ah, chan);
24875406Sache
24975406Sache	AH5416(ah)->ah_spurMitigate(ah, chan);
25075406Sache
25175406Sache	/* Setup board specific options for EEPROM version 3 */
25275406Sache	if (!ar5416SetBoardValues(ah, chan)) {
25375406Sache		HALDEBUG(ah, HAL_DEBUG_ANY,
25475406Sache		    "%s: error setting board options\n", __func__);
25575406Sache		FAIL(HAL_EIO);
25675406Sache	}
25775406Sache
25875406Sache	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
25975406Sache
26075406Sache	OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
26175406Sache	OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
26275406Sache		| macStaId1
26375406Sache		| AR_STA_ID1_RTS_USE_DEF
26475406Sache		| ahp->ah_staId1Defaults
26575406Sache	);
26675406Sache	ar5212SetOperatingMode(ah, opmode);
26775406Sache
26875406Sache	/* Set Venice BSSID mask according to current state */
26975406Sache	OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
27075406Sache	OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
27175406Sache
27275406Sache	/* Restore previous led state */
27375406Sache	OS_REG_WRITE(ah, AR_MAC_LED, OS_REG_READ(ah, AR_MAC_LED) | saveLedState);
27475406Sache
27575406Sache	/* Restore previous antenna */
27675406Sache	OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
27775406Sache
27875406Sache	/* then our BSSID */
27975406Sache	OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
28075406Sache	OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4));
28175406Sache
28275406Sache	/* Restore bmiss rssi & count thresholds */
28375406Sache	OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr);
28475406Sache
28575406Sache	OS_REG_WRITE(ah, AR_ISR, ~0);		/* cleared on write */
28675406Sache
28775406Sache	if (!ar5212SetChannel(ah, chan))
28875406Sache		FAIL(HAL_EIO);
28975406Sache
29075406Sache	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
29175406Sache
29275406Sache	/* Set 1:1 QCU to DCU mapping for all queues */
29375406Sache	for (i = 0; i < AR_NUM_DCU; i++)
29475406Sache		OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
29575406Sache
29675406Sache	ahp->ah_intrTxqs = 0;
29775406Sache	for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++)
29875406Sache		ar5212ResetTxQueue(ah, i);
29975406Sache
30075406Sache	ar5416InitIMR(ah, opmode);
30175406Sache	ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1);
30275406Sache	ar5416InitQoS(ah);
30375406Sache	ar5416InitUserSettings(ah);
30475406Sache
30575406Sache	/*
30675406Sache	 * disable seq number generation in hw
30775406Sache	 */
30875406Sache	 OS_REG_WRITE(ah, AR_STA_ID1,
30975406Sache	     OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
31021308Sache
31121308Sache	ar5416InitDMA(ah);
31221308Sache
31321308Sache	/*
31421308Sache	 * program OBS bus to see MAC interrupts
31521308Sache	 */
31675406Sache	OS_REG_WRITE(ah, AR_OBS, 8);
31775406Sache
31875406Sache#ifdef AR5416_INT_MITIGATION
31975406Sache	OS_REG_WRITE(ah, AR_MIRT, 0);
32075406Sache	OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
32175406Sache	OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
32275406Sache#endif
32375406Sache
32475406Sache	ar5416InitBB(ah, chan);
32575406Sache
32675406Sache	/* Setup compression registers */
32775406Sache	ar5212SetCompRegs(ah);		/* XXX not needed? */
32875406Sache
32975406Sache	/*
33075406Sache	 * 5416 baseband will check the per rate power table
33175406Sache	 * and select the lower of the two
33275406Sache	 */
33375406Sache	ackTpcPow = 63;
33475406Sache	ctsTpcPow = 63;
33575406Sache	chirpTpcPow = 63;
33675406Sache	powerVal = SM(ackTpcPow, AR_TPC_ACK) |
33775406Sache		SM(ctsTpcPow, AR_TPC_CTS) |
33875406Sache		SM(chirpTpcPow, AR_TPC_CHIRP);
33975406Sache	OS_REG_WRITE(ah, AR_TPC, powerVal);
34075406Sache
34175406Sache	if (!ar5416InitCal(ah, chan))
34275406Sache		FAIL(HAL_ESELFTEST);
34321308Sache
34475406Sache	AH_PRIVATE(ah)->ah_opmode = opmode;	/* record operating mode */
34575406Sache
34675406Sache	if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
34775406Sache		chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
34875406Sache
34921308Sache	HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
35021308Sache
35175406Sache	OS_MARK(ah, AH_MARK_RESET_DONE, 0);
35275406Sache
35375406Sache	return AH_TRUE;
35475406Sachebad:
35575406Sache	OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
35675406Sache	if (status != AH_NULL)
35775406Sache		*status = ecode;
35875406Sache	return AH_FALSE;
35975406Sache#undef FAIL
36075406Sache#undef N
36175406Sache}
36275406Sache
36375406Sache#if 0
36475406Sache/*
36575406Sache * This channel change evaluates whether the selected hardware can
36675406Sache * perform a synthesizer-only channel change (no reset).  If the
36721308Sache * TX is not stopped, or the RFBus cannot be granted in the given
36821308Sache * time, the function returns false as a reset is necessary
36975406Sache */
37075406SacheHAL_BOOL
37175406Sachear5416ChannelChange(struct ath_hal *ah, const structu ieee80211_channel *chan)
37275406Sache{
37375406Sache	uint32_t       ulCount;
37475406Sache	uint32_t   data, synthDelay, qnum;
37575406Sache	uint16_t   rfXpdGain[4];
37675406Sache	struct ath_hal_5212 *ahp = AH5212(ah);
37775406Sache	HAL_CHANNEL_INTERNAL *ichan;
37875406Sache
37921308Sache	/*
38021308Sache	 * Map public channel to private.
38175406Sache	 */
38275406Sache	ichan = ath_hal_checkchannel(ah, chan);
38375406Sache
38475406Sache	/* TX must be stopped or RF Bus grant will not work */
38575406Sache	for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) {
38675406Sache		if (ar5212NumTxPending(ah, qnum)) {
38775406Sache			HALDEBUG(ah, HAL_DEBUG_ANY,
38821308Sache			    "%s: frames pending on queue %d\n", __func__, qnum);
38921308Sache			return AH_FALSE;
39075406Sache		}
39175406Sache	}
39275406Sache
39375406Sache	/*
39475406Sache	 * Kill last Baseband Rx Frame - Request analog bus grant
39575406Sache	 */
39675406Sache	OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST);
39775406Sache	if (!ath_hal_wait(ah, AR_PHY_RFBUS_GNT, AR_PHY_RFBUS_GRANT_EN, AR_PHY_RFBUS_GRANT_EN)) {
39875406Sache		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: could not kill baseband rx\n",
39975406Sache		    __func__);
40075406Sache		return AH_FALSE;
40175406Sache	}
40275406Sache
40375406Sache	ar5416Set11nRegs(ah, chan);	/* NB: setup 5416-specific regs */
40475406Sache
40575406Sache	/* Change the synth */
40675406Sache	if (!ar5212SetChannel(ah, chan))
40775406Sache		return AH_FALSE;
40875406Sache
40975406Sache	/* Setup the transmit power values. */
41075406Sache	if (!ar5416SetTransmitPower(ah, chan, rfXpdGain)) {
41175406Sache		HALDEBUG(ah, HAL_DEBUG_ANY,
41275406Sache		    "%s: error init'ing transmit power\n", __func__);
41375406Sache		return AH_FALSE;
41475406Sache	}
41575406Sache
41621308Sache	/*
41721308Sache	 * Wait for the frequency synth to settle (synth goes on
41875406Sache	 * via PHY_ACTIVE_EN).  Read the phy active delay register.
41975406Sache	 * Value is in 100ns increments.
42075406Sache	 */
42175406Sache	data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
42275406Sache	if (IS_CHAN_CCK(ichan)) {
42375406Sache		synthDelay = (4 * data) / 22;
42421308Sache	} else {
42521308Sache		synthDelay = data / 10;
42675406Sache	}
42775406Sache
42875406Sache	OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
42975406Sache
43075406Sache	/* Release the RFBus Grant */
43175406Sache	OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
43275406Sache
43375406Sache	/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
43475406Sache	if (IEEE80211_IS_CHAN_OFDM(ichan)|| IEEE80211_IS_CHAN_HT(chan)) {
43575406Sache		HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3);
43675406Sache		ar5212SetSpurMitigation(ah, chan);
43775406Sache		ar5416SetDeltaSlope(ah, chan);
43875406Sache	}
43975406Sache
44075406Sache	/* XXX spur mitigation for Melin */
44175406Sache
44275406Sache	if (!IEEE80211_IS_CHAN_DFS(chan))
44375406Sache		chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
44475406Sache
44575406Sache	ichan->channel_time = 0;
44675406Sache	ichan->tsf_last = ar5212GetTsf64(ah);
44775406Sache	ar5212TxEnable(ah, AH_TRUE);
44875406Sache	return AH_TRUE;
44975406Sache}
45075406Sache#endif
45175406Sache
45221308Sachestatic void
45321308Sachear5416InitDMA(struct ath_hal *ah)
45475406Sache{
45575406Sache
45675406Sache	/*
45775406Sache	 * set AHB_MODE not to do cacheline prefetches
45875406Sache	 */
45921308Sache	OS_REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN);
46021308Sache
46121308Sache	/*
46221308Sache	 * let mac dma reads be in 128 byte chunks
46321308Sache	 */
46421308Sache	OS_REG_WRITE(ah, AR_TXCFG,
46521308Sache		(OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK) | AR_TXCFG_DMASZ_128B);
46621308Sache
46721308Sache	/*
46821308Sache	 * let mac dma writes be in 128 byte chunks
46921308Sache	 */
47021308Sache	OS_REG_WRITE(ah, AR_RXCFG,
47121308Sache		(OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK) | AR_RXCFG_DMASZ_128B);
47221308Sache
47321308Sache	/* XXX restore TX trigger level */
47421308Sache
47521308Sache	/*
47621308Sache	 * Setup receive FIFO threshold to hold off TX activities
47721308Sache	 */
47821308Sache	OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
47921308Sache
48021308Sache	/*
48121308Sache	 * reduce the number of usable entries in PCU TXBUF to avoid
48221308Sache	 * wrap around.
48321308Sache	 */
48421308Sache	if (AR_SREV_KITE(ah))
48521308Sache		OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
48621308Sache		    AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
48721308Sache	else
48821308Sache		OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
48921308Sache		    AR_PCU_TXBUF_CTRL_USABLE_SIZE);
49021308Sache}
49121308Sache
49221308Sachestatic void
49321308Sachear5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *chan)
49421308Sache{
49521308Sache	uint32_t synthDelay;
49621308Sache
49721308Sache	/*
49821308Sache	 * Wait for the frequency synth to settle (synth goes on
49921308Sache	 * via AR_PHY_ACTIVE_EN).  Read the phy active delay register.
50021308Sache	 * Value is in 100ns increments.
50121308Sache	  */
50221308Sache	synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
50321308Sache	if (IEEE80211_IS_CHAN_CCK(chan)) {
50421308Sache		synthDelay = (4 * synthDelay) / 22;
50521308Sache	} else {
50621308Sache		synthDelay /= 10;
50721308Sache	}
50821308Sache
50921308Sache	/* Turn on PLL on 5416 */
51021308Sache	HALDEBUG(ah, HAL_DEBUG_RESET, "%s %s channel\n",
51121308Sache	    __func__, IEEE80211_IS_CHAN_5GHZ(chan) ? "5GHz" : "2GHz");
51221308Sache	ar5416InitPLL(ah, chan);
51321308Sache
51421308Sache	/* Activate the PHY (includes baseband activate and synthesizer on) */
51521308Sache	OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
51621308Sache
51721308Sache	/*
51821308Sache	 * If the AP starts the calibration before the base band timeout
51921308Sache	 * completes  we could get rx_clear false triggering.  Add an
52021308Sache	 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
52121308Sache	 * does not happen.
52221308Sache	 */
52321308Sache	if (IEEE80211_IS_CHAN_HALF(chan)) {
52421308Sache		OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);
52521308Sache	} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
52621308Sache		OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);
52721308Sache	} else {
52821308Sache		OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
52921308Sache	}
53021308Sache}
53121308Sache
53221308Sachestatic void
53321308Sachear5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode)
53421308Sache{
53521308Sache	struct ath_hal_5212 *ahp = AH5212(ah);
53621308Sache
53721308Sache	/*
53821308Sache	 * Setup interrupt handling.  Note that ar5212ResetTxQueue
53921308Sache	 * manipulates the secondary IMR's as queues are enabled
54021308Sache	 * and disabled.  This is done with RMW ops to insure the
54121308Sache	 * settings we make here are preserved.
54221308Sache	 */
54321308Sache        ahp->ah_maskReg = AR_IMR_TXERR | AR_IMR_TXURN
54421308Sache			| AR_IMR_RXERR | AR_IMR_RXORN
54521308Sache                        | AR_IMR_BCNMISC;
54621308Sache
54721308Sache#ifdef AR5416_INT_MITIGATION
54821308Sache       	ahp->ah_maskReg |= AR_IMR_TXINTM | AR_IMR_RXINTM
54921308Sache			|  AR_IMR_TXMINTR | AR_IMR_RXMINTR;
55021308Sache#else
55121308Sache        ahp->ah_maskReg |= AR_IMR_TXOK | AR_IMR_RXOK;
55221308Sache#endif
55321308Sache	if (opmode == HAL_M_HOSTAP)
55421308Sache		ahp->ah_maskReg |= AR_IMR_MIB;
55521308Sache	OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
55621308Sache	/* Enable bus errors that are OR'd to set the HIUERR bit */
55721308Sache#if 0
55821308Sache	OS_REG_WRITE(ah, AR_IMR_S2,
55921308Sache	    	OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT | AR_IMR_S2_CST);
56021308Sache#endif
56121308Sache}
56221308Sache
56321308Sachestatic void
56421308Sachear5416InitQoS(struct ath_hal *ah)
56521308Sache{
56621308Sache	/* QoS support */
56721308Sache	OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa);	/* XXX magic */
56821308Sache	OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210);	/* XXX magic */
56921308Sache
57021308Sache	/* Turn on NOACK Support for QoS packets */
57121308Sache	OS_REG_WRITE(ah, AR_NOACK,
57221308Sache		SM(2, AR_NOACK_2BIT_VALUE) |
57321308Sache		SM(5, AR_NOACK_BIT_OFFSET) |
57421308Sache		SM(0, AR_NOACK_BYTE_OFFSET));
57521308Sache
57621308Sache    	/*
57721308Sache    	 * initialize TXOP for all TIDs
57821308Sache    	 */
57921308Sache	OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
58021308Sache	OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
58121308Sache	OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
58221308Sache	OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
58321308Sache	OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
58421308Sache}
58521308Sache
58621308Sachestatic void
58721308Sachear5416InitUserSettings(struct ath_hal *ah)
58821308Sache{
58921308Sache	struct ath_hal_5212 *ahp = AH5212(ah);
59021308Sache
59121308Sache	/* Restore user-specified settings */
59221308Sache	if (ahp->ah_miscMode != 0)
59321308Sache		OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
59421308Sache	if (ahp->ah_sifstime != (u_int) -1)
59521308Sache		ar5212SetSifsTime(ah, ahp->ah_sifstime);
59621308Sache	if (ahp->ah_slottime != (u_int) -1)
59721308Sache		ar5212SetSlotTime(ah, ahp->ah_slottime);
59821308Sache	if (ahp->ah_acktimeout != (u_int) -1)
59921308Sache		ar5212SetAckTimeout(ah, ahp->ah_acktimeout);
60021308Sache	if (ahp->ah_ctstimeout != (u_int) -1)
60175406Sache		ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout);
60275406Sache	if (AH_PRIVATE(ah)->ah_diagreg != 0)
60375406Sache		OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
60475406Sache#if 0 /* XXX Todo */
60575406Sache	if (ahp->ah_globaltxtimeout != (u_int) -1)
60675406Sache        	ar5416SetGlobalTxTimeout(ah, ahp->ah_globaltxtimeout);
60775406Sache#endif
60875406Sache}
60975406Sache
61075406Sache/*
61175406Sache * Places the hardware into reset and then pulls it out of reset
61275406Sache */
61375406SacheHAL_BOOL
61475406Sachear5416ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
61575406Sache{
61675406Sache	OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
61775406Sache	/*
61875406Sache	 * Warm reset is optimistic.
61975406Sache	 */
62075406Sache	if (AR_SREV_MERLIN_20_OR_LATER(ah) &&
62175406Sache	    ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) {
62275406Sache		if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON))
62375406Sache			return AH_FALSE;
62475406Sache	} else {
62575406Sache		if (!ar5416SetResetReg(ah, HAL_RESET_WARM))
62675406Sache			return AH_FALSE;
62775406Sache	}
62821308Sache
62975406Sache	/* Bring out of sleep mode (AGAIN) */
63075406Sache	if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
63175406Sache	       return AH_FALSE;
63275406Sache
63375406Sache	ar5416InitPLL(ah, chan);
63421308Sache
63521308Sache	/*
63675406Sache	 * Perform warm reset before the mode/PLL/turbo registers
63775406Sache	 * are changed in order to deactivate the radio.  Mode changes
63875406Sache	 * with an active radio can result in corrupted shifts to the
63975406Sache	 * radio device.
64075406Sache	 */
64175406Sache	if (chan != AH_NULL) {
64275406Sache		uint32_t rfMode;
64375406Sache
64475406Sache		/* treat channel B as channel G , no  B mode suport in owl */
64575406Sache		rfMode = IEEE80211_IS_CHAN_CCK(chan) ?
64675406Sache		    AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
64775406Sache		if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
64875406Sache			/* phy mode bits for 5GHz channels require Fast Clock */
64975406Sache			rfMode |= AR_PHY_MODE_DYNAMIC
65075406Sache			       |  AR_PHY_MODE_DYN_CCK_DISABLE;
65175406Sache		} else if (!AR_SREV_MERLIN_10_OR_LATER(ah)) {
65221308Sache			rfMode |= IEEE80211_IS_CHAN_5GHZ(chan) ?
65321308Sache				AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
65475406Sache		}
65575406Sache		OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
65675406Sache	}
65775406Sache	return AH_TRUE;
65875406Sache}
65975406Sache
66075406Sache/*
66175406Sache * Delta slope coefficient computation.
66275406Sache * Required for OFDM operation.
66375406Sache */
66421308Sachestatic void
66521308Sachear5416GetDeltaSlopeValues(struct ath_hal *ah, uint32_t coef_scaled,
66675406Sache                          uint32_t *coef_mantissa, uint32_t *coef_exponent)
66775406Sache{
66875406Sache#define COEF_SCALE_S 24
66975406Sache    uint32_t coef_exp, coef_man;
67075406Sache    /*
67175406Sache     * ALGO -> coef_exp = 14-floor(log2(coef));
67275406Sache     * floor(log2(x)) is the highest set bit position
67321308Sache     */
67421308Sache    for (coef_exp = 31; coef_exp > 0; coef_exp--)
67575406Sache            if ((coef_scaled >> coef_exp) & 0x1)
67675406Sache                    break;
67775406Sache    /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */
67875406Sache    HALASSERT(coef_exp);
67975406Sache    coef_exp = 14 - (coef_exp - COEF_SCALE_S);
68075406Sache
68175406Sache    /*
68275406Sache     * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5);
68375406Sache     * The coefficient is already shifted up for scaling
68475406Sache     */
68575406Sache    coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
68675406Sache
68775406Sache    *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
68875406Sache    *coef_exponent = coef_exp - 16;
68975406Sache
69075406Sache#undef COEF_SCALE_S
69175406Sache}
69275406Sache
69375406Sachevoid
69475406Sachear5416SetDeltaSlope(struct ath_hal *ah, const struct ieee80211_channel *chan)
69575406Sache{
69675406Sache#define INIT_CLOCKMHZSCALED	0x64000000
69775406Sache	uint32_t coef_scaled, ds_coef_exp, ds_coef_man;
69875406Sache	uint32_t clockMhzScaled;
69975406Sache
70075406Sache	CHAN_CENTERS centers;
70121308Sache
70221308Sache	/* half and quarter rate can divide the scaled clock by 2 or 4 respectively */
70375406Sache	/* scale for selected channel bandwidth */
70475406Sache	clockMhzScaled = INIT_CLOCKMHZSCALED;
70575406Sache	if (IEEE80211_IS_CHAN_TURBO(chan))
70675406Sache		clockMhzScaled <<= 1;
70775406Sache	else if (IEEE80211_IS_CHAN_HALF(chan))
70875406Sache		clockMhzScaled >>= 1;
70921308Sache	else if (IEEE80211_IS_CHAN_QUARTER(chan))
71021308Sache		clockMhzScaled >>= 2;
71175406Sache
71275406Sache	/*
71375406Sache	 * ALGO -> coef = 1e8/fcarrier*fclock/40;
71475406Sache	 * scaled coef to provide precision for this floating calculation
71575406Sache	 */
71675406Sache	ar5416GetChannelCenters(ah, chan, &centers);
71775406Sache	coef_scaled = clockMhzScaled / centers.synth_center;
71875406Sache
71975406Sache 	ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
72075406Sache
72175406Sache	OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3,
72275406Sache		AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
72375406Sache	OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3,
72475406Sache		AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
72575406Sache
72675406Sache        /*
72775406Sache         * For Short GI,
72875406Sache         * scaled coeff is 9/10 that of normal coeff
72975406Sache         */
73075406Sache        coef_scaled = (9 * coef_scaled)/10;
73175406Sache
73275406Sache        ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
73375406Sache
73475406Sache        /* for short gi */
73575406Sache        OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI,
73675406Sache                AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
73721308Sache        OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI,
73821308Sache                AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
73975406Sache#undef INIT_CLOCKMHZSCALED
74075406Sache}
74175406Sache
74275406Sache/*
74375406Sache * Set a limit on the overall output power.  Used for dynamic
74421308Sache * transmit power control and the like.
74521308Sache *
74621308Sache * NB: limit is in units of 0.5 dbM.
74775406Sache */
74875406SacheHAL_BOOL
74975406Sachear5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
75075406Sache{
75175406Sache	uint16_t dummyXpdGains[2];
75275406Sache
75375406Sache	AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);
75475406Sache	return ar5416SetTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan,
75575406Sache			dummyXpdGains);
75675406Sache}
75775406Sache
75875406SacheHAL_BOOL
75975406Sachear5416GetChipPowerLimits(struct ath_hal *ah,
76075406Sache	struct ieee80211_channel *chan)
76175406Sache{
76275406Sache	struct ath_hal_5212 *ahp = AH5212(ah);
76375406Sache	int16_t minPower, maxPower;
76475406Sache
76575406Sache	/*
76675406Sache	 * Get Pier table max and min powers.
76775406Sache	 */
76875406Sache	if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) {
76975406Sache		/* NB: rf code returns 1/4 dBm units, convert */
77075406Sache		chan->ic_maxpower = maxPower / 2;
77175406Sache		chan->ic_minpower = minPower / 2;
77275406Sache	} else {
77375406Sache		HALDEBUG(ah, HAL_DEBUG_ANY,
77475406Sache		    "%s: no min/max power for %u/0x%x\n",
77575406Sache		    __func__, chan->ic_freq, chan->ic_flags);
77675406Sache		chan->ic_maxpower = AR5416_MAX_RATE_POWER;
77775406Sache		chan->ic_minpower = 0;
77875406Sache	}
77975406Sache	HALDEBUG(ah, HAL_DEBUG_RESET,
78075406Sache	    "Chan %d: MaxPow = %d MinPow = %d\n",
78175406Sache	    chan->ic_freq, chan->ic_maxpower, chan->ic_minpower);
78275406Sache	return AH_TRUE;
78375406Sache}
78475406Sache
78575406Sache/* XXX gag, this is sick */
78675406Sachetypedef enum Ar5416_Rates {
78775406Sache	rate6mb,  rate9mb,  rate12mb, rate18mb,
78875406Sache	rate24mb, rate36mb, rate48mb, rate54mb,
78975406Sache	rate1l,   rate2l,   rate2s,   rate5_5l,
79075406Sache	rate5_5s, rate11l,  rate11s,  rateXr,
79175406Sache	rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
79275406Sache	rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
79375406Sache	rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
79475406Sache	rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
79575406Sache	rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
79675406Sache	Ar5416RateSize
79775406Sache} AR5416_RATES;
79875406Sache
79975406Sache/**************************************************************
80075406Sache * ar5416SetTransmitPower
80175406Sache *
80275406Sache * Set the transmit power in the baseband for the given
80375406Sache * operating channel and mode.
80475406Sache */
80575406Sachestatic HAL_BOOL
80675406Sachear5416SetTransmitPower(struct ath_hal *ah,
80775406Sache	const struct ieee80211_channel *chan, uint16_t *rfXpdGain)
80875406Sache{
80975406Sache#define POW_SM(_r, _s)     (((_r) & 0x3f) << (_s))
81075406Sache#define N(a)            (sizeof (a) / sizeof (a[0]))
81175406Sache
81275406Sache    MODAL_EEP_HEADER	*pModal;
81375406Sache    MODAL_EEP4K_HEADER	*pModal4k;
81475406Sache    struct ath_hal_5212 *ahp = AH5212(ah);
81575406Sache    int16_t		ratesArray[Ar5416RateSize];
81675406Sache    int16_t		txPowerIndexOffset = 0;
81775406Sache    uint8_t		ht40PowerIncForPdadc = 2;
81875406Sache    int			i;
81975406Sache
82075406Sache    uint16_t		cfgCtl;
82175406Sache    uint16_t		powerLimit;
82275406Sache    uint16_t		twiceAntennaReduction;
82375406Sache    uint16_t		twiceMaxRegulatoryPower;
82475406Sache    int16_t		maxPower;
82575406Sache    HAL_EEPROM_v14 *ee;
82675406Sache    HAL_EEPROM_v4k *ee4k;
82775406Sache    struct ar5416eeprom	*pEepData;
82875406Sache    struct ar5416eeprom_4k *pEepData4k;
82975406Sache
83075406Sache    HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1);
83175406Sache
83275406Sache    /* Setup info for the actual eeprom */
83375406Sache    OS_MEMZERO(ratesArray, sizeof(ratesArray));
83475406Sache    cfgCtl = ath_hal_getctl(ah, chan);
83575406Sache    powerLimit = chan->ic_maxregpower * 2;
83675406Sache    twiceAntennaReduction = chan->ic_maxantgain;
83775406Sache    twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit);
83875406Sache    if (AR_SREV_KITE(ah)) {
83975406Sache        ee4k = AH_PRIVATE(ah)->ah_eeprom;
84075406Sache	pEepData4k = &ee4k->ee_base;
84175406Sache	pModal4k = &pEepData4k->modalHeader;
84275406Sache	ee = NULL;
84375406Sache	pEepData = NULL;
84475406Sache	pModal = NULL;
84575406Sache    } else {
84675406Sache	ee = AH_PRIVATE(ah)->ah_eeprom;
84775406Sache	pEepData = &ee->ee_base;
84875406Sache	pModal = &pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)];
84975406Sache	ee4k = NULL;
85075406Sache	pEepData4k = NULL;
85175406Sache	pModal4k = NULL;
85275406Sache    }
85375406Sache    HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n",
85475406Sache	__func__,chan->ic_freq, cfgCtl );
85575406Sache
85675406Sache    if (IS_EEP_MINOR_V2(ah)) {
85775406Sache	if (pModal)
85875406Sache	    ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
85975406Sache	else
86075406Sache	    ht40PowerIncForPdadc = pModal4k->ht40PowerIncForPdadc;
86175406Sache    }
86275406Sache
86375406Sache    if (!ar5416SetPowerPerRateTable(ah, pEepData, pEepData4k, chan,
86475406Sache                                    &ratesArray[0],cfgCtl,
86575406Sache                                    twiceAntennaReduction,
86675406Sache				    twiceMaxRegulatoryPower, powerLimit)) {
86775406Sache        HALDEBUG(ah, HAL_DEBUG_ANY,
86875406Sache	    "%s: unable to set tx power per rate table\n", __func__);
86975406Sache        return AH_FALSE;
87075406Sache    }
87175406Sache
87275406Sache    if (!ar5416SetPowerCalTable(ah, pEepData, pEepData4k, chan,
87375406Sache	&txPowerIndexOffset)) {
87475406Sache        HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n",
87521308Sache	    __func__);
87621308Sache        return AH_FALSE;
87721308Sache    }
878
879    maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]);
880
881    if (IEEE80211_IS_CHAN_2GHZ(chan)) {
882        maxPower = AH_MAX(maxPower, ratesArray[rate1l]);
883    }
884
885    if (IEEE80211_IS_CHAN_HT40(chan)) {
886        maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]);
887    }
888
889    ahp->ah_tx6PowerInHalfDbm = maxPower;
890    AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower;
891    ahp->ah_txPowerIndexOffset = txPowerIndexOffset;
892
893    /*
894     * txPowerIndexOffset is set by the SetPowerTable() call -
895     *  adjust the rate table (0 offset if rates EEPROM not loaded)
896     */
897    for (i = 0; i < N(ratesArray); i++) {
898        ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
899        if (ratesArray[i] > AR5416_MAX_RATE_POWER)
900            ratesArray[i] = AR5416_MAX_RATE_POWER;
901    }
902
903#ifdef AH_EEPROM_DUMP
904    ar5416PrintPowerPerRate(ah, ratesArray);
905#endif
906
907    /* Write the OFDM power per rate set */
908    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
909        POW_SM(ratesArray[rate18mb], 24)
910          | POW_SM(ratesArray[rate12mb], 16)
911          | POW_SM(ratesArray[rate9mb], 8)
912          | POW_SM(ratesArray[rate6mb], 0)
913    );
914    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
915        POW_SM(ratesArray[rate54mb], 24)
916          | POW_SM(ratesArray[rate48mb], 16)
917          | POW_SM(ratesArray[rate36mb], 8)
918          | POW_SM(ratesArray[rate24mb], 0)
919    );
920
921    if (IEEE80211_IS_CHAN_2GHZ(chan)) {
922        /* Write the CCK power per rate set */
923        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
924            POW_SM(ratesArray[rate2s], 24)
925              | POW_SM(ratesArray[rate2l],  16)
926              | POW_SM(ratesArray[rateXr],  8) /* XR target power */
927              | POW_SM(ratesArray[rate1l],   0)
928        );
929        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
930            POW_SM(ratesArray[rate11s], 24)
931              | POW_SM(ratesArray[rate11l], 16)
932              | POW_SM(ratesArray[rate5_5s], 8)
933              | POW_SM(ratesArray[rate5_5l], 0)
934        );
935    HALDEBUG(ah, HAL_DEBUG_RESET,
936	"%s AR_PHY_POWER_TX_RATE3=0x%x AR_PHY_POWER_TX_RATE4=0x%x\n",
937	    __func__, OS_REG_READ(ah,AR_PHY_POWER_TX_RATE3),
938	    OS_REG_READ(ah,AR_PHY_POWER_TX_RATE4));
939    }
940
941    /* Write the HT20 power per rate set */
942    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
943        POW_SM(ratesArray[rateHt20_3], 24)
944          | POW_SM(ratesArray[rateHt20_2], 16)
945          | POW_SM(ratesArray[rateHt20_1], 8)
946          | POW_SM(ratesArray[rateHt20_0], 0)
947    );
948    OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
949        POW_SM(ratesArray[rateHt20_7], 24)
950          | POW_SM(ratesArray[rateHt20_6], 16)
951          | POW_SM(ratesArray[rateHt20_5], 8)
952          | POW_SM(ratesArray[rateHt20_4], 0)
953    );
954
955    if (IEEE80211_IS_CHAN_HT40(chan)) {
956        /* Write the HT40 power per rate set */
957	/* Correct PAR difference between HT40 and HT20/LEGACY */
958        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
959            POW_SM(ratesArray[rateHt40_3] + ht40PowerIncForPdadc, 24)
960              | POW_SM(ratesArray[rateHt40_2] + ht40PowerIncForPdadc, 16)
961              | POW_SM(ratesArray[rateHt40_1] + ht40PowerIncForPdadc, 8)
962              | POW_SM(ratesArray[rateHt40_0] + ht40PowerIncForPdadc, 0)
963        );
964        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
965            POW_SM(ratesArray[rateHt40_7] + ht40PowerIncForPdadc, 24)
966              | POW_SM(ratesArray[rateHt40_6] + ht40PowerIncForPdadc, 16)
967              | POW_SM(ratesArray[rateHt40_5] + ht40PowerIncForPdadc, 8)
968              | POW_SM(ratesArray[rateHt40_4] + ht40PowerIncForPdadc, 0)
969        );
970        /* Write the Dup/Ext 40 power per rate set */
971        OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
972            POW_SM(ratesArray[rateExtOfdm], 24)
973              | POW_SM(ratesArray[rateExtCck], 16)
974              | POW_SM(ratesArray[rateDupOfdm], 8)
975              | POW_SM(ratesArray[rateDupCck], 0)
976        );
977    }
978
979    /* Write the Power subtraction for dynamic chain changing, for per-packet powertx */
980    if (pModal)
981	    OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
982		POW_SM(pModal->pwrDecreaseFor3Chain, 6)
983		  | POW_SM(pModal->pwrDecreaseFor2Chain, 0)
984	    );
985    return AH_TRUE;
986#undef POW_SM
987#undef N
988}
989
990/*
991 * Exported call to check for a recent gain reading and return
992 * the current state of the thermal calibration gain engine.
993 */
994HAL_RFGAIN
995ar5416GetRfgain(struct ath_hal *ah)
996{
997	return HAL_RFGAIN_INACTIVE;
998}
999
1000/*
1001 * Places all of hardware into reset
1002 */
1003HAL_BOOL
1004ar5416Disable(struct ath_hal *ah)
1005{
1006	if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
1007		return AH_FALSE;
1008	return ar5416SetResetReg(ah, HAL_RESET_COLD);
1009}
1010
1011/*
1012 * Places the PHY and Radio chips into reset.  A full reset
1013 * must be called to leave this state.  The PCI/MAC/PCU are
1014 * not placed into reset as we must receive interrupt to
1015 * re-enable the hardware.
1016 */
1017HAL_BOOL
1018ar5416PhyDisable(struct ath_hal *ah)
1019{
1020	return ar5416SetResetReg(ah, HAL_RESET_WARM);
1021}
1022
1023/*
1024 * Write the given reset bit mask into the reset register
1025 */
1026HAL_BOOL
1027ar5416SetResetReg(struct ath_hal *ah, uint32_t type)
1028{
1029	switch (type) {
1030	case HAL_RESET_POWER_ON:
1031		return ar5416SetResetPowerOn(ah);
1032	case HAL_RESET_WARM:
1033	case HAL_RESET_COLD:
1034		return ar5416SetReset(ah, type);
1035	default:
1036		HALASSERT(AH_FALSE);
1037		return AH_FALSE;
1038	}
1039}
1040
1041static HAL_BOOL
1042ar5416SetResetPowerOn(struct ath_hal *ah)
1043{
1044    /* Power On Reset (Hard Reset) */
1045
1046    /*
1047     * Set force wake
1048     *
1049     * If the MAC was running, previously calling
1050     * reset will wake up the MAC but it may go back to sleep
1051     * before we can start polling.
1052     * Set force wake  stops that
1053     * This must be called before initiating a hard reset.
1054     */
1055    OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1056            AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1057
1058    /*
1059     * RTC reset and clear
1060     */
1061    OS_REG_WRITE(ah, AR_RTC_RESET, 0);
1062    OS_DELAY(20);
1063    OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1064
1065    /*
1066     * Poll till RTC is ON
1067     */
1068    if (!ath_hal_wait(ah, AR_RTC_STATUS, AR_RTC_PM_STATUS_M, AR_RTC_STATUS_ON)) {
1069        HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC not waking up\n", __func__);
1070        return AH_FALSE;
1071    }
1072
1073    return ar5416SetReset(ah, HAL_RESET_COLD);
1074}
1075
1076static HAL_BOOL
1077ar5416SetReset(struct ath_hal *ah, int type)
1078{
1079    uint32_t tmpReg, mask;
1080
1081    /*
1082     * Force wake
1083     */
1084    OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1085	AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1086
1087    /*
1088     * Reset AHB
1089     */
1090    tmpReg = OS_REG_READ(ah, AR_INTR_SYNC_CAUSE);
1091    if (tmpReg & (AR_INTR_SYNC_LOCAL_TIMEOUT|AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1092	OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
1093	OS_REG_WRITE(ah, AR_RC, AR_RC_AHB|AR_RC_HOSTIF);
1094    } else {
1095	OS_REG_WRITE(ah, AR_RC, AR_RC_AHB);
1096    }
1097
1098    /*
1099     * Set Mac(BB,Phy) Warm Reset
1100     */
1101    switch (type) {
1102    case HAL_RESET_WARM:
1103            OS_REG_WRITE(ah, AR_RTC_RC, AR_RTC_RC_MAC_WARM);
1104            break;
1105    case HAL_RESET_COLD:
1106            OS_REG_WRITE(ah, AR_RTC_RC, AR_RTC_RC_MAC_WARM|AR_RTC_RC_MAC_COLD);
1107            break;
1108    default:
1109            HALASSERT(AH_FALSE);
1110            break;
1111    }
1112
1113    /*
1114     * Clear resets and force wakeup
1115     */
1116    OS_REG_WRITE(ah, AR_RTC_RC, 0);
1117    if (!ath_hal_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) {
1118        HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC stuck in MAC reset\n", __func__);
1119        return AH_FALSE;
1120    }
1121
1122    /* Clear AHB reset */
1123    OS_REG_WRITE(ah, AR_RC, 0);
1124
1125	if (type == HAL_RESET_COLD) {
1126		if (isBigEndian()) {
1127			/*
1128			 * Set CFG, little-endian for register
1129			 * and descriptor accesses.
1130			 */
1131			mask = INIT_CONFIG_STATUS | AR_CFG_SWRD | AR_CFG_SWRG;
1132#ifndef AH_NEED_DESC_SWAP
1133			mask |= AR_CFG_SWTD;
1134#endif
1135			HALDEBUG(ah, HAL_DEBUG_RESET,
1136			    "%s Applying descriptor swap\n", __func__);
1137			OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask));
1138		} else
1139			OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS);
1140	}
1141
1142    ar5416InitPLL(ah, AH_NULL);
1143
1144    return AH_TRUE;
1145}
1146
1147#ifndef IS_5GHZ_FAST_CLOCK_EN
1148#define	IS_5GHZ_FAST_CLOCK_EN(ah, chan)	AH_FALSE
1149#endif
1150
1151static void
1152ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan)
1153{
1154	uint32_t pll;
1155
1156	if (AR_SREV_MERLIN_20(ah) &&
1157	    chan != AH_NULL && IEEE80211_IS_CHAN_5GHZ(chan)) {
1158		/*
1159		 * PLL WAR for Merlin 2.0/2.1
1160		 * When doing fast clock, set PLL to 0x142c
1161		 * Else, set PLL to 0x2850 to prevent reset-to-reset variation
1162		 */
1163		pll = IS_5GHZ_FAST_CLOCK_EN(ah, chan) ? 0x142c : 0x2850;
1164	} else if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
1165		pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV);
1166		if (chan != AH_NULL) {
1167			if (IEEE80211_IS_CHAN_HALF(chan))
1168				pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL);
1169			else if (IEEE80211_IS_CHAN_QUARTER(chan))
1170				pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL);
1171			else if (IEEE80211_IS_CHAN_5GHZ(chan))
1172				pll |= SM(0x28, AR_RTC_SOWL_PLL_DIV);
1173			else
1174				pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV);
1175		} else
1176			pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV);
1177	} else if (AR_SREV_SOWL_10_OR_LATER(ah)) {
1178		pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV);
1179		if (chan != AH_NULL) {
1180			if (IEEE80211_IS_CHAN_HALF(chan))
1181				pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL);
1182			else if (IEEE80211_IS_CHAN_QUARTER(chan))
1183				pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL);
1184			else if (IEEE80211_IS_CHAN_5GHZ(chan))
1185				pll |= SM(0x50, AR_RTC_SOWL_PLL_DIV);
1186			else
1187				pll |= SM(0x58, AR_RTC_SOWL_PLL_DIV);
1188		} else
1189			pll |= SM(0x58, AR_RTC_SOWL_PLL_DIV);
1190	} else {
1191		pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
1192		if (chan != AH_NULL) {
1193			if (IEEE80211_IS_CHAN_HALF(chan))
1194				pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1195			else if (IEEE80211_IS_CHAN_QUARTER(chan))
1196				pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1197			else if (IEEE80211_IS_CHAN_5GHZ(chan))
1198				pll |= SM(0xa, AR_RTC_PLL_DIV);
1199			else
1200				pll |= SM(0xb, AR_RTC_PLL_DIV);
1201		} else
1202			pll |= SM(0xb, AR_RTC_PLL_DIV);
1203	}
1204	OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
1205
1206	/* TODO:
1207	* For multi-band owl, switch between bands by reiniting the PLL.
1208	*/
1209
1210	OS_DELAY(RTC_PLL_SETTLE_DELAY);
1211
1212	OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_SLEEP_DERIVED_CLK);
1213}
1214
1215/*
1216 * Read EEPROM header info and program the device for correct operation
1217 * given the channel value.
1218 */
1219static HAL_BOOL
1220ar5416SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan)
1221{
1222    const HAL_EEPROM_v14 *ee;
1223    const HAL_EEPROM_v4k *ee4k;
1224    const struct ar5416eeprom *eep;
1225    const struct ar5416eeprom_4k *eep4k;
1226    const MODAL_EEP_HEADER *pModal;
1227    const MODAL_EEP4K_HEADER *pModal4k;
1228    int			i, regChainOffset;
1229    uint8_t		txRxAttenLocal;    /* workaround for eeprom versions <= 14.2 */
1230
1231    HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1);
1232
1233    if (AR_SREV_KITE(ah)) {
1234	    ee4k = AH_PRIVATE(ah)->ah_eeprom;
1235	    eep4k = &ee4k->ee_base;
1236	    pModal4k = &eep4k->modalHeader;
1237	    ee = NULL;
1238	    eep = NULL;
1239	    pModal = NULL;
1240    } else {
1241	    ee = AH_PRIVATE(ah)->ah_eeprom;
1242	    eep = &ee->ee_base;
1243	    pModal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)];
1244	    ee4k = NULL;
1245	    eep4k = NULL;
1246	    pModal4k = NULL;
1247    }
1248
1249    /* NB: workaround for eeprom versions <= 14.2 */
1250    txRxAttenLocal = IEEE80211_IS_CHAN_2GHZ(chan) ? 23 : 44;
1251
1252    OS_REG_WRITE(ah, AR_PHY_SWITCH_COM,
1253	(pModal) ? pModal->antCtrlCommon :
1254	pModal4k->antCtrlCommon);
1255    for (i = 0; i < AR5416_MAX_CHAINS; i++) {
1256	   if (AR_SREV_KITE(ah) && i >= 1) break;
1257	   if (AR_SREV_MERLIN(ah) && i >= 2) break;
1258       	   if (AR_SREV_OWL_20_OR_LATER(ah) &&
1259            (AH5416(ah)->ah_rx_chainmask == 0x5 ||
1260	     AH5416(ah)->ah_tx_chainmask == 0x5) && i != 0) {
1261            /* Regs are swapped from chain 2 to 1 for 5416 2_0 with
1262             * only chains 0 and 2 populated
1263             */
1264            regChainOffset = (i == 1) ? 0x2000 : 0x1000;
1265        } else {
1266            regChainOffset = i * 0x1000;
1267        }
1268
1269        OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
1270	    (pModal) ? pModal->antCtrlChain[i] : pModal4k->antCtrlChain[i]);
1271        OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4 + regChainOffset,
1272        	(OS_REG_READ(ah, AR_PHY_TIMING_CTRL4 + regChainOffset) &
1273        	~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
1274        	SM((pModal) ? pModal->iqCalICh[i] : pModal4k->iqCalICh[i],
1275		    AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
1276        	SM((pModal) ? pModal->iqCalQCh[i] : pModal4k->iqCalQCh[i],
1277		    AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
1278
1279        /*
1280         * Large signal upgrade.
1281	 * XXX update
1282         */
1283
1284        if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) {
1285	    int txRxAtten;
1286	    if (IS_EEP_MINOR_V3(ah)) {
1287		if (pModal) txRxAtten = pModal->txRxAttenCh[i];
1288		else txRxAtten = pModal4k->txRxAttenCh[i];
1289	    } else
1290		txRxAtten = txRxAttenLocal;
1291
1292            OS_REG_WRITE(ah, AR_PHY_RXGAIN + regChainOffset,
1293		(OS_REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) & ~AR_PHY_RXGAIN_TXRX_ATTEN) |
1294			SM(txRxAtten, AR_PHY_RXGAIN_TXRX_ATTEN));
1295
1296            OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1297	    	(OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
1298			SM((pModal) ? pModal->rxTxMarginCh[i]:
1299			      pModal4k->rxTxMarginCh[i],
1300			    AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
1301        }
1302    }
1303
1304    OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
1305	(pModal) ? pModal->switchSettling : pModal4k->switchSettling);
1306    OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
1307	(pModal) ? pModal->adcDesiredSize : pModal4k->adcDesiredSize);
1308    OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_PGA,
1309	(pModal) ? pModal->pgaDesiredSize : pModal4k->pgaDesiredSize);
1310    OS_REG_WRITE(ah, AR_PHY_RF_CTL4,
1311                 SM((pModal) ? pModal->txEndToXpaOff : pModal4k->txEndToXpaOff,
1312	             AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
1313               | SM((pModal) ? pModal->txEndToXpaOff : pModal4k->txEndToXpaOff,
1314	             AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
1315               | SM((pModal) ? pModal->txFrameToXpaOn : pModal4k->txFrameToXpaOn,
1316	             AR_PHY_RF_CTL4_FRAME_XPAA_ON)
1317               | SM((pModal) ? pModal->txFrameToXpaOn : pModal4k->txFrameToXpaOn,
1318	             AR_PHY_RF_CTL4_FRAME_XPAB_ON));
1319
1320    OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
1321	            (pModal) ? pModal->txEndToRxOn : pModal4k->txEndToRxOn);
1322
1323    if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
1324	OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
1325	    (pModal) ? pModal->thresh62 : pModal4k->thresh62);
1326	OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
1327	    (pModal) ? pModal->thresh62 : pModal4k->thresh62);
1328    } else {
1329	OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
1330	    (pModal) ? pModal->thresh62 : pModal4k->thresh62);
1331	OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA_THRESH62,
1332	    (pModal) ? pModal->thresh62 : pModal4k->thresh62);
1333    }
1334
1335    /* Minor Version Specific application */
1336    if (IS_EEP_MINOR_V2(ah)) {
1337        OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,  AR_PHY_TX_FRAME_TO_DATA_START,
1338	                 (pModal) ? pModal->txFrameToDataStart : pModal4k->txFrameToDataStart);
1339        OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,  AR_PHY_TX_FRAME_TO_PA_ON,
1340	                 (pModal) ? pModal->txFrameToPaOn : pModal4k->txFrameToPaOn);
1341    }
1342
1343    if (IS_EEP_MINOR_V3(ah)) {
1344	if (IEEE80211_IS_CHAN_HT40(chan)) {
1345		/* Overwrite switch settling with HT40 value */
1346		OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
1347		                 (pModal) ? pModal->swSettleHt40 : pModal4k->swSettleHt40);
1348	}
1349
1350        if ((AR_SREV_OWL_20_OR_LATER(ah)) &&
1351            (  AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5)){
1352            /* NB: no v4k EEPROM */
1353            /* Reg Offsets are swapped for logical mapping */
1354		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) |
1355			SM(pModal->bswMargin[2], AR_PHY_GAIN_2GHZ_BSW_MARGIN));
1356		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) |
1357			SM(pModal->bswAtten[2], AR_PHY_GAIN_2GHZ_BSW_ATTEN));
1358		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) |
1359			SM(pModal->bswMargin[1], AR_PHY_GAIN_2GHZ_BSW_MARGIN));
1360		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) |
1361			SM(pModal->bswAtten[1], AR_PHY_GAIN_2GHZ_BSW_ATTEN));
1362        } else {
1363		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) |
1364			SM((pModal) ? pModal->bswMargin[1] :
1365			  pModal4k->bswMargin[1], AR_PHY_GAIN_2GHZ_BSW_MARGIN));
1366		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) |
1367			SM((pModal) ? pModal->bswAtten[1] :
1368			  pModal4k->bswAtten[1], AR_PHY_GAIN_2GHZ_BSW_ATTEN));
1369		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) |
1370			SM((pModal) ? pModal->bswMargin[2] :
1371			    pModal4k->bswMargin[2], AR_PHY_GAIN_2GHZ_BSW_MARGIN));
1372		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) |
1373			SM((pModal) ? pModal->bswAtten[2] :
1374			  pModal4k->bswAtten[2], AR_PHY_GAIN_2GHZ_BSW_ATTEN));
1375        }
1376        OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_BSW_MARGIN,
1377	    (pModal) ? pModal->bswMargin[0] : pModal4k->bswMargin[0]);
1378        OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_BSW_ATTEN,
1379	    (pModal) ? pModal->bswAtten[0] : pModal4k->bswAtten[0]);
1380    }
1381    return AH_TRUE;
1382}
1383
1384/*
1385 * Helper functions common for AP/CB/XB
1386 */
1387
1388/*
1389 * ar5416SetPowerPerRateTable
1390 *
1391 * Sets the transmit power in the baseband for the given
1392 * operating channel and mode.
1393 */
1394HAL_BOOL
1395ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
1396    			   struct ar5416eeprom_4k *pEepData4k,
1397                           const struct ieee80211_channel *chan,
1398                           int16_t *ratesArray, uint16_t cfgCtl,
1399                           uint16_t AntennaReduction,
1400                           uint16_t twiceMaxRegulatoryPower,
1401                           uint16_t powerLimit)
1402{
1403#define	N(a)	(sizeof(a)/sizeof(a[0]))
1404/* Local defines to distinguish between extension and control CTL's */
1405#define EXT_ADDITIVE (0x8000)
1406#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
1407#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
1408#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
1409
1410	uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1411	int i;
1412	int16_t  twiceLargestAntenna;
1413	CAL_CTL_DATA *rep;
1414	CAL_CTL_DATA_4K *rep4k;
1415	CAL_TARGET_POWER_LEG targetPowerOfdm, targetPowerCck = {0, {0, 0, 0, 0}};
1416	CAL_TARGET_POWER_LEG targetPowerOfdmExt = {0, {0, 0, 0, 0}}, targetPowerCckExt = {0, {0, 0, 0, 0}};
1417	CAL_TARGET_POWER_HT  targetPowerHt20, targetPowerHt40 = {0, {0, 0, 0, 0}};
1418	int16_t scaledPower, minCtlPower;
1419
1420#define SUB_NUM_CTL_MODES_AT_5G_40 2   /* excluding HT40, EXT-OFDM */
1421#define SUB_NUM_CTL_MODES_AT_2G_40 3   /* excluding HT40, EXT-OFDM, EXT-CCK */
1422	static const uint16_t ctlModesFor11a[] = {
1423	   CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
1424	};
1425	static const uint16_t ctlModesFor11g[] = {
1426	   CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
1427	};
1428	const uint16_t *pCtlMode;
1429	uint16_t numCtlModes, ctlMode, freq;
1430	CHAN_CENTERS centers;
1431	int n2gcck, n2g20, n2g40, numctls;
1432
1433	ar5416GetChannelCenters(ah,  chan, &centers);
1434
1435	/* Compute TxPower reduction due to Antenna Gain */
1436
1437	if (pEepData)
1438		twiceLargestAntenna = AH_MAX(AH_MAX(
1439		    pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[0],
1440		    pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[1]),
1441		    pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
1442	else
1443		twiceLargestAntenna = AH_MAX(AH_MAX(
1444		    pEepData4k->modalHeader.antennaGainCh[0],
1445		    pEepData4k->modalHeader.antennaGainCh[1]),
1446		    pEepData4k->modalHeader.antennaGainCh[2]);
1447#if 0
1448	/* Turn it back on if we need to calculate per chain antenna gain reduction */
1449	/* Use only if the expected gain > 6dbi */
1450	/* Chain 0 is always used */
1451	twiceLargestAntenna = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[0];
1452
1453	/* Look at antenna gains of Chains 1 and 2 if the TX mask is set */
1454	if (ahp->ah_tx_chainmask & 0x2)
1455		twiceLargestAntenna = AH_MAX(twiceLargestAntenna,
1456			pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
1457
1458	if (ahp->ah_tx_chainmask & 0x4)
1459		twiceLargestAntenna = AH_MAX(twiceLargestAntenna,
1460			pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
1461#endif
1462	twiceLargestAntenna = (int16_t)AH_MIN((AntennaReduction) - twiceLargestAntenna, 0);
1463
1464	/* XXX setup for 5212 use (really used?) */
1465	ath_hal_eepromSet(ah,
1466	    IEEE80211_IS_CHAN_2GHZ(chan) ? AR_EEP_ANTGAINMAX_2 : AR_EEP_ANTGAINMAX_5,
1467	    twiceLargestAntenna);
1468
1469	/*
1470	 * scaledPower is the minimum of the user input power level and
1471	 * the regulatory allowed power level
1472	 */
1473	scaledPower = AH_MIN(powerLimit, twiceMaxRegulatoryPower + twiceLargestAntenna);
1474
1475	/* Reduce scaled Power by number of chains active to get to per chain tx power level */
1476	/* TODO: better value than these? */
1477	switch (owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask)) {
1478	case 1:
1479		break;
1480	case 2:
1481		if (pEepData)
1482			scaledPower -= pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain;
1483		break;
1484	case 3:
1485		if (pEepData)
1486			scaledPower -= pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain;
1487		break;
1488	default:
1489		return AH_FALSE; /* Unsupported number of chains */
1490	}
1491
1492	scaledPower = AH_MAX(0, scaledPower);
1493
1494	n2gcck = (pEepData) ? AR5416_NUM_2G_CCK_TARGET_POWERS :
1495	    AR5416_4K_NUM_2G_CCK_TARGET_POWERS;
1496	n2g20 = (pEepData) ? AR5416_NUM_2G_20_TARGET_POWERS :
1497	    AR5416_4K_NUM_2G_20_TARGET_POWERS;
1498	n2g40 = (pEepData) ? AR5416_NUM_2G_40_TARGET_POWERS :
1499	    AR5416_4K_NUM_2G_40_TARGET_POWERS;
1500
1501	/* Get target powers from EEPROM - our baseline for TX Power */
1502	if (IEEE80211_IS_CHAN_2GHZ(chan)) {
1503		/* Setup for CTL modes */
1504		numCtlModes = N(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; /* CTL_11B, CTL_11G, CTL_2GHT20 */
1505		pCtlMode = ctlModesFor11g;
1506
1507		ar5416GetTargetPowersLeg(ah,  chan,
1508		    (pEepData) ? pEepData->calTargetPowerCck :
1509		        pEepData4k->calTargetPowerCck,
1510		    n2gcck, &targetPowerCck, 4, AH_FALSE);
1511		ar5416GetTargetPowersLeg(ah,  chan,
1512		    (pEepData) ? pEepData->calTargetPower2G :
1513		        pEepData4k->calTargetPower2G,
1514		    n2g20, &targetPowerOfdm, 4, AH_FALSE);
1515		ar5416GetTargetPowers(ah,  chan,
1516		    (pEepData) ? pEepData->calTargetPower2GHT20 :
1517		        pEepData4k->calTargetPower2GHT20,
1518		    n2g20, &targetPowerHt20, 8, AH_FALSE);
1519
1520		if (IEEE80211_IS_CHAN_HT40(chan)) {
1521			numCtlModes = N(ctlModesFor11g);    /* All 2G CTL's */
1522
1523			ar5416GetTargetPowers(ah, chan,
1524			    (pEepData) ? pEepData->calTargetPower2GHT40 :
1525			        pEepData4k->calTargetPower2GHT40,
1526			    n2g40, &targetPowerHt40, 8, AH_TRUE);
1527			/* Get target powers for extension channels */
1528			ar5416GetTargetPowersLeg(ah, chan,
1529			    (pEepData) ? pEepData->calTargetPowerCck :
1530			        pEepData4k->calTargetPowerCck,
1531			    n2gcck, &targetPowerCckExt, 4, AH_TRUE);
1532			ar5416GetTargetPowersLeg(ah, chan,
1533			    (pEepData) ? pEepData->calTargetPower2G :
1534			        pEepData4k->calTargetPower2G,
1535			    n2g20, &targetPowerOfdmExt, 4, AH_TRUE);
1536		}
1537	} else {
1538		/* Setup for CTL modes */
1539		numCtlModes = N(ctlModesFor11a) - SUB_NUM_CTL_MODES_AT_5G_40; /* CTL_11A, CTL_5GHT20 */
1540		pCtlMode = ctlModesFor11a;
1541
1542		/* NB: v4k EEPROM has no 5Ghz info */
1543		ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower5G,
1544				AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE);
1545		ar5416GetTargetPowers(ah,  chan, pEepData->calTargetPower5GHT20,
1546				AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE);
1547
1548		if (IEEE80211_IS_CHAN_HT40(chan)) {
1549			numCtlModes = N(ctlModesFor11a); /* All 5G CTL's */
1550
1551			ar5416GetTargetPowers(ah,  chan, pEepData->calTargetPower5GHT40,
1552				AR5416_NUM_5G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE);
1553			ar5416GetTargetPowersLeg(ah,  chan, pEepData->calTargetPower5G,
1554				AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE);
1555		}
1556	}
1557
1558	/*
1559	 * For MIMO, need to apply regulatory caps individually across dynamically
1560	 * running modes: CCK, OFDM, HT20, HT40
1561	 *
1562	 * The outer loop walks through each possible applicable runtime mode.
1563	 * The inner loop walks through each ctlIndex entry in EEPROM.
1564	 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
1565	 *
1566	 */
1567	numctls = (pEepData) ? AR5416_NUM_CTLS : AR5416_4K_NUM_CTLS;
1568	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
1569		int ctlIndex;
1570		HAL_BOOL isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
1571		    (pCtlMode[ctlMode] == CTL_2GHT40);
1572		if (isHt40CtlMode) {
1573			freq = centers.ctl_center;
1574		} else if (pCtlMode[ctlMode] & EXT_ADDITIVE) {
1575			freq = centers.ext_center;
1576		} else {
1577			freq = centers.ctl_center;
1578		}
1579
1580		ctlIndex = (pEepData) ? pEepData->ctlIndex[0] :
1581		    pEepData4k->ctlIndex[0];
1582		/* walk through each CTL index stored in EEPROM */
1583		for (i = 0; (i < numctls) && ctlIndex; i++) {
1584			uint16_t twiceMinEdgePower;
1585			CAL_CTL_EDGES *ctlEdge;
1586
1587			ctlIndex = (pEepData) ? pEepData->ctlIndex[i] :
1588			    pEepData4k->ctlIndex[i];
1589
1590			/* compare test group from regulatory channel list with test mode from pCtlMode list */
1591			if ((((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == ctlIndex) ||
1592				(((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1593				 ((ctlIndex & CTL_MODE_M) | SD_NO_CTL))) {
1594				if (pEepData) {
1595					rep = &(pEepData->ctlData[i]);
1596					ctlEdge = rep->ctlEdges[
1597					    owl_get_ntxchains(
1598						AH5416(ah)->ah_tx_chainmask) - 1];
1599				} else {
1600					rep4k = &(pEepData4k->ctlData[i]);
1601					ctlEdge = rep4k->ctlEdges[
1602					    owl_get_ntxchains(
1603						AH5416(ah)->ah_tx_chainmask) - 1];
1604				}
1605				twiceMinEdgePower = ar5416GetMaxEdgePower(ah,
1606				    freq, ctlEdge,
1607				    IEEE80211_IS_CHAN_2GHZ(chan));
1608				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
1609					/* Find the minimum of all CTL edge powers that apply to this channel */
1610					twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower);
1611				} else {
1612					/* specific */
1613					twiceMaxEdgePower = twiceMinEdgePower;
1614					break;
1615				}
1616			}
1617		}
1618		minCtlPower = (uint8_t)AH_MIN(twiceMaxEdgePower, scaledPower);
1619		/* Apply ctl mode to correct target power set */
1620		switch(pCtlMode[ctlMode]) {
1621		case CTL_11B:
1622			for (i = 0; i < N(targetPowerCck.tPow2x); i++) {
1623				targetPowerCck.tPow2x[i] = (uint8_t)AH_MIN(targetPowerCck.tPow2x[i], minCtlPower);
1624			}
1625			break;
1626		case CTL_11A:
1627		case CTL_11G:
1628			for (i = 0; i < N(targetPowerOfdm.tPow2x); i++) {
1629				targetPowerOfdm.tPow2x[i] = (uint8_t)AH_MIN(targetPowerOfdm.tPow2x[i], minCtlPower);
1630			}
1631			break;
1632		case CTL_5GHT20:
1633		case CTL_2GHT20:
1634			for (i = 0; i < N(targetPowerHt20.tPow2x); i++) {
1635				targetPowerHt20.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt20.tPow2x[i], minCtlPower);
1636			}
1637			break;
1638		case CTL_11B_EXT:
1639			targetPowerCckExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerCckExt.tPow2x[0], minCtlPower);
1640			break;
1641		case CTL_11A_EXT:
1642		case CTL_11G_EXT:
1643			targetPowerOfdmExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerOfdmExt.tPow2x[0], minCtlPower);
1644			break;
1645		case CTL_5GHT40:
1646		case CTL_2GHT40:
1647			for (i = 0; i < N(targetPowerHt40.tPow2x); i++) {
1648				targetPowerHt40.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt40.tPow2x[i], minCtlPower);
1649			}
1650			break;
1651		default:
1652			return AH_FALSE;
1653			break;
1654		}
1655	} /* end ctl mode checking */
1656
1657	/* Set rates Array from collected data */
1658	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = ratesArray[rate18mb] = ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0];
1659	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
1660	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
1661	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
1662	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
1663
1664	for (i = 0; i < N(targetPowerHt20.tPow2x); i++) {
1665		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
1666	}
1667
1668	if (IEEE80211_IS_CHAN_2GHZ(chan)) {
1669		ratesArray[rate1l]  = targetPowerCck.tPow2x[0];
1670		ratesArray[rate2s] = ratesArray[rate2l]  = targetPowerCck.tPow2x[1];
1671		ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
1672		ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
1673	}
1674	if (IEEE80211_IS_CHAN_HT40(chan)) {
1675		for (i = 0; i < N(targetPowerHt40.tPow2x); i++) {
1676			ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i];
1677		}
1678		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
1679		ratesArray[rateDupCck]  = targetPowerHt40.tPow2x[0];
1680		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
1681		if (IEEE80211_IS_CHAN_2GHZ(chan)) {
1682			ratesArray[rateExtCck]  = targetPowerCckExt.tPow2x[0];
1683		}
1684	}
1685	return AH_TRUE;
1686#undef EXT_ADDITIVE
1687#undef CTL_11A_EXT
1688#undef CTL_11G_EXT
1689#undef CTL_11B_EXT
1690#undef SUB_NUM_CTL_MODES_AT_5G_40
1691#undef SUB_NUM_CTL_MODES_AT_2G_40
1692#undef N
1693}
1694
1695/**************************************************************************
1696 * fbin2freq
1697 *
1698 * Get channel value from binary representation held in eeprom
1699 * RETURNS: the frequency in MHz
1700 */
1701static uint16_t
1702fbin2freq(uint8_t fbin, HAL_BOOL is2GHz)
1703{
1704    /*
1705     * Reserved value 0xFF provides an empty definition both as
1706     * an fbin and as a frequency - do not convert
1707     */
1708    if (fbin == AR5416_BCHAN_UNUSED) {
1709        return fbin;
1710    }
1711
1712    return (uint16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
1713}
1714
1715/*
1716 * ar5416GetMaxEdgePower
1717 *
1718 * Find the maximum conformance test limit for the given channel and CTL info
1719 */
1720static uint16_t
1721ar5416GetMaxEdgePower(struct ath_hal *ah,
1722    uint16_t freq, CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz)
1723{
1724    uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1725    int      i, numBand;
1726
1727    if (AR_SREV_KITE(ah))
1728	    numBand = AR5416_4K_NUM_BAND_EDGES;
1729    else
1730	    numBand = AR5416_NUM_BAND_EDGES;
1731
1732    /* Get the edge power */
1733    for (i = 0; (i < numBand) && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED) ; i++) {
1734        /*
1735         * If there's an exact channel match or an inband flag set
1736         * on the lower channel use the given rdEdgePower
1737         */
1738        if (freq == fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
1739            twiceMaxEdgePower = MS(pRdEdgesPower[i].tPowerFlag, CAL_CTL_EDGES_POWER);
1740            break;
1741        } else if ((i > 0) && (freq < fbin2freq(pRdEdgesPower[i].bChannel, is2GHz))) {
1742            if (fbin2freq(pRdEdgesPower[i - 1].bChannel, is2GHz) < freq && (pRdEdgesPower[i - 1].tPowerFlag & CAL_CTL_EDGES_FLAG) != 0) {
1743                twiceMaxEdgePower = MS(pRdEdgesPower[i - 1].tPowerFlag, CAL_CTL_EDGES_POWER);
1744            }
1745            /* Leave loop - no more affecting edges possible in this monotonic increasing list */
1746            break;
1747        }
1748    }
1749    HALASSERT(twiceMaxEdgePower > 0);
1750    return twiceMaxEdgePower;
1751}
1752
1753/**************************************************************
1754 * ar5416GetTargetPowers
1755 *
1756 * Return the rates of target power for the given target power table
1757 * channel, and number of channels
1758 */
1759static void
1760ar5416GetTargetPowers(struct ath_hal *ah,  const struct ieee80211_channel *chan,
1761                      CAL_TARGET_POWER_HT *powInfo, uint16_t numChannels,
1762                      CAL_TARGET_POWER_HT *pNewPower, uint16_t numRates,
1763                      HAL_BOOL isHt40Target)
1764{
1765    uint16_t clo, chi;
1766    int i;
1767    int matchIndex = -1, lowIndex = -1;
1768    uint16_t freq;
1769    CHAN_CENTERS centers;
1770
1771    ar5416GetChannelCenters(ah,  chan, &centers);
1772    freq = isHt40Target ? centers.synth_center : centers.ctl_center;
1773
1774    /* Copy the target powers into the temp channel list */
1775    if (freq <= fbin2freq(powInfo[0].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) {
1776        matchIndex = 0;
1777    } else {
1778        for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
1779            if (freq == fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) {
1780                matchIndex = i;
1781                break;
1782            } else if ((freq < fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) &&
1783                       (freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))))
1784            {
1785                lowIndex = i - 1;
1786                break;
1787            }
1788        }
1789        if ((matchIndex == -1) && (lowIndex == -1)) {
1790            HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)));
1791            matchIndex = i - 1;
1792        }
1793    }
1794
1795    if (matchIndex != -1) {
1796        OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower));
1797    } else {
1798        HALASSERT(lowIndex != -1);
1799        /*
1800         * Get the lower and upper channels, target powers,
1801         * and interpolate between them.
1802         */
1803        clo = fbin2freq(powInfo[lowIndex].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
1804        chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
1805
1806        for (i = 0; i < numRates; i++) {
1807            pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi,
1808                                   powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]);
1809        }
1810    }
1811}
1812/**************************************************************
1813 * ar5416GetTargetPowersLeg
1814 *
1815 * Return the four rates of target power for the given target power table
1816 * channel, and number of channels
1817 */
1818static void
1819ar5416GetTargetPowersLeg(struct ath_hal *ah,
1820                         const struct ieee80211_channel *chan,
1821                         CAL_TARGET_POWER_LEG *powInfo, uint16_t numChannels,
1822                         CAL_TARGET_POWER_LEG *pNewPower, uint16_t numRates,
1823			 HAL_BOOL isExtTarget)
1824{
1825    uint16_t clo, chi;
1826    int i;
1827    int matchIndex = -1, lowIndex = -1;
1828    uint16_t freq;
1829    CHAN_CENTERS centers;
1830
1831    ar5416GetChannelCenters(ah,  chan, &centers);
1832    freq = (isExtTarget) ? centers.ext_center :centers.ctl_center;
1833
1834    /* Copy the target powers into the temp channel list */
1835    if (freq <= fbin2freq(powInfo[0].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) {
1836        matchIndex = 0;
1837    } else {
1838        for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
1839            if (freq == fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) {
1840                matchIndex = i;
1841                break;
1842            } else if ((freq < fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) &&
1843                       (freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))))
1844            {
1845                lowIndex = i - 1;
1846                break;
1847            }
1848        }
1849        if ((matchIndex == -1) && (lowIndex == -1)) {
1850            HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)));
1851            matchIndex = i - 1;
1852        }
1853    }
1854
1855    if (matchIndex != -1) {
1856        OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower));
1857    } else {
1858        HALASSERT(lowIndex != -1);
1859        /*
1860         * Get the lower and upper channels, target powers,
1861         * and interpolate between them.
1862         */
1863        clo = fbin2freq(powInfo[lowIndex].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
1864        chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan));
1865
1866        for (i = 0; i < numRates; i++) {
1867            pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi,
1868                                   powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]);
1869        }
1870    }
1871}
1872
1873/**************************************************************
1874 * ar5416SetPowerCalTable
1875 *
1876 * Pull the PDADC piers from cal data and interpolate them across the given
1877 * points as well as from the nearest pier(s) to get a power detector
1878 * linear voltage to power level table.
1879 */
1880HAL_BOOL
1881ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
1882        struct ar5416eeprom_4k *pEepData4k,
1883	const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset)
1884{
1885    CAL_DATA_PER_FREQ *pRawDataset = NULL;
1886    CAL_DATA_PER_FREQ_4K *pRawDataset4k = NULL;
1887    uint8_t  *pCalBChans = AH_NULL;
1888    uint16_t pdGainOverlap_t2;
1889    static uint8_t  pdadcValues[AR5416_NUM_PDADC_VALUES];
1890    uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
1891    uint16_t numPiers, i, j;
1892    int16_t  tMinCalPower;
1893    uint16_t numXpdGain, xpdMask;
1894    uint16_t xpdGainValues[AR5416_NUM_PD_GAINS];
1895    uint32_t reg32, regOffset, regChainOffset;
1896
1897    OS_MEMZERO(xpdGainValues, sizeof(xpdGainValues));
1898
1899    if (pEepData)
1900	    xpdMask = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].xpdGain;
1901    else
1902	    xpdMask = pEepData4k->modalHeader.xpdGain;
1903
1904    if (IS_EEP_MINOR_V2(ah)) {
1905	if (pEepData)
1906		pdGainOverlap_t2 = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pdGainOverlap;
1907	else
1908		pdGainOverlap_t2 = pEepData4k->modalHeader.pdGainOverlap;
1909    } else {
1910    	pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
1911    }
1912
1913    if (IEEE80211_IS_CHAN_2GHZ(chan)) {
1914	if (pEepData) {
1915		pCalBChans = pEepData->calFreqPier2G;
1916		numPiers = AR5416_NUM_2G_CAL_PIERS;
1917	} else {
1918		pCalBChans = pEepData4k->calFreqPier2G;
1919		numPiers = AR5416_4K_NUM_2G_CAL_PIERS;
1920	}
1921    } else {
1922        pCalBChans = pEepData->calFreqPier5G;
1923        numPiers = AR5416_NUM_5G_CAL_PIERS;
1924    }
1925
1926    numXpdGain = 0;
1927    /* Calculate the value of xpdgains from the xpdGain Mask */
1928    for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
1929        if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
1930            if (numXpdGain >= AR5416_NUM_PD_GAINS) {
1931                HALASSERT(0);
1932                break;
1933            }
1934            xpdGainValues[numXpdGain] = (uint16_t)(AR5416_PD_GAINS_IN_MASK - i);
1935            numXpdGain++;
1936        }
1937    }
1938
1939    /* Write the detector gain biases and their number */
1940    OS_REG_WRITE(ah, AR_PHY_TPCRG1, (OS_REG_READ(ah, AR_PHY_TPCRG1) &
1941    	~(AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 | AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3)) |
1942	SM(numXpdGain - 1, AR_PHY_TPCRG1_NUM_PD_GAIN) | SM(xpdGainValues[0], AR_PHY_TPCRG1_PD_GAIN_1 ) |
1943	SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) | SM(xpdGainValues[2],  AR_PHY_TPCRG1_PD_GAIN_3));
1944
1945    for (i = 0; i < AR5416_MAX_CHAINS; i++) {
1946	    if (AR_SREV_KITE(ah) && i >= AR5416_4K_MAX_CHAINS) break;
1947            if (AR_SREV_OWL_20_OR_LATER(ah) &&
1948            ( AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) {
1949            /* Regs are swapped from chain 2 to 1 for 5416 2_0 with
1950             * only chains 0 and 2 populated
1951             */
1952            regChainOffset = (i == 1) ? 0x2000 : 0x1000;
1953        } else {
1954            regChainOffset = i * 0x1000;
1955        }
1956
1957	int txMask;
1958	txMask = (pEepData) ? pEepData->baseEepHeader.txMask :
1959	    pEepData4k->baseEepHeader.txMask;
1960
1961        if (txMask & (1 << i)) {
1962            if (IEEE80211_IS_CHAN_2GHZ(chan)) {
1963		if (pEepData)
1964		    pRawDataset = pEepData->calPierData2G[i];
1965		else
1966		    pRawDataset4k = pEepData4k->calPierData2G[i];
1967            } else {
1968                pRawDataset = pEepData->calPierData5G[i];
1969            }
1970
1971            ar5416GetGainBoundariesAndPdadcs(ah, chan, pRawDataset,
1972					     pRawDataset4k,
1973                                             pCalBChans, numPiers,
1974                                             pdGainOverlap_t2,
1975                                             &tMinCalPower, gainBoundaries,
1976                                             pdadcValues, numXpdGain);
1977
1978            if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) {
1979                /*
1980                 * Note the pdadc table may not start at 0 dBm power, could be
1981                 * negative or greater than 0.  Need to offset the power
1982                 * values by the amount of minPower for griffin
1983                 */
1984
1985                OS_REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
1986                     SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
1987                     SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)  |
1988                     SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)  |
1989                     SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)  |
1990                     SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
1991            }
1992
1993            /* Write the power values into the baseband power table */
1994            regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
1995
1996            for (j = 0; j < 32; j++) {
1997                reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0)  |
1998                    ((pdadcValues[4*j + 1] & 0xFF) << 8)  |
1999                    ((pdadcValues[4*j + 2] & 0xFF) << 16) |
2000                    ((pdadcValues[4*j + 3] & 0xFF) << 24) ;
2001                OS_REG_WRITE(ah, regOffset, reg32);
2002
2003#ifdef PDADC_DUMP
2004		ath_hal_printf(ah, "PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n",
2005			       i,
2006			       4*j, pdadcValues[4*j],
2007			       4*j+1, pdadcValues[4*j + 1],
2008			       4*j+2, pdadcValues[4*j + 2],
2009			       4*j+3, pdadcValues[4*j + 3]);
2010#endif
2011                regOffset += 4;
2012            }
2013        }
2014    }
2015    *pTxPowerIndexOffset = 0;
2016
2017    return AH_TRUE;
2018}
2019
2020/**************************************************************
2021 * ar5416GetGainBoundariesAndPdadcs
2022 *
2023 * Uses the data points read from EEPROM to reconstruct the pdadc power table
2024 * Called by ar5416SetPowerCalTable only.
2025 */
2026static void
2027ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
2028                                 const struct ieee80211_channel *chan,
2029				 CAL_DATA_PER_FREQ *pRawDataSet,
2030				 CAL_DATA_PER_FREQ_4K *pRawDataSet4k,
2031                                 uint8_t * bChans,  uint16_t availPiers,
2032                                 uint16_t tPdGainOverlap, int16_t *pMinCalPower,
2033				 uint16_t * pPdGainBoundaries,
2034                                 uint8_t * pPDADCValues, uint16_t numXpdGains)
2035{
2036
2037    int       i, j, k;
2038    int16_t   ss;         /* potentially -ve index for taking care of pdGainOverlap */
2039    uint16_t  idxL, idxR, numPiers; /* Pier indexes */
2040
2041    /* filled out Vpd table for all pdGains (chanL) */
2042    static uint8_t   vpdTableL[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB];
2043
2044    /* filled out Vpd table for all pdGains (chanR) */
2045    static uint8_t   vpdTableR[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB];
2046
2047    /* filled out Vpd table for all pdGains (interpolated) */
2048    static uint8_t   vpdTableI[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB];
2049
2050    uint8_t   *pVpdL, *pVpdR, *pPwrL, *pPwrR;
2051    uint8_t   minPwrT4[AR5416_NUM_PD_GAINS];
2052    uint8_t   maxPwrT4[AR5416_NUM_PD_GAINS];
2053    int16_t   vpdStep;
2054    int16_t   tmpVal;
2055    uint16_t  sizeCurrVpdTable, maxIndex, tgtIndex;
2056    HAL_BOOL    match;
2057    int16_t  minDelta = 0;
2058    CHAN_CENTERS centers;
2059
2060    ar5416GetChannelCenters(ah, chan, &centers);
2061
2062    /* Trim numPiers for the number of populated channel Piers */
2063    for (numPiers = 0; numPiers < availPiers; numPiers++) {
2064        if (bChans[numPiers] == AR5416_BCHAN_UNUSED) {
2065            break;
2066        }
2067    }
2068
2069    /* Find pier indexes around the current channel */
2070    match = getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)),
2071			bChans, numPiers, &idxL, &idxR);
2072
2073    if (match) {
2074        /* Directly fill both vpd tables from the matching index */
2075        for (i = 0; i < numXpdGains; i++) {
2076	    if (pRawDataSet) {
2077		    minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
2078		    maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
2079		    ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i],
2080				       pRawDataSet[idxL].pwrPdg[i],
2081				       pRawDataSet[idxL].vpdPdg[i],
2082				       AR5416_PD_GAIN_ICEPTS, vpdTableI[i]);
2083	    } else {
2084		    minPwrT4[i] = pRawDataSet4k[idxL].pwrPdg[i][0];
2085		    maxPwrT4[i] = pRawDataSet4k[idxL].pwrPdg[i][4];
2086		    ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i],
2087				       pRawDataSet4k[idxL].pwrPdg[i],
2088				       pRawDataSet4k[idxL].vpdPdg[i],
2089				       AR5416_PD_GAIN_ICEPTS, vpdTableI[i]);
2090	    }
2091        }
2092    } else {
2093        for (i = 0; i < numXpdGains; i++) {
2094	    if (pRawDataSet) {
2095		    pVpdL = pRawDataSet[idxL].vpdPdg[i];
2096		    pPwrL = pRawDataSet[idxL].pwrPdg[i];
2097		    pVpdR = pRawDataSet[idxR].vpdPdg[i];
2098		    pPwrR = pRawDataSet[idxR].pwrPdg[i];
2099	    } else {
2100		    pVpdL = pRawDataSet4k[idxL].vpdPdg[i];
2101		    pPwrL = pRawDataSet4k[idxL].pwrPdg[i];
2102		    pVpdR = pRawDataSet4k[idxR].vpdPdg[i];
2103		    pPwrR = pRawDataSet4k[idxR].pwrPdg[i];
2104	    }
2105
2106            /* Start Vpd interpolation from the max of the minimum powers */
2107            minPwrT4[i] = AH_MAX(pPwrL[0], pPwrR[0]);
2108
2109            /* End Vpd interpolation from the min of the max powers */
2110            maxPwrT4[i] = AH_MIN(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
2111            HALASSERT(maxPwrT4[i] > minPwrT4[i]);
2112
2113            /* Fill pier Vpds */
2114            ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, AR5416_PD_GAIN_ICEPTS, vpdTableL[i]);
2115            ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, AR5416_PD_GAIN_ICEPTS, vpdTableR[i]);
2116
2117            /* Interpolate the final vpd */
2118            for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
2119                vpdTableI[i][j] = (uint8_t)(interpolate((uint16_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)),
2120                    bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j]));
2121            }
2122        }
2123    }
2124    *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
2125
2126    k = 0; /* index for the final table */
2127    for (i = 0; i < numXpdGains; i++) {
2128        if (i == (numXpdGains - 1)) {
2129            pPdGainBoundaries[i] = (uint16_t)(maxPwrT4[i] / 2);
2130        } else {
2131            pPdGainBoundaries[i] = (uint16_t)((maxPwrT4[i] + minPwrT4[i+1]) / 4);
2132        }
2133
2134        pPdGainBoundaries[i] = (uint16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
2135
2136	/* NB: only applies to owl 1.0 */
2137        if ((i == 0) && !AR_SREV_OWL_20_OR_LATER(ah) ) {
2138	    /*
2139             * fix the gain delta, but get a delta that can be applied to min to
2140             * keep the upper power values accurate, don't think max needs to
2141             * be adjusted because should not be at that area of the table?
2142	     */
2143            minDelta = pPdGainBoundaries[0] - 23;
2144            pPdGainBoundaries[0] = 23;
2145        }
2146        else {
2147            minDelta = 0;
2148        }
2149
2150        /* Find starting index for this pdGain */
2151        if (i == 0) {
2152            ss = 0; /* for the first pdGain, start from index 0 */
2153        } else {
2154	    /* need overlap entries extrapolated below. */
2155            ss = (int16_t)((pPdGainBoundaries[i-1] - (minPwrT4[i] / 2)) - tPdGainOverlap + 1 + minDelta);
2156        }
2157        vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
2158        vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
2159        /*
2160         *-ve ss indicates need to extrapolate data below for this pdGain
2161         */
2162        while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2163            tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
2164            pPDADCValues[k++] = (uint8_t)((tmpVal < 0) ? 0 : tmpVal);
2165            ss++;
2166        }
2167
2168        sizeCurrVpdTable = (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 +1);
2169        tgtIndex = (uint8_t)(pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2));
2170        maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
2171
2172        while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2173            pPDADCValues[k++] = vpdTableI[i][ss++];
2174        }
2175
2176        vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - vpdTableI[i][sizeCurrVpdTable - 2]);
2177        vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
2178        /*
2179         * for last gain, pdGainBoundary == Pmax_t2, so will
2180         * have to extrapolate
2181         */
2182        if (tgtIndex > maxIndex) {  /* need to extrapolate above */
2183            while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2184                tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
2185                          (ss - maxIndex +1) * vpdStep));
2186                pPDADCValues[k++] = (uint8_t)((tmpVal > 255) ? 255 : tmpVal);
2187                ss++;
2188            }
2189        }               /* extrapolated above */
2190    }                   /* for all pdGainUsed */
2191
2192    /* Fill out pdGainBoundaries - only up to 2 allowed here, but hardware allows up to 4 */
2193    while (i < AR5416_PD_GAINS_IN_MASK) {
2194        pPdGainBoundaries[i] = pPdGainBoundaries[i-1];
2195        i++;
2196    }
2197
2198    while (k < AR5416_NUM_PDADC_VALUES) {
2199        pPDADCValues[k] = pPDADCValues[k-1];
2200        k++;
2201    }
2202    return;
2203}
2204
2205/**************************************************************
2206 * getLowerUppderIndex
2207 *
2208 * Return indices surrounding the value in sorted integer lists.
2209 * Requirement: the input list must be monotonically increasing
2210 *     and populated up to the list size
2211 * Returns: match is set if an index in the array matches exactly
2212 *     or a the target is before or after the range of the array.
2213 */
2214HAL_BOOL
2215getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize,
2216                   uint16_t *indexL, uint16_t *indexR)
2217{
2218    uint16_t i;
2219
2220    /*
2221     * Check first and last elements for beyond ordered array cases.
2222     */
2223    if (target <= pList[0]) {
2224        *indexL = *indexR = 0;
2225        return AH_TRUE;
2226    }
2227    if (target >= pList[listSize-1]) {
2228        *indexL = *indexR = (uint16_t)(listSize - 1);
2229        return AH_TRUE;
2230    }
2231
2232    /* look for value being near or between 2 values in list */
2233    for (i = 0; i < listSize - 1; i++) {
2234        /*
2235         * If value is close to the current value of the list
2236         * then target is not between values, it is one of the values
2237         */
2238        if (pList[i] == target) {
2239            *indexL = *indexR = i;
2240            return AH_TRUE;
2241        }
2242        /*
2243         * Look for value being between current value and next value
2244         * if so return these 2 values
2245         */
2246        if (target < pList[i + 1]) {
2247            *indexL = i;
2248            *indexR = (uint16_t)(i + 1);
2249            return AH_FALSE;
2250        }
2251    }
2252    HALASSERT(0);
2253    *indexL = *indexR = 0;
2254    return AH_FALSE;
2255}
2256
2257/**************************************************************
2258 * ar5416FillVpdTable
2259 *
2260 * Fill the Vpdlist for indices Pmax-Pmin
2261 * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4
2262 */
2263static HAL_BOOL
2264ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList,
2265                   uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList)
2266{
2267    uint16_t  i, k;
2268    uint8_t   currPwr = pwrMin;
2269    uint16_t  idxL, idxR;
2270
2271    HALASSERT(pwrMax > pwrMin);
2272    for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
2273        getLowerUpperIndex(currPwr, pPwrList, numIntercepts,
2274                           &(idxL), &(idxR));
2275        if (idxR < 1)
2276            idxR = 1;           /* extrapolate below */
2277        if (idxL == numIntercepts - 1)
2278            idxL = (uint16_t)(numIntercepts - 2);   /* extrapolate above */
2279        if (pPwrList[idxL] == pPwrList[idxR])
2280            k = pVpdList[idxL];
2281        else
2282            k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
2283                  (pPwrList[idxR] - pPwrList[idxL]) );
2284        HALASSERT(k < 256);
2285        pRetVpdList[i] = (uint8_t)k;
2286        currPwr += 2;               /* half dB steps */
2287    }
2288
2289    return AH_TRUE;
2290}
2291
2292/**************************************************************************
2293 * interpolate
2294 *
2295 * Returns signed interpolated or the scaled up interpolated value
2296 */
2297static int16_t
2298interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
2299            int16_t targetLeft, int16_t targetRight)
2300{
2301    int16_t rv;
2302
2303    if (srcRight == srcLeft) {
2304        rv = targetLeft;
2305    } else {
2306        rv = (int16_t)( ((target - srcLeft) * targetRight +
2307              (srcRight - target) * targetLeft) / (srcRight - srcLeft) );
2308    }
2309    return rv;
2310}
2311
2312static void
2313ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan)
2314{
2315	uint32_t phymode;
2316	HAL_HT_MACMODE macmode;		/* MAC - 20/40 mode */
2317
2318	if (!IEEE80211_IS_CHAN_HT(chan))
2319		return;
2320
2321	/* Enable 11n HT, 20 MHz */
2322	phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
2323		| AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
2324
2325	/* Configure baseband for dynamic 20/40 operation */
2326	if (IEEE80211_IS_CHAN_HT40(chan)) {
2327		phymode |= AR_PHY_FC_DYN2040_EN | AR_PHY_FC_SHORT_GI_40;
2328
2329		/* Configure control (primary) channel at +-10MHz */
2330		if (IEEE80211_IS_CHAN_HT40U(chan))
2331			phymode |= AR_PHY_FC_DYN2040_PRI_CH;
2332#if 0
2333		/* Configure 20/25 spacing */
2334		if (ht->ht_extprotspacing == HAL_HT_EXTPROTSPACING_25)
2335			phymode |= AR_PHY_FC_DYN2040_EXT_CH;
2336#endif
2337		macmode = HAL_HT_MACMODE_2040;
2338	} else
2339		macmode = HAL_HT_MACMODE_20;
2340	OS_REG_WRITE(ah, AR_PHY_TURBO, phymode);
2341
2342	/* Configure MAC for 20/40 operation */
2343	ar5416Set11nMac2040(ah, macmode);
2344
2345	/* global transmit timeout (25 TUs default)*/
2346	/* XXX - put this elsewhere??? */
2347	OS_REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S) ;
2348
2349	/* carrier sense timeout */
2350	OS_REG_SET_BIT(ah, AR_GTTM, AR_GTTM_CST_USEC);
2351	OS_REG_WRITE(ah, AR_CST, 1 << AR_CST_TIMEOUT_LIMIT_S);
2352}
2353
2354void
2355ar5416GetChannelCenters(struct ath_hal *ah,
2356	const struct ieee80211_channel *chan, CHAN_CENTERS *centers)
2357{
2358	uint16_t freq = ath_hal_gethwchannel(ah, chan);
2359
2360	centers->ctl_center = freq;
2361	centers->synth_center = freq;
2362	/*
2363	 * In 20/40 phy mode, the center frequency is
2364	 * "between" the control and extension channels.
2365	 */
2366	if (IEEE80211_IS_CHAN_HT40U(chan)) {
2367		centers->synth_center += HT40_CHANNEL_CENTER_SHIFT;
2368		centers->ext_center =
2369		    centers->synth_center + HT40_CHANNEL_CENTER_SHIFT;
2370	} else if (IEEE80211_IS_CHAN_HT40D(chan)) {
2371		centers->synth_center -= HT40_CHANNEL_CENTER_SHIFT;
2372		centers->ext_center =
2373		    centers->synth_center - HT40_CHANNEL_CENTER_SHIFT;
2374	} else {
2375		centers->ext_center = freq;
2376	}
2377}
2378