aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
diff options
context:
space:
mode:
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. */