X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/99c2098456c9a8bcdcb415c69f02340c9d695859..a6e86dfede9e41ca29aba09133236a5fa8c885b3:/package/mac80211/patches/510-pending_work.patch diff --git a/package/mac80211/patches/510-pending_work.patch b/package/mac80211/patches/510-pending_work.patch index d52eaa444..c4c589cf5 100644 --- a/package/mac80211/patches/510-pending_work.patch +++ b/package/mac80211/patches/510-pending_work.patch @@ -1,1893 +1,3644 @@ ---- a/drivers/net/wireless/ath/ath9k/Makefile -+++ b/drivers/net/wireless/ath/ath9k/Makefile -@@ -32,7 +32,8 @@ ath9k_hw-y:= \ - mac.o \ - ar9002_mac.o \ - ar9003_mac.o \ -- ar9003_eeprom.o -+ ar9003_eeprom.o \ -+ ar9003_paprd.o - - obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o +--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c +@@ -1579,6 +1579,37 @@ static void ar5008_hw_set_nf_limits(stru + ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ; + } ++static void ar5008_hw_set_radar_params(struct ath_hw *ah, ++ struct ath_hw_radar_conf *conf) ++{ ++ u32 radar_0 = 0, radar_1 = 0; ++ ++ if (!conf) { ++ REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA); ++ return; ++ } ++ ++ radar_0 |= AR_PHY_RADAR_0_ENA | AR_PHY_RADAR_0_FFT_ENA; ++ radar_0 |= SM(conf->fir_power, AR_PHY_RADAR_0_FIRPWR); ++ radar_0 |= SM(conf->radar_rssi, AR_PHY_RADAR_0_RRSSI); ++ radar_0 |= SM(conf->pulse_height, AR_PHY_RADAR_0_HEIGHT); ++ radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI); ++ radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND); ++ ++ radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI; ++ radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK; ++ radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN); ++ radar_1 |= SM(conf->pulse_inband_step, AR_PHY_RADAR_1_RELSTEP_THRESH); ++ radar_1 |= SM(conf->radar_inband, AR_PHY_RADAR_1_RELPWR_THRESH); ++ ++ REG_WRITE(ah, AR_PHY_RADAR_0, radar_0); ++ REG_WRITE(ah, AR_PHY_RADAR_1, radar_1); ++ if (conf->ext_channel) ++ REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); ++ else ++ REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); ++} ++ + void ar5008_hw_attach_phy_ops(struct ath_hw *ah) + { + struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); +@@ -1609,6 +1640,7 @@ void ar5008_hw_attach_phy_ops(struct ath + priv_ops->restore_chainmask = ar5008_restore_chainmask; + priv_ops->set_diversity = ar5008_set_diversity; + priv_ops->do_getnf = ar5008_hw_do_getnf; ++ priv_ops->set_radar_params = ar5008_hw_set_radar_params; + + if (modparam_force_new_ani) { + priv_ops->ani_control = ar5008_hw_ani_control_new; +--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c +@@ -718,12 +718,19 @@ static bool ar9003_hw_init_cal(struct at + struct ath9k_channel *chan) + { + struct ath_common *common = ath9k_hw_common(ah); ++ int val; + +- /* +- * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain mode before +- * running AGC/TxIQ cals +- */ +- ar9003_hw_set_chain_masks(ah, 0x7, 0x7); ++ val = REG_READ(ah, AR_ENT_OTP); ++ ath_print(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val); ++ ++ if (val & AR_ENT_OTP_CHAIN2_DISABLE) ++ ar9003_hw_set_chain_masks(ah, 0x3, 0x3); ++ else ++ /* ++ * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain ++ * mode before running AGC/TxIQ cals ++ */ ++ ar9003_hw_set_chain_masks(ah, 0x7, 0x7); + + /* Do Tx IQ Calibration */ + ar9003_hw_tx_iq_cal(ah); --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -@@ -67,6 +67,7 @@ static const struct ar9300_eeprom ar9300 - * bit2 - enable fastClock - enabled - * bit3 - enable doubling - enabled - * bit4 - enable internal regulator - disabled +@@ -22,12 +22,14 @@ + #define COMP_CKSUM_LEN 2 + + #define AR_CH0_TOP (0x00016288) +-#define AR_CH0_TOP_XPABIASLVL (0x3) ++#define AR_CH0_TOP_XPABIASLVL (0x300) + #define AR_CH0_TOP_XPABIASLVL_S (8) + + #define AR_CH0_THERM (0x00016290) +-#define AR_CH0_THERM_SPARE (0x3f) +-#define AR_CH0_THERM_SPARE_S (0) ++#define AR_CH0_THERM_XPABIASLVL_MSB 0x3 ++#define AR_CH0_THERM_XPABIASLVL_MSB_S 0 ++#define AR_CH0_THERM_XPASHORT2GND 0x4 ++#define AR_CH0_THERM_XPASHORT2GND_S 2 + + #define AR_SWITCH_TABLE_COM_ALL (0xffff) + #define AR_SWITCH_TABLE_COM_ALL_S (0) +@@ -55,15 +57,2327 @@ + #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ + #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ + ++static int ar9003_hw_power_interpolate(int32_t x, ++ int32_t *px, int32_t *py, u_int16_t np); + static const struct ar9300_eeprom ar9300_default = { + .eepromVersion = 2, +- .templateVersion = 2, +- .macAddr = {1, 2, 3, 4, 5, 6}, +- .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, ++ .templateVersion = 2, ++ .macAddr = {1, 2, 3, 4, 5, 6}, ++ .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, ++ .baseEepHeader = { ++ .regDmn = { LE16(0), LE16(0x1f) }, ++ .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ ++ .opCapFlags = { ++ .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, ++ .eepMisc = 0, ++ }, ++ .rfSilent = 0, ++ .blueToothOptions = 0, ++ .deviceCap = 0, ++ .deviceType = 5, /* takes lower byte in eeprom location */ ++ .pwrTableOffset = AR9300_PWR_TABLE_OFFSET, ++ .params_for_tuning_caps = {0, 0}, ++ .featureEnable = 0x0c, ++ /* ++ * bit0 - enable tx temp comp - disabled ++ * bit1 - enable tx volt comp - disabled ++ * bit2 - enable fastClock - enabled ++ * bit3 - enable doubling - enabled ++ * bit4 - enable internal regulator - disabled + * bit5 - enable pa predistortion - disabled ++ */ ++ .miscConfiguration = 0, /* bit0 - turn down drivestrength */ ++ .eepromWriteEnableGpio = 3, ++ .wlanDisableGpio = 0, ++ .wlanLedGpio = 8, ++ .rxBandSelectGpio = 0xff, ++ .txrxgain = 0, ++ .swreg = 0, ++ }, ++ .modalHeader2G = { ++ /* ar9300_modal_eep_header 2g */ ++ /* 4 idle,t1,t2,b(4 bits per setting) */ ++ .antCtrlCommon = LE32(0x110), ++ /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ ++ .antCtrlCommon2 = LE32(0x22222), ++ ++ /* ++ * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r, ++ * rx1, rx12, b (2 bits each) ++ */ ++ .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) }, ++ ++ /* ++ * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db ++ * for ar9280 (0xa20c/b20c 5:0) ++ */ ++ .xatten1DB = {0, 0, 0}, ++ ++ /* ++ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin ++ * for ar9280 (0xa20c/b20c 16:12 ++ */ ++ .xatten1Margin = {0, 0, 0}, ++ .tempSlope = 36, ++ .voltSlope = 0, ++ ++ /* ++ * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur ++ * channels in usual fbin coding format ++ */ ++ .spurChans = {0, 0, 0, 0, 0}, ++ ++ /* ++ * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check ++ * if the register is per chain ++ */ ++ .noiseFloorThreshCh = {-1, 0, 0}, ++ .ob = {1, 1, 1},/* 3 chain */ ++ .db_stage2 = {1, 1, 1}, /* 3 chain */ ++ .db_stage3 = {0, 0, 0}, ++ .db_stage4 = {0, 0, 0}, ++ .xpaBiasLvl = 0, ++ .txFrameToDataStart = 0x0e, ++ .txFrameToPaOn = 0x0e, ++ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ ++ .antennaGain = 0, ++ .switchSettling = 0x2c, ++ .adcDesiredSize = -30, ++ .txEndToXpaOff = 0, ++ .txEndToRxOn = 0x2, ++ .txFrameToXpaOn = 0xe, ++ .thresh62 = 28, ++ .papdRateMaskHt20 = LE32(0x0cf0e0e0), ++ .papdRateMaskHt40 = LE32(0x6cf0e0e0), ++ .futureModal = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ }, ++ }, ++ .base_ext1 = { ++ .ant_div_control = 0, ++ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ++ }, ++ .calFreqPier2G = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1), ++ }, ++ /* ar9300_cal_data_per_freq_op_loop 2g */ ++ .calPierData2G = { ++ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, ++ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, ++ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, ++ }, ++ .calTarget_freqbin_Cck = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2484, 1), ++ }, ++ .calTarget_freqbin_2G = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1) ++ }, ++ .calTarget_freqbin_2GHT20 = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1) ++ }, ++ .calTarget_freqbin_2GHT40 = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1) ++ }, ++ .calTargetPowerCck = { ++ /* 1L-5L,5S,11L,11S */ ++ { {36, 36, 36, 36} }, ++ { {36, 36, 36, 36} }, ++ }, ++ .calTargetPower2G = { ++ /* 6-24,36,48,54 */ ++ { {32, 32, 28, 24} }, ++ { {32, 32, 28, 24} }, ++ { {32, 32, 28, 24} }, ++ }, ++ .calTargetPower2GHT20 = { ++ { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, ++ { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, ++ { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, ++ }, ++ .calTargetPower2GHT40 = { ++ { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, ++ { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, ++ { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, ++ }, ++ .ctlIndex_2G = { ++ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, ++ 0x45, 0x47, 0x31, 0x32, 0x35, 0x37, ++ }, ++ .ctl_freqbin_2G = { ++ { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2457, 1), ++ FREQ2FBIN(2462, 1) ++ }, ++ { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2462, 1), ++ 0xFF, ++ }, ++ ++ { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2462, 1), ++ 0xFF, ++ }, ++ { ++ FREQ2FBIN(2422, 1), ++ FREQ2FBIN(2427, 1), ++ FREQ2FBIN(2447, 1), ++ FREQ2FBIN(2452, 1) ++ }, ++ ++ { ++ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1), ++ }, ++ ++ { ++ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ 0, ++ }, ++ ++ { ++ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2472, 1), ++ 0, ++ }, ++ ++ { ++ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), ++ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), ++ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), ++ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), ++ }, ++ ++ { ++ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ }, ++ ++ { ++ /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ 0 ++ }, ++ ++ { ++ /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ 0 ++ }, ++ ++ { ++ /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), ++ /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), ++ /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), ++ /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), ++ } ++ }, ++ .ctlPowerData_2G = { ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, ++ ++ { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, ++ }, ++ .modalHeader5G = { ++ /* 4 idle,t1,t2,b (4 bits per setting) */ ++ .antCtrlCommon = LE32(0x110), ++ /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ ++ .antCtrlCommon2 = LE32(0x22222), ++ /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ ++ .antCtrlChain = { ++ LE16(0x000), LE16(0x000), LE16(0x000), ++ }, ++ /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ ++ .xatten1DB = {0, 0, 0}, ++ ++ /* ++ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin ++ * for merlin (0xa20c/b20c 16:12 ++ */ ++ .xatten1Margin = {0, 0, 0}, ++ .tempSlope = 68, ++ .voltSlope = 0, ++ /* spurChans spur channels in usual fbin coding format */ ++ .spurChans = {0, 0, 0, 0, 0}, ++ /* noiseFloorThreshCh Check if the register is per chain */ ++ .noiseFloorThreshCh = {-1, 0, 0}, ++ .ob = {3, 3, 3}, /* 3 chain */ ++ .db_stage2 = {3, 3, 3}, /* 3 chain */ ++ .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ ++ .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ ++ .xpaBiasLvl = 0, ++ .txFrameToDataStart = 0x0e, ++ .txFrameToPaOn = 0x0e, ++ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ ++ .antennaGain = 0, ++ .switchSettling = 0x2d, ++ .adcDesiredSize = -30, ++ .txEndToXpaOff = 0, ++ .txEndToRxOn = 0x2, ++ .txFrameToXpaOn = 0xe, ++ .thresh62 = 28, ++ .papdRateMaskHt20 = LE32(0x0c80c080), ++ .papdRateMaskHt40 = LE32(0x0080c080), ++ .futureModal = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ }, ++ }, ++ .base_ext2 = { ++ .tempSlopeLow = 0, ++ .tempSlopeHigh = 0, ++ .xatten1DBLow = {0, 0, 0}, ++ .xatten1MarginLow = {0, 0, 0}, ++ .xatten1DBHigh = {0, 0, 0}, ++ .xatten1MarginHigh = {0, 0, 0} ++ }, ++ .calFreqPier5G = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5220, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5600, 0), ++ FREQ2FBIN(5725, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calPierData5G = { ++ { ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ }, ++ { ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ }, ++ { ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ }, ++ ++ }, ++ .calTarget_freqbin_5G = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5220, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5600, 0), ++ FREQ2FBIN(5725, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calTarget_freqbin_5GHT20 = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5240, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5700, 0), ++ FREQ2FBIN(5745, 0), ++ FREQ2FBIN(5725, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calTarget_freqbin_5GHT40 = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5240, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5700, 0), ++ FREQ2FBIN(5745, 0), ++ FREQ2FBIN(5725, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calTargetPower5G = { ++ /* 6-24,36,48,54 */ ++ { {20, 20, 20, 10} }, ++ { {20, 20, 20, 10} }, ++ { {20, 20, 20, 10} }, ++ { {20, 20, 20, 10} }, ++ { {20, 20, 20, 10} }, ++ { {20, 20, 20, 10} }, ++ { {20, 20, 20, 10} }, ++ { {20, 20, 20, 10} }, ++ }, ++ .calTargetPower5GHT20 = { ++ /* ++ * 0_8_16,1-3_9-11_17-19, ++ * 4,5,6,7,12,13,14,15,20,21,22,23 ++ */ ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ }, ++ .calTargetPower5GHT40 = { ++ /* ++ * 0_8_16,1-3_9-11_17-19, ++ * 4,5,6,7,12,13,14,15,20,21,22,23 ++ */ ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ }, ++ .ctlIndex_5G = { ++ 0x10, 0x16, 0x18, 0x40, 0x46, ++ 0x48, 0x30, 0x36, 0x38 ++ }, ++ .ctl_freqbin_5G = { ++ { ++ /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), ++ /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0), ++ /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), ++ /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) ++ }, ++ { ++ /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), ++ /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0), ++ /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), ++ /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) ++ }, ++ ++ { ++ /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), ++ /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), ++ /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), ++ /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0), ++ /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0), ++ /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0), ++ /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0), ++ /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0) ++ }, ++ ++ { ++ /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), ++ /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0), ++ /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[3].ctlEdges[6].bChannel */ 0xFF, ++ /* Data[3].ctlEdges[7].bChannel */ 0xFF, ++ }, ++ ++ { ++ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[4].ctlEdges[4].bChannel */ 0xFF, ++ /* Data[4].ctlEdges[5].bChannel */ 0xFF, ++ /* Data[4].ctlEdges[6].bChannel */ 0xFF, ++ /* Data[4].ctlEdges[7].bChannel */ 0xFF, ++ }, ++ ++ { ++ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), ++ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0), ++ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0), ++ /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), ++ /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0), ++ /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), ++ /* Data[5].ctlEdges[6].bChannel */ 0xFF, ++ /* Data[5].ctlEdges[7].bChannel */ 0xFF ++ }, ++ ++ { ++ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), ++ /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0), ++ /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0), ++ /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0) ++ }, ++ ++ { ++ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0), ++ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0), ++ /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), ++ /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) ++ }, ++ ++ { ++ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), ++ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), ++ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), ++ /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), ++ /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0), ++ /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), ++ /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0), ++ /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0) ++ } ++ }, ++ .ctlPowerData_5G = { ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 0}, {60, 1}, {60, 0}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ } ++ }, ++ { ++ { ++ {60, 0}, {60, 1}, {60, 1}, {60, 0}, ++ {60, 1}, {60, 0}, {60, 0}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ {60, 0}, {60, 0}, {60, 0}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 0}, {60, 0}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 0}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 0}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 0}, {60, 1}, ++ } ++ }, ++ } ++}; ++ ++static const struct ar9300_eeprom ar9300_x113 = { ++ .eepromVersion = 2, ++ .templateVersion = 6, ++ .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0}, ++ .custData = {"x113-023-f0000"}, ++ .baseEepHeader = { ++ .regDmn = { LE16(0), LE16(0x1f) }, ++ .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ ++ .opCapFlags = { ++ .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, ++ .eepMisc = 0, ++ }, ++ .rfSilent = 0, ++ .blueToothOptions = 0, ++ .deviceCap = 0, ++ .deviceType = 5, /* takes lower byte in eeprom location */ ++ .pwrTableOffset = AR9300_PWR_TABLE_OFFSET, ++ .params_for_tuning_caps = {0, 0}, ++ .featureEnable = 0x0d, ++ /* ++ * bit0 - enable tx temp comp - disabled ++ * bit1 - enable tx volt comp - disabled ++ * bit2 - enable fastClock - enabled ++ * bit3 - enable doubling - enabled ++ * bit4 - enable internal regulator - disabled ++ * bit5 - enable pa predistortion - disabled ++ */ ++ .miscConfiguration = 0, /* bit0 - turn down drivestrength */ ++ .eepromWriteEnableGpio = 6, ++ .wlanDisableGpio = 0, ++ .wlanLedGpio = 8, ++ .rxBandSelectGpio = 0xff, ++ .txrxgain = 0x21, ++ .swreg = 0, ++ }, ++ .modalHeader2G = { ++ /* ar9300_modal_eep_header 2g */ ++ /* 4 idle,t1,t2,b(4 bits per setting) */ ++ .antCtrlCommon = LE32(0x110), ++ /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ ++ .antCtrlCommon2 = LE32(0x44444), ++ ++ /* ++ * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r, ++ * rx1, rx12, b (2 bits each) ++ */ ++ .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) }, ++ ++ /* ++ * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db ++ * for ar9280 (0xa20c/b20c 5:0) ++ */ ++ .xatten1DB = {0, 0, 0}, ++ ++ /* ++ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin ++ * for ar9280 (0xa20c/b20c 16:12 ++ */ ++ .xatten1Margin = {0, 0, 0}, ++ .tempSlope = 25, ++ .voltSlope = 0, ++ ++ /* ++ * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur ++ * channels in usual fbin coding format ++ */ ++ .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0}, ++ ++ /* ++ * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check ++ * if the register is per chain ++ */ ++ .noiseFloorThreshCh = {-1, 0, 0}, ++ .ob = {1, 1, 1},/* 3 chain */ ++ .db_stage2 = {1, 1, 1}, /* 3 chain */ ++ .db_stage3 = {0, 0, 0}, ++ .db_stage4 = {0, 0, 0}, ++ .xpaBiasLvl = 0, ++ .txFrameToDataStart = 0x0e, ++ .txFrameToPaOn = 0x0e, ++ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ ++ .antennaGain = 0, ++ .switchSettling = 0x2c, ++ .adcDesiredSize = -30, ++ .txEndToXpaOff = 0, ++ .txEndToRxOn = 0x2, ++ .txFrameToXpaOn = 0xe, ++ .thresh62 = 28, ++ .papdRateMaskHt20 = LE32(0x0c80c080), ++ .papdRateMaskHt40 = LE32(0x0080c080), ++ .futureModal = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ }, ++ }, ++ .base_ext1 = { ++ .ant_div_control = 0, ++ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ++ }, ++ .calFreqPier2G = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1), ++ }, ++ /* ar9300_cal_data_per_freq_op_loop 2g */ ++ .calPierData2G = { ++ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, ++ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, ++ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, ++ }, ++ .calTarget_freqbin_Cck = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2472, 1), ++ }, ++ .calTarget_freqbin_2G = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1) ++ }, ++ .calTarget_freqbin_2GHT20 = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1) ++ }, ++ .calTarget_freqbin_2GHT40 = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1) ++ }, ++ .calTargetPowerCck = { ++ /* 1L-5L,5S,11L,11S */ ++ { {34, 34, 34, 34} }, ++ { {34, 34, 34, 34} }, ++ }, ++ .calTargetPower2G = { ++ /* 6-24,36,48,54 */ ++ { {34, 34, 32, 32} }, ++ { {34, 34, 32, 32} }, ++ { {34, 34, 32, 32} }, ++ }, ++ .calTargetPower2GHT20 = { ++ { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} }, ++ { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} }, ++ { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} }, ++ }, ++ .calTargetPower2GHT40 = { ++ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} }, ++ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} }, ++ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} }, ++ }, ++ .ctlIndex_2G = { ++ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, ++ 0x45, 0x47, 0x31, 0x32, 0x35, 0x37, ++ }, ++ .ctl_freqbin_2G = { ++ { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2457, 1), ++ FREQ2FBIN(2462, 1) ++ }, ++ { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2462, 1), ++ 0xFF, ++ }, ++ ++ { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2462, 1), ++ 0xFF, ++ }, ++ { ++ FREQ2FBIN(2422, 1), ++ FREQ2FBIN(2427, 1), ++ FREQ2FBIN(2447, 1), ++ FREQ2FBIN(2452, 1) ++ }, ++ ++ { ++ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1), ++ }, ++ ++ { ++ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ 0, ++ }, ++ ++ { ++ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2472, 1), ++ 0, ++ }, ++ ++ { ++ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), ++ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), ++ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), ++ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), ++ }, ++ ++ { ++ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ }, ++ ++ { ++ /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ 0 ++ }, ++ ++ { ++ /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ 0 ++ }, ++ ++ { ++ /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), ++ /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), ++ /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), ++ /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), ++ } ++ }, ++ .ctlPowerData_2G = { ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, ++ ++ { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, ++ }, ++ .modalHeader5G = { ++ /* 4 idle,t1,t2,b (4 bits per setting) */ ++ .antCtrlCommon = LE32(0x220), ++ /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ ++ .antCtrlCommon2 = LE32(0x11111), ++ /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ ++ .antCtrlChain = { ++ LE16(0x150), LE16(0x150), LE16(0x150), ++ }, ++ /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ ++ .xatten1DB = {0, 0, 0}, ++ ++ /* ++ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin ++ * for merlin (0xa20c/b20c 16:12 ++ */ ++ .xatten1Margin = {0, 0, 0}, ++ .tempSlope = 68, ++ .voltSlope = 0, ++ /* spurChans spur channels in usual fbin coding format */ ++ .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0}, ++ /* noiseFloorThreshCh Check if the register is per chain */ ++ .noiseFloorThreshCh = {-1, 0, 0}, ++ .ob = {3, 3, 3}, /* 3 chain */ ++ .db_stage2 = {3, 3, 3}, /* 3 chain */ ++ .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ ++ .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ ++ .xpaBiasLvl = 0, ++ .txFrameToDataStart = 0x0e, ++ .txFrameToPaOn = 0x0e, ++ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ ++ .antennaGain = 0, ++ .switchSettling = 0x2d, ++ .adcDesiredSize = -30, ++ .txEndToXpaOff = 0, ++ .txEndToRxOn = 0x2, ++ .txFrameToXpaOn = 0xe, ++ .thresh62 = 28, ++ .papdRateMaskHt20 = LE32(0x0cf0e0e0), ++ .papdRateMaskHt40 = LE32(0x6cf0e0e0), ++ .futureModal = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ }, ++ }, ++ .base_ext2 = { ++ .tempSlopeLow = 72, ++ .tempSlopeHigh = 105, ++ .xatten1DBLow = {0, 0, 0}, ++ .xatten1MarginLow = {0, 0, 0}, ++ .xatten1DBHigh = {0, 0, 0}, ++ .xatten1MarginHigh = {0, 0, 0} ++ }, ++ .calFreqPier5G = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5240, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5600, 0), ++ FREQ2FBIN(5745, 0), ++ FREQ2FBIN(5785, 0) ++ }, ++ .calPierData5G = { ++ { ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ }, ++ { ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ }, ++ { ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ }, ++ ++ }, ++ .calTarget_freqbin_5G = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5220, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5600, 0), ++ FREQ2FBIN(5745, 0), ++ FREQ2FBIN(5785, 0) ++ }, ++ .calTarget_freqbin_5GHT20 = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5240, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5700, 0), ++ FREQ2FBIN(5745, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calTarget_freqbin_5GHT40 = { ++ FREQ2FBIN(5190, 0), ++ FREQ2FBIN(5230, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5410, 0), ++ FREQ2FBIN(5510, 0), ++ FREQ2FBIN(5670, 0), ++ FREQ2FBIN(5755, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calTargetPower5G = { ++ /* 6-24,36,48,54 */ ++ { {42, 40, 40, 34} }, ++ { {42, 40, 40, 34} }, ++ { {42, 40, 40, 34} }, ++ { {42, 40, 40, 34} }, ++ { {42, 40, 40, 34} }, ++ { {42, 40, 40, 34} }, ++ { {42, 40, 40, 34} }, ++ { {42, 40, 40, 34} }, ++ }, ++ .calTargetPower5GHT20 = { ++ /* ++ * 0_8_16,1-3_9-11_17-19, ++ * 4,5,6,7,12,13,14,15,20,21,22,23 ++ */ ++ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} }, ++ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} }, ++ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} }, ++ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} }, ++ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} }, ++ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} }, ++ { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} }, ++ { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} }, ++ }, ++ .calTargetPower5GHT40 = { ++ /* ++ * 0_8_16,1-3_9-11_17-19, ++ * 4,5,6,7,12,13,14,15,20,21,22,23 ++ */ ++ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} }, ++ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} }, ++ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} }, ++ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} }, ++ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} }, ++ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} }, ++ { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} }, ++ { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} }, ++ }, ++ .ctlIndex_5G = { ++ 0x10, 0x16, 0x18, 0x40, 0x46, ++ 0x48, 0x30, 0x36, 0x38 ++ }, ++ .ctl_freqbin_5G = { ++ { ++ /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), ++ /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0), ++ /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), ++ /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) ++ }, ++ { ++ /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), ++ /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0), ++ /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), ++ /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) ++ }, ++ ++ { ++ /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), ++ /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), ++ /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), ++ /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0), ++ /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0), ++ /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0), ++ /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0), ++ /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0) ++ }, ++ ++ { ++ /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), ++ /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0), ++ /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[3].ctlEdges[6].bChannel */ 0xFF, ++ /* Data[3].ctlEdges[7].bChannel */ 0xFF, ++ }, ++ ++ { ++ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[4].ctlEdges[4].bChannel */ 0xFF, ++ /* Data[4].ctlEdges[5].bChannel */ 0xFF, ++ /* Data[4].ctlEdges[6].bChannel */ 0xFF, ++ /* Data[4].ctlEdges[7].bChannel */ 0xFF, ++ }, ++ ++ { ++ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), ++ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0), ++ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0), ++ /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), ++ /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0), ++ /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), ++ /* Data[5].ctlEdges[6].bChannel */ 0xFF, ++ /* Data[5].ctlEdges[7].bChannel */ 0xFF ++ }, ++ ++ { ++ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), ++ /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0), ++ /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0), ++ /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0) ++ }, ++ ++ { ++ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0), ++ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0), ++ /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), ++ /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) ++ }, ++ ++ { ++ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), ++ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), ++ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), ++ /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), ++ /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0), ++ /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), ++ /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0), ++ /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0) ++ } ++ }, ++ .ctlPowerData_5G = { ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 0}, {60, 1}, {60, 0}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ } ++ }, ++ { ++ { ++ {60, 0}, {60, 1}, {60, 1}, {60, 0}, ++ {60, 1}, {60, 0}, {60, 0}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ {60, 0}, {60, 0}, {60, 0}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 0}, {60, 0}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 0}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 0}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 0}, {60, 1}, ++ } ++ }, ++ } ++}; ++ ++ ++static const struct ar9300_eeprom ar9300_h112 = { ++ .eepromVersion = 2, ++ .templateVersion = 3, ++ .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0}, ++ .custData = {"h112-241-f0000"}, ++ .baseEepHeader = { ++ .regDmn = { LE16(0), LE16(0x1f) }, ++ .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ ++ .opCapFlags = { ++ .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, ++ .eepMisc = 0, ++ }, ++ .rfSilent = 0, ++ .blueToothOptions = 0, ++ .deviceCap = 0, ++ .deviceType = 5, /* takes lower byte in eeprom location */ ++ .pwrTableOffset = AR9300_PWR_TABLE_OFFSET, ++ .params_for_tuning_caps = {0, 0}, ++ .featureEnable = 0x0d, ++ /* ++ * bit0 - enable tx temp comp - disabled ++ * bit1 - enable tx volt comp - disabled ++ * bit2 - enable fastClock - enabled ++ * bit3 - enable doubling - enabled ++ * bit4 - enable internal regulator - disabled ++ * bit5 - enable pa predistortion - disabled ++ */ ++ .miscConfiguration = 0, /* bit0 - turn down drivestrength */ ++ .eepromWriteEnableGpio = 6, ++ .wlanDisableGpio = 0, ++ .wlanLedGpio = 8, ++ .rxBandSelectGpio = 0xff, ++ .txrxgain = 0x10, ++ .swreg = 0, ++ }, ++ .modalHeader2G = { ++ /* ar9300_modal_eep_header 2g */ ++ /* 4 idle,t1,t2,b(4 bits per setting) */ ++ .antCtrlCommon = LE32(0x110), ++ /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ ++ .antCtrlCommon2 = LE32(0x44444), ++ ++ /* ++ * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r, ++ * rx1, rx12, b (2 bits each) ++ */ ++ .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) }, ++ ++ /* ++ * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db ++ * for ar9280 (0xa20c/b20c 5:0) ++ */ ++ .xatten1DB = {0, 0, 0}, ++ ++ /* ++ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin ++ * for ar9280 (0xa20c/b20c 16:12 ++ */ ++ .xatten1Margin = {0, 0, 0}, ++ .tempSlope = 25, ++ .voltSlope = 0, ++ ++ /* ++ * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur ++ * channels in usual fbin coding format ++ */ ++ .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0}, ++ ++ /* ++ * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check ++ * if the register is per chain ++ */ ++ .noiseFloorThreshCh = {-1, 0, 0}, ++ .ob = {1, 1, 1},/* 3 chain */ ++ .db_stage2 = {1, 1, 1}, /* 3 chain */ ++ .db_stage3 = {0, 0, 0}, ++ .db_stage4 = {0, 0, 0}, ++ .xpaBiasLvl = 0, ++ .txFrameToDataStart = 0x0e, ++ .txFrameToPaOn = 0x0e, ++ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ ++ .antennaGain = 0, ++ .switchSettling = 0x2c, ++ .adcDesiredSize = -30, ++ .txEndToXpaOff = 0, ++ .txEndToRxOn = 0x2, ++ .txFrameToXpaOn = 0xe, ++ .thresh62 = 28, ++ .papdRateMaskHt20 = LE32(0x80c080), ++ .papdRateMaskHt40 = LE32(0x80c080), ++ .futureModal = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ }, ++ }, ++ .base_ext1 = { ++ .ant_div_control = 0, ++ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ++ }, ++ .calFreqPier2G = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1), ++ }, ++ /* ar9300_cal_data_per_freq_op_loop 2g */ ++ .calPierData2G = { ++ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, ++ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, ++ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, ++ }, ++ .calTarget_freqbin_Cck = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2484, 1), ++ }, ++ .calTarget_freqbin_2G = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1) ++ }, ++ .calTarget_freqbin_2GHT20 = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1) ++ }, ++ .calTarget_freqbin_2GHT40 = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1) ++ }, ++ .calTargetPowerCck = { ++ /* 1L-5L,5S,11L,11S */ ++ { {34, 34, 34, 34} }, ++ { {34, 34, 34, 34} }, ++ }, ++ .calTargetPower2G = { ++ /* 6-24,36,48,54 */ ++ { {34, 34, 32, 32} }, ++ { {34, 34, 32, 32} }, ++ { {34, 34, 32, 32} }, ++ }, ++ .calTargetPower2GHT20 = { ++ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} }, ++ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} }, ++ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} }, ++ }, ++ .calTargetPower2GHT40 = { ++ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} }, ++ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} }, ++ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} }, ++ }, ++ .ctlIndex_2G = { ++ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, ++ 0x45, 0x47, 0x31, 0x32, 0x35, 0x37, ++ }, ++ .ctl_freqbin_2G = { ++ { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2457, 1), ++ FREQ2FBIN(2462, 1) ++ }, ++ { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2462, 1), ++ 0xFF, ++ }, ++ ++ { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2462, 1), ++ 0xFF, ++ }, ++ { ++ FREQ2FBIN(2422, 1), ++ FREQ2FBIN(2427, 1), ++ FREQ2FBIN(2447, 1), ++ FREQ2FBIN(2452, 1) ++ }, ++ ++ { ++ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1), ++ }, ++ ++ { ++ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ 0, ++ }, ++ ++ { ++ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2472, 1), ++ 0, ++ }, ++ ++ { ++ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), ++ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), ++ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), ++ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), ++ }, ++ ++ { ++ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ }, ++ ++ { ++ /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ 0 ++ }, ++ ++ { ++ /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), ++ /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), ++ /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), ++ 0 ++ }, ++ ++ { ++ /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), ++ /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), ++ /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), ++ /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), ++ } ++ }, ++ .ctlPowerData_2G = { ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, ++ ++ { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, ++ }, ++ .modalHeader5G = { ++ /* 4 idle,t1,t2,b (4 bits per setting) */ ++ .antCtrlCommon = LE32(0x220), ++ /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ ++ .antCtrlCommon2 = LE32(0x44444), ++ /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ ++ .antCtrlChain = { ++ LE16(0x150), LE16(0x150), LE16(0x150), ++ }, ++ /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ ++ .xatten1DB = {0, 0, 0}, ++ ++ /* ++ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin ++ * for merlin (0xa20c/b20c 16:12 ++ */ ++ .xatten1Margin = {0, 0, 0}, ++ .tempSlope = 45, ++ .voltSlope = 0, ++ /* spurChans spur channels in usual fbin coding format */ ++ .spurChans = {0, 0, 0, 0, 0}, ++ /* noiseFloorThreshCh Check if the register is per chain */ ++ .noiseFloorThreshCh = {-1, 0, 0}, ++ .ob = {3, 3, 3}, /* 3 chain */ ++ .db_stage2 = {3, 3, 3}, /* 3 chain */ ++ .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ ++ .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ ++ .xpaBiasLvl = 0, ++ .txFrameToDataStart = 0x0e, ++ .txFrameToPaOn = 0x0e, ++ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ ++ .antennaGain = 0, ++ .switchSettling = 0x2d, ++ .adcDesiredSize = -30, ++ .txEndToXpaOff = 0, ++ .txEndToRxOn = 0x2, ++ .txFrameToXpaOn = 0xe, ++ .thresh62 = 28, ++ .papdRateMaskHt20 = LE32(0x0cf0e0e0), ++ .papdRateMaskHt40 = LE32(0x6cf0e0e0), ++ .futureModal = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ }, ++ }, ++ .base_ext2 = { ++ .tempSlopeLow = 40, ++ .tempSlopeHigh = 50, ++ .xatten1DBLow = {0, 0, 0}, ++ .xatten1MarginLow = {0, 0, 0}, ++ .xatten1DBHigh = {0, 0, 0}, ++ .xatten1MarginHigh = {0, 0, 0} ++ }, ++ .calFreqPier5G = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5220, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5600, 0), ++ FREQ2FBIN(5700, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calPierData5G = { ++ { ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ }, ++ { ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ }, ++ { ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ }, ++ ++ }, ++ .calTarget_freqbin_5G = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5240, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5600, 0), ++ FREQ2FBIN(5700, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calTarget_freqbin_5GHT20 = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5240, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5700, 0), ++ FREQ2FBIN(5745, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calTarget_freqbin_5GHT40 = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5240, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5700, 0), ++ FREQ2FBIN(5745, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calTargetPower5G = { ++ /* 6-24,36,48,54 */ ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ }, ++ .calTargetPower5GHT20 = { ++ /* ++ * 0_8_16,1-3_9-11_17-19, ++ * 4,5,6,7,12,13,14,15,20,21,22,23 ++ */ ++ { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} }, ++ { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} }, ++ { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} }, ++ { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} }, ++ { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} }, ++ { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} }, ++ { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} }, ++ { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} }, ++ }, ++ .calTargetPower5GHT40 = { ++ /* ++ * 0_8_16,1-3_9-11_17-19, ++ * 4,5,6,7,12,13,14,15,20,21,22,23 ++ */ ++ { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} }, ++ { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} }, ++ { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} }, ++ { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} }, ++ { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} }, ++ { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} }, ++ { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} }, ++ { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} }, ++ }, ++ .ctlIndex_5G = { ++ 0x10, 0x16, 0x18, 0x40, 0x46, ++ 0x48, 0x30, 0x36, 0x38 ++ }, ++ .ctl_freqbin_5G = { ++ { ++ /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), ++ /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0), ++ /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), ++ /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) ++ }, ++ { ++ /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), ++ /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0), ++ /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), ++ /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) ++ }, ++ ++ { ++ /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), ++ /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), ++ /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), ++ /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0), ++ /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0), ++ /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0), ++ /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0), ++ /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0) ++ }, ++ ++ { ++ /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), ++ /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0), ++ /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[3].ctlEdges[6].bChannel */ 0xFF, ++ /* Data[3].ctlEdges[7].bChannel */ 0xFF, ++ }, ++ ++ { ++ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[4].ctlEdges[4].bChannel */ 0xFF, ++ /* Data[4].ctlEdges[5].bChannel */ 0xFF, ++ /* Data[4].ctlEdges[6].bChannel */ 0xFF, ++ /* Data[4].ctlEdges[7].bChannel */ 0xFF, ++ }, ++ ++ { ++ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), ++ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0), ++ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0), ++ /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), ++ /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0), ++ /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), ++ /* Data[5].ctlEdges[6].bChannel */ 0xFF, ++ /* Data[5].ctlEdges[7].bChannel */ 0xFF ++ }, ++ ++ { ++ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), ++ /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0), ++ /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0), ++ /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0) ++ }, ++ ++ { ++ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), ++ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), ++ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0), ++ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), ++ /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0), ++ /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), ++ /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), ++ /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) ++ }, ++ ++ { ++ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), ++ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), ++ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), ++ /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), ++ /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0), ++ /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), ++ /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0), ++ /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0) ++ } ++ }, ++ .ctlPowerData_5G = { ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 0}, {60, 1}, {60, 0}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ } ++ }, ++ { ++ { ++ {60, 0}, {60, 1}, {60, 1}, {60, 0}, ++ {60, 1}, {60, 0}, {60, 0}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ {60, 0}, {60, 0}, {60, 0}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 0}, {60, 0}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 0}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 0}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 0}, {60, 1}, ++ } ++ }, ++ } ++}; ++ ++ ++static const struct ar9300_eeprom ar9300_x112 = { ++ .eepromVersion = 2, ++ .templateVersion = 5, ++ .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0}, ++ .custData = {"x112-041-f0000"}, ++ .baseEepHeader = { ++ .regDmn = { LE16(0), LE16(0x1f) }, ++ .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ ++ .opCapFlags = { ++ .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, ++ .eepMisc = 0, ++ }, ++ .rfSilent = 0, ++ .blueToothOptions = 0, ++ .deviceCap = 0, ++ .deviceType = 5, /* takes lower byte in eeprom location */ ++ .pwrTableOffset = AR9300_PWR_TABLE_OFFSET, ++ .params_for_tuning_caps = {0, 0}, ++ .featureEnable = 0x0d, ++ /* ++ * bit0 - enable tx temp comp - disabled ++ * bit1 - enable tx volt comp - disabled ++ * bit2 - enable fastclock - enabled ++ * bit3 - enable doubling - enabled ++ * bit4 - enable internal regulator - disabled ++ * bit5 - enable pa predistortion - disabled ++ */ ++ .miscConfiguration = 0, /* bit0 - turn down drivestrength */ ++ .eepromWriteEnableGpio = 6, ++ .wlanDisableGpio = 0, ++ .wlanLedGpio = 8, ++ .rxBandSelectGpio = 0xff, ++ .txrxgain = 0x0, ++ .swreg = 0, ++ }, ++ .modalHeader2G = { ++ /* ar9300_modal_eep_header 2g */ ++ /* 4 idle,t1,t2,b(4 bits per setting) */ ++ .antCtrlCommon = LE32(0x110), ++ /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ ++ .antCtrlCommon2 = LE32(0x22222), ++ ++ /* ++ * antCtrlChain[ar9300_max_chains]; 6 idle, t, r, ++ * rx1, rx12, b (2 bits each) ++ */ ++ .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) }, ++ ++ /* ++ * xatten1DB[AR9300_max_chains]; 3 xatten1_db ++ * for ar9280 (0xa20c/b20c 5:0) ++ */ ++ .xatten1DB = {0x1b, 0x1b, 0x1b}, ++ ++ /* ++ * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin ++ * for ar9280 (0xa20c/b20c 16:12 ++ */ ++ .xatten1Margin = {0x15, 0x15, 0x15}, ++ .tempSlope = 50, ++ .voltSlope = 0, ++ ++ /* ++ * spurChans[OSPrey_eeprom_modal_sPURS]; spur ++ * channels in usual fbin coding format ++ */ ++ .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0}, ++ ++ /* ++ * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check ++ * if the register is per chain ++ */ ++ .noiseFloorThreshCh = {-1, 0, 0}, ++ .ob = {1, 1, 1},/* 3 chain */ ++ .db_stage2 = {1, 1, 1}, /* 3 chain */ ++ .db_stage3 = {0, 0, 0}, ++ .db_stage4 = {0, 0, 0}, ++ .xpaBiasLvl = 0, ++ .txFrameToDataStart = 0x0e, ++ .txFrameToPaOn = 0x0e, ++ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ ++ .antennaGain = 0, ++ .switchSettling = 0x2c, ++ .adcDesiredSize = -30, ++ .txEndToXpaOff = 0, ++ .txEndToRxOn = 0x2, ++ .txFrameToXpaOn = 0xe, ++ .thresh62 = 28, ++ .papdRateMaskHt20 = LE32(0x0c80c080), ++ .papdRateMaskHt40 = LE32(0x0080c080), ++ .futureModal = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ }, ++ }, ++ .base_ext1 = { ++ .ant_div_control = 0, ++ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ++ }, ++ .calFreqPier2G = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1), ++ }, ++ /* ar9300_cal_data_per_freq_op_loop 2g */ ++ .calPierData2G = { ++ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, ++ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, ++ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, ++ }, ++ .calTarget_freqbin_Cck = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2472, 1), ++ }, ++ .calTarget_freqbin_2G = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1) ++ }, ++ .calTarget_freqbin_2GHT20 = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1) ++ }, ++ .calTarget_freqbin_2GHT40 = { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2437, 1), ++ FREQ2FBIN(2472, 1) ++ }, ++ .calTargetPowerCck = { ++ /* 1L-5L,5S,11L,11s */ ++ { {38, 38, 38, 38} }, ++ { {38, 38, 38, 38} }, ++ }, ++ .calTargetPower2G = { ++ /* 6-24,36,48,54 */ ++ { {38, 38, 36, 34} }, ++ { {38, 38, 36, 34} }, ++ { {38, 38, 34, 32} }, ++ }, ++ .calTargetPower2GHT20 = { ++ { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} }, ++ { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} }, ++ { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} }, ++ }, ++ .calTargetPower2GHT40 = { ++ { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} }, ++ { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} }, ++ { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} }, ++ }, ++ .ctlIndex_2G = { ++ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, ++ 0x45, 0x47, 0x31, 0x32, 0x35, 0x37, ++ }, ++ .ctl_freqbin_2G = { ++ { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2457, 1), ++ FREQ2FBIN(2462, 1) ++ }, ++ { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2462, 1), ++ 0xFF, ++ }, ++ ++ { ++ FREQ2FBIN(2412, 1), ++ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2462, 1), ++ 0xFF, ++ }, ++ { ++ FREQ2FBIN(2422, 1), ++ FREQ2FBIN(2427, 1), ++ FREQ2FBIN(2447, 1), ++ FREQ2FBIN(2452, 1) ++ }, ++ ++ { ++ /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1), ++ /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1), ++ /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1), ++ /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1), ++ }, ++ ++ { ++ /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1), ++ /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1), ++ /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1), ++ 0, ++ }, ++ ++ { ++ /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1), ++ /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1), ++ FREQ2FBIN(2472, 1), ++ 0, ++ }, ++ ++ { ++ /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1), ++ /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1), ++ /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1), ++ /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1), ++ }, ++ ++ { ++ /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1), ++ /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1), ++ /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1), ++ }, ++ ++ { ++ /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1), ++ /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1), ++ /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1), ++ 0 ++ }, ++ ++ { ++ /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1), ++ /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1), ++ /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1), ++ 0 ++ }, ++ ++ { ++ /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1), ++ /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1), ++ /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1), ++ /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1), ++ } ++ }, ++ .ctlPowerData_2G = { ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, ++ ++ { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ ++ { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, ++ }, ++ .modalHeader5G = { ++ /* 4 idle,t1,t2,b (4 bits per setting) */ ++ .antCtrlCommon = LE32(0x110), ++ /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ ++ .antCtrlCommon2 = LE32(0x22222), ++ /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ ++ .antCtrlChain = { ++ LE16(0x0), LE16(0x0), LE16(0x0), ++ }, ++ /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */ ++ .xatten1DB = {0x13, 0x19, 0x17}, ++ ++ /* ++ * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin ++ * for merlin (0xa20c/b20c 16:12 ++ */ ++ .xatten1Margin = {0x19, 0x19, 0x19}, ++ .tempSlope = 70, ++ .voltSlope = 15, ++ /* spurChans spur channels in usual fbin coding format */ ++ .spurChans = {0, 0, 0, 0, 0}, ++ /* noiseFloorThreshch check if the register is per chain */ ++ .noiseFloorThreshCh = {-1, 0, 0}, ++ .ob = {3, 3, 3}, /* 3 chain */ ++ .db_stage2 = {3, 3, 3}, /* 3 chain */ ++ .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ ++ .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ ++ .xpaBiasLvl = 0, ++ .txFrameToDataStart = 0x0e, ++ .txFrameToPaOn = 0x0e, ++ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ ++ .antennaGain = 0, ++ .switchSettling = 0x2d, ++ .adcDesiredSize = -30, ++ .txEndToXpaOff = 0, ++ .txEndToRxOn = 0x2, ++ .txFrameToXpaOn = 0xe, ++ .thresh62 = 28, ++ .papdRateMaskHt20 = LE32(0x0cf0e0e0), ++ .papdRateMaskHt40 = LE32(0x6cf0e0e0), ++ .futureModal = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ }, ++ }, ++ .base_ext2 = { ++ .tempSlopeLow = 72, ++ .tempSlopeHigh = 105, ++ .xatten1DBLow = {0x10, 0x14, 0x10}, ++ .xatten1MarginLow = {0x19, 0x19 , 0x19}, ++ .xatten1DBHigh = {0x1d, 0x20, 0x24}, ++ .xatten1MarginHigh = {0x10, 0x10, 0x10} ++ }, ++ .calFreqPier5G = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5220, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5600, 0), ++ FREQ2FBIN(5700, 0), ++ FREQ2FBIN(5785, 0) ++ }, ++ .calPierData5G = { ++ { ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ }, ++ { ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ }, ++ { ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0}, ++ }, ++ ++ }, ++ .calTarget_freqbin_5G = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5220, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5600, 0), ++ FREQ2FBIN(5725, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calTarget_freqbin_5GHT20 = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5220, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5600, 0), ++ FREQ2FBIN(5725, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calTarget_freqbin_5GHT40 = { ++ FREQ2FBIN(5180, 0), ++ FREQ2FBIN(5220, 0), ++ FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), ++ FREQ2FBIN(5500, 0), ++ FREQ2FBIN(5600, 0), ++ FREQ2FBIN(5725, 0), ++ FREQ2FBIN(5825, 0) ++ }, ++ .calTargetPower5G = { ++ /* 6-24,36,48,54 */ ++ { {32, 32, 28, 26} }, ++ { {32, 32, 28, 26} }, ++ { {32, 32, 28, 26} }, ++ { {32, 32, 26, 24} }, ++ { {32, 32, 26, 24} }, ++ { {32, 32, 24, 22} }, ++ { {30, 30, 24, 22} }, ++ { {30, 30, 24, 22} }, ++ }, ++ .calTargetPower5GHT20 = { ++ /* ++ * 0_8_16,1-3_9-11_17-19, ++ * 4,5,6,7,12,13,14,15,20,21,22,23 ++ */ ++ { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} }, ++ { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} }, ++ { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} }, ++ { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} }, ++ { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} }, ++ { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} }, ++ { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} }, ++ { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} }, ++ }, ++ .calTargetPower5GHT40 = { ++ /* ++ * 0_8_16,1-3_9-11_17-19, ++ * 4,5,6,7,12,13,14,15,20,21,22,23 ++ */ ++ { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} }, ++ { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} }, ++ { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} }, ++ { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} }, ++ { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} }, ++ { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} }, ++ { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} }, ++ { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} }, ++ }, ++ .ctlIndex_5G = { ++ 0x10, 0x16, 0x18, 0x40, 0x46, ++ 0x48, 0x30, 0x36, 0x38 ++ }, ++ .ctl_freqbin_5G = { ++ { ++ /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0), ++ /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0), ++ /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0), ++ /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0), ++ /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0), ++ /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0), ++ /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0), ++ /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0) ++ }, ++ { ++ /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0), ++ /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0), ++ /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0), ++ /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0), ++ /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0), ++ /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0), ++ /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0), ++ /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0) ++ }, ++ ++ { ++ /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0), ++ /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0), ++ /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0), ++ /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0), ++ /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0), ++ /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0), ++ /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0), ++ /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0) ++ }, ++ ++ { ++ /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0), ++ /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0), ++ /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0), ++ /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0), ++ /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0), ++ /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0), ++ /* Data[3].ctledges[6].bchannel */ 0xFF, ++ /* Data[3].ctledges[7].bchannel */ 0xFF, ++ }, ++ ++ { ++ /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0), ++ /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0), ++ /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0), ++ /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0), ++ /* Data[4].ctledges[4].bchannel */ 0xFF, ++ /* Data[4].ctledges[5].bchannel */ 0xFF, ++ /* Data[4].ctledges[6].bchannel */ 0xFF, ++ /* Data[4].ctledges[7].bchannel */ 0xFF, ++ }, ++ ++ { ++ /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0), ++ /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0), ++ /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0), ++ /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0), ++ /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0), ++ /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0), ++ /* Data[5].ctledges[6].bchannel */ 0xFF, ++ /* Data[5].ctledges[7].bchannel */ 0xFF ++ }, ++ ++ { ++ /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0), ++ /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0), ++ /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0), ++ /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0), ++ /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0), ++ /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0), ++ /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0), ++ /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0) ++ }, ++ ++ { ++ /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0), ++ /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0), ++ /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0), ++ /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0), ++ /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0), ++ /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0), ++ /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0), ++ /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0) ++ }, ++ ++ { ++ /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0), ++ /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0), ++ /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0), ++ /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0), ++ /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0), ++ /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0), ++ /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0), ++ /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0) ++ } ++ }, ++ .ctlPowerData_5G = { ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 0}, {60, 1}, {60, 0}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ } ++ }, ++ { ++ { ++ {60, 0}, {60, 1}, {60, 1}, {60, 0}, ++ {60, 1}, {60, 0}, {60, 0}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ {60, 0}, {60, 0}, {60, 0}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 0}, {60, 0}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 1}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 1}, {60, 0}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 1}, {60, 0}, ++ } ++ }, ++ { ++ { ++ {60, 1}, {60, 0}, {60, 1}, {60, 1}, ++ {60, 1}, {60, 1}, {60, 0}, {60, 1}, ++ } ++ }, ++ } ++}; ++ ++static const struct ar9300_eeprom ar9300_h116 = { ++ .eepromVersion = 2, ++ .templateVersion = 4, ++ .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0}, ++ .custData = {"h116-041-f0000"}, + .baseEepHeader = { + .regDmn = { LE16(0), LE16(0x1f) }, +- .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ ++ .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */ + .opCapFlags = { + .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, + .eepMisc = 0, +@@ -74,7 +2388,7 @@ static const struct ar9300_eeprom ar9300 + .deviceType = 5, /* takes lower byte in eeprom location */ + .pwrTableOffset = AR9300_PWR_TABLE_OFFSET, + .params_for_tuning_caps = {0, 0}, +- .featureEnable = 0x0c, ++ .featureEnable = 0x0d, + /* + * bit0 - enable tx temp comp - disabled + * bit1 - enable tx volt comp - disabled +@@ -84,11 +2398,11 @@ static const struct ar9300_eeprom ar9300 + * bit5 - enable pa predistortion - disabled */ .miscConfiguration = 0, /* bit0 - turn down drivestrength */ - .eepromWriteEnableGpio = 3, -@@ -129,9 +130,11 @@ static const struct ar9300_eeprom ar9300 +- .eepromWriteEnableGpio = 3, ++ .eepromWriteEnableGpio = 6, + .wlanDisableGpio = 0, + .wlanLedGpio = 8, + .rxBandSelectGpio = 0xff, +- .txrxgain = 0, ++ .txrxgain = 0x10, + .swreg = 0, + }, + .modalHeader2G = { +@@ -96,33 +2410,33 @@ static const struct ar9300_eeprom ar9300 + /* 4 idle,t1,t2,b(4 bits per setting) */ + .antCtrlCommon = LE32(0x110), + /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ +- .antCtrlCommon2 = LE32(0x22222), ++ .antCtrlCommon2 = LE32(0x44444), + + /* + * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r, + * rx1, rx12, b (2 bits each) + */ +- .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) }, ++ .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) }, + + /* + * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db + * for ar9280 (0xa20c/b20c 5:0) + */ +- .xatten1DB = {0, 0, 0}, ++ .xatten1DB = {0x1f, 0x1f, 0x1f}, + + /* + * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin + * for ar9280 (0xa20c/b20c 16:12 + */ +- .xatten1Margin = {0, 0, 0}, +- .tempSlope = 36, ++ .xatten1Margin = {0x12, 0x12, 0x12}, ++ .tempSlope = 25, + .voltSlope = 0, + + /* + * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur + * channels in usual fbin coding format + */ +- .spurChans = {0, 0, 0, 0, 0}, ++ .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0}, + + /* + * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check +@@ -144,13 +2458,16 @@ static const struct ar9300_eeprom ar9300 .txEndToRxOn = 0x2, .txFrameToXpaOn = 0xe, .thresh62 = 28, -- .futureModal = { /* [32] */ -+ .papdRateMaskHt20 = LE32(0x80c080), -+ .papdRateMaskHt40 = LE32(0x80c080), -+ .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+ 0, 0, 0, 0, 0, 0, 0, 0 +- .papdRateMaskHt20 = LE32(0x80c080), +- .papdRateMaskHt40 = LE32(0x80c080), ++ .papdRateMaskHt20 = LE32(0x0c80C080), ++ .papdRateMaskHt40 = LE32(0x0080C080), + .futureModal = { +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0 ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, }, ++ .base_ext1 = { ++ .ant_div_control = 0, ++ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ++ }, .calFreqPier2G = { -@@ -326,9 +329,11 @@ static const struct ar9300_eeprom ar9300 + FREQ2FBIN(2412, 1), + FREQ2FBIN(2437, 1), +@@ -164,7 +2481,7 @@ static const struct ar9300_eeprom ar9300 + }, + .calTarget_freqbin_Cck = { + FREQ2FBIN(2412, 1), +- FREQ2FBIN(2484, 1), ++ FREQ2FBIN(2472, 1), + }, + .calTarget_freqbin_2G = { + FREQ2FBIN(2412, 1), +@@ -183,24 +2500,24 @@ static const struct ar9300_eeprom ar9300 + }, + .calTargetPowerCck = { + /* 1L-5L,5S,11L,11S */ +- { {36, 36, 36, 36} }, +- { {36, 36, 36, 36} }, ++ { {34, 34, 34, 34} }, ++ { {34, 34, 34, 34} }, + }, + .calTargetPower2G = { + /* 6-24,36,48,54 */ +- { {32, 32, 28, 24} }, +- { {32, 32, 28, 24} }, +- { {32, 32, 28, 24} }, ++ { {34, 34, 32, 32} }, ++ { {34, 34, 32, 32} }, ++ { {34, 34, 32, 32} }, + }, + .calTargetPower2GHT20 = { +- { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, +- { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, +- { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, ++ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} }, ++ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} }, ++ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} }, + }, + .calTargetPower2GHT40 = { +- { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, +- { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, +- { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, ++ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} }, ++ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} }, ++ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} }, + }, + .ctlIndex_2G = { + 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, +@@ -285,8 +2602,7 @@ static const struct ar9300_eeprom ar9300 + /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), + /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), + /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), +- /* Data[11].ctlEdges[3].bChannel */ +- FREQ2FBIN(2462, 1), ++ /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), + } + }, + .ctlPowerData_2G = { +@@ -304,25 +2620,26 @@ static const struct ar9300_eeprom ar9300 + + { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, ++ { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, + }, + .modalHeader5G = { + /* 4 idle,t1,t2,b (4 bits per setting) */ +- .antCtrlCommon = LE32(0x110), ++ .antCtrlCommon = LE32(0x220), + /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ +- .antCtrlCommon2 = LE32(0x22222), ++ .antCtrlCommon2 = LE32(0x44444), + /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ + .antCtrlChain = { +- LE16(0x000), LE16(0x000), LE16(0x000), ++ LE16(0x150), LE16(0x150), LE16(0x150), + }, + /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ +- .xatten1DB = {0, 0, 0}, ++ .xatten1DB = {0x19, 0x19, 0x19}, + + /* + * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin + * for merlin (0xa20c/b20c 16:12 + */ +- .xatten1Margin = {0, 0, 0}, +- .tempSlope = 68, ++ .xatten1Margin = {0x14, 0x14, 0x14}, ++ .tempSlope = 70, + .voltSlope = 0, + /* spurChans spur channels in usual fbin coding format */ + .spurChans = {0, 0, 0, 0, 0}, +@@ -343,13 +2660,20 @@ static const struct ar9300_eeprom ar9300 .txEndToRxOn = 0x2, .txFrameToXpaOn = 0xe, .thresh62 = 28, -+ .papdRateMaskHt20 = LE32(0xf0e0e0), -+ .papdRateMaskHt40 = LE32(0xf0e0e0), +- .papdRateMaskHt20 = LE32(0xf0e0e0), +- .papdRateMaskHt40 = LE32(0xf0e0e0), ++ .papdRateMaskHt20 = LE32(0x0cf0e0e0), ++ .papdRateMaskHt40 = LE32(0x6cf0e0e0), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+ 0, 0, 0, 0, 0, 0, 0, 0 +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0 ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, }, ++ .base_ext2 = { ++ .tempSlopeLow = 35, ++ .tempSlopeHigh = 50, ++ .xatten1DBLow = {0, 0, 0}, ++ .xatten1MarginLow = {0, 0, 0}, ++ .xatten1DBHigh = {0, 0, 0}, ++ .xatten1MarginHigh = {0, 0, 0} ++ }, .calFreqPier5G = { -@@ -644,6 +649,8 @@ static u32 ath9k_hw_ar9300_get_eeprom(st - return (pBase->featureEnable & 0x10) >> 4; - case EEP_SWREG: - return le32_to_cpu(pBase->swreg); -+ case EEP_PAPRD: -+ return !!(pBase->featureEnable & BIT(5)); - default: - return 0; - } ---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h -@@ -234,7 +234,9 @@ struct ar9300_modal_eep_header { - u8 txEndToRxOn; - u8 txFrameToXpaOn; - u8 thresh62; -- u8 futureModal[32]; -+ __le32 papdRateMaskHt20; -+ __le32 papdRateMaskHt40; -+ u8 futureModal[24]; - } __packed; - - struct ar9300_cal_data_per_freq_op_loop { ---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c -@@ -470,6 +470,14 @@ static void ar9003_hw_set11n_virtualmore - ads->ctl11 &= ~AR_VirtMoreFrag; - } + FREQ2FBIN(5180, 0), + FREQ2FBIN(5220, 0), +@@ -357,8 +2681,8 @@ static const struct ar9300_eeprom ar9300 + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5600, 0), +- FREQ2FBIN(5725, 0), +- FREQ2FBIN(5825, 0) ++ FREQ2FBIN(5700, 0), ++ FREQ2FBIN(5785, 0) + }, + .calPierData5G = { + { +@@ -395,72 +2719,72 @@ static const struct ar9300_eeprom ar9300 + }, + .calTarget_freqbin_5G = { + FREQ2FBIN(5180, 0), +- FREQ2FBIN(5220, 0), ++ FREQ2FBIN(5240, 0), + FREQ2FBIN(5320, 0), + FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5600, 0), +- FREQ2FBIN(5725, 0), ++ FREQ2FBIN(5700, 0), + FREQ2FBIN(5825, 0) + }, + .calTarget_freqbin_5GHT20 = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5240, 0), + FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5700, 0), + FREQ2FBIN(5745, 0), +- FREQ2FBIN(5725, 0), + FREQ2FBIN(5825, 0) + }, + .calTarget_freqbin_5GHT40 = { + FREQ2FBIN(5180, 0), + FREQ2FBIN(5240, 0), + FREQ2FBIN(5320, 0), ++ FREQ2FBIN(5400, 0), + FREQ2FBIN(5500, 0), + FREQ2FBIN(5700, 0), + FREQ2FBIN(5745, 0), +- FREQ2FBIN(5725, 0), + FREQ2FBIN(5825, 0) + }, + .calTargetPower5G = { + /* 6-24,36,48,54 */ +- { {20, 20, 20, 10} }, +- { {20, 20, 20, 10} }, +- { {20, 20, 20, 10} }, +- { {20, 20, 20, 10} }, +- { {20, 20, 20, 10} }, +- { {20, 20, 20, 10} }, +- { {20, 20, 20, 10} }, +- { {20, 20, 20, 10} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, ++ { {30, 30, 28, 24} }, + }, + .calTargetPower5GHT20 = { + /* + * 0_8_16,1-3_9-11_17-19, + * 4,5,6,7,12,13,14,15,20,21,22,23 + */ +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} }, ++ { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} }, ++ { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} }, ++ { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} }, ++ { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} }, ++ { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} }, ++ { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} }, ++ { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} }, + }, + .calTargetPower5GHT40 = { + /* + * 0_8_16,1-3_9-11_17-19, + * 4,5,6,7,12,13,14,15,20,21,22,23 + */ +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, +- { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, ++ { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} }, ++ { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} }, ++ { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} }, ++ { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} }, ++ { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} }, ++ { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} }, ++ { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} }, ++ { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} }, + }, + .ctlIndex_5G = { + 0x10, 0x16, 0x18, 0x40, 0x46, +@@ -623,6 +2947,28 @@ static const struct ar9300_eeprom ar9300 + } + }; -+void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains) -+{ -+ struct ar9003_txc *ads = ds; + -+ ads->ctl12 |= SM(chains, AR_PAPRDChainMask); -+} -+EXPORT_SYMBOL(ar9003_hw_set_paprd_txdesc); -+ - void ar9003_hw_attach_mac_ops(struct ath_hw *hw) - { - struct ath_hw_ops *ops = ath9k_hw_ops(hw); ---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h -+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h -@@ -40,6 +40,10 @@ - - #define AR_Not_Sounding 0x20000000 - -+/* ctl 12 */ -+#define AR_PAPRDChainMask 0x00000e00 -+#define AR_PAPRDChainMask_S 9 -+ - #define MAP_ISR_S2_CST 6 - #define MAP_ISR_S2_GTT 6 - #define MAP_ISR_S2_TIM 3 ---- /dev/null -+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c -@@ -0,0 +1,713 @@ -+/* -+ * Copyright (c) 2010 Atheros Communications Inc. -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ ++static const struct ar9300_eeprom *ar9300_eep_templates[] = { ++ &ar9300_default, ++ &ar9300_x112, ++ &ar9300_h116, ++ &ar9300_h112, ++ &ar9300_x113, ++}; + -+#include "hw.h" -+#include "ar9003_phy.h" -+ -+void ar9003_paprd_enable(struct ath_hw *ah, bool val) ++static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id) +{ -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, -+ AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1, -+ AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2, -+ AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); ++#define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0])) ++ int it; ++ ++ for (it = 0; it < N_LOOP; it++) ++ if (ar9300_eep_templates[it]->templateVersion == id) ++ return ar9300_eep_templates[it]; ++ return NULL; ++#undef N_LOOP +} -+EXPORT_SYMBOL(ar9003_paprd_enable); -+ -+static void ar9003_paprd_setup_single_table(struct ath_hw *ah) -+{ -+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; -+ struct ar9300_modal_eep_header *hdr; -+ const u32 ctrl0[3] = { -+ AR_PHY_PAPRD_CTRL0_B0, -+ AR_PHY_PAPRD_CTRL0_B1, -+ AR_PHY_PAPRD_CTRL0_B2 -+ }; -+ const u32 ctrl1[3] = { -+ AR_PHY_PAPRD_CTRL1_B0, -+ AR_PHY_PAPRD_CTRL1_B1, -+ AR_PHY_PAPRD_CTRL1_B2 -+ }; -+ u32 am_mask, ht40_mask; -+ int i; -+ -+ if (ah->curchan && IS_CHAN_5GHZ(ah->curchan)) -+ hdr = &eep->modalHeader5G; -+ else -+ hdr = &eep->modalHeader2G; -+ -+ am_mask = le32_to_cpu(hdr->papdRateMaskHt20); -+ ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40); -+ -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask); -+ -+ for (i = 0; i < 3; i++) { -+ REG_RMW_FIELD(ah, ctrl0[i], -+ AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1); -+ REG_RMW_FIELD(ah, ctrl1[i], -+ AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE, 1); -+ REG_RMW_FIELD(ah, ctrl1[i], -+ AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE, 1); -+ REG_RMW_FIELD(ah, ctrl1[i], -+ AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA, 0); -+ REG_RMW_FIELD(ah, ctrl1[i], -+ AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK, 181); -+ REG_RMW_FIELD(ah, ctrl1[i], -+ AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT, 361); -+ REG_RMW_FIELD(ah, ctrl1[i], -+ AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA, 0); -+ REG_RMW_FIELD(ah, ctrl0[i], -+ AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH, 3); -+ } + -+ ar9003_paprd_enable(ah, false); -+ -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP, 0x30); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE, 1); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE, 1); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE, 0); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE, 0); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2, -+ AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 147); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN, 4); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN, 4); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -+ -15); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE, 1); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4, -+ AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA, 0); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4, -+ AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR, 400); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4, -+ AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES, -+ 100); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_0_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 261376); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_1_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 248079); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_2_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 233759); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_3_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 220464); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_4_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 208194); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_5_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 196949); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_6_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 185706); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 175487); -+} + -+static void ar9003_paprd_get_gain_table(struct ath_hw *ah) + static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) + { + if (fbin == AR9300_BCHAN_UNUSED) +@@ -636,6 +2982,16 @@ static int ath9k_hw_ar9300_check_eeprom( + return 0; + } + ++static int interpolate(int x, int xa, int xb, int ya, int yb) +{ -+ u32 *entry = ah->paprd_gain_table_entries; -+ u8 *index = ah->paprd_gain_table_index; -+ u32 reg = AR_PHY_TXGAIN_TABLE; -+ int i; ++ int bf, factor, plus; + -+ memset(entry, 0, sizeof(ah->paprd_gain_table_entries)); -+ memset(index, 0, sizeof(ah->paprd_gain_table_index)); -+ -+ for (i = 0; i < 32; i++) { -+ entry[i] = REG_READ(ah, reg); -+ index[i] = (entry[i] >> 24) & 0xff; -+ reg += 4; -+ } ++ bf = 2 * (yb - ya) * (x - xa) / (xb - xa); ++ factor = bf / 2; ++ plus = bf % 2; ++ return ya + factor + plus; +} + -+static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain, -+ int target_power) + static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, + enum eeprom_param param) + { +@@ -824,6 +3180,7 @@ static int ar9300_compress_decision(stru + { + struct ath_common *common = ath9k_hw_common(ah); + u8 *dptr; ++ const struct ar9300_eeprom *eep = NULL; + + switch (code) { + case _CompressNone: +@@ -841,13 +3198,14 @@ static int ar9300_compress_decision(stru + if (reference == 0) { + dptr = mptr; + } else { +- if (reference != 2) { ++ eep = ar9003_eeprom_struct_find_by_id(reference); ++ if (eep == NULL) { + ath_print(common, ATH_DBG_EEPROM, + "cant find reference eeprom" + "struct %d\n", reference); + return -1; + } +- memcpy(mptr, &ar9300_default, mdata_size); ++ memcpy(mptr, eep, mdata_size); + } + ath_print(common, ATH_DBG_EEPROM, + "restore eeprom %d: block, reference %d," +@@ -992,9 +3350,9 @@ static s32 ar9003_hw_xpa_bias_level_get( + static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) + { + int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); +- REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3)); +- REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE, +- ((bias >> 2) & 0x3)); ++ REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); ++ REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB, bias >> 2); ++ REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1); + } + + static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz) +@@ -1097,6 +3455,82 @@ static void ar9003_hw_drive_strength_app + REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg); + } + ++static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain, ++ struct ath9k_channel *chan) +{ -+ int olpc_gain_delta = 0; -+ int alpha_therm, alpha_volt; -+ int therm_cal_value, volt_cal_value; -+ int therm_value, volt_value; -+ int thermal_gain_corr, voltage_gain_corr; -+ int desired_scale, desired_gain = 0; -+ u32 reg; -+ -+ REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, -+ AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); -+ desired_scale = REG_READ_FIELD(ah, AR_PHY_TPC_12, -+ AR_PHY_TPC_12_DESIRED_SCALE_HT40_5); -+ alpha_therm = REG_READ_FIELD(ah, AR_PHY_TPC_19, -+ AR_PHY_TPC_19_ALPHA_THERM); -+ alpha_volt = REG_READ_FIELD(ah, AR_PHY_TPC_19, -+ AR_PHY_TPC_19_ALPHA_VOLT); -+ therm_cal_value = REG_READ_FIELD(ah, AR_PHY_TPC_18, -+ AR_PHY_TPC_18_THERM_CAL_VALUE); -+ volt_cal_value = REG_READ_FIELD(ah, AR_PHY_TPC_18, -+ AR_PHY_TPC_18_VOLT_CAL_VALUE); -+ therm_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, -+ AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE); -+ volt_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, -+ AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE); -+ -+ if (chain == 0) -+ reg = AR_PHY_TPC_11_B0; -+ else if (chain == 1) -+ reg = AR_PHY_TPC_11_B1; -+ else -+ reg = AR_PHY_TPC_11_B2; -+ -+ olpc_gain_delta = REG_READ_FIELD(ah, reg, -+ AR_PHY_TPC_11_OLPC_GAIN_DELTA); -+ -+ if (olpc_gain_delta >= 128) -+ olpc_gain_delta = olpc_gain_delta - 256; ++ int f[3], t[3]; ++ u16 value; ++ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + -+ thermal_gain_corr = (alpha_therm * (therm_value - therm_cal_value) + -+ (256 / 2)) / 256; -+ voltage_gain_corr = (alpha_volt * (volt_value - volt_cal_value) + -+ (128 / 2)) / 128; -+ desired_gain = target_power - olpc_gain_delta - thermal_gain_corr - -+ voltage_gain_corr + desired_scale; ++ if (chain >= 0 && chain < 3) { ++ if (IS_CHAN_2GHZ(chan)) ++ return eep->modalHeader2G.xatten1DB[chain]; ++ else if (eep->base_ext2.xatten1DBLow[chain] != 0) { ++ t[0] = eep->base_ext2.xatten1DBLow[chain]; ++ f[0] = 5180; ++ t[1] = eep->modalHeader5G.xatten1DB[chain]; ++ f[1] = 5500; ++ t[2] = eep->base_ext2.xatten1DBHigh[chain]; ++ f[2] = 5785; ++ value = ar9003_hw_power_interpolate((s32) chan->channel, ++ f, t, 3); ++ return value; ++ } else ++ return eep->modalHeader5G.xatten1DB[chain]; ++ } + -+ return desired_gain; ++ return 0; +} + -+static void ar9003_tx_force_gain(struct ath_hw *ah, unsigned int gain_index) -+{ -+ int selected_gain_entry, txbb1dbgain, txbb6dbgain, txmxrgain; -+ int padrvgnA, padrvgnB, padrvgnC, padrvgnD; -+ u32 *gain_table_entries = ah->paprd_gain_table_entries; -+ -+ selected_gain_entry = gain_table_entries[gain_index]; -+ txbb1dbgain = selected_gain_entry & 0x7; -+ txbb6dbgain = (selected_gain_entry >> 3) & 0x3; -+ txmxrgain = (selected_gain_entry >> 5) & 0xf; -+ padrvgnA = (selected_gain_entry >> 9) & 0xf; -+ padrvgnB = (selected_gain_entry >> 13) & 0xf; -+ padrvgnC = (selected_gain_entry >> 17) & 0xf; -+ padrvgnD = (selected_gain_entry >> 21) & 0x3; -+ -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN, txbb1dbgain); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN, txbb6dbgain); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN, txmxrgain); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA, padrvgnA); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB, padrvgnB); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC, padrvgnC); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND, padrvgnD); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL, 0); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN, 0); -+ REG_RMW_FIELD(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCED_DAC_GAIN, 0); -+ REG_RMW_FIELD(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCE_DAC_GAIN, 0); -+} + -+static inline int find_expn(int num) ++static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain, ++ struct ath9k_channel *chan) +{ -+ return fls(num) - 1; -+} ++ int f[3], t[3]; ++ u16 value; ++ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + -+static inline int find_proper_scale(int expn, int N) -+{ -+ return (expn > N) ? expn - 10 : 0; -+} ++ if (chain >= 0 && chain < 3) { ++ if (IS_CHAN_2GHZ(chan)) ++ return eep->modalHeader2G.xatten1Margin[chain]; ++ else if (eep->base_ext2.xatten1MarginLow[chain] != 0) { ++ t[0] = eep->base_ext2.xatten1MarginLow[chain]; ++ f[0] = 5180; ++ t[1] = eep->modalHeader5G.xatten1Margin[chain]; ++ f[1] = 5500; ++ t[2] = eep->base_ext2.xatten1MarginHigh[chain]; ++ f[2] = 5785; ++ value = ar9003_hw_power_interpolate((s32) chan->channel, ++ f, t, 3); ++ return value; ++ } else ++ return eep->modalHeader5G.xatten1Margin[chain]; ++ } + -+#define NUM_BIN 23 ++ return 0; ++} + -+static bool create_pa_curve(u32 *data_L, u32 *data_U, u32 *pa_table, u16 *gain) ++static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan) +{ -+ unsigned int thresh_accum_cnt; -+ int x_est[NUM_BIN + 1], Y[NUM_BIN + 1], theta[NUM_BIN + 1]; -+ int PA_in[NUM_BIN + 1]; -+ int B1_tmp[NUM_BIN + 1], B2_tmp[NUM_BIN + 1]; -+ unsigned int B1_abs_max, B2_abs_max; -+ int max_index, scale_factor; -+ int y_est[NUM_BIN + 1]; -+ int x_est_fxp1_nonlin, x_tilde[NUM_BIN + 1]; -+ unsigned int x_tilde_abs; -+ int G_fxp, Y_intercept, order_x_by_y, M, I, L, sum_y_sqr, sum_y_quad; -+ int Q_x, Q_B1, Q_B2, beta_raw, alpha_raw, scale_B; -+ int Q_scale_B, Q_beta, Q_alpha, alpha, beta, order_1, order_2; -+ int order1_5x, order2_3x, order1_5x_rem, order2_3x_rem; -+ int y5, y3, tmp; -+ int theta_low_bin = 0; + int i; ++ u16 value; ++ unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0, ++ AR_PHY_EXT_ATTEN_CTL_1, ++ AR_PHY_EXT_ATTEN_CTL_2, ++ }; + -+ /* disregard any bin that contains <= 16 samples */ -+ thresh_accum_cnt = 16; -+ scale_factor = 5; -+ max_index = 0; -+ memset(theta, 0, sizeof(theta)); -+ memset(x_est, 0, sizeof(x_est)); -+ memset(Y, 0, sizeof(Y)); -+ memset(y_est, 0, sizeof(y_est)); -+ memset(x_tilde, 0, sizeof(x_tilde)); -+ -+ for (i = 0; i < NUM_BIN; i++) { -+ s32 accum_cnt, accum_tx, accum_rx, accum_ang; -+ -+ /* number of samples */ -+ accum_cnt = data_L[i] & 0xffff; -+ -+ if (accum_cnt <= thresh_accum_cnt) -+ continue; -+ -+ /* sum(tx amplitude) */ -+ accum_tx = ((data_L[i] >> 16) & 0xffff) | -+ ((data_U[i] & 0x7ff) << 16); -+ -+ /* sum(rx amplitude distance to lower bin edge) */ -+ accum_rx = ((data_U[i] >> 11) & 0x1f) | -+ ((data_L[i + 23] & 0xffff) << 5); -+ -+ /* sum(angles) */ -+ accum_ang = ((data_L[i + 23] >> 16) & 0xffff) | -+ ((data_U[i + 23] & 0x7ff) << 16); -+ -+ accum_tx <<= scale_factor; -+ accum_rx <<= scale_factor; -+ x_est[i + 1] = (((accum_tx + accum_cnt) / accum_cnt) + 32) >> -+ scale_factor; -+ -+ Y[i + 1] = ((((accum_rx + accum_cnt) / accum_cnt) + 32) >> -+ scale_factor) + (1 << scale_factor) * max_index + 16; -+ -+ if (accum_ang >= (1 << 26)) -+ accum_ang -= 1 << 27; -+ -+ theta[i + 1] = ((accum_ang * (1 << scale_factor)) + accum_cnt) / -+ accum_cnt; -+ -+ max_index++; -+ } -+ -+ /* -+ * Find average theta of first 5 bin and all of those to same value. -+ * Curve is linear at that range. -+ */ -+ for (i = 1; i < 6; i++) -+ theta_low_bin += theta[i]; -+ -+ theta_low_bin = theta_low_bin / 5; -+ for (i = 1; i < 6; i++) -+ theta[i] = theta_low_bin; -+ -+ /* Set values at origin */ -+ theta[0] = theta_low_bin; -+ for (i = 0; i <= max_index; i++) -+ theta[i] -= theta_low_bin; -+ -+ x_est[0] = 0; -+ Y[0] = 0; -+ scale_factor = 8; -+ -+ /* low signal gain */ -+ if (x_est[6] == x_est[3]) -+ return false; -+ -+ G_fxp = -+ (((Y[6] - Y[3]) * 1 << scale_factor) + -+ (x_est[6] - x_est[3])) / (x_est[6] - x_est[3]); -+ -+ Y_intercept = -+ (G_fxp * (x_est[0] - x_est[3]) + -+ (1 << scale_factor)) / (1 << scale_factor) + Y[3]; -+ -+ for (i = 0; i <= max_index; i++) -+ y_est[i] = Y[i] - Y_intercept; -+ -+ for (i = 0; i <= 3; i++) { -+ y_est[i] = i * 32; -+ -+ /* prevent division by zero */ -+ if (G_fxp == 0) -+ return false; -+ -+ x_est[i] = ((y_est[i] * 1 << scale_factor) + G_fxp) / G_fxp; -+ } -+ -+ x_est_fxp1_nonlin = -+ x_est[max_index] - ((1 << scale_factor) * y_est[max_index] + -+ G_fxp) / G_fxp; -+ -+ order_x_by_y = -+ (x_est_fxp1_nonlin + y_est[max_index]) / y_est[max_index]; -+ -+ if (order_x_by_y == 0) -+ M = 10; -+ else if (order_x_by_y == 1) -+ M = 9; -+ else -+ M = 8; -+ -+ I = (max_index > 15) ? 7 : max_index >> 1; -+ L = max_index - I; -+ scale_factor = 8; -+ sum_y_sqr = 0; -+ sum_y_quad = 0; -+ x_tilde_abs = 0; -+ -+ for (i = 0; i <= L; i++) { -+ unsigned int y_sqr; -+ unsigned int y_quad; -+ unsigned int tmp_abs; -+ -+ /* prevent division by zero */ -+ if (y_est[i + I] == 0) -+ return false; -+ -+ x_est_fxp1_nonlin = -+ x_est[i + I] - ((1 << scale_factor) * y_est[i + I] + -+ G_fxp) / G_fxp; -+ -+ x_tilde[i] = -+ (x_est_fxp1_nonlin * (1 << M) + y_est[i + I]) / y_est[i + -+ I]; -+ x_tilde[i] = -+ (x_tilde[i] * (1 << M) + y_est[i + I]) / y_est[i + I]; -+ x_tilde[i] = -+ (x_tilde[i] * (1 << M) + y_est[i + I]) / y_est[i + I]; -+ y_sqr = -+ (y_est[i + I] * y_est[i + I] + -+ (scale_factor * scale_factor)) / (scale_factor * -+ scale_factor); -+ tmp_abs = abs(x_tilde[i]); -+ if (tmp_abs > x_tilde_abs) -+ x_tilde_abs = tmp_abs; -+ -+ y_quad = y_sqr * y_sqr; -+ sum_y_sqr = sum_y_sqr + y_sqr; -+ sum_y_quad = sum_y_quad + y_quad; -+ B1_tmp[i] = y_sqr * (L + 1); -+ B2_tmp[i] = y_sqr; -+ } -+ -+ B1_abs_max = 0; -+ B2_abs_max = 0; -+ for (i = 0; i <= L; i++) { -+ int abs_val; -+ -+ B1_tmp[i] -= sum_y_sqr; -+ B2_tmp[i] = sum_y_quad - sum_y_sqr * B2_tmp[i]; -+ -+ abs_val = abs(B1_tmp[i]); -+ if (abs_val > B1_abs_max) -+ B1_abs_max = abs_val; -+ -+ abs_val = abs(B2_tmp[i]); -+ if (abs_val > B2_abs_max) -+ B2_abs_max = abs_val; -+ } ++ /* Test value. if 0 then attenuation is unused. Don't load anything. */ ++ for (i = 0; i < 3; i++) { ++ value = ar9003_hw_atten_chain_get(ah, i, chan); ++ REG_RMW_FIELD(ah, ext_atten_reg[i], ++ AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); + -+ Q_x = find_proper_scale(find_expn(x_tilde_abs), 10); -+ Q_B1 = find_proper_scale(find_expn(B1_abs_max), 10); -+ Q_B2 = find_proper_scale(find_expn(B2_abs_max), 10); -+ -+ beta_raw = 0; -+ alpha_raw = 0; -+ for (i = 0; i <= L; i++) { -+ x_tilde[i] = x_tilde[i] / (1 << Q_x); -+ B1_tmp[i] = B1_tmp[i] / (1 << Q_B1); -+ B2_tmp[i] = B2_tmp[i] / (1 << Q_B2); -+ beta_raw = beta_raw + B1_tmp[i] * x_tilde[i]; -+ alpha_raw = alpha_raw + B2_tmp[i] * x_tilde[i]; ++ value = ar9003_hw_atten_chain_get_margin(ah, i, chan); ++ REG_RMW_FIELD(ah, ext_atten_reg[i], ++ AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value); + } ++} + -+ scale_B = -+ ((sum_y_quad / scale_factor) * (L + 1) - -+ (sum_y_sqr / scale_factor) * sum_y_sqr) * scale_factor; -+ -+ Q_scale_B = find_proper_scale(find_expn(abs(scale_B)), 10); -+ scale_B = scale_B / (1 << Q_scale_B); -+ Q_beta = find_proper_scale(find_expn(abs(beta_raw)), 10); -+ Q_alpha = find_proper_scale(find_expn(abs(alpha_raw)), 10); -+ beta_raw = beta_raw / (1 << Q_beta); -+ alpha_raw = alpha_raw / (1 << Q_alpha); -+ alpha = (alpha_raw << 10) / scale_B; -+ beta = (beta_raw << 10) / scale_B; -+ order_1 = 3 * M - Q_x - Q_B1 - Q_beta + 10 + Q_scale_B; -+ order_2 = 3 * M - Q_x - Q_B2 - Q_alpha + 10 + Q_scale_B; -+ order1_5x = order_1 / 5; -+ order2_3x = order_2 / 3; -+ order1_5x_rem = order_1 - 5 * order1_5x; -+ order2_3x_rem = order_2 - 3 * order2_3x; -+ -+ for (i = 0; i < PAPRD_TABLE_SZ; i++) { -+ tmp = i * 32; -+ y5 = ((beta * tmp) >> 6) >> order1_5x; -+ y5 = (y5 * tmp) >> order1_5x; -+ y5 = (y5 * tmp) >> order1_5x; -+ y5 = (y5 * tmp) >> order1_5x; -+ y5 = (y5 * tmp) >> order1_5x; -+ y5 = y5 >> order1_5x_rem; -+ y3 = (alpha * tmp) >> order2_3x; -+ y3 = (y3 * tmp) >> order2_3x; -+ y3 = (y3 * tmp) >> order2_3x; -+ y3 = y3 >> order2_3x_rem; -+ PA_in[i] = y5 + y3 + (256 * tmp) / G_fxp; -+ -+ if (i >= 2) { -+ tmp = PA_in[i] - PA_in[i - 1]; -+ if (tmp < 0) -+ PA_in[i] = -+ PA_in[i - 1] + (PA_in[i - 1] - -+ PA_in[i - 2]); + static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) + { + int internal_regulator = +@@ -1128,6 +3562,7 @@ static void ath9k_hw_ar9300_set_board_va + ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan)); + ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); + ar9003_hw_drive_strength_apply(ah); ++ ar9003_hw_atten_apply(ah, chan); + ar9003_hw_internal_regulator_apply(ah); + } + +@@ -1189,7 +3624,7 @@ static int ar9003_hw_power_interpolate(i + if (hx == lx) + y = ly; + else /* interpolate */ +- y = ly + (((x - lx) * (hy - ly)) / (hx - lx)); ++ y = interpolate(x, lx, hx, ly, hy); + } else /* only low is good, use it */ + y = ly; + } else if (hhave) /* only high is good, use it */ +@@ -1637,6 +4072,7 @@ static int ar9003_hw_power_control_overr + { + int tempSlope = 0; + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; ++ int f[3], t[3]; + + REG_RMW(ah, AR_PHY_TPC_11_B0, + (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), +@@ -1665,7 +4101,16 @@ static int ar9003_hw_power_control_overr + */ + if (frequency < 4000) + tempSlope = eep->modalHeader2G.tempSlope; +- else ++ else if (eep->base_ext2.tempSlopeLow != 0) { ++ t[0] = eep->base_ext2.tempSlopeLow; ++ f[0] = 5180; ++ t[1] = eep->modalHeader5G.tempSlope; ++ f[1] = 5500; ++ t[2] = eep->base_ext2.tempSlopeHigh; ++ f[2] = 5785; ++ tempSlope = ar9003_hw_power_interpolate((s32) frequency, ++ f, t, 3); ++ } else + tempSlope = eep->modalHeader5G.tempSlope; + + REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope); +@@ -1769,25 +4214,23 @@ static int ar9003_hw_calibration_apply(s + /* so is the high frequency, interpolate */ + if (hfrequency[ichain] - frequency < 1000) { + +- correction[ichain] = lcorrection[ichain] + +- (((frequency - lfrequency[ichain]) * +- (hcorrection[ichain] - +- lcorrection[ichain])) / +- (hfrequency[ichain] - lfrequency[ichain])); +- +- temperature[ichain] = ltemperature[ichain] + +- (((frequency - lfrequency[ichain]) * +- (htemperature[ichain] - +- ltemperature[ichain])) / +- (hfrequency[ichain] - lfrequency[ichain])); +- +- voltage[ichain] = +- lvoltage[ichain] + +- (((frequency - +- lfrequency[ichain]) * (hvoltage[ichain] - +- lvoltage[ichain])) +- / (hfrequency[ichain] - +- lfrequency[ichain])); ++ correction[ichain] = interpolate(frequency, ++ lfrequency[ichain], ++ hfrequency[ichain], ++ lcorrection[ichain], ++ hcorrection[ichain]); ++ ++ temperature[ichain] = interpolate(frequency, ++ lfrequency[ichain], ++ hfrequency[ichain], ++ ltemperature[ichain], ++ htemperature[ichain]); ++ ++ voltage[ichain] = interpolate(frequency, ++ lfrequency[ichain], ++ hfrequency[ichain], ++ lvoltage[ichain], ++ hvoltage[ichain]); + } + /* only low is good, use it */ + else { +--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h ++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +@@ -236,7 +236,7 @@ struct ar9300_modal_eep_header { + u8 thresh62; + __le32 papdRateMaskHt20; + __le32 papdRateMaskHt40; +- u8 futureModal[24]; ++ u8 futureModal[10]; + } __packed; + + struct ar9300_cal_data_per_freq_op_loop { +@@ -274,6 +274,20 @@ struct cal_ctl_data_5g { + struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G]; + } __packed; + ++struct ar9300_BaseExtension_1 { ++ u8 ant_div_control; ++ u8 future[13]; ++} __packed; ++ ++struct ar9300_BaseExtension_2 { ++ int8_t tempSlopeLow; ++ int8_t tempSlopeHigh; ++ u8 xatten1DBLow[AR9300_MAX_CHAINS]; ++ u8 xatten1MarginLow[AR9300_MAX_CHAINS]; ++ u8 xatten1DBHigh[AR9300_MAX_CHAINS]; ++ u8 xatten1MarginHigh[AR9300_MAX_CHAINS]; ++} __packed; ++ + struct ar9300_eeprom { + u8 eepromVersion; + u8 templateVersion; +@@ -283,6 +297,7 @@ struct ar9300_eeprom { + struct ar9300_base_eep_hdr baseEepHeader; + + struct ar9300_modal_eep_header modalHeader2G; ++ struct ar9300_BaseExtension_1 base_ext1; + u8 calFreqPier2G[AR9300_NUM_2G_CAL_PIERS]; + struct ar9300_cal_data_per_freq_op_loop + calPierData2G[AR9300_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS]; +@@ -302,6 +317,7 @@ struct ar9300_eeprom { + u8 ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G]; + struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G]; + struct ar9300_modal_eep_header modalHeader5G; ++ struct ar9300_BaseExtension_2 base_ext2; + u8 calFreqPier5G[AR9300_NUM_5G_CAL_PIERS]; + struct ar9300_cal_data_per_freq_op_loop + calPierData5G[AR9300_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS]; +--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c +@@ -410,12 +410,36 @@ static void ar9003_hw_set11n_ratescenari + static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, + u32 aggrLen) + { ++#define FIRST_DESC_NDELIMS 60 + struct ar9003_txc *ads = (struct ar9003_txc *) ds; + + ads->ctl12 |= (AR_IsAggr | AR_MoreAggr); + +- ads->ctl17 &= ~AR_AggrLen; +- ads->ctl17 |= SM(aggrLen, AR_AggrLen); ++ if (ah->ent_mode & AR_ENT_OTP_MPSD) { ++ u32 ctl17, ndelim; ++ /* ++ * Add delimiter when using RTS/CTS with aggregation ++ * and non enterprise AR9003 card ++ */ ++ ctl17 = ads->ctl17; ++ ndelim = MS(ctl17, AR_PadDelim); ++ ++ if (ndelim < FIRST_DESC_NDELIMS) { ++ aggrLen += (FIRST_DESC_NDELIMS - ndelim) * 4; ++ ndelim = FIRST_DESC_NDELIMS; + } + -+ PA_in[i] = (PA_in[i] < 1400) ? PA_in[i] : 1400; -+ } -+ -+ beta_raw = 0; -+ alpha_raw = 0; -+ -+ for (i = 0; i <= L; i++) { -+ int theta_tilde = -+ ((theta[i + I] << M) + y_est[i + I]) / y_est[i + I]; -+ theta_tilde = -+ ((theta_tilde << M) + y_est[i + I]) / y_est[i + I]; -+ theta_tilde = -+ ((theta_tilde << M) + y_est[i + I]) / y_est[i + I]; -+ beta_raw = beta_raw + B1_tmp[i] * theta_tilde; -+ alpha_raw = alpha_raw + B2_tmp[i] * theta_tilde; -+ } ++ ctl17 &= ~AR_AggrLen; ++ ctl17 |= SM(aggrLen, AR_AggrLen); + -+ Q_beta = find_proper_scale(find_expn(abs(beta_raw)), 10); -+ Q_alpha = find_proper_scale(find_expn(abs(alpha_raw)), 10); -+ beta_raw = beta_raw / (1 << Q_beta); -+ alpha_raw = alpha_raw / (1 << Q_alpha); -+ -+ alpha = (alpha_raw << 10) / scale_B; -+ beta = (beta_raw << 10) / scale_B; -+ order_1 = 3 * M - Q_x - Q_B1 - Q_beta + 10 + Q_scale_B + 5; -+ order_2 = 3 * M - Q_x - Q_B2 - Q_alpha + 10 + Q_scale_B + 5; -+ order1_5x = order_1 / 5; -+ order2_3x = order_2 / 3; -+ order1_5x_rem = order_1 - 5 * order1_5x; -+ order2_3x_rem = order_2 - 3 * order2_3x; -+ -+ for (i = 0; i < PAPRD_TABLE_SZ; i++) { -+ int PA_angle; -+ -+ /* pa_table[4] is calculated from PA_angle for i=5 */ -+ if (i == 4) -+ continue; -+ -+ tmp = i * 32; -+ if (beta > 0) -+ y5 = (((beta * tmp - 64) >> 6) - -+ (1 << order1_5x)) / (1 << order1_5x); -+ else -+ y5 = ((((beta * tmp - 64) >> 6) + -+ (1 << order1_5x)) / (1 << order1_5x)); -+ -+ y5 = (y5 * tmp) / (1 << order1_5x); -+ y5 = (y5 * tmp) / (1 << order1_5x); -+ y5 = (y5 * tmp) / (1 << order1_5x); -+ y5 = (y5 * tmp) / (1 << order1_5x); -+ y5 = y5 / (1 << order1_5x_rem); -+ -+ if (beta > 0) -+ y3 = (alpha * tmp - -+ (1 << order2_3x)) / (1 << order2_3x); -+ else -+ y3 = (alpha * tmp + -+ (1 << order2_3x)) / (1 << order2_3x); -+ y3 = (y3 * tmp) / (1 << order2_3x); -+ y3 = (y3 * tmp) / (1 << order2_3x); -+ y3 = y3 / (1 << order2_3x_rem); -+ -+ if (i < 4) { -+ PA_angle = 0; -+ } else { -+ PA_angle = y5 + y3; -+ if (PA_angle < -150) -+ PA_angle = -150; -+ else if (PA_angle > 150) -+ PA_angle = 150; -+ } ++ ctl17 &= ~AR_PadDelim; ++ ctl17 |= SM(ndelim, AR_PadDelim); + -+ pa_table[i] = ((PA_in[i] & 0x7ff) << 11) + (PA_angle & 0x7ff); -+ if (i == 5) { -+ PA_angle = (PA_angle + 2) >> 1; -+ pa_table[i - 1] = ((PA_in[i - 1] & 0x7ff) << 11) + -+ (PA_angle & 0x7ff); -+ } ++ ads->ctl17 = ctl17; ++ } else { ++ ads->ctl17 &= ~AR_AggrLen; ++ ads->ctl17 |= SM(aggrLen, AR_AggrLen); + } -+ -+ *gain = G_fxp; -+ return true; -+} -+ -+void ar9003_paprd_populate_single_table(struct ath_hw *ah, -+ struct ath9k_channel *chan, int chain) + } + + static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c +@@ -1113,6 +1113,37 @@ static void ar9003_hw_ani_cache_ini_regs + aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; + } + ++static void ar9003_hw_set_radar_params(struct ath_hw *ah, ++ struct ath_hw_radar_conf *conf) +{ -+ u32 *paprd_table_val = chan->pa_table[chain]; -+ u32 small_signal_gain = chan->small_signal_gain[chain]; -+ u32 training_power; -+ u32 reg = 0; -+ int i; ++ u32 radar_0 = 0, radar_1 = 0; + -+ training_power = -+ REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, -+ AR_PHY_POWERTX_RATE5_POWERTXHT20_0); -+ training_power -= 4; -+ -+ if (chain == 0) -+ reg = AR_PHY_PAPRD_MEM_TAB_B0; -+ else if (chain == 1) -+ reg = AR_PHY_PAPRD_MEM_TAB_B1; -+ else if (chain == 2) -+ reg = AR_PHY_PAPRD_MEM_TAB_B2; -+ -+ for (i = 0; i < PAPRD_TABLE_SZ; i++) { -+ REG_WRITE(ah, reg, paprd_table_val[i]); -+ reg = reg + 4; ++ if (!conf) { ++ REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA); ++ return; + } + -+ if (chain == 0) -+ reg = AR_PHY_PA_GAIN123_B0; -+ else if (chain == 1) -+ reg = AR_PHY_PA_GAIN123_B1; ++ radar_0 |= AR_PHY_RADAR_0_ENA | AR_PHY_RADAR_0_FFT_ENA; ++ radar_0 |= SM(conf->fir_power, AR_PHY_RADAR_0_FIRPWR); ++ radar_0 |= SM(conf->radar_rssi, AR_PHY_RADAR_0_RRSSI); ++ radar_0 |= SM(conf->pulse_height, AR_PHY_RADAR_0_HEIGHT); ++ radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI); ++ radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND); ++ ++ radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI; ++ radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK; ++ radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN); ++ radar_1 |= SM(conf->pulse_inband_step, AR_PHY_RADAR_1_RELSTEP_THRESH); ++ radar_1 |= SM(conf->radar_inband, AR_PHY_RADAR_1_RELPWR_THRESH); ++ ++ REG_WRITE(ah, AR_PHY_RADAR_0, radar_0); ++ REG_WRITE(ah, AR_PHY_RADAR_1, radar_1); ++ if (conf->ext_channel) ++ REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); + else -+ reg = AR_PHY_PA_GAIN123_B2; -+ -+ REG_RMW_FIELD(ah, reg, AR_PHY_PA_GAIN123_PA_GAIN1, small_signal_gain); -+ -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B0, -+ AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, -+ training_power); -+ -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B1, -+ AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, -+ training_power); -+ -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2, -+ AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, -+ training_power); ++ REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); +} -+EXPORT_SYMBOL(ar9003_paprd_populate_single_table); + -+int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) -+{ -+ -+ unsigned int i, desired_gain, gain_index; -+ unsigned int train_power; -+ -+ train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, -+ AR_PHY_POWERTX_RATE5_POWERTXHT20_0); -+ -+ train_power = train_power - 4; -+ -+ desired_gain = ar9003_get_desired_gain(ah, chain, train_power); -+ -+ gain_index = 0; -+ for (i = 0; i < 32; i++) { -+ if (ah->paprd_gain_table_index[i] >= desired_gain) -+ break; -+ gain_index++; -+ } -+ -+ ar9003_tx_force_gain(ah, gain_index); -+ -+ REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, -+ AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); -+ -+ return 0; -+} -+EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); -+ -+int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan, -+ int chain) -+{ -+ u16 *small_signal_gain = &chan->small_signal_gain[chain]; -+ u32 *pa_table = chan->pa_table[chain]; -+ u32 *data_L, *data_U; -+ int i, status = 0; -+ u32 *buf; -+ u32 reg; -+ -+ memset(chan->pa_table[chain], 0, sizeof(chan->pa_table[chain])); -+ -+ buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC); -+ if (!buf) -+ return -ENOMEM; -+ -+ data_L = &buf[0]; -+ data_U = &buf[48]; -+ -+ REG_CLR_BIT(ah, AR_PHY_CHAN_INFO_MEMORY, -+ AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ); -+ -+ reg = AR_PHY_CHAN_INFO_TAB_0; -+ for (i = 0; i < 48; i++) -+ data_L[i] = REG_READ(ah, reg + (i << 2)); -+ -+ REG_SET_BIT(ah, AR_PHY_CHAN_INFO_MEMORY, -+ AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ); -+ -+ for (i = 0; i < 48; i++) -+ data_U[i] = REG_READ(ah, reg + (i << 2)); -+ -+ if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) -+ status = -2; -+ -+ REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, -+ AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); -+ -+ kfree(buf); -+ -+ return status; -+} -+EXPORT_SYMBOL(ar9003_paprd_create_curve); -+ -+int ar9003_paprd_init_table(struct ath_hw *ah) -+{ -+ ar9003_paprd_setup_single_table(ah); -+ ar9003_paprd_get_gain_table(ah); -+ return 0; -+} -+EXPORT_SYMBOL(ar9003_paprd_init_table); -+ -+bool ar9003_paprd_is_done(struct ath_hw *ah) -+{ -+ return !!REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, -+ AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); -+} -+EXPORT_SYMBOL(ar9003_paprd_is_done); ---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h -+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h -@@ -451,7 +451,11 @@ - #define AR_PHY_TSTDAC (AR_SM_BASE + 0x168) - - #define AR_PHY_CHAN_STATUS (AR_SM_BASE + 0x16c) --#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170) -+ -+#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170) -+#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ 0x00000008 -+#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ_S 3 -+ - #define AR_PHY_CHNINFO_NOISEPWR (AR_SM_BASE + 0x174) - #define AR_PHY_CHNINFO_GAINDIFF (AR_SM_BASE + 0x178) - #define AR_PHY_CHNINFO_FINETIM (AR_SM_BASE + 0x17c) -@@ -467,17 +471,63 @@ - #define AR_PHY_PWRTX_MAX (AR_SM_BASE + 0x1f0) - #define AR_PHY_POWER_TX_SUB (AR_SM_BASE + 0x1f4) - --#define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204) --#define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208) --#define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c) --#define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220) --#define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c) --#define AR_PHY_TPC_19 (AR_SM_BASE + 0x240) -+#define AR_PHY_TPC_1 (AR_SM_BASE + 0x1f8) -+#define AR_PHY_TPC_1_FORCED_DAC_GAIN 0x0000003e -+#define AR_PHY_TPC_1_FORCED_DAC_GAIN_S 1 -+#define AR_PHY_TPC_1_FORCE_DAC_GAIN 0x00000001 -+#define AR_PHY_TPC_1_FORCE_DAC_GAIN_S 0 -+ -+#define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204) -+#define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208) -+#define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c) -+ -+#define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220) -+#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) -+#define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220) -+#define AR_PHY_TPC_11_OLPC_GAIN_DELTA 0x00ff0000 -+#define AR_PHY_TPC_11_OLPC_GAIN_DELTA_S 16 -+ -+#define AR_PHY_TPC_12 (AR_SM_BASE + 0x224) -+#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5 0x3e000000 -+#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5_S 25 -+ -+#define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c) -+#define AR_PHY_TPC_18_THERM_CAL_VALUE 0x000000ff -+#define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0 -+#define AR_PHY_TPC_18_VOLT_CAL_VALUE 0x0000ff00 -+#define AR_PHY_TPC_18_VOLT_CAL_VALUE_S 8 -+ -+#define AR_PHY_TPC_19 (AR_SM_BASE + 0x240) -+#define AR_PHY_TPC_19_ALPHA_VOLT 0x001f0000 -+#define AR_PHY_TPC_19_ALPHA_VOLT_S 16 -+#define AR_PHY_TPC_19_ALPHA_THERM 0xff -+#define AR_PHY_TPC_19_ALPHA_THERM_S 0 -+ -+#define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258) -+#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN 0x00000001 -+#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN_S 0 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN 0x0000000e -+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_S 1 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN 0x00000030 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_S 4 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN 0x000003c0 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN_S 6 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA 0x00003c00 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA_S 10 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB 0x0003c000 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB_S 14 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC 0x003c0000 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC_S 18 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND 0x00c00000 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND_S 22 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL 0x01000000 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL_S 24 - --#define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258) - - #define AR_PHY_PDADC_TAB_0 (AR_SM_BASE + 0x280) - -+#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) -+ - #define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448) - #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440) - #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c) -@@ -490,7 +540,17 @@ - #define AR_PHY_ONLY_WARMRESET (AR_SM_BASE + 0x5d0) - #define AR_PHY_ONLY_CTL (AR_SM_BASE + 0x5d4) - #define AR_PHY_ECO_CTRL (AR_SM_BASE + 0x5dc) --#define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248) -+ -+#define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248) -+#define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff -+#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0 -+ -+#define AR_PHY_BB_THERM_ADC_4 (AR_SM_BASE + 0x254) -+#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE 0x000000ff -+#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_S 0 -+#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE 0x0000ff00 -+#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_S 8 -+ - - #define AR_PHY_65NM_CH0_SYNTH4 0x1608c - #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002 -@@ -660,17 +720,9 @@ - #define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x00003fff - #define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0 - --#define AR_PHY_TPC_18_THERM_CAL_VALUE 0xff --#define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0 --#define AR_PHY_TPC_19_ALPHA_THERM 0xff --#define AR_PHY_TPC_19_ALPHA_THERM_S 0 -- - #define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000 - #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28 - --#define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff --#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0 -- - /* - * Channel 1 Register Map - */ -@@ -842,6 +894,144 @@ - - #define AR_PHY_WATCHDOG_STATUS_CLR 0x00000008 - -+/* -+ * PAPRD registers -+ */ -+#define AR_PHY_XPA_TIMING_CTL (AR_SM_BASE + 0x64) -+ -+#define AR_PHY_PAPRD_AM2AM (AR_CHAN_BASE + 0xe4) -+#define AR_PHY_PAPRD_AM2AM_MASK 0x01ffffff -+#define AR_PHY_PAPRD_AM2AM_MASK_S 0 -+ -+#define AR_PHY_PAPRD_AM2PM (AR_CHAN_BASE + 0xe8) -+#define AR_PHY_PAPRD_AM2PM_MASK 0x01ffffff -+#define AR_PHY_PAPRD_AM2PM_MASK_S 0 -+ -+#define AR_PHY_PAPRD_HT40 (AR_CHAN_BASE + 0xec) -+#define AR_PHY_PAPRD_HT40_MASK 0x01ffffff -+#define AR_PHY_PAPRD_HT40_MASK_S 0 -+ -+#define AR_PHY_PAPRD_CTRL0_B0 (AR_CHAN_BASE + 0xf0) -+#define AR_PHY_PAPRD_CTRL0_B1 (AR_CHAN1_BASE + 0xf0) -+#define AR_PHY_PAPRD_CTRL0_B2 (AR_CHAN2_BASE + 0xf0) -+#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE 0x00000001 -+#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE_S 0 -+#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK 0x00000002 -+#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK_S 1 -+#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH 0xf8000000 -+#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH_S 27 -+ -+#define AR_PHY_PAPRD_CTRL1_B0 (AR_CHAN_BASE + 0xf4) -+#define AR_PHY_PAPRD_CTRL1_B1 (AR_CHAN1_BASE + 0xf4) -+#define AR_PHY_PAPRD_CTRL1_B2 (AR_CHAN2_BASE + 0xf4) -+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA 0x00000001 -+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA_S 0 -+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE 0x00000002 -+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE_S 1 -+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE 0x00000004 -+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE_S 2 -+#define AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL 0x000001f8 -+#define AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_S 3 -+#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK 0x0001fe00 -+#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK_S 9 -+#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT 0x0ffe0000 -+#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT_S 17 -+ -+#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + 0x490) -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE 0x00000001 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE_S 0 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING 0x0000007e -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_S 1 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE 0x00000100 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_S 8 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE 0x00000200 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_S 9 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE 0x00000400 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_S 10 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE 0x00000800 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_S 11 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP 0x0003f000 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_S 12 -+ -+#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + 0x494) -+#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN 0xFFFFFFFF -+#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_S 0 -+ -+#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + 0x498) -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE 0x0000003f -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_S 0 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP 0x00000fc0 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_S 6 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL 0x0001f000 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_S 12 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES 0x000e0000 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_S 17 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN 0x00f00000 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_S 20 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN 0x0f000000 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_S 24 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE 0x20000000 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_S 29 -+ -+#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + 0x49c) -+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES 0x03ff0000 -+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_S 16 -+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA 0x0000f000 -+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_S 12 -+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR 0x00000fff -+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_S 0 -+ -+#define AR_PHY_PAPRD_PRE_POST_SCALE_0_B0 (AR_CHAN_BASE + 0x100) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_1_B0 (AR_CHAN_BASE + 0x104) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_2_B0 (AR_CHAN_BASE + 0x108) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_3_B0 (AR_CHAN_BASE + 0x10c) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_4_B0 (AR_CHAN_BASE + 0x110) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_5_B0 (AR_CHAN_BASE + 0x114) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_6_B0 (AR_CHAN_BASE + 0x118) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_7_B0 (AR_CHAN_BASE + 0x11c) -+#define AR_PHY_PAPRD_PRE_POST_SCALING 0x3FFFF -+#define AR_PHY_PAPRD_PRE_POST_SCALING_S 0 -+ -+#define AR_PHY_PAPRD_TRAINER_STAT1 (AR_SM_BASE + 0x4a0) -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE 0x00000001 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_S 0 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE 0x00000002 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_S 1 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR 0x00000004 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_S 2 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE 0x00000008 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_S 3 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX 0x000001f0 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_S 4 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR 0x0001fe00 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_S 9 -+ -+#define AR_PHY_PAPRD_TRAINER_STAT2 (AR_SM_BASE + 0x4a4) -+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL 0x0000ffff -+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_S 0 -+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX 0x001f0000 -+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_S 16 -+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX 0x00600000 -+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_S 21 -+ -+#define AR_PHY_PAPRD_TRAINER_STAT3 (AR_SM_BASE + 0x4a8) -+#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT 0x000fffff -+#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_S 0 -+ -+#define AR_PHY_PAPRD_MEM_TAB_B0 (AR_CHAN_BASE + 0x120) -+#define AR_PHY_PAPRD_MEM_TAB_B1 (AR_CHAN1_BASE + 0x120) -+#define AR_PHY_PAPRD_MEM_TAB_B2 (AR_CHAN2_BASE + 0x120) -+ -+#define AR_PHY_PA_GAIN123_B0 (AR_CHAN_BASE + 0xf8) -+#define AR_PHY_PA_GAIN123_B1 (AR_CHAN1_BASE + 0xf8) -+#define AR_PHY_PA_GAIN123_B2 (AR_CHAN2_BASE + 0xf8) -+#define AR_PHY_PA_GAIN123_PA_GAIN1 0x3FF -+#define AR_PHY_PA_GAIN123_PA_GAIN1_S 0 -+ -+#define AR_PHY_POWERTX_RATE5 (AR_SM_BASE + 0x1d0) -+#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0 0x3F -+#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S 0 -+ - void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); - - #endif /* AR9003_PHY_H */ + void ar9003_hw_attach_phy_ops(struct ath_hw *ah) + { + struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); +@@ -1141,6 +1172,7 @@ void ar9003_hw_attach_phy_ops(struct ath + priv_ops->ani_control = ar9003_hw_ani_control; + priv_ops->do_getnf = ar9003_hw_do_getnf; + priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; ++ priv_ops->set_radar_params = ar9003_hw_set_radar_params; + + ar9003_hw_set_nf_limits(ah); + memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs)); --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - #include "debug.h" - #include "common.h" -@@ -194,6 +195,7 @@ enum ATH_AGGR_STATUS { - - #define ATH_TXFIFO_DEPTH 8 - struct ath_txq { -+ int axq_class; - u32 axq_qnum; - u32 *axq_link; - struct list_head axq_q; -@@ -206,7 +208,6 @@ struct ath_txq { - struct list_head txq_fifo_pending; - u8 txq_headidx; - u8 txq_tailidx; -- int pending_frames; - }; - - struct ath_atx_ac { -@@ -224,6 +225,7 @@ struct ath_buf_state { - int bfs_tidno; - int bfs_retries; - u8 bf_type; -+ u8 bfs_paprd; +@@ -177,8 +177,8 @@ void ath_descdma_cleanup(struct ath_soft + + /* returns delimiter padding required given the packet length */ + #define ATH_AGGR_GET_NDELIM(_len) \ +- (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \ +- (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2) ++ (((_len) >= ATH_AGGR_MINPLEN) ? 0 : \ ++ DIV_ROUND_UP(ATH_AGGR_MINPLEN - (_len), ATH_AGGR_DELIM_SZ)) + + #define BAW_WITHIN(_start, _bawsz, _seqno) \ + ((((_seqno) - (_start)) & 4095) < (_bawsz)) +@@ -229,6 +229,7 @@ struct ath_buf_state { + unsigned long bfs_paprd_timestamp; u32 bfs_keyix; enum ath9k_key_type bfs_keytype; - }; -@@ -244,7 +246,6 @@ struct ath_buf { - struct ath_buf_state bf_state; - dma_addr_t bf_dmacontext; - struct ath_wiphy *aphy; -- struct ath_txq *txq; - }; - - struct ath_atx_tid { -@@ -281,6 +282,7 @@ struct ath_tx_control { - struct ath_txq *txq; - int if_id; - enum ath9k_internal_frame_type frame_type; -+ u8 paprd; - }; - - #define ATH_TX_ERROR 0x01 -@@ -290,11 +292,12 @@ struct ath_tx_control { - struct ath_tx { - u16 seq_no; - u32 txqsetup; -- int hwq_map[ATH9K_WME_AC_VO+1]; -+ int hwq_map[WME_NUM_AC]; - spinlock_t txbuflock; - struct list_head txbuf; - struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; - struct ath_descdma txdma; -+ int pending_frames[WME_NUM_AC]; ++ enum ath9k_internal_frame_type bfs_ftype; }; - struct ath_rx_edma { -@@ -421,6 +424,7 @@ int ath_beaconq_config(struct ath_softc - #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ - #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ - -+void ath_paprd_calibrate(struct work_struct *work); - void ath_ani_calibrate(unsigned long data); - - /**********/ -@@ -553,6 +557,9 @@ struct ath_softc { - spinlock_t sc_serial_rw; - spinlock_t sc_pm_lock; - struct mutex mutex; -+ struct work_struct paprd_work; -+ struct completion paprd_complete; -+ int paprd_txok; - - u32 intrstatus; - u32 sc_flags; /* SC_OP_* */ -@@ -613,7 +620,6 @@ struct ath_wiphy { - - void ath9k_tasklet(unsigned long data); - int ath_reset(struct ath_softc *sc, bool retry_tx); --int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); - int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); - int ath_cabq_update(struct ath_softc *); - -@@ -629,8 +635,6 @@ irqreturn_t ath_isr(int irq, void *dev); - int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, - const struct ath_bus_ops *bus_ops); - void ath9k_deinit_device(struct ath_softc *sc); --const char *ath_mac_bb_name(u32 mac_bb_version); --const char *ath_rf_name(u16 rf_version); - void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); - void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, - struct ath9k_channel *ichan); -@@ -681,8 +685,6 @@ void ath9k_set_wiphy_idle(struct ath_wip - void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue); - void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); - --int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); -- - void ath_start_rfkill_poll(struct ath_softc *sc); - extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); - ---- a/drivers/net/wireless/ath/ath9k/eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/eeprom.h -@@ -263,7 +263,8 @@ enum eeprom_param { - EEP_PWR_TABLE_OFFSET, - EEP_DRIVE_STRENGTH, - EEP_INTERNAL_REGULATOR, -- EEP_SWREG -+ EEP_SWREG, -+ EEP_PAPRD, - }; - - enum ar5416_rates { + struct ath_buf { +@@ -712,7 +713,7 @@ void ath9k_ps_restore(struct ath_softc * + void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif); + int ath9k_wiphy_add(struct ath_softc *sc); + int ath9k_wiphy_del(struct ath_wiphy *aphy); +-void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb); ++void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype); + int ath9k_wiphy_pause(struct ath_wiphy *aphy); + int ath9k_wiphy_unpause(struct ath_wiphy *aphy); + int ath9k_wiphy_select(struct ath_wiphy *aphy); --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -2246,6 +2246,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw - pCap->rx_status_len = sizeof(struct ar9003_rxs); - pCap->tx_desc_len = sizeof(struct ar9003_txc); - pCap->txs_len = sizeof(struct ar9003_txs); -+ if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) -+ pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; - } else { - pCap->tx_desc_len = sizeof(struct ath_desc); - if (AR_SREV_9280_20(ah) && +@@ -1991,6 +1991,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw + if (AR_SREV_9300_20_OR_LATER(ah)) + pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED; + ++ if (AR_SREV_9300_20_OR_LATER(ah)) ++ ah->ent_mode = REG_READ(ah, AR_ENT_OTP); ++ + if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah)) + pCap->hw_caps |= ATH9K_HW_CAP_SGI_20; + --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h -@@ -158,6 +158,9 @@ - #define ATH9K_HW_RX_HP_QDEPTH 16 - #define ATH9K_HW_RX_LP_QDEPTH 128 - -+#define PAPRD_GAIN_TABLE_ENTRIES 32 -+#define PAPRD_TABLE_SZ 24 -+ - enum ath_ini_subsys { - ATH_INI_PRE = 0, - ATH_INI_CORE, -@@ -200,6 +203,7 @@ enum ath9k_hw_caps { - ATH9K_HW_CAP_LDPC = BIT(19), - ATH9K_HW_CAP_FASTCLOCK = BIT(20), - ATH9K_HW_CAP_SGI_20 = BIT(21), -+ ATH9K_HW_CAP_PAPRD = BIT(22), - }; - - enum ath9k_capability_type { -@@ -359,6 +363,9 @@ struct ath9k_channel { - int8_t iCoff; - int8_t qCoff; - int16_t rawNoiseFloor; -+ bool paprd_done; -+ u16 small_signal_gain[AR9300_MAX_CHAINS]; -+ u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; +@@ -485,6 +485,40 @@ struct ath_hw_antcomb_conf { }; - #define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ -@@ -793,6 +800,9 @@ struct ath_hw { - - u32 bb_watchdog_last_status; - u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */ -+ -+ u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; -+ u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; + /** ++ * struct ath_hw_radar_conf - radar detection initialization parameters ++ * ++ * @pulse_inband: threshold for checking the ratio of in-band power ++ * to total power for short radar pulses (half dB steps) ++ * @pulse_inband_step: threshold for checking an in-band power to total ++ * power ratio increase for short radar pulses (half dB steps) ++ * @pulse_height: threshold for detecting the beginning of a short ++ * radar pulse (dB step) ++ * @pulse_rssi: threshold for detecting if a short radar pulse is ++ * gone (dB step) ++ * @pulse_maxlen: maximum pulse length (0.8 us steps) ++ * ++ * @radar_rssi: RSSI threshold for starting long radar detection (dB steps) ++ * @radar_inband: threshold for checking the ratio of in-band power ++ * to total power for long radar pulses (half dB steps) ++ * @fir_power: threshold for detecting the end of a long radar pulse (dB) ++ * ++ * @ext_channel: enable extension channel radar detection ++ */ ++struct ath_hw_radar_conf { ++ unsigned int pulse_inband; ++ unsigned int pulse_inband_step; ++ unsigned int pulse_height; ++ unsigned int pulse_rssi; ++ unsigned int pulse_maxlen; ++ ++ unsigned int radar_rssi; ++ unsigned int radar_inband; ++ int fir_power; ++ ++ bool ext_channel; ++}; ++ ++/** + * struct ath_hw_private_ops - callbacks used internally by hardware code + * + * This structure contains private callbacks designed to only be used internally +@@ -549,6 +583,8 @@ struct ath_hw_private_ops { + bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd, + int param); + void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]); ++ void (*set_radar_params)(struct ath_hw *ah, ++ struct ath_hw_radar_conf *conf); + + /* ANI */ + void (*ani_cache_ini_regs)(struct ath_hw *ah); +@@ -806,6 +842,9 @@ struct ath_hw { + * this register when in sleep states. + */ + u32 WARegVal; ++ ++ /* Enterprise mode cap */ ++ u32 ent_mode; }; static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) -@@ -922,6 +932,15 @@ void ar9003_hw_set_nf_limits(struct ath_ - void ar9003_hw_bb_watchdog_config(struct ath_hw *ah); - void ar9003_hw_bb_watchdog_read(struct ath_hw *ah); - void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah); -+void ar9003_paprd_enable(struct ath_hw *ah, bool val); -+void ar9003_paprd_populate_single_table(struct ath_hw *ah, -+ struct ath9k_channel *chan, int chain); -+int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan, -+ int chain); -+int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); -+int ar9003_paprd_init_table(struct ath_hw *ah); -+bool ar9003_paprd_is_done(struct ath_hw *ah); -+void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains); - - /* Hardware family op attach helpers */ - void ar5008_hw_attach_phy_ops(struct ath_hw *ah); ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -427,7 +427,7 @@ static int ath9k_init_btcoex(struct ath_ - r = ath_init_btcoex_timer(sc); - if (r) - return -1; -- qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); -+ qnum = sc->tx.hwq_map[WME_AC_BE]; - ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum); - sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; - break; -@@ -464,23 +464,23 @@ static int ath9k_init_queues(struct ath_ - sc->config.cabqReadytime = ATH_CABQ_READY_TIME; - ath_cabq_update(sc); - -- if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { -+ if (!ath_tx_setup(sc, WME_AC_BK)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for BK traffic\n"); - goto err; +--- a/drivers/net/wireless/ath/ath9k/rc.c ++++ b/drivers/net/wireless/ath/ath9k/rc.c +@@ -1354,23 +1354,7 @@ static void ath_tx_status(void *priv, st + tx_info->status.ampdu_len = 1; } -- if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { -+ if (!ath_tx_setup(sc, WME_AC_BE)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for BE traffic\n"); - goto err; - } -- if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { -+ if (!ath_tx_setup(sc, WME_AC_VI)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for VI traffic\n"); - goto err; - } -- if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { -+ if (!ath_tx_setup(sc, WME_AC_VO)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for VO traffic\n"); - goto err; -@@ -769,6 +769,7 @@ int ath9k_init_device(u16 devid, struct - goto error_world; - } +- /* +- * If an underrun error is seen assume it as an excessive retry only +- * if max frame trigger level has been reached (2 KB for singel stream, +- * and 4 KB for dual stream). Adjust the long retry as if the frame was +- * tried hw->max_rate_tries times to affect how ratectrl updates PER for +- * the failed rate. In case of congestion on the bus penalizing these +- * type of underruns should help hardware actually transmit new frames +- * successfully by eventually preferring slower rates. This itself +- * should also alleviate congestion on the bus. +- */ +- if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) && +- (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) { +- tx_status = 1; +- is_underrun = 1; +- } +- +- if (tx_info->pad[0] & ATH_TX_INFO_XRETRY) ++ if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) + tx_status = 1; -+ INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); - INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); - INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); - sc->wiphy_scheduler_int = msecs_to_jiffies(500); ---- a/drivers/net/wireless/ath/ath9k/main.c -+++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -233,6 +233,104 @@ int ath_set_channel(struct ath_softc *sc - return r; - } + ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, +@@ -1596,8 +1580,6 @@ static void *ath_rate_alloc_sta(void *pr + return NULL; + } -+static void ath_paprd_activate(struct ath_softc *sc) -+{ -+ struct ath_hw *ah = sc->sc_ah; -+ int chain; -+ -+ if (!ah->curchan->paprd_done) -+ return; -+ -+ ath9k_ps_wakeup(sc); -+ for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { -+ if (!(ah->caps.tx_chainmask & BIT(chain))) -+ continue; -+ -+ ar9003_paprd_populate_single_table(ah, ah->curchan, chain); -+ } -+ -+ ar9003_paprd_enable(ah, true); -+ ath9k_ps_restore(sc); -+} -+ -+void ath_paprd_calibrate(struct work_struct *work) -+{ -+ struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); -+ struct ieee80211_hw *hw = sc->hw; -+ struct ath_hw *ah = sc->sc_ah; -+ struct ieee80211_hdr *hdr; -+ struct sk_buff *skb = NULL; -+ struct ieee80211_tx_info *tx_info; -+ int band = hw->conf.channel->band; -+ struct ieee80211_supported_band *sband = &sc->sbands[band]; -+ struct ath_tx_control txctl; -+ int qnum, ftype; -+ int chain_ok = 0; -+ int chain; -+ int len = 1800; -+ int i; -+ -+ ath9k_ps_wakeup(sc); -+ skb = alloc_skb(len, GFP_KERNEL); -+ if (!skb) -+ return; -+ -+ tx_info = IEEE80211_SKB_CB(skb); -+ -+ skb_put(skb, len); -+ memset(skb->data, 0, len); -+ hdr = (struct ieee80211_hdr *)skb->data; -+ ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC; -+ hdr->frame_control = cpu_to_le16(ftype); -+ hdr->duration_id = 10; -+ memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); -+ memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); -+ memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); -+ -+ memset(&txctl, 0, sizeof(txctl)); -+ qnum = sc->tx.hwq_map[WME_AC_BE]; -+ txctl.txq = &sc->tx.txq[qnum]; -+ -+ ar9003_paprd_init_table(ah); -+ for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { -+ if (!(ah->caps.tx_chainmask & BIT(chain))) -+ continue; -+ -+ chain_ok = 0; -+ memset(tx_info, 0, sizeof(*tx_info)); -+ tx_info->band = band; -+ -+ for (i = 0; i < 4; i++) { -+ tx_info->control.rates[i].idx = sband->n_bitrates - 1; -+ tx_info->control.rates[i].count = 6; -+ } -+ -+ init_completion(&sc->paprd_complete); -+ ar9003_paprd_setup_gain_table(ah, chain); -+ txctl.paprd = BIT(chain); -+ if (ath_tx_start(hw, skb, &txctl) != 0) -+ break; -+ -+ wait_for_completion(&sc->paprd_complete); -+ -+ if (!ar9003_paprd_is_done(ah)) -+ break; -+ -+ if (ar9003_paprd_create_curve(ah, ah->curchan, chain) != 0) -+ break; -+ -+ chain_ok = 1; -+ } -+ kfree_skb(skb); -+ -+ if (chain_ok) { -+ ah->curchan->paprd_done = true; -+ ath_paprd_activate(sc); -+ } -+ -+ ath9k_ps_restore(sc); -+} -+ - /* - * This routine performs the periodic noise floor calibration function - * that is used to adjust and optimize the chip performance. This -@@ -332,6 +430,13 @@ set_timer: - cal_interval = min(cal_interval, (u32)short_cal_interval); - - mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); -+ if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && -+ !(sc->sc_flags & SC_OP_SCANNING)) { -+ if (!sc->sc_ah->curchan->paprd_done) -+ ieee80211_queue_work(sc->hw, &sc->paprd_work); -+ else -+ ath_paprd_activate(sc); -+ } +- rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max; +- + return rate_priv; } - static void ath_start_ani(struct ath_common *common) -@@ -805,25 +910,25 @@ int ath_reset(struct ath_softc *sc, bool - return r; - } +--- a/drivers/net/wireless/ath/ath9k/rc.h ++++ b/drivers/net/wireless/ath/ath9k/rc.h +@@ -215,7 +215,6 @@ struct ath_rate_priv { + u32 per_down_time; + u32 probe_interval; + u32 prev_data_rix; +- u32 tx_triglevel_max; + struct ath_rateset neg_rates; + struct ath_rateset neg_ht_rates; + struct ath_rate_softc *asc; +@@ -225,11 +224,6 @@ struct ath_rate_priv { + struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; + }; --int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) -+static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) +-#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) +-#define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) +-#define ATH_TX_INFO_XRETRY (1 << 3) +-#define ATH_TX_INFO_UNDERRUN (1 << 4) +- + enum ath9k_internal_frame_type { + ATH9K_IFT_NOT_INTERNAL, + ATH9K_IFT_PAUSE, +--- a/drivers/net/wireless/ath/ath9k/reg.h ++++ b/drivers/net/wireless/ath/ath9k/reg.h +@@ -1066,6 +1066,9 @@ enum { + #define AR_INTR_PRIO_ASYNC_MASK 0x40c8 + #define AR_INTR_PRIO_SYNC_MASK 0x40cc + #define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4 ++#define AR_ENT_OTP 0x40d8 ++#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 ++#define AR_ENT_OTP_MPSD 0x00800000 + + #define AR_RTC_9300_PLL_DIV 0x000003ff + #define AR_RTC_9300_PLL_DIV_S 0 +--- a/drivers/net/wireless/ath/ath9k/virtual.c ++++ b/drivers/net/wireless/ath/ath9k/virtual.c +@@ -305,13 +305,12 @@ void ath9k_wiphy_chan_work(struct work_s + * ath9k version of ieee80211_tx_status() for TX frames that are generated + * internally in the driver. + */ +-void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) ++void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype) { - int qnum; - - switch (queue) { - case 0: -- qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO]; -+ qnum = sc->tx.hwq_map[WME_AC_VO]; - break; - case 1: -- qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI]; -+ qnum = sc->tx.hwq_map[WME_AC_VI]; - break; - case 2: -- qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; -+ qnum = sc->tx.hwq_map[WME_AC_BE]; - break; - case 3: -- qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK]; -+ qnum = sc->tx.hwq_map[WME_AC_BK]; - break; - default: -- qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; -+ qnum = sc->tx.hwq_map[WME_AC_BE]; - break; - } + struct ath_wiphy *aphy = hw->priv; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); -@@ -835,16 +940,16 @@ int ath_get_mac80211_qnum(u32 queue, str - int qnum; - - switch (queue) { -- case ATH9K_WME_AC_VO: -+ case WME_AC_VO: - qnum = 0; - break; -- case ATH9K_WME_AC_VI: -+ case WME_AC_VI: - qnum = 1; - break; -- case ATH9K_WME_AC_BE: -+ case WME_AC_BE: - qnum = 2; - break; -- case ATH9K_WME_AC_BK: -+ case WME_AC_BK: - qnum = 3; - break; - default: -@@ -1128,6 +1233,7 @@ static void ath9k_stop(struct ieee80211_ - - cancel_delayed_work_sync(&sc->ath_led_blink_work); - cancel_delayed_work_sync(&sc->tx_complete_work); -+ cancel_work_sync(&sc->paprd_work); - - if (!sc->num_sec_wiphy) { - cancel_delayed_work_sync(&sc->wiphy_work); -@@ -1556,7 +1662,7 @@ static int ath9k_conf_tx(struct ieee8021 - ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); - - if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) -- if ((qnum == sc->tx.hwq_map[ATH9K_WME_AC_BE]) && !ret) -+ if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret) - ath_beaconq_config(sc); - - mutex_unlock(&sc->mutex); -@@ -1843,6 +1949,7 @@ static void ath9k_sw_scan_start(struct i - ath9k_wiphy_pause_all_forced(sc, aphy); - sc->sc_flags |= SC_OP_SCANNING; - del_timer_sync(&common->ani.timer); -+ cancel_work_sync(&sc->paprd_work); - cancel_delayed_work_sync(&sc->tx_complete_work); - mutex_unlock(&sc->mutex); - } +- if ((tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_PAUSE) && +- aphy->state == ATH_WIPHY_PAUSING) { ++ if (ftype == ATH9K_IFT_PAUSE && aphy->state == ATH_WIPHY_PAUSING) { + if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) { + printk(KERN_DEBUG "ath9k: %s: no ACK for pause " + "frame\n", wiphy_name(hw->wiphy)); --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -941,6 +941,7 @@ struct ath_txq *ath_txq_setup(struct ath - if (!ATH_TXQ_SETUP(sc, qnum)) { - struct ath_txq *txq = &sc->tx.txq[qnum]; - -+ txq->axq_class = subtype; - txq->axq_qnum = qnum; - txq->axq_link = NULL; - INIT_LIST_HEAD(&txq->axq_q); -@@ -958,32 +959,6 @@ struct ath_txq *ath_txq_setup(struct ath - return &sc->tx.txq[qnum]; +@@ -48,9 +48,9 @@ static u16 bits_per_symbol[][2] = { + + #define IS_HT_RATE(_rate) ((_rate) & 0x80) + +-static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq, +- struct ath_atx_tid *tid, +- struct list_head *bf_head); ++static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, ++ struct ath_atx_tid *tid, ++ struct list_head *bf_head); + static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, + struct ath_txq *txq, struct list_head *bf_q, + struct ath_tx_status *ts, int txok, int sendbar); +@@ -160,7 +160,7 @@ static void ath_tx_flush_tid(struct ath_ + ath_tx_update_baw(sc, tid, bf->bf_seqno); + ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); + } else { +- ath_tx_send_ht_normal(sc, txq, tid, &bf_head); ++ ath_tx_send_normal(sc, txq, tid, &bf_head); + } + } + +@@ -1322,9 +1322,9 @@ static void ath_tx_send_ampdu(struct ath + ath_tx_txqaddbuf(sc, txctl->txq, bf_head); + } + +-static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq, +- struct ath_atx_tid *tid, +- struct list_head *bf_head) ++static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, ++ struct ath_atx_tid *tid, ++ struct list_head *bf_head) + { + struct ath_buf *bf; + +@@ -1332,7 +1332,8 @@ static void ath_tx_send_ht_normal(struct + bf->bf_state.bf_type &= ~BUF_AMPDU; + + /* update starting sequence number for subsequent ADDBA request */ +- INCR(tid->seq_start, IEEE80211_SEQ_MAX); ++ if (tid) ++ INCR(tid->seq_start, IEEE80211_SEQ_MAX); + + bf->bf_nframes = 1; + bf->bf_lastbf = bf; +@@ -1341,20 +1342,6 @@ static void ath_tx_send_ht_normal(struct + TX_STAT_INC(txq->axq_qnum, queued); } --int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) +-static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, +- struct list_head *bf_head) -{ -- int qnum; +- struct ath_buf *bf; - -- switch (qtype) { -- case ATH9K_TX_QUEUE_DATA: -- if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) { -- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, -- "HAL AC %u out of range, max %zu!\n", -- haltype, ARRAY_SIZE(sc->tx.hwq_map)); -- return -1; -- } -- qnum = sc->tx.hwq_map[haltype]; -- break; -- case ATH9K_TX_QUEUE_BEACON: -- qnum = sc->beacon.beaconq; -- break; -- case ATH9K_TX_QUEUE_CAB: -- qnum = sc->beacon.cabq->axq_qnum; -- break; -- default: -- qnum = -1; -- } -- return qnum; +- bf = list_first_entry(bf_head, struct ath_buf, list); +- +- bf->bf_lastbf = bf; +- bf->bf_nframes = 1; +- ath_buf_set_rate(sc, bf); +- ath_tx_txqaddbuf(sc, txq, bf_head); +- TX_STAT_INC(txq->axq_qnum, queued); -} - - int ath_txq_update(struct ath_softc *sc, int qnum, - struct ath9k_tx_queue_info *qinfo) + static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) + { + struct ieee80211_hdr *hdr; +@@ -1411,7 +1398,7 @@ static void assign_aggr_tid_seqno(struct + INCR(tid->seq_next, IEEE80211_SEQ_MAX); + } + +-static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc) ++static int setup_tx_flags(struct sk_buff *skb) + { + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + int flags = 0; +@@ -1422,7 +1409,7 @@ static int setup_tx_flags(struct sk_buff + if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) + flags |= ATH9K_TXDESC_NOACK; + +- if (use_ldpc) ++ if (tx_info->flags & IEEE80211_TX_CTL_LDPC) + flags |= ATH9K_TXDESC_LDPC; + + return flags; +@@ -1567,30 +1554,25 @@ static void ath_buf_set_rate(struct ath_ + ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192); + } + +-static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, +- struct sk_buff *skb, +- struct ath_tx_control *txctl) ++static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, ++ struct sk_buff *skb) { -@@ -1662,12 +1637,13 @@ static int ath_tx_setup_buffer(struct ie + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; ++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; ++ struct ath_buf *bf; + int hdrlen; + __le16 fc; + int padpos, padsize; +- bool use_ldpc = false; + +- tx_info->pad[0] = 0; +- switch (txctl->frame_type) { +- case ATH9K_IFT_NOT_INTERNAL: +- break; +- case ATH9K_IFT_PAUSE: +- tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE; +- /* fall through */ +- case ATH9K_IFT_UNPAUSE: +- tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL; +- break; ++ bf = ath_tx_get_buffer(sc); ++ if (!bf) { ++ ath_print(common, ATH_DBG_XMIT, "TX buffers are full\n"); ++ return NULL; + } ++ + hdrlen = ieee80211_get_hdrlen_from_skb(skb); + fc = hdr->frame_control; + +@@ -1605,16 +1587,13 @@ static int ath_tx_setup_buffer(struct ie bf->bf_frmlen -= padsize; } -- if (conf_is_ht(&hw->conf)) { -+ if (!txctl->paprd && conf_is_ht(&hw->conf)) { +- if (!txctl->paprd && conf_is_ht(&hw->conf)) { ++ if (ieee80211_is_data_qos(fc) && conf_is_ht(&hw->conf)) { bf->bf_state.bf_type |= BUF_HT; - if (tx_info->flags & IEEE80211_TX_CTL_LDPC) - use_ldpc = true; +- if (tx_info->flags & IEEE80211_TX_CTL_LDPC) +- use_ldpc = true; ++ if (sc->sc_flags & SC_OP_TXAGGR) ++ assign_aggr_tid_seqno(skb, bf); } -+ bf->bf_state.bfs_paprd = txctl->paprd; - bf->bf_flags = setup_tx_flags(skb, use_ldpc); - - bf->bf_keytype = get_hw_crypto_keytype(skb); -@@ -1742,6 +1718,9 @@ static void ath_tx_start_dma(struct ath_ - bf->bf_buf_addr, - txctl->txq->axq_qnum); - -+ if (bf->bf_state.bfs_paprd) -+ ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd); -+ - spin_lock_bh(&txctl->txq->axq_lock); - - if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && -@@ -1785,7 +1764,7 @@ int ath_tx_start(struct ieee80211_hw *hw - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ath_txq *txq = txctl->txq; - struct ath_buf *bf; -- int r; -+ int q, r; +- bf->bf_state.bfs_paprd = txctl->paprd; +- if (txctl->paprd) +- bf->bf_state.bfs_paprd_timestamp = jiffies; +- bf->bf_flags = setup_tx_flags(skb, use_ldpc); ++ bf->bf_flags = setup_tx_flags(skb); - bf = ath_tx_get_buffer(sc); - if (!bf) { -@@ -1793,14 +1772,6 @@ int ath_tx_start(struct ieee80211_hw *hw - return -1; + bf->bf_keytype = ath9k_cmn_get_hw_crypto_keytype(skb); + if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) { +@@ -1624,10 +1603,6 @@ static int ath_tx_setup_buffer(struct ie + bf->bf_keyix = ATH9K_TXKEYIX_INVALID; } -- bf->txq = txctl->txq; -- spin_lock_bh(&bf->txq->axq_lock); -- if (++bf->txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { -- ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); -- txq->stopped = 1; -- } -- spin_unlock_bh(&bf->txq->axq_lock); +- if (ieee80211_is_data_qos(fc) && bf_isht(bf) && +- (sc->sc_flags & SC_OP_TXAGGR)) +- assign_aggr_tid_seqno(skb, bf); - - r = ath_tx_setup_buffer(hw, bf, skb, txctl); - if (unlikely(r)) { - ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n"); -@@ -1821,6 +1792,17 @@ int ath_tx_start(struct ieee80211_hw *hw - return r; + bf->bf_mpdu = skb; + + bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, +@@ -1637,12 +1612,13 @@ static int ath_tx_setup_buffer(struct ie + bf->bf_buf_addr = 0; + ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, + "dma_mapping_error() on TX\n"); +- return -ENOMEM; ++ ath_tx_return_buffer(sc, bf); ++ return NULL; } -+ q = skb_get_queue_mapping(skb); -+ if (q >= 4) -+ q = 0; -+ -+ spin_lock_bh(&txq->axq_lock); -+ if (++sc->tx.pending_frames[q] > ATH_MAX_QDEPTH && !txq->stopped) { -+ ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); -+ txq->stopped = 1; -+ } -+ spin_unlock_bh(&txq->axq_lock); -+ - ath_tx_start_dma(sc, bf, txctl); - - return 0; -@@ -1890,7 +1872,7 @@ static void ath_tx_complete(struct ath_s - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; -- int padpos, padsize; -+ int q, padpos, padsize; + bf->bf_tx_aborted = false; - ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); +- return 0; ++ return bf; + } -@@ -1929,8 +1911,16 @@ static void ath_tx_complete(struct ath_s + /* FIXME: tx power */ +@@ -1690,11 +1666,6 @@ static void ath_tx_start_dma(struct ath_ + an = (struct ath_node *)tx_info->control.sta->drv_priv; + tid = ATH_AN_2_TID(an, bf->bf_tidno); - if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) - ath9k_tx_status(hw, skb); -- else -+ else { -+ q = skb_get_queue_mapping(skb); -+ if (q >= 4) -+ q = 0; +- if (!ieee80211_is_data_qos(fc)) { +- ath_tx_send_normal(sc, txctl->txq, &bf_head); +- goto tx_done; +- } +- + WARN_ON(tid->ac->txq != txctl->txq); + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + /* +@@ -1707,14 +1678,18 @@ static void ath_tx_start_dma(struct ath_ + * Send this frame as regular when ADDBA + * exchange is neither complete nor pending. + */ +- ath_tx_send_ht_normal(sc, txctl->txq, +- tid, &bf_head); ++ ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); + } + } else { +- ath_tx_send_normal(sc, txctl->txq, &bf_head); ++ bf->bf_state.bfs_ftype = txctl->frame_type; ++ bf->bf_state.bfs_paprd = txctl->paprd; + -+ if (--sc->tx.pending_frames[q] < 0) -+ sc->tx.pending_frames[q] = 0; ++ if (txctl->paprd) ++ bf->bf_state.bfs_paprd_timestamp = jiffies; + - ieee80211_tx_status(hw, skb); -+ } - } - - static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, -@@ -1951,16 +1941,15 @@ static void ath_tx_complete_buf(struct a - tx_flags |= ATH_TX_XRETRY; ++ ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head); } -- if (bf->txq) { -- spin_lock_bh(&bf->txq->axq_lock); -- bf->txq->pending_frames--; -- spin_unlock_bh(&bf->txq->axq_lock); -- bf->txq = NULL; -- } -- - dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); -- ath_tx_complete(sc, skb, bf->aphy, tx_flags); -- ath_debug_stat_tx(sc, txq, bf, ts); -+ -+ if (bf->bf_state.bfs_paprd) { -+ sc->paprd_txok = txok; -+ complete(&sc->paprd_complete); -+ } else { -+ ath_tx_complete(sc, skb, bf->aphy, tx_flags); -+ ath_debug_stat_tx(sc, txq, bf, ts); -+ } +-tx_done: + spin_unlock_bh(&txctl->txq->axq_lock); + } - /* - * Return the list of ath_buf of this mpdu to free queue -@@ -2045,13 +2034,14 @@ static void ath_wake_mac80211_queue(stru +@@ -1724,39 +1699,15 @@ int ath_tx_start(struct ieee80211_hw *hw { - int qnum; + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; +- struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_txq *txq = txctl->txq; + struct ath_buf *bf; +- int q, r; ++ int q; -+ qnum = ath_get_mac80211_qnum(txq->axq_class, sc); -+ if (qnum == -1) -+ return; -+ - spin_lock_bh(&txq->axq_lock); -- if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { -- qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc); -- if (qnum != -1) { -- ath_mac80211_start_queue(sc, qnum); -- txq->stopped = 0; -- } -+ if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) { -+ ath_mac80211_start_queue(sc, qnum); -+ txq->stopped = 0; - } - spin_unlock_bh(&txq->axq_lock); - } -@@ -2422,26 +2412,8 @@ void ath_tx_node_init(struct ath_softc * - for (acno = 0, ac = &an->ac[acno]; - acno < WME_NUM_AC; acno++, ac++) { - ac->sched = false; -+ ac->qnum = sc->tx.hwq_map[acno]; - INIT_LIST_HEAD(&ac->tid_q); +- bf = ath_tx_get_buffer(sc); +- if (!bf) { +- ath_print(common, ATH_DBG_XMIT, "TX buffers are full\n"); +- return -1; +- } ++ bf = ath_tx_setup_buffer(hw, skb); ++ if (unlikely(!bf)) ++ return -ENOMEM; + + q = skb_get_queue_mapping(skb); +- r = ath_tx_setup_buffer(hw, bf, skb, txctl); +- if (unlikely(r)) { +- ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n"); - -- switch (acno) { -- case WME_AC_BE: -- ac->qnum = ath_tx_get_qnum(sc, -- ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); -- break; -- case WME_AC_BK: -- ac->qnum = ath_tx_get_qnum(sc, -- ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK); -- break; -- case WME_AC_VI: -- ac->qnum = ath_tx_get_qnum(sc, -- ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI); -- break; -- case WME_AC_VO: -- ac->qnum = ath_tx_get_qnum(sc, -- ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO); -- break; +- /* upon ath_tx_processq() this TX queue will be resumed, we +- * guarantee this will happen by knowing beforehand that +- * we will at least have to run TX completionon one buffer +- * on the queue */ +- spin_lock_bh(&txq->axq_lock); +- if (txq == sc->tx.txq_map[q] && !txq->stopped && +- txq->axq_depth > 1) { +- ath_mac80211_stop_queue(sc, q); +- txq->stopped = 1; - } - } - } - ---- a/drivers/net/wireless/ath/ath9k/beacon.c -+++ b/drivers/net/wireless/ath/ath9k/beacon.c -@@ -38,8 +38,7 @@ int ath_beaconq_config(struct ath_softc - qi.tqi_cwmax = 0; - } else { - /* Adhoc mode; important thing is to use 2x cwmin. */ -- qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, -- ATH9K_WME_AC_BE); -+ qnum = sc->tx.hwq_map[WME_AC_BE]; - ath9k_hw_get_txq_props(ah, qnum, &qi_be); - qi.tqi_aifs = qi_be.tqi_aifs; - qi.tqi_cwmin = 4*qi_be.tqi_cwmin; ---- a/drivers/net/wireless/ath/ath9k/debug.c -+++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -630,10 +630,10 @@ static const struct file_operations fops - do { \ - len += snprintf(buf + len, size - len, \ - "%s%13u%11u%10u%10u\n", str, \ -- sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BE]].elem, \ -- sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BK]].elem, \ -- sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VI]].elem, \ -- sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VO]].elem); \ -+ sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BE]].elem, \ -+ sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BK]].elem, \ -+ sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VI]].elem, \ -+ sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VO]].elem); \ - } while(0) - - static ssize_t read_file_xmit(struct file *file, char __user *user_buf, -@@ -956,6 +956,10 @@ int ath9k_init_debug(struct ath_hw *ah) - sc->debug.debugfs_phy, sc, &fops_regval)) - goto err; - -+ if (!debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR, -+ sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca)) -+ goto err; -+ - sc->debug.regidx = 0; - return 0; - err: ---- a/drivers/net/wireless/ath/ath9k/htc.h -+++ b/drivers/net/wireless/ath/ath9k/htc.h -@@ -398,7 +398,7 @@ struct ath9k_htc_priv { - - int beaconq; - int cabq; -- int hwq_map[ATH9K_WME_AC_VO+1]; -+ int hwq_map[WME_NUM_AC]; - - #ifdef CONFIG_ATH9K_HTC_DEBUGFS - struct ath9k_debug debug; ---- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c -@@ -227,7 +227,7 @@ void ath9k_htc_beaconq_config(struct ath +- spin_unlock_bh(&txq->axq_lock); +- +- ath_tx_return_buffer(sc, bf); +- +- return r; +- } +- + spin_lock_bh(&txq->axq_lock); + if (txq == sc->tx.txq_map[q] && + ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { +@@ -1828,7 +1779,7 @@ exit: + /*****************/ + + static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, +- struct ath_wiphy *aphy, int tx_flags, ++ struct ath_wiphy *aphy, int tx_flags, int ftype, + struct ath_txq *txq) { - struct ath_hw *ah = priv->ah; - struct ath9k_tx_queue_info qi, qi_be; -- int qnum = priv->hwq_map[ATH9K_WME_AC_BE]; -+ int qnum = priv->hwq_map[WME_AC_BE]; - - memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); - memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); ---- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c -@@ -521,23 +521,23 @@ static int ath9k_init_queues(struct ath9 - goto err; + struct ieee80211_hw *hw = sc->hw; +@@ -1872,8 +1823,8 @@ static void ath_tx_complete(struct ath_s + PS_WAIT_FOR_TX_ACK)); } -- if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BE)) { -+ if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for BE traffic\n"); - goto err; - } - -- if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BK)) { -+ if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for BK traffic\n"); - goto err; - } -- if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VI)) { -+ if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for VI traffic\n"); - goto err; - } -- if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VO)) { -+ if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for VO traffic\n"); - goto err; ---- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c -@@ -1590,7 +1590,7 @@ static int ath9k_htc_conf_tx(struct ieee +- if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) +- ath9k_tx_status(hw, skb); ++ if (unlikely(ftype)) ++ ath9k_tx_status(hw, skb, ftype); + else { + q = skb_get_queue_mapping(skb); + if (txq == sc->tx.txq_map[q]) { +@@ -1917,7 +1868,8 @@ static void ath_tx_complete_buf(struct a + complete(&sc->paprd_complete); + } else { + ath_debug_stat_tx(sc, bf, ts); +- ath_tx_complete(sc, skb, bf->aphy, tx_flags, txq); ++ ath_tx_complete(sc, skb, bf->aphy, tx_flags, ++ bf->bf_state.bfs_ftype, txq); } - - if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) && -- (qnum == priv->hwq_map[ATH9K_WME_AC_BE])) -+ (qnum == priv->hwq_map[WME_AC_BE])) - ath9k_htc_beaconq_config(priv); - out: - ath9k_htc_ps_restore(priv); ---- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c -@@ -34,15 +34,15 @@ int get_hw_qnum(u16 queue, int *hwq_map) - { - switch (queue) { - case 0: -- return hwq_map[ATH9K_WME_AC_VO]; -+ return hwq_map[WME_AC_VO]; - case 1: -- return hwq_map[ATH9K_WME_AC_VI]; -+ return hwq_map[WME_AC_VI]; - case 2: -- return hwq_map[ATH9K_WME_AC_BE]; -+ return hwq_map[WME_AC_BE]; - case 3: -- return hwq_map[ATH9K_WME_AC_BK]; -+ return hwq_map[WME_AC_BK]; - default: -- return hwq_map[ATH9K_WME_AC_BE]; -+ return hwq_map[WME_AC_BE]; + /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't + * accidentally reference it later. +@@ -1968,6 +1920,8 @@ static void ath_tx_rc_status(struct ath_ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_hw *hw = bf->aphy->hw; ++ struct ath_softc *sc = bf->aphy->sc; ++ struct ath_hw *ah = sc->sc_ah; + u8 i, tx_rateindex; + + if (txok) +@@ -1989,14 +1943,24 @@ static void ath_tx_rc_status(struct ath_ + + if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && + (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { +- if (ieee80211_is_data(hdr->frame_control)) { +- if (ts->ts_flags & +- (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) +- tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; +- if ((ts->ts_status & ATH9K_TXERR_XRETRY) || +- (ts->ts_status & ATH9K_TXERR_FIFO)) +- tx_info->pad[0] |= ATH_TX_INFO_XRETRY; +- } ++ /* ++ * If an underrun error is seen assume it as an excessive ++ * retry only if max frame trigger level has been reached ++ * (2 KB for single stream, and 4 KB for dual stream). ++ * Adjust the long retry as if the frame was tried ++ * hw->max_rate_tries times to affect how rate control updates ++ * PER for the failed rate. ++ * In case of congestion on the bus penalizing this type of ++ * underruns should help hardware actually transmit new frames ++ * successfully by eventually preferring slower rates. ++ * This itself should also alleviate congestion on the bus. ++ */ ++ if (ieee80211_is_data(hdr->frame_control) && ++ (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN | ++ ATH9K_TX_DELIM_UNDERRUN)) && ++ ah->tx_trig_level >= sc->sc_ah->caps.tx_triglevel_max) ++ tx_info->status.rates[tx_rateindex].count = ++ hw->max_rate_tries; } - } - ---- a/drivers/net/wireless/ath/ath9k/mac.h -+++ b/drivers/net/wireless/ath/ath9k/mac.h -@@ -577,13 +577,8 @@ enum ath9k_tx_queue { - - #define ATH9K_NUM_TX_QUEUES 10 - --enum ath9k_tx_queue_subtype { -- ATH9K_WME_AC_BK = 0, -- ATH9K_WME_AC_BE, -- ATH9K_WME_AC_VI, -- ATH9K_WME_AC_VO, -- ATH9K_WME_UPSD --}; -+/* Used as a queue subtype instead of a WMM AC */ -+#define ATH9K_WME_UPSD 4 - - enum ath9k_tx_queue_flags { - TXQ_FLAG_TXOKINT_ENABLE = 0x0001, -@@ -617,7 +612,7 @@ enum ath9k_pkt_type { - struct ath9k_tx_queue_info { - u32 tqi_ver; - enum ath9k_tx_queue tqi_type; -- enum ath9k_tx_queue_subtype tqi_subtype; -+ int tqi_subtype; - enum ath9k_tx_queue_flags tqi_qflags; - u32 tqi_priority; - u32 tqi_aifs; ---- a/drivers/net/wireless/ath/ath9k/virtual.c -+++ b/drivers/net/wireless/ath/ath9k/virtual.c -@@ -219,7 +219,7 @@ static int ath9k_send_nullfunc(struct at - info->control.rates[1].idx = -1; - - memset(&txctl, 0, sizeof(struct ath_tx_control)); -- txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]]; -+ txctl.txq = &sc->tx.txq[sc->tx.hwq_map[WME_AC_VO]]; - txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE; - if (ath_tx_start(aphy->hw, skb, &txctl) != 0) + for (i = tx_rateindex + 1; i < hw->max_rates; i++) {