diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_calib.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_calib.c | 92 |
1 files changed, 73 insertions, 19 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 6988e1d081f2..22934d3ca544 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
| @@ -727,8 +727,12 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | |||
| 727 | REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, | 727 | REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, |
| 728 | AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); | 728 | AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); |
| 729 | 729 | ||
| 730 | if (caldata) | 730 | if (caldata) { |
| 731 | caldata->done_txiqcal_once = is_reusable; | 731 | if (is_reusable) |
| 732 | set_bit(TXIQCAL_DONE, &caldata->cal_flags); | ||
| 733 | else | ||
| 734 | clear_bit(TXIQCAL_DONE, &caldata->cal_flags); | ||
| 735 | } | ||
| 732 | 736 | ||
| 733 | return; | 737 | return; |
| 734 | } | 738 | } |
| @@ -961,18 +965,44 @@ static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g) | |||
| 961 | } | 965 | } |
| 962 | 966 | ||
| 963 | static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah, | 967 | static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah, |
| 964 | struct ath9k_channel *chan) | 968 | struct ath9k_channel *chan, |
| 969 | bool run_rtt_cal) | ||
| 965 | { | 970 | { |
| 971 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
| 966 | int i; | 972 | int i; |
| 967 | 973 | ||
| 968 | if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah) && !AR_SREV_9485(ah)) | 974 | if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah) && !AR_SREV_9485(ah)) |
| 969 | return; | 975 | return; |
| 970 | 976 | ||
| 977 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && !run_rtt_cal) | ||
| 978 | return; | ||
| 979 | |||
| 971 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | 980 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { |
| 972 | if (!(ah->rxchainmask & (1 << i))) | 981 | if (!(ah->rxchainmask & (1 << i))) |
| 973 | continue; | 982 | continue; |
| 974 | ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan)); | 983 | ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan)); |
| 975 | } | 984 | } |
| 985 | |||
| 986 | if (caldata) | ||
| 987 | set_bit(SW_PKDET_DONE, &caldata->cal_flags); | ||
| 988 | |||
| 989 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && caldata) { | ||
| 990 | if (IS_CHAN_2GHZ(chan)){ | ||
| 991 | caldata->caldac[0] = REG_READ_FIELD(ah, | ||
| 992 | AR_PHY_65NM_RXRF_AGC(0), | ||
| 993 | AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR); | ||
| 994 | caldata->caldac[1] = REG_READ_FIELD(ah, | ||
| 995 | AR_PHY_65NM_RXRF_AGC(1), | ||
| 996 | AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR); | ||
| 997 | } else { | ||
| 998 | caldata->caldac[0] = REG_READ_FIELD(ah, | ||
| 999 | AR_PHY_65NM_RXRF_AGC(0), | ||
| 1000 | AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR); | ||
| 1001 | caldata->caldac[1] = REG_READ_FIELD(ah, | ||
| 1002 | AR_PHY_65NM_RXRF_AGC(1), | ||
| 1003 | AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR); | ||
| 1004 | } | ||
| 1005 | } | ||
| 976 | } | 1006 | } |
| 977 | 1007 | ||
| 978 | static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) | 1008 | static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) |
| @@ -990,7 +1020,7 @@ static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) | |||
| 990 | txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & | 1020 | txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & |
| 991 | AR_PHY_AGC_CONTROL_CLC_SUCCESS); | 1021 | AR_PHY_AGC_CONTROL_CLC_SUCCESS); |
| 992 | 1022 | ||
| 993 | if (caldata->done_txclcal_once) { | 1023 | if (test_bit(TXCLCAL_DONE, &caldata->cal_flags)) { |
| 994 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | 1024 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { |
| 995 | if (!(ah->txchainmask & (1 << i))) | 1025 | if (!(ah->txchainmask & (1 << i))) |
| 996 | continue; | 1026 | continue; |
| @@ -1006,7 +1036,7 @@ static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) | |||
| 1006 | caldata->tx_clcal[i][j] = | 1036 | caldata->tx_clcal[i][j] = |
| 1007 | REG_READ(ah, CL_TAB_ENTRY(cl_idx[i])); | 1037 | REG_READ(ah, CL_TAB_ENTRY(cl_idx[i])); |
| 1008 | } | 1038 | } |
| 1009 | caldata->done_txclcal_once = true; | 1039 | set_bit(TXCLCAL_DONE, &caldata->cal_flags); |
| 1010 | } | 1040 | } |
| 1011 | } | 1041 | } |
| 1012 | 1042 | ||
| @@ -1019,6 +1049,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
| 1019 | bool is_reusable = true, status = true; | 1049 | bool is_reusable = true, status = true; |
| 1020 | bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false; | 1050 | bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false; |
| 1021 | bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); | 1051 | bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); |
| 1052 | u32 rx_delay = 0; | ||
| 1022 | u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | | 1053 | u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | |
| 1023 | AR_PHY_AGC_CONTROL_FLTR_CAL | | 1054 | AR_PHY_AGC_CONTROL_FLTR_CAL | |
| 1024 | AR_PHY_AGC_CONTROL_PKDET_CAL; | 1055 | AR_PHY_AGC_CONTROL_PKDET_CAL; |
| @@ -1042,17 +1073,22 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
| 1042 | ar9003_hw_rtt_clear_hist(ah); | 1073 | ar9003_hw_rtt_clear_hist(ah); |
| 1043 | } | 1074 | } |
| 1044 | 1075 | ||
| 1045 | if (rtt && !run_rtt_cal) { | 1076 | if (rtt) { |
| 1046 | agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL); | 1077 | if (!run_rtt_cal) { |
| 1047 | agc_supp_cals &= agc_ctrl; | 1078 | agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL); |
| 1048 | agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL | | 1079 | agc_supp_cals &= agc_ctrl; |
| 1049 | AR_PHY_AGC_CONTROL_FLTR_CAL | | 1080 | agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL | |
| 1050 | AR_PHY_AGC_CONTROL_PKDET_CAL); | 1081 | AR_PHY_AGC_CONTROL_FLTR_CAL | |
| 1051 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl); | 1082 | AR_PHY_AGC_CONTROL_PKDET_CAL); |
| 1083 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl); | ||
| 1084 | } else { | ||
| 1085 | if (ah->ah_flags & AH_FASTCC) | ||
| 1086 | run_agc_cal = true; | ||
| 1087 | } | ||
| 1052 | } | 1088 | } |
| 1053 | 1089 | ||
| 1054 | if (ah->enabled_cals & TX_CL_CAL) { | 1090 | if (ah->enabled_cals & TX_CL_CAL) { |
| 1055 | if (caldata && caldata->done_txclcal_once) | 1091 | if (caldata && test_bit(TXCLCAL_DONE, &caldata->cal_flags)) |
| 1056 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, | 1092 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, |
| 1057 | AR_PHY_CL_CAL_ENABLE); | 1093 | AR_PHY_CL_CAL_ENABLE); |
| 1058 | else { | 1094 | else { |
| @@ -1076,14 +1112,14 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
| 1076 | * AGC calibration | 1112 | * AGC calibration |
| 1077 | */ | 1113 | */ |
| 1078 | if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { | 1114 | if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { |
| 1079 | if (caldata && !caldata->done_txiqcal_once) | 1115 | if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) |
| 1080 | REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, | 1116 | REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, |
| 1081 | AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); | 1117 | AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); |
| 1082 | else | 1118 | else |
| 1083 | REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, | 1119 | REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, |
| 1084 | AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); | 1120 | AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); |
| 1085 | txiqcal_done = run_agc_cal = true; | 1121 | txiqcal_done = run_agc_cal = true; |
| 1086 | } else if (caldata && !caldata->done_txiqcal_once) { | 1122 | } else if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) { |
| 1087 | run_agc_cal = true; | 1123 | run_agc_cal = true; |
| 1088 | sep_iq_cal = true; | 1124 | sep_iq_cal = true; |
| 1089 | } | 1125 | } |
| @@ -1099,6 +1135,15 @@ skip_tx_iqcal: | |||
| 1099 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | 1135 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); |
| 1100 | } | 1136 | } |
| 1101 | 1137 | ||
| 1138 | if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { | ||
| 1139 | rx_delay = REG_READ(ah, AR_PHY_RX_DELAY); | ||
| 1140 | /* Disable BB_active */ | ||
| 1141 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | ||
| 1142 | udelay(5); | ||
| 1143 | REG_WRITE(ah, AR_PHY_RX_DELAY, AR_PHY_RX_DELAY_DELAY); | ||
| 1144 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | ||
| 1145 | } | ||
| 1146 | |||
| 1102 | if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { | 1147 | if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { |
| 1103 | /* Calibrate the AGC */ | 1148 | /* Calibrate the AGC */ |
| 1104 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | 1149 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, |
| @@ -1110,7 +1155,12 @@ skip_tx_iqcal: | |||
| 1110 | AR_PHY_AGC_CONTROL_CAL, | 1155 | AR_PHY_AGC_CONTROL_CAL, |
| 1111 | 0, AH_WAIT_TIMEOUT); | 1156 | 0, AH_WAIT_TIMEOUT); |
| 1112 | 1157 | ||
| 1113 | ar9003_hw_do_manual_peak_cal(ah, chan); | 1158 | ar9003_hw_do_manual_peak_cal(ah, chan, run_rtt_cal); |
| 1159 | } | ||
| 1160 | |||
| 1161 | if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { | ||
| 1162 | REG_WRITE(ah, AR_PHY_RX_DELAY, rx_delay); | ||
| 1163 | udelay(5); | ||
| 1114 | } | 1164 | } |
| 1115 | 1165 | ||
| 1116 | if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) | 1166 | if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) |
| @@ -1133,19 +1183,23 @@ skip_tx_iqcal: | |||
| 1133 | 1183 | ||
| 1134 | if (txiqcal_done) | 1184 | if (txiqcal_done) |
| 1135 | ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); | 1185 | ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); |
| 1136 | else if (caldata && caldata->done_txiqcal_once) | 1186 | else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags)) |
| 1137 | ar9003_hw_tx_iq_cal_reload(ah); | 1187 | ar9003_hw_tx_iq_cal_reload(ah); |
| 1138 | 1188 | ||
| 1139 | ar9003_hw_cl_cal_post_proc(ah, is_reusable); | 1189 | ar9003_hw_cl_cal_post_proc(ah, is_reusable); |
| 1140 | 1190 | ||
| 1141 | if (run_rtt_cal && caldata) { | 1191 | if (run_rtt_cal && caldata) { |
| 1142 | if (is_reusable) { | 1192 | if (is_reusable) { |
| 1143 | if (!ath9k_hw_rfbus_req(ah)) | 1193 | if (!ath9k_hw_rfbus_req(ah)) { |
| 1144 | ath_err(ath9k_hw_common(ah), | 1194 | ath_err(ath9k_hw_common(ah), |
| 1145 | "Could not stop baseband\n"); | 1195 | "Could not stop baseband\n"); |
| 1146 | else | 1196 | } else { |
| 1147 | ar9003_hw_rtt_fill_hist(ah); | 1197 | ar9003_hw_rtt_fill_hist(ah); |
| 1148 | 1198 | ||
| 1199 | if (test_bit(SW_PKDET_DONE, &caldata->cal_flags)) | ||
| 1200 | ar9003_hw_rtt_load_hist(ah); | ||
| 1201 | } | ||
| 1202 | |||
| 1149 | ath9k_hw_rfbus_done(ah); | 1203 | ath9k_hw_rfbus_done(ah); |
| 1150 | } | 1204 | } |
| 1151 | 1205 | ||
