1189747Ssam/* 2189747Ssam * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting 3189747Ssam * Copyright (c) 2008 Atheros Communications, Inc. 4189747Ssam * 5189747Ssam * Permission to use, copy, modify, and/or distribute this software for any 6189747Ssam * purpose with or without fee is hereby granted, provided that the above 7189747Ssam * copyright notice and this permission notice appear in all copies. 8189747Ssam * 9189747Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10189747Ssam * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11189747Ssam * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12189747Ssam * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13189747Ssam * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14189747Ssam * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15189747Ssam * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16189747Ssam * 17189747Ssam * $FreeBSD$ 18189747Ssam */ 19189747Ssam#include "opt_ah.h" 20189747Ssam 21189747Ssam/* 22189747Ssam * NB: Merlin and later have a simpler RF backend. 23189747Ssam */ 24189747Ssam#include "ah.h" 25189747Ssam#include "ah_internal.h" 26189747Ssam 27189747Ssam#include "ah_eeprom_v14.h" 28189747Ssam 29217631Sadrian#include "ar9002/ar9280.h" 30189747Ssam#include "ar5416/ar5416reg.h" 31189747Ssam#include "ar5416/ar5416phy.h" 32189747Ssam 33189747Ssam#define N(a) (sizeof(a)/sizeof(a[0])) 34189747Ssam 35189747Ssamstruct ar9280State { 36189747Ssam RF_HAL_FUNCS base; /* public state, must be first */ 37189747Ssam uint16_t pcdacTable[1]; /* XXX */ 38189747Ssam}; 39189747Ssam#define AR9280(ah) ((struct ar9280State *) AH5212(ah)->ah_rfHal) 40189747Ssam 41189747Ssamstatic HAL_BOOL ar9280GetChannelMaxMinPower(struct ath_hal *, 42189747Ssam const struct ieee80211_channel *, int16_t *maxPow,int16_t *minPow); 43189747Ssamint16_t ar9280GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c); 44189747Ssam 45189747Ssamstatic void 46189747Ssamar9280WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex, 47189747Ssam int writes) 48189747Ssam{ 49189747Ssam (void) ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_bb_rfgain, 50189747Ssam freqIndex, writes); 51189747Ssam} 52189747Ssam 53189747Ssam/* 54189747Ssam * Take the MHz channel value and set the Channel value 55189747Ssam * 56189747Ssam * ASSUMES: Writes enabled to analog bus 57189747Ssam * 58189747Ssam * Actual Expression, 59189747Ssam * 60189747Ssam * For 2GHz channel, 61189747Ssam * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) 62189747Ssam * (freq_ref = 40MHz) 63189747Ssam * 64189747Ssam * For 5GHz channel, 65189747Ssam * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10) 66189747Ssam * (freq_ref = 40MHz/(24>>amodeRefSel)) 67189747Ssam * 68189747Ssam * For 5GHz channels which are 5MHz spaced, 69189747Ssam * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) 70189747Ssam * (freq_ref = 40MHz) 71189747Ssam */ 72189747Ssamstatic HAL_BOOL 73189747Ssamar9280SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan) 74189747Ssam{ 75189747Ssam uint16_t bMode, fracMode, aModeRefSel = 0; 76189747Ssam uint32_t freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0; 77189747Ssam CHAN_CENTERS centers; 78189747Ssam uint32_t refDivA = 24; 79224519Sadrian uint8_t frac_n_5g; 80189747Ssam 81189747Ssam OS_MARK(ah, AH_MARK_SETCHANNEL, chan->ic_freq); 82189747Ssam 83189747Ssam ar5416GetChannelCenters(ah, chan, ¢ers); 84189747Ssam freq = centers.synth_center; 85189747Ssam 86189747Ssam reg32 = OS_REG_READ(ah, AR_PHY_SYNTH_CONTROL); 87189747Ssam reg32 &= 0xc0000000; 88189747Ssam 89224519Sadrian if (ath_hal_eepromGet(ah, AR_EEP_FRAC_N_5G, &frac_n_5g) != HAL_OK) 90224519Sadrian frac_n_5g = 0; 91224519Sadrian 92189747Ssam if (freq < 4800) { /* 2 GHz, fractional mode */ 93189747Ssam uint32_t txctl; 94189747Ssam 95189747Ssam bMode = 1; 96189747Ssam fracMode = 1; 97189747Ssam aModeRefSel = 0; 98189747Ssam channelSel = (freq * 0x10000)/15; 99189747Ssam 100189747Ssam txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL); 101189747Ssam if (freq == 2484) { 102189747Ssam /* Enable channel spreading for channel 14 */ 103189747Ssam OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, 104189747Ssam txctl | AR_PHY_CCK_TX_CTRL_JAPAN); 105189747Ssam } else { 106189747Ssam OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, 107189747Ssam txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN); 108189747Ssam } 109189747Ssam } else { 110189747Ssam bMode = 0; 111189747Ssam fracMode = 0; 112189747Ssam 113224519Sadrian switch (frac_n_5g) { 114224519Sadrian case 0: 115240449Sadrian /* 116240449Sadrian * Enable fractional mode for half/quarter rate 117240449Sadrian * channels. 118240449Sadrian * 119240449Sadrian * This is from the Linux ath9k code, rather than 120240449Sadrian * the Atheros HAL code. 121240449Sadrian */ 122240449Sadrian if (IEEE80211_IS_CHAN_QUARTER(chan) || 123240449Sadrian IEEE80211_IS_CHAN_HALF(chan)) 124240449Sadrian aModeRefSel = 0; 125240449Sadrian else if ((freq % 20) == 0) { 126224519Sadrian aModeRefSel = 3; 127224519Sadrian } else if ((freq % 10) == 0) { 128224519Sadrian aModeRefSel = 2; 129224519Sadrian } 130224519Sadrian if (aModeRefSel) break; 131224519Sadrian case 1: 132224519Sadrian default: 133189747Ssam aModeRefSel = 0; 134189747Ssam /* Enable 2G (fractional) mode for channels which are 5MHz spaced */ 135189747Ssam 136241195Sadrian /* 137241195Sadrian * Workaround for talking on PSB non-5MHz channels; 138241195Sadrian * the pre-Merlin chips only had a 2.5MHz channel 139241195Sadrian * spacing so some channels aren't reachable. 140241195Sadrian 141241195Sadrian * 142241195Sadrian * This interoperates on the quarter rate channels 143241195Sadrian * with the AR5112 and later RF synths. Please note 144241195Sadrian * that the synthesiser isn't able to completely 145241195Sadrian * accurately represent these frequencies (as the 146241195Sadrian * resolution in this reference is 2.5MHz) and thus 147241195Sadrian * it will be slightly "off centre." This matches 148241195Sadrian * the same slightly incorrect centre frequency 149241195Sadrian * behaviour that the AR5112 and later channel 150241195Sadrian * selection code has. 151241195Sadrian * 152241195Sadrian * This also interoperates with the AR5416 153241195Sadrian * synthesiser modification for programming 154241195Sadrian * fractional frequencies in 5GHz mode. However 155241195Sadrian * that modification is also disabled by default. 156241195Sadrian * 157241195Sadrian * This is disabled because it hasn't been tested for 158241195Sadrian * regulatory compliance and neither have the NICs 159241195Sadrian * which would use it. So if you enable this code, 160241195Sadrian * you must first ensure that you've re-certified the 161241195Sadrian * NICs in question beforehand or you will be 162241195Sadrian * violating your local regulatory rules and breaking 163241195Sadrian * the law. 164241195Sadrian */ 165241195Sadrian#if 0 166241195Sadrian if (freq % 5 == 0) { 167241195Sadrian#endif 168241195Sadrian /* Normal */ 169241195Sadrian fracMode = 1; 170241195Sadrian refDivA = 1; 171241195Sadrian channelSel = (freq * 0x8000)/15; 172241195Sadrian#if 0 173241195Sadrian } else { 174241195Sadrian /* Offset by 500KHz */ 175241195Sadrian uint32_t f, ch, ch2; 176241195Sadrian 177241195Sadrian fracMode = 1; 178241195Sadrian refDivA = 1; 179241195Sadrian 180241195Sadrian /* Calculate the "adjusted" frequency */ 181241195Sadrian f = freq - 2; 182241195Sadrian ch = (((f - 4800) * 10) / 25) + 1; 183241195Sadrian 184241195Sadrian ch2 = ((ch * 25) / 5) + 9600; 185241195Sadrian channelSel = (ch2 * 0x4000) / 15; 186241195Sadrian //ath_hal_printf(ah, 187241195Sadrian // "%s: freq=%d, ch=%d, ch2=%d, " 188241195Sadrian // "channelSel=%d\n", 189241195Sadrian // __func__, freq, ch, ch2, channelSel); 190241195Sadrian } 191241195Sadrian#endif 192241195Sadrian 193189747Ssam /* RefDivA setting */ 194218416Sadrian OS_A_REG_RMW_FIELD(ah, AR_AN_SYNTH9, 195189747Ssam AR_AN_SYNTH9_REFDIVA, refDivA); 196189747Ssam } 197224519Sadrian 198189747Ssam if (!fracMode) { 199189747Ssam ndiv = (freq * (refDivA >> aModeRefSel))/60; 200189747Ssam channelSel = ndiv & 0x1ff; 201189747Ssam channelFrac = (ndiv & 0xfffffe00) * 2; 202189747Ssam channelSel = (channelSel << 17) | channelFrac; 203189747Ssam } 204189747Ssam } 205189747Ssam 206189747Ssam reg32 = reg32 | (bMode << 29) | (fracMode << 28) | 207189747Ssam (aModeRefSel << 26) | (channelSel); 208189747Ssam 209189747Ssam OS_REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); 210189747Ssam 211189747Ssam AH_PRIVATE(ah)->ah_curchan = chan; 212189747Ssam 213189747Ssam return AH_TRUE; 214189747Ssam} 215189747Ssam 216189747Ssam/* 217189747Ssam * Return a reference to the requested RF Bank. 218189747Ssam */ 219189747Ssamstatic uint32_t * 220189747Ssamar9280GetRfBank(struct ath_hal *ah, int bank) 221189747Ssam{ 222189747Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown RF Bank %d requested\n", 223189747Ssam __func__, bank); 224189747Ssam return AH_NULL; 225189747Ssam} 226189747Ssam 227189747Ssam/* 228189747Ssam * Reads EEPROM header info from device structure and programs 229189747Ssam * all rf registers 230189747Ssam */ 231189747Ssamstatic HAL_BOOL 232189747Ssamar9280SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan, 233189747Ssam uint16_t modesIndex, uint16_t *rfXpdGain) 234189747Ssam{ 235189747Ssam return AH_TRUE; /* nothing to do */ 236189747Ssam} 237189747Ssam 238189747Ssam/* 239189747Ssam * Read the transmit power levels from the structures taken from EEPROM 240189747Ssam * Interpolate read transmit power values for this channel 241189747Ssam * Organize the transmit power values into a table for writing into the hardware 242189747Ssam */ 243189747Ssam 244189747Ssamstatic HAL_BOOL 245189747Ssamar9280SetPowerTable(struct ath_hal *ah, int16_t *pPowerMin, int16_t *pPowerMax, 246189747Ssam const struct ieee80211_channel *chan, uint16_t *rfXpdGain) 247189747Ssam{ 248189747Ssam return AH_TRUE; 249189747Ssam} 250189747Ssam 251189747Ssam#if 0 252189747Ssamstatic int16_t 253189747Ssamar9280GetMinPower(struct ath_hal *ah, EXPN_DATA_PER_CHANNEL_5112 *data) 254189747Ssam{ 255189747Ssam int i, minIndex; 256189747Ssam int16_t minGain,minPwr,minPcdac,retVal; 257189747Ssam 258189747Ssam /* Assume NUM_POINTS_XPD0 > 0 */ 259189747Ssam minGain = data->pDataPerXPD[0].xpd_gain; 260189747Ssam for (minIndex=0,i=1; i<NUM_XPD_PER_CHANNEL; i++) { 261189747Ssam if (data->pDataPerXPD[i].xpd_gain < minGain) { 262189747Ssam minIndex = i; 263189747Ssam minGain = data->pDataPerXPD[i].xpd_gain; 264189747Ssam } 265189747Ssam } 266189747Ssam minPwr = data->pDataPerXPD[minIndex].pwr_t4[0]; 267189747Ssam minPcdac = data->pDataPerXPD[minIndex].pcdac[0]; 268189747Ssam for (i=1; i<NUM_POINTS_XPD0; i++) { 269189747Ssam if (data->pDataPerXPD[minIndex].pwr_t4[i] < minPwr) { 270189747Ssam minPwr = data->pDataPerXPD[minIndex].pwr_t4[i]; 271189747Ssam minPcdac = data->pDataPerXPD[minIndex].pcdac[i]; 272189747Ssam } 273189747Ssam } 274189747Ssam retVal = minPwr - (minPcdac*2); 275189747Ssam return(retVal); 276189747Ssam} 277189747Ssam#endif 278189747Ssam 279189747Ssamstatic HAL_BOOL 280189747Ssamar9280GetChannelMaxMinPower(struct ath_hal *ah, 281189747Ssam const struct ieee80211_channel *chan, 282189747Ssam int16_t *maxPow, int16_t *minPow) 283189747Ssam{ 284189747Ssam#if 0 285189747Ssam struct ath_hal_5212 *ahp = AH5212(ah); 286189747Ssam int numChannels=0,i,last; 287189747Ssam int totalD, totalF,totalMin; 288189747Ssam EXPN_DATA_PER_CHANNEL_5112 *data=AH_NULL; 289189747Ssam EEPROM_POWER_EXPN_5112 *powerArray=AH_NULL; 290189747Ssam 291189747Ssam *maxPow = 0; 292189747Ssam if (IS_CHAN_A(chan)) { 293189747Ssam powerArray = ahp->ah_modePowerArray5112; 294189747Ssam data = powerArray[headerInfo11A].pDataPerChannel; 295189747Ssam numChannels = powerArray[headerInfo11A].numChannels; 296189747Ssam } else if (IS_CHAN_G(chan) || IS_CHAN_108G(chan)) { 297189747Ssam /* XXX - is this correct? Should we also use the same power for turbo G? */ 298189747Ssam powerArray = ahp->ah_modePowerArray5112; 299189747Ssam data = powerArray[headerInfo11G].pDataPerChannel; 300189747Ssam numChannels = powerArray[headerInfo11G].numChannels; 301189747Ssam } else if (IS_CHAN_B(chan)) { 302189747Ssam powerArray = ahp->ah_modePowerArray5112; 303189747Ssam data = powerArray[headerInfo11B].pDataPerChannel; 304189747Ssam numChannels = powerArray[headerInfo11B].numChannels; 305189747Ssam } else { 306189747Ssam return (AH_TRUE); 307189747Ssam } 308189747Ssam /* Make sure the channel is in the range of the TP values 309189747Ssam * (freq piers) 310189747Ssam */ 311189747Ssam if ((numChannels < 1) || 312189747Ssam (chan->channel < data[0].channelValue) || 313189747Ssam (chan->channel > data[numChannels-1].channelValue)) 314189747Ssam return(AH_FALSE); 315189747Ssam 316189747Ssam /* Linearly interpolate the power value now */ 317189747Ssam for (last=0,i=0; 318189747Ssam (i<numChannels) && (chan->channel > data[i].channelValue); 319189747Ssam last=i++); 320189747Ssam totalD = data[i].channelValue - data[last].channelValue; 321189747Ssam if (totalD > 0) { 322189747Ssam totalF = data[i].maxPower_t4 - data[last].maxPower_t4; 323189747Ssam *maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) + data[last].maxPower_t4*totalD)/totalD); 324189747Ssam 325189747Ssam totalMin = ar9280GetMinPower(ah,&data[i]) - ar9280GetMinPower(ah, &data[last]); 326189747Ssam *minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) + ar9280GetMinPower(ah, &data[last])*totalD)/totalD); 327189747Ssam return (AH_TRUE); 328189747Ssam } else { 329189747Ssam if (chan->channel == data[i].channelValue) { 330189747Ssam *maxPow = data[i].maxPower_t4; 331189747Ssam *minPow = ar9280GetMinPower(ah, &data[i]); 332189747Ssam return(AH_TRUE); 333189747Ssam } else 334189747Ssam return(AH_FALSE); 335189747Ssam } 336189747Ssam#else 337189747Ssam *maxPow = *minPow = 0; 338189747Ssam return AH_FALSE; 339189747Ssam#endif 340189747Ssam} 341189747Ssam 342219605Sadrian/* 343219605Sadrian * The ordering of nfarray is thus: 344219605Sadrian * 345219605Sadrian * nfarray[0]: Chain 0 ctl 346219605Sadrian * nfarray[1]: Chain 1 ctl 347219605Sadrian * nfarray[2]: Chain 2 ctl 348219605Sadrian * nfarray[3]: Chain 0 ext 349219605Sadrian * nfarray[4]: Chain 1 ext 350219605Sadrian * nfarray[5]: Chain 2 ext 351219605Sadrian */ 352189747Ssamstatic void 353189747Ssamar9280GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) 354189747Ssam{ 355189747Ssam int16_t nf; 356189747Ssam 357189747Ssam nf = MS(OS_REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR); 358189747Ssam if (nf & 0x100) 359189747Ssam nf = 0 - ((nf ^ 0x1ff) + 1); 360189747Ssam HALDEBUG(ah, HAL_DEBUG_NFCAL, 361189747Ssam "NF calibrated [ctl] [chain 0] is %d\n", nf); 362189747Ssam nfarray[0] = nf; 363189747Ssam 364203882Srpaulo nf = MS(OS_REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR); 365203882Srpaulo if (nf & 0x100) 366203882Srpaulo nf = 0 - ((nf ^ 0x1ff) + 1); 367203882Srpaulo HALDEBUG(ah, HAL_DEBUG_NFCAL, 368203882Srpaulo "NF calibrated [ctl] [chain 1] is %d\n", nf); 369203882Srpaulo nfarray[1] = nf; 370189747Ssam 371189747Ssam nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR); 372189747Ssam if (nf & 0x100) 373189747Ssam nf = 0 - ((nf ^ 0x1ff) + 1); 374189747Ssam HALDEBUG(ah, HAL_DEBUG_NFCAL, 375189747Ssam "NF calibrated [ext] [chain 0] is %d\n", nf); 376189747Ssam nfarray[3] = nf; 377189747Ssam 378203882Srpaulo nf = MS(OS_REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR); 379203882Srpaulo if (nf & 0x100) 380189747Ssam nf = 0 - ((nf ^ 0x1ff) + 1); 381203882Srpaulo HALDEBUG(ah, HAL_DEBUG_NFCAL, 382203882Srpaulo "NF calibrated [ext] [chain 1] is %d\n", nf); 383203882Srpaulo nfarray[4] = nf; 384219605Sadrian 385219605Sadrian /* Chain 2 - invalid */ 386219605Sadrian nfarray[2] = 0; 387219605Sadrian nfarray[5] = 0; 388219605Sadrian 389189747Ssam} 390189747Ssam 391189747Ssam/* 392189747Ssam * Adjust NF based on statistical values for 5GHz frequencies. 393189747Ssam * Stubbed:Not used by Fowl 394189747Ssam */ 395189747Ssamint16_t 396189747Ssamar9280GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c) 397189747Ssam{ 398189747Ssam return 0; 399189747Ssam} 400189747Ssam 401189747Ssam/* 402189747Ssam * Free memory for analog bank scratch buffers 403189747Ssam */ 404189747Ssamstatic void 405189747Ssamar9280RfDetach(struct ath_hal *ah) 406189747Ssam{ 407189747Ssam struct ath_hal_5212 *ahp = AH5212(ah); 408189747Ssam 409189747Ssam HALASSERT(ahp->ah_rfHal != AH_NULL); 410189747Ssam ath_hal_free(ahp->ah_rfHal); 411189747Ssam ahp->ah_rfHal = AH_NULL; 412189747Ssam} 413189747Ssam 414189747SsamHAL_BOOL 415189747Ssamar9280RfAttach(struct ath_hal *ah, HAL_STATUS *status) 416189747Ssam{ 417189747Ssam struct ath_hal_5212 *ahp = AH5212(ah); 418189747Ssam struct ar9280State *priv; 419189747Ssam 420189747Ssam HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: attach AR9280 radio\n", __func__); 421189747Ssam 422189747Ssam HALASSERT(ahp->ah_rfHal == AH_NULL); 423189747Ssam priv = ath_hal_malloc(sizeof(struct ar9280State)); 424189747Ssam if (priv == AH_NULL) { 425189747Ssam HALDEBUG(ah, HAL_DEBUG_ANY, 426189747Ssam "%s: cannot allocate private state\n", __func__); 427189747Ssam *status = HAL_ENOMEM; /* XXX */ 428189747Ssam return AH_FALSE; 429189747Ssam } 430189747Ssam priv->base.rfDetach = ar9280RfDetach; 431189747Ssam priv->base.writeRegs = ar9280WriteRegs; 432189747Ssam priv->base.getRfBank = ar9280GetRfBank; 433189747Ssam priv->base.setChannel = ar9280SetChannel; 434189747Ssam priv->base.setRfRegs = ar9280SetRfRegs; 435189747Ssam priv->base.setPowerTable = ar9280SetPowerTable; 436189747Ssam priv->base.getChannelMaxMinPower = ar9280GetChannelMaxMinPower; 437189747Ssam priv->base.getNfAdjust = ar9280GetNfAdjust; 438189747Ssam 439189747Ssam ahp->ah_pcdacTable = priv->pcdacTable; 440189747Ssam ahp->ah_pcdacTableSize = sizeof(priv->pcdacTable); 441189747Ssam ahp->ah_rfHal = &priv->base; 442189747Ssam /* 443189747Ssam * Set noise floor adjust method; we arrange a 444189747Ssam * direct call instead of thunking. 445189747Ssam */ 446189747Ssam AH_PRIVATE(ah)->ah_getNfAdjust = priv->base.getNfAdjust; 447189747Ssam AH_PRIVATE(ah)->ah_getNoiseFloor = ar9280GetNoiseFloor; 448189747Ssam 449189747Ssam return AH_TRUE; 450189747Ssam} 451228517Sadrian 452228517Sadrianstatic HAL_BOOL 453228517Sadrianar9280RfProbe(struct ath_hal *ah) 454228517Sadrian{ 455228517Sadrian return (AR_SREV_MERLIN(ah)); 456228517Sadrian} 457228517Sadrian 458228517SadrianAH_RF(RF9280, ar9280RfProbe, ar9280RfAttach); 459