aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/recv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/recv.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c215
1 files changed, 167 insertions, 48 deletions
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index c5b7cbe59bf..4f52e0429f9 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -28,6 +28,33 @@ static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta,
28 (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); 28 (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50);
29} 29}
30 30
31static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio,
32 int curr_main_set, int curr_alt_set,
33 int alt_rssi_avg, int main_rssi_avg)
34{
35 bool result = false;
36 switch (div_group) {
37 case 0:
38 if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
39 result = true;
40 break;
41 case 1:
42 if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) &&
43 (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) &&
44 (alt_rssi_avg >= (main_rssi_avg - 5))) ||
45 ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) &&
46 (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) &&
47 (alt_rssi_avg >= (main_rssi_avg - 2)))) &&
48 (alt_rssi_avg >= 4))
49 result = true;
50 else
51 result = false;
52 break;
53 }
54
55 return result;
56}
57
31static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) 58static inline bool ath9k_check_auto_sleep(struct ath_softc *sc)
32{ 59{
33 return sc->ps_enabled && 60 return sc->ps_enabled &&
@@ -572,6 +599,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
572 ath_dbg(common, ATH_DBG_PS, 599 ath_dbg(common, ATH_DBG_PS,
573 "Reconfigure Beacon timers based on timestamp from the AP\n"); 600 "Reconfigure Beacon timers based on timestamp from the AP\n");
574 ath_set_beacon(sc); 601 ath_set_beacon(sc);
602 sc->ps_flags &= ~PS_TSFOOR_SYNC;
575 } 603 }
576 604
577 if (ath_beacon_dtim_pending_cab(skb)) { 605 if (ath_beacon_dtim_pending_cab(skb)) {
@@ -916,7 +944,8 @@ static void ath9k_process_rssi(struct ath_common *common,
916 int last_rssi; 944 int last_rssi;
917 __le16 fc; 945 __le16 fc;
918 946
919 if (ah->opmode != NL80211_IFTYPE_STATION) 947 if ((ah->opmode != NL80211_IFTYPE_STATION) &&
948 (ah->opmode != NL80211_IFTYPE_ADHOC))
920 return; 949 return;
921 950
922 fc = hdr->frame_control; 951 fc = hdr->frame_control;
@@ -1288,49 +1317,138 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
1288 } 1317 }
1289} 1318}
1290 1319
1291static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf) 1320static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
1321 struct ath_ant_comb *antcomb, int alt_ratio)
1292{ 1322{
1293 /* Adjust the fast_div_bias based on main and alt lna conf */ 1323 if (ant_conf->div_group == 0) {
1294 switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) { 1324 /* Adjust the fast_div_bias based on main and alt lna conf */
1295 case (0x01): /* A-B LNA2 */ 1325 switch ((ant_conf->main_lna_conf << 4) |
1296 ant_conf->fast_div_bias = 0x3b; 1326 ant_conf->alt_lna_conf) {
1297 break; 1327 case (0x01): /* A-B LNA2 */
1298 case (0x02): /* A-B LNA1 */ 1328 ant_conf->fast_div_bias = 0x3b;
1299 ant_conf->fast_div_bias = 0x3d; 1329 break;
1300 break; 1330 case (0x02): /* A-B LNA1 */
1301 case (0x03): /* A-B A+B */ 1331 ant_conf->fast_div_bias = 0x3d;
1302 ant_conf->fast_div_bias = 0x1; 1332 break;
1303 break; 1333 case (0x03): /* A-B A+B */
1304 case (0x10): /* LNA2 A-B */ 1334 ant_conf->fast_div_bias = 0x1;
1305 ant_conf->fast_div_bias = 0x7; 1335 break;
1306 break; 1336 case (0x10): /* LNA2 A-B */
1307 case (0x12): /* LNA2 LNA1 */ 1337 ant_conf->fast_div_bias = 0x7;
1308 ant_conf->fast_div_bias = 0x2; 1338 break;
1309 break; 1339 case (0x12): /* LNA2 LNA1 */
1310 case (0x13): /* LNA2 A+B */ 1340 ant_conf->fast_div_bias = 0x2;
1311 ant_conf->fast_div_bias = 0x7; 1341 break;
1312 break; 1342 case (0x13): /* LNA2 A+B */
1313 case (0x20): /* LNA1 A-B */ 1343 ant_conf->fast_div_bias = 0x7;
1314 ant_conf->fast_div_bias = 0x6; 1344 break;
1315 break; 1345 case (0x20): /* LNA1 A-B */
1316 case (0x21): /* LNA1 LNA2 */ 1346 ant_conf->fast_div_bias = 0x6;
1317 ant_conf->fast_div_bias = 0x0; 1347 break;
1318 break; 1348 case (0x21): /* LNA1 LNA2 */
1319 case (0x23): /* LNA1 A+B */ 1349 ant_conf->fast_div_bias = 0x0;
1320 ant_conf->fast_div_bias = 0x6; 1350 break;
1321 break; 1351 case (0x23): /* LNA1 A+B */
1322 case (0x30): /* A+B A-B */ 1352 ant_conf->fast_div_bias = 0x6;
1323 ant_conf->fast_div_bias = 0x1; 1353 break;
1324 break; 1354 case (0x30): /* A+B A-B */
1325 case (0x31): /* A+B LNA2 */ 1355 ant_conf->fast_div_bias = 0x1;
1326 ant_conf->fast_div_bias = 0x3b; 1356 break;
1327 break; 1357 case (0x31): /* A+B LNA2 */
1328 case (0x32): /* A+B LNA1 */ 1358 ant_conf->fast_div_bias = 0x3b;
1329 ant_conf->fast_div_bias = 0x3d; 1359 break;
1330 break; 1360 case (0x32): /* A+B LNA1 */
1331 default: 1361 ant_conf->fast_div_bias = 0x3d;
1332 break; 1362 break;
1363 default:
1364 break;
1365 }
1366 } else if (ant_conf->div_group == 2) {
1367 /* Adjust the fast_div_bias based on main and alt_lna_conf */
1368 switch ((ant_conf->main_lna_conf << 4) |
1369 ant_conf->alt_lna_conf) {
1370 case (0x01): /* A-B LNA2 */
1371 ant_conf->fast_div_bias = 0x1;
1372 ant_conf->main_gaintb = 0;
1373 ant_conf->alt_gaintb = 0;
1374 break;
1375 case (0x02): /* A-B LNA1 */
1376 ant_conf->fast_div_bias = 0x1;
1377 ant_conf->main_gaintb = 0;
1378 ant_conf->alt_gaintb = 0;
1379 break;
1380 case (0x03): /* A-B A+B */
1381 ant_conf->fast_div_bias = 0x1;
1382 ant_conf->main_gaintb = 0;
1383 ant_conf->alt_gaintb = 0;
1384 break;
1385 case (0x10): /* LNA2 A-B */
1386 if (!(antcomb->scan) &&
1387 (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
1388 ant_conf->fast_div_bias = 0x1;
1389 else
1390 ant_conf->fast_div_bias = 0x2;
1391 ant_conf->main_gaintb = 0;
1392 ant_conf->alt_gaintb = 0;
1393 break;
1394 case (0x12): /* LNA2 LNA1 */
1395 ant_conf->fast_div_bias = 0x1;
1396 ant_conf->main_gaintb = 0;
1397 ant_conf->alt_gaintb = 0;
1398 break;
1399 case (0x13): /* LNA2 A+B */
1400 if (!(antcomb->scan) &&
1401 (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
1402 ant_conf->fast_div_bias = 0x1;
1403 else
1404 ant_conf->fast_div_bias = 0x2;
1405 ant_conf->main_gaintb = 0;
1406 ant_conf->alt_gaintb = 0;
1407 break;
1408 case (0x20): /* LNA1 A-B */
1409 if (!(antcomb->scan) &&
1410 (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
1411 ant_conf->fast_div_bias = 0x1;
1412 else
1413 ant_conf->fast_div_bias = 0x2;
1414 ant_conf->main_gaintb = 0;
1415 ant_conf->alt_gaintb = 0;
1416 break;
1417 case (0x21): /* LNA1 LNA2 */
1418 ant_conf->fast_div_bias = 0x1;
1419 ant_conf->main_gaintb = 0;
1420 ant_conf->alt_gaintb = 0;
1421 break;
1422 case (0x23): /* LNA1 A+B */
1423 if (!(antcomb->scan) &&
1424 (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
1425 ant_conf->fast_div_bias = 0x1;
1426 else
1427 ant_conf->fast_div_bias = 0x2;
1428 ant_conf->main_gaintb = 0;
1429 ant_conf->alt_gaintb = 0;
1430 break;
1431 case (0x30): /* A+B A-B */
1432 ant_conf->fast_div_bias = 0x1;
1433 ant_conf->main_gaintb = 0;
1434 ant_conf->alt_gaintb = 0;
1435 break;
1436 case (0x31): /* A+B LNA2 */
1437 ant_conf->fast_div_bias = 0x1;
1438 ant_conf->main_gaintb = 0;
1439 ant_conf->alt_gaintb = 0;
1440 break;
1441 case (0x32): /* A+B LNA1 */
1442 ant_conf->fast_div_bias = 0x1;
1443 ant_conf->main_gaintb = 0;
1444 ant_conf->alt_gaintb = 0;
1445 break;
1446 default:
1447 break;
1448 }
1449
1333 } 1450 }
1451
1334} 1452}
1335 1453
1336/* Antenna diversity and combining */ 1454/* Antenna diversity and combining */
@@ -1350,8 +1468,8 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
1350 main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & 1468 main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
1351 ATH_ANT_RX_MASK; 1469 ATH_ANT_RX_MASK;
1352 1470
1353 /* Record packet only when alt_rssi is positive */ 1471 /* Record packet only when both main_rssi and alt_rssi is positive */
1354 if (alt_rssi > 0) { 1472 if (main_rssi > 0 && alt_rssi > 0) {
1355 antcomb->total_pkt_count++; 1473 antcomb->total_pkt_count++;
1356 antcomb->main_total_rssi += main_rssi; 1474 antcomb->main_total_rssi += main_rssi;
1357 antcomb->alt_total_rssi += alt_rssi; 1475 antcomb->alt_total_rssi += alt_rssi;
@@ -1411,7 +1529,9 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
1411 } 1529 }
1412 1530
1413 if (!antcomb->scan) { 1531 if (!antcomb->scan) {
1414 if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { 1532 if (ath_ant_div_comb_alt_check(div_ant_conf.div_group,
1533 alt_ratio, curr_main_set, curr_alt_set,
1534 alt_rssi_avg, main_rssi_avg)) {
1415 if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { 1535 if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) {
1416 /* Switch main and alt LNA */ 1536 /* Switch main and alt LNA */
1417 div_ant_conf.main_lna_conf = 1537 div_ant_conf.main_lna_conf =
@@ -1440,7 +1560,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
1440 } 1560 }
1441 1561
1442 if ((alt_rssi_avg < (main_rssi_avg + 1562 if ((alt_rssi_avg < (main_rssi_avg +
1443 ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA))) 1563 div_ant_conf.lna1_lna2_delta)))
1444 goto div_comb_done; 1564 goto div_comb_done;
1445 } 1565 }
1446 1566
@@ -1554,8 +1674,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
1554 antcomb->quick_scan_cnt++; 1674 antcomb->quick_scan_cnt++;
1555 1675
1556div_comb_done: 1676div_comb_done:
1557 ath_ant_div_conf_fast_divbias(&div_ant_conf); 1677 ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio);
1558
1559 ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); 1678 ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
1560 1679
1561 antcomb->scan_start_time = jiffies; 1680 antcomb->scan_start_time = jiffies;