ar5416_attach.c revision 188973
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 * 17188970Ssam * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c 188973 2009-02-24 00:03:14Z sam $ 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_getChipPowerLimits = ar5416GetChipPowerLimits; 151185377Ssam 152185377Ssam /* 153185377Ssam * Start by setting all Owl devices to 2x2 154185377Ssam */ 155185377Ssam AH5416(ah)->ah_rx_chainmask = AR5416_DEFAULT_RXCHAINMASK; 156185377Ssam AH5416(ah)->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK; 157185377Ssam} 158185377Ssam 159188971Ssamuint32_t 160188971Ssamar5416GetRadioRev(struct ath_hal *ah) 161188971Ssam{ 162188971Ssam uint32_t val; 163188971Ssam int i; 164188971Ssam 165188971Ssam /* Read Radio Chip Rev Extract */ 166188971Ssam OS_REG_WRITE(ah, AR_PHY(0x36), 0x00007058); 167188971Ssam for (i = 0; i < 8; i++) 168188971Ssam OS_REG_WRITE(ah, AR_PHY(0x20), 0x00010000); 169188971Ssam val = (OS_REG_READ(ah, AR_PHY(256)) >> 24) & 0xff; 170188971Ssam val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4); 171188971Ssam return ath_hal_reverseBits(val, 8); 172188971Ssam} 173188971Ssam 174185377Ssam/* 175185377Ssam * Attach for an AR5416 part. 176185377Ssam */ 177188972Ssamstatic struct ath_hal * 178185377Ssamar5416Attach(uint16_t devid, HAL_SOFTC sc, 179185377Ssam HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) 180185377Ssam{ 181185377Ssam struct ath_hal_5416 *ahp5416; 182185377Ssam struct ath_hal_5212 *ahp; 183185377Ssam struct ath_hal *ah; 184185377Ssam uint32_t val; 185185377Ssam HAL_STATUS ecode; 186185377Ssam HAL_BOOL rfStatus; 187185377Ssam 188185377Ssam HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", 189185377Ssam __func__, sc, (void*) st, (void*) sh); 190185377Ssam 191185377Ssam /* NB: memory is returned zero'd */ 192185377Ssam ahp5416 = ath_hal_malloc(sizeof (struct ath_hal_5416) + 193185377Ssam /* extra space for Owl 2.1/2.2 WAR */ 194185377Ssam sizeof(ar5416Addac) 195185377Ssam ); 196185377Ssam if (ahp5416 == AH_NULL) { 197185377Ssam HALDEBUG(AH_NULL, HAL_DEBUG_ANY, 198185377Ssam "%s: cannot allocate memory for state block\n", __func__); 199185377Ssam *status = HAL_ENOMEM; 200185377Ssam return AH_NULL; 201185377Ssam } 202185377Ssam ar5416InitState(ahp5416, devid, sc, st, sh, status); 203185377Ssam ahp = &ahp5416->ah_5212; 204185377Ssam ah = &ahp->ah_priv.h; 205185377Ssam 206185377Ssam if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) { 207185377Ssam /* reset chip */ 208185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n", __func__); 209185377Ssam ecode = HAL_EIO; 210185377Ssam goto bad; 211185377Ssam } 212185377Ssam 213185377Ssam if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 214185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n", __func__); 215185377Ssam ecode = HAL_EIO; 216185377Ssam goto bad; 217185377Ssam } 218185377Ssam /* Read Revisions from Chips before taking out of reset */ 219185377Ssam val = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID; 220185377Ssam AH_PRIVATE(ah)->ah_macVersion = val >> AR_SREV_ID_S; 221185377Ssam AH_PRIVATE(ah)->ah_macRev = val & AR_SREV_REVISION; 222185377Ssam 223185377Ssam /* setup common ini data; rf backends handle remainder */ 224185377Ssam HAL_INI_INIT(&ahp->ah_ini_modes, ar5416Modes, 6); 225185377Ssam HAL_INI_INIT(&ahp->ah_ini_common, ar5416Common, 2); 226185377Ssam 227185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bb_rfgain, ar5416BB_RfGain, 3); 228185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bank0, ar5416Bank0, 2); 229185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bank1, ar5416Bank1, 2); 230185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bank2, ar5416Bank2, 2); 231185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bank3, ar5416Bank3, 3); 232185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bank6, ar5416Bank6, 3); 233185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_bank7, ar5416Bank7, 2); 234185377Ssam HAL_INI_INIT(&AH5416(ah)->ah_ini_addac, ar5416Addac, 2); 235185377Ssam 236185377Ssam if (!IS_5416V2_2(ah)) { /* Owl 2.1/2.0 */ 237185377Ssam struct ini { 238185377Ssam uint32_t *data; /* NB: !const */ 239185377Ssam int rows, cols; 240185377Ssam }; 241185377Ssam /* override CLKDRV value */ 242185377Ssam OS_MEMCPY(&AH5416(ah)[1], ar5416Addac, sizeof(ar5416Addac)); 243185377Ssam AH5416(ah)->ah_ini_addac.data = (uint32_t *) &AH5416(ah)[1]; 244185377Ssam HAL_INI_VAL((struct ini *)&AH5416(ah)->ah_ini_addac, 31, 1) = 0; 245185377Ssam } 246185377Ssam 247188973Ssam ecode = ath_hal_v14EepromAttach(ah); 248188973Ssam if (ecode != HAL_OK) 249188973Ssam goto bad; 250188973Ssam 251185377Ssam if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */ 252185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", 253185377Ssam __func__); 254185377Ssam ecode = HAL_EIO; 255185377Ssam goto bad; 256185377Ssam } 257185377Ssam 258185377Ssam AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID); 259185377Ssam 260185377Ssam if (!ar5212ChipTest(ah)) { 261185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n", 262185377Ssam __func__); 263185377Ssam ecode = HAL_ESELFTEST; 264185377Ssam goto bad; 265185377Ssam } 266185377Ssam 267185377Ssam /* 268185377Ssam * Set correct Baseband to analog shift 269185377Ssam * setting to access analog chips. 270185377Ssam */ 271185377Ssam OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 272185377Ssam 273185377Ssam /* Read Radio Chip Rev Extract */ 274185377Ssam AH_PRIVATE(ah)->ah_analog5GhzRev = ar5212GetRadioRev(ah); 275185377Ssam switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) { 276185377Ssam case AR_RAD5122_SREV_MAJOR: /* Fowl: 5G/2x2 */ 277185377Ssam case AR_RAD2122_SREV_MAJOR: /* Fowl: 2+5G/2x2 */ 278185377Ssam case AR_RAD2133_SREV_MAJOR: /* Fowl: 2G/3x3 */ 279185377Ssam case AR_RAD5133_SREV_MAJOR: /* Fowl: 2+5G/3x3 */ 280185377Ssam break; 281185377Ssam default: 282185377Ssam if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) { 283185377Ssam /* 284185377Ssam * When RF_Silen is used the analog chip is reset. 285185377Ssam * So when the system boots with radio switch off 286185377Ssam * the RF chip rev reads back as zero and we need 287185377Ssam * to use the mac+phy revs to set the radio rev. 288185377Ssam */ 289185377Ssam AH_PRIVATE(ah)->ah_analog5GhzRev = 290185377Ssam AR_RAD5133_SREV_MAJOR; 291185377Ssam break; 292185377Ssam } 293185377Ssam /* NB: silently accept anything in release code per Atheros */ 294185377Ssam#ifdef AH_DEBUG 295185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, 296185377Ssam "%s: 5G Radio Chip Rev 0x%02X is not supported by " 297185377Ssam "this driver\n", __func__, 298185377Ssam AH_PRIVATE(ah)->ah_analog5GhzRev); 299185377Ssam ecode = HAL_ENOTSUPP; 300185377Ssam goto bad; 301185377Ssam#endif 302185377Ssam } 303185377Ssam 304185377Ssam /* 305185377Ssam * Got everything we need now to setup the capabilities. 306185377Ssam */ 307185377Ssam if (!ar5416FillCapabilityInfo(ah)) { 308185377Ssam ecode = HAL_EEREAD; 309185377Ssam goto bad; 310185377Ssam } 311185377Ssam 312185377Ssam ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr); 313185377Ssam if (ecode != HAL_OK) { 314185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, 315185377Ssam "%s: error getting mac address from EEPROM\n", __func__); 316185377Ssam goto bad; 317185377Ssam } 318185377Ssam /* XXX How about the serial number ? */ 319185377Ssam /* Read Reg Domain */ 320185377Ssam AH_PRIVATE(ah)->ah_currentRD = 321185377Ssam ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); 322185377Ssam 323185377Ssam /* 324185377Ssam * ah_miscMode is populated by ar5416FillCapabilityInfo() 325185377Ssam * starting from griffin. Set here to make sure that 326185377Ssam * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is 327185380Ssam * placed into hardware. 328185377Ssam */ 329185377Ssam if (ahp->ah_miscMode != 0) 330185377Ssam OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); 331185377Ssam 332185377Ssam HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: Attaching AR2133 radio\n", 333185377Ssam __func__); 334185377Ssam rfStatus = ar2133RfAttach(ah, &ecode); 335185377Ssam if (!rfStatus) { 336185377Ssam HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n", 337185377Ssam __func__, ecode); 338185377Ssam goto bad; 339185377Ssam } 340185377Ssam 341185377Ssam ar5416AniSetup(ah); /* Anti Noise Immunity */ 342185380Ssam ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist); 343185377Ssam 344185377Ssam HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__); 345185377Ssam 346185377Ssam return ah; 347185377Ssambad: 348185377Ssam if (ahp) 349185377Ssam ar5416Detach((struct ath_hal *) ahp); 350185377Ssam if (status) 351185377Ssam *status = ecode; 352185377Ssam return AH_NULL; 353185377Ssam} 354185377Ssam 355185377Ssamvoid 356185377Ssamar5416Detach(struct ath_hal *ah) 357185377Ssam{ 358185377Ssam HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s:\n", __func__); 359185377Ssam 360185377Ssam HALASSERT(ah != AH_NULL); 361185377Ssam HALASSERT(ah->ah_magic == AR5416_MAGIC); 362185377Ssam 363185380Ssam ar5416AniDetach(ah); 364185377Ssam ar5212RfDetach(ah); 365185377Ssam ah->ah_disable(ah); 366185377Ssam ar5416SetPowerMode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); 367185377Ssam ath_hal_eepromDetach(ah); 368185377Ssam ath_hal_free(ah); 369185377Ssam} 370185377Ssam 371185377Ssam/* 372185377Ssam * Fill all software cached or static hardware state information. 373185377Ssam * Return failure if capabilities are to come from EEPROM and 374185377Ssam * cannot be read. 375185377Ssam */ 376185377SsamHAL_BOOL 377185377Ssamar5416FillCapabilityInfo(struct ath_hal *ah) 378185377Ssam{ 379185377Ssam struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 380185377Ssam HAL_CAPABILITIES *pCap = &ahpriv->ah_caps; 381185377Ssam uint16_t val; 382185377Ssam 383185377Ssam /* Construct wireless mode from EEPROM */ 384185377Ssam pCap->halWirelessModes = 0; 385185377Ssam if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) { 386185377Ssam pCap->halWirelessModes |= HAL_MODE_11A 387185377Ssam | HAL_MODE_11NA_HT20 388185377Ssam | HAL_MODE_11NA_HT40PLUS 389185377Ssam | HAL_MODE_11NA_HT40MINUS 390185377Ssam ; 391185377Ssam } 392185377Ssam if (ath_hal_eepromGetFlag(ah, AR_EEP_GMODE)) { 393185377Ssam pCap->halWirelessModes |= HAL_MODE_11G 394185377Ssam | HAL_MODE_11NG_HT20 395185377Ssam | HAL_MODE_11NG_HT40PLUS 396185377Ssam | HAL_MODE_11NG_HT40MINUS 397185377Ssam ; 398185377Ssam pCap->halWirelessModes |= HAL_MODE_11A 399185377Ssam | HAL_MODE_11NA_HT20 400185377Ssam | HAL_MODE_11NA_HT40PLUS 401185377Ssam | HAL_MODE_11NA_HT40MINUS 402185377Ssam ; 403185377Ssam } 404185377Ssam 405185377Ssam pCap->halLow2GhzChan = 2312; 406185377Ssam pCap->halHigh2GhzChan = 2732; 407185377Ssam 408185377Ssam pCap->halLow5GhzChan = 4915; 409185377Ssam pCap->halHigh5GhzChan = 6100; 410185377Ssam 411185377Ssam pCap->halCipherCkipSupport = AH_FALSE; 412185377Ssam pCap->halCipherTkipSupport = AH_TRUE; 413185377Ssam pCap->halCipherAesCcmSupport = ath_hal_eepromGetFlag(ah, AR_EEP_AES); 414185377Ssam 415185377Ssam pCap->halMicCkipSupport = AH_FALSE; 416185377Ssam pCap->halMicTkipSupport = AH_TRUE; 417185377Ssam pCap->halMicAesCcmSupport = ath_hal_eepromGetFlag(ah, AR_EEP_AES); 418185377Ssam /* 419185377Ssam * Starting with Griffin TX+RX mic keys can be combined 420185377Ssam * in one key cache slot. 421185377Ssam */ 422185377Ssam pCap->halTkipMicTxRxKeySupport = AH_TRUE; 423185377Ssam pCap->halChanSpreadSupport = AH_TRUE; 424185377Ssam pCap->halSleepAfterBeaconBroken = AH_TRUE; 425185377Ssam 426185377Ssam pCap->halCompressSupport = AH_FALSE; 427185377Ssam pCap->halBurstSupport = AH_TRUE; 428185377Ssam pCap->halFastFramesSupport = AH_FALSE; /* XXX? */ 429185377Ssam pCap->halChapTuningSupport = AH_TRUE; 430185377Ssam pCap->halTurboPrimeSupport = AH_TRUE; 431185377Ssam 432185377Ssam pCap->halTurboGSupport = pCap->halWirelessModes & HAL_MODE_108G; 433185377Ssam 434185377Ssam pCap->halPSPollBroken = AH_TRUE; /* XXX fixed in later revs? */ 435185377Ssam pCap->halVEOLSupport = AH_TRUE; 436185377Ssam pCap->halBssIdMaskSupport = AH_TRUE; 437185377Ssam pCap->halMcastKeySrchSupport = AH_FALSE; 438185377Ssam pCap->halTsfAddSupport = AH_TRUE; 439185377Ssam 440185377Ssam if (ath_hal_eepromGet(ah, AR_EEP_MAXQCU, &val) == HAL_OK) 441185377Ssam pCap->halTotalQueues = val; 442185377Ssam else 443185377Ssam pCap->halTotalQueues = HAL_NUM_TX_QUEUES; 444185377Ssam 445185377Ssam if (ath_hal_eepromGet(ah, AR_EEP_KCENTRIES, &val) == HAL_OK) 446185377Ssam pCap->halKeyCacheSize = val; 447185377Ssam else 448185377Ssam pCap->halKeyCacheSize = AR5416_KEYTABLE_SIZE; 449185377Ssam 450185377Ssam /* XXX not needed */ 451185377Ssam pCap->halChanHalfRate = AH_FALSE; /* XXX ? */ 452185377Ssam pCap->halChanQuarterRate = AH_FALSE; /* XXX ? */ 453185377Ssam 454185377Ssam pCap->halTstampPrecision = 32; 455185377Ssam pCap->halHwPhyCounterSupport = AH_TRUE; 456185377Ssam 457185377Ssam pCap->halFastCCSupport = AH_TRUE; 458185377Ssam pCap->halNumGpioPins = 6; 459185377Ssam pCap->halWowSupport = AH_FALSE; 460185377Ssam pCap->halWowMatchPatternExact = AH_FALSE; 461185377Ssam pCap->halBtCoexSupport = AH_FALSE; /* XXX need support */ 462185377Ssam pCap->halAutoSleepSupport = AH_FALSE; 463185377Ssam#if 0 /* XXX not yet */ 464185377Ssam pCap->halNumAntCfg2GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_2GHZ); 465185377Ssam pCap->halNumAntCfg5GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_5GHZ); 466185377Ssam#endif 467185377Ssam pCap->halHTSupport = AH_TRUE; 468185377Ssam pCap->halTxChainMask = ath_hal_eepromGet(ah, AR_EEP_TXMASK, AH_NULL); 469185377Ssam /* XXX CB71 uses GPIO 0 to indicate 3 rx chains */ 470185377Ssam pCap->halRxChainMask = ath_hal_eepromGet(ah, AR_EEP_RXMASK, AH_NULL); 471185377Ssam pCap->halRtsAggrLimit = 8*1024; /* Owl 2.0 limit */ 472185377Ssam pCap->halMbssidAggrSupport = AH_TRUE; 473185377Ssam pCap->halForcePpmSupport = AH_TRUE; 474185377Ssam pCap->halEnhancedPmSupport = AH_TRUE; 475185377Ssam 476185377Ssam if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) && 477185377Ssam ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) { 478185377Ssam /* NB: enabled by default */ 479185377Ssam ahpriv->ah_rfkillEnabled = AH_TRUE; 480185377Ssam pCap->halRfSilentSupport = AH_TRUE; 481185377Ssam } 482185377Ssam 483185377Ssam ahpriv->ah_rxornIsFatal = AH_FALSE; 484185377Ssam 485185377Ssam return AH_TRUE; 486185377Ssam} 487185406Ssam 488185406Ssamstatic const char* 489185406Ssamar5416Probe(uint16_t vendorid, uint16_t devid) 490185406Ssam{ 491185406Ssam if (vendorid == ATHEROS_VENDOR_ID && 492185406Ssam (devid == AR5416_DEVID_PCI || devid == AR5416_DEVID_PCIE)) 493185406Ssam return "Atheros 5416"; 494185406Ssam return AH_NULL; 495185406Ssam} 496185418SsamAH_CHIP(AR5416, ar5416Probe, ar5416Attach); 497