aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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