ar5416_attach.c revision 185406
1185377Ssam/* 2185377Ssam * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3185377Ssam * Copyright (c) 2002-2008 Atheros Communications, Inc. 4185377Ssam * 5185377Ssam * Permission to use, copy, modify, and/or distribute this software for any 6185377Ssam * purpose with or without fee is hereby granted, provided that the above 7185377Ssam * copyright notice and this permission notice appear in all copies. 8185377Ssam * 9185377Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10185377Ssam * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11185377Ssam * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12185377Ssam * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13185377Ssam * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14185377Ssam * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15185377Ssam * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16185377Ssam * 17185380Ssam * $Id: ar5416_attach.c,v 1.27 2008/11/27 22:30:07 sam Exp $ 18185377Ssam */ 19185377Ssam#include "opt_ah.h" 20185377Ssam 21185377Ssam#include "ah.h" 22185377Ssam#include "ah_internal.h" 23185377Ssam#include "ah_devid.h" 24185377Ssam 25185377Ssam#include "ar5416/ar5416.h" 26185377Ssam#include "ar5416/ar5416reg.h" 27185377Ssam#include "ar5416/ar5416phy.h" 28185377Ssam 29185377Ssam#include "ar5416/ar5416.ini" 30185377Ssam 31185377Ssamstatic void 32185377Ssamar5416AniSetup(struct ath_hal *ah) 33185377Ssam{ 34185377Ssam static const struct ar5212AniParams aniparams = { 35185377Ssam .maxNoiseImmunityLevel = 4, /* levels 0..4 */ 36185377Ssam .totalSizeDesired = { -55, -55, -55, -55, -62 }, 37185377Ssam .coarseHigh = { -14, -14, -14, -14, -12 }, 38185377Ssam .coarseLow = { -64, -64, -64, -64, -70 }, 39185377Ssam .firpwr = { -78, -78, -78, -78, -80 }, 40185377Ssam .maxSpurImmunityLevel = 2, 41185377Ssam .cycPwrThr1 = { 2, 4, 6 }, 42185377Ssam .maxFirstepLevel = 2, /* levels 0..2 */ 43185377Ssam .firstep = { 0, 4, 8 }, 44185377Ssam .ofdmTrigHigh = 500, 45185377Ssam .ofdmTrigLow = 200, 46185377Ssam .cckTrigHigh = 200, 47185377Ssam .cckTrigLow = 100, 48185377Ssam .rssiThrHigh = 40, 49185377Ssam .rssiThrLow = 7, 50185377Ssam .period = 100, 51185377Ssam }; 52185377Ssam /* NB: ANI is not enabled yet */ 53185377Ssam ar5212AniAttach(ah, &aniparams, &aniparams, AH_FALSE); 54185377Ssam} 55185377Ssam 56185377Ssam/* 57185377Ssam * Attach for an AR5416 part. 58185377Ssam */ 59185377Ssamvoid 60185377Ssamar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc, 61185377Ssam HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) 62185377Ssam{ 63185377Ssam struct ath_hal_5212 *ahp; 64185377Ssam struct ath_hal *ah; 65185377Ssam 66185377Ssam ahp = &ahp5416->ah_5212; 67185377Ssam ar5212InitState(ahp, devid, sc, st, sh, status); 68185377Ssam ah = &ahp->ah_priv.h; 69185377Ssam 70185377Ssam /* override 5212 methods for our needs */ 71185377Ssam ah->ah_magic = AR5416_MAGIC; 72185377Ssam ah->ah_getRateTable = ar5416GetRateTable; 73185377Ssam ah->ah_detach = ar5416Detach; 74185377Ssam 75185377Ssam /* Reset functions */ 76185377Ssam ah->ah_reset = ar5416Reset; 77185377Ssam ah->ah_phyDisable = ar5416PhyDisable; 78185377Ssam ah->ah_disable = ar5416Disable; 79185377Ssam ah->ah_perCalibration = ar5416PerCalibration; 80185380Ssam ah->ah_perCalibrationN = ar5416PerCalibrationN, 81185380Ssam ah->ah_resetCalValid = ar5416ResetCalValid, 82185377Ssam ah->ah_setTxPowerLimit = ar5416SetTxPowerLimit; 83185377Ssam 84185377Ssam /* Transmit functions */ 85185377Ssam ah->ah_stopTxDma = ar5416StopTxDma; 86185377Ssam ah->ah_setupTxDesc = ar5416SetupTxDesc; 87185377Ssam ah->ah_setupXTxDesc = ar5416SetupXTxDesc; 88185377Ssam ah->ah_fillTxDesc = ar5416FillTxDesc; 89185377Ssam ah->ah_procTxDesc = ar5416ProcTxDesc; 90185377Ssam 91185377Ssam /* Receive Functions */ 92185377Ssam ah->ah_startPcuReceive = ar5416StartPcuReceive; 93185377Ssam ah->ah_stopPcuReceive = ar5416StopPcuReceive; 94185377Ssam ah->ah_setupRxDesc = ar5416SetupRxDesc; 95185377Ssam ah->ah_procRxDesc = ar5416ProcRxDesc; 96185380Ssam ah->ah_rxMonitor = ar5416AniPoll, 97185380Ssam ah->ah_procMibEvent = ar5416ProcessMibIntr, 98185377Ssam 99185377Ssam /* Misc Functions */ 100185377Ssam ah->ah_getDiagState = ar5416GetDiagState; 101185377Ssam ah->ah_setLedState = ar5416SetLedState; 102185377Ssam ah->ah_gpioCfgOutput = ar5416GpioCfgOutput; 103185377Ssam ah->ah_gpioCfgInput = ar5416GpioCfgInput; 104185377Ssam ah->ah_gpioGet = ar5416GpioGet; 105185377Ssam ah->ah_gpioSet = ar5416GpioSet; 106185377Ssam ah->ah_gpioSetIntr = ar5416GpioSetIntr; 107185377Ssam ah->ah_resetTsf = ar5416ResetTsf; 108185377Ssam ah->ah_getRfGain = ar5416GetRfgain; 109185377Ssam ah->ah_setAntennaSwitch = ar5416SetAntennaSwitch; 110185377Ssam ah->ah_setDecompMask = ar5416SetDecompMask; 111185377Ssam ah->ah_setCoverageClass = ar5416SetCoverageClass; 112185377Ssam 113185377Ssam ah->ah_resetKeyCacheEntry = ar5416ResetKeyCacheEntry; 114185377Ssam ah->ah_setKeyCacheEntry = ar5416SetKeyCacheEntry; 115185377Ssam 116185377Ssam /* Power Management Functions */ 117185377Ssam ah->ah_setPowerMode = ar5416SetPowerMode; 118185377Ssam 119185377Ssam /* Beacon Management Functions */ 120185377Ssam ah->ah_setBeaconTimers = ar5416SetBeaconTimers; 121185377Ssam ah->ah_beaconInit = ar5416BeaconInit; 122185377Ssam ah->ah_setStationBeaconTimers = ar5416SetStaBeaconTimers; 123185377Ssam ah->ah_resetStationBeaconTimers = ar5416ResetStaBeaconTimers; 124185377Ssam 125185377Ssam /* XXX 802.11n Functions */ 126185377Ssam#if 0 127185377Ssam ah->ah_chainTxDesc = ar5416ChainTxDesc; 128185377Ssam ah->ah_setupFirstTxDesc = ar5416SetupFirstTxDesc; 129185377Ssam ah->ah_setupLastTxDesc = ar5416SetupLastTxDesc; 130185377Ssam ah->ah_set11nRateScenario = ar5416Set11nRateScenario; 131185377Ssam ah->ah_set11nAggrMiddle = ar5416Set11nAggrMiddle; 132185377Ssam ah->ah_clr11nAggr = ar5416Clr11nAggr; 133185377Ssam ah->ah_set11nBurstDuration = ar5416Set11nBurstDuration; 134185377Ssam ah->ah_get11nExtBusy = ar5416Get11nExtBusy; 135185377Ssam ah->ah_set11nMac2040 = ar5416Set11nMac2040; 136185377Ssam ah->ah_get11nRxClear = ar5416Get11nRxClear; 137185377Ssam ah->ah_set11nRxClear = ar5416Set11nRxClear; 138185377Ssam#endif 139185377Ssam 140185377Ssam /* Interrupt functions */ 141185377Ssam ah->ah_isInterruptPending = ar5416IsInterruptPending; 142185377Ssam ah->ah_getPendingInterrupts = ar5416GetPendingInterrupts; 143185377Ssam ah->ah_setInterrupts = ar5416SetInterrupts; 144185377Ssam 145185377Ssam ahp->ah_priv.ah_getWirelessModes= ar5416GetWirelessModes; 146185377Ssam ahp->ah_priv.ah_eepromRead = ar5416EepromRead; 147185377Ssam#ifdef AH_SUPPORT_WRITE_EEPROM 148185377Ssam ahp->ah_priv.ah_eepromWrite = ar5416EepromWrite; 149185377Ssam#endif 150185377Ssam ahp->ah_priv.ah_gpioCfgOutput = ar5416GpioCfgOutput; 151185377Ssam ahp->ah_priv.ah_gpioCfgInput = ar5416GpioCfgInput; 152185377Ssam ahp->ah_priv.ah_gpioGet = ar5416GpioGet; 153185377Ssam ahp->ah_priv.ah_gpioSet = ar5416GpioSet; 154185377Ssam ahp->ah_priv.ah_gpioSetIntr = ar5416GpioSetIntr; 155185377Ssam ahp->ah_priv.ah_getChipPowerLimits = ar5416GetChipPowerLimits; 156185377Ssam 157185377Ssam /* 158185377Ssam * Start by setting all Owl devices to 2x2 159185377Ssam */ 160185377Ssam AH5416(ah)->ah_rx_chainmask = AR5416_DEFAULT_RXCHAINMASK; 161185377Ssam AH5416(ah)->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK; 162185377Ssam} 163185377Ssam 164185377Ssam/* 165185377Ssam * Attach for an AR5416 part. 166185377Ssam */ 167185377Ssamstruct ath_hal * 168185377Ssamar5416Attach(uint16_t devid, HAL_SOFTC sc, 169185377Ssam HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) 170185377Ssam{ 171185377Ssam struct ath_hal_5416 *ahp5416; 172185377Ssam struct ath_hal_5212 *ahp; 173185377Ssam struct ath_hal *ah; 174185377Ssam uint32_t val; 175185377Ssam HAL_STATUS ecode; 176185377Ssam HAL_BOOL rfStatus; 177185377Ssam 178185377Ssam HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", 179185377Ssam __func__, sc, (void*) st, (void*) sh); 180185377Ssam 181185377Ssam /* NB: memory is returned zero'd */ 182185377Ssam ahp5416 = ath_hal_malloc(sizeof (struct ath_hal_5416) + 183185377Ssam /* extra space for Owl 2.1/2.2 WAR */ 184185377Ssam sizeof(ar5416Addac) 185185377Ssam ); 186185377Ssam if (ahp5416 == AH_NULL) { 187185377Ssam HALDEBUG(AH_NULL, HAL_DEBUG_ANY, 188185377Ssam "%s: cannot allocate memory for state block\n", __func__); 189185377Ssam *status = HAL_ENOMEM; 190185377Ssam return AH_NULL; 191185377Ssam } 192185377Ssam ar5416InitState(ahp5416, devid, sc, st, sh, status); 193185377Ssam ahp = &ahp5416->ah_5212; 194185377Ssam ah = &ahp->ah_priv.h; 195185377Ssam 196185377Ssam if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) { 197185377Ssam /* reset chip */ 198185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n", __func__); 199185377Ssam ecode = HAL_EIO; 200185377Ssam goto bad; 201185377Ssam } 202185377Ssam 203185377Ssam if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 204185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n", __func__); 205185377Ssam ecode = HAL_EIO; 206185377Ssam goto bad; 207185377Ssam } 208185377Ssam /* Read Revisions from Chips before taking out of reset */ 209185377Ssam val = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID; 210185377Ssam AH_PRIVATE(ah)->ah_macVersion = val >> AR_SREV_ID_S; 211185377Ssam AH_PRIVATE(ah)->ah_macRev = val & AR_SREV_REVISION; 212185377Ssam 213185377Ssam /* setup common ini data; rf backends handle remainder */ 214185377Ssam HAL_INI_INIT(&ahp->ah_ini_modes, ar5416Modes, 6); 215185377Ssam HAL_INI_INIT(&ahp->ah_ini_common, ar5416Common, 2); 216185377Ssam 217185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bb_rfgain, ar5416BB_RfGain, 3); 218185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bank0, ar5416Bank0, 2); 219185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bank1, ar5416Bank1, 2); 220185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bank2, ar5416Bank2, 2); 221185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bank3, ar5416Bank3, 3); 222185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bank6, ar5416Bank6, 3); 223185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bank7, ar5416Bank7, 2); 224185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_addac, ar5416Addac, 2); 225185377Ssam 226185377Ssam if (!IS_5416V2_2(ah)) { /* Owl 2.1/2.0 */ 227185377Ssam struct ini { 228185377Ssam uint32_t *data; /* NB: !const */ 229185377Ssam int rows, cols; 230185377Ssam }; 231185377Ssam /* override CLKDRV value */ 232185377Ssam OS_MEMCPY(&AH5416(ah)[1], ar5416Addac, sizeof(ar5416Addac)); 233185377Ssam AH5416(ah)->ah_ini_addac.data = (uint32_t *) &AH5416(ah)[1]; 234185377Ssam HAL_INI_VAL((struct ini *)&AH5416(ah)->ah_ini_addac, 31, 1) = 0; 235185377Ssam } 236185377Ssam 237185377Ssam if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */ 238185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", 239185377Ssam __func__); 240185377Ssam ecode = HAL_EIO; 241185377Ssam goto bad; 242185377Ssam } 243185377Ssam 244185377Ssam AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID); 245185377Ssam 246185377Ssam if (!ar5212ChipTest(ah)) { 247185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n", 248185377Ssam __func__); 249185377Ssam ecode = HAL_ESELFTEST; 250185377Ssam goto bad; 251185377Ssam } 252185377Ssam 253185377Ssam /* 254185377Ssam * Set correct Baseband to analog shift 255185377Ssam * setting to access analog chips. 256185377Ssam */ 257185377Ssam OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 258185377Ssam 259185377Ssam /* Read Radio Chip Rev Extract */ 260185377Ssam AH_PRIVATE(ah)->ah_analog5GhzRev = ar5212GetRadioRev(ah); 261185377Ssam switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) { 262185377Ssam case AR_RAD5122_SREV_MAJOR: /* Fowl: 5G/2x2 */ 263185377Ssam case AR_RAD2122_SREV_MAJOR: /* Fowl: 2+5G/2x2 */ 264185377Ssam case AR_RAD2133_SREV_MAJOR: /* Fowl: 2G/3x3 */ 265185377Ssam case AR_RAD5133_SREV_MAJOR: /* Fowl: 2+5G/3x3 */ 266185377Ssam break; 267185377Ssam default: 268185377Ssam if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) { 269185377Ssam /* 270185377Ssam * When RF_Silen is used the analog chip is reset. 271185377Ssam * So when the system boots with radio switch off 272185377Ssam * the RF chip rev reads back as zero and we need 273185377Ssam * to use the mac+phy revs to set the radio rev. 274185377Ssam */ 275185377Ssam AH_PRIVATE(ah)->ah_analog5GhzRev = 276185377Ssam AR_RAD5133_SREV_MAJOR; 277185377Ssam break; 278185377Ssam } 279185377Ssam /* NB: silently accept anything in release code per Atheros */ 280185377Ssam#ifdef AH_DEBUG 281185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, 282185377Ssam "%s: 5G Radio Chip Rev 0x%02X is not supported by " 283185377Ssam "this driver\n", __func__, 284185377Ssam AH_PRIVATE(ah)->ah_analog5GhzRev); 285185377Ssam ecode = HAL_ENOTSUPP; 286185377Ssam goto bad; 287185377Ssam#endif 288185377Ssam } 289185377Ssam 290185377Ssam ecode = ath_hal_v14EepromAttach(ah); 291185377Ssam if (ecode != HAL_OK) 292185377Ssam goto bad; 293185377Ssam 294185377Ssam /* 295185377Ssam * Got everything we need now to setup the capabilities. 296185377Ssam */ 297185377Ssam if (!ar5416FillCapabilityInfo(ah)) { 298185377Ssam ecode = HAL_EEREAD; 299185377Ssam goto bad; 300185377Ssam } 301185377Ssam 302185377Ssam ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr); 303185377Ssam if (ecode != HAL_OK) { 304185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, 305185377Ssam "%s: error getting mac address from EEPROM\n", __func__); 306185377Ssam goto bad; 307185377Ssam } 308185377Ssam /* XXX How about the serial number ? */ 309185377Ssam /* Read Reg Domain */ 310185377Ssam AH_PRIVATE(ah)->ah_currentRD = 311185377Ssam ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); 312185377Ssam 313185377Ssam /* 314185377Ssam * ah_miscMode is populated by ar5416FillCapabilityInfo() 315185377Ssam * starting from griffin. Set here to make sure that 316185377Ssam * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is 317185380Ssam * placed into hardware. 318185377Ssam */ 319185377Ssam if (ahp->ah_miscMode != 0) 320185377Ssam OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); 321185377Ssam 322185377Ssam HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: Attaching AR2133 radio\n", 323185377Ssam __func__); 324185377Ssam rfStatus = ar2133RfAttach(ah, &ecode); 325185377Ssam if (!rfStatus) { 326185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n", 327185377Ssam __func__, ecode); 328185377Ssam goto bad; 329185377Ssam } 330185377Ssam 331185377Ssam ar5416AniSetup(ah); /* Anti Noise Immunity */ 332185380Ssam ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist); 333185377Ssam 334185377Ssam HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__); 335185377Ssam 336185377Ssam return ah; 337185377Ssambad: 338185377Ssam if (ahp) 339185377Ssam ar5416Detach((struct ath_hal *) ahp); 340185377Ssam if (status) 341185377Ssam *status = ecode; 342185377Ssam return AH_NULL; 343185377Ssam} 344185377Ssam 345185377Ssamvoid 346185377Ssamar5416Detach(struct ath_hal *ah) 347185377Ssam{ 348185377Ssam HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s:\n", __func__); 349185377Ssam 350185377Ssam HALASSERT(ah != AH_NULL); 351185377Ssam HALASSERT(ah->ah_magic == AR5416_MAGIC); 352185377Ssam 353185380Ssam ar5416AniDetach(ah); 354185377Ssam ar5212RfDetach(ah); 355185377Ssam ah->ah_disable(ah); 356185377Ssam ar5416SetPowerMode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); 357185377Ssam ath_hal_eepromDetach(ah); 358185377Ssam ath_hal_free(ah); 359185377Ssam} 360185377Ssam 361185377Ssam/* 362185377Ssam * Fill all software cached or static hardware state information. 363185377Ssam * Return failure if capabilities are to come from EEPROM and 364185377Ssam * cannot be read. 365185377Ssam */ 366185377SsamHAL_BOOL 367185377Ssamar5416FillCapabilityInfo(struct ath_hal *ah) 368185377Ssam{ 369185377Ssam struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 370185377Ssam HAL_CAPABILITIES *pCap = &ahpriv->ah_caps; 371185377Ssam uint16_t val; 372185377Ssam 373185377Ssam /* Construct wireless mode from EEPROM */ 374185377Ssam pCap->halWirelessModes = 0; 375185377Ssam if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) { 376185377Ssam pCap->halWirelessModes |= HAL_MODE_11A 377185377Ssam | HAL_MODE_11NA_HT20 378185377Ssam | HAL_MODE_11NA_HT40PLUS 379185377Ssam | HAL_MODE_11NA_HT40MINUS 380185377Ssam ; 381185377Ssam } 382185377Ssam if (ath_hal_eepromGetFlag(ah, AR_EEP_GMODE)) { 383185377Ssam pCap->halWirelessModes |= HAL_MODE_11G 384185377Ssam | HAL_MODE_11NG_HT20 385185377Ssam | HAL_MODE_11NG_HT40PLUS 386185377Ssam | HAL_MODE_11NG_HT40MINUS 387185377Ssam ; 388185377Ssam pCap->halWirelessModes |= HAL_MODE_11A 389185377Ssam | HAL_MODE_11NA_HT20 390185377Ssam | HAL_MODE_11NA_HT40PLUS 391185377Ssam | HAL_MODE_11NA_HT40MINUS 392185377Ssam ; 393185377Ssam } 394185377Ssam 395185377Ssam pCap->halLow2GhzChan = 2312; 396185377Ssam pCap->halHigh2GhzChan = 2732; 397185377Ssam 398185377Ssam pCap->halLow5GhzChan = 4915; 399185377Ssam pCap->halHigh5GhzChan = 6100; 400185377Ssam 401185377Ssam pCap->halCipherCkipSupport = AH_FALSE; 402185377Ssam pCap->halCipherTkipSupport = AH_TRUE; 403185377Ssam pCap->halCipherAesCcmSupport = ath_hal_eepromGetFlag(ah, AR_EEP_AES); 404185377Ssam 405185377Ssam pCap->halMicCkipSupport = AH_FALSE; 406185377Ssam pCap->halMicTkipSupport = AH_TRUE; 407185377Ssam pCap->halMicAesCcmSupport = ath_hal_eepromGetFlag(ah, AR_EEP_AES); 408185377Ssam /* 409185377Ssam * Starting with Griffin TX+RX mic keys can be combined 410185377Ssam * in one key cache slot. 411185377Ssam */ 412185377Ssam pCap->halTkipMicTxRxKeySupport = AH_TRUE; 413185377Ssam pCap->halChanSpreadSupport = AH_TRUE; 414185377Ssam pCap->halSleepAfterBeaconBroken = AH_TRUE; 415185377Ssam 416185377Ssam pCap->halCompressSupport = AH_FALSE; 417185377Ssam pCap->halBurstSupport = AH_TRUE; 418185377Ssam pCap->halFastFramesSupport = AH_FALSE; /* XXX? */ 419185377Ssam pCap->halChapTuningSupport = AH_TRUE; 420185377Ssam pCap->halTurboPrimeSupport = AH_TRUE; 421185377Ssam 422185377Ssam pCap->halTurboGSupport = pCap->halWirelessModes & HAL_MODE_108G; 423185377Ssam 424185377Ssam pCap->halPSPollBroken = AH_TRUE; /* XXX fixed in later revs? */ 425185377Ssam pCap->halVEOLSupport = AH_TRUE; 426185377Ssam pCap->halBssIdMaskSupport = AH_TRUE; 427185377Ssam pCap->halMcastKeySrchSupport = AH_FALSE; 428185377Ssam pCap->halTsfAddSupport = AH_TRUE; 429185377Ssam 430185377Ssam if (ath_hal_eepromGet(ah, AR_EEP_MAXQCU, &val) == HAL_OK) 431185377Ssam pCap->halTotalQueues = val; 432185377Ssam else 433185377Ssam pCap->halTotalQueues = HAL_NUM_TX_QUEUES; 434185377Ssam 435185377Ssam if (ath_hal_eepromGet(ah, AR_EEP_KCENTRIES, &val) == HAL_OK) 436185377Ssam pCap->halKeyCacheSize = val; 437185377Ssam else 438185377Ssam pCap->halKeyCacheSize = AR5416_KEYTABLE_SIZE; 439185377Ssam 440185377Ssam /* XXX not needed */ 441185377Ssam pCap->halChanHalfRate = AH_FALSE; /* XXX ? */ 442185377Ssam pCap->halChanQuarterRate = AH_FALSE; /* XXX ? */ 443185377Ssam 444185377Ssam pCap->halTstampPrecision = 32; 445185377Ssam pCap->halHwPhyCounterSupport = AH_TRUE; 446185377Ssam 447185377Ssam pCap->halFastCCSupport = AH_TRUE; 448185377Ssam pCap->halNumGpioPins = 6; 449185377Ssam pCap->halWowSupport = AH_FALSE; 450185377Ssam pCap->halWowMatchPatternExact = AH_FALSE; 451185377Ssam pCap->halBtCoexSupport = AH_FALSE; /* XXX need support */ 452185377Ssam pCap->halAutoSleepSupport = AH_FALSE; 453185377Ssam#if 0 /* XXX not yet */ 454185377Ssam pCap->halNumAntCfg2GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_2GHZ); 455185377Ssam pCap->halNumAntCfg5GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_5GHZ); 456185377Ssam#endif 457185377Ssam pCap->halHTSupport = AH_TRUE; 458185377Ssam pCap->halTxChainMask = ath_hal_eepromGet(ah, AR_EEP_TXMASK, AH_NULL); 459185377Ssam /* XXX CB71 uses GPIO 0 to indicate 3 rx chains */ 460185377Ssam pCap->halRxChainMask = ath_hal_eepromGet(ah, AR_EEP_RXMASK, AH_NULL); 461185377Ssam pCap->halRtsAggrLimit = 8*1024; /* Owl 2.0 limit */ 462185377Ssam pCap->halMbssidAggrSupport = AH_TRUE; 463185377Ssam pCap->halForcePpmSupport = AH_TRUE; 464185377Ssam pCap->halEnhancedPmSupport = AH_TRUE; 465185377Ssam 466185377Ssam if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) && 467185377Ssam ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) { 468185377Ssam /* NB: enabled by default */ 469185377Ssam ahpriv->ah_rfkillEnabled = AH_TRUE; 470185377Ssam pCap->halRfSilentSupport = AH_TRUE; 471185377Ssam } 472185377Ssam 473185377Ssam ahpriv->ah_rxornIsFatal = AH_FALSE; 474185377Ssam 475185377Ssam return AH_TRUE; 476185377Ssam} 477185406Ssam 478185406Ssamstatic const char* 479185406Ssamar5416Probe(uint16_t vendorid, uint16_t devid) 480185406Ssam{ 481185406Ssam if (vendorid == ATHEROS_VENDOR_ID && 482185406Ssam (devid == AR5416_DEVID_PCI || devid == AR5416_DEVID_PCIE)) 483185406Ssam return "Atheros 5416"; 484185406Ssam return AH_NULL; 485185406Ssam} 486185406SsamAH_CHIP(ar5416, ar5416Probe, ar5416Attach); 487