xref: /freebsd/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1*6e778a7eSPedro F. Giffuni /*-
2*6e778a7eSPedro F. Giffuni  * SPDX-License-Identifier: ISC
3*6e778a7eSPedro F. Giffuni  *
459efa8b5SSam Leffler  * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
514779705SSam Leffler  * Copyright (c) 2002-2004 Atheros Communications, Inc.
614779705SSam Leffler  *
714779705SSam Leffler  * Permission to use, copy, modify, and/or distribute this software for any
814779705SSam Leffler  * purpose with or without fee is hereby granted, provided that the above
914779705SSam Leffler  * copyright notice and this permission notice appear in all copies.
1014779705SSam Leffler  *
1114779705SSam Leffler  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1214779705SSam Leffler  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1314779705SSam Leffler  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1414779705SSam Leffler  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1514779705SSam Leffler  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1614779705SSam Leffler  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1714779705SSam Leffler  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1814779705SSam Leffler  */
1914779705SSam Leffler #include "opt_ah.h"
2014779705SSam Leffler 
2114779705SSam Leffler #include "ah.h"
2214779705SSam Leffler #include "ah_internal.h"
2314779705SSam Leffler 
2414779705SSam Leffler #include "ar5210/ar5210.h"
2514779705SSam Leffler #include "ar5210/ar5210reg.h"
2614779705SSam Leffler #include "ar5210/ar5210phy.h"
2714779705SSam Leffler 
2814779705SSam Leffler #include "ah_eeprom_v1.h"
2914779705SSam Leffler 
3014779705SSam Leffler typedef struct {
3114779705SSam Leffler 	uint32_t	Offset;
3214779705SSam Leffler 	uint32_t	Value;
3314779705SSam Leffler } REGISTER_VAL;
3414779705SSam Leffler 
3514779705SSam Leffler static const REGISTER_VAL ar5k0007_init[] = {
3614779705SSam Leffler #include "ar5210/ar5k_0007.ini"
3714779705SSam Leffler };
3814779705SSam Leffler 
3914779705SSam Leffler /* Default Power Settings for channels outside of EEPROM range */
4014779705SSam Leffler static const uint8_t ar5k0007_pwrSettings[17] = {
4114779705SSam Leffler /*	gain delta			pc dac */
4214779705SSam Leffler /* 54  48  36  24  18  12   9   54  48  36  24  18  12   9   6  ob  db	  */
4314779705SSam Leffler     9,  9,  0,  0,  0,  0,  0,   2,  2,  6,  6,  6,  6,  6,  6,  2,  2
4414779705SSam Leffler };
4514779705SSam Leffler 
4614779705SSam Leffler /*
4714779705SSam Leffler  * The delay, in usecs, between writing AR_RC with a reset
4814779705SSam Leffler  * request and waiting for the chip to settle.  If this is
4914779705SSam Leffler  * too short then the chip does not come out of sleep state.
5014779705SSam Leffler  * Note this value was empirically derived and may be dependent
5114779705SSam Leffler  * on the host machine (don't know--the problem was identified
5214779705SSam Leffler  * on an IBM 570e laptop; 10us delays worked on other systems).
5314779705SSam Leffler  */
5414779705SSam Leffler #define	AR_RC_SETTLE_TIME	20000
5514779705SSam Leffler 
5614779705SSam Leffler static HAL_BOOL ar5210SetResetReg(struct ath_hal *,
5714779705SSam Leffler 		uint32_t resetMask, u_int delay);
5859efa8b5SSam Leffler static HAL_BOOL ar5210SetChannel(struct ath_hal *, struct ieee80211_channel *);
5914779705SSam Leffler static void ar5210SetOperatingMode(struct ath_hal *, int opmode);
6014779705SSam Leffler 
6114779705SSam Leffler /*
6214779705SSam Leffler  * Places the device in and out of reset and then places sane
6314779705SSam Leffler  * values in the registers based on EEPROM config, initialization
6414779705SSam Leffler  * vectors (as determined by the mode), and station configuration
6514779705SSam Leffler  *
6614779705SSam Leffler  * bChannelChange is used to preserve DMA/PCU registers across
6714779705SSam Leffler  * a HW Reset during channel change.
6814779705SSam Leffler  */
6914779705SSam Leffler HAL_BOOL
ar5210Reset(struct ath_hal * ah,HAL_OPMODE opmode,struct ieee80211_channel * chan,HAL_BOOL bChannelChange,HAL_RESET_TYPE resetType,HAL_STATUS * status)7014779705SSam Leffler ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
7159efa8b5SSam Leffler 	struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
72f50e4ebfSAdrian Chadd 	HAL_RESET_TYPE resetType,
7359efa8b5SSam Leffler 	HAL_STATUS *status)
7414779705SSam Leffler {
7514779705SSam Leffler #define	N(a)	(sizeof (a) /sizeof (a[0]))
7614779705SSam Leffler #define	FAIL(_code)	do { ecode = _code; goto bad; } while (0)
7714779705SSam Leffler 	struct ath_hal_5210 *ahp = AH5210(ah);
7814779705SSam Leffler 	const HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom;
7914779705SSam Leffler 	HAL_CHANNEL_INTERNAL *ichan;
8014779705SSam Leffler 	HAL_STATUS ecode;
8114779705SSam Leffler 	uint32_t ledstate;
8214779705SSam Leffler 	int i, q;
8314779705SSam Leffler 
8414779705SSam Leffler 	HALDEBUG(ah, HAL_DEBUG_RESET,
8514779705SSam Leffler 	    "%s: opmode %u channel %u/0x%x %s channel\n", __func__,
8659efa8b5SSam Leffler 	    opmode, chan->ic_freq, chan->ic_flags,
8714779705SSam Leffler 	    bChannelChange ? "change" : "same");
8814779705SSam Leffler 
8959efa8b5SSam Leffler 	if (!IEEE80211_IS_CHAN_5GHZ(chan)) {
9014779705SSam Leffler 		/* Only 11a mode */
9179649302SGavin Atkinson 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: channel not 5GHz\n", __func__);
9214779705SSam Leffler 		FAIL(HAL_EINVAL);
9314779705SSam Leffler 	}
9414779705SSam Leffler 	/*
9514779705SSam Leffler 	 * Map public channel to private.
9614779705SSam Leffler 	 */
9714779705SSam Leffler 	ichan = ath_hal_checkchannel(ah, chan);
9814779705SSam Leffler 	if (ichan == AH_NULL) {
9914779705SSam Leffler 		HALDEBUG(ah, HAL_DEBUG_ANY,
10014779705SSam Leffler 		    "%s: invalid channel %u/0x%x; no mapping\n",
10159efa8b5SSam Leffler 		    __func__, chan->ic_freq, chan->ic_flags);
10214779705SSam Leffler 		FAIL(HAL_EINVAL);
10314779705SSam Leffler 	}
10414779705SSam Leffler 	switch (opmode) {
10514779705SSam Leffler 	case HAL_M_STA:
10614779705SSam Leffler 	case HAL_M_IBSS:
10714779705SSam Leffler 	case HAL_M_HOSTAP:
10814779705SSam Leffler 	case HAL_M_MONITOR:
10914779705SSam Leffler 		break;
11014779705SSam Leffler 	default:
11114779705SSam Leffler 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n",
11214779705SSam Leffler 		    __func__, opmode);
11314779705SSam Leffler 		FAIL(HAL_EINVAL);
11414779705SSam Leffler 		break;
11514779705SSam Leffler 	}
11614779705SSam Leffler 
11714779705SSam Leffler 	ledstate = OS_REG_READ(ah, AR_PCICFG) &
11814779705SSam Leffler 		(AR_PCICFG_LED_PEND | AR_PCICFG_LED_ACT);
11914779705SSam Leffler 
12014779705SSam Leffler 	if (!ar5210ChipReset(ah, chan)) {
12114779705SSam Leffler 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n",
12214779705SSam Leffler 		    __func__);
12314779705SSam Leffler 		FAIL(HAL_EIO);
12414779705SSam Leffler 	}
12514779705SSam Leffler 
12614779705SSam Leffler 	OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
12714779705SSam Leffler 	OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4));
12814779705SSam Leffler 	ar5210SetOperatingMode(ah, opmode);
12914779705SSam Leffler 
13014779705SSam Leffler 	switch (opmode) {
13114779705SSam Leffler 	case HAL_M_HOSTAP:
13214779705SSam Leffler 		OS_REG_WRITE(ah, AR_BCR, INIT_BCON_CNTRL_REG);
13314779705SSam Leffler 		OS_REG_WRITE(ah, AR_PCICFG,
13414779705SSam Leffler 			AR_PCICFG_LED_ACT | AR_PCICFG_LED_BCTL);
13514779705SSam Leffler 		break;
13614779705SSam Leffler 	case HAL_M_IBSS:
13714779705SSam Leffler 		OS_REG_WRITE(ah, AR_BCR, INIT_BCON_CNTRL_REG | AR_BCR_BCMD);
13814779705SSam Leffler 		OS_REG_WRITE(ah, AR_PCICFG,
13914779705SSam Leffler 			AR_PCICFG_CLKRUNEN | AR_PCICFG_LED_PEND | AR_PCICFG_LED_BCTL);
14014779705SSam Leffler 		break;
14114779705SSam Leffler 	case HAL_M_STA:
14214779705SSam Leffler 		OS_REG_WRITE(ah, AR_BCR, INIT_BCON_CNTRL_REG);
14314779705SSam Leffler 		OS_REG_WRITE(ah, AR_PCICFG,
14414779705SSam Leffler 			AR_PCICFG_CLKRUNEN | AR_PCICFG_LED_PEND | AR_PCICFG_LED_BCTL);
14514779705SSam Leffler 		break;
14614779705SSam Leffler 	case HAL_M_MONITOR:
14714779705SSam Leffler 		OS_REG_WRITE(ah, AR_BCR, INIT_BCON_CNTRL_REG);
14814779705SSam Leffler 		OS_REG_WRITE(ah, AR_PCICFG,
14914779705SSam Leffler 			AR_PCICFG_LED_ACT | AR_PCICFG_LED_BCTL);
15014779705SSam Leffler 		break;
15114779705SSam Leffler 	}
15214779705SSam Leffler 
15314779705SSam Leffler 	/* Restore previous led state */
15414779705SSam Leffler 	OS_REG_WRITE(ah, AR_PCICFG, OS_REG_READ(ah, AR_PCICFG) | ledstate);
15514779705SSam Leffler 
1569b34359bSAdrian Chadd #if 0
15714779705SSam Leffler 	OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
15814779705SSam Leffler 	OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4));
1599b34359bSAdrian Chadd #endif
1609b34359bSAdrian Chadd 	/* BSSID, association id, ps-poll */
1619b34359bSAdrian Chadd 	ar5210WriteAssocid(ah, ahp->ah_bssid, ahp->ah_associd);
16214779705SSam Leffler 
16314779705SSam Leffler 	OS_REG_WRITE(ah, AR_TXDP0, 0);
16414779705SSam Leffler 	OS_REG_WRITE(ah, AR_TXDP1, 0);
16514779705SSam Leffler 	OS_REG_WRITE(ah, AR_RXDP, 0);
16614779705SSam Leffler 
16714779705SSam Leffler 	/*
16814779705SSam Leffler 	 * Initialize interrupt state.
16914779705SSam Leffler 	 */
17014779705SSam Leffler 	(void) OS_REG_READ(ah, AR_ISR);		/* cleared on read */
17114779705SSam Leffler 	OS_REG_WRITE(ah, AR_IMR, 0);
17214779705SSam Leffler 	OS_REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
17314779705SSam Leffler 	ahp->ah_maskReg = 0;
17414779705SSam Leffler 
17514779705SSam Leffler 	(void) OS_REG_READ(ah, AR_BSR);		/* cleared on read */
17614779705SSam Leffler 	OS_REG_WRITE(ah, AR_TXCFG, AR_DMASIZE_128B);
17714779705SSam Leffler 	OS_REG_WRITE(ah, AR_RXCFG, AR_DMASIZE_128B);
17814779705SSam Leffler 
17914779705SSam Leffler 	OS_REG_WRITE(ah, AR_TOPS, 8);		/* timeout prescale */
18014779705SSam Leffler 	OS_REG_WRITE(ah, AR_RXNOFRM, 8);	/* RX no frame timeout */
18114779705SSam Leffler 	OS_REG_WRITE(ah, AR_RPGTO, 0);		/* RX frame gap timeout */
18214779705SSam Leffler 	OS_REG_WRITE(ah, AR_TXNOFRM, 0);	/* TX no frame timeout */
18314779705SSam Leffler 
18414779705SSam Leffler 	OS_REG_WRITE(ah, AR_SFR, 0);
18514779705SSam Leffler 	OS_REG_WRITE(ah, AR_MIBC, 0);		/* unfreeze ctrs + clr state */
18614779705SSam Leffler 	OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr);
18714779705SSam Leffler 	OS_REG_WRITE(ah, AR_CFP_DUR, 0);
18814779705SSam Leffler 
18914779705SSam Leffler 	ar5210SetRxFilter(ah, 0);		/* nothing for now */
19014779705SSam Leffler 	OS_REG_WRITE(ah, AR_MCAST_FIL0, 0);	/* multicast filter */
19114779705SSam Leffler 	OS_REG_WRITE(ah, AR_MCAST_FIL1, 0);	/* XXX was 2 */
19214779705SSam Leffler 
19314779705SSam Leffler 	OS_REG_WRITE(ah, AR_TX_MASK0, 0);
19414779705SSam Leffler 	OS_REG_WRITE(ah, AR_TX_MASK1, 0);
19514779705SSam Leffler 	OS_REG_WRITE(ah, AR_CLR_TMASK, 1);
19614779705SSam Leffler 	OS_REG_WRITE(ah, AR_TRIG_LEV, 1);	/* minimum */
19714779705SSam Leffler 
198143cfad7SAdrian Chadd 	ar5210UpdateDiagReg(ah, 0);
19914779705SSam Leffler 
20014779705SSam Leffler 	OS_REG_WRITE(ah, AR_CFP_PERIOD, 0);
20114779705SSam Leffler 	OS_REG_WRITE(ah, AR_TIMER0, 0);		/* next beacon time */
20214779705SSam Leffler 	OS_REG_WRITE(ah, AR_TSF_L32, 0);	/* local clock */
20314779705SSam Leffler 	OS_REG_WRITE(ah, AR_TIMER1, ~0);	/* next DMA beacon alert */
20414779705SSam Leffler 	OS_REG_WRITE(ah, AR_TIMER2, ~0);	/* next SW beacon alert */
20514779705SSam Leffler 	OS_REG_WRITE(ah, AR_TIMER3, 1);		/* next ATIM window */
20614779705SSam Leffler 
20714779705SSam Leffler 	/* Write the INI values for PHYreg initialization */
20814779705SSam Leffler 	for (i = 0; i < N(ar5k0007_init); i++) {
20914779705SSam Leffler 		uint32_t reg = ar5k0007_init[i].Offset;
21014779705SSam Leffler 		/* On channel change, don't reset the PCU registers */
21114779705SSam Leffler 		if (!(bChannelChange && (0x8000 <= reg && reg < 0x9000)))
21214779705SSam Leffler 			OS_REG_WRITE(ah, reg, ar5k0007_init[i].Value);
21314779705SSam Leffler 	}
21414779705SSam Leffler 
21514779705SSam Leffler 	/* Setup the transmit power values for cards since 0x0[0-2]05 */
21614779705SSam Leffler 	if (!ar5210SetTransmitPower(ah, chan)) {
21714779705SSam Leffler 		HALDEBUG(ah, HAL_DEBUG_ANY,
21814779705SSam Leffler 		    "%s: error init'ing transmit power\n", __func__);
21914779705SSam Leffler 		FAIL(HAL_EIO);
22014779705SSam Leffler 	}
22114779705SSam Leffler 
22214779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY(10),
22314779705SSam Leffler 		(OS_REG_READ(ah, AR_PHY(10)) & 0xFFFF00FF) |
22414779705SSam Leffler 		(ee->ee_xlnaOn << 8));
22514779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY(13),
22614779705SSam Leffler 		(ee->ee_xpaOff << 24) | (ee->ee_xpaOff << 16) |
22714779705SSam Leffler 		(ee->ee_xpaOn << 8) | ee->ee_xpaOn);
22814779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY(17),
22914779705SSam Leffler 		(OS_REG_READ(ah, AR_PHY(17)) & 0xFFFFC07F) |
23014779705SSam Leffler 		((ee->ee_antenna >> 1) & 0x3F80));
23114779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY(18),
23214779705SSam Leffler 		(OS_REG_READ(ah, AR_PHY(18)) & 0xFFFC0FFF) |
23314779705SSam Leffler 		((ee->ee_antenna << 10) & 0x3F000));
23414779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY(25),
23514779705SSam Leffler 		(OS_REG_READ(ah, AR_PHY(25)) & 0xFFF80FFF) |
23614779705SSam Leffler 		((ee->ee_thresh62 << 12) & 0x7F000));
23714779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY(68),
23814779705SSam Leffler 		(OS_REG_READ(ah, AR_PHY(68)) & 0xFFFFFFFC) |
23914779705SSam Leffler 		(ee->ee_antenna & 0x3));
24014779705SSam Leffler 
24159efa8b5SSam Leffler 	if (!ar5210SetChannel(ah, chan)) {
24214779705SSam Leffler 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set channel\n",
24314779705SSam Leffler 		    __func__);
24414779705SSam Leffler 		FAIL(HAL_EIO);
24514779705SSam Leffler 	}
24659efa8b5SSam Leffler 	if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
24759efa8b5SSam Leffler 		chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
24814779705SSam Leffler 
24914779705SSam Leffler 	/* Activate the PHY */
25014779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ENABLE);
25114779705SSam Leffler 
25214779705SSam Leffler 	OS_DELAY(1000);		/* Wait a bit (1 msec) */
25314779705SSam Leffler 
25414779705SSam Leffler 	/* calibrate the HW and poll the bit going to 0 for completion */
25514779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY_AGCCTL,
25614779705SSam Leffler 		OS_REG_READ(ah, AR_PHY_AGCCTL) | AR_PHY_AGC_CAL);
25714779705SSam Leffler 	(void) ath_hal_wait(ah, AR_PHY_AGCCTL, AR_PHY_AGC_CAL, 0);
25814779705SSam Leffler 
25914779705SSam Leffler 	/* Perform noise floor calibration and set status */
26014779705SSam Leffler 	if (!ar5210CalNoiseFloor(ah, ichan)) {
26159efa8b5SSam Leffler 		chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
26214779705SSam Leffler 		HALDEBUG(ah, HAL_DEBUG_ANY,
26314779705SSam Leffler 		    "%s: noise floor calibration failed\n", __func__);
26414779705SSam Leffler 		FAIL(HAL_EIO);
26514779705SSam Leffler 	}
26614779705SSam Leffler 
26714779705SSam Leffler 	for (q = 0; q < HAL_NUM_TX_QUEUES; q++)
26814779705SSam Leffler 		ar5210ResetTxQueue(ah, q);
26914779705SSam Leffler 
27014779705SSam Leffler 	if (AH_PRIVATE(ah)->ah_rfkillEnabled)
27114779705SSam Leffler 		ar5210EnableRfKill(ah);
27214779705SSam Leffler 
27314779705SSam Leffler 	/*
27414779705SSam Leffler 	 * Writing to AR_BEACON will start timers. Hence it should be
27514779705SSam Leffler 	 * the last register to be written. Do not reset tsf, do not
27614779705SSam Leffler 	 * enable beacons at this point, but preserve other values
27714779705SSam Leffler 	 * like beaconInterval.
27814779705SSam Leffler 	 */
27914779705SSam Leffler 	OS_REG_WRITE(ah, AR_BEACON,
28014779705SSam Leffler 		(OS_REG_READ(ah, AR_BEACON) &
28114779705SSam Leffler 			~(AR_BEACON_EN | AR_BEACON_RESET_TSF)));
28214779705SSam Leffler 
28314779705SSam Leffler 	/* Restore user-specified slot time and timeouts */
28414779705SSam Leffler 	if (ahp->ah_sifstime != (u_int) -1)
28514779705SSam Leffler 		ar5210SetSifsTime(ah, ahp->ah_sifstime);
28614779705SSam Leffler 	if (ahp->ah_slottime != (u_int) -1)
28714779705SSam Leffler 		ar5210SetSlotTime(ah, ahp->ah_slottime);
28814779705SSam Leffler 	if (ahp->ah_acktimeout != (u_int) -1)
28914779705SSam Leffler 		ar5210SetAckTimeout(ah, ahp->ah_acktimeout);
29014779705SSam Leffler 	if (ahp->ah_ctstimeout != (u_int) -1)
29114779705SSam Leffler 		ar5210SetCTSTimeout(ah, ahp->ah_ctstimeout);
29214779705SSam Leffler 	if (AH_PRIVATE(ah)->ah_diagreg != 0)
293143cfad7SAdrian Chadd 		ar5210UpdateDiagReg(ah, AH_PRIVATE(ah)->ah_diagreg);
29414779705SSam Leffler 
29514779705SSam Leffler 	AH_PRIVATE(ah)->ah_opmode = opmode;	/* record operating mode */
29614779705SSam Leffler 
29714779705SSam Leffler 	HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
29814779705SSam Leffler 
29914779705SSam Leffler 	return AH_TRUE;
30014779705SSam Leffler bad:
3018698ea65SSam Leffler 	if (status != AH_NULL)
30214779705SSam Leffler 		*status = ecode;
30314779705SSam Leffler 	return AH_FALSE;
30414779705SSam Leffler #undef FAIL
30514779705SSam Leffler #undef N
30614779705SSam Leffler }
30714779705SSam Leffler 
30814779705SSam Leffler static void
ar5210SetOperatingMode(struct ath_hal * ah,int opmode)30914779705SSam Leffler ar5210SetOperatingMode(struct ath_hal *ah, int opmode)
31014779705SSam Leffler {
31114779705SSam Leffler 	struct ath_hal_5210 *ahp = AH5210(ah);
31214779705SSam Leffler 	uint32_t val;
31314779705SSam Leffler 
31414779705SSam Leffler 	val = OS_REG_READ(ah, AR_STA_ID1) & 0xffff;
31514779705SSam Leffler 	switch (opmode) {
31614779705SSam Leffler 	case HAL_M_HOSTAP:
31714779705SSam Leffler 		OS_REG_WRITE(ah, AR_STA_ID1, val
31814779705SSam Leffler 			| AR_STA_ID1_AP
31914779705SSam Leffler 			| AR_STA_ID1_NO_PSPOLL
32014779705SSam Leffler 			| AR_STA_ID1_DESC_ANTENNA
32114779705SSam Leffler 			| ahp->ah_staId1Defaults);
32214779705SSam Leffler 		break;
32314779705SSam Leffler 	case HAL_M_IBSS:
32414779705SSam Leffler 		OS_REG_WRITE(ah, AR_STA_ID1, val
32514779705SSam Leffler 			| AR_STA_ID1_ADHOC
32614779705SSam Leffler 			| AR_STA_ID1_NO_PSPOLL
32714779705SSam Leffler 			| AR_STA_ID1_DESC_ANTENNA
32814779705SSam Leffler 			| ahp->ah_staId1Defaults);
32914779705SSam Leffler 		break;
33014779705SSam Leffler 	case HAL_M_STA:
33114779705SSam Leffler 		OS_REG_WRITE(ah, AR_STA_ID1, val
33214779705SSam Leffler 			| AR_STA_ID1_NO_PSPOLL
33314779705SSam Leffler 			| AR_STA_ID1_PWR_SV
33414779705SSam Leffler 			| ahp->ah_staId1Defaults);
33514779705SSam Leffler 		break;
33614779705SSam Leffler 	case HAL_M_MONITOR:
33714779705SSam Leffler 		OS_REG_WRITE(ah, AR_STA_ID1, val
33814779705SSam Leffler 			| AR_STA_ID1_NO_PSPOLL
33914779705SSam Leffler 			| ahp->ah_staId1Defaults);
34014779705SSam Leffler 		break;
34114779705SSam Leffler 	}
34214779705SSam Leffler }
34314779705SSam Leffler 
34414779705SSam Leffler void
ar5210SetPCUConfig(struct ath_hal * ah)34514779705SSam Leffler ar5210SetPCUConfig(struct ath_hal *ah)
34614779705SSam Leffler {
34714779705SSam Leffler 	ar5210SetOperatingMode(ah, AH_PRIVATE(ah)->ah_opmode);
34814779705SSam Leffler }
34914779705SSam Leffler 
35014779705SSam Leffler /*
35114779705SSam Leffler  * Places the PHY and Radio chips into reset.  A full reset
35214779705SSam Leffler  * must be called to leave this state.  The PCI/MAC/PCU are
35314779705SSam Leffler  * not placed into reset as we must receive interrupt to
35414779705SSam Leffler  * re-enable the hardware.
35514779705SSam Leffler  */
35614779705SSam Leffler HAL_BOOL
ar5210PhyDisable(struct ath_hal * ah)35714779705SSam Leffler ar5210PhyDisable(struct ath_hal *ah)
35814779705SSam Leffler {
35914779705SSam Leffler 	return ar5210SetResetReg(ah, AR_RC_RPHY, 10);
36014779705SSam Leffler }
36114779705SSam Leffler 
36214779705SSam Leffler /*
36314779705SSam Leffler  * Places all of hardware into reset
36414779705SSam Leffler  */
36514779705SSam Leffler HAL_BOOL
ar5210Disable(struct ath_hal * ah)36614779705SSam Leffler ar5210Disable(struct ath_hal *ah)
36714779705SSam Leffler {
36814779705SSam Leffler #define	AR_RC_HW (AR_RC_RPCU | AR_RC_RDMA | AR_RC_RPHY | AR_RC_RMAC)
36914779705SSam Leffler 	if (!ar5210SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
37014779705SSam Leffler 		return AH_FALSE;
37114779705SSam Leffler 
37214779705SSam Leffler 	/*
37314779705SSam Leffler 	 * Reset the HW - PCI must be reset after the rest of the
37414779705SSam Leffler 	 * device has been reset
37514779705SSam Leffler 	 */
37614779705SSam Leffler 	if (!ar5210SetResetReg(ah, AR_RC_HW, AR_RC_SETTLE_TIME))
37714779705SSam Leffler 		return AH_FALSE;
37814779705SSam Leffler 	OS_DELAY(1000);
37914779705SSam Leffler 	(void) ar5210SetResetReg(ah, AR_RC_HW | AR_RC_RPCI, AR_RC_SETTLE_TIME);
38014779705SSam Leffler 	OS_DELAY(2100);   /* 8245 @ 96Mhz hangs with 2000us. */
38114779705SSam Leffler 
38214779705SSam Leffler 	return AH_TRUE;
38314779705SSam Leffler #undef AR_RC_HW
38414779705SSam Leffler }
38514779705SSam Leffler 
38614779705SSam Leffler /*
38714779705SSam Leffler  * Places the hardware into reset and then pulls it out of reset
38814779705SSam Leffler  */
38914779705SSam Leffler HAL_BOOL
ar5210ChipReset(struct ath_hal * ah,struct ieee80211_channel * chan)39059efa8b5SSam Leffler ar5210ChipReset(struct ath_hal *ah, struct ieee80211_channel *chan)
39114779705SSam Leffler {
39214779705SSam Leffler #define	AR_RC_HW (AR_RC_RPCU | AR_RC_RDMA | AR_RC_RPHY | AR_RC_RMAC)
39314779705SSam Leffler 
39414779705SSam Leffler 	HALDEBUG(ah, HAL_DEBUG_RESET, "%s turbo %s\n", __func__,
39559efa8b5SSam Leffler 		chan && IEEE80211_IS_CHAN_TURBO(chan) ?
39659efa8b5SSam Leffler 		"enabled" : "disabled");
39714779705SSam Leffler 
39814779705SSam Leffler 	if (!ar5210SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
39914779705SSam Leffler 		return AH_FALSE;
40014779705SSam Leffler 
40114779705SSam Leffler 	/* Place chip in turbo before reset to cleanly reset clocks */
40214779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY_FRCTL,
40359efa8b5SSam Leffler 		chan && IEEE80211_IS_CHAN_TURBO(chan) ? AR_PHY_TURBO_MODE : 0);
40414779705SSam Leffler 
40514779705SSam Leffler 	/*
40614779705SSam Leffler 	 * Reset the HW.
40714779705SSam Leffler 	 * PCI must be reset after the rest of the device has been reset.
40814779705SSam Leffler 	 */
40914779705SSam Leffler 	if (!ar5210SetResetReg(ah, AR_RC_HW, AR_RC_SETTLE_TIME))
41014779705SSam Leffler 		return AH_FALSE;
41114779705SSam Leffler 	OS_DELAY(1000);
41214779705SSam Leffler 	if (!ar5210SetResetReg(ah, AR_RC_HW | AR_RC_RPCI, AR_RC_SETTLE_TIME))
41314779705SSam Leffler 		return AH_FALSE;
41414779705SSam Leffler 	OS_DELAY(2100);   /* 8245 @ 96Mhz hangs with 2000us. */
41514779705SSam Leffler 
41614779705SSam Leffler 	/*
41714779705SSam Leffler 	 * Bring out of sleep mode (AGAIN)
41814779705SSam Leffler 	 *
41914779705SSam Leffler 	 * WARNING WARNING WARNING
42014779705SSam Leffler 	 *
42114779705SSam Leffler 	 * There is a problem with the chip where it doesn't always indicate
42214779705SSam Leffler 	 * that it's awake, so initializePowerUp() will fail.
42314779705SSam Leffler 	 */
42414779705SSam Leffler 	if (!ar5210SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
42514779705SSam Leffler 		return AH_FALSE;
42614779705SSam Leffler 
42714779705SSam Leffler 	/* Clear warm reset reg */
42814779705SSam Leffler 	return ar5210SetResetReg(ah, 0, 10);
42914779705SSam Leffler #undef AR_RC_HW
43014779705SSam Leffler }
43114779705SSam Leffler 
43214779705SSam Leffler enum {
43314779705SSam Leffler 	FIRPWR_M	= 0x03fc0000,
43414779705SSam Leffler 	FIRPWR_S	= 18,
43514779705SSam Leffler 	KCOARSEHIGH_M   = 0x003f8000,
43614779705SSam Leffler 	KCOARSEHIGH_S   = 15,
43714779705SSam Leffler 	KCOARSELOW_M	= 0x00007f80,
43814779705SSam Leffler 	KCOARSELOW_S	= 7,
43914779705SSam Leffler 	ADCSAT_ICOUNT_M	= 0x0001f800,
44014779705SSam Leffler 	ADCSAT_ICOUNT_S	= 11,
44114779705SSam Leffler 	ADCSAT_THRESH_M	= 0x000007e0,
44214779705SSam Leffler 	ADCSAT_THRESH_S	= 5
44314779705SSam Leffler };
44414779705SSam Leffler 
44514779705SSam Leffler /*
44614779705SSam Leffler  * Recalibrate the lower PHY chips to account for temperature/environment
44714779705SSam Leffler  * changes.
44814779705SSam Leffler  */
44914779705SSam Leffler HAL_BOOL
ar5210PerCalibrationN(struct ath_hal * ah,struct ieee80211_channel * chan,u_int chainMask,HAL_BOOL longCal,HAL_BOOL * isCalDone)45059efa8b5SSam Leffler ar5210PerCalibrationN(struct ath_hal *ah,
45159efa8b5SSam Leffler 	struct ieee80211_channel *chan, u_int chainMask,
45214779705SSam Leffler 	HAL_BOOL longCal, HAL_BOOL *isCalDone)
45314779705SSam Leffler {
45414779705SSam Leffler 	uint32_t regBeacon;
45514779705SSam Leffler 	uint32_t reg9858, reg985c, reg9868;
45614779705SSam Leffler 	HAL_CHANNEL_INTERNAL *ichan;
45714779705SSam Leffler 
45814779705SSam Leffler 	ichan = ath_hal_checkchannel(ah, chan);
45959efa8b5SSam Leffler 	if (ichan == AH_NULL)
46014779705SSam Leffler 		return AH_FALSE;
46114779705SSam Leffler 	/* Disable tx and rx */
462143cfad7SAdrian Chadd 	ar5210UpdateDiagReg(ah,
46314779705SSam Leffler 		OS_REG_READ(ah, AR_DIAG_SW) | (AR_DIAG_SW_DIS_TX | AR_DIAG_SW_DIS_RX));
46414779705SSam Leffler 
46514779705SSam Leffler 	/* Disable Beacon Enable */
46614779705SSam Leffler 	regBeacon = OS_REG_READ(ah, AR_BEACON);
46714779705SSam Leffler 	OS_REG_WRITE(ah, AR_BEACON, regBeacon & ~AR_BEACON_EN);
46814779705SSam Leffler 
46914779705SSam Leffler 	/* Delay 4ms to ensure that all tx and rx activity has ceased */
47014779705SSam Leffler 	OS_DELAY(4000);
47114779705SSam Leffler 
47214779705SSam Leffler 	/* Disable AGC to radio traffic */
47314779705SSam Leffler 	OS_REG_WRITE(ah, 0x9808, OS_REG_READ(ah, 0x9808) | 0x08000000);
47414779705SSam Leffler 	/* Wait for the AGC traffic to cease. */
47514779705SSam Leffler 	OS_DELAY(10);
47614779705SSam Leffler 
47714779705SSam Leffler 	/* Change Channel to relock synth */
47859efa8b5SSam Leffler 	if (!ar5210SetChannel(ah, chan))
47914779705SSam Leffler 		return AH_FALSE;
48014779705SSam Leffler 
48114779705SSam Leffler 	/* wait for the synthesizer lock to stabilize */
48214779705SSam Leffler 	OS_DELAY(1000);
48314779705SSam Leffler 
48414779705SSam Leffler 	/* Re-enable AGC to radio traffic */
48514779705SSam Leffler 	OS_REG_WRITE(ah, 0x9808, OS_REG_READ(ah, 0x9808) & (~0x08000000));
48614779705SSam Leffler 
48714779705SSam Leffler 	/*
48814779705SSam Leffler 	 * Configure the AGC so that it is highly unlikely (if not
48914779705SSam Leffler 	 * impossible) for it to send any gain changes to the analog
49014779705SSam Leffler 	 * chip.  We store off the current values so that they can
49114779705SSam Leffler 	 * be rewritten below. Setting the following values:
49214779705SSam Leffler 	 * firpwr	 = -1
49314779705SSam Leffler 	 * Kcoursehigh   = -1
49414779705SSam Leffler 	 * Kcourselow	 = -127
49514779705SSam Leffler 	 * ADCsat_icount = 2
49614779705SSam Leffler 	 * ADCsat_thresh = 12
49714779705SSam Leffler 	 */
49814779705SSam Leffler 	reg9858 = OS_REG_READ(ah, 0x9858);
49914779705SSam Leffler 	reg985c = OS_REG_READ(ah, 0x985c);
50014779705SSam Leffler 	reg9868 = OS_REG_READ(ah, 0x9868);
50114779705SSam Leffler 
50214779705SSam Leffler 	OS_REG_WRITE(ah, 0x9858, (reg9858 & ~FIRPWR_M) |
50314779705SSam Leffler 					 ((-1 << FIRPWR_S) & FIRPWR_M));
50414779705SSam Leffler 	OS_REG_WRITE(ah, 0x985c,
50514779705SSam Leffler 		 (reg985c & ~(KCOARSEHIGH_M | KCOARSELOW_M)) |
50614779705SSam Leffler 		 ((-1 << KCOARSEHIGH_S) & KCOARSEHIGH_M) |
50714779705SSam Leffler 		 ((-127 << KCOARSELOW_S) & KCOARSELOW_M));
50814779705SSam Leffler 	OS_REG_WRITE(ah, 0x9868,
50914779705SSam Leffler 		 (reg9868 & ~(ADCSAT_ICOUNT_M | ADCSAT_THRESH_M)) |
51014779705SSam Leffler 		 ((2 << ADCSAT_ICOUNT_S) & ADCSAT_ICOUNT_M) |
51114779705SSam Leffler 		 ((12 << ADCSAT_THRESH_S) & ADCSAT_THRESH_M));
51214779705SSam Leffler 
51314779705SSam Leffler 	/* Wait for AGC changes to be enacted */
51414779705SSam Leffler 	OS_DELAY(20);
51514779705SSam Leffler 
51614779705SSam Leffler 	/*
51714779705SSam Leffler 	 * We disable RF mix/gain stages for the PGA to avoid a
51814779705SSam Leffler 	 * race condition that will occur with receiving a frame
51914779705SSam Leffler 	 * and performing the AGC calibration.  This will be
52014779705SSam Leffler 	 * re-enabled at the end of offset cal.  We turn off AGC
52114779705SSam Leffler 	 * writes during this write as it will go over the analog bus.
52214779705SSam Leffler 	 */
52314779705SSam Leffler 	OS_REG_WRITE(ah, 0x9808, OS_REG_READ(ah, 0x9808) | 0x08000000);
52414779705SSam Leffler 	OS_DELAY(10);		 /* wait for the AGC traffic to cease */
52514779705SSam Leffler 	OS_REG_WRITE(ah, 0x98D4, 0x21);
52614779705SSam Leffler 	OS_REG_WRITE(ah, 0x9808, OS_REG_READ(ah, 0x9808) & (~0x08000000));
52714779705SSam Leffler 
52814779705SSam Leffler 	/* wait to make sure that additional AGC traffic has quiesced */
52914779705SSam Leffler 	OS_DELAY(1000);
53014779705SSam Leffler 
53114779705SSam Leffler 	/* AGC calibration (this was added to make the NF threshold check work) */
53214779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY_AGCCTL,
53314779705SSam Leffler 		 OS_REG_READ(ah, AR_PHY_AGCCTL) | AR_PHY_AGC_CAL);
5343a4a1441SRui Paulo 	if (!ath_hal_wait(ah, AR_PHY_AGCCTL, AR_PHY_AGC_CAL, 0)) {
53514779705SSam Leffler 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: AGC calibration timeout\n",
53614779705SSam Leffler 		    __func__);
5373a4a1441SRui Paulo 	}
53814779705SSam Leffler 
53914779705SSam Leffler 	/* Rewrite our AGC values we stored off earlier (return AGC to normal operation) */
54014779705SSam Leffler 	OS_REG_WRITE(ah, 0x9858, reg9858);
54114779705SSam Leffler 	OS_REG_WRITE(ah, 0x985c, reg985c);
54214779705SSam Leffler 	OS_REG_WRITE(ah, 0x9868, reg9868);
54314779705SSam Leffler 
54414779705SSam Leffler 	/* Perform noise floor and set status */
54514779705SSam Leffler 	if (!ar5210CalNoiseFloor(ah, ichan)) {
54614779705SSam Leffler 		/*
54714779705SSam Leffler 		 * Delay 5ms before retrying the noise floor -
54814779705SSam Leffler 		 * just to make sure.  We're in an error
54914779705SSam Leffler 		 * condition here
55014779705SSam Leffler 		 */
55114779705SSam Leffler 		HALDEBUG(ah, HAL_DEBUG_NFCAL | HAL_DEBUG_PERCAL,
55214779705SSam Leffler 		    "%s: Performing 2nd Noise Cal\n", __func__);
55314779705SSam Leffler 		OS_DELAY(5000);
55414779705SSam Leffler 		if (!ar5210CalNoiseFloor(ah, ichan))
55559efa8b5SSam Leffler 			chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
55614779705SSam Leffler 	}
55714779705SSam Leffler 
55814779705SSam Leffler 	/* Clear tx and rx disable bit */
559143cfad7SAdrian Chadd 	ar5210UpdateDiagReg(ah,
56014779705SSam Leffler 		 OS_REG_READ(ah, AR_DIAG_SW) & ~(AR_DIAG_SW_DIS_TX | AR_DIAG_SW_DIS_RX));
56114779705SSam Leffler 
56214779705SSam Leffler 	/* Re-enable Beacons */
56314779705SSam Leffler 	OS_REG_WRITE(ah, AR_BEACON, regBeacon);
56414779705SSam Leffler 
56514779705SSam Leffler 	*isCalDone = AH_TRUE;
56614779705SSam Leffler 
56714779705SSam Leffler 	return AH_TRUE;
56814779705SSam Leffler }
56914779705SSam Leffler 
57014779705SSam Leffler HAL_BOOL
ar5210PerCalibration(struct ath_hal * ah,struct ieee80211_channel * chan,HAL_BOOL * isIQdone)57159efa8b5SSam Leffler ar5210PerCalibration(struct ath_hal *ah, struct ieee80211_channel *chan,
57259efa8b5SSam Leffler 	HAL_BOOL *isIQdone)
57314779705SSam Leffler {
57414779705SSam Leffler 	return ar5210PerCalibrationN(ah,  chan, 0x1, AH_TRUE, isIQdone);
57514779705SSam Leffler }
57614779705SSam Leffler 
57714779705SSam Leffler HAL_BOOL
ar5210ResetCalValid(struct ath_hal * ah,const struct ieee80211_channel * chan)57859efa8b5SSam Leffler ar5210ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *chan)
57914779705SSam Leffler {
58014779705SSam Leffler 	return AH_TRUE;
58114779705SSam Leffler }
58214779705SSam Leffler 
58314779705SSam Leffler /*
58414779705SSam Leffler  * Writes the given reset bit mask into the reset register
58514779705SSam Leffler  */
58614779705SSam Leffler static HAL_BOOL
ar5210SetResetReg(struct ath_hal * ah,uint32_t resetMask,u_int delay)58714779705SSam Leffler ar5210SetResetReg(struct ath_hal *ah, uint32_t resetMask, u_int delay)
58814779705SSam Leffler {
58914779705SSam Leffler 	uint32_t mask = resetMask ? resetMask : ~0;
59014779705SSam Leffler 	HAL_BOOL rt;
59114779705SSam Leffler 
59214779705SSam Leffler 	OS_REG_WRITE(ah, AR_RC, resetMask);
59314779705SSam Leffler 	/* need to wait at least 128 clocks when reseting PCI before read */
59414779705SSam Leffler 	OS_DELAY(delay);
59514779705SSam Leffler 
59614779705SSam Leffler 	resetMask &= AR_RC_RPCU | AR_RC_RDMA | AR_RC_RPHY | AR_RC_RMAC;
59714779705SSam Leffler 	mask &= AR_RC_RPCU | AR_RC_RDMA | AR_RC_RPHY | AR_RC_RMAC;
59814779705SSam Leffler 	rt = ath_hal_wait(ah, AR_RC, mask, resetMask);
59914779705SSam Leffler         if ((resetMask & AR_RC_RMAC) == 0) {
60014779705SSam Leffler 		if (isBigEndian()) {
60114779705SSam Leffler 			/*
602a47f39daSAdrian Chadd 			 * Set CFG, little-endian for descriptor accesses.
60314779705SSam Leffler 			 */
604a47f39daSAdrian Chadd 			mask = INIT_CONFIG_STATUS | AR_CFG_SWTD | AR_CFG_SWRD;
605a47f39daSAdrian Chadd 			OS_REG_WRITE(ah, AR_CFG, mask);
60614779705SSam Leffler 		} else
60714779705SSam Leffler 			OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS);
60814779705SSam Leffler 	}
60914779705SSam Leffler 	return rt;
61014779705SSam Leffler }
61114779705SSam Leffler 
61214779705SSam Leffler /*
61314779705SSam Leffler  * Returns: the pcdac value
61414779705SSam Leffler  */
61514779705SSam Leffler static uint8_t
getPcdac(struct ath_hal * ah,const struct tpcMap * pRD,uint8_t dBm)61614779705SSam Leffler getPcdac(struct ath_hal *ah, const struct tpcMap *pRD, uint8_t dBm)
61714779705SSam Leffler {
61814779705SSam Leffler 	int32_t	 i;
61914779705SSam Leffler 	int useNextEntry = AH_FALSE;
62014779705SSam Leffler 	uint32_t interp;
62114779705SSam Leffler 
62214779705SSam Leffler 	for (i = AR_TP_SCALING_ENTRIES - 1; i >= 0; i--) {
62314779705SSam Leffler 		/* Check for exact entry */
62414779705SSam Leffler 		if (dBm == AR_I2DBM(i)) {
62514779705SSam Leffler 			if (pRD->pcdac[i] != 63)
62614779705SSam Leffler 				return pRD->pcdac[i];
62714779705SSam Leffler 			useNextEntry = AH_TRUE;
62814779705SSam Leffler 		} else if (dBm + 1 == AR_I2DBM(i) && i > 0) {
62914779705SSam Leffler 			/* Interpolate for between entry with a logish scale */
63014779705SSam Leffler 			if (pRD->pcdac[i] != 63 && pRD->pcdac[i-1] != 63) {
63114779705SSam Leffler 				interp = (350 * (pRD->pcdac[i] - pRD->pcdac[i-1])) + 999;
63214779705SSam Leffler 				interp = (interp / 1000) + pRD->pcdac[i-1];
63314779705SSam Leffler 				return interp;
63414779705SSam Leffler 			}
63514779705SSam Leffler 			useNextEntry = AH_TRUE;
63614779705SSam Leffler 		} else if (useNextEntry == AH_TRUE) {
63714779705SSam Leffler 			/* Grab the next lowest */
63814779705SSam Leffler 			if (pRD->pcdac[i] != 63)
63914779705SSam Leffler 				return pRD->pcdac[i];
64014779705SSam Leffler 		}
64114779705SSam Leffler 	}
64214779705SSam Leffler 
64314779705SSam Leffler 	/* Return the lowest Entry if we haven't returned */
64414779705SSam Leffler 	for (i = 0; i < AR_TP_SCALING_ENTRIES; i++)
64514779705SSam Leffler 		if (pRD->pcdac[i] != 63)
64614779705SSam Leffler 			return pRD->pcdac[i];
64714779705SSam Leffler 
64814779705SSam Leffler 	/* No value to return from table */
64914779705SSam Leffler #ifdef AH_DEBUG
65014779705SSam Leffler 	ath_hal_printf(ah, "%s: empty transmit power table?\n", __func__);
65114779705SSam Leffler #endif
65214779705SSam Leffler 	return 1;
65314779705SSam Leffler }
65414779705SSam Leffler 
65514779705SSam Leffler /*
65614779705SSam Leffler  * Find or interpolates the gainF value from the table ptr.
65714779705SSam Leffler  */
65814779705SSam Leffler static uint8_t
getGainF(struct ath_hal * ah,const struct tpcMap * pRD,uint8_t pcdac,uint8_t * dBm)65914779705SSam Leffler getGainF(struct ath_hal *ah, const struct tpcMap *pRD,
66014779705SSam Leffler 	uint8_t pcdac, uint8_t *dBm)
66114779705SSam Leffler {
66214779705SSam Leffler 	uint32_t interp;
66314779705SSam Leffler 	int low, high, i;
66414779705SSam Leffler 
66514779705SSam Leffler 	low = high = -1;
66614779705SSam Leffler 
66714779705SSam Leffler 	for (i = 0; i < AR_TP_SCALING_ENTRIES; i++) {
66814779705SSam Leffler 		if(pRD->pcdac[i] == 63)
66914779705SSam Leffler 			continue;
67014779705SSam Leffler 		if (pcdac == pRD->pcdac[i]) {
67114779705SSam Leffler 			*dBm = AR_I2DBM(i);
67214779705SSam Leffler 			return pRD->gainF[i];  /* Exact Match */
67314779705SSam Leffler 		}
67414779705SSam Leffler 		if (pcdac > pRD->pcdac[i])
67514779705SSam Leffler 			low = i;
67614779705SSam Leffler 		if (pcdac < pRD->pcdac[i]) {
67714779705SSam Leffler 			high = i;
67814779705SSam Leffler 			if (low == -1) {
67914779705SSam Leffler 				*dBm = AR_I2DBM(i);
68014779705SSam Leffler 				/* PCDAC is lower than lowest setting */
68114779705SSam Leffler 				return pRD->gainF[i];
68214779705SSam Leffler 			}
68314779705SSam Leffler 			break;
68414779705SSam Leffler 		}
68514779705SSam Leffler 	}
68614779705SSam Leffler 	if (i >= AR_TP_SCALING_ENTRIES && low == -1) {
68714779705SSam Leffler 		/* No settings were found */
68814779705SSam Leffler #ifdef AH_DEBUG
68914779705SSam Leffler 		ath_hal_printf(ah,
69014779705SSam Leffler 			"%s: no valid entries in the pcdac table: %d\n",
69114779705SSam Leffler 			__func__, pcdac);
69214779705SSam Leffler #endif
69314779705SSam Leffler 		return 63;
69414779705SSam Leffler 	}
69514779705SSam Leffler 	if (i >= AR_TP_SCALING_ENTRIES) {
69614779705SSam Leffler 		/* PCDAC setting was above the max setting in the table */
69714779705SSam Leffler 		*dBm = AR_I2DBM(low);
69814779705SSam Leffler 		return pRD->gainF[low];
69914779705SSam Leffler 	}
70014779705SSam Leffler 	/* Only exact if table has no missing entries */
70114779705SSam Leffler 	*dBm = (low + high) + 3;
70214779705SSam Leffler 
70314779705SSam Leffler 	/*
70414779705SSam Leffler 	 * Perform interpolation between low and high values to find gainF
70514779705SSam Leffler 	 * linearly scale the pcdac between low and high
70614779705SSam Leffler 	 */
70714779705SSam Leffler 	interp = ((pcdac - pRD->pcdac[low]) * 1000) /
70814779705SSam Leffler 		  (pRD->pcdac[high] - pRD->pcdac[low]);
70914779705SSam Leffler 	/*
71014779705SSam Leffler 	 * Multiply the scale ratio by the gainF difference
71114779705SSam Leffler 	 * (plus a rnd up factor)
71214779705SSam Leffler 	 */
71314779705SSam Leffler 	interp = ((interp * (pRD->gainF[high] - pRD->gainF[low])) + 999) / 1000;
71414779705SSam Leffler 
71514779705SSam Leffler 	/* Add ratioed gain_f to low gain_f value */
71614779705SSam Leffler 	return interp + pRD->gainF[low];
71714779705SSam Leffler }
71814779705SSam Leffler 
71914779705SSam Leffler HAL_BOOL
ar5210SetTxPowerLimit(struct ath_hal * ah,uint32_t limit)72014779705SSam Leffler ar5210SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
72114779705SSam Leffler {
72214779705SSam Leffler 	AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, AR5210_MAX_RATE_POWER);
72314779705SSam Leffler 	/* XXX flush to h/w */
72414779705SSam Leffler 	return AH_TRUE;
72514779705SSam Leffler }
72614779705SSam Leffler 
72714779705SSam Leffler /*
72814779705SSam Leffler  * Get TXPower values and set them in the radio
72914779705SSam Leffler  */
73014779705SSam Leffler static HAL_BOOL
setupPowerSettings(struct ath_hal * ah,const struct ieee80211_channel * chan,uint8_t cp[17])73159efa8b5SSam Leffler setupPowerSettings(struct ath_hal *ah, const struct ieee80211_channel *chan,
73259efa8b5SSam Leffler 	uint8_t cp[17])
73314779705SSam Leffler {
73459efa8b5SSam Leffler 	uint16_t freq = ath_hal_gethwchannel(ah, chan);
73514779705SSam Leffler 	const HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom;
73614779705SSam Leffler 	uint8_t gainFRD, gainF36, gainF48, gainF54;
73714779705SSam Leffler 	uint8_t dBmRD, dBm36, dBm48, dBm54, dontcare;
73814779705SSam Leffler 	uint32_t rd, group;
73914779705SSam Leffler 	const struct tpcMap  *pRD;
74014779705SSam Leffler 
74114779705SSam Leffler 	/* Set OB/DB Values regardless of channel */
74214779705SSam Leffler 	cp[15] = (ee->ee_biasCurrents >> 4) & 0x7;
74314779705SSam Leffler 	cp[16] = ee->ee_biasCurrents & 0x7;
74414779705SSam Leffler 
74559efa8b5SSam Leffler 	if (freq < 5170 || freq > 5320) {
74614779705SSam Leffler 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u\n",
74759efa8b5SSam Leffler 		    __func__, freq);
74814779705SSam Leffler 		return AH_FALSE;
74914779705SSam Leffler 	}
75014779705SSam Leffler 
75114779705SSam Leffler 	HALASSERT(ee->ee_version >= AR_EEPROM_VER1 &&
75214779705SSam Leffler 	    ee->ee_version < AR_EEPROM_VER3);
75314779705SSam Leffler 
75414779705SSam Leffler 	/* Match regulatory domain */
75514779705SSam Leffler 	for (rd = 0; rd < AR_REG_DOMAINS_MAX; rd++)
75614779705SSam Leffler 		if (AH_PRIVATE(ah)->ah_currentRD == ee->ee_regDomain[rd])
75714779705SSam Leffler 			break;
75814779705SSam Leffler 	if (rd == AR_REG_DOMAINS_MAX) {
75914779705SSam Leffler #ifdef AH_DEBUG
76014779705SSam Leffler 		ath_hal_printf(ah,
76114779705SSam Leffler 			"%s: no calibrated regulatory domain matches the "
76214779705SSam Leffler 			"current regularly domain (0x%0x)\n", __func__,
76314779705SSam Leffler 			AH_PRIVATE(ah)->ah_currentRD);
76414779705SSam Leffler #endif
76514779705SSam Leffler 		return AH_FALSE;
76614779705SSam Leffler 	}
76759efa8b5SSam Leffler 	group = ((freq - 5170) / 10);
76814779705SSam Leffler 
76914779705SSam Leffler 	if (group > 11) {
77014779705SSam Leffler 		/* Pull 5.29 into the 5.27 group */
77114779705SSam Leffler 		group--;
77214779705SSam Leffler 	}
77314779705SSam Leffler 
77414779705SSam Leffler 	/* Integer divide will set group from 0 to 4 */
77514779705SSam Leffler 	group = group / 3;
77614779705SSam Leffler 	pRD   = &ee->ee_tpc[group];
77714779705SSam Leffler 
77814779705SSam Leffler 	/* Set PC DAC Values */
77914779705SSam Leffler 	cp[14] = pRD->regdmn[rd];
78014779705SSam Leffler 	cp[9]  = AH_MIN(pRD->regdmn[rd], pRD->rate36);
78114779705SSam Leffler 	cp[8]  = AH_MIN(pRD->regdmn[rd], pRD->rate48);
78214779705SSam Leffler 	cp[7]  = AH_MIN(pRD->regdmn[rd], pRD->rate54);
78314779705SSam Leffler 
78414779705SSam Leffler 	/* Find Corresponding gainF values for RD, 36, 48, 54 */
78514779705SSam Leffler 	gainFRD = getGainF(ah, pRD, pRD->regdmn[rd], &dBmRD);
78614779705SSam Leffler 	gainF36 = getGainF(ah, pRD, cp[9], &dBm36);
78714779705SSam Leffler 	gainF48 = getGainF(ah, pRD, cp[8], &dBm48);
78814779705SSam Leffler 	gainF54 = getGainF(ah, pRD, cp[7], &dBm54);
78914779705SSam Leffler 
79014779705SSam Leffler 	/* Power Scale if requested */
79114779705SSam Leffler 	if (AH_PRIVATE(ah)->ah_tpScale != HAL_TP_SCALE_MAX) {
79214779705SSam Leffler 		static const uint16_t tpcScaleReductionTable[5] =
79314779705SSam Leffler 			{ 0, 3, 6, 9, AR5210_MAX_RATE_POWER };
79414779705SSam Leffler 		uint16_t tpScale;
79514779705SSam Leffler 
79614779705SSam Leffler 		tpScale = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale];
79714779705SSam Leffler 		if (dBmRD < tpScale+3)
79814779705SSam Leffler 			dBmRD = 3;		/* min */
79914779705SSam Leffler 		else
80014779705SSam Leffler 			dBmRD -= tpScale;
80114779705SSam Leffler 		cp[14]  = getPcdac(ah, pRD, dBmRD);
80214779705SSam Leffler 		gainFRD = getGainF(ah, pRD, cp[14], &dontcare);
80314779705SSam Leffler 		dBm36   = AH_MIN(dBm36, dBmRD);
80414779705SSam Leffler 		cp[9]   = getPcdac(ah, pRD, dBm36);
80514779705SSam Leffler 		gainF36 = getGainF(ah, pRD, cp[9], &dontcare);
80614779705SSam Leffler 		dBm48   = AH_MIN(dBm48, dBmRD);
80714779705SSam Leffler 		cp[8]   = getPcdac(ah, pRD, dBm48);
80814779705SSam Leffler 		gainF48 = getGainF(ah, pRD, cp[8], &dontcare);
80914779705SSam Leffler 		dBm54   = AH_MIN(dBm54, dBmRD);
81014779705SSam Leffler 		cp[7]   = getPcdac(ah, pRD, dBm54);
81114779705SSam Leffler 		gainF54 = getGainF(ah, pRD, cp[7], &dontcare);
81214779705SSam Leffler 	}
81314779705SSam Leffler 	/* Record current dBm at rate 6 */
81414779705SSam Leffler 	AH_PRIVATE(ah)->ah_maxPowerLevel = 2*dBmRD;
81514779705SSam Leffler 
81614779705SSam Leffler 	cp[13] = cp[12] = cp[11] = cp[10] = cp[14];
81714779705SSam Leffler 
81814779705SSam Leffler 	/* Set GainF Values */
81914779705SSam Leffler 	cp[0] = gainFRD - gainF54;
82014779705SSam Leffler 	cp[1] = gainFRD - gainF48;
82114779705SSam Leffler 	cp[2] = gainFRD - gainF36;
82214779705SSam Leffler 	/* 9, 12, 18, 24 have no gain_delta from 6 */
82314779705SSam Leffler 	cp[3] = cp[4] = cp[5] = cp[6] = 0;
82414779705SSam Leffler 	return AH_TRUE;
82514779705SSam Leffler }
82614779705SSam Leffler 
82714779705SSam Leffler /*
82814779705SSam Leffler  * Places the device in and out of reset and then places sane
82914779705SSam Leffler  * values in the registers based on EEPROM config, initialization
83014779705SSam Leffler  * vectors (as determined by the mode), and station configuration
83114779705SSam Leffler  */
83214779705SSam Leffler HAL_BOOL
ar5210SetTransmitPower(struct ath_hal * ah,const struct ieee80211_channel * chan)83359efa8b5SSam Leffler ar5210SetTransmitPower(struct ath_hal *ah, const struct ieee80211_channel *chan)
83414779705SSam Leffler {
83514779705SSam Leffler #define	N(a)	(sizeof (a) / sizeof (a[0]))
83614779705SSam Leffler 	static const uint32_t pwr_regs_start[17] = {
83714779705SSam Leffler 		0x00000000, 0x00000000, 0x00000000,
83814779705SSam Leffler 		0x00000000, 0x00000000, 0xf0000000,
83914779705SSam Leffler 		0xcc000000, 0x00000000, 0x00000000,
84014779705SSam Leffler 		0x00000000, 0x0a000000, 0x000000e2,
84114779705SSam Leffler 		0x0a000020, 0x01000002, 0x01000018,
84214779705SSam Leffler 		0x40000000, 0x00000418
84314779705SSam Leffler 	};
84414779705SSam Leffler 	uint16_t i;
84514779705SSam Leffler 	uint8_t cp[sizeof(ar5k0007_pwrSettings)];
84614779705SSam Leffler 	uint32_t pwr_regs[17];
84714779705SSam Leffler 
84814779705SSam Leffler 	OS_MEMCPY(pwr_regs, pwr_regs_start, sizeof(pwr_regs));
84914779705SSam Leffler 	OS_MEMCPY(cp, ar5k0007_pwrSettings, sizeof(cp));
85014779705SSam Leffler 
85114779705SSam Leffler 	/* Check the EEPROM tx power calibration settings */
85214779705SSam Leffler 	if (!setupPowerSettings(ah, chan, cp)) {
85314779705SSam Leffler #ifdef AH_DEBUG
85414779705SSam Leffler 		ath_hal_printf(ah, "%s: unable to setup power settings\n",
85514779705SSam Leffler 			__func__);
85614779705SSam Leffler #endif
85714779705SSam Leffler 		return AH_FALSE;
85814779705SSam Leffler 	}
85914779705SSam Leffler 	if (cp[15] < 1 || cp[15] > 5) {
86014779705SSam Leffler #ifdef AH_DEBUG
86114779705SSam Leffler 		ath_hal_printf(ah, "%s: OB out of range (%u)\n",
86214779705SSam Leffler 			__func__, cp[15]);
86314779705SSam Leffler #endif
86414779705SSam Leffler 		return AH_FALSE;
86514779705SSam Leffler 	}
86614779705SSam Leffler 	if (cp[16] < 1 || cp[16] > 5) {
86714779705SSam Leffler #ifdef AH_DEBUG
86814779705SSam Leffler 		ath_hal_printf(ah, "%s: DB out of range (%u)\n",
86914779705SSam Leffler 			__func__, cp[16]);
87014779705SSam Leffler #endif
87114779705SSam Leffler 		return AH_FALSE;
87214779705SSam Leffler 	}
87314779705SSam Leffler 
87414779705SSam Leffler 	/* reverse bits of the transmit power array */
87514779705SSam Leffler 	for (i = 0; i < 7; i++)
87614779705SSam Leffler 		cp[i] = ath_hal_reverseBits(cp[i], 5);
87714779705SSam Leffler 	for (i = 7; i < 15; i++)
87814779705SSam Leffler 		cp[i] = ath_hal_reverseBits(cp[i], 6);
87914779705SSam Leffler 
88014779705SSam Leffler 	/* merge transmit power values into the register - quite gross */
88114779705SSam Leffler 	pwr_regs[0] |= ((cp[1] << 5) & 0xE0) | (cp[0] & 0x1F);
88214779705SSam Leffler 	pwr_regs[1] |= ((cp[3] << 7) & 0x80) | ((cp[2] << 2) & 0x7C) |
88314779705SSam Leffler 			((cp[1] >> 3) & 0x03);
88414779705SSam Leffler 	pwr_regs[2] |= ((cp[4] << 4) & 0xF0) | ((cp[3] >> 1) & 0x0F);
88514779705SSam Leffler 	pwr_regs[3] |= ((cp[6] << 6) & 0xC0) | ((cp[5] << 1) & 0x3E) |
88614779705SSam Leffler 		       ((cp[4] >> 4) & 0x01);
88714779705SSam Leffler 	pwr_regs[4] |= ((cp[7] << 3) & 0xF8) | ((cp[6] >> 2) & 0x07);
88814779705SSam Leffler 	pwr_regs[5] |= ((cp[9] << 7) & 0x80) | ((cp[8] << 1) & 0x7E) |
88914779705SSam Leffler 			((cp[7] >> 5) & 0x01);
89014779705SSam Leffler 	pwr_regs[6] |= ((cp[10] << 5) & 0xE0) | ((cp[9] >> 1) & 0x1F);
89114779705SSam Leffler 	pwr_regs[7] |= ((cp[11] << 3) & 0xF8) | ((cp[10] >> 3) & 0x07);
89214779705SSam Leffler 	pwr_regs[8] |= ((cp[12] << 1) & 0x7E) | ((cp[11] >> 5) & 0x01);
89314779705SSam Leffler 	pwr_regs[9] |= ((cp[13] << 5) & 0xE0);
89414779705SSam Leffler 	pwr_regs[10] |= ((cp[14] << 3) & 0xF8) | ((cp[13] >> 3) & 0x07);
89514779705SSam Leffler 	pwr_regs[11] |= ((cp[14] >> 5) & 0x01);
89614779705SSam Leffler 
89714779705SSam Leffler 	/* Set OB */
89814779705SSam Leffler 	pwr_regs[8] |=  (ath_hal_reverseBits(cp[15], 3) << 7) & 0x80;
89914779705SSam Leffler 	pwr_regs[9] |=  (ath_hal_reverseBits(cp[15], 3) >> 1) & 0x03;
90014779705SSam Leffler 
90114779705SSam Leffler 	/* Set DB */
90214779705SSam Leffler 	pwr_regs[9] |=  (ath_hal_reverseBits(cp[16], 3) << 2) & 0x1C;
90314779705SSam Leffler 
90414779705SSam Leffler 	/* Write the registers */
90514779705SSam Leffler 	for (i = 0; i < N(pwr_regs)-1; i++)
90614779705SSam Leffler 		OS_REG_WRITE(ah, 0x0000989c, pwr_regs[i]);
90714779705SSam Leffler 	/* last write is a flush */
90814779705SSam Leffler 	OS_REG_WRITE(ah, 0x000098d4, pwr_regs[i]);
90914779705SSam Leffler 
91014779705SSam Leffler 	return AH_TRUE;
91114779705SSam Leffler #undef N
91214779705SSam Leffler }
91314779705SSam Leffler 
91414779705SSam Leffler /*
91514779705SSam Leffler  * Takes the MHz channel value and sets the Channel value
91614779705SSam Leffler  *
91714779705SSam Leffler  * ASSUMES: Writes enabled to analog bus before AGC is active
91814779705SSam Leffler  *   or by disabling the AGC.
91914779705SSam Leffler  */
92014779705SSam Leffler static HAL_BOOL
ar5210SetChannel(struct ath_hal * ah,struct ieee80211_channel * chan)92159efa8b5SSam Leffler ar5210SetChannel(struct ath_hal *ah, struct ieee80211_channel *chan)
92214779705SSam Leffler {
92359efa8b5SSam Leffler 	uint16_t freq = ath_hal_gethwchannel(ah, chan);
92414779705SSam Leffler 	uint32_t data;
92514779705SSam Leffler 
92614779705SSam Leffler 	/* Set the Channel */
92759efa8b5SSam Leffler 	data = ath_hal_reverseBits((freq - 5120)/10, 5);
92814779705SSam Leffler 	data = (data << 1) | 0x41;
92914779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY(0x27), data);
93014779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY(0x30), 0);
93114779705SSam Leffler 	AH_PRIVATE(ah)->ah_curchan = chan;
93214779705SSam Leffler 	return AH_TRUE;
93314779705SSam Leffler }
93414779705SSam Leffler 
93514779705SSam Leffler int16_t
ar5210GetNoiseFloor(struct ath_hal * ah)93614779705SSam Leffler ar5210GetNoiseFloor(struct ath_hal *ah)
93714779705SSam Leffler {
93814779705SSam Leffler 	int16_t nf;
93914779705SSam Leffler 
94014779705SSam Leffler 	nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff;
94114779705SSam Leffler 	if (nf & 0x100)
94214779705SSam Leffler 		nf = 0 - ((nf ^ 0x1ff) + 1);
94314779705SSam Leffler 	return nf;
94414779705SSam Leffler }
94514779705SSam Leffler 
94614779705SSam Leffler #define NORMAL_NF_THRESH (-72)
94714779705SSam Leffler /*
94814779705SSam Leffler  * Peform the noisefloor calibration and check for
94914779705SSam Leffler  * any constant channel interference
95014779705SSam Leffler  *
95114779705SSam Leffler  * Returns: TRUE for a successful noise floor calibration; else FALSE
95214779705SSam Leffler  */
95314779705SSam Leffler HAL_BOOL
ar5210CalNoiseFloor(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan)95459efa8b5SSam Leffler ar5210CalNoiseFloor(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
95514779705SSam Leffler {
95614779705SSam Leffler 	int32_t nf, nfLoops;
95714779705SSam Leffler 
95814779705SSam Leffler 	/* Calibrate the noise floor */
95914779705SSam Leffler 	OS_REG_WRITE(ah, AR_PHY_AGCCTL,
96014779705SSam Leffler 		OS_REG_READ(ah, AR_PHY_AGCCTL) | AR_PHY_AGC_NF);
96114779705SSam Leffler 
96214779705SSam Leffler 	/* Do not read noise floor until it has done the first update */
96314779705SSam Leffler 	if (!ath_hal_wait(ah, AR_PHY_AGCCTL, AR_PHY_AGC_NF, 0)) {
96414779705SSam Leffler #ifdef ATH_HAL_DEBUG
96514779705SSam Leffler 		ath_hal_printf(ah, " -PHY NF Reg state: 0x%x\n",
96614779705SSam Leffler 			OS_REG_READ(ah, AR_PHY_AGCCTL));
96714779705SSam Leffler 		ath_hal_printf(ah, " -MAC Reset Reg state: 0x%x\n",
96814779705SSam Leffler 			OS_REG_READ(ah, AR_RC));
96914779705SSam Leffler 		ath_hal_printf(ah, " -PHY Active Reg state: 0x%x\n",
97014779705SSam Leffler 			OS_REG_READ(ah, AR_PHY_ACTIVE));
97114779705SSam Leffler #endif /* ATH_HAL_DEBUG */
97214779705SSam Leffler 		return AH_FALSE;
97314779705SSam Leffler 	}
97414779705SSam Leffler 
97514779705SSam Leffler 	nf = 0;
97614779705SSam Leffler 	/* Keep checking until the floor is below the threshold or the nf is done */
97714779705SSam Leffler 	for (nfLoops = 0; ((nfLoops < 21) && (nf > NORMAL_NF_THRESH)); nfLoops++) {
97814779705SSam Leffler 		OS_DELAY(1000); /* Sleep for 1 ms */
97914779705SSam Leffler 		nf = ar5210GetNoiseFloor(ah);
98014779705SSam Leffler 	}
98114779705SSam Leffler 
98214779705SSam Leffler 	if (nf > NORMAL_NF_THRESH) {
98314779705SSam Leffler 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: Bad noise cal %d\n",
98414779705SSam Leffler 		    __func__, nf);
98559efa8b5SSam Leffler 		ichan->rawNoiseFloor = 0;
98614779705SSam Leffler 		return AH_FALSE;
98714779705SSam Leffler 	}
98859efa8b5SSam Leffler 	ichan->rawNoiseFloor = nf;
98914779705SSam Leffler 	return AH_TRUE;
99014779705SSam Leffler }
99114779705SSam Leffler 
99214779705SSam Leffler /*
99314779705SSam Leffler  * Adjust NF based on statistical values for 5GHz frequencies.
99414779705SSam Leffler  */
99514779705SSam Leffler int16_t
ar5210GetNfAdjust(struct ath_hal * ah,const HAL_CHANNEL_INTERNAL * c)99614779705SSam Leffler ar5210GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c)
99714779705SSam Leffler {
99814779705SSam Leffler 	return 0;
99914779705SSam Leffler }
100014779705SSam Leffler 
100114779705SSam Leffler HAL_RFGAIN
ar5210GetRfgain(struct ath_hal * ah)100214779705SSam Leffler ar5210GetRfgain(struct ath_hal *ah)
100314779705SSam Leffler {
100414779705SSam Leffler 	return HAL_RFGAIN_INACTIVE;
100514779705SSam Leffler }
1006