aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/ar9003_phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_phy.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c213
1 files changed, 24 insertions, 189 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 19bc05c4113..7c93338540a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1015,213 +1015,38 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
1015 return true; 1015 return true;
1016} 1016}
1017 1017
1018static void ar9003_hw_nf_sanitize_2g(struct ath_hw *ah, s16 *nf)
1019{
1020 struct ath_common *common = ath9k_hw_common(ah);
1021
1022 if (*nf > ah->nf_2g_max) {
1023 ath_print(common, ATH_DBG_CALIBRATE,
1024 "2 GHz NF (%d) > MAX (%d), "
1025 "correcting to MAX",
1026 *nf, ah->nf_2g_max);
1027 *nf = ah->nf_2g_max;
1028 } else if (*nf < ah->nf_2g_min) {
1029 ath_print(common, ATH_DBG_CALIBRATE,
1030 "2 GHz NF (%d) < MIN (%d), "
1031 "correcting to MIN",
1032 *nf, ah->nf_2g_min);
1033 *nf = ah->nf_2g_min;
1034 }
1035}
1036
1037static void ar9003_hw_nf_sanitize_5g(struct ath_hw *ah, s16 *nf)
1038{
1039 struct ath_common *common = ath9k_hw_common(ah);
1040
1041 if (*nf > ah->nf_5g_max) {
1042 ath_print(common, ATH_DBG_CALIBRATE,
1043 "5 GHz NF (%d) > MAX (%d), "
1044 "correcting to MAX",
1045 *nf, ah->nf_5g_max);
1046 *nf = ah->nf_5g_max;
1047 } else if (*nf < ah->nf_5g_min) {
1048 ath_print(common, ATH_DBG_CALIBRATE,
1049 "5 GHz NF (%d) < MIN (%d), "
1050 "correcting to MIN",
1051 *nf, ah->nf_5g_min);
1052 *nf = ah->nf_5g_min;
1053 }
1054}
1055
1056static void ar9003_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
1057{
1058 if (IS_CHAN_2GHZ(ah->curchan))
1059 ar9003_hw_nf_sanitize_2g(ah, nf);
1060 else
1061 ar9003_hw_nf_sanitize_5g(ah, nf);
1062}
1063
1064static void ar9003_hw_do_getnf(struct ath_hw *ah, 1018static void ar9003_hw_do_getnf(struct ath_hw *ah,
1065 int16_t nfarray[NUM_NF_READINGS]) 1019 int16_t nfarray[NUM_NF_READINGS])
1066{ 1020{
1067 struct ath_common *common = ath9k_hw_common(ah);
1068 int16_t nf; 1021 int16_t nf;
1069 1022
1070 nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR); 1023 nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);
1071 if (nf & 0x100) 1024 nfarray[0] = sign_extend(nf, 9);
1072 nf = 0 - ((nf ^ 0x1ff) + 1);
1073 ar9003_hw_nf_sanitize(ah, &nf);
1074 ath_print(common, ATH_DBG_CALIBRATE,
1075 "NF calibrated [ctl] [chain 0] is %d\n", nf);
1076 nfarray[0] = nf;
1077 1025
1078 nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR); 1026 nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR);
1079 if (nf & 0x100) 1027 nfarray[1] = sign_extend(nf, 9);
1080 nf = 0 - ((nf ^ 0x1ff) + 1);
1081 ar9003_hw_nf_sanitize(ah, &nf);
1082 ath_print(common, ATH_DBG_CALIBRATE,
1083 "NF calibrated [ctl] [chain 1] is %d\n", nf);
1084 nfarray[1] = nf;
1085 1028
1086 nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR); 1029 nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
1087 if (nf & 0x100) 1030 nfarray[2] = sign_extend(nf, 9);
1088 nf = 0 - ((nf ^ 0x1ff) + 1);
1089 ar9003_hw_nf_sanitize(ah, &nf);
1090 ath_print(common, ATH_DBG_CALIBRATE,
1091 "NF calibrated [ctl] [chain 2] is %d\n", nf);
1092 nfarray[2] = nf;
1093 1031
1094 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); 1032 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
1095 if (nf & 0x100) 1033 nfarray[3] = sign_extend(nf, 9);
1096 nf = 0 - ((nf ^ 0x1ff) + 1);
1097 ar9003_hw_nf_sanitize(ah, &nf);
1098 ath_print(common, ATH_DBG_CALIBRATE,
1099 "NF calibrated [ext] [chain 0] is %d\n", nf);
1100 nfarray[3] = nf;
1101 1034
1102 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR); 1035 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR);
1103 if (nf & 0x100) 1036 nfarray[4] = sign_extend(nf, 9);
1104 nf = 0 - ((nf ^ 0x1ff) + 1);
1105 ar9003_hw_nf_sanitize(ah, &nf);
1106 ath_print(common, ATH_DBG_CALIBRATE,
1107 "NF calibrated [ext] [chain 1] is %d\n", nf);
1108 nfarray[4] = nf;
1109 1037
1110 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR); 1038 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR);
1111 if (nf & 0x100) 1039 nfarray[5] = sign_extend(nf, 9);
1112 nf = 0 - ((nf ^ 0x1ff) + 1);
1113 ar9003_hw_nf_sanitize(ah, &nf);
1114 ath_print(common, ATH_DBG_CALIBRATE,
1115 "NF calibrated [ext] [chain 2] is %d\n", nf);
1116 nfarray[5] = nf;
1117} 1040}
1118 1041
1119void ar9003_hw_set_nf_limits(struct ath_hw *ah) 1042static void ar9003_hw_set_nf_limits(struct ath_hw *ah)
1120{ 1043{
1121 ah->nf_2g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ; 1044 ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ;
1122 ah->nf_2g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ; 1045 ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ;
1123 ah->nf_5g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ; 1046 ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ;
1124 ah->nf_5g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ; 1047 ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ;
1125} 1048 ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
1126 1049 ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ;
1127/*
1128 * Find out which of the RX chains are enabled
1129 */
1130static u32 ar9003_hw_get_rx_chainmask(struct ath_hw *ah)
1131{
1132 u32 chain = REG_READ(ah, AR_PHY_RX_CHAINMASK);
1133 /*
1134 * The bits [2:0] indicate the rx chain mask and are to be
1135 * interpreted as follows:
1136 * 00x => Only chain 0 is enabled
1137 * 01x => Chain 1 and 0 enabled
1138 * 1xx => Chain 2,1 and 0 enabled
1139 */
1140 return chain & 0x7;
1141}
1142
1143static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
1144{
1145 struct ath9k_nfcal_hist *h;
1146 unsigned i, j;
1147 int32_t val;
1148 const u32 ar9300_cca_regs[6] = {
1149 AR_PHY_CCA_0,
1150 AR_PHY_CCA_1,
1151 AR_PHY_CCA_2,
1152 AR_PHY_EXT_CCA,
1153 AR_PHY_EXT_CCA_1,
1154 AR_PHY_EXT_CCA_2,
1155 };
1156 u8 chainmask, rx_chain_status;
1157 struct ath_common *common = ath9k_hw_common(ah);
1158
1159 rx_chain_status = ar9003_hw_get_rx_chainmask(ah);
1160
1161 chainmask = 0x3F;
1162 h = ah->nfCalHist;
1163
1164 for (i = 0; i < NUM_NF_READINGS; i++) {
1165 if (chainmask & (1 << i)) {
1166 val = REG_READ(ah, ar9300_cca_regs[i]);
1167 val &= 0xFFFFFE00;
1168 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
1169 REG_WRITE(ah, ar9300_cca_regs[i], val);
1170 }
1171 }
1172
1173 /*
1174 * Load software filtered NF value into baseband internal minCCApwr
1175 * variable.
1176 */
1177 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1178 AR_PHY_AGC_CONTROL_ENABLE_NF);
1179 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1180 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1181 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1182
1183 /*
1184 * Wait for load to complete, should be fast, a few 10s of us.
1185 * The max delay was changed from an original 250us to 10000us
1186 * since 250us often results in NF load timeout and causes deaf
1187 * condition during stress testing 12/12/2009
1188 */
1189 for (j = 0; j < 1000; j++) {
1190 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
1191 AR_PHY_AGC_CONTROL_NF) == 0)
1192 break;
1193 udelay(10);
1194 }
1195
1196 /*
1197 * We timed out waiting for the noisefloor to load, probably due to an
1198 * in-progress rx. Simply return here and allow the load plenty of time
1199 * to complete before the next calibration interval. We need to avoid
1200 * trying to load -50 (which happens below) while the previous load is
1201 * still in progress as this can cause rx deafness. Instead by returning
1202 * here, the baseband nf cal will just be capped by our present
1203 * noisefloor until the next calibration timer.
1204 */
1205 if (j == 1000) {
1206 ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
1207 "to load: AR_PHY_AGC_CONTROL=0x%x\n",
1208 REG_READ(ah, AR_PHY_AGC_CONTROL));
1209 return;
1210 }
1211
1212 /*
1213 * Restore maxCCAPower register parameter again so that we're not capped
1214 * by the median we just loaded. This will be initial (and max) value
1215 * of next noise floor calibration the baseband does.
1216 */
1217 for (i = 0; i < NUM_NF_READINGS; i++) {
1218 if (chainmask & (1 << i)) {
1219 val = REG_READ(ah, ar9300_cca_regs[i]);
1220 val &= 0xFFFFFE00;
1221 val |= (((u32) (-50) << 1) & 0x1ff);
1222 REG_WRITE(ah, ar9300_cca_regs[i], val);
1223 }
1224 }
1225} 1050}
1226 1051
1227/* 1052/*
@@ -1291,6 +1116,14 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1291void ar9003_hw_attach_phy_ops(struct ath_hw *ah) 1116void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1292{ 1117{
1293 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1118 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1119 const u32 ar9300_cca_regs[6] = {
1120 AR_PHY_CCA_0,
1121 AR_PHY_CCA_1,
1122 AR_PHY_CCA_2,
1123 AR_PHY_EXT_CCA,
1124 AR_PHY_EXT_CCA_1,
1125 AR_PHY_EXT_CCA_2,
1126 };
1294 1127
1295 priv_ops->rf_set_freq = ar9003_hw_set_channel; 1128 priv_ops->rf_set_freq = ar9003_hw_set_channel;
1296 priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate; 1129 priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate;
@@ -1307,8 +1140,10 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1307 priv_ops->set_diversity = ar9003_hw_set_diversity; 1140 priv_ops->set_diversity = ar9003_hw_set_diversity;
1308 priv_ops->ani_control = ar9003_hw_ani_control; 1141 priv_ops->ani_control = ar9003_hw_ani_control;
1309 priv_ops->do_getnf = ar9003_hw_do_getnf; 1142 priv_ops->do_getnf = ar9003_hw_do_getnf;
1310 priv_ops->loadnf = ar9003_hw_loadnf;
1311 priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; 1143 priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
1144
1145 ar9003_hw_set_nf_limits(ah);
1146 memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
1312} 1147}
1313 1148
1314void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) 1149void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)