ath9k_hw: add OFDM spur mitigation for AR9003
We add this now as OFDM spur mitigation required accessing the EEPROM for the AR9003 devices. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
15c9ee7af8
commit
1547da37db
5 changed files with 267 additions and 4 deletions
|
@ -289,8 +289,6 @@
|
|||
#define AR_PHY_TIMING11 0x99a0
|
||||
#define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF
|
||||
#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
|
||||
#define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000
|
||||
#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000
|
||||
|
||||
|
|
|
@ -103,8 +103,8 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
|
|||
*
|
||||
* Spur mitigation for MRC CCK
|
||||
*/
|
||||
static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
u32 spur_freq[4] = { 2420, 2440, 2464, 2480 };
|
||||
int cur_bb_spur, negative = 0, cck_spur_freq;
|
||||
|
@ -157,6 +157,212 @@ static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
|
|||
AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0x0);
|
||||
}
|
||||
|
||||
/* Clean all spur register fields */
|
||||
static void ar9003_hw_spur_ofdm_clear(struct ath_hw *ah)
|
||||
{
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING4,
|
||||
AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING11,
|
||||
AR_PHY_TIMING11_SPUR_FREQ_SD, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING11,
|
||||
AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING11,
|
||||
AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING11,
|
||||
AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING4,
|
||||
AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
||||
AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
||||
AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 0);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
||||
AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING4,
|
||||
AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING4,
|
||||
AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
|
||||
AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
|
||||
AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
|
||||
AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
|
||||
AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
|
||||
AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
|
||||
AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
||||
AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0);
|
||||
}
|
||||
|
||||
static void ar9003_hw_spur_ofdm(struct ath_hw *ah,
|
||||
int freq_offset,
|
||||
int spur_freq_sd,
|
||||
int spur_delta_phase,
|
||||
int spur_subchannel_sd)
|
||||
{
|
||||
int mask_index = 0;
|
||||
|
||||
/* OFDM Spur mitigation */
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING4,
|
||||
AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0x1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING11,
|
||||
AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING11,
|
||||
AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, spur_subchannel_sd);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING11,
|
||||
AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING11,
|
||||
AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING4,
|
||||
AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
||||
AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
||||
AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
|
||||
|
||||
if (REG_READ_FIELD(ah, AR_PHY_MODE,
|
||||
AR_PHY_MODE_DYNAMIC) == 0x1)
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
||||
AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
|
||||
|
||||
mask_index = (freq_offset << 4) / 5;
|
||||
if (mask_index < 0)
|
||||
mask_index = mask_index - 1;
|
||||
|
||||
mask_index = mask_index & 0x7f;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
||||
AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0x1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING4,
|
||||
AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0x1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING4,
|
||||
AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0x1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
|
||||
AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, mask_index);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
|
||||
AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, mask_index);
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
|
||||
AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, mask_index);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
|
||||
AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0xc);
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
|
||||
AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0xc);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
|
||||
AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
||||
AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff);
|
||||
}
|
||||
|
||||
static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
int freq_offset)
|
||||
{
|
||||
int spur_freq_sd = 0;
|
||||
int spur_subchannel_sd = 0;
|
||||
int spur_delta_phase = 0;
|
||||
|
||||
if (IS_CHAN_HT40(chan)) {
|
||||
if (freq_offset < 0) {
|
||||
if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
|
||||
AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
|
||||
spur_subchannel_sd = 1;
|
||||
else
|
||||
spur_subchannel_sd = 0;
|
||||
|
||||
spur_freq_sd = ((freq_offset + 10) << 9) / 11;
|
||||
|
||||
} else {
|
||||
if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
|
||||
AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
|
||||
spur_subchannel_sd = 0;
|
||||
else
|
||||
spur_subchannel_sd = 1;
|
||||
|
||||
spur_freq_sd = ((freq_offset - 10) << 9) / 11;
|
||||
|
||||
}
|
||||
|
||||
spur_delta_phase = (freq_offset << 17) / 5;
|
||||
|
||||
} else {
|
||||
spur_subchannel_sd = 0;
|
||||
spur_freq_sd = (freq_offset << 9) /11;
|
||||
spur_delta_phase = (freq_offset << 18) / 5;
|
||||
}
|
||||
|
||||
spur_freq_sd = spur_freq_sd & 0x3ff;
|
||||
spur_delta_phase = spur_delta_phase & 0xfffff;
|
||||
|
||||
ar9003_hw_spur_ofdm(ah,
|
||||
freq_offset,
|
||||
spur_freq_sd,
|
||||
spur_delta_phase,
|
||||
spur_subchannel_sd);
|
||||
}
|
||||
|
||||
/* Spur mitigation for OFDM */
|
||||
static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
int synth_freq;
|
||||
int range = 10;
|
||||
int freq_offset = 0;
|
||||
int mode;
|
||||
u8* spurChansPtr;
|
||||
unsigned int i;
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
|
||||
if (IS_CHAN_5GHZ(chan)) {
|
||||
spurChansPtr = &(eep->modalHeader5G.spurChans[0]);
|
||||
mode = 0;
|
||||
}
|
||||
else {
|
||||
spurChansPtr = &(eep->modalHeader2G.spurChans[0]);
|
||||
mode = 1;
|
||||
}
|
||||
|
||||
if (spurChansPtr[0] == 0)
|
||||
return; /* No spur in the mode */
|
||||
|
||||
if (IS_CHAN_HT40(chan)) {
|
||||
range = 19;
|
||||
if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
|
||||
AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
|
||||
synth_freq = chan->channel - 10;
|
||||
else
|
||||
synth_freq = chan->channel + 10;
|
||||
} else {
|
||||
range = 10;
|
||||
synth_freq = chan->channel;
|
||||
}
|
||||
|
||||
ar9003_hw_spur_ofdm_clear(ah);
|
||||
|
||||
for (i = 0; spurChansPtr[i] && i < 5; i++) {
|
||||
freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq;
|
||||
if (abs(freq_offset) < range) {
|
||||
ar9003_hw_spur_ofdm_work(ah, chan, freq_offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
ar9003_hw_spur_mitigate_mrc_cck(ah, chan);
|
||||
ar9003_hw_spur_mitigate_ofdm(ah, chan);
|
||||
}
|
||||
|
||||
static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
|
|
|
@ -33,6 +33,30 @@
|
|||
#define AR_PHY_RX_IQCAL_CORR_B0 (AR_CHAN_BASE + 0xdc)
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_3 (AR_CHAN_BASE + 0xb0)
|
||||
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
|
||||
|
||||
#define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF
|
||||
#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
|
||||
|
||||
#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC 0x40000000
|
||||
#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC_S 30
|
||||
|
||||
#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR 0x80000000
|
||||
#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR_S 31
|
||||
|
||||
#define AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT 0x4000000
|
||||
#define AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT_S 26
|
||||
|
||||
#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000 /* bins move with freq offset */
|
||||
#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM_S 17
|
||||
#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x000000FF
|
||||
#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
|
||||
#define AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI 0x00000100
|
||||
#define AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI_S 8
|
||||
#define AR_PHY_SPUR_REG_MASK_RATE_CNTL 0x03FC0000
|
||||
#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
|
||||
|
||||
#define AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN 0x20000000
|
||||
#define AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN_S 29
|
||||
|
||||
|
@ -84,6 +108,17 @@
|
|||
#define AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX 0xF000
|
||||
#define AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX_S 12
|
||||
#define AR_PHY_TIMING4_DO_CAL 0x10000
|
||||
|
||||
#define AR_PHY_TIMING4_ENABLE_PILOT_MASK 0x10000000
|
||||
#define AR_PHY_TIMING4_ENABLE_PILOT_MASK_S 28
|
||||
#define AR_PHY_TIMING4_ENABLE_CHAN_MASK 0x20000000
|
||||
#define AR_PHY_TIMING4_ENABLE_CHAN_MASK_S 29
|
||||
|
||||
#define AR_PHY_TIMING4_ENABLE_SPUR_FILTER 0x40000000
|
||||
#define AR_PHY_TIMING4_ENABLE_SPUR_FILTER_S 30
|
||||
#define AR_PHY_TIMING4_ENABLE_SPUR_RSSI 0x80000000
|
||||
#define AR_PHY_TIMING4_ENABLE_SPUR_RSSI_S 31
|
||||
|
||||
#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
|
||||
#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
|
||||
#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
|
||||
|
@ -107,6 +142,8 @@
|
|||
#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
|
||||
#define AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD 0x10000000
|
||||
#define AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD_S 28
|
||||
#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
|
||||
#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
|
||||
#define AR_PHY_EXT_CCA_THRESH62_S 16
|
||||
|
@ -184,6 +221,16 @@
|
|||
#define AR_PHY_ML_CNTL_2 (AR_MRC_BASE + 0x1c)
|
||||
#define AR_PHY_TST_ADC (AR_MRC_BASE + 0x20)
|
||||
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A 0x00000FE0
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_S 5
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A 0x1F
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A_S 0
|
||||
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A 0x00000FE0
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_S 5
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A 0x1F
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A_S 0
|
||||
|
||||
/*
|
||||
* MRC Feild Definitions
|
||||
*/
|
||||
|
@ -372,6 +419,11 @@
|
|||
#define AR_PHY_ADDAC_PARA_CTL (AR_SM_BASE + 0x150)
|
||||
#define AR_PHY_XPA_CFG (AR_SM_BASE + 0x158)
|
||||
|
||||
#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A 0x0001FC00
|
||||
#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_S 10
|
||||
#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A 0x3FF
|
||||
#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A_S 0
|
||||
|
||||
#define AR_PHY_TEST (AR_SM_BASE + 0x160)
|
||||
|
||||
#define AR_PHY_TEST_BBB_OBS_SEL 0x780000
|
||||
|
@ -499,6 +551,7 @@
|
|||
#define AR_PHY_GC_DYN2040_EN 0x00000004 /* enable dyn 20/40 mode */
|
||||
#define AR_PHY_GC_DYN2040_PRI_ONLY 0x00000008 /* dyn 20/40 - primary only */
|
||||
#define AR_PHY_GC_DYN2040_PRI_CH 0x00000010 /* dyn 20/40 - primary ch offset (0=+10MHz, 1=-10MHz)*/
|
||||
#define AR_PHY_GC_DYN2040_PRI_CH_S 4
|
||||
#define AR_PHY_GC_DYN2040_EXT_CH 0x00000020 /* dyn 20/40 - ext ch spacing (0=20MHz/ 1=25MHz) */
|
||||
#define AR_PHY_GC_HT_EN 0x00000040 /* ht enable */
|
||||
#define AR_PHY_GC_SHORT_GI_40 0x00000080 /* allow short GI for HT 40 */
|
||||
|
@ -516,6 +569,7 @@
|
|||
#define AR_PHY_MODE_OFDM 0x00000000
|
||||
#define AR_PHY_MODE_CCK 0x00000001
|
||||
#define AR_PHY_MODE_DYNAMIC 0x00000004
|
||||
#define AR_PHY_MODE_DYNAMIC_S 2
|
||||
#define AR_PHY_MODE_HALF 0x00000020
|
||||
#define AR_PHY_MODE_QUARTER 0x00000040
|
||||
#define AR_PHY_MAC_CLK_MODE 0x00000080
|
||||
|
|
|
@ -76,6 +76,8 @@
|
|||
#define REG_RMW_FIELD(_a, _r, _f, _v) \
|
||||
REG_WRITE(_a, _r, \
|
||||
(REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
|
||||
#define REG_READ_FIELD(_a, _r, _f) \
|
||||
(((REG_READ(_a, _r) & _f) >> _f##_S))
|
||||
#define REG_SET_BIT(_a, _r, _f) \
|
||||
REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
|
||||
#define REG_CLR_BIT(_a, _r, _f) \
|
||||
|
|
|
@ -59,4 +59,7 @@
|
|||
(_bank)[i] = INI_RA((_iniarray), i, _col);; \
|
||||
} while (0)
|
||||
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue