ar5416_attach.c revision 188973
1/* 2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3 * Copyright (c) 2002-2008 Atheros Communications, Inc. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * 17 * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c 188973 2009-02-24 00:03:14Z sam $ 18 */ 19#include "opt_ah.h" 20 21#include "ah.h" 22#include "ah_internal.h" 23#include "ah_devid.h" 24 25#include "ar5416/ar5416.h" 26#include "ar5416/ar5416reg.h" 27#include "ar5416/ar5416phy.h" 28 29#include "ar5416/ar5416.ini" 30 31static void 32ar5416AniSetup(struct ath_hal *ah) 33{ 34 static const struct ar5212AniParams aniparams = { 35 .maxNoiseImmunityLevel = 4, /* levels 0..4 */ 36 .totalSizeDesired = { -55, -55, -55, -55, -62 }, 37 .coarseHigh = { -14, -14, -14, -14, -12 }, 38 .coarseLow = { -64, -64, -64, -64, -70 }, 39 .firpwr = { -78, -78, -78, -78, -80 }, 40 .maxSpurImmunityLevel = 2, 41 .cycPwrThr1 = { 2, 4, 6 }, 42 .maxFirstepLevel = 2, /* levels 0..2 */ 43 .firstep = { 0, 4, 8 }, 44 .ofdmTrigHigh = 500, 45 .ofdmTrigLow = 200, 46 .cckTrigHigh = 200, 47 .cckTrigLow = 100, 48 .rssiThrHigh = 40, 49 .rssiThrLow = 7, 50 .period = 100, 51 }; 52 /* NB: ANI is not enabled yet */ 53 ar5212AniAttach(ah, &aniparams, &aniparams, AH_FALSE); 54} 55 56/* 57 * Attach for an AR5416 part. 58 */ 59void 60ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc, 61 HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) 62{ 63 struct ath_hal_5212 *ahp; 64 struct ath_hal *ah; 65 66 ahp = &ahp5416->ah_5212; 67 ar5212InitState(ahp, devid, sc, st, sh, status); 68 ah = &ahp->ah_priv.h; 69 70 /* override 5212 methods for our needs */ 71 ah->ah_magic = AR5416_MAGIC; 72 ah->ah_getRateTable = ar5416GetRateTable; 73 ah->ah_detach = ar5416Detach; 74 75 /* Reset functions */ 76 ah->ah_reset = ar5416Reset; 77 ah->ah_phyDisable = ar5416PhyDisable; 78 ah->ah_disable = ar5416Disable; 79 ah->ah_perCalibration = ar5416PerCalibration; 80 ah->ah_perCalibrationN = ar5416PerCalibrationN, 81 ah->ah_resetCalValid = ar5416ResetCalValid, 82 ah->ah_setTxPowerLimit = ar5416SetTxPowerLimit; 83 84 /* Transmit functions */ 85 ah->ah_stopTxDma = ar5416StopTxDma; 86 ah->ah_setupTxDesc = ar5416SetupTxDesc; 87 ah->ah_setupXTxDesc = ar5416SetupXTxDesc; 88 ah->ah_fillTxDesc = ar5416FillTxDesc; 89 ah->ah_procTxDesc = ar5416ProcTxDesc; 90 91 /* Receive Functions */ 92 ah->ah_startPcuReceive = ar5416StartPcuReceive; 93 ah->ah_stopPcuReceive = ar5416StopPcuReceive; 94 ah->ah_setupRxDesc = ar5416SetupRxDesc; 95 ah->ah_procRxDesc = ar5416ProcRxDesc; 96 ah->ah_rxMonitor = ar5416AniPoll, 97 ah->ah_procMibEvent = ar5416ProcessMibIntr, 98 99 /* Misc Functions */ 100 ah->ah_getDiagState = ar5416GetDiagState; 101 ah->ah_setLedState = ar5416SetLedState; 102 ah->ah_gpioCfgOutput = ar5416GpioCfgOutput; 103 ah->ah_gpioCfgInput = ar5416GpioCfgInput; 104 ah->ah_gpioGet = ar5416GpioGet; 105 ah->ah_gpioSet = ar5416GpioSet; 106 ah->ah_gpioSetIntr = ar5416GpioSetIntr; 107 ah->ah_resetTsf = ar5416ResetTsf; 108 ah->ah_getRfGain = ar5416GetRfgain; 109 ah->ah_setAntennaSwitch = ar5416SetAntennaSwitch; 110 ah->ah_setDecompMask = ar5416SetDecompMask; 111 ah->ah_setCoverageClass = ar5416SetCoverageClass; 112 113 ah->ah_resetKeyCacheEntry = ar5416ResetKeyCacheEntry; 114 ah->ah_setKeyCacheEntry = ar5416SetKeyCacheEntry; 115 116 /* Power Management Functions */ 117 ah->ah_setPowerMode = ar5416SetPowerMode; 118 119 /* Beacon Management Functions */ 120 ah->ah_setBeaconTimers = ar5416SetBeaconTimers; 121 ah->ah_beaconInit = ar5416BeaconInit; 122 ah->ah_setStationBeaconTimers = ar5416SetStaBeaconTimers; 123 ah->ah_resetStationBeaconTimers = ar5416ResetStaBeaconTimers; 124 125 /* XXX 802.11n Functions */ 126#if 0 127 ah->ah_chainTxDesc = ar5416ChainTxDesc; 128 ah->ah_setupFirstTxDesc = ar5416SetupFirstTxDesc; 129 ah->ah_setupLastTxDesc = ar5416SetupLastTxDesc; 130 ah->ah_set11nRateScenario = ar5416Set11nRateScenario; 131 ah->ah_set11nAggrMiddle = ar5416Set11nAggrMiddle; 132 ah->ah_clr11nAggr = ar5416Clr11nAggr; 133 ah->ah_set11nBurstDuration = ar5416Set11nBurstDuration; 134 ah->ah_get11nExtBusy = ar5416Get11nExtBusy; 135 ah->ah_set11nMac2040 = ar5416Set11nMac2040; 136 ah->ah_get11nRxClear = ar5416Get11nRxClear; 137 ah->ah_set11nRxClear = ar5416Set11nRxClear; 138#endif 139 140 /* Interrupt functions */ 141 ah->ah_isInterruptPending = ar5416IsInterruptPending; 142 ah->ah_getPendingInterrupts = ar5416GetPendingInterrupts; 143 ah->ah_setInterrupts = ar5416SetInterrupts; 144 145 ahp->ah_priv.ah_getWirelessModes= ar5416GetWirelessModes; 146 ahp->ah_priv.ah_eepromRead = ar5416EepromRead; 147#ifdef AH_SUPPORT_WRITE_EEPROM 148 ahp->ah_priv.ah_eepromWrite = ar5416EepromWrite; 149#endif 150 ahp->ah_priv.ah_getChipPowerLimits = ar5416GetChipPowerLimits; 151 152 /* 153 * Start by setting all Owl devices to 2x2 154 */ 155 AH5416(ah)->ah_rx_chainmask = AR5416_DEFAULT_RXCHAINMASK; 156 AH5416(ah)->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK; 157} 158 159uint32_t 160ar5416GetRadioRev(struct ath_hal *ah) 161{ 162 uint32_t val; 163 int i; 164 165 /* Read Radio Chip Rev Extract */ 166 OS_REG_WRITE(ah, AR_PHY(0x36), 0x00007058); 167 for (i = 0; i < 8; i++) 168 OS_REG_WRITE(ah, AR_PHY(0x20), 0x00010000); 169 val = (OS_REG_READ(ah, AR_PHY(256)) >> 24) & 0xff; 170 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4); 171 return ath_hal_reverseBits(val, 8); 172} 173 174/* 175 * Attach for an AR5416 part. 176 */ 177static struct ath_hal * 178ar5416Attach(uint16_t devid, HAL_SOFTC sc, 179 HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) 180{ 181 struct ath_hal_5416 *ahp5416; 182 struct ath_hal_5212 *ahp; 183 struct ath_hal *ah; 184 uint32_t val; 185 HAL_STATUS ecode; 186 HAL_BOOL rfStatus; 187 188 HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", 189 __func__, sc, (void*) st, (void*) sh); 190 191 /* NB: memory is returned zero'd */ 192 ahp5416 = ath_hal_malloc(sizeof (struct ath_hal_5416) + 193 /* extra space for Owl 2.1/2.2 WAR */ 194 sizeof(ar5416Addac) 195 ); 196 if (ahp5416 == AH_NULL) { 197 HALDEBUG(AH_NULL, HAL_DEBUG_ANY, 198 "%s: cannot allocate memory for state block\n", __func__); 199 *status = HAL_ENOMEM; 200 return AH_NULL; 201 } 202 ar5416InitState(ahp5416, devid, sc, st, sh, status); 203 ahp = &ahp5416->ah_5212; 204 ah = &ahp->ah_priv.h; 205 206 if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) { 207 /* reset chip */ 208 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n", __func__); 209 ecode = HAL_EIO; 210 goto bad; 211 } 212 213 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 214 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n", __func__); 215 ecode = HAL_EIO; 216 goto bad; 217 } 218 /* Read Revisions from Chips before taking out of reset */ 219 val = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID; 220 AH_PRIVATE(ah)->ah_macVersion = val >> AR_SREV_ID_S; 221 AH_PRIVATE(ah)->ah_macRev = val & AR_SREV_REVISION; 222 223 /* setup common ini data; rf backends handle remainder */ 224 HAL_INI_INIT(&ahp->ah_ini_modes, ar5416Modes, 6); 225 HAL_INI_INIT(&ahp->ah_ini_common, ar5416Common, 2); 226 227 HAL_INI_INIT(&AH5416(ah)->ah_ini_bb_rfgain, ar5416BB_RfGain, 3); 228 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank0, ar5416Bank0, 2); 229 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank1, ar5416Bank1, 2); 230 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank2, ar5416Bank2, 2); 231 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank3, ar5416Bank3, 3); 232 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank6, ar5416Bank6, 3); 233 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank7, ar5416Bank7, 2); 234 HAL_INI_INIT(&AH5416(ah)->ah_ini_addac, ar5416Addac, 2); 235 236 if (!IS_5416V2_2(ah)) { /* Owl 2.1/2.0 */ 237 struct ini { 238 uint32_t *data; /* NB: !const */ 239 int rows, cols; 240 }; 241 /* override CLKDRV value */ 242 OS_MEMCPY(&AH5416(ah)[1], ar5416Addac, sizeof(ar5416Addac)); 243 AH5416(ah)->ah_ini_addac.data = (uint32_t *) &AH5416(ah)[1]; 244 HAL_INI_VAL((struct ini *)&AH5416(ah)->ah_ini_addac, 31, 1) = 0; 245 } 246 247 ecode = ath_hal_v14EepromAttach(ah); 248 if (ecode != HAL_OK) 249 goto bad; 250 251 if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */ 252 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", 253 __func__); 254 ecode = HAL_EIO; 255 goto bad; 256 } 257 258 AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID); 259 260 if (!ar5212ChipTest(ah)) { 261 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n", 262 __func__); 263 ecode = HAL_ESELFTEST; 264 goto bad; 265 } 266 267 /* 268 * Set correct Baseband to analog shift 269 * setting to access analog chips. 270 */ 271 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 272 273 /* Read Radio Chip Rev Extract */ 274 AH_PRIVATE(ah)->ah_analog5GhzRev = ar5212GetRadioRev(ah); 275 switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) { 276 case AR_RAD5122_SREV_MAJOR: /* Fowl: 5G/2x2 */ 277 case AR_RAD2122_SREV_MAJOR: /* Fowl: 2+5G/2x2 */ 278 case AR_RAD2133_SREV_MAJOR: /* Fowl: 2G/3x3 */ 279 case AR_RAD5133_SREV_MAJOR: /* Fowl: 2+5G/3x3 */ 280 break; 281 default: 282 if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) { 283 /* 284 * When RF_Silen is used the analog chip is reset. 285 * So when the system boots with radio switch off 286 * the RF chip rev reads back as zero and we need 287 * to use the mac+phy revs to set the radio rev. 288 */ 289 AH_PRIVATE(ah)->ah_analog5GhzRev = 290 AR_RAD5133_SREV_MAJOR; 291 break; 292 } 293 /* NB: silently accept anything in release code per Atheros */ 294#ifdef AH_DEBUG 295 HALDEBUG(ah, HAL_DEBUG_ANY, 296 "%s: 5G Radio Chip Rev 0x%02X is not supported by " 297 "this driver\n", __func__, 298 AH_PRIVATE(ah)->ah_analog5GhzRev); 299 ecode = HAL_ENOTSUPP; 300 goto bad; 301#endif 302 } 303 304 /* 305 * Got everything we need now to setup the capabilities. 306 */ 307 if (!ar5416FillCapabilityInfo(ah)) { 308 ecode = HAL_EEREAD; 309 goto bad; 310 } 311 312 ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr); 313 if (ecode != HAL_OK) { 314 HALDEBUG(ah, HAL_DEBUG_ANY, 315 "%s: error getting mac address from EEPROM\n", __func__); 316 goto bad; 317 } 318 /* XXX How about the serial number ? */ 319 /* Read Reg Domain */ 320 AH_PRIVATE(ah)->ah_currentRD = 321 ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); 322 323 /* 324 * ah_miscMode is populated by ar5416FillCapabilityInfo() 325 * starting from griffin. Set here to make sure that 326 * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is 327 * placed into hardware. 328 */ 329 if (ahp->ah_miscMode != 0) 330 OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); 331 332 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: Attaching AR2133 radio\n", 333 __func__); 334 rfStatus = ar2133RfAttach(ah, &ecode); 335 if (!rfStatus) { 336 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n", 337 __func__, ecode); 338 goto bad; 339 } 340 341 ar5416AniSetup(ah); /* Anti Noise Immunity */ 342 ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist); 343 344 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__); 345 346 return ah; 347bad: 348 if (ahp) 349 ar5416Detach((struct ath_hal *) ahp); 350 if (status) 351 *status = ecode; 352 return AH_NULL; 353} 354 355void 356ar5416Detach(struct ath_hal *ah) 357{ 358 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s:\n", __func__); 359 360 HALASSERT(ah != AH_NULL); 361 HALASSERT(ah->ah_magic == AR5416_MAGIC); 362 363 ar5416AniDetach(ah); 364 ar5212RfDetach(ah); 365 ah->ah_disable(ah); 366 ar5416SetPowerMode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); 367 ath_hal_eepromDetach(ah); 368 ath_hal_free(ah); 369} 370 371/* 372 * Fill all software cached or static hardware state information. 373 * Return failure if capabilities are to come from EEPROM and 374 * cannot be read. 375 */ 376HAL_BOOL 377ar5416FillCapabilityInfo(struct ath_hal *ah) 378{ 379 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 380 HAL_CAPABILITIES *pCap = &ahpriv->ah_caps; 381 uint16_t val; 382 383 /* Construct wireless mode from EEPROM */ 384 pCap->halWirelessModes = 0; 385 if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) { 386 pCap->halWirelessModes |= HAL_MODE_11A 387 | HAL_MODE_11NA_HT20 388 | HAL_MODE_11NA_HT40PLUS 389 | HAL_MODE_11NA_HT40MINUS 390 ; 391 } 392 if (ath_hal_eepromGetFlag(ah, AR_EEP_GMODE)) { 393 pCap->halWirelessModes |= HAL_MODE_11G 394 | HAL_MODE_11NG_HT20 395 | HAL_MODE_11NG_HT40PLUS 396 | HAL_MODE_11NG_HT40MINUS 397 ; 398 pCap->halWirelessModes |= HAL_MODE_11A 399 | HAL_MODE_11NA_HT20 400 | HAL_MODE_11NA_HT40PLUS 401 | HAL_MODE_11NA_HT40MINUS 402 ; 403 } 404 405 pCap->halLow2GhzChan = 2312; 406 pCap->halHigh2GhzChan = 2732; 407 408 pCap->halLow5GhzChan = 4915; 409 pCap->halHigh5GhzChan = 6100; 410 411 pCap->halCipherCkipSupport = AH_FALSE; 412 pCap->halCipherTkipSupport = AH_TRUE; 413 pCap->halCipherAesCcmSupport = ath_hal_eepromGetFlag(ah, AR_EEP_AES); 414 415 pCap->halMicCkipSupport = AH_FALSE; 416 pCap->halMicTkipSupport = AH_TRUE; 417 pCap->halMicAesCcmSupport = ath_hal_eepromGetFlag(ah, AR_EEP_AES); 418 /* 419 * Starting with Griffin TX+RX mic keys can be combined 420 * in one key cache slot. 421 */ 422 pCap->halTkipMicTxRxKeySupport = AH_TRUE; 423 pCap->halChanSpreadSupport = AH_TRUE; 424 pCap->halSleepAfterBeaconBroken = AH_TRUE; 425 426 pCap->halCompressSupport = AH_FALSE; 427 pCap->halBurstSupport = AH_TRUE; 428 pCap->halFastFramesSupport = AH_FALSE; /* XXX? */ 429 pCap->halChapTuningSupport = AH_TRUE; 430 pCap->halTurboPrimeSupport = AH_TRUE; 431 432 pCap->halTurboGSupport = pCap->halWirelessModes & HAL_MODE_108G; 433 434 pCap->halPSPollBroken = AH_TRUE; /* XXX fixed in later revs? */ 435 pCap->halVEOLSupport = AH_TRUE; 436 pCap->halBssIdMaskSupport = AH_TRUE; 437 pCap->halMcastKeySrchSupport = AH_FALSE; 438 pCap->halTsfAddSupport = AH_TRUE; 439 440 if (ath_hal_eepromGet(ah, AR_EEP_MAXQCU, &val) == HAL_OK) 441 pCap->halTotalQueues = val; 442 else 443 pCap->halTotalQueues = HAL_NUM_TX_QUEUES; 444 445 if (ath_hal_eepromGet(ah, AR_EEP_KCENTRIES, &val) == HAL_OK) 446 pCap->halKeyCacheSize = val; 447 else 448 pCap->halKeyCacheSize = AR5416_KEYTABLE_SIZE; 449 450 /* XXX not needed */ 451 pCap->halChanHalfRate = AH_FALSE; /* XXX ? */ 452 pCap->halChanQuarterRate = AH_FALSE; /* XXX ? */ 453 454 pCap->halTstampPrecision = 32; 455 pCap->halHwPhyCounterSupport = AH_TRUE; 456 457 pCap->halFastCCSupport = AH_TRUE; 458 pCap->halNumGpioPins = 6; 459 pCap->halWowSupport = AH_FALSE; 460 pCap->halWowMatchPatternExact = AH_FALSE; 461 pCap->halBtCoexSupport = AH_FALSE; /* XXX need support */ 462 pCap->halAutoSleepSupport = AH_FALSE; 463#if 0 /* XXX not yet */ 464 pCap->halNumAntCfg2GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_2GHZ); 465 pCap->halNumAntCfg5GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_5GHZ); 466#endif 467 pCap->halHTSupport = AH_TRUE; 468 pCap->halTxChainMask = ath_hal_eepromGet(ah, AR_EEP_TXMASK, AH_NULL); 469 /* XXX CB71 uses GPIO 0 to indicate 3 rx chains */ 470 pCap->halRxChainMask = ath_hal_eepromGet(ah, AR_EEP_RXMASK, AH_NULL); 471 pCap->halRtsAggrLimit = 8*1024; /* Owl 2.0 limit */ 472 pCap->halMbssidAggrSupport = AH_TRUE; 473 pCap->halForcePpmSupport = AH_TRUE; 474 pCap->halEnhancedPmSupport = AH_TRUE; 475 476 if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) && 477 ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) { 478 /* NB: enabled by default */ 479 ahpriv->ah_rfkillEnabled = AH_TRUE; 480 pCap->halRfSilentSupport = AH_TRUE; 481 } 482 483 ahpriv->ah_rxornIsFatal = AH_FALSE; 484 485 return AH_TRUE; 486} 487 488static const char* 489ar5416Probe(uint16_t vendorid, uint16_t devid) 490{ 491 if (vendorid == ATHEROS_VENDOR_ID && 492 (devid == AR5416_DEVID_PCI || devid == AR5416_DEVID_PCIE)) 493 return "Atheros 5416"; 494 return AH_NULL; 495} 496AH_CHIP(AR5416, ar5416Probe, ar5416Attach); 497