aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/calib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/calib.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c59
1 files changed, 58 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index d5026e4f484b..064f5b51dfcd 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -18,6 +18,7 @@
18 18
19/* We can tune this as we go by monitoring really low values */ 19/* We can tune this as we go by monitoring really low values */
20#define ATH9K_NF_TOO_LOW -60 20#define ATH9K_NF_TOO_LOW -60
21#define AR9285_CLCAL_REDO_THRESH 1
21 22
22/* AR5416 may return very high value (like -31 dBm), in those cases the nf 23/* AR5416 may return very high value (like -31 dBm), in those cases the nf
23 * is incorrect and we should use the static NF value. Later we can try to 24 * is incorrect and we should use the static NF value. Later we can try to
@@ -1091,7 +1092,7 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
1091EXPORT_SYMBOL(ath9k_hw_calibrate); 1092EXPORT_SYMBOL(ath9k_hw_calibrate);
1092 1093
1093/* Carrier leakage Calibration fix */ 1094/* Carrier leakage Calibration fix */
1094static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan) 1095static bool ar9285_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
1095{ 1096{
1096 struct ath_common *common = ath9k_hw_common(ah); 1097 struct ath_common *common = ath9k_hw_common(ah);
1097 1098
@@ -1132,6 +1133,62 @@ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
1132 return true; 1133 return true;
1133} 1134}
1134 1135
1136static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
1137{
1138 int i;
1139 u_int32_t txgain_max;
1140 u_int32_t clc_gain, gain_mask = 0, clc_num = 0;
1141 u_int32_t reg_clc_I0, reg_clc_Q0;
1142 u_int32_t i0_num = 0;
1143 u_int32_t q0_num = 0;
1144 u_int32_t total_num = 0;
1145 u_int32_t reg_rf2g5_org;
1146 bool retv = true;
1147
1148 if (!(ar9285_cl_cal(ah, chan)))
1149 return false;
1150
1151 txgain_max = MS(REG_READ(ah, AR_PHY_TX_PWRCTRL7),
1152 AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX);
1153
1154 for (i = 0; i < (txgain_max+1); i++) {
1155 clc_gain = (REG_READ(ah, (AR_PHY_TX_GAIN_TBL1+(i<<2))) &
1156 AR_PHY_TX_GAIN_CLC) >> AR_PHY_TX_GAIN_CLC_S;
1157 if (!(gain_mask & (1 << clc_gain))) {
1158 gain_mask |= (1 << clc_gain);
1159 clc_num++;
1160 }
1161 }
1162
1163 for (i = 0; i < clc_num; i++) {
1164 reg_clc_I0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
1165 & AR_PHY_CLC_I0) >> AR_PHY_CLC_I0_S;
1166 reg_clc_Q0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
1167 & AR_PHY_CLC_Q0) >> AR_PHY_CLC_Q0_S;
1168 if (reg_clc_I0 == 0)
1169 i0_num++;
1170
1171 if (reg_clc_Q0 == 0)
1172 q0_num++;
1173 }
1174 total_num = i0_num + q0_num;
1175 if (total_num > AR9285_CLCAL_REDO_THRESH) {
1176 reg_rf2g5_org = REG_READ(ah, AR9285_RF2G5);
1177 if (AR_SREV_9285E_20(ah)) {
1178 REG_WRITE(ah, AR9285_RF2G5,
1179 (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
1180 AR9285_RF2G5_IC50TX_XE_SET);
1181 } else {
1182 REG_WRITE(ah, AR9285_RF2G5,
1183 (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
1184 AR9285_RF2G5_IC50TX_SET);
1185 }
1186 retv = ar9285_cl_cal(ah, chan);
1187 REG_WRITE(ah, AR9285_RF2G5, reg_rf2g5_org);
1188 }
1189 return retv;
1190}
1191
1135bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) 1192bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
1136{ 1193{
1137 struct ath_common *common = ath9k_hw_common(ah); 1194 struct ath_common *common = ath9k_hw_common(ah);