diff options
author | Rajkumar Manoharan <rmanohar@qca.qualcomm.com> | 2011-10-13 01:30:37 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-10-14 14:48:22 -0400 |
commit | 77a5a6648da6b90d6ba990bf03c59993cdd5a516 (patch) | |
tree | c9ac2693b213cbe5e5b353d310c4947fa8927b14 /drivers/net | |
parent | 34013524a1644bbd00c592541f67c536a384e707 (diff) |
ath9k_hw: Add support to reuse Carrier leak calibration
This patch adds support to reuse Carrier leak calibration
during fast channel change for AR9480 chips.
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_calib.c | 46 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 3 |
3 files changed, 50 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 6d685664f916..5f406382677e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -905,8 +905,23 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
905 | { | 905 | { |
906 | struct ath_common *common = ath9k_hw_common(ah); | 906 | struct ath_common *common = ath9k_hw_common(ah); |
907 | struct ath9k_hw_cal_data *caldata = ah->caldata; | 907 | struct ath9k_hw_cal_data *caldata = ah->caldata; |
908 | bool txiqcal_done = false; | 908 | bool txiqcal_done = false, txclcal_done = false; |
909 | bool is_reusable = true; | 909 | bool is_reusable = true, txclcal_enabled; |
910 | u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0, | ||
911 | AR_PHY_CL_TAB_1, | ||
912 | AR_PHY_CL_TAB_2 }; | ||
913 | |||
914 | txclcal_enabled = !!(REG_READ(ah, AR_PHY_CL_CAL_CTL) & | ||
915 | AR_PHY_CL_CAL_ENABLE); | ||
916 | |||
917 | if (txclcal_enabled) { | ||
918 | if (caldata && caldata->done_txclcal_once) | ||
919 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, | ||
920 | AR_PHY_CL_CAL_ENABLE); | ||
921 | else | ||
922 | REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, | ||
923 | AR_PHY_CL_CAL_ENABLE); | ||
924 | } | ||
910 | 925 | ||
911 | /* Do Tx IQ Calibration */ | 926 | /* Do Tx IQ Calibration */ |
912 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, | 927 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, |
@@ -950,6 +965,33 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
950 | else if (caldata && caldata->done_txiqcal_once) | 965 | else if (caldata && caldata->done_txiqcal_once) |
951 | ar9003_hw_tx_iq_cal_reload(ah); | 966 | ar9003_hw_tx_iq_cal_reload(ah); |
952 | 967 | ||
968 | #define CL_TAB_ENTRY(reg_base) (reg_base + (4 * j)) | ||
969 | if (caldata && txclcal_enabled) { | ||
970 | int i, j; | ||
971 | txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & | ||
972 | AR_PHY_AGC_CONTROL_CLC_SUCCESS); | ||
973 | if (caldata->done_txclcal_once) { | ||
974 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
975 | if (!(ah->txchainmask & (1 << i))) | ||
976 | continue; | ||
977 | for (j = 0; j < MAX_CL_TAB_ENTRY; j++) | ||
978 | REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]), | ||
979 | caldata->tx_clcal[i][j]); | ||
980 | } | ||
981 | } else if (is_reusable && txclcal_done) { | ||
982 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
983 | if (!(ah->txchainmask & (1 << i))) | ||
984 | continue; | ||
985 | for (j = 0; j < MAX_CL_TAB_ENTRY; j++) | ||
986 | caldata->tx_clcal[i][j] = | ||
987 | REG_READ(ah, | ||
988 | CL_TAB_ENTRY(cl_idx[i])); | ||
989 | } | ||
990 | caldata->done_txclcal_once = true; | ||
991 | } | ||
992 | } | ||
993 | #undef CL_TAB_ENTRY | ||
994 | |||
953 | ath9k_hw_loadnf(ah, chan); | 995 | ath9k_hw_loadnf(ah, chan); |
954 | ath9k_hw_start_nfcal(ah, true); | 996 | ath9k_hw_start_nfcal(ah, true); |
955 | 997 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index e51d93d33d5f..0aa05841b263 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1707,8 +1707,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1707 | 1707 | ||
1708 | ath9k_hw_init_bb(ah, chan); | 1708 | ath9k_hw_init_bb(ah, chan); |
1709 | 1709 | ||
1710 | if (caldata) | 1710 | if (caldata) { |
1711 | caldata->done_txiqcal_once = false; | 1711 | caldata->done_txiqcal_once = false; |
1712 | caldata->done_txclcal_once = false; | ||
1713 | } | ||
1712 | if (!ath9k_hw_init_cal(ah, chan)) | 1714 | if (!ath9k_hw_init_cal(ah, chan)) |
1713 | return -EIO; | 1715 | return -EIO; |
1714 | 1716 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index e5c458d22c82..446f4d309bec 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -338,6 +338,7 @@ enum ath9k_int { | |||
338 | CHANNEL_HT40MINUS) | 338 | CHANNEL_HT40MINUS) |
339 | 339 | ||
340 | #define MAX_IQCAL_MEASUREMENT 8 | 340 | #define MAX_IQCAL_MEASUREMENT 8 |
341 | #define MAX_CL_TAB_ENTRY 16 | ||
341 | 342 | ||
342 | struct ath9k_hw_cal_data { | 343 | struct ath9k_hw_cal_data { |
343 | u16 channel; | 344 | u16 channel; |
@@ -349,10 +350,12 @@ struct ath9k_hw_cal_data { | |||
349 | bool nfcal_pending; | 350 | bool nfcal_pending; |
350 | bool nfcal_interference; | 351 | bool nfcal_interference; |
351 | bool done_txiqcal_once; | 352 | bool done_txiqcal_once; |
353 | bool done_txclcal_once; | ||
352 | u16 small_signal_gain[AR9300_MAX_CHAINS]; | 354 | u16 small_signal_gain[AR9300_MAX_CHAINS]; |
353 | u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; | 355 | u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; |
354 | u32 num_measures[AR9300_MAX_CHAINS]; | 356 | u32 num_measures[AR9300_MAX_CHAINS]; |
355 | int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS]; | 357 | int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS]; |
358 | u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY]; | ||
356 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; | 359 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; |
357 | }; | 360 | }; |
358 | 361 | ||