ar9285_attach.c revision 251441
1/* 2 * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting 3 * Copyright (c) 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/ar9002/ar9285_attach.c 251441 2013-06-05 22:21:13Z adrian $ 18 */ 19#include "opt_ah.h" 20 21#include "ah.h" 22#include "ah_internal.h" 23#include "ah_devid.h" 24 25#include "ah_eeprom_v4k.h" /* XXX for tx/rx gain */ 26 27#include "ar9002/ar9280.h" 28#include "ar9002/ar9285.h" 29#include "ar5416/ar5416reg.h" 30#include "ar5416/ar5416phy.h" 31 32#include "ar9002/ar9285.ini" 33#include "ar9002/ar9285v2.ini" 34#include "ar9002/ar9280v2.ini" /* XXX ini for tx/rx gain */ 35 36#include "ar9002/ar9285_cal.h" 37#include "ar9002/ar9285_phy.h" 38#include "ar9002/ar9285_diversity.h" 39 40static const HAL_PERCAL_DATA ar9280_iq_cal = { /* single sample */ 41 .calName = "IQ", .calType = IQ_MISMATCH_CAL, 42 .calNumSamples = MIN_CAL_SAMPLES, 43 .calCountMax = PER_MAX_LOG_COUNT, 44 .calCollect = ar5416IQCalCollect, 45 .calPostProc = ar5416IQCalibration 46}; 47static const HAL_PERCAL_DATA ar9280_adc_gain_cal = { /* single sample */ 48 .calName = "ADC Gain", .calType = ADC_GAIN_CAL, 49 .calNumSamples = MIN_CAL_SAMPLES, 50 .calCountMax = PER_MIN_LOG_COUNT, 51 .calCollect = ar5416AdcGainCalCollect, 52 .calPostProc = ar5416AdcGainCalibration 53}; 54static const HAL_PERCAL_DATA ar9280_adc_dc_cal = { /* single sample */ 55 .calName = "ADC DC", .calType = ADC_DC_CAL, 56 .calNumSamples = MIN_CAL_SAMPLES, 57 .calCountMax = PER_MIN_LOG_COUNT, 58 .calCollect = ar5416AdcDcCalCollect, 59 .calPostProc = ar5416AdcDcCalibration 60}; 61static const HAL_PERCAL_DATA ar9280_adc_init_dc_cal = { 62 .calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL, 63 .calNumSamples = MIN_CAL_SAMPLES, 64 .calCountMax = INIT_LOG_COUNT, 65 .calCollect = ar5416AdcDcCalCollect, 66 .calPostProc = ar5416AdcDcCalibration 67}; 68 69static void ar9285ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore, 70 HAL_BOOL power_off); 71static void ar9285DisablePCIE(struct ath_hal *ah); 72static HAL_BOOL ar9285FillCapabilityInfo(struct ath_hal *ah); 73static void ar9285WriteIni(struct ath_hal *ah, 74 const struct ieee80211_channel *chan); 75 76static void 77ar9285AniSetup(struct ath_hal *ah) 78{ 79 /* 80 * These are the parameters from the AR5416 ANI code; 81 * they likely need quite a bit of adjustment for the 82 * AR9285. 83 */ 84 static const struct ar5212AniParams aniparams = { 85 .maxNoiseImmunityLevel = 4, /* levels 0..4 */ 86 .totalSizeDesired = { -55, -55, -55, -55, -62 }, 87 .coarseHigh = { -14, -14, -14, -14, -12 }, 88 .coarseLow = { -64, -64, -64, -64, -70 }, 89 .firpwr = { -78, -78, -78, -78, -80 }, 90 .maxSpurImmunityLevel = 7, 91 .cycPwrThr1 = { 2, 4, 6, 8, 10, 12, 14, 16 }, 92 .maxFirstepLevel = 2, /* levels 0..2 */ 93 .firstep = { 0, 4, 8 }, 94 .ofdmTrigHigh = 500, 95 .ofdmTrigLow = 200, 96 .cckTrigHigh = 200, 97 .cckTrigLow = 100, 98 .rssiThrHigh = 40, 99 .rssiThrLow = 7, 100 .period = 100, 101 }; 102 /* NB: disable ANI noise immmunity for reliable RIFS rx */ 103 AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL); 104 105 ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE); 106} 107 108static const char * ar9285_lna_conf[] = { 109 "LNA1-LNA2", 110 "LNA2", 111 "LNA1", 112 "LNA1+LNA2", 113}; 114 115static void 116ar9285_eeprom_print_diversity_settings(struct ath_hal *ah) 117{ 118 const HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom; 119 const MODAL_EEP4K_HEADER *pModal = &ee->ee_base.modalHeader; 120 121 ath_hal_printf(ah, "[ath] AR9285 Main LNA config: %s\n", 122 ar9285_lna_conf[(pModal->antdiv_ctl2 >> 2) & 0x3]); 123 ath_hal_printf(ah, "[ath] AR9285 Alt LNA config: %s\n", 124 ar9285_lna_conf[pModal->antdiv_ctl2 & 0x3]); 125 ath_hal_printf(ah, "[ath] LNA diversity %s, Diversity %s\n", 126 ((pModal->antdiv_ctl1 & 0x1) ? "enabled" : "disabled"), 127 ((pModal->antdiv_ctl1 & 0x8) ? "enabled" : "disabled")); 128} 129 130/* 131 * Attach for an AR9285 part. 132 */ 133static struct ath_hal * 134ar9285Attach(uint16_t devid, HAL_SOFTC sc, 135 HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, 136 HAL_STATUS *status) 137{ 138 struct ath_hal_9285 *ahp9285; 139 struct ath_hal_5212 *ahp; 140 struct ath_hal *ah; 141 uint32_t val; 142 HAL_STATUS ecode; 143 HAL_BOOL rfStatus; 144 145 HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", 146 __func__, sc, (void*) st, (void*) sh); 147 148 /* NB: memory is returned zero'd */ 149 ahp9285 = ath_hal_malloc(sizeof (struct ath_hal_9285)); 150 if (ahp9285 == AH_NULL) { 151 HALDEBUG(AH_NULL, HAL_DEBUG_ANY, 152 "%s: cannot allocate memory for state block\n", __func__); 153 *status = HAL_ENOMEM; 154 return AH_NULL; 155 } 156 ahp = AH5212(ahp9285); 157 ah = &ahp->ah_priv.h; 158 159 ar5416InitState(AH5416(ah), devid, sc, st, sh, status); 160 161 /* 162 * Use the "local" EEPROM data given to us by the higher layers. 163 * This is a private copy out of system flash. The Linux ath9k 164 * commit for the initial AR9130 support mentions MMIO flash 165 * access is "unreliable." -adrian 166 */ 167 if (eepromdata != AH_NULL) { 168 AH_PRIVATE(ah)->ah_eepromRead = ath_hal_EepromDataRead; 169 AH_PRIVATE(ah)->ah_eepromWrite = NULL; 170 ah->ah_eepromdata = eepromdata; 171 } 172 173 /* override with 9285 specific state */ 174 AH5416(ah)->ah_initPLL = ar9280InitPLL; 175 AH5416(ah)->ah_btCoexSetDiversity = ar5416BTCoexAntennaDiversity; 176 177 ah->ah_setAntennaSwitch = ar9285SetAntennaSwitch; 178 ah->ah_configPCIE = ar9285ConfigPCIE; 179 ah->ah_disablePCIE = ar9285DisablePCIE; 180 ah->ah_setTxPower = ar9285SetTransmitPower; 181 ah->ah_setBoardValues = ar9285SetBoardValues; 182 ah->ah_btcoexSetParameter = ar9285BTCoexSetParameter; 183 184 AH5416(ah)->ah_cal.iqCalData.calData = &ar9280_iq_cal; 185 AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9280_adc_gain_cal; 186 AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9280_adc_dc_cal; 187 AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9280_adc_init_dc_cal; 188 AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; 189 190 AH5416(ah)->ah_spurMitigate = ar9280SpurMitigate; 191 AH5416(ah)->ah_writeIni = ar9285WriteIni; 192 AH5416(ah)->ah_rx_chainmask = AR9285_DEFAULT_RXCHAINMASK; 193 AH5416(ah)->ah_tx_chainmask = AR9285_DEFAULT_TXCHAINMASK; 194 195 ahp->ah_maxTxTrigLev = MAX_TX_FIFO_THRESHOLD >> 1; 196 197 if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) { 198 /* reset chip */ 199 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n", 200 __func__); 201 ecode = HAL_EIO; 202 goto bad; 203 } 204 205 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 206 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n", 207 __func__); 208 ecode = HAL_EIO; 209 goto bad; 210 } 211 /* Read Revisions from Chips before taking out of reset */ 212 val = OS_REG_READ(ah, AR_SREV); 213 HALDEBUG(ah, HAL_DEBUG_ATTACH, 214 "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n", 215 __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION), 216 MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION)); 217 /* NB: include chip type to differentiate from pre-Sowl versions */ 218 AH_PRIVATE(ah)->ah_macVersion = 219 (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S; 220 AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION); 221 AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0; 222 223 /* setup common ini data; rf backends handle remainder */ 224 if (AR_SREV_KITE_12_OR_LATER(ah)) { 225 HAL_INI_INIT(&ahp->ah_ini_modes, ar9285Modes_v2, 6); 226 HAL_INI_INIT(&ahp->ah_ini_common, ar9285Common_v2, 2); 227 HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes, 228 ar9285PciePhy_clkreq_always_on_L1_v2, 2); 229 } else { 230 HAL_INI_INIT(&ahp->ah_ini_modes, ar9285Modes, 6); 231 HAL_INI_INIT(&ahp->ah_ini_common, ar9285Common, 2); 232 HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes, 233 ar9285PciePhy_clkreq_always_on_L1, 2); 234 } 235 ar5416AttachPCIE(ah); 236 237 /* Attach methods that require MAC version/revision info */ 238 if (AR_SREV_KITE_12_OR_LATER(ah)) 239 AH5416(ah)->ah_cal_initcal = ar9285InitCalHardware; 240 if (AR_SREV_KITE_11_OR_LATER(ah)) 241 AH5416(ah)->ah_cal_pacal = ar9002_hw_pa_cal; 242 243 ecode = ath_hal_v4kEepromAttach(ah); 244 if (ecode != HAL_OK) 245 goto bad; 246 247 if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */ 248 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", 249 __func__); 250 ecode = HAL_EIO; 251 goto bad; 252 } 253 254 AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID); 255 256 if (!ar5212ChipTest(ah)) { 257 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n", 258 __func__); 259 ecode = HAL_ESELFTEST; 260 goto bad; 261 } 262 263 /* 264 * Set correct Baseband to analog shift 265 * setting to access analog chips. 266 */ 267 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 268 269 /* Read Radio Chip Rev Extract */ 270 AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah); 271 switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) { 272 case AR_RAD2133_SREV_MAJOR: /* Sowl: 2G/3x3 */ 273 case AR_RAD5133_SREV_MAJOR: /* Sowl: 2+5G/3x3 */ 274 break; 275 default: 276 if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) { 277 AH_PRIVATE(ah)->ah_analog5GhzRev = 278 AR_RAD5133_SREV_MAJOR; 279 break; 280 } 281#ifdef AH_DEBUG 282 HALDEBUG(ah, HAL_DEBUG_ANY, 283 "%s: 5G Radio Chip Rev 0x%02X is not supported by " 284 "this driver\n", __func__, 285 AH_PRIVATE(ah)->ah_analog5GhzRev); 286 ecode = HAL_ENOTSUPP; 287 goto bad; 288#endif 289 } 290 rfStatus = ar9285RfAttach(ah, &ecode); 291 if (!rfStatus) { 292 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n", 293 __func__, ecode); 294 goto bad; 295 } 296 297 HAL_INI_INIT(&ahp9285->ah_ini_rxgain, ar9280Modes_original_rxgain_v2, 298 6); 299 300 if (AR_SREV_9285E_20(ah)) 301 ath_hal_printf(ah, "[ath] AR9285E_20 detected; using XE TX gain tables\n"); 302 303 /* setup txgain table */ 304 switch (ath_hal_eepromGet(ah, AR_EEP_TXGAIN_TYPE, AH_NULL)) { 305 case AR5416_EEP_TXGAIN_HIGH_POWER: 306 if (AR_SREV_9285E_20(ah)) 307 HAL_INI_INIT(&ahp9285->ah_ini_txgain, 308 ar9285Modes_XE2_0_high_power, 6); 309 else 310 HAL_INI_INIT(&ahp9285->ah_ini_txgain, 311 ar9285Modes_high_power_tx_gain_v2, 6); 312 break; 313 case AR5416_EEP_TXGAIN_ORIG: 314 if (AR_SREV_9285E_20(ah)) 315 HAL_INI_INIT(&ahp9285->ah_ini_txgain, 316 ar9285Modes_XE2_0_normal_power, 6); 317 else 318 HAL_INI_INIT(&ahp9285->ah_ini_txgain, 319 ar9285Modes_original_tx_gain_v2, 6); 320 break; 321 default: 322 HALASSERT(AH_FALSE); 323 goto bad; /* XXX ? try to continue */ 324 } 325 326 /* 327 * Got everything we need now to setup the capabilities. 328 */ 329 if (!ar9285FillCapabilityInfo(ah)) { 330 ecode = HAL_EEREAD; 331 goto bad; 332 } 333 334 /* 335 * Print out the EEPROM antenna configuration mapping. 336 * Some devices have a hard-coded LNA configuration profile; 337 * others enable diversity. 338 */ 339 ar9285_eeprom_print_diversity_settings(ah); 340 341 /* Print out whether the EEPROM settings enable AR9285 diversity */ 342 if (ar9285_check_div_comb(ah)) { 343 ath_hal_printf(ah, "[ath] Enabling diversity for Kite\n"); 344 ah->ah_rxAntCombDiversity = ar9285_ant_comb_scan; 345 } 346 347 /* Disable 11n for the AR2427 */ 348 if (devid == AR2427_DEVID_PCIE) 349 AH_PRIVATE(ah)->ah_caps.halHTSupport = AH_FALSE; 350 351 ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr); 352 if (ecode != HAL_OK) { 353 HALDEBUG(ah, HAL_DEBUG_ANY, 354 "%s: error getting mac address from EEPROM\n", __func__); 355 goto bad; 356 } 357 /* XXX How about the serial number ? */ 358 /* Read Reg Domain */ 359 AH_PRIVATE(ah)->ah_currentRD = 360 ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); 361 /* 362 * For Kite and later chipsets, the following bits are not 363 * programmed in EEPROM and so are set as enabled always. 364 */ 365 AH_PRIVATE(ah)->ah_currentRDext = AR9285_RDEXT_DEFAULT; 366 367 /* 368 * ah_miscMode is populated by ar5416FillCapabilityInfo() 369 * starting from griffin. Set here to make sure that 370 * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is 371 * placed into hardware. 372 */ 373 if (ahp->ah_miscMode != 0) 374 OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode); 375 376 ar9285AniSetup(ah); /* Anti Noise Immunity */ 377 378 /* Setup noise floor min/max/nominal values */ 379 AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ; 380 AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ; 381 AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9285_2GHZ; 382 /* XXX no 5ghz values? */ 383 384 ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist); 385 386 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__); 387 388 return ah; 389bad: 390 if (ah != AH_NULL) 391 ah->ah_detach(ah); 392 if (status) 393 *status = ecode; 394 return AH_NULL; 395} 396 397static void 398ar9285ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore, HAL_BOOL power_off) 399{ 400 uint32_t val; 401 402 /* 403 * This workaround needs some integration work with the HAL 404 * config parameters and the if_ath_pci.c glue. 405 * Specifically, read the value of the PCI register 0x70c 406 * (4 byte PCI config space register) and store it in ath_hal_war70c. 407 * Then if it's non-zero, the below WAR would override register 408 * 0x570c upon suspend/resume. 409 */ 410#if 0 411 if (AR_SREV_9285E_20(ah)) { 412 val = AH_PRIVATE(ah)->ah_config.ath_hal_war70c; 413 if (val) { 414 val &= 0xffff00ff; 415 val |= 0x6f00; 416 OS_REG_WRITE(ah, 0x570c, val); 417 } 418 } 419#endif 420 421 if (AH_PRIVATE(ah)->ah_ispcie && !restore) { 422 ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0); 423 OS_DELAY(1000); 424 } 425 426 /* 427 * Set PCIe workaround bits 428 * 429 * NOTE: 430 * 431 * In Merlin and Kite, bit 14 in WA register (disable L1) should only 432 * be set when device enters D3 and be cleared when device comes back 433 * to D0. 434 */ 435 if (power_off) { /* Power-off */ 436 OS_REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 437 438 val = OS_REG_READ(ah, AR_WA); 439 440 /* 441 * Disable bit 6 and 7 before entering D3 to prevent 442 * system hang. 443 */ 444 val &= ~(AR_WA_BIT6 | AR_WA_BIT7); 445 446 /* 447 * See above: set AR_WA_D3_L1_DISABLE when entering D3 state. 448 * 449 * XXX The reference HAL does it this way - it only sets 450 * AR_WA_D3_L1_DISABLE if it's set in AR9280_WA_DEFAULT, 451 * which it (currently) isn't. So the following statement 452 * is currently a NOP. 453 */ 454 if (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE) 455 val |= AR_WA_D3_L1_DISABLE; 456 457 if (AR_SREV_9285E_20(ah)) 458 val |= AR_WA_BIT23; 459 460 OS_REG_WRITE(ah, AR_WA, val); 461 } else { /* Power-on */ 462 val = AR9285_WA_DEFAULT; 463 /* 464 * See note above: make sure L1_DISABLE is not set. 465 */ 466 val &= (~AR_WA_D3_L1_DISABLE); 467 468 /* Software workaroud for ASPM system hang. */ 469 val |= (AR_WA_BIT6 | AR_WA_BIT7); 470 471 if (AR_SREV_9285E_20(ah)) 472 val |= AR_WA_BIT23; 473 474 OS_REG_WRITE(ah, AR_WA, val); 475 476 /* set bit 19 to allow forcing of pcie core into L1 state */ 477 OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 478 } 479} 480 481static void 482ar9285DisablePCIE(struct ath_hal *ah) 483{ 484} 485 486static void 487ar9285WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan) 488{ 489 u_int modesIndex, freqIndex; 490 int regWrites = 0; 491 492 /* Setup the indices for the next set of register array writes */ 493 /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */ 494 freqIndex = 2; 495 if (IEEE80211_IS_CHAN_HT40(chan)) 496 modesIndex = 3; 497 else if (IEEE80211_IS_CHAN_108G(chan)) 498 modesIndex = 5; 499 else 500 modesIndex = 4; 501 502 /* Set correct Baseband to analog shift setting to access analog chips. */ 503 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 504 OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); 505 regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes, 506 modesIndex, regWrites); 507 if (AR_SREV_KITE_12_OR_LATER(ah)) { 508 regWrites = ath_hal_ini_write(ah, &AH9285(ah)->ah_ini_txgain, 509 modesIndex, regWrites); 510 } 511 regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common, 512 1, regWrites); 513} 514 515/* 516 * Fill all software cached or static hardware state information. 517 * Return failure if capabilities are to come from EEPROM and 518 * cannot be read. 519 */ 520static HAL_BOOL 521ar9285FillCapabilityInfo(struct ath_hal *ah) 522{ 523 HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; 524 525 if (!ar5416FillCapabilityInfo(ah)) 526 return AH_FALSE; 527 pCap->halNumGpioPins = 12; 528 pCap->halWowSupport = AH_TRUE; 529 pCap->halWowMatchPatternExact = AH_TRUE; 530#if 0 531 pCap->halWowMatchPatternDword = AH_TRUE; 532#endif 533 /* AR9285 has 2 antennas but is a 1x1 stream device */ 534 pCap->halTxStreams = 1; 535 pCap->halRxStreams = 1; 536 537 if (ar9285_check_div_comb(ah)) 538 pCap->halAntDivCombSupport = AH_TRUE; 539 540 pCap->halCSTSupport = AH_TRUE; 541 pCap->halRifsRxSupport = AH_TRUE; 542 pCap->halRifsTxSupport = AH_TRUE; 543 pCap->halRtsAggrLimit = 64*1024; /* 802.11n max */ 544 pCap->halExtChanDfsSupport = AH_TRUE; 545 pCap->halUseCombinedRadarRssi = AH_TRUE; 546#if 0 547 /* XXX bluetooth */ 548 pCap->halBtCoexSupport = AH_TRUE; 549#endif 550 pCap->halAutoSleepSupport = AH_FALSE; /* XXX? */ 551 pCap->hal4kbSplitTransSupport = AH_FALSE; 552 /* Disable this so Block-ACK works correctly */ 553 pCap->halHasRxSelfLinkedTail = AH_FALSE; 554 pCap->halMbssidAggrSupport = AH_TRUE; 555 pCap->hal4AddrAggrSupport = AH_TRUE; 556 pCap->halSpectralScanSupport = AH_TRUE; 557 pCap->halRxUsingLnaMixing = AH_TRUE; 558 559 if (AR_SREV_KITE_12_OR_LATER(ah)) 560 pCap->halPSPollBroken = AH_FALSE; 561 562 /* Only RX STBC supported */ 563 pCap->halRxStbcSupport = 1; 564 pCap->halTxStbcSupport = 0; 565 566 return AH_TRUE; 567} 568 569static const char* 570ar9285Probe(uint16_t vendorid, uint16_t devid) 571{ 572 if (vendorid == ATHEROS_VENDOR_ID && devid == AR9285_DEVID_PCIE) 573 return "Atheros 9285"; 574 if (vendorid == ATHEROS_VENDOR_ID && (devid == AR2427_DEVID_PCIE)) 575 return "Atheros 2427"; 576 577 return AH_NULL; 578} 579AH_CHIP(AR9285, ar9285Probe, ar9285Attach); 580