ar9280_attach.c revision 221603
138032Speter/* 2132943Sgshapiro * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting 364562Sgshapiro * Copyright (c) 2008 Atheros Communications, Inc. 438032Speter * 538032Speter * Permission to use, copy, modify, and/or distribute this software for any 638032Speter * purpose with or without fee is hereby granted, provided that the above 738032Speter * copyright notice and this permission notice appear in all copies. 838032Speter * 938032Speter * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1038032Speter * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1138032Speter * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1238032Speter * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1338032Speter * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1464562Sgshapiro * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1564562Sgshapiro * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16132943Sgshapiro * 1738032Speter * $FreeBSD: head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c 221603 2011-05-07 15:30:23Z adrian $ 1890792Sgshapiro */ 1938032Speter#include "opt_ah.h" 2090792Sgshapiro 2190792Sgshapiro#include "ah.h" 2290792Sgshapiro#include "ah_internal.h" 23120256Sgshapiro#include "ah_devid.h" 2490792Sgshapiro 25125820Sgshapiro#include "ah_eeprom_v14.h" /* XXX for tx/rx gain */ 26125820Sgshapiro 27125820Sgshapiro#include "ar9002/ar9280.h" 28125820Sgshapiro#include "ar5416/ar5416reg.h" 29125820Sgshapiro#include "ar5416/ar5416phy.h" 30125820Sgshapiro 31120256Sgshapiro#include "ar9002/ar9280v1.ini" 32125820Sgshapiro#include "ar9002/ar9280v2.ini" 33125820Sgshapiro#include "ar9002/ar9280_olc.h" 34125820Sgshapiro 35125820Sgshapirostatic const HAL_PERCAL_DATA ar9280_iq_cal = { /* single sample */ 3690792Sgshapiro .calName = "IQ", .calType = IQ_MISMATCH_CAL, 3790792Sgshapiro .calNumSamples = MIN_CAL_SAMPLES, 38120256Sgshapiro .calCountMax = PER_MAX_LOG_COUNT, 39120256Sgshapiro .calCollect = ar5416IQCalCollect, 40132943Sgshapiro .calPostProc = ar5416IQCalibration 41132943Sgshapiro}; 42132943Sgshapirostatic const HAL_PERCAL_DATA ar9280_adc_gain_cal = { /* single sample */ 4390792Sgshapiro .calName = "ADC Gain", .calType = ADC_GAIN_CAL, 4490792Sgshapiro .calNumSamples = MIN_CAL_SAMPLES, 45132943Sgshapiro .calCountMax = PER_MIN_LOG_COUNT, 46132943Sgshapiro .calCollect = ar5416AdcGainCalCollect, 4790792Sgshapiro .calPostProc = ar5416AdcGainCalibration 4890792Sgshapiro}; 4964562Sgshapirostatic const HAL_PERCAL_DATA ar9280_adc_dc_cal = { /* single sample */ 5090792Sgshapiro .calName = "ADC DC", .calType = ADC_DC_CAL, 5190792Sgshapiro .calNumSamples = MIN_CAL_SAMPLES, 5238032Speter .calCountMax = PER_MIN_LOG_COUNT, 5338032Speter .calCollect = ar5416AdcDcCalCollect, 5438032Speter .calPostProc = ar5416AdcDcCalibration 5538032Speter}; 5638032Speterstatic const HAL_PERCAL_DATA ar9280_adc_init_dc_cal = { 5738032Speter .calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL, 5838032Speter .calNumSamples = MIN_CAL_SAMPLES, 5938032Speter .calCountMax = INIT_LOG_COUNT, 6038032Speter .calCollect = ar5416AdcDcCalCollect, 6138032Speter .calPostProc = ar5416AdcDcCalibration 6238032Speter}; 6390792Sgshapiro 6490792Sgshapirostatic void ar9280ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore); 6590792Sgshapirostatic HAL_BOOL ar9280FillCapabilityInfo(struct ath_hal *ah); 6690792Sgshapirostatic void ar9280WriteIni(struct ath_hal *ah, 6738032Speter const struct ieee80211_channel *chan); 6838032Speter 6938032Speterstatic void 7038032Speterar9280AniSetup(struct ath_hal *ah) 7138032Speter{ 7290792Sgshapiro /* 7390792Sgshapiro * These are the parameters from the AR5416 ANI code; 74120256Sgshapiro * they likely need quite a bit of adjustment for the 7538032Speter * AR9280. 76120256Sgshapiro */ 77120256Sgshapiro static const struct ar5212AniParams aniparams = { 78120256Sgshapiro .maxNoiseImmunityLevel = 4, /* levels 0..4 */ 79120256Sgshapiro .totalSizeDesired = { -55, -55, -55, -55, -62 }, 80120256Sgshapiro .coarseHigh = { -14, -14, -14, -14, -12 }, 81120256Sgshapiro .coarseLow = { -64, -64, -64, -64, -70 }, 82120256Sgshapiro .firpwr = { -78, -78, -78, -78, -80 }, 83120256Sgshapiro .maxSpurImmunityLevel = 2, 84120256Sgshapiro .cycPwrThr1 = { 2, 4, 6 }, 85120256Sgshapiro .maxFirstepLevel = 2, /* levels 0..2 */ 86120256Sgshapiro .firstep = { 0, 4, 8 }, 87120256Sgshapiro .ofdmTrigHigh = 500, 88120256Sgshapiro .ofdmTrigLow = 200, 89120256Sgshapiro .cckTrigHigh = 200, 9090792Sgshapiro .cckTrigLow = 100, 9194334Sgshapiro .rssiThrHigh = 40, 9294334Sgshapiro .rssiThrLow = 7, 9390792Sgshapiro .period = 100, 9490792Sgshapiro }; 95111823Sgshapiro /* NB: disable ANI noise immmunity for reliable RIFS rx */ 9690792Sgshapiro AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL; 9790792Sgshapiro 9890792Sgshapiro /* NB: ANI is not enabled yet */ 9990792Sgshapiro ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE); 10090792Sgshapiro} 10190792Sgshapiro 10290792Sgshapiro/* 10390792Sgshapiro * Attach for an AR9280 part. 10490792Sgshapiro */ 10590792Sgshapirostatic struct ath_hal * 10690792Sgshapiroar9280Attach(uint16_t devid, HAL_SOFTC sc, 10790792Sgshapiro HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, 10890792Sgshapiro HAL_STATUS *status) 10990792Sgshapiro{ 11090792Sgshapiro struct ath_hal_9280 *ahp9280; 11190792Sgshapiro struct ath_hal_5212 *ahp; 11290792Sgshapiro struct ath_hal *ah; 11390792Sgshapiro uint32_t val; 11490792Sgshapiro HAL_STATUS ecode; 11590792Sgshapiro HAL_BOOL rfStatus; 11690792Sgshapiro int8_t pwr_table_offset; 11790792Sgshapiro uint8_t pwr; 11890792Sgshapiro 11990792Sgshapiro HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", 12090792Sgshapiro __func__, sc, (void*) st, (void*) sh); 12190792Sgshapiro 12290792Sgshapiro /* NB: memory is returned zero'd */ 12390792Sgshapiro ahp9280 = ath_hal_malloc(sizeof (struct ath_hal_9280)); 12490792Sgshapiro if (ahp9280 == AH_NULL) { 12590792Sgshapiro HALDEBUG(AH_NULL, HAL_DEBUG_ANY, 12690792Sgshapiro "%s: cannot allocate memory for state block\n", __func__); 12790792Sgshapiro *status = HAL_ENOMEM; 12890792Sgshapiro return AH_NULL; 12990792Sgshapiro } 13090792Sgshapiro ahp = AH5212(ahp9280); 13190792Sgshapiro ah = &ahp->ah_priv.h; 13290792Sgshapiro 13390792Sgshapiro ar5416InitState(AH5416(ah), devid, sc, st, sh, status); 13490792Sgshapiro 13590792Sgshapiro /* XXX override with 9280 specific state */ 13690792Sgshapiro /* override 5416 methods for our needs */ 13790792Sgshapiro ah->ah_setAntennaSwitch = ar9280SetAntennaSwitch; 13890792Sgshapiro ah->ah_configPCIE = ar9280ConfigPCIE; 13990792Sgshapiro 14090792Sgshapiro AH5416(ah)->ah_cal.iqCalData.calData = &ar9280_iq_cal; 14190792Sgshapiro AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9280_adc_gain_cal; 14294334Sgshapiro AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9280_adc_dc_cal; 14364562Sgshapiro AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9280_adc_init_dc_cal; 14490792Sgshapiro AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; 14590792Sgshapiro 14690792Sgshapiro AH5416(ah)->ah_spurMitigate = ar9280SpurMitigate; 14790792Sgshapiro AH5416(ah)->ah_writeIni = ar9280WriteIni; 14890792Sgshapiro AH5416(ah)->ah_olcInit = ar9280olcInit; 14964562Sgshapiro AH5416(ah)->ah_olcTempCompensation = ar9280olcTemperatureCompensation; 15064562Sgshapiro AH5416(ah)->ah_setPowerCalTable = ar9280SetPowerCalTable; 15164562Sgshapiro 15264562Sgshapiro AH5416(ah)->ah_rx_chainmask = AR9280_DEFAULT_RXCHAINMASK; 15364562Sgshapiro AH5416(ah)->ah_tx_chainmask = AR9280_DEFAULT_TXCHAINMASK; 154110560Sgshapiro 15590792Sgshapiro if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) { 15690792Sgshapiro /* reset chip */ 15790792Sgshapiro HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n", 15890792Sgshapiro __func__); 15990792Sgshapiro ecode = HAL_EIO; 16038032Speter goto bad; 16190792Sgshapiro } 16290792Sgshapiro 16390792Sgshapiro if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 16490792Sgshapiro HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n", 16590792Sgshapiro __func__); 16690792Sgshapiro ecode = HAL_EIO; 16780785Sgshapiro goto bad; 16890792Sgshapiro } 16990792Sgshapiro /* Read Revisions from Chips before taking out of reset */ 17090792Sgshapiro val = OS_REG_READ(ah, AR_SREV); 17190792Sgshapiro HALDEBUG(ah, HAL_DEBUG_ATTACH, 17290792Sgshapiro "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n", 17390792Sgshapiro __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION), 17490792Sgshapiro MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION)); 17590792Sgshapiro /* NB: include chip type to differentiate from pre-Sowl versions */ 17690792Sgshapiro AH_PRIVATE(ah)->ah_macVersion = 17790792Sgshapiro (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S; 17890792Sgshapiro AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION); 17990792Sgshapiro AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0; 18090792Sgshapiro 18190792Sgshapiro /* setup common ini data; rf backends handle remainder */ 18290792Sgshapiro if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 18390792Sgshapiro HAL_INI_INIT(&ahp->ah_ini_modes, ar9280Modes_v2, 6); 18490792Sgshapiro HAL_INI_INIT(&ahp->ah_ini_common, ar9280Common_v2, 2); 18590792Sgshapiro HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes, 18690792Sgshapiro ar9280PciePhy_clkreq_always_on_L1_v2, 2); 18790792Sgshapiro HAL_INI_INIT(&ahp9280->ah_ini_xmodes, 18890792Sgshapiro ar9280Modes_fast_clock_v2, 3); 18990792Sgshapiro } else { 19090792Sgshapiro HAL_INI_INIT(&ahp->ah_ini_modes, ar9280Modes_v1, 6); 19190792Sgshapiro HAL_INI_INIT(&ahp->ah_ini_common, ar9280Common_v1, 2); 19290792Sgshapiro HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes, 19390792Sgshapiro ar9280PciePhy_v1, 2); 19490792Sgshapiro } 19590792Sgshapiro ar5416AttachPCIE(ah); 19690792Sgshapiro 19790792Sgshapiro ecode = ath_hal_v14EepromAttach(ah); 19890792Sgshapiro if (ecode != HAL_OK) 19990792Sgshapiro goto bad; 20090792Sgshapiro 20190792Sgshapiro if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */ 20290792Sgshapiro HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__); 20390792Sgshapiro ecode = HAL_EIO; 20490792Sgshapiro goto bad; 20590792Sgshapiro } 20690792Sgshapiro 20790792Sgshapiro AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID); 20890792Sgshapiro 20990792Sgshapiro if (!ar5212ChipTest(ah)) { 21090792Sgshapiro HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n", 21190792Sgshapiro __func__); 21290792Sgshapiro ecode = HAL_ESELFTEST; 21390792Sgshapiro goto bad; 21490792Sgshapiro } 21590792Sgshapiro 21690792Sgshapiro /* 21790792Sgshapiro * Set correct Baseband to analog shift 21890792Sgshapiro * setting to access analog chips. 219110560Sgshapiro */ 22090792Sgshapiro OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 22190792Sgshapiro 22290792Sgshapiro /* Read Radio Chip Rev Extract */ 22390792Sgshapiro AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah); 22490792Sgshapiro switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) { 22590792Sgshapiro case AR_RAD2133_SREV_MAJOR: /* Sowl: 2G/3x3 */ 22690792Sgshapiro case AR_RAD5133_SREV_MAJOR: /* Sowl: 2+5G/3x3 */ 22790792Sgshapiro break; 22890792Sgshapiro default: 22990792Sgshapiro if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) { 23090792Sgshapiro AH_PRIVATE(ah)->ah_analog5GhzRev = 23190792Sgshapiro AR_RAD5133_SREV_MAJOR; 23290792Sgshapiro break; 23390792Sgshapiro } 23490792Sgshapiro#ifdef AH_DEBUG 23590792Sgshapiro HALDEBUG(ah, HAL_DEBUG_ANY, 23690792Sgshapiro "%s: 5G Radio Chip Rev 0x%02X is not supported by " 23790792Sgshapiro "this driver\n", __func__, 23890792Sgshapiro AH_PRIVATE(ah)->ah_analog5GhzRev); 23990792Sgshapiro ecode = HAL_ENOTSUPP; 24090792Sgshapiro goto bad; 241112810Sgshapiro#endif 24290792Sgshapiro } 24390792Sgshapiro rfStatus = ar9280RfAttach(ah, &ecode); 24490792Sgshapiro if (!rfStatus) { 24590792Sgshapiro HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n", 24690792Sgshapiro __func__, ecode); 24790792Sgshapiro goto bad; 24890792Sgshapiro } 24990792Sgshapiro 25090792Sgshapiro /* Enable fixup for AR_AN_TOP2 if necessary */ 25190792Sgshapiro /* 25290792Sgshapiro * The v14 EEPROM layer returns HAL_EIO if PWDCLKIND isn't supported 25390792Sgshapiro * by the EEPROM version. 25490792Sgshapiro * 25590792Sgshapiro * ath9k checks the EEPROM minor version is >= 0x0a here, instead of 25690792Sgshapiro * the abstracted EEPROM access layer. 25790792Sgshapiro */ 25890792Sgshapiro ecode = ath_hal_eepromGet(ah, AR_EEP_PWDCLKIND, &pwr); 25990792Sgshapiro if (AR_SREV_MERLIN_20_OR_LATER(ah) && ecode == HAL_OK && pwr == 0) { 26090792Sgshapiro printf("[ath] enabling AN_TOP2_FIXUP\n"); 26190792Sgshapiro AH5416(ah)->ah_need_an_top2_fixup = 1; 26290792Sgshapiro } 26390792Sgshapiro 26490792Sgshapiro /* 26590792Sgshapiro * Check whether the power table offset isn't the default. 26690792Sgshapiro * This can occur with eeprom minor V21 or greater on Merlin. 26790792Sgshapiro */ 26890792Sgshapiro (void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET, &pwr_table_offset); 26990792Sgshapiro if (pwr_table_offset != AR5416_PWR_TABLE_OFFSET_DB) 27090792Sgshapiro ath_hal_printf(ah, "[ath]: default pwr offset: %d dBm != EEPROM pwr offset: %d dBm; curves will be adjusted.\n", 27190792Sgshapiro AR5416_PWR_TABLE_OFFSET_DB, (int) pwr_table_offset); 27290792Sgshapiro 27390792Sgshapiro if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 27490792Sgshapiro /* setup rxgain table */ 27590792Sgshapiro switch (ath_hal_eepromGet(ah, AR_EEP_RXGAIN_TYPE, AH_NULL)) { 27690792Sgshapiro case AR5416_EEP_RXGAIN_13dB_BACKOFF: 277110560Sgshapiro HAL_INI_INIT(&ahp9280->ah_ini_rxgain, 27890792Sgshapiro ar9280Modes_backoff_13db_rxgain_v2, 6); 27990792Sgshapiro break; 28090792Sgshapiro case AR5416_EEP_RXGAIN_23dB_BACKOFF: 28190792Sgshapiro HAL_INI_INIT(&ahp9280->ah_ini_rxgain, 28290792Sgshapiro ar9280Modes_backoff_23db_rxgain_v2, 6); 28390792Sgshapiro break; 28490792Sgshapiro case AR5416_EEP_RXGAIN_ORIG: 28590792Sgshapiro HAL_INI_INIT(&ahp9280->ah_ini_rxgain, 28690792Sgshapiro ar9280Modes_original_rxgain_v2, 6); 28790792Sgshapiro break; 288110560Sgshapiro default: 28990792Sgshapiro HALASSERT(AH_FALSE); 29080785Sgshapiro goto bad; /* XXX ? try to continue */ 29180785Sgshapiro } 29280785Sgshapiro } 29380785Sgshapiro if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 29480785Sgshapiro /* setp txgain table */ 29580785Sgshapiro switch (ath_hal_eepromGet(ah, AR_EEP_TXGAIN_TYPE, AH_NULL)) { 29690792Sgshapiro case AR5416_EEP_TXGAIN_HIGH_POWER: 29780785Sgshapiro HAL_INI_INIT(&ahp9280->ah_ini_txgain, 29880785Sgshapiro ar9280Modes_high_power_tx_gain_v2, 6); 299132943Sgshapiro break; 30080785Sgshapiro case AR5416_EEP_TXGAIN_ORIG: 30180785Sgshapiro HAL_INI_INIT(&ahp9280->ah_ini_txgain, 30280785Sgshapiro ar9280Modes_original_tx_gain_v2, 6); 30380785Sgshapiro break; 30498841Sgshapiro default: 30580785Sgshapiro HALASSERT(AH_FALSE); 30680785Sgshapiro goto bad; /* XXX ? try to continue */ 307132943Sgshapiro } 30880785Sgshapiro } 30990792Sgshapiro 31080785Sgshapiro /* 31180785Sgshapiro * Got everything we need now to setup the capabilities. 31280785Sgshapiro */ 31380785Sgshapiro if (!ar9280FillCapabilityInfo(ah)) { 31490792Sgshapiro ecode = HAL_EEREAD; 315132943Sgshapiro goto bad; 31680785Sgshapiro } 31790792Sgshapiro 31880785Sgshapiro ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr); 31980785Sgshapiro if (ecode != HAL_OK) { 32080785Sgshapiro HALDEBUG(ah, HAL_DEBUG_ANY, 32180785Sgshapiro "%s: error getting mac address from EEPROM\n", __func__); 32290792Sgshapiro goto bad; 32338032Speter } 32438032Speter /* XXX How about the serial number ? */ 32538032Speter /* Read Reg Domain */ 32638032Speter AH_PRIVATE(ah)->ah_currentRD = 32790792Sgshapiro ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); 32890792Sgshapiro AH_PRIVATE(ah)->ah_currentRDext = 32938032Speter ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL); 33038032Speter 33138032Speter /* 33238032Speter * ah_miscMode is populated by ar5416FillCapabilityInfo() 33338032Speter * starting from griffin. Set here to make sure that 33490792Sgshapiro * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is 33538032Speter * placed into hardware. 33638032Speter */ 33738032Speter if (ahp->ah_miscMode != 0) 33838032Speter OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode); 33990792Sgshapiro 34038032Speter ar9280AniSetup(ah); /* Anti Noise Immunity */ 34138032Speter 34290792Sgshapiro /* Setup noise floor min/max/nominal values */ 34338032Speter AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ; 34490792Sgshapiro AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ; 34538032Speter AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9280_2GHZ; 34638032Speter AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ; 34764562Sgshapiro AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ; 34838032Speter AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9280_5GHZ; 34938032Speter 35038032Speter ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist); 35138032Speter 35238032Speter HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__); 35390792Sgshapiro 35464562Sgshapiro return ah; 35590792Sgshapirobad: 35638032Speter if (ah != AH_NULL) 35738032Speter ah->ah_detach(ah); 35838032Speter if (status) 35938032Speter *status = ecode; 36038032Speter return AH_NULL; 36138032Speter} 362125820Sgshapiro 363125820Sgshapirostatic void 364125820Sgshapiroar9280ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore) 365125820Sgshapiro{ 366125820Sgshapiro if (AH_PRIVATE(ah)->ah_ispcie && !restore) { 367125820Sgshapiro ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0); 368125820Sgshapiro OS_DELAY(1000); 369125820Sgshapiro OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 370125820Sgshapiro OS_REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT); 371125820Sgshapiro } 372125820Sgshapiro} 373125820Sgshapiro 37438032Speterstatic void 37590792Sgshapiroar9280WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan) 37638032Speter{ 377120256Sgshapiro u_int modesIndex, freqIndex; 378120256Sgshapiro int regWrites = 0; 379120256Sgshapiro int i; 380120256Sgshapiro const HAL_INI_ARRAY *ia; 381120256Sgshapiro 382120256Sgshapiro /* Setup the indices for the next set of register array writes */ 383120256Sgshapiro /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */ 38438032Speter if (IEEE80211_IS_CHAN_2GHZ(chan)) { 385120256Sgshapiro freqIndex = 2; 386125820Sgshapiro if (IEEE80211_IS_CHAN_HT40(chan)) 387120256Sgshapiro modesIndex = 3; 388125820Sgshapiro else if (IEEE80211_IS_CHAN_108G(chan)) 389120256Sgshapiro modesIndex = 5; 390125820Sgshapiro else 391120256Sgshapiro modesIndex = 4; 392132943Sgshapiro } else { 393120256Sgshapiro freqIndex = 1; 394120256Sgshapiro if (IEEE80211_IS_CHAN_HT40(chan) || 395120256Sgshapiro IEEE80211_IS_CHAN_TURBO(chan)) 396120256Sgshapiro modesIndex = 2; 397120256Sgshapiro else 398120256Sgshapiro modesIndex = 1; 399132943Sgshapiro } 400132943Sgshapiro 401120256Sgshapiro /* Set correct Baseband to analog shift setting to access analog chips. */ 402120256Sgshapiro OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 403120256Sgshapiro OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); 404120256Sgshapiro 405120256Sgshapiro /* 40690792Sgshapiro * This is unwound because at the moment, there's a requirement 40738032Speter * for Merlin (and later, perhaps) to have a specific bit fixed 40838032Speter * in the AR_AN_TOP2 register before writing it. 40938032Speter */ 41038032Speter ia = &AH5212(ah)->ah_ini_modes; 41138032Speter#if 0 41264562Sgshapiro regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes, 41338032Speter modesIndex, regWrites); 414125820Sgshapiro#endif 41564562Sgshapiro HALASSERT(modesIndex < ia->cols); 41664562Sgshapiro for (i = 0; i < ia->rows; i++) { 41764562Sgshapiro uint32_t reg = HAL_INI_VAL(ia, i, 0); 41864562Sgshapiro uint32_t val = HAL_INI_VAL(ia, i, modesIndex); 41964562Sgshapiro 42064562Sgshapiro if (reg == AR_AN_TOP2 && AH5416(ah)->ah_need_an_top2_fixup) 42164562Sgshapiro val &= ~AR_AN_TOP2_PWDCLKIND; 42298121Sgshapiro 42390792Sgshapiro OS_REG_WRITE(ah, reg, val); 42464562Sgshapiro 425125820Sgshapiro /* Analog shift register delay seems needed for Merlin - PR kern/154220 */ 426125820Sgshapiro if (reg >= 0x7800 && reg < 0x78a0) 427125820Sgshapiro OS_DELAY(100); 428125820Sgshapiro 42938032Speter DMA_YIELD(regWrites); 43064562Sgshapiro } 43138032Speter 432125820Sgshapiro if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 433125820Sgshapiro regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_rxgain, 434125820Sgshapiro modesIndex, regWrites); 435125820Sgshapiro regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_txgain, 43664562Sgshapiro modesIndex, regWrites); 43738032Speter } 438125820Sgshapiro /* XXX Merlin 100us delay for shift registers */ 439125820Sgshapiro regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common, 440125820Sgshapiro 1, regWrites); 44138032Speter 44264562Sgshapiro if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 44390792Sgshapiro /* 5GHz channels w/ Fast Clock use different modal values */ 44464562Sgshapiro regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_xmodes, 44564562Sgshapiro modesIndex, regWrites); 44664562Sgshapiro } 44764562Sgshapiro} 44864562Sgshapiro 44938032Speter#define AR_BASE_FREQ_2GHZ 2300 45038032Speter#define AR_BASE_FREQ_5GHZ 4900 45138032Speter#define AR_SPUR_FEEQ_BOUND_HT40 19 45238032Speter#define AR_SPUR_FEEQ_BOUND_HT20 10 45338032Speter 45464562Sgshapirovoid 45538032Speterar9280SpurMitigate(struct ath_hal *ah, const struct ieee80211_channel *chan) 45638032Speter{ 45764562Sgshapiro static const int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, 45838032Speter AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 }; 45990792Sgshapiro static const int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, 460120256Sgshapiro AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 }; 46190792Sgshapiro static int inc[4] = { 0, 100, 0, 0 }; 46238032Speter 46364562Sgshapiro int bb_spur = AR_NO_SPUR; 46464562Sgshapiro int freq; 46590792Sgshapiro int bin, cur_bin; 46664562Sgshapiro int bb_spur_off, spur_subchannel_sd; 46738032Speter int spur_freq_sd; 46898121Sgshapiro int spur_delta_phase; 46938032Speter int denominator; 47038032Speter int upper, lower, cur_vit_mask; 47138032Speter int tmp, newVal; 47238032Speter int i; 47390792Sgshapiro CHAN_CENTERS centers; 47490792Sgshapiro 47590792Sgshapiro int8_t mask_m[123]; 47690792Sgshapiro int8_t mask_p[123]; 47738032Speter int8_t mask_amt; 47838032Speter int tmp_mask; 47990792Sgshapiro int cur_bb_spur; 48038032Speter HAL_BOOL is2GHz = IEEE80211_IS_CHAN_2GHZ(chan); 48138032Speter 48238032Speter OS_MEMZERO(&mask_m, sizeof(int8_t) * 123); 48338032Speter OS_MEMZERO(&mask_p, sizeof(int8_t) * 123); 48490792Sgshapiro 485132943Sgshapiro ar5416GetChannelCenters(ah, chan, ¢ers); 48638032Speter freq = centers.synth_center; 48738032Speter 48838032Speter /* 48990792Sgshapiro * Need to verify range +/- 9.38 for static ht20 and +/- 18.75 for ht40, 49090792Sgshapiro * otherwise spur is out-of-band and can be ignored. 49190792Sgshapiro */ 49238032Speter for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 49390792Sgshapiro cur_bb_spur = ath_hal_getSpurChan(ah, i, is2GHz); 49438032Speter /* Get actual spur freq in MHz from EEPROM read value */ 49590792Sgshapiro if (is2GHz) { 49690792Sgshapiro cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ; 49738032Speter } else { 49838032Speter cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ; 49938032Speter } 50038032Speter 50138032Speter if (AR_NO_SPUR == cur_bb_spur) 50238032Speter break; 50390792Sgshapiro cur_bb_spur = cur_bb_spur - freq; 50464562Sgshapiro 50538032Speter if (IEEE80211_IS_CHAN_HT40(chan)) { 50690792Sgshapiro if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) && 50790792Sgshapiro (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) { 508132943Sgshapiro bb_spur = cur_bb_spur; 50990792Sgshapiro break; 51090792Sgshapiro } 51190792Sgshapiro } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) && 51264562Sgshapiro (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) { 51398121Sgshapiro bb_spur = cur_bb_spur; 51490792Sgshapiro break; 51590792Sgshapiro } 51690792Sgshapiro } 51790792Sgshapiro 51890792Sgshapiro if (AR_NO_SPUR == bb_spur) { 51990792Sgshapiro#if 1 52090792Sgshapiro /* 52190792Sgshapiro * MRC CCK can interfere with beacon detection and cause deaf/mute. 52290792Sgshapiro * Disable MRC CCK for now. 52390792Sgshapiro */ 52490792Sgshapiro OS_REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); 52590792Sgshapiro#else 52690792Sgshapiro /* Enable MRC CCK if no spur is found in this channel. */ 52790792Sgshapiro OS_REG_SET_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); 52890792Sgshapiro#endif 52990792Sgshapiro return; 53090792Sgshapiro } else { 53190792Sgshapiro /* 53290792Sgshapiro * For Merlin, spur can break CCK MRC algorithm. Disable CCK MRC if spur 53364562Sgshapiro * is found in this channel. 53464562Sgshapiro */ 53564562Sgshapiro OS_REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); 53664562Sgshapiro } 53790792Sgshapiro 53890792Sgshapiro bin = bb_spur * 320; 53938032Speter 54038032Speter tmp = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4_CHAIN(0)); 54190792Sgshapiro 54290792Sgshapiro newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | 54364562Sgshapiro AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | 54464562Sgshapiro AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | 54590792Sgshapiro AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); 54690792Sgshapiro OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4_CHAIN(0), newVal); 547120256Sgshapiro 548120256Sgshapiro newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | 54990792Sgshapiro AR_PHY_SPUR_REG_ENABLE_MASK_PPM | 55090792Sgshapiro AR_PHY_SPUR_REG_MASK_RATE_SELECT | 55190792Sgshapiro AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | 552120256Sgshapiro SM(AR5416_SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); 55390792Sgshapiro OS_REG_WRITE(ah, AR_PHY_SPUR_REG, newVal); 55438032Speter 55598121Sgshapiro /* Pick control or extn channel to cancel the spur */ 55664562Sgshapiro if (IEEE80211_IS_CHAN_HT40(chan)) { 55738032Speter if (bb_spur < 0) { 55838032Speter spur_subchannel_sd = 1; 55938032Speter bb_spur_off = bb_spur + 10; 56038032Speter } else { 56190792Sgshapiro spur_subchannel_sd = 0; 56238032Speter bb_spur_off = bb_spur - 10; 56338032Speter } 56464562Sgshapiro } else { 56538032Speter spur_subchannel_sd = 0; 56638032Speter bb_spur_off = bb_spur; 56738032Speter } 56890792Sgshapiro 56990792Sgshapiro /* 570132943Sgshapiro * spur_delta_phase = bb_spur/40 * 2**21 for static ht20, 57190792Sgshapiro * /80 for dyn2040. 57290792Sgshapiro */ 57390792Sgshapiro if (IEEE80211_IS_CHAN_HT40(chan)) 57490792Sgshapiro spur_delta_phase = ((bb_spur * 262144) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; 57590792Sgshapiro else 57690792Sgshapiro spur_delta_phase = ((bb_spur * 524288) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; 57790792Sgshapiro 57890792Sgshapiro /* 57990792Sgshapiro * in 11A mode the denominator of spur_freq_sd should be 40 and 58090792Sgshapiro * it should be 44 in 11G 58190792Sgshapiro */ 58290792Sgshapiro denominator = IEEE80211_IS_CHAN_2GHZ(chan) ? 44 : 40; 58390792Sgshapiro spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff; 58490792Sgshapiro 58590792Sgshapiro newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | 58690792Sgshapiro SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | 58790792Sgshapiro SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); 58890792Sgshapiro OS_REG_WRITE(ah, AR_PHY_TIMING11, newVal); 58964562Sgshapiro 59098121Sgshapiro /* Choose to cancel between control and extension channels */ 59138032Speter newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S; 59238032Speter OS_REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal); 59338032Speter 59438032Speter /* 59538032Speter * ============================================ 59638032Speter * Set Pilot and Channel Masks 59790792Sgshapiro * 59838032Speter * pilot mask 1 [31:0] = +6..-26, no 0 bin 59938032Speter * pilot mask 2 [19:0] = +26..+7 60038032Speter * 60190792Sgshapiro * channel mask 1 [31:0] = +6..-26, no 0 bin 60238032Speter * channel mask 2 [19:0] = +26..+7 60338032Speter */ 60490792Sgshapiro cur_bin = -6000; 60538032Speter upper = bin + 100; 60638032Speter lower = bin - 100; 60790792Sgshapiro 60838032Speter for (i = 0; i < 4; i++) { 60938032Speter int pilot_mask = 0; 61090792Sgshapiro int chan_mask = 0; 61138032Speter int bp = 0; 61238032Speter for (bp = 0; bp < 30; bp++) { 61390792Sgshapiro if ((cur_bin > lower) && (cur_bin < upper)) { 61438032Speter pilot_mask = pilot_mask | 0x1 << bp; 61590792Sgshapiro chan_mask = chan_mask | 0x1 << bp; 61690792Sgshapiro } 61790792Sgshapiro cur_bin += 100; 61890792Sgshapiro } 61990792Sgshapiro cur_bin += inc[i]; 62090792Sgshapiro OS_REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); 62190792Sgshapiro OS_REG_WRITE(ah, chan_mask_reg[i], chan_mask); 62290792Sgshapiro } 62390792Sgshapiro 62490792Sgshapiro /* ================================================= 62590792Sgshapiro * viterbi mask 1 based on channel magnitude 62638032Speter * four levels 0-3 62738032Speter * - mask (-27 to 27) (reg 64,0x9900 to 67,0x990c) 62838032Speter * [1 2 2 1] for -9.6 or [1 2 1] for +16 62938032Speter * - enable_mask_ppm, all bins move with freq 63090792Sgshapiro * 63190792Sgshapiro * - mask_select, 8 bits for rates (reg 67,0x990c) 63290792Sgshapiro * - mask_rate_cntl, 8 bits for rates (reg 67,0x990c) 63390792Sgshapiro * choose which mask to use mask or mask2 63438032Speter */ 63538032Speter 63638032Speter /* 63738032Speter * viterbi mask 2 2nd set for per data rate puncturing 63890792Sgshapiro * four levels 0-3 63990792Sgshapiro * - mask_select, 8 bits for rates (reg 67) 64038032Speter * - mask (-27 to 27) (reg 98,0x9988 to 101,0x9994) 64190792Sgshapiro * [1 2 2 1] for -9.6 or [1 2 1] for +16 64290792Sgshapiro */ 64390792Sgshapiro cur_vit_mask = 6100; 64490792Sgshapiro upper = bin + 120; 64538032Speter lower = bin - 120; 64638032Speter 64738032Speter for (i = 0; i < 123; i++) { 64890792Sgshapiro if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { 64990792Sgshapiro if ((abs(cur_vit_mask - bin)) < 75) { 65038032Speter mask_amt = 1; 65138032Speter } else { 65238032Speter mask_amt = 0; 65338032Speter } 65438032Speter if (cur_vit_mask < 0) { 65538032Speter mask_m[abs(cur_vit_mask / 100)] = mask_amt; 65638032Speter } else { 65738032Speter mask_p[cur_vit_mask / 100] = mask_amt; 65838032Speter } 65938032Speter } 66038032Speter cur_vit_mask -= 100; 66138032Speter } 66238032Speter 66338032Speter tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) 66438032Speter | (mask_m[48] << 26) | (mask_m[49] << 24) 66590792Sgshapiro | (mask_m[50] << 22) | (mask_m[51] << 20) 66690792Sgshapiro | (mask_m[52] << 18) | (mask_m[53] << 16) 66738032Speter | (mask_m[54] << 14) | (mask_m[55] << 12) 66838032Speter | (mask_m[56] << 10) | (mask_m[57] << 8) 66990792Sgshapiro | (mask_m[58] << 6) | (mask_m[59] << 4) 67038032Speter | (mask_m[60] << 2) | (mask_m[61] << 0); 67164562Sgshapiro OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); 67290792Sgshapiro OS_REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); 67338032Speter 67438032Speter tmp_mask = (mask_m[31] << 28) 67538032Speter | (mask_m[32] << 26) | (mask_m[33] << 24) 67638032Speter | (mask_m[34] << 22) | (mask_m[35] << 20) 67738032Speter | (mask_m[36] << 18) | (mask_m[37] << 16) 67838032Speter | (mask_m[48] << 14) | (mask_m[39] << 12) 67990792Sgshapiro | (mask_m[40] << 10) | (mask_m[41] << 8) 68090792Sgshapiro | (mask_m[42] << 6) | (mask_m[43] << 4) 68138032Speter | (mask_m[44] << 2) | (mask_m[45] << 0); 68238032Speter OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); 68338032Speter OS_REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); 68490792Sgshapiro 68590792Sgshapiro tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) 68638032Speter | (mask_m[18] << 26) | (mask_m[18] << 24) 68764562Sgshapiro | (mask_m[20] << 22) | (mask_m[20] << 20) 68864562Sgshapiro | (mask_m[22] << 18) | (mask_m[22] << 16) 68990792Sgshapiro | (mask_m[24] << 14) | (mask_m[24] << 12) 69090792Sgshapiro | (mask_m[25] << 10) | (mask_m[26] << 8) 69190792Sgshapiro | (mask_m[27] << 6) | (mask_m[28] << 4) 69290792Sgshapiro | (mask_m[29] << 2) | (mask_m[30] << 0); 69390792Sgshapiro OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); 69464562Sgshapiro OS_REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); 69538032Speter 69638032Speter tmp_mask = (mask_m[ 0] << 30) | (mask_m[ 1] << 28) 69738032Speter | (mask_m[ 2] << 26) | (mask_m[ 3] << 24) 69838032Speter | (mask_m[ 4] << 22) | (mask_m[ 5] << 20) 69964562Sgshapiro | (mask_m[ 6] << 18) | (mask_m[ 7] << 16) 70038032Speter | (mask_m[ 8] << 14) | (mask_m[ 9] << 12) 70164562Sgshapiro | (mask_m[10] << 10) | (mask_m[11] << 8) 70290792Sgshapiro | (mask_m[12] << 6) | (mask_m[13] << 4) 70390792Sgshapiro | (mask_m[14] << 2) | (mask_m[15] << 0); 70490792Sgshapiro OS_REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); 70590792Sgshapiro OS_REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); 70690792Sgshapiro 70790792Sgshapiro tmp_mask = (mask_p[15] << 28) 70838032Speter | (mask_p[14] << 26) | (mask_p[13] << 24) 70938032Speter | (mask_p[12] << 22) | (mask_p[11] << 20) 71090792Sgshapiro | (mask_p[10] << 18) | (mask_p[ 9] << 16) 71190792Sgshapiro | (mask_p[ 8] << 14) | (mask_p[ 7] << 12) 71290792Sgshapiro | (mask_p[ 6] << 10) | (mask_p[ 5] << 8) 71390792Sgshapiro | (mask_p[ 4] << 6) | (mask_p[ 3] << 4) 71490792Sgshapiro | (mask_p[ 2] << 2) | (mask_p[ 1] << 0); 71590792Sgshapiro OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); 71690792Sgshapiro OS_REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); 71790792Sgshapiro 71838032Speter tmp_mask = (mask_p[30] << 28) 71990792Sgshapiro | (mask_p[29] << 26) | (mask_p[28] << 24) 72038032Speter | (mask_p[27] << 22) | (mask_p[26] << 20) 72190792Sgshapiro | (mask_p[25] << 18) | (mask_p[24] << 16) 72238032Speter | (mask_p[23] << 14) | (mask_p[22] << 12) 72390792Sgshapiro | (mask_p[21] << 10) | (mask_p[20] << 8) 72438032Speter | (mask_p[19] << 6) | (mask_p[18] << 4) 72590792Sgshapiro | (mask_p[17] << 2) | (mask_p[16] << 0); 72638032Speter OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); 72790792Sgshapiro OS_REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); 72871345Sgshapiro 72971345Sgshapiro tmp_mask = (mask_p[45] << 28) 73090792Sgshapiro | (mask_p[44] << 26) | (mask_p[43] << 24) 73190792Sgshapiro | (mask_p[42] << 22) | (mask_p[41] << 20) 73290792Sgshapiro | (mask_p[40] << 18) | (mask_p[39] << 16) 73390792Sgshapiro | (mask_p[38] << 14) | (mask_p[37] << 12) 73438032Speter | (mask_p[36] << 10) | (mask_p[35] << 8) 73538032Speter | (mask_p[34] << 6) | (mask_p[33] << 4) 73690792Sgshapiro | (mask_p[32] << 2) | (mask_p[31] << 0); 73790792Sgshapiro OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); 73890792Sgshapiro OS_REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); 73990792Sgshapiro 74090792Sgshapiro tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) 74138032Speter | (mask_p[59] << 26) | (mask_p[58] << 24) 74290792Sgshapiro | (mask_p[57] << 22) | (mask_p[56] << 20) 74338032Speter | (mask_p[55] << 18) | (mask_p[54] << 16) 74464562Sgshapiro | (mask_p[53] << 14) | (mask_p[52] << 12) 74590792Sgshapiro | (mask_p[51] << 10) | (mask_p[50] << 8) 74638032Speter | (mask_p[49] << 6) | (mask_p[48] << 4) 74738032Speter | (mask_p[47] << 2) | (mask_p[46] << 0); 74838032Speter OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); 74938032Speter OS_REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); 75090792Sgshapiro} 751132943Sgshapiro 75238032Speter/* 75338032Speter * Fill all software cached or static hardware state information. 75438032Speter * Return failure if capabilities are to come from EEPROM and 75538032Speter * cannot be read. 75638032Speter */ 75738032Speterstatic HAL_BOOL 75838032Speterar9280FillCapabilityInfo(struct ath_hal *ah) 75938032Speter{ 76038032Speter HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; 76138032Speter 76238032Speter if (!ar5416FillCapabilityInfo(ah)) 76338032Speter return AH_FALSE; 76438032Speter pCap->halNumGpioPins = 10; 76564562Sgshapiro pCap->halWowSupport = AH_TRUE; 76638032Speter pCap->halWowMatchPatternExact = AH_TRUE; 76738032Speter#if 0 76838032Speter pCap->halWowMatchPatternDword = AH_TRUE; 76964562Sgshapiro#endif 77038032Speter /* AR9280 is a 2x2 stream device */ 77138032Speter pCap->halTxStreams = 2; 77238032Speter pCap->halRxStreams = 2; 77390792Sgshapiro 77438032Speter pCap->halCSTSupport = AH_TRUE; 77538032Speter pCap->halRifsRxSupport = AH_TRUE; 77643730Speter pCap->halRifsTxSupport = AH_TRUE; 77738032Speter pCap->halRtsAggrLimit = 64*1024; /* 802.11n max */ 77838032Speter pCap->halExtChanDfsSupport = AH_TRUE; 77938032Speter#if 0 78064562Sgshapiro /* XXX bluetooth */ 78164562Sgshapiro pCap->halBtCoexSupport = AH_TRUE; 78238032Speter#endif 78338032Speter pCap->halAutoSleepSupport = AH_FALSE; /* XXX? */ 78438032Speter pCap->hal4kbSplitTransSupport = AH_FALSE; 78538032Speter /* Disable this so Block-ACK works correctly */ 78638032Speter pCap->halHasRxSelfLinkedTail = AH_FALSE; 78738032Speter pCap->halMbssidAggrSupport = AH_TRUE; 78838032Speter pCap->hal4AddrAggrSupport = AH_TRUE; 78938032Speter 79038032Speter if (AR_SREV_MERLIN_20_OR_LATER(ah)) 79138032Speter pCap->halPSPollBroken = AH_FALSE; 79238032Speter pCap->halRxStbcSupport = 1; 79390792Sgshapiro pCap->halTxStbcSupport = 1; 79438032Speter 79564562Sgshapiro return AH_TRUE; 79664562Sgshapiro} 79738032Speter 79864562Sgshapiro/* 79990792Sgshapiro * This has been disabled - having the HAL flip chainmasks on/off 80090792Sgshapiro * when attempting to implement 11n disrupts things. For now, just 80190792Sgshapiro * leave this flipped off and worry about implementing TX diversity 80264562Sgshapiro * for legacy and MCS0-7 when 11n is fully functioning. 80390792Sgshapiro */ 80490792SgshapiroHAL_BOOL 80564562Sgshapiroar9280SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings) 80664562Sgshapiro{ 80764562Sgshapiro#define ANTENNA0_CHAINMASK 0x1 80864562Sgshapiro#define ANTENNA1_CHAINMASK 0x2 80938032Speter#if 0 81038032Speter struct ath_hal_5416 *ahp = AH5416(ah); 81164562Sgshapiro 81238032Speter /* Antenna selection is done by setting the tx/rx chainmasks approp. */ 81338032Speter switch (settings) { 81490792Sgshapiro case HAL_ANT_FIXED_A: 81590792Sgshapiro /* Enable first antenna only */ 81638032Speter ahp->ah_tx_chainmask = ANTENNA0_CHAINMASK; 81790792Sgshapiro ahp->ah_rx_chainmask = ANTENNA0_CHAINMASK; 81838032Speter break; 81938032Speter case HAL_ANT_FIXED_B: 82064562Sgshapiro /* Enable second antenna only, after checking capability */ 82164562Sgshapiro if (AH_PRIVATE(ah)->ah_caps.halTxChainMask > ANTENNA1_CHAINMASK) 82238032Speter ahp->ah_tx_chainmask = ANTENNA1_CHAINMASK; 82390792Sgshapiro ahp->ah_rx_chainmask = ANTENNA1_CHAINMASK; 82490792Sgshapiro break; 82590792Sgshapiro case HAL_ANT_VARIABLE: 82638032Speter /* Restore original chainmask settings */ 82764562Sgshapiro /* XXX */ 82864562Sgshapiro ahp->ah_tx_chainmask = AR9280_DEFAULT_TXCHAINMASK; 82938032Speter ahp->ah_rx_chainmask = AR9280_DEFAULT_RXCHAINMASK; 83038032Speter break; 83190792Sgshapiro } 83238032Speter 83338032Speter HALDEBUG(ah, HAL_DEBUG_ANY, "%s: settings=%d, tx/rx chainmask=%d/%d\n", 83438032Speter __func__, settings, ahp->ah_tx_chainmask, ahp->ah_rx_chainmask); 83538032Speter 83690792Sgshapiro#endif 83738032Speter return AH_TRUE; 83838032Speter#undef ANTENNA0_CHAINMASK 83938032Speter#undef ANTENNA1_CHAINMASK 84038032Speter} 84138032Speter 84238032Speterstatic const char* 84338032Speterar9280Probe(uint16_t vendorid, uint16_t devid) 84490792Sgshapiro{ 84590792Sgshapiro if (vendorid == ATHEROS_VENDOR_ID && 84690792Sgshapiro (devid == AR9280_DEVID_PCI || devid == AR9280_DEVID_PCIE)) 84790792Sgshapiro return "Atheros 9280"; 84838032Speter return AH_NULL; 84938032Speter} 85038032SpeterAH_CHIP(AR9280, ar9280Probe, ar9280Attach); 85138032Speter