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