diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 47 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 2 |
2 files changed, 40 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 0a71bb55d0ee..3fa06afce86a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -100,6 +100,7 @@ struct iwl_scale_tbl_info { | |||
100 | u8 is_fat; /* 1 = 40 MHz channel width */ | 100 | u8 is_fat; /* 1 = 40 MHz channel width */ |
101 | u8 is_dup; /* 1 = duplicated data streams */ | 101 | u8 is_dup; /* 1 = duplicated data streams */ |
102 | u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ | 102 | u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ |
103 | u8 max_search; /* maximun number of tables we can search */ | ||
103 | s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ | 104 | s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ |
104 | u32 current_rate; /* rate_n_flags, uCode API format */ | 105 | u32 current_rate; /* rate_n_flags, uCode API format */ |
105 | struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ | 106 | struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ |
@@ -579,6 +580,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags, | |||
579 | tbl->is_dup = 0; | 580 | tbl->is_dup = 0; |
580 | tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS); | 581 | tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS); |
581 | tbl->lq_type = LQ_NONE; | 582 | tbl->lq_type = LQ_NONE; |
583 | tbl->max_search = IWL_MAX_SEARCH; | ||
582 | 584 | ||
583 | /* legacy rate format */ | 585 | /* legacy rate format */ |
584 | if (!(rate_n_flags & RATE_MCS_HT_MSK)) { | 586 | if (!(rate_n_flags & RATE_MCS_HT_MSK)) { |
@@ -612,8 +614,10 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags, | |||
612 | tbl->lq_type = LQ_MIMO2; | 614 | tbl->lq_type = LQ_MIMO2; |
613 | /* MIMO3 */ | 615 | /* MIMO3 */ |
614 | } else { | 616 | } else { |
615 | if (num_of_ant == 3) | 617 | if (num_of_ant == 3) { |
618 | tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH; | ||
616 | tbl->lq_type = LQ_MIMO3; | 619 | tbl->lq_type = LQ_MIMO3; |
620 | } | ||
617 | } | 621 | } |
618 | } | 622 | } |
619 | return 0; | 623 | return 0; |
@@ -771,6 +775,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, | |||
771 | 775 | ||
772 | tbl->is_fat = 0; | 776 | tbl->is_fat = 0; |
773 | tbl->is_SGI = 0; | 777 | tbl->is_SGI = 0; |
778 | tbl->max_search = IWL_MAX_SEARCH; | ||
774 | } | 779 | } |
775 | 780 | ||
776 | rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type); | 781 | rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type); |
@@ -1026,6 +1031,7 @@ static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy, | |||
1026 | lq_sta->total_failed = 0; | 1031 | lq_sta->total_failed = 0; |
1027 | lq_sta->total_success = 0; | 1032 | lq_sta->total_success = 0; |
1028 | lq_sta->flush_timer = jiffies; | 1033 | lq_sta->flush_timer = jiffies; |
1034 | lq_sta->action_counter = 0; | ||
1029 | } | 1035 | } |
1030 | 1036 | ||
1031 | /* | 1037 | /* |
@@ -1205,6 +1211,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, | |||
1205 | tbl->lq_type = LQ_MIMO2; | 1211 | tbl->lq_type = LQ_MIMO2; |
1206 | tbl->is_dup = lq_sta->is_dup; | 1212 | tbl->is_dup = lq_sta->is_dup; |
1207 | tbl->action = 0; | 1213 | tbl->action = 0; |
1214 | tbl->max_search = IWL_MAX_SEARCH; | ||
1208 | rate_mask = lq_sta->active_mimo2_rate; | 1215 | rate_mask = lq_sta->active_mimo2_rate; |
1209 | 1216 | ||
1210 | if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) | 1217 | if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) |
@@ -1270,6 +1277,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv, | |||
1270 | tbl->lq_type = LQ_MIMO3; | 1277 | tbl->lq_type = LQ_MIMO3; |
1271 | tbl->is_dup = lq_sta->is_dup; | 1278 | tbl->is_dup = lq_sta->is_dup; |
1272 | tbl->action = 0; | 1279 | tbl->action = 0; |
1280 | tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH; | ||
1273 | rate_mask = lq_sta->active_mimo3_rate; | 1281 | rate_mask = lq_sta->active_mimo3_rate; |
1274 | 1282 | ||
1275 | if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) | 1283 | if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) |
@@ -1328,6 +1336,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, | |||
1328 | tbl->is_dup = lq_sta->is_dup; | 1336 | tbl->is_dup = lq_sta->is_dup; |
1329 | tbl->lq_type = LQ_SISO; | 1337 | tbl->lq_type = LQ_SISO; |
1330 | tbl->action = 0; | 1338 | tbl->action = 0; |
1339 | tbl->max_search = IWL_MAX_SEARCH; | ||
1331 | rate_mask = lq_sta->active_siso_rate; | 1340 | rate_mask = lq_sta->active_siso_rate; |
1332 | 1341 | ||
1333 | if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) | 1342 | if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) |
@@ -1384,15 +1393,15 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1384 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | 1393 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; |
1385 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 1394 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1386 | int ret = 0; | 1395 | int ret = 0; |
1396 | u8 update_search_tbl_counter = 0; | ||
1387 | 1397 | ||
1388 | for (; ;) { | 1398 | for (; ;) { |
1399 | lq_sta->action_counter++; | ||
1389 | switch (tbl->action) { | 1400 | switch (tbl->action) { |
1390 | case IWL_LEGACY_SWITCH_ANTENNA1: | 1401 | case IWL_LEGACY_SWITCH_ANTENNA1: |
1391 | case IWL_LEGACY_SWITCH_ANTENNA2: | 1402 | case IWL_LEGACY_SWITCH_ANTENNA2: |
1392 | IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n"); | 1403 | IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n"); |
1393 | 1404 | ||
1394 | lq_sta->action_counter++; | ||
1395 | |||
1396 | if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 && | 1405 | if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 && |
1397 | tx_chains_num <= 1) || | 1406 | tx_chains_num <= 1) || |
1398 | (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 && | 1407 | (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 && |
@@ -1408,6 +1417,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1408 | 1417 | ||
1409 | if (rs_toggle_antenna(valid_tx_ant, | 1418 | if (rs_toggle_antenna(valid_tx_ant, |
1410 | &search_tbl->current_rate, search_tbl)) { | 1419 | &search_tbl->current_rate, search_tbl)) { |
1420 | update_search_tbl_counter = 1; | ||
1411 | rs_set_expected_tpt_table(lq_sta, search_tbl); | 1421 | rs_set_expected_tpt_table(lq_sta, search_tbl); |
1412 | goto out; | 1422 | goto out; |
1413 | } | 1423 | } |
@@ -1489,6 +1499,8 @@ out: | |||
1489 | tbl->action++; | 1499 | tbl->action++; |
1490 | if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC) | 1500 | if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC) |
1491 | tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; | 1501 | tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; |
1502 | if (update_search_tbl_counter) | ||
1503 | search_tbl->action = tbl->action; | ||
1492 | return 0; | 1504 | return 0; |
1493 | 1505 | ||
1494 | } | 1506 | } |
@@ -1511,6 +1523,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1511 | u8 start_action = tbl->action; | 1523 | u8 start_action = tbl->action; |
1512 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | 1524 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; |
1513 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 1525 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1526 | u8 update_search_tbl_counter = 0; | ||
1514 | int ret; | 1527 | int ret; |
1515 | 1528 | ||
1516 | for (;;) { | 1529 | for (;;) { |
@@ -1531,8 +1544,10 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1531 | 1544 | ||
1532 | memcpy(search_tbl, tbl, sz); | 1545 | memcpy(search_tbl, tbl, sz); |
1533 | if (rs_toggle_antenna(valid_tx_ant, | 1546 | if (rs_toggle_antenna(valid_tx_ant, |
1534 | &search_tbl->current_rate, search_tbl)) | 1547 | &search_tbl->current_rate, search_tbl)) { |
1548 | update_search_tbl_counter = 1; | ||
1535 | goto out; | 1549 | goto out; |
1550 | } | ||
1536 | break; | 1551 | break; |
1537 | case IWL_SISO_SWITCH_MIMO2_AB: | 1552 | case IWL_SISO_SWITCH_MIMO2_AB: |
1538 | case IWL_SISO_SWITCH_MIMO2_AC: | 1553 | case IWL_SISO_SWITCH_MIMO2_AC: |
@@ -1586,6 +1601,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1586 | search_tbl->current_rate = | 1601 | search_tbl->current_rate = |
1587 | rate_n_flags_from_tbl(priv, search_tbl, | 1602 | rate_n_flags_from_tbl(priv, search_tbl, |
1588 | index, is_green); | 1603 | index, is_green); |
1604 | update_search_tbl_counter = 1; | ||
1589 | goto out; | 1605 | goto out; |
1590 | case IWL_SISO_SWITCH_MIMO3_ABC: | 1606 | case IWL_SISO_SWITCH_MIMO3_ABC: |
1591 | IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n"); | 1607 | IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n"); |
@@ -1617,6 +1633,9 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1617 | tbl->action++; | 1633 | tbl->action++; |
1618 | if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC) | 1634 | if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC) |
1619 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; | 1635 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; |
1636 | if (update_search_tbl_counter) | ||
1637 | search_tbl->action = tbl->action; | ||
1638 | |||
1620 | return 0; | 1639 | return 0; |
1621 | } | 1640 | } |
1622 | 1641 | ||
@@ -1638,6 +1657,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, | |||
1638 | u8 start_action = tbl->action; | 1657 | u8 start_action = tbl->action; |
1639 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | 1658 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; |
1640 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 1659 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1660 | u8 update_search_tbl_counter = 0; | ||
1641 | int ret; | 1661 | int ret; |
1642 | 1662 | ||
1643 | for (;;) { | 1663 | for (;;) { |
@@ -1655,8 +1675,10 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, | |||
1655 | 1675 | ||
1656 | memcpy(search_tbl, tbl, sz); | 1676 | memcpy(search_tbl, tbl, sz); |
1657 | if (rs_toggle_antenna(valid_tx_ant, | 1677 | if (rs_toggle_antenna(valid_tx_ant, |
1658 | &search_tbl->current_rate, search_tbl)) | 1678 | &search_tbl->current_rate, search_tbl)) { |
1679 | update_search_tbl_counter = 1; | ||
1659 | goto out; | 1680 | goto out; |
1681 | } | ||
1660 | break; | 1682 | break; |
1661 | case IWL_MIMO2_SWITCH_SISO_A: | 1683 | case IWL_MIMO2_SWITCH_SISO_A: |
1662 | case IWL_MIMO2_SWITCH_SISO_B: | 1684 | case IWL_MIMO2_SWITCH_SISO_B: |
@@ -1713,6 +1735,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, | |||
1713 | search_tbl->current_rate = | 1735 | search_tbl->current_rate = |
1714 | rate_n_flags_from_tbl(priv, search_tbl, | 1736 | rate_n_flags_from_tbl(priv, search_tbl, |
1715 | index, is_green); | 1737 | index, is_green); |
1738 | update_search_tbl_counter = 1; | ||
1716 | goto out; | 1739 | goto out; |
1717 | 1740 | ||
1718 | case IWL_MIMO2_SWITCH_MIMO3_ABC: | 1741 | case IWL_MIMO2_SWITCH_MIMO3_ABC: |
@@ -1745,6 +1768,9 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, | |||
1745 | tbl->action++; | 1768 | tbl->action++; |
1746 | if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC) | 1769 | if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC) |
1747 | tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; | 1770 | tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; |
1771 | if (update_search_tbl_counter) | ||
1772 | search_tbl->action = tbl->action; | ||
1773 | |||
1748 | return 0; | 1774 | return 0; |
1749 | 1775 | ||
1750 | } | 1776 | } |
@@ -1768,6 +1794,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, | |||
1768 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | 1794 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; |
1769 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 1795 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1770 | int ret; | 1796 | int ret; |
1797 | u8 update_search_tbl_counter = 0; | ||
1771 | 1798 | ||
1772 | for (;;) { | 1799 | for (;;) { |
1773 | lq_sta->action_counter++; | 1800 | lq_sta->action_counter++; |
@@ -1866,6 +1893,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, | |||
1866 | search_tbl->current_rate = | 1893 | search_tbl->current_rate = |
1867 | rate_n_flags_from_tbl(priv, search_tbl, | 1894 | rate_n_flags_from_tbl(priv, search_tbl, |
1868 | index, is_green); | 1895 | index, is_green); |
1896 | update_search_tbl_counter = 1; | ||
1869 | goto out; | 1897 | goto out; |
1870 | } | 1898 | } |
1871 | tbl->action++; | 1899 | tbl->action++; |
@@ -1882,6 +1910,9 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, | |||
1882 | tbl->action++; | 1910 | tbl->action++; |
1883 | if (tbl->action > IWL_MIMO3_SWITCH_GI) | 1911 | if (tbl->action > IWL_MIMO3_SWITCH_GI) |
1884 | tbl->action = IWL_MIMO3_SWITCH_ANTENNA1; | 1912 | tbl->action = IWL_MIMO3_SWITCH_ANTENNA1; |
1913 | if (update_search_tbl_counter) | ||
1914 | search_tbl->action = tbl->action; | ||
1915 | |||
1885 | return 0; | 1916 | return 0; |
1886 | 1917 | ||
1887 | } | 1918 | } |
@@ -2326,8 +2357,7 @@ lq_update: | |||
2326 | * before next round of mode comparisons. */ | 2357 | * before next round of mode comparisons. */ |
2327 | tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); | 2358 | tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); |
2328 | if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) && | 2359 | if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) && |
2329 | lq_sta->action_counter >= 1) { | 2360 | lq_sta->action_counter > tbl1->max_search) { |
2330 | lq_sta->action_counter = 0; | ||
2331 | IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n"); | 2361 | IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n"); |
2332 | rs_set_stay_in_table(priv, 1, lq_sta); | 2362 | rs_set_stay_in_table(priv, 1, lq_sta); |
2333 | } | 2363 | } |
@@ -2336,7 +2366,7 @@ lq_update: | |||
2336 | * have been tried and compared, stay in this best modulation | 2366 | * have been tried and compared, stay in this best modulation |
2337 | * mode for a while before next round of mode comparisons. */ | 2367 | * mode for a while before next round of mode comparisons. */ |
2338 | if (lq_sta->enable_counter && | 2368 | if (lq_sta->enable_counter && |
2339 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { | 2369 | (lq_sta->action_counter >= tbl1->max_search)) { |
2340 | if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && | 2370 | if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && |
2341 | (lq_sta->tx_agg_tid_en & (1 << tid)) && | 2371 | (lq_sta->tx_agg_tid_en & (1 << tid)) && |
2342 | (tid != MAX_TID_COUNT)) { | 2372 | (tid != MAX_TID_COUNT)) { |
@@ -2350,7 +2380,6 @@ lq_update: | |||
2350 | lq_sta, sta); | 2380 | lq_sta, sta); |
2351 | } | 2381 | } |
2352 | } | 2382 | } |
2353 | lq_sta->action_counter = 0; | ||
2354 | rs_set_stay_in_table(priv, 0, lq_sta); | 2383 | rs_set_stay_in_table(priv, 0, lq_sta); |
2355 | } | 2384 | } |
2356 | } | 2385 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index f875136bc5dc..25050bf315a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h | |||
@@ -275,6 +275,8 @@ enum { | |||
275 | #define IWL_MIMO3_SWITCH_GI 8 | 275 | #define IWL_MIMO3_SWITCH_GI 8 |
276 | 276 | ||
277 | 277 | ||
278 | #define IWL_MAX_11N_MIMO3_SEARCH IWL_MIMO3_SWITCH_GI | ||
279 | #define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_MIMO3_ABC | ||
278 | 280 | ||
279 | /*FIXME:RS:add possible actions for MIMO3*/ | 281 | /*FIXME:RS:add possible actions for MIMO3*/ |
280 | 282 | ||