Commit df23acaa authored by Luis R. Rodriguez's avatar Luis R. Rodriguez Committed by John W. Linville

ath9k_hw: complete AR9003 calibration

This goes with some new shiny TX IQ calibration that AR9003
hardware family supports.
Signed-off-by: default avatarLuis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: default avatarVasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 4b01931e
......@@ -814,6 +814,105 @@ void ar9003_hw_set_nf_limits(struct ath_hw *ah)
ah->nf_5g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
}
/*
* Find out which of the RX chains are enabled
*/
static u32 ar9003_hw_get_rx_chainmask(struct ath_hw *ah)
{
u32 chain = REG_READ(ah, AR_PHY_RX_CHAINMASK);
/*
* The bits [2:0] indicate the rx chain mask and are to be
* interpreted as follows:
* 00x => Only chain 0 is enabled
* 01x => Chain 1 and 0 enabled
* 1xx => Chain 2,1 and 0 enabled
*/
return chain & 0x7;
}
static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
{
struct ath9k_nfcal_hist *h;
unsigned i, j;
int32_t val;
const u32 ar9300_cca_regs[6] = {
AR_PHY_CCA_0,
AR_PHY_CCA_1,
AR_PHY_CCA_2,
AR_PHY_EXT_CCA,
AR_PHY_EXT_CCA_1,
AR_PHY_EXT_CCA_2,
};
u8 chainmask, rx_chain_status;
struct ath_common *common = ath9k_hw_common(ah);
rx_chain_status = ar9003_hw_get_rx_chainmask(ah);
chainmask = 0x3F;
h = ah->nfCalHist;
for (i = 0; i < NUM_NF_READINGS; i++) {
if (chainmask & (1 << i)) {
val = REG_READ(ah, ar9300_cca_regs[i]);
val &= 0xFFFFFE00;
val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
REG_WRITE(ah, ar9300_cca_regs[i], val);
}
}
/*
* Load software filtered NF value into baseband internal minCCApwr
* variable.
*/
REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_ENABLE_NF);
REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
/*
* Wait for load to complete, should be fast, a few 10s of us.
* The max delay was changed from an original 250us to 10000us
* since 250us often results in NF load timeout and causes deaf
* condition during stress testing 12/12/2009
*/
for (j = 0; j < 1000; j++) {
if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
AR_PHY_AGC_CONTROL_NF) == 0)
break;
udelay(10);
}
/*
* We timed out waiting for the noisefloor to load, probably due to an
* in-progress rx. Simply return here and allow the load plenty of time
* to complete before the next calibration interval. We need to avoid
* trying to load -50 (which happens below) while the previous load is
* still in progress as this can cause rx deafness. Instead by returning
* here, the baseband nf cal will just be capped by our present
* noisefloor until the next calibration timer.
*/
if (j == 1000) {
ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
"to load: AR_PHY_AGC_CONTROL=0x%x\n",
REG_READ(ah, AR_PHY_AGC_CONTROL));
}
/*
* Restore maxCCAPower register parameter again so that we're not capped
* by the median we just loaded. This will be initial (and max) value
* of next noise floor calibration the baseband does.
*/
for (i = 0; i < NUM_NF_READINGS; i++) {
if (chainmask & (1 << i)) {
val = REG_READ(ah, ar9300_cca_regs[i]);
val &= 0xFFFFFE00;
val |= (((u32) (-50) << 1) & 0x1ff);
REG_WRITE(ah, ar9300_cca_regs[i], val);
}
}
}
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
......@@ -833,4 +932,5 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
priv_ops->set_diversity = ar9003_hw_set_diversity;
priv_ops->ani_control = ar9003_hw_ani_control;
priv_ops->do_getnf = ar9003_hw_do_getnf;
priv_ops->loadnf = ar9003_hw_loadnf;
}
......@@ -155,6 +155,7 @@
#define AR5416_BCHAN_UNUSED 0xFF
#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
#define AR5416_MAX_CHAINS 3
#define AR9300_MAX_CHAINS 3
#define AR5416_PWR_TABLE_OFFSET_DB -5
/* Rx gain type values */
......
......@@ -611,6 +611,7 @@ struct ath_hw {
struct ath9k_cal_list adcgain_caldata;
struct ath9k_cal_list adcdc_calinitdata;
struct ath9k_cal_list adcdc_caldata;
struct ath9k_cal_list tempCompCalData;
struct ath9k_cal_list *cal_list;
struct ath9k_cal_list *cal_list_last;
struct ath9k_cal_list *cal_list_curr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment