1 /* 2 * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting 3 * Copyright (c) 2008 Atheros Communications, Inc. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * 17 * $FreeBSD$ 18 */ 19 #include "opt_ah.h" 20 21 #include "ah.h" 22 #include "ah_internal.h" 23 #include "ah_devid.h" 24 25 #include "ah_eeprom_v4k.h" /* XXX for tx/rx gain */ 26 27 #include "ar9002/ar9280.h" 28 #include "ar9002/ar9285.h" 29 #include "ar5416/ar5416reg.h" 30 #include "ar5416/ar5416phy.h" 31 32 #include "ar9002/ar9285.ini" 33 #include "ar9002/ar9285v2.ini" 34 #include "ar9002/ar9280v2.ini" /* XXX ini for tx/rx gain */ 35 36 #include "ar9002/ar9285_cal.h" 37 #include "ar9002/ar9285_phy.h" 38 #include "ar9002/ar9285_diversity.h" 39 40 static const HAL_PERCAL_DATA ar9280_iq_cal = { /* single sample */ 41 .calName = "IQ", .calType = IQ_MISMATCH_CAL, 42 .calNumSamples = MIN_CAL_SAMPLES, 43 .calCountMax = PER_MAX_LOG_COUNT, 44 .calCollect = ar5416IQCalCollect, 45 .calPostProc = ar5416IQCalibration 46 }; 47 static const HAL_PERCAL_DATA ar9280_adc_gain_cal = { /* single sample */ 48 .calName = "ADC Gain", .calType = ADC_GAIN_CAL, 49 .calNumSamples = MIN_CAL_SAMPLES, 50 .calCountMax = PER_MIN_LOG_COUNT, 51 .calCollect = ar5416AdcGainCalCollect, 52 .calPostProc = ar5416AdcGainCalibration 53 }; 54 static const HAL_PERCAL_DATA ar9280_adc_dc_cal = { /* single sample */ 55 .calName = "ADC DC", .calType = ADC_DC_CAL, 56 .calNumSamples = MIN_CAL_SAMPLES, 57 .calCountMax = PER_MIN_LOG_COUNT, 58 .calCollect = ar5416AdcDcCalCollect, 59 .calPostProc = ar5416AdcDcCalibration 60 }; 61 static const HAL_PERCAL_DATA ar9280_adc_init_dc_cal = { 62 .calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL, 63 .calNumSamples = MIN_CAL_SAMPLES, 64 .calCountMax = INIT_LOG_COUNT, 65 .calCollect = ar5416AdcDcCalCollect, 66 .calPostProc = ar5416AdcDcCalibration 67 }; 68 69 static void ar9285ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore); 70 static HAL_BOOL ar9285FillCapabilityInfo(struct ath_hal *ah); 71 static void ar9285WriteIni(struct ath_hal *ah, 72 const struct ieee80211_channel *chan); 73 74 static void 75 ar9285AniSetup(struct ath_hal *ah) 76 { 77 /* 78 * These are the parameters from the AR5416 ANI code; 79 * they likely need quite a bit of adjustment for the 80 * AR9285. 81 */ 82 static const struct ar5212AniParams aniparams = { 83 .maxNoiseImmunityLevel = 4, /* levels 0..4 */ 84 .totalSizeDesired = { -55, -55, -55, -55, -62 }, 85 .coarseHigh = { -14, -14, -14, -14, -12 }, 86 .coarseLow = { -64, -64, -64, -64, -70 }, 87 .firpwr = { -78, -78, -78, -78, -80 }, 88 .maxSpurImmunityLevel = 2, 89 .cycPwrThr1 = { 2, 4, 6 }, 90 .maxFirstepLevel = 2, /* levels 0..2 */ 91 .firstep = { 0, 4, 8 }, 92 .ofdmTrigHigh = 500, 93 .ofdmTrigLow = 200, 94 .cckTrigHigh = 200, 95 .cckTrigLow = 100, 96 .rssiThrHigh = 40, 97 .rssiThrLow = 7, 98 .period = 100, 99 }; 100 /* NB: disable ANI noise immmunity for reliable RIFS rx */ 101 AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL); 102 103 ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE); 104 } 105 106 /* 107 * Attach for an AR9285 part. 108 */ 109 static struct ath_hal * 110 ar9285Attach(uint16_t devid, HAL_SOFTC sc, 111 HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, 112 HAL_STATUS *status) 113 { 114 struct ath_hal_9285 *ahp9285; 115 struct ath_hal_5212 *ahp; 116 struct ath_hal *ah; 117 uint32_t val; 118 HAL_STATUS ecode; 119 HAL_BOOL rfStatus; 120 121 HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", 122 __func__, sc, (void*) st, (void*) sh); 123 124 /* NB: memory is returned zero'd */ 125 ahp9285 = ath_hal_malloc(sizeof (struct ath_hal_9285)); 126 if (ahp9285 == AH_NULL) { 127 HALDEBUG(AH_NULL, HAL_DEBUG_ANY, 128 "%s: cannot allocate memory for state block\n", __func__); 129 *status = HAL_ENOMEM; 130 return AH_NULL; 131 } 132 ahp = AH5212(ahp9285); 133 ah = &ahp->ah_priv.h; 134 135 ar5416InitState(AH5416(ah), devid, sc, st, sh, status); 136 137 /* XXX override with 9285 specific state */ 138 /* override 5416 methods for our needs */ 139 AH5416(ah)->ah_initPLL = ar9280InitPLL; 140 141 ah->ah_setAntennaSwitch = ar9285SetAntennaSwitch; 142 ah->ah_configPCIE = ar9285ConfigPCIE; 143 ah->ah_setTxPower = ar9285SetTransmitPower; 144 ah->ah_setBoardValues = ar9285SetBoardValues; 145 146 AH5416(ah)->ah_cal.iqCalData.calData = &ar9280_iq_cal; 147 AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9280_adc_gain_cal; 148 AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9280_adc_dc_cal; 149 AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9280_adc_init_dc_cal; 150 AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; 151 152 AH5416(ah)->ah_spurMitigate = ar9280SpurMitigate; 153 AH5416(ah)->ah_writeIni = ar9285WriteIni; 154 AH5416(ah)->ah_rx_chainmask = AR9285_DEFAULT_RXCHAINMASK; 155 AH5416(ah)->ah_tx_chainmask = AR9285_DEFAULT_TXCHAINMASK; 156 157 ahp->ah_maxTxTrigLev = MAX_TX_FIFO_THRESHOLD >> 1; 158 159 if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) { 160 /* reset chip */ 161 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n", 162 __func__); 163 ecode = HAL_EIO; 164 goto bad; 165 } 166 167 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 168 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n", 169 __func__); 170 ecode = HAL_EIO; 171 goto bad; 172 } 173 /* Read Revisions from Chips before taking out of reset */ 174 val = OS_REG_READ(ah, AR_SREV); 175 HALDEBUG(ah, HAL_DEBUG_ATTACH, 176 "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n", 177 __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION), 178 MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION)); 179 /* NB: include chip type to differentiate from pre-Sowl versions */ 180 AH_PRIVATE(ah)->ah_macVersion = 181 (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S; 182 AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION); 183 AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0; 184 185 /* setup common ini data; rf backends handle remainder */ 186 if (AR_SREV_KITE_12_OR_LATER(ah)) { 187 HAL_INI_INIT(&ahp->ah_ini_modes, ar9285Modes_v2, 6); 188 HAL_INI_INIT(&ahp->ah_ini_common, ar9285Common_v2, 2); 189 HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes, 190 ar9285PciePhy_clkreq_always_on_L1_v2, 2); 191 } else { 192 HAL_INI_INIT(&ahp->ah_ini_modes, ar9285Modes, 6); 193 HAL_INI_INIT(&ahp->ah_ini_common, ar9285Common, 2); 194 HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes, 195 ar9285PciePhy_clkreq_always_on_L1, 2); 196 } 197 ar5416AttachPCIE(ah); 198 199 /* Attach methods that require MAC version/revision info */ 200 if (AR_SREV_KITE_12_OR_LATER(ah)) 201 AH5416(ah)->ah_cal_initcal = ar9285InitCalHardware; 202 if (AR_SREV_KITE_11_OR_LATER(ah)) 203 AH5416(ah)->ah_cal_pacal = ar9002_hw_pa_cal; 204 205 ecode = ath_hal_v4kEepromAttach(ah); 206 if (ecode != HAL_OK) 207 goto bad; 208 209 if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */ 210 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", 211 __func__); 212 ecode = HAL_EIO; 213 goto bad; 214 } 215 216 AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID); 217 218 if (!ar5212ChipTest(ah)) { 219 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n", 220 __func__); 221 ecode = HAL_ESELFTEST; 222 goto bad; 223 } 224 225 /* 226 * Set correct Baseband to analog shift 227 * setting to access analog chips. 228 */ 229 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 230 231 /* Read Radio Chip Rev Extract */ 232 AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah); 233 switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) { 234 case AR_RAD2133_SREV_MAJOR: /* Sowl: 2G/3x3 */ 235 case AR_RAD5133_SREV_MAJOR: /* Sowl: 2+5G/3x3 */ 236 break; 237 default: 238 if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) { 239 AH_PRIVATE(ah)->ah_analog5GhzRev = 240 AR_RAD5133_SREV_MAJOR; 241 break; 242 } 243 #ifdef AH_DEBUG 244 HALDEBUG(ah, HAL_DEBUG_ANY, 245 "%s: 5G Radio Chip Rev 0x%02X is not supported by " 246 "this driver\n", __func__, 247 AH_PRIVATE(ah)->ah_analog5GhzRev); 248 ecode = HAL_ENOTSUPP; 249 goto bad; 250 #endif 251 } 252 rfStatus = ar9285RfAttach(ah, &ecode); 253 if (!rfStatus) { 254 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n", 255 __func__, ecode); 256 goto bad; 257 } 258 259 HAL_INI_INIT(&ahp9285->ah_ini_rxgain, ar9280Modes_original_rxgain_v2, 260 6); 261 262 if (AR_SREV_9285E_20(ah)) 263 ath_hal_printf(ah, "[ath] AR9285E_20 detected; using XE TX gain tables\n"); 264 265 /* setup txgain table */ 266 switch (ath_hal_eepromGet(ah, AR_EEP_TXGAIN_TYPE, AH_NULL)) { 267 case AR5416_EEP_TXGAIN_HIGH_POWER: 268 if (AR_SREV_9285E_20(ah)) 269 HAL_INI_INIT(&ahp9285->ah_ini_txgain, 270 ar9285Modes_XE2_0_high_power, 6); 271 else 272 HAL_INI_INIT(&ahp9285->ah_ini_txgain, 273 ar9285Modes_high_power_tx_gain_v2, 6); 274 break; 275 case AR5416_EEP_TXGAIN_ORIG: 276 if (AR_SREV_9285E_20(ah)) 277 HAL_INI_INIT(&ahp9285->ah_ini_txgain, 278 ar9285Modes_XE2_0_normal_power, 6); 279 else 280 HAL_INI_INIT(&ahp9285->ah_ini_txgain, 281 ar9285Modes_original_tx_gain_v2, 6); 282 break; 283 default: 284 HALASSERT(AH_FALSE); 285 goto bad; /* XXX ? try to continue */ 286 } 287 288 /* 289 * Got everything we need now to setup the capabilities. 290 */ 291 if (!ar9285FillCapabilityInfo(ah)) { 292 ecode = HAL_EEREAD; 293 goto bad; 294 } 295 296 /* Print out whether the EEPROM settings enable AR9285 diversity */ 297 if (ar9285_check_div_comb(ah)) { 298 ath_hal_printf(ah, "[ath] Enabling diversity for Kite\n"); 299 ah->ah_rxAntCombDiversity = ar9285_ant_comb_scan; 300 } 301 302 /* Disable 11n for the AR2427 */ 303 if (devid == AR2427_DEVID_PCIE) 304 AH_PRIVATE(ah)->ah_caps.halHTSupport = AH_FALSE; 305 306 ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr); 307 if (ecode != HAL_OK) { 308 HALDEBUG(ah, HAL_DEBUG_ANY, 309 "%s: error getting mac address from EEPROM\n", __func__); 310 goto bad; 311 } 312 /* XXX How about the serial number ? */ 313 /* Read Reg Domain */ 314 AH_PRIVATE(ah)->ah_currentRD = 315 ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); 316 /* 317 * For Kite and later chipsets, the following bits are not 318 * programmed in EEPROM and so are set as enabled always. 319 */ 320 AH_PRIVATE(ah)->ah_currentRDext = AR9285_RDEXT_DEFAULT; 321 322 /* 323 * ah_miscMode is populated by ar5416FillCapabilityInfo() 324 * starting from griffin. Set here to make sure that 325 * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is 326 * placed into hardware. 327 */ 328 if (ahp->ah_miscMode != 0) 329 OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode); 330 331 ar9285AniSetup(ah); /* Anti Noise Immunity */ 332 333 /* Setup noise floor min/max/nominal values */ 334 AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ; 335 AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ; 336 AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9285_2GHZ; 337 /* XXX no 5ghz values? */ 338 339 ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist); 340 341 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__); 342 343 return ah; 344 bad: 345 if (ah != AH_NULL) 346 ah->ah_detach(ah); 347 if (status) 348 *status = ecode; 349 return AH_NULL; 350 } 351 352 static void 353 ar9285ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore) 354 { 355 if (AH_PRIVATE(ah)->ah_ispcie && !restore) { 356 ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0); 357 OS_DELAY(1000); 358 OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 359 OS_REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); 360 } 361 } 362 363 static void 364 ar9285WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan) 365 { 366 u_int modesIndex, freqIndex; 367 int regWrites = 0; 368 369 /* Setup the indices for the next set of register array writes */ 370 /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */ 371 freqIndex = 2; 372 if (IEEE80211_IS_CHAN_HT40(chan)) 373 modesIndex = 3; 374 else if (IEEE80211_IS_CHAN_108G(chan)) 375 modesIndex = 5; 376 else 377 modesIndex = 4; 378 379 /* Set correct Baseband to analog shift setting to access analog chips. */ 380 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 381 OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); 382 regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes, 383 modesIndex, regWrites); 384 if (AR_SREV_KITE_12_OR_LATER(ah)) { 385 regWrites = ath_hal_ini_write(ah, &AH9285(ah)->ah_ini_txgain, 386 modesIndex, regWrites); 387 } 388 regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common, 389 1, regWrites); 390 } 391 392 /* 393 * Fill all software cached or static hardware state information. 394 * Return failure if capabilities are to come from EEPROM and 395 * cannot be read. 396 */ 397 static HAL_BOOL 398 ar9285FillCapabilityInfo(struct ath_hal *ah) 399 { 400 HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; 401 402 if (!ar5416FillCapabilityInfo(ah)) 403 return AH_FALSE; 404 pCap->halNumGpioPins = 12; 405 pCap->halWowSupport = AH_TRUE; 406 pCap->halWowMatchPatternExact = AH_TRUE; 407 #if 0 408 pCap->halWowMatchPatternDword = AH_TRUE; 409 #endif 410 /* AR9285 has 2 antennas but is a 1x1 stream device */ 411 pCap->halTxStreams = 1; 412 pCap->halRxStreams = 1; 413 414 pCap->halCSTSupport = AH_TRUE; 415 pCap->halRifsRxSupport = AH_TRUE; 416 pCap->halRifsTxSupport = AH_TRUE; 417 pCap->halRtsAggrLimit = 64*1024; /* 802.11n max */ 418 pCap->halExtChanDfsSupport = AH_TRUE; 419 pCap->halUseCombinedRadarRssi = AH_TRUE; 420 #if 0 421 /* XXX bluetooth */ 422 pCap->halBtCoexSupport = AH_TRUE; 423 #endif 424 pCap->halAutoSleepSupport = AH_FALSE; /* XXX? */ 425 pCap->hal4kbSplitTransSupport = AH_FALSE; 426 /* Disable this so Block-ACK works correctly */ 427 pCap->halHasRxSelfLinkedTail = AH_FALSE; 428 pCap->halMbssidAggrSupport = AH_TRUE; 429 pCap->hal4AddrAggrSupport = AH_TRUE; 430 431 if (AR_SREV_KITE_12_OR_LATER(ah)) 432 pCap->halPSPollBroken = AH_FALSE; 433 434 /* Only RX STBC supported */ 435 pCap->halRxStbcSupport = 1; 436 pCap->halTxStbcSupport = 0; 437 438 return AH_TRUE; 439 } 440 441 static const char* 442 ar9285Probe(uint16_t vendorid, uint16_t devid) 443 { 444 if (vendorid == ATHEROS_VENDOR_ID && devid == AR9285_DEVID_PCIE) 445 return "Atheros 9285"; 446 if (vendorid == ATHEROS_VENDOR_ID && (devid == AR2427_DEVID_PCIE)) 447 return "Atheros 2427"; 448 449 return AH_NULL; 450 } 451 AH_CHIP(AR9285, ar9285Probe, ar9285Attach); 452