aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohamed Abbas <mohamed.abbas@intel.com>2009-05-08 16:44:39 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-11 15:24:01 -0400
commitd6e933993fdad4a270c557fa5317f668bef1d824 (patch)
tree81610adcf2d587486517262e8c14c3e34d0fb26e
parent7af2c460789a78d9c0d4dc7776fcb87acdc71052 (diff)
iwlagn: improve rate scale table search
iwlagn rate scaling will periodically search other rate scale tables to switch to the best table regarding performance. In the past the number of search tables were 3. Every time the rate scale algorithm goes through these available tables in will stay in current table for some time before start searching again. Recent driver support more feature and antenna, so we have more tables to search. This patch make sure we go through all available tables. Signed-off-by: Mohamed Abbas <mohamed.abbas@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h2
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