aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2010-08-23 10:57:13 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-08-25 14:34:53 -0400
commitda5dbb971573efda54c7c39e7e4ccd3fc7c86e49 (patch)
treef7350f6d2ead2bef4c3b663a18c6ec1ceac1c996 /drivers/net/wireless/iwlwifi/iwl-agn-rs.c
parentf37837c962c309f1d90636626c779497b614be42 (diff)
iwlagn: set traffic load based on multiple factors
Current BT traffic load should based on the following conditions: 1. BT On/Off status 2. Channel announcement enable/disable 3. Curren traffic load report from uCode Need to modify rate scale to down-grade from MIMO to SISO if detected high BT traffic load. Also need to make sure not using chain "B" with high BT traffic or if it is in "full concurrency" mode. Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-rs.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c113
1 files changed, 71 insertions, 42 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 687b534d83d..e78f3f0592d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -82,7 +82,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
82 struct iwl_lq_sta *lq_sta); 82 struct iwl_lq_sta *lq_sta);
83static void rs_fill_link_cmd(struct iwl_priv *priv, 83static void rs_fill_link_cmd(struct iwl_priv *priv,
84 struct iwl_lq_sta *lq_sta, u32 rate_n_flags); 84 struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
85static void rs_stay_in_table(struct iwl_lq_sta *lq_sta); 85static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
86 86
87 87
88#ifdef CONFIG_MAC80211_DEBUGFS 88#ifdef CONFIG_MAC80211_DEBUGFS
@@ -900,7 +900,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
900 * no matching table found, let's by-pass the data collection 900 * no matching table found, let's by-pass the data collection
901 * and continue to perform rate scale to find the rate table 901 * and continue to perform rate scale to find the rate table
902 */ 902 */
903 rs_stay_in_table(lq_sta); 903 rs_stay_in_table(lq_sta, true);
904 goto done; 904 goto done;
905 } 905 }
906 906
@@ -1334,15 +1334,17 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1334 break; 1334 break;
1335 case IWL_BT_COEX_TRAFFIC_LOAD_LOW: 1335 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1336 /* avoid antenna B unless MIMO */ 1336 /* avoid antenna B unless MIMO */
1337 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1337 if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2) 1338 if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2)
1338 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; 1339 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1339 break; 1340 break;
1340 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: 1341 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1341 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: 1342 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1342 /* avoid antenna B and MIMO */ 1343 /* avoid antenna B and MIMO */
1344 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1343 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && 1345 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 &&
1344 tbl->action != IWL_LEGACY_SWITCH_SISO) 1346 tbl->action != IWL_LEGACY_SWITCH_SISO)
1345 tbl->action = IWL_SISO_SWITCH_ANTENNA1; 1347 tbl->action = IWL_LEGACY_SWITCH_SISO;
1346 break; 1348 break;
1347 default: 1349 default:
1348 IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); 1350 IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
@@ -1362,6 +1364,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1362 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; 1364 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1363 else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) 1365 else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
1364 tbl->action = IWL_LEGACY_SWITCH_SISO; 1366 tbl->action = IWL_LEGACY_SWITCH_SISO;
1367 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1365 } 1368 }
1366 1369
1367 start_action = tbl->action; 1370 start_action = tbl->action;
@@ -1379,7 +1382,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1379 break; 1382 break;
1380 1383
1381 /* Don't change antenna if success has been great */ 1384 /* Don't change antenna if success has been great */
1382 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1385 if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
1386 !priv->bt_full_concurrent &&
1387 priv->bt_traffic_load ==
1388 IWL_BT_COEX_TRAFFIC_LOAD_NONE)
1383 break; 1389 break;
1384 1390
1385 /* Set up search table to try other antenna */ 1391 /* Set up search table to try other antenna */
@@ -1503,14 +1509,15 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1503 break; 1509 break;
1504 case IWL_BT_COEX_TRAFFIC_LOAD_LOW: 1510 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1505 /* avoid antenna B unless MIMO */ 1511 /* avoid antenna B unless MIMO */
1512 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1506 if (tbl->action == IWL_SISO_SWITCH_ANTENNA2) 1513 if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)
1507 tbl->action = IWL_SISO_SWITCH_ANTENNA1; 1514 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1508 break; 1515 break;
1509 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: 1516 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1510 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: 1517 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1511 /* avoid antenna B and MIMO */ 1518 /* avoid antenna B and MIMO */
1512 if (tbl->action >= IWL_SISO_SWITCH_ANTENNA2 && 1519 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1513 tbl->action != IWL_SISO_SWITCH_GI) 1520 if (tbl->action != IWL_SISO_SWITCH_ANTENNA1)
1514 tbl->action = IWL_SISO_SWITCH_ANTENNA1; 1521 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1515 break; 1522 break;
1516 default: 1523 default:
@@ -1525,9 +1532,11 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1525 } 1532 }
1526 1533
1527 /* configure as 1x1 if bt full concurrency */ 1534 /* configure as 1x1 if bt full concurrency */
1528 if (priv->bt_full_concurrent && 1535 if (priv->bt_full_concurrent) {
1529 tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) 1536 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1530 tbl->action = IWL_SISO_SWITCH_ANTENNA1; 1537 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
1538 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1539 }
1531 1540
1532 start_action = tbl->action; 1541 start_action = tbl->action;
1533 for (;;) { 1542 for (;;) {
@@ -1536,14 +1545,16 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1536 case IWL_SISO_SWITCH_ANTENNA1: 1545 case IWL_SISO_SWITCH_ANTENNA1:
1537 case IWL_SISO_SWITCH_ANTENNA2: 1546 case IWL_SISO_SWITCH_ANTENNA2:
1538 IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n"); 1547 IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n");
1539
1540 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 && 1548 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
1541 tx_chains_num <= 1) || 1549 tx_chains_num <= 1) ||
1542 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 && 1550 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
1543 tx_chains_num <= 2)) 1551 tx_chains_num <= 2))
1544 break; 1552 break;
1545 1553
1546 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1554 if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
1555 !priv->bt_full_concurrent &&
1556 priv->bt_traffic_load ==
1557 IWL_BT_COEX_TRAFFIC_LOAD_NONE)
1547 break; 1558 break;
1548 1559
1549 memcpy(search_tbl, tbl, sz); 1560 memcpy(search_tbl, tbl, sz);
@@ -1670,13 +1681,13 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
1670 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: 1681 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1671 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: 1682 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1672 /* avoid antenna B and MIMO */ 1683 /* avoid antenna B and MIMO */
1673 if (tbl->action == IWL_MIMO2_SWITCH_MIMO3_ABC) 1684 if (tbl->action != IWL_MIMO2_SWITCH_SISO_A)
1674 tbl->action = IWL_SISO_SWITCH_ANTENNA1; 1685 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1686 break;
1675 case IWL_BT_COEX_TRAFFIC_LOAD_LOW: 1687 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1676 /* avoid antenna B unless MIMO */ 1688 /* avoid antenna B unless MIMO */
1677 if (tbl->action == IWL_MIMO2_SWITCH_ANTENNA2) 1689 if (tbl->action == IWL_MIMO2_SWITCH_SISO_B ||
1678 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; 1690 tbl->action == IWL_MIMO2_SWITCH_SISO_C)
1679 else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B)
1680 tbl->action = IWL_MIMO2_SWITCH_SISO_A; 1691 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1681 break; 1692 break;
1682 default: 1693 default:
@@ -1840,16 +1851,14 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1840 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: 1851 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1841 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: 1852 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1842 /* avoid antenna B and MIMO */ 1853 /* avoid antenna B and MIMO */
1843 if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB || 1854 if (tbl->action != IWL_MIMO3_SWITCH_SISO_A)
1844 tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC ||
1845 tbl->action == IWL_MIMO3_SWITCH_MIMO2_BC)
1846 tbl->action = IWL_MIMO3_SWITCH_SISO_A; 1855 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1856 break;
1847 case IWL_BT_COEX_TRAFFIC_LOAD_LOW: 1857 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1848 /* avoid antenna B unless MIMO */ 1858 /* avoid antenna B unless MIMO */
1849 if (tbl->action == IWL_MIMO3_SWITCH_SISO_B) 1859 if (tbl->action == IWL_MIMO3_SWITCH_SISO_B ||
1860 tbl->action == IWL_MIMO3_SWITCH_SISO_C)
1850 tbl->action = IWL_MIMO3_SWITCH_SISO_A; 1861 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1851 else if (tbl->action == IWL_MIMO3_SWITCH_ANTENNA2)
1852 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
1853 break; 1862 break;
1854 default: 1863 default:
1855 IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); 1864 IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
@@ -1996,7 +2005,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1996 * 2) # times calling this function 2005 * 2) # times calling this function
1997 * 3) elapsed time in this mode (not used, for now) 2006 * 3) elapsed time in this mode (not used, for now)
1998 */ 2007 */
1999static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) 2008static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
2000{ 2009{
2001 struct iwl_scale_tbl_info *tbl; 2010 struct iwl_scale_tbl_info *tbl;
2002 int i; 2011 int i;
@@ -2027,7 +2036,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
2027 * allow a new search. Also (below) reset all bitmaps and 2036 * allow a new search. Also (below) reset all bitmaps and
2028 * stats in active history. 2037 * stats in active history.
2029 */ 2038 */
2030 if ((lq_sta->total_failed > lq_sta->max_failure_limit) || 2039 if (force_search ||
2040 (lq_sta->total_failed > lq_sta->max_failure_limit) ||
2031 (lq_sta->total_success > lq_sta->max_success_limit) || 2041 (lq_sta->total_success > lq_sta->max_success_limit) ||
2032 ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer) 2042 ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
2033 && (flush_interval_passed))) { 2043 && (flush_interval_passed))) {
@@ -2243,7 +2253,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2243 2253
2244 /* Should we stay with this modulation mode, 2254 /* Should we stay with this modulation mode,
2245 * or search for a new one? */ 2255 * or search for a new one? */
2246 rs_stay_in_table(lq_sta); 2256 rs_stay_in_table(lq_sta, false);
2247 2257
2248 goto out; 2258 goto out;
2249 } 2259 }
@@ -2392,16 +2402,25 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2392 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) 2402 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type)))
2393 scale_action = -1; 2403 scale_action = -1;
2394 2404
2395 if (lq_sta->last_bt_traffic > priv->bt_traffic_load) { 2405 if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
2396 lq_sta->last_bt_traffic = priv->bt_traffic_load; 2406 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
2397 /* 2407 if (lq_sta->last_bt_traffic > priv->bt_traffic_load) {
2398 * don't set scale_action, don't want to scale up if 2408 /*
2399 * the rate scale doesn't otherwise think that is a 2409 * don't set scale_action, don't want to scale up if
2400 * good idea. 2410 * the rate scale doesn't otherwise think that is a
2401 */ 2411 * good idea.
2402 } else if (lq_sta->last_bt_traffic < priv->bt_traffic_load) { 2412 */
2403 lq_sta->last_bt_traffic = priv->bt_traffic_load; 2413 } else if (lq_sta->last_bt_traffic <= priv->bt_traffic_load) {
2404 scale_action = -1; 2414 scale_action = -1;
2415 }
2416 }
2417 lq_sta->last_bt_traffic = priv->bt_traffic_load;
2418
2419 if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
2420 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
2421 /* search for a new modulation */
2422 rs_stay_in_table(lq_sta, true);
2423 goto lq_update;
2405 } 2424 }
2406 2425
2407 switch (scale_action) { 2426 switch (scale_action) {
@@ -2440,7 +2459,7 @@ lq_update:
2440 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) { 2459 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) {
2441 /* Should we stay with this modulation mode, 2460 /* Should we stay with this modulation mode,
2442 * or search for a new one? */ 2461 * or search for a new one? */
2443 rs_stay_in_table(lq_sta); 2462 rs_stay_in_table(lq_sta, false);
2444 } 2463 }
2445 /* 2464 /*
2446 * Search for new modulation mode if we're: 2465 * Search for new modulation mode if we're:
@@ -2786,6 +2805,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2786 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, 2805 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
2787 &tbl_type, &rate_idx); 2806 &tbl_type, &rate_idx);
2788 2807
2808 if (priv && priv->bt_full_concurrent) {
2809 /* 1x1 only */
2810 tbl_type.ant_type =
2811 first_antenna(priv->hw_params.valid_tx_ant);
2812 }
2813
2789 /* How many times should we repeat the initial rate? */ 2814 /* How many times should we repeat the initial rate? */
2790 if (is_legacy(tbl_type.lq_type)) { 2815 if (is_legacy(tbl_type.lq_type)) {
2791 ant_toggle_cnt = 1; 2816 ant_toggle_cnt = 1;
@@ -2800,8 +2825,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2800 /* Fill 1st table entry (index 0) */ 2825 /* Fill 1st table entry (index 0) */
2801 lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate); 2826 lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate);
2802 2827
2803 if (num_of_ant(tbl_type.ant_type) == 1 || 2828 if (num_of_ant(tbl_type.ant_type) == 1) {
2804 (priv && priv->bt_full_concurrent)) {
2805 lq_cmd->general_params.single_stream_ant_msk = 2829 lq_cmd->general_params.single_stream_ant_msk =
2806 tbl_type.ant_type; 2830 tbl_type.ant_type;
2807 } else if (num_of_ant(tbl_type.ant_type) == 2) { 2831 } else if (num_of_ant(tbl_type.ant_type) == 2) {
@@ -2811,7 +2835,6 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2811 2835
2812 index++; 2836 index++;
2813 repeat_rate--; 2837 repeat_rate--;
2814
2815 if (priv) { 2838 if (priv) {
2816 if (priv->bt_full_concurrent) 2839 if (priv->bt_full_concurrent)
2817 valid_tx_ant = ANT_A; 2840 valid_tx_ant = ANT_A;
@@ -2832,7 +2855,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2832 rs_toggle_antenna(valid_tx_ant, 2855 rs_toggle_antenna(valid_tx_ant,
2833 &new_rate, &tbl_type)) 2856 &new_rate, &tbl_type))
2834 ant_toggle_cnt = 1; 2857 ant_toggle_cnt = 1;
2835} 2858 }
2836 2859
2837 /* Override next rate if needed for debug purposes */ 2860 /* Override next rate if needed for debug purposes */
2838 rs_dbgfs_set_mcs(lq_sta, &new_rate, index); 2861 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
@@ -2847,6 +2870,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2847 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, 2870 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,
2848 &rate_idx); 2871 &rate_idx);
2849 2872
2873 if (priv && priv->bt_full_concurrent) {
2874 /* 1x1 only */
2875 tbl_type.ant_type =
2876 first_antenna(priv->hw_params.valid_tx_ant);
2877 }
2878
2850 /* Indicate to uCode which entries might be MIMO. 2879 /* Indicate to uCode which entries might be MIMO.
2851 * If initial rate was MIMO, this will finally end up 2880 * If initial rate was MIMO, this will finally end up
2852 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ 2881 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */