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 * $Id: ar5416_attach.c,v 1.1.1.1 2008/12/11 04:46:47 alc Exp $ 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 31 static void 32 ar5416AniSetup(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 */ 59 void 60 ar5416InitState(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_gpioCfgOutput = ar5416GpioCfgOutput; 151 ahp->ah_priv.ah_gpioCfgInput = ar5416GpioCfgInput; 152 ahp->ah_priv.ah_gpioGet = ar5416GpioGet; 153 ahp->ah_priv.ah_gpioSet = ar5416GpioSet; 154 ahp->ah_priv.ah_gpioSetIntr = ar5416GpioSetIntr; 155 ahp->ah_priv.ah_getChipPowerLimits = ar5416GetChipPowerLimits; 156 157 /* 158 * Start by setting all Owl devices to 2x2 159 */ 160 AH5416(ah)->ah_rx_chainmask = AR5416_DEFAULT_RXCHAINMASK; 161 AH5416(ah)->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK; 162 } 163 164 /* 165 * Attach for an AR5416 part. 166 */ 167 struct ath_hal * 168 ar5416Attach(uint16_t devid, HAL_SOFTC sc, 169 HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) 170 { 171 struct ath_hal_5416 *ahp5416; 172 struct ath_hal_5212 *ahp; 173 struct ath_hal *ah; 174 uint32_t val; 175 HAL_STATUS ecode; 176 HAL_BOOL rfStatus; 177 178 HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", 179 __func__, sc, (void*) st, (void*) sh); 180 181 /* NB: memory is returned zero'd */ 182 ahp5416 = ath_hal_malloc(sizeof (struct ath_hal_5416) + 183 /* extra space for Owl 2.1/2.2 WAR */ 184 sizeof(ar5416Addac) 185 ); 186 if (ahp5416 == AH_NULL) { 187 HALDEBUG(AH_NULL, HAL_DEBUG_ANY, 188 "%s: cannot allocate memory for state block\n", __func__); 189 *status = HAL_ENOMEM; 190 return AH_NULL; 191 } 192 ar5416InitState(ahp5416, devid, sc, st, sh, status); 193 ahp = &ahp5416->ah_5212; 194 ah = &ahp->ah_priv.h; 195 196 if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) { 197 /* reset chip */ 198 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n", __func__); 199 ecode = HAL_EIO; 200 goto bad; 201 } 202 203 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 204 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n", __func__); 205 ecode = HAL_EIO; 206 goto bad; 207 } 208 /* Read Revisions from Chips before taking out of reset */ 209 val = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID; 210 AH_PRIVATE(ah)->ah_macVersion = val >> AR_SREV_ID_S; 211 AH_PRIVATE(ah)->ah_macRev = val & AR_SREV_REVISION; 212 213 /* setup common ini data; rf backends handle remainder */ 214 HAL_INI_INIT(&ahp->ah_ini_modes, ar5416Modes, 6); 215 HAL_INI_INIT(&ahp->ah_ini_common, ar5416Common, 2); 216 217 HAL_INI_INIT(&AH5416(ah)->ah_ini_bb_rfgain, ar5416BB_RfGain, 3); 218 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank0, ar5416Bank0, 2); 219 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank1, ar5416Bank1, 2); 220 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank2, ar5416Bank2, 2); 221 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank3, ar5416Bank3, 3); 222 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank6, ar5416Bank6, 3); 223 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank7, ar5416Bank7, 2); 224 HAL_INI_INIT(&AH5416(ah)->ah_ini_addac, ar5416Addac, 2); 225 226 if (!IS_5416V2_2(ah)) { /* Owl 2.1/2.0 */ 227 struct ini { 228 uint32_t *data; /* NB: !const */ 229 int rows, cols; 230 }; 231 /* override CLKDRV value */ 232 OS_MEMCPY(&AH5416(ah)[1], ar5416Addac, sizeof(ar5416Addac)); 233 AH5416(ah)->ah_ini_addac.data = (uint32_t *) &AH5416(ah)[1]; 234 HAL_INI_VAL((struct ini *)&AH5416(ah)->ah_ini_addac, 31, 1) = 0; 235 } 236 237 if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */ 238 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", 239 __func__); 240 ecode = HAL_EIO; 241 goto bad; 242 } 243 244 AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID); 245 246 if (!ar5212ChipTest(ah)) { 247 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n", 248 __func__); 249 ecode = HAL_ESELFTEST; 250 goto bad; 251 } 252 253 /* 254 * Set correct Baseband to analog shift 255 * setting to access analog chips. 256 */ 257 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 258 259 /* Read Radio Chip Rev Extract */ 260 AH_PRIVATE(ah)->ah_analog5GhzRev = ar5212GetRadioRev(ah); 261 switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) { 262 case AR_RAD5122_SREV_MAJOR: /* Fowl: 5G/2x2 */ 263 case AR_RAD2122_SREV_MAJOR: /* Fowl: 2+5G/2x2 */ 264 case AR_RAD2133_SREV_MAJOR: /* Fowl: 2G/3x3 */ 265 case AR_RAD5133_SREV_MAJOR: /* Fowl: 2+5G/3x3 */ 266 break; 267 default: 268 if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) { 269 /* 270 * When RF_Silen is used the analog chip is reset. 271 * So when the system boots with radio switch off 272 * the RF chip rev reads back as zero and we need 273 * to use the mac+phy revs to set the radio rev. 274 */ 275 AH_PRIVATE(ah)->ah_analog5GhzRev = 276 AR_RAD5133_SREV_MAJOR; 277 break; 278 } 279 /* NB: silently accept anything in release code per Atheros */ 280 #ifdef AH_DEBUG 281 HALDEBUG(ah, HAL_DEBUG_ANY, 282 "%s: 5G Radio Chip Rev 0x%02X is not supported by " 283 "this driver\n", __func__, 284 AH_PRIVATE(ah)->ah_analog5GhzRev); 285 ecode = HAL_ENOTSUPP; 286 goto bad; 287 #endif 288 } 289 290 ecode = ath_hal_v14EepromAttach(ah); 291 if (ecode != HAL_OK) 292 goto bad; 293 294 /* 295 * Got everything we need now to setup the capabilities. 296 */ 297 if (!ar5416FillCapabilityInfo(ah)) { 298 ecode = HAL_EEREAD; 299 goto bad; 300 } 301 302 ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr); 303 if (ecode != HAL_OK) { 304 HALDEBUG(ah, HAL_DEBUG_ANY, 305 "%s: error getting mac address from EEPROM\n", __func__); 306 goto bad; 307 } 308 /* XXX How about the serial number ? */ 309 /* Read Reg Domain */ 310 AH_PRIVATE(ah)->ah_currentRD = 311 ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); 312 313 /* 314 * ah_miscMode is populated by ar5416FillCapabilityInfo() 315 * starting from griffin. Set here to make sure that 316 * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is 317 * placed into hardware. 318 */ 319 if (ahp->ah_miscMode != 0) 320 OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); 321 322 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: Attaching AR2133 radio\n", 323 __func__); 324 rfStatus = ar2133RfAttach(ah, &ecode); 325 if (!rfStatus) { 326 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n", 327 __func__, ecode); 328 goto bad; 329 } 330 331 ar5416AniSetup(ah); /* Anti Noise Immunity */ 332 ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist); 333 334 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__); 335 336 return ah; 337 bad: 338 if (ahp) 339 ar5416Detach((struct ath_hal *) ahp); 340 if (status) 341 *status = ecode; 342 return AH_NULL; 343 } 344 345 void 346 ar5416Detach(struct ath_hal *ah) 347 { 348 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s:\n", __func__); 349 350 HALASSERT(ah != AH_NULL); 351 HALASSERT(ah->ah_magic == AR5416_MAGIC); 352 353 ar5416AniDetach(ah); 354 ar5212RfDetach(ah); 355 ah->ah_disable(ah); 356 ar5416SetPowerMode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); 357 ath_hal_eepromDetach(ah); 358 ath_hal_free(ah); 359 } 360 361 /* 362 * Fill all software cached or static hardware state information. 363 * Return failure if capabilities are to come from EEPROM and 364 * cannot be read. 365 */ 366 HAL_BOOL 367 ar5416FillCapabilityInfo(struct ath_hal *ah) 368 { 369 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 370 HAL_CAPABILITIES *pCap = &ahpriv->ah_caps; 371 uint16_t val; 372 373 /* Construct wireless mode from EEPROM */ 374 pCap->halWirelessModes = 0; 375 if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) { 376 pCap->halWirelessModes |= HAL_MODE_11A 377 | HAL_MODE_11NA_HT20 378 | HAL_MODE_11NA_HT40PLUS 379 | HAL_MODE_11NA_HT40MINUS 380 ; 381 } 382 if (ath_hal_eepromGetFlag(ah, AR_EEP_GMODE)) { 383 pCap->halWirelessModes |= HAL_MODE_11G 384 | HAL_MODE_11NG_HT20 385 | HAL_MODE_11NG_HT40PLUS 386 | HAL_MODE_11NG_HT40MINUS 387 ; 388 pCap->halWirelessModes |= HAL_MODE_11A 389 | HAL_MODE_11NA_HT20 390 | HAL_MODE_11NA_HT40PLUS 391 | HAL_MODE_11NA_HT40MINUS 392 ; 393 } 394 395 pCap->halLow2GhzChan = 2312; 396 pCap->halHigh2GhzChan = 2732; 397 398 pCap->halLow5GhzChan = 4915; 399 pCap->halHigh5GhzChan = 6100; 400 401 pCap->halCipherCkipSupport = AH_FALSE; 402 pCap->halCipherTkipSupport = AH_TRUE; 403 pCap->halCipherAesCcmSupport = ath_hal_eepromGetFlag(ah, AR_EEP_AES); 404 405 pCap->halMicCkipSupport = AH_FALSE; 406 pCap->halMicTkipSupport = AH_TRUE; 407 pCap->halMicAesCcmSupport = ath_hal_eepromGetFlag(ah, AR_EEP_AES); 408 /* 409 * Starting with Griffin TX+RX mic keys can be combined 410 * in one key cache slot. 411 */ 412 pCap->halTkipMicTxRxKeySupport = AH_TRUE; 413 pCap->halChanSpreadSupport = AH_TRUE; 414 pCap->halSleepAfterBeaconBroken = AH_TRUE; 415 416 pCap->halCompressSupport = AH_FALSE; 417 pCap->halBurstSupport = AH_TRUE; 418 pCap->halFastFramesSupport = AH_FALSE; /* XXX? */ 419 pCap->halChapTuningSupport = AH_TRUE; 420 pCap->halTurboPrimeSupport = AH_TRUE; 421 422 pCap->halTurboGSupport = pCap->halWirelessModes & HAL_MODE_108G; 423 424 pCap->halPSPollBroken = AH_TRUE; /* XXX fixed in later revs? */ 425 pCap->halVEOLSupport = AH_TRUE; 426 pCap->halBssIdMaskSupport = AH_TRUE; 427 pCap->halMcastKeySrchSupport = AH_FALSE; 428 pCap->halTsfAddSupport = AH_TRUE; 429 430 if (ath_hal_eepromGet(ah, AR_EEP_MAXQCU, &val) == HAL_OK) 431 pCap->halTotalQueues = val; 432 else 433 pCap->halTotalQueues = HAL_NUM_TX_QUEUES; 434 435 if (ath_hal_eepromGet(ah, AR_EEP_KCENTRIES, &val) == HAL_OK) 436 pCap->halKeyCacheSize = val; 437 else 438 pCap->halKeyCacheSize = AR5416_KEYTABLE_SIZE; 439 440 /* XXX not needed */ 441 pCap->halChanHalfRate = AH_FALSE; /* XXX ? */ 442 pCap->halChanQuarterRate = AH_FALSE; /* XXX ? */ 443 444 pCap->halTstampPrecision = 32; 445 pCap->halHwPhyCounterSupport = AH_TRUE; 446 447 pCap->halFastCCSupport = AH_TRUE; 448 pCap->halNumGpioPins = 6; 449 pCap->halWowSupport = AH_FALSE; 450 pCap->halWowMatchPatternExact = AH_FALSE; 451 pCap->halBtCoexSupport = AH_FALSE; /* XXX need support */ 452 pCap->halAutoSleepSupport = AH_FALSE; 453 #if 0 /* XXX not yet */ 454 pCap->halNumAntCfg2GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_2GHZ); 455 pCap->halNumAntCfg5GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_5GHZ); 456 #endif 457 pCap->halHTSupport = AH_TRUE; 458 pCap->halTxChainMask = ath_hal_eepromGet(ah, AR_EEP_TXMASK, AH_NULL); 459 /* XXX CB71 uses GPIO 0 to indicate 3 rx chains */ 460 pCap->halRxChainMask = ath_hal_eepromGet(ah, AR_EEP_RXMASK, AH_NULL); 461 pCap->halRtsAggrLimit = 8*1024; /* Owl 2.0 limit */ 462 pCap->halMbssidAggrSupport = AH_TRUE; 463 pCap->halForcePpmSupport = AH_TRUE; 464 pCap->halEnhancedPmSupport = AH_TRUE; 465 466 if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) && 467 ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) { 468 /* NB: enabled by default */ 469 ahpriv->ah_rfkillEnabled = AH_TRUE; 470 pCap->halRfSilentSupport = AH_TRUE; 471 } 472 473 ahpriv->ah_rxornIsFatal = AH_FALSE; 474 475 return AH_TRUE; 476 } 477 478 static const char* 479 ar5416Probe(uint16_t vendorid, uint16_t devid) 480 { 481 if (vendorid == ATHEROS_VENDOR_ID && 482 (devid == AR5416_DEVID_PCI || devid == AR5416_DEVID_PCIE)) 483 return "Atheros 5416"; 484 return AH_NULL; 485 } 486 AH_CHIP(AR5416, ar5416Probe, ar5416Attach); 487