From: Felix Fietkau Date: Mon, 6 Aug 2012 22:11:30 +0000 (+0000) Subject: ath9k: extend and enable PA predistortion X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fstaging%2Flynxis%2Fomap.git;a=commitdiff_plain;h=a55de42c7d911dae01c9a31b15e70f550e81df49 ath9k: extend and enable PA predistortion SVN-Revision: 33031 --- diff --git a/package/mac80211/patches/570-ath9k_paprd_hornet_mask.patch b/package/mac80211/patches/570-ath9k_paprd_hornet_mask.patch new file mode 100644 index 0000000000..90e3ef2ac8 --- /dev/null +++ b/package/mac80211/patches/570-ath9k_paprd_hornet_mask.patch @@ -0,0 +1,25 @@ +--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +@@ -142,6 +142,7 @@ static int ar9003_paprd_setup_single_tab + }; + int training_power; + int i, val; ++ u32 am2pm_mask = ah->paprd_ratemask; + + if (IS_CHAN_2GHZ(ah->curchan)) + training_power = ar9003_get_training_power_2g(ah); +@@ -158,10 +159,13 @@ static int ar9003_paprd_setup_single_tab + } + ah->paprd_training_power = training_power; + ++ if (AR_SREV_9330(ah)) ++ am2pm_mask = 0; ++ + REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, + ah->paprd_ratemask); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, +- ah->paprd_ratemask); ++ am2pm_mask); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, + ah->paprd_ratemask_ht40); + diff --git a/package/mac80211/patches/571-ath9k_paprd_retrain_pa_in.patch b/package/mac80211/patches/571-ath9k_paprd_retrain_pa_in.patch new file mode 100644 index 0000000000..4a366e3306 --- /dev/null +++ b/package/mac80211/patches/571-ath9k_paprd_retrain_pa_in.patch @@ -0,0 +1,153 @@ +--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +@@ -786,6 +786,102 @@ int ar9003_paprd_setup_gain_table(struct + } + EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); + ++static bool ar9003_paprd_retrain_pa_in(struct ath_hw *ah, ++ struct ath9k_hw_cal_data *caldata, ++ int chain) ++{ ++ u32 *pa_in = caldata->pa_table[chain]; ++ int capdiv_offset, quick_drop_offset; ++ int capdiv2g, quick_drop; ++ int count = 0; ++ int i; ++ ++ if (!AR_SREV_9485(ah) && !AR_SREV_9330(ah)) ++ return false; ++ ++ capdiv2g = REG_READ_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, ++ AR_PHY_65NM_CH0_TXRF3_CAPDIV2G); ++ ++ quick_drop = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, ++ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP); ++ ++ if (quick_drop) ++ quick_drop -= 0x40; ++ ++ for (i = 0; i < NUM_BIN + 1; i++) { ++ if (pa_in[i] == 1400) ++ count++; ++ } ++ ++ if (AR_SREV_9485(ah)) { ++ if (pa_in[23] < 800) { ++ capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150); ++ capdiv2g += capdiv_offset; ++ if (capdiv2g > 7) { ++ capdiv2g = 7; ++ if (pa_in[23] < 600) { ++ quick_drop++; ++ if (quick_drop > 0) ++ quick_drop = 0; ++ } ++ } ++ } else if (pa_in[23] == 1400) { ++ quick_drop_offset = min_t(int, count / 3, 2); ++ quick_drop += quick_drop_offset; ++ capdiv2g += quick_drop_offset / 2; ++ ++ if (capdiv2g > 7) ++ capdiv2g = 7; ++ ++ if (quick_drop > 0) { ++ quick_drop = 0; ++ capdiv2g -= quick_drop_offset; ++ if (capdiv2g < 0) ++ capdiv2g = 0; ++ } ++ } else { ++ return false; ++ } ++ } else if (AR_SREV_9330(ah)) { ++ if (pa_in[23] < 1000) { ++ capdiv_offset = (1000 - pa_in[23]) / 100; ++ capdiv2g += capdiv_offset; ++ if (capdiv_offset > 3) { ++ capdiv_offset = 1; ++ quick_drop--; ++ } ++ ++ capdiv2g += capdiv_offset; ++ if (capdiv2g > 6) ++ capdiv2g = 6; ++ if (quick_drop < -4) ++ quick_drop = -4; ++ } else if (pa_in[23] == 1400) { ++ if (count > 3) { ++ quick_drop++; ++ capdiv2g -= count / 4; ++ if (quick_drop > -2) ++ quick_drop = -2; ++ } else { ++ capdiv2g--; ++ } ++ ++ if (capdiv2g < 0) ++ capdiv2g = 0; ++ } else { ++ return false; ++ } ++ } ++ ++ REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, ++ AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, capdiv2g); ++ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, ++ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, ++ quick_drop); ++ ++ return true; ++} ++ + int ar9003_paprd_create_curve(struct ath_hw *ah, + struct ath9k_hw_cal_data *caldata, int chain) + { +@@ -821,6 +917,9 @@ int ar9003_paprd_create_curve(struct ath + if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) + status = -2; + ++ if (ar9003_paprd_retrain_pa_in(ah, caldata, chain)) ++ status = -EINPROGRESS; ++ + REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, + AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); + +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h +@@ -625,6 +625,10 @@ + #define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) + #define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) + ++#define AR_PHY_65NM_CH0_TXRF3 0x16048 ++#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G 0x0000001e ++#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S 1 ++ + #define AR_PHY_65NM_CH0_SYNTH4 0x1608c + #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002) + #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) +--- a/drivers/net/wireless/ath/ath9k/link.c ++++ b/drivers/net/wireless/ath/ath9k/link.c +@@ -254,6 +254,7 @@ void ath_paprd_calibrate(struct work_str + int chain_ok = 0; + int chain; + int len = 1800; ++ int ret; + + if (!caldata) + return; +@@ -302,7 +303,13 @@ void ath_paprd_calibrate(struct work_str + break; + } + +- if (ar9003_paprd_create_curve(ah, caldata, chain)) { ++ ret = ar9003_paprd_create_curve(ah, caldata, chain); ++ if (ret == -EINPROGRESS) { ++ ath_dbg(common, CALIBRATE, ++ "PAPRD curve on chain %d needs to be re-trained\n", ++ chain); ++ break; ++ } else if (ret) { + ath_dbg(common, CALIBRATE, + "PAPRD create curve failed on chain %d\n", + chain); diff --git a/package/mac80211/patches/572-ath9k_enable_paprd.patch b/package/mac80211/patches/572-ath9k_enable_paprd.patch new file mode 100644 index 0000000000..ff39587f61 --- /dev/null +++ b/package/mac80211/patches/572-ath9k_enable_paprd.patch @@ -0,0 +1,12 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -464,9 +464,6 @@ static void ath9k_hw_init_config(struct + ah->config.spurchans[i][1] = AR_NO_SPUR; + } + +- /* PAPRD needs some more work to be enabled */ +- ah->config.paprd_disable = 1; +- + ah->config.rx_intr_mitigation = true; + ah->config.pcieSerDesWrite = true; +