diff options
author | Sujith Manoharan <c_manoha@qca.qualcomm.com> | 2012-06-04 10:53:49 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-06-06 15:20:31 -0400 |
commit | 8da07830e10a91cbe7badf9767230aafdd520b9c (patch) | |
tree | fd71bd855f0a1f2372756622e5a3e443c09a631f /drivers/net/wireless/ath/ath9k/recv.c | |
parent | af68abadac378f7a4a44fe766383e7b88c7f9c3b (diff) |
ath9k: Move LNA code to antenna.c
And use a helper function to setup antennae after a reset.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/recv.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 740 |
1 files changed, 0 insertions, 740 deletions
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 611be4f934e7..c2f5fd1c8b87 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -20,43 +20,6 @@ | |||
20 | 20 | ||
21 | #define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb)) | 21 | #define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb)) |
22 | 22 | ||
23 | static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, | ||
24 | int mindelta, int main_rssi_avg, | ||
25 | int alt_rssi_avg, int pkt_count) | ||
26 | { | ||
27 | return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
28 | (alt_rssi_avg > main_rssi_avg + maxdelta)) || | ||
29 | (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); | ||
30 | } | ||
31 | |||
32 | static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio, | ||
33 | int curr_main_set, int curr_alt_set, | ||
34 | int alt_rssi_avg, int main_rssi_avg) | ||
35 | { | ||
36 | bool result = false; | ||
37 | switch (div_group) { | ||
38 | case 0: | ||
39 | if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) | ||
40 | result = true; | ||
41 | break; | ||
42 | case 1: | ||
43 | case 2: | ||
44 | if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) && | ||
45 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) && | ||
46 | (alt_rssi_avg >= (main_rssi_avg - 5))) || | ||
47 | ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) && | ||
48 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) && | ||
49 | (alt_rssi_avg >= (main_rssi_avg - 2)))) && | ||
50 | (alt_rssi_avg >= 4)) | ||
51 | result = true; | ||
52 | else | ||
53 | result = false; | ||
54 | break; | ||
55 | } | ||
56 | |||
57 | return result; | ||
58 | } | ||
59 | |||
60 | static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) | 23 | static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) |
61 | { | 24 | { |
62 | return sc->ps_enabled && | 25 | return sc->ps_enabled && |
@@ -1067,709 +1030,6 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, | |||
1067 | rxs->flag &= ~RX_FLAG_DECRYPTED; | 1030 | rxs->flag &= ~RX_FLAG_DECRYPTED; |
1068 | } | 1031 | } |
1069 | 1032 | ||
1070 | static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb, | ||
1071 | struct ath_hw_antcomb_conf ant_conf, | ||
1072 | int main_rssi_avg) | ||
1073 | { | ||
1074 | antcomb->quick_scan_cnt = 0; | ||
1075 | |||
1076 | if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA2) | ||
1077 | antcomb->rssi_lna2 = main_rssi_avg; | ||
1078 | else if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA1) | ||
1079 | antcomb->rssi_lna1 = main_rssi_avg; | ||
1080 | |||
1081 | switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) { | ||
1082 | case 0x10: /* LNA2 A-B */ | ||
1083 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1084 | antcomb->first_quick_scan_conf = | ||
1085 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1086 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; | ||
1087 | break; | ||
1088 | case 0x20: /* LNA1 A-B */ | ||
1089 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1090 | antcomb->first_quick_scan_conf = | ||
1091 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1092 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1093 | break; | ||
1094 | case 0x21: /* LNA1 LNA2 */ | ||
1095 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1096 | antcomb->first_quick_scan_conf = | ||
1097 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1098 | antcomb->second_quick_scan_conf = | ||
1099 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1100 | break; | ||
1101 | case 0x12: /* LNA2 LNA1 */ | ||
1102 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1; | ||
1103 | antcomb->first_quick_scan_conf = | ||
1104 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1105 | antcomb->second_quick_scan_conf = | ||
1106 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1107 | break; | ||
1108 | case 0x13: /* LNA2 A+B */ | ||
1109 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1110 | antcomb->first_quick_scan_conf = | ||
1111 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1112 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; | ||
1113 | break; | ||
1114 | case 0x23: /* LNA1 A+B */ | ||
1115 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1116 | antcomb->first_quick_scan_conf = | ||
1117 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1118 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1119 | break; | ||
1120 | default: | ||
1121 | break; | ||
1122 | } | ||
1123 | } | ||
1124 | |||
1125 | static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, | ||
1126 | struct ath_hw_antcomb_conf *div_ant_conf, | ||
1127 | int main_rssi_avg, int alt_rssi_avg, | ||
1128 | int alt_ratio) | ||
1129 | { | ||
1130 | /* alt_good */ | ||
1131 | switch (antcomb->quick_scan_cnt) { | ||
1132 | case 0: | ||
1133 | /* set alt to main, and alt to first conf */ | ||
1134 | div_ant_conf->main_lna_conf = antcomb->main_conf; | ||
1135 | div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf; | ||
1136 | break; | ||
1137 | case 1: | ||
1138 | /* set alt to main, and alt to first conf */ | ||
1139 | div_ant_conf->main_lna_conf = antcomb->main_conf; | ||
1140 | div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf; | ||
1141 | antcomb->rssi_first = main_rssi_avg; | ||
1142 | antcomb->rssi_second = alt_rssi_avg; | ||
1143 | |||
1144 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { | ||
1145 | /* main is LNA1 */ | ||
1146 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
1147 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI, | ||
1148 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
1149 | main_rssi_avg, alt_rssi_avg, | ||
1150 | antcomb->total_pkt_count)) | ||
1151 | antcomb->first_ratio = true; | ||
1152 | else | ||
1153 | antcomb->first_ratio = false; | ||
1154 | } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { | ||
1155 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
1156 | ATH_ANT_DIV_COMB_LNA1_DELTA_MID, | ||
1157 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
1158 | main_rssi_avg, alt_rssi_avg, | ||
1159 | antcomb->total_pkt_count)) | ||
1160 | antcomb->first_ratio = true; | ||
1161 | else | ||
1162 | antcomb->first_ratio = false; | ||
1163 | } else { | ||
1164 | if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
1165 | (alt_rssi_avg > main_rssi_avg + | ||
1166 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || | ||
1167 | (alt_rssi_avg > main_rssi_avg)) && | ||
1168 | (antcomb->total_pkt_count > 50)) | ||
1169 | antcomb->first_ratio = true; | ||
1170 | else | ||
1171 | antcomb->first_ratio = false; | ||
1172 | } | ||
1173 | break; | ||
1174 | case 2: | ||
1175 | antcomb->alt_good = false; | ||
1176 | antcomb->scan_not_start = false; | ||
1177 | antcomb->scan = false; | ||
1178 | antcomb->rssi_first = main_rssi_avg; | ||
1179 | antcomb->rssi_third = alt_rssi_avg; | ||
1180 | |||
1181 | if (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) | ||
1182 | antcomb->rssi_lna1 = alt_rssi_avg; | ||
1183 | else if (antcomb->second_quick_scan_conf == | ||
1184 | ATH_ANT_DIV_COMB_LNA2) | ||
1185 | antcomb->rssi_lna2 = alt_rssi_avg; | ||
1186 | else if (antcomb->second_quick_scan_conf == | ||
1187 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2) { | ||
1188 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) | ||
1189 | antcomb->rssi_lna2 = main_rssi_avg; | ||
1190 | else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) | ||
1191 | antcomb->rssi_lna1 = main_rssi_avg; | ||
1192 | } | ||
1193 | |||
1194 | if (antcomb->rssi_lna2 > antcomb->rssi_lna1 + | ||
1195 | ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA) | ||
1196 | div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1197 | else | ||
1198 | div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; | ||
1199 | |||
1200 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { | ||
1201 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
1202 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI, | ||
1203 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
1204 | main_rssi_avg, alt_rssi_avg, | ||
1205 | antcomb->total_pkt_count)) | ||
1206 | antcomb->second_ratio = true; | ||
1207 | else | ||
1208 | antcomb->second_ratio = false; | ||
1209 | } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { | ||
1210 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
1211 | ATH_ANT_DIV_COMB_LNA1_DELTA_MID, | ||
1212 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
1213 | main_rssi_avg, alt_rssi_avg, | ||
1214 | antcomb->total_pkt_count)) | ||
1215 | antcomb->second_ratio = true; | ||
1216 | else | ||
1217 | antcomb->second_ratio = false; | ||
1218 | } else { | ||
1219 | if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
1220 | (alt_rssi_avg > main_rssi_avg + | ||
1221 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || | ||
1222 | (alt_rssi_avg > main_rssi_avg)) && | ||
1223 | (antcomb->total_pkt_count > 50)) | ||
1224 | antcomb->second_ratio = true; | ||
1225 | else | ||
1226 | antcomb->second_ratio = false; | ||
1227 | } | ||
1228 | |||
1229 | /* set alt to the conf with maximun ratio */ | ||
1230 | if (antcomb->first_ratio && antcomb->second_ratio) { | ||
1231 | if (antcomb->rssi_second > antcomb->rssi_third) { | ||
1232 | /* first alt*/ | ||
1233 | if ((antcomb->first_quick_scan_conf == | ||
1234 | ATH_ANT_DIV_COMB_LNA1) || | ||
1235 | (antcomb->first_quick_scan_conf == | ||
1236 | ATH_ANT_DIV_COMB_LNA2)) | ||
1237 | /* Set alt LNA1 or LNA2*/ | ||
1238 | if (div_ant_conf->main_lna_conf == | ||
1239 | ATH_ANT_DIV_COMB_LNA2) | ||
1240 | div_ant_conf->alt_lna_conf = | ||
1241 | ATH_ANT_DIV_COMB_LNA1; | ||
1242 | else | ||
1243 | div_ant_conf->alt_lna_conf = | ||
1244 | ATH_ANT_DIV_COMB_LNA2; | ||
1245 | else | ||
1246 | /* Set alt to A+B or A-B */ | ||
1247 | div_ant_conf->alt_lna_conf = | ||
1248 | antcomb->first_quick_scan_conf; | ||
1249 | } else if ((antcomb->second_quick_scan_conf == | ||
1250 | ATH_ANT_DIV_COMB_LNA1) || | ||
1251 | (antcomb->second_quick_scan_conf == | ||
1252 | ATH_ANT_DIV_COMB_LNA2)) { | ||
1253 | /* Set alt LNA1 or LNA2 */ | ||
1254 | if (div_ant_conf->main_lna_conf == | ||
1255 | ATH_ANT_DIV_COMB_LNA2) | ||
1256 | div_ant_conf->alt_lna_conf = | ||
1257 | ATH_ANT_DIV_COMB_LNA1; | ||
1258 | else | ||
1259 | div_ant_conf->alt_lna_conf = | ||
1260 | ATH_ANT_DIV_COMB_LNA2; | ||
1261 | } else { | ||
1262 | /* Set alt to A+B or A-B */ | ||
1263 | div_ant_conf->alt_lna_conf = | ||
1264 | antcomb->second_quick_scan_conf; | ||
1265 | } | ||
1266 | } else if (antcomb->first_ratio) { | ||
1267 | /* first alt */ | ||
1268 | if ((antcomb->first_quick_scan_conf == | ||
1269 | ATH_ANT_DIV_COMB_LNA1) || | ||
1270 | (antcomb->first_quick_scan_conf == | ||
1271 | ATH_ANT_DIV_COMB_LNA2)) | ||
1272 | /* Set alt LNA1 or LNA2 */ | ||
1273 | if (div_ant_conf->main_lna_conf == | ||
1274 | ATH_ANT_DIV_COMB_LNA2) | ||
1275 | div_ant_conf->alt_lna_conf = | ||
1276 | ATH_ANT_DIV_COMB_LNA1; | ||
1277 | else | ||
1278 | div_ant_conf->alt_lna_conf = | ||
1279 | ATH_ANT_DIV_COMB_LNA2; | ||
1280 | else | ||
1281 | /* Set alt to A+B or A-B */ | ||
1282 | div_ant_conf->alt_lna_conf = | ||
1283 | antcomb->first_quick_scan_conf; | ||
1284 | } else if (antcomb->second_ratio) { | ||
1285 | /* second alt */ | ||
1286 | if ((antcomb->second_quick_scan_conf == | ||
1287 | ATH_ANT_DIV_COMB_LNA1) || | ||
1288 | (antcomb->second_quick_scan_conf == | ||
1289 | ATH_ANT_DIV_COMB_LNA2)) | ||
1290 | /* Set alt LNA1 or LNA2 */ | ||
1291 | if (div_ant_conf->main_lna_conf == | ||
1292 | ATH_ANT_DIV_COMB_LNA2) | ||
1293 | div_ant_conf->alt_lna_conf = | ||
1294 | ATH_ANT_DIV_COMB_LNA1; | ||
1295 | else | ||
1296 | div_ant_conf->alt_lna_conf = | ||
1297 | ATH_ANT_DIV_COMB_LNA2; | ||
1298 | else | ||
1299 | /* Set alt to A+B or A-B */ | ||
1300 | div_ant_conf->alt_lna_conf = | ||
1301 | antcomb->second_quick_scan_conf; | ||
1302 | } else { | ||
1303 | /* main is largest */ | ||
1304 | if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) || | ||
1305 | (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)) | ||
1306 | /* Set alt LNA1 or LNA2 */ | ||
1307 | if (div_ant_conf->main_lna_conf == | ||
1308 | ATH_ANT_DIV_COMB_LNA2) | ||
1309 | div_ant_conf->alt_lna_conf = | ||
1310 | ATH_ANT_DIV_COMB_LNA1; | ||
1311 | else | ||
1312 | div_ant_conf->alt_lna_conf = | ||
1313 | ATH_ANT_DIV_COMB_LNA2; | ||
1314 | else | ||
1315 | /* Set alt to A+B or A-B */ | ||
1316 | div_ant_conf->alt_lna_conf = antcomb->main_conf; | ||
1317 | } | ||
1318 | break; | ||
1319 | default: | ||
1320 | break; | ||
1321 | } | ||
1322 | } | ||
1323 | |||
1324 | static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, | ||
1325 | struct ath_ant_comb *antcomb, int alt_ratio) | ||
1326 | { | ||
1327 | if (ant_conf->div_group == 0) { | ||
1328 | /* Adjust the fast_div_bias based on main and alt lna conf */ | ||
1329 | switch ((ant_conf->main_lna_conf << 4) | | ||
1330 | ant_conf->alt_lna_conf) { | ||
1331 | case 0x01: /* A-B LNA2 */ | ||
1332 | ant_conf->fast_div_bias = 0x3b; | ||
1333 | break; | ||
1334 | case 0x02: /* A-B LNA1 */ | ||
1335 | ant_conf->fast_div_bias = 0x3d; | ||
1336 | break; | ||
1337 | case 0x03: /* A-B A+B */ | ||
1338 | ant_conf->fast_div_bias = 0x1; | ||
1339 | break; | ||
1340 | case 0x10: /* LNA2 A-B */ | ||
1341 | ant_conf->fast_div_bias = 0x7; | ||
1342 | break; | ||
1343 | case 0x12: /* LNA2 LNA1 */ | ||
1344 | ant_conf->fast_div_bias = 0x2; | ||
1345 | break; | ||
1346 | case 0x13: /* LNA2 A+B */ | ||
1347 | ant_conf->fast_div_bias = 0x7; | ||
1348 | break; | ||
1349 | case 0x20: /* LNA1 A-B */ | ||
1350 | ant_conf->fast_div_bias = 0x6; | ||
1351 | break; | ||
1352 | case 0x21: /* LNA1 LNA2 */ | ||
1353 | ant_conf->fast_div_bias = 0x0; | ||
1354 | break; | ||
1355 | case 0x23: /* LNA1 A+B */ | ||
1356 | ant_conf->fast_div_bias = 0x6; | ||
1357 | break; | ||
1358 | case 0x30: /* A+B A-B */ | ||
1359 | ant_conf->fast_div_bias = 0x1; | ||
1360 | break; | ||
1361 | case 0x31: /* A+B LNA2 */ | ||
1362 | ant_conf->fast_div_bias = 0x3b; | ||
1363 | break; | ||
1364 | case 0x32: /* A+B LNA1 */ | ||
1365 | ant_conf->fast_div_bias = 0x3d; | ||
1366 | break; | ||
1367 | default: | ||
1368 | break; | ||
1369 | } | ||
1370 | } else if (ant_conf->div_group == 1) { | ||
1371 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | ||
1372 | switch ((ant_conf->main_lna_conf << 4) | | ||
1373 | ant_conf->alt_lna_conf) { | ||
1374 | case 0x01: /* A-B LNA2 */ | ||
1375 | ant_conf->fast_div_bias = 0x1; | ||
1376 | ant_conf->main_gaintb = 0; | ||
1377 | ant_conf->alt_gaintb = 0; | ||
1378 | break; | ||
1379 | case 0x02: /* A-B LNA1 */ | ||
1380 | ant_conf->fast_div_bias = 0x1; | ||
1381 | ant_conf->main_gaintb = 0; | ||
1382 | ant_conf->alt_gaintb = 0; | ||
1383 | break; | ||
1384 | case 0x03: /* A-B A+B */ | ||
1385 | ant_conf->fast_div_bias = 0x1; | ||
1386 | ant_conf->main_gaintb = 0; | ||
1387 | ant_conf->alt_gaintb = 0; | ||
1388 | break; | ||
1389 | case 0x10: /* LNA2 A-B */ | ||
1390 | if (!(antcomb->scan) && | ||
1391 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1392 | ant_conf->fast_div_bias = 0x3f; | ||
1393 | else | ||
1394 | ant_conf->fast_div_bias = 0x1; | ||
1395 | ant_conf->main_gaintb = 0; | ||
1396 | ant_conf->alt_gaintb = 0; | ||
1397 | break; | ||
1398 | case 0x12: /* LNA2 LNA1 */ | ||
1399 | ant_conf->fast_div_bias = 0x1; | ||
1400 | ant_conf->main_gaintb = 0; | ||
1401 | ant_conf->alt_gaintb = 0; | ||
1402 | break; | ||
1403 | case 0x13: /* LNA2 A+B */ | ||
1404 | if (!(antcomb->scan) && | ||
1405 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1406 | ant_conf->fast_div_bias = 0x3f; | ||
1407 | else | ||
1408 | ant_conf->fast_div_bias = 0x1; | ||
1409 | ant_conf->main_gaintb = 0; | ||
1410 | ant_conf->alt_gaintb = 0; | ||
1411 | break; | ||
1412 | case 0x20: /* LNA1 A-B */ | ||
1413 | if (!(antcomb->scan) && | ||
1414 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1415 | ant_conf->fast_div_bias = 0x3f; | ||
1416 | else | ||
1417 | ant_conf->fast_div_bias = 0x1; | ||
1418 | ant_conf->main_gaintb = 0; | ||
1419 | ant_conf->alt_gaintb = 0; | ||
1420 | break; | ||
1421 | case 0x21: /* LNA1 LNA2 */ | ||
1422 | ant_conf->fast_div_bias = 0x1; | ||
1423 | ant_conf->main_gaintb = 0; | ||
1424 | ant_conf->alt_gaintb = 0; | ||
1425 | break; | ||
1426 | case 0x23: /* LNA1 A+B */ | ||
1427 | if (!(antcomb->scan) && | ||
1428 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1429 | ant_conf->fast_div_bias = 0x3f; | ||
1430 | else | ||
1431 | ant_conf->fast_div_bias = 0x1; | ||
1432 | ant_conf->main_gaintb = 0; | ||
1433 | ant_conf->alt_gaintb = 0; | ||
1434 | break; | ||
1435 | case 0x30: /* A+B A-B */ | ||
1436 | ant_conf->fast_div_bias = 0x1; | ||
1437 | ant_conf->main_gaintb = 0; | ||
1438 | ant_conf->alt_gaintb = 0; | ||
1439 | break; | ||
1440 | case 0x31: /* A+B LNA2 */ | ||
1441 | ant_conf->fast_div_bias = 0x1; | ||
1442 | ant_conf->main_gaintb = 0; | ||
1443 | ant_conf->alt_gaintb = 0; | ||
1444 | break; | ||
1445 | case 0x32: /* A+B LNA1 */ | ||
1446 | ant_conf->fast_div_bias = 0x1; | ||
1447 | ant_conf->main_gaintb = 0; | ||
1448 | ant_conf->alt_gaintb = 0; | ||
1449 | break; | ||
1450 | default: | ||
1451 | break; | ||
1452 | } | ||
1453 | } else if (ant_conf->div_group == 2) { | ||
1454 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | ||
1455 | switch ((ant_conf->main_lna_conf << 4) | | ||
1456 | ant_conf->alt_lna_conf) { | ||
1457 | case 0x01: /* A-B LNA2 */ | ||
1458 | ant_conf->fast_div_bias = 0x1; | ||
1459 | ant_conf->main_gaintb = 0; | ||
1460 | ant_conf->alt_gaintb = 0; | ||
1461 | break; | ||
1462 | case 0x02: /* A-B LNA1 */ | ||
1463 | ant_conf->fast_div_bias = 0x1; | ||
1464 | ant_conf->main_gaintb = 0; | ||
1465 | ant_conf->alt_gaintb = 0; | ||
1466 | break; | ||
1467 | case 0x03: /* A-B A+B */ | ||
1468 | ant_conf->fast_div_bias = 0x1; | ||
1469 | ant_conf->main_gaintb = 0; | ||
1470 | ant_conf->alt_gaintb = 0; | ||
1471 | break; | ||
1472 | case 0x10: /* LNA2 A-B */ | ||
1473 | if (!(antcomb->scan) && | ||
1474 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1475 | ant_conf->fast_div_bias = 0x1; | ||
1476 | else | ||
1477 | ant_conf->fast_div_bias = 0x2; | ||
1478 | ant_conf->main_gaintb = 0; | ||
1479 | ant_conf->alt_gaintb = 0; | ||
1480 | break; | ||
1481 | case 0x12: /* LNA2 LNA1 */ | ||
1482 | ant_conf->fast_div_bias = 0x1; | ||
1483 | ant_conf->main_gaintb = 0; | ||
1484 | ant_conf->alt_gaintb = 0; | ||
1485 | break; | ||
1486 | case 0x13: /* LNA2 A+B */ | ||
1487 | if (!(antcomb->scan) && | ||
1488 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1489 | ant_conf->fast_div_bias = 0x1; | ||
1490 | else | ||
1491 | ant_conf->fast_div_bias = 0x2; | ||
1492 | ant_conf->main_gaintb = 0; | ||
1493 | ant_conf->alt_gaintb = 0; | ||
1494 | break; | ||
1495 | case 0x20: /* LNA1 A-B */ | ||
1496 | if (!(antcomb->scan) && | ||
1497 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1498 | ant_conf->fast_div_bias = 0x1; | ||
1499 | else | ||
1500 | ant_conf->fast_div_bias = 0x2; | ||
1501 | ant_conf->main_gaintb = 0; | ||
1502 | ant_conf->alt_gaintb = 0; | ||
1503 | break; | ||
1504 | case 0x21: /* LNA1 LNA2 */ | ||
1505 | ant_conf->fast_div_bias = 0x1; | ||
1506 | ant_conf->main_gaintb = 0; | ||
1507 | ant_conf->alt_gaintb = 0; | ||
1508 | break; | ||
1509 | case 0x23: /* LNA1 A+B */ | ||
1510 | if (!(antcomb->scan) && | ||
1511 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1512 | ant_conf->fast_div_bias = 0x1; | ||
1513 | else | ||
1514 | ant_conf->fast_div_bias = 0x2; | ||
1515 | ant_conf->main_gaintb = 0; | ||
1516 | ant_conf->alt_gaintb = 0; | ||
1517 | break; | ||
1518 | case 0x30: /* A+B A-B */ | ||
1519 | ant_conf->fast_div_bias = 0x1; | ||
1520 | ant_conf->main_gaintb = 0; | ||
1521 | ant_conf->alt_gaintb = 0; | ||
1522 | break; | ||
1523 | case 0x31: /* A+B LNA2 */ | ||
1524 | ant_conf->fast_div_bias = 0x1; | ||
1525 | ant_conf->main_gaintb = 0; | ||
1526 | ant_conf->alt_gaintb = 0; | ||
1527 | break; | ||
1528 | case 0x32: /* A+B LNA1 */ | ||
1529 | ant_conf->fast_div_bias = 0x1; | ||
1530 | ant_conf->main_gaintb = 0; | ||
1531 | ant_conf->alt_gaintb = 0; | ||
1532 | break; | ||
1533 | default: | ||
1534 | break; | ||
1535 | } | ||
1536 | } | ||
1537 | } | ||
1538 | |||
1539 | /* Antenna diversity and combining */ | ||
1540 | static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | ||
1541 | { | ||
1542 | struct ath_hw_antcomb_conf div_ant_conf; | ||
1543 | struct ath_ant_comb *antcomb = &sc->ant_comb; | ||
1544 | int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; | ||
1545 | int curr_main_set; | ||
1546 | int main_rssi = rs->rs_rssi_ctl0; | ||
1547 | int alt_rssi = rs->rs_rssi_ctl1; | ||
1548 | int rx_ant_conf, main_ant_conf; | ||
1549 | bool short_scan = false; | ||
1550 | |||
1551 | rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & | ||
1552 | ATH_ANT_RX_MASK; | ||
1553 | main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & | ||
1554 | ATH_ANT_RX_MASK; | ||
1555 | |||
1556 | /* Record packet only when both main_rssi and alt_rssi is positive */ | ||
1557 | if (main_rssi > 0 && alt_rssi > 0) { | ||
1558 | antcomb->total_pkt_count++; | ||
1559 | antcomb->main_total_rssi += main_rssi; | ||
1560 | antcomb->alt_total_rssi += alt_rssi; | ||
1561 | if (main_ant_conf == rx_ant_conf) | ||
1562 | antcomb->main_recv_cnt++; | ||
1563 | else | ||
1564 | antcomb->alt_recv_cnt++; | ||
1565 | } | ||
1566 | |||
1567 | /* Short scan check */ | ||
1568 | if (antcomb->scan && antcomb->alt_good) { | ||
1569 | if (time_after(jiffies, antcomb->scan_start_time + | ||
1570 | msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR))) | ||
1571 | short_scan = true; | ||
1572 | else | ||
1573 | if (antcomb->total_pkt_count == | ||
1574 | ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) { | ||
1575 | alt_ratio = ((antcomb->alt_recv_cnt * 100) / | ||
1576 | antcomb->total_pkt_count); | ||
1577 | if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO) | ||
1578 | short_scan = true; | ||
1579 | } | ||
1580 | } | ||
1581 | |||
1582 | if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) || | ||
1583 | rs->rs_moreaggr) && !short_scan) | ||
1584 | return; | ||
1585 | |||
1586 | if (antcomb->total_pkt_count) { | ||
1587 | alt_ratio = ((antcomb->alt_recv_cnt * 100) / | ||
1588 | antcomb->total_pkt_count); | ||
1589 | main_rssi_avg = (antcomb->main_total_rssi / | ||
1590 | antcomb->total_pkt_count); | ||
1591 | alt_rssi_avg = (antcomb->alt_total_rssi / | ||
1592 | antcomb->total_pkt_count); | ||
1593 | } | ||
1594 | |||
1595 | |||
1596 | ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); | ||
1597 | curr_alt_set = div_ant_conf.alt_lna_conf; | ||
1598 | curr_main_set = div_ant_conf.main_lna_conf; | ||
1599 | |||
1600 | antcomb->count++; | ||
1601 | |||
1602 | if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) { | ||
1603 | if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { | ||
1604 | ath_lnaconf_alt_good_scan(antcomb, div_ant_conf, | ||
1605 | main_rssi_avg); | ||
1606 | antcomb->alt_good = true; | ||
1607 | } else { | ||
1608 | antcomb->alt_good = false; | ||
1609 | } | ||
1610 | |||
1611 | antcomb->count = 0; | ||
1612 | antcomb->scan = true; | ||
1613 | antcomb->scan_not_start = true; | ||
1614 | } | ||
1615 | |||
1616 | if (!antcomb->scan) { | ||
1617 | if (ath_ant_div_comb_alt_check(div_ant_conf.div_group, | ||
1618 | alt_ratio, curr_main_set, curr_alt_set, | ||
1619 | alt_rssi_avg, main_rssi_avg)) { | ||
1620 | if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { | ||
1621 | /* Switch main and alt LNA */ | ||
1622 | div_ant_conf.main_lna_conf = | ||
1623 | ATH_ANT_DIV_COMB_LNA2; | ||
1624 | div_ant_conf.alt_lna_conf = | ||
1625 | ATH_ANT_DIV_COMB_LNA1; | ||
1626 | } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) { | ||
1627 | div_ant_conf.main_lna_conf = | ||
1628 | ATH_ANT_DIV_COMB_LNA1; | ||
1629 | div_ant_conf.alt_lna_conf = | ||
1630 | ATH_ANT_DIV_COMB_LNA2; | ||
1631 | } | ||
1632 | |||
1633 | goto div_comb_done; | ||
1634 | } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) && | ||
1635 | (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) { | ||
1636 | /* Set alt to another LNA */ | ||
1637 | if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) | ||
1638 | div_ant_conf.alt_lna_conf = | ||
1639 | ATH_ANT_DIV_COMB_LNA1; | ||
1640 | else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) | ||
1641 | div_ant_conf.alt_lna_conf = | ||
1642 | ATH_ANT_DIV_COMB_LNA2; | ||
1643 | |||
1644 | goto div_comb_done; | ||
1645 | } | ||
1646 | |||
1647 | if ((alt_rssi_avg < (main_rssi_avg + | ||
1648 | div_ant_conf.lna1_lna2_delta))) | ||
1649 | goto div_comb_done; | ||
1650 | } | ||
1651 | |||
1652 | if (!antcomb->scan_not_start) { | ||
1653 | switch (curr_alt_set) { | ||
1654 | case ATH_ANT_DIV_COMB_LNA2: | ||
1655 | antcomb->rssi_lna2 = alt_rssi_avg; | ||
1656 | antcomb->rssi_lna1 = main_rssi_avg; | ||
1657 | antcomb->scan = true; | ||
1658 | /* set to A+B */ | ||
1659 | div_ant_conf.main_lna_conf = | ||
1660 | ATH_ANT_DIV_COMB_LNA1; | ||
1661 | div_ant_conf.alt_lna_conf = | ||
1662 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1663 | break; | ||
1664 | case ATH_ANT_DIV_COMB_LNA1: | ||
1665 | antcomb->rssi_lna1 = alt_rssi_avg; | ||
1666 | antcomb->rssi_lna2 = main_rssi_avg; | ||
1667 | antcomb->scan = true; | ||
1668 | /* set to A+B */ | ||
1669 | div_ant_conf.main_lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1670 | div_ant_conf.alt_lna_conf = | ||
1671 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1672 | break; | ||
1673 | case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2: | ||
1674 | antcomb->rssi_add = alt_rssi_avg; | ||
1675 | antcomb->scan = true; | ||
1676 | /* set to A-B */ | ||
1677 | div_ant_conf.alt_lna_conf = | ||
1678 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1679 | break; | ||
1680 | case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2: | ||
1681 | antcomb->rssi_sub = alt_rssi_avg; | ||
1682 | antcomb->scan = false; | ||
1683 | if (antcomb->rssi_lna2 > | ||
1684 | (antcomb->rssi_lna1 + | ||
1685 | ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) { | ||
1686 | /* use LNA2 as main LNA */ | ||
1687 | if ((antcomb->rssi_add > antcomb->rssi_lna1) && | ||
1688 | (antcomb->rssi_add > antcomb->rssi_sub)) { | ||
1689 | /* set to A+B */ | ||
1690 | div_ant_conf.main_lna_conf = | ||
1691 | ATH_ANT_DIV_COMB_LNA2; | ||
1692 | div_ant_conf.alt_lna_conf = | ||
1693 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1694 | } else if (antcomb->rssi_sub > | ||
1695 | antcomb->rssi_lna1) { | ||
1696 | /* set to A-B */ | ||
1697 | div_ant_conf.main_lna_conf = | ||
1698 | ATH_ANT_DIV_COMB_LNA2; | ||
1699 | div_ant_conf.alt_lna_conf = | ||
1700 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1701 | } else { | ||
1702 | /* set to LNA1 */ | ||
1703 | div_ant_conf.main_lna_conf = | ||
1704 | ATH_ANT_DIV_COMB_LNA2; | ||
1705 | div_ant_conf.alt_lna_conf = | ||
1706 | ATH_ANT_DIV_COMB_LNA1; | ||
1707 | } | ||
1708 | } else { | ||
1709 | /* use LNA1 as main LNA */ | ||
1710 | if ((antcomb->rssi_add > antcomb->rssi_lna2) && | ||
1711 | (antcomb->rssi_add > antcomb->rssi_sub)) { | ||
1712 | /* set to A+B */ | ||
1713 | div_ant_conf.main_lna_conf = | ||
1714 | ATH_ANT_DIV_COMB_LNA1; | ||
1715 | div_ant_conf.alt_lna_conf = | ||
1716 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1717 | } else if (antcomb->rssi_sub > | ||
1718 | antcomb->rssi_lna1) { | ||
1719 | /* set to A-B */ | ||
1720 | div_ant_conf.main_lna_conf = | ||
1721 | ATH_ANT_DIV_COMB_LNA1; | ||
1722 | div_ant_conf.alt_lna_conf = | ||
1723 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1724 | } else { | ||
1725 | /* set to LNA2 */ | ||
1726 | div_ant_conf.main_lna_conf = | ||
1727 | ATH_ANT_DIV_COMB_LNA1; | ||
1728 | div_ant_conf.alt_lna_conf = | ||
1729 | ATH_ANT_DIV_COMB_LNA2; | ||
1730 | } | ||
1731 | } | ||
1732 | break; | ||
1733 | default: | ||
1734 | break; | ||
1735 | } | ||
1736 | } else { | ||
1737 | if (!antcomb->alt_good) { | ||
1738 | antcomb->scan_not_start = false; | ||
1739 | /* Set alt to another LNA */ | ||
1740 | if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) { | ||
1741 | div_ant_conf.main_lna_conf = | ||
1742 | ATH_ANT_DIV_COMB_LNA2; | ||
1743 | div_ant_conf.alt_lna_conf = | ||
1744 | ATH_ANT_DIV_COMB_LNA1; | ||
1745 | } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) { | ||
1746 | div_ant_conf.main_lna_conf = | ||
1747 | ATH_ANT_DIV_COMB_LNA1; | ||
1748 | div_ant_conf.alt_lna_conf = | ||
1749 | ATH_ANT_DIV_COMB_LNA2; | ||
1750 | } | ||
1751 | goto div_comb_done; | ||
1752 | } | ||
1753 | } | ||
1754 | |||
1755 | ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf, | ||
1756 | main_rssi_avg, alt_rssi_avg, | ||
1757 | alt_ratio); | ||
1758 | |||
1759 | antcomb->quick_scan_cnt++; | ||
1760 | |||
1761 | div_comb_done: | ||
1762 | ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio); | ||
1763 | ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); | ||
1764 | |||
1765 | antcomb->scan_start_time = jiffies; | ||
1766 | antcomb->total_pkt_count = 0; | ||
1767 | antcomb->main_total_rssi = 0; | ||
1768 | antcomb->alt_total_rssi = 0; | ||
1769 | antcomb->main_recv_cnt = 0; | ||
1770 | antcomb->alt_recv_cnt = 0; | ||
1771 | } | ||
1772 | |||
1773 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | 1033 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) |
1774 | { | 1034 | { |
1775 | struct ath_buf *bf; | 1035 | struct ath_buf *bf; |