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