diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-6000.c | 29 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 113 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 16 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 1 |
5 files changed, 112 insertions, 51 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index ebf0c7ecef4e..30dc1f334202 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -428,6 +428,9 @@ static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work) | |||
428 | container_of(work, struct iwl_priv, bt_traffic_change_work); | 428 | container_of(work, struct iwl_priv, bt_traffic_change_work); |
429 | int smps_request = -1; | 429 | int smps_request = -1; |
430 | 430 | ||
431 | IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n", | ||
432 | priv->bt_traffic_load); | ||
433 | |||
431 | switch (priv->bt_traffic_load) { | 434 | switch (priv->bt_traffic_load) { |
432 | case IWL_BT_COEX_TRAFFIC_LOAD_NONE: | 435 | case IWL_BT_COEX_TRAFFIC_LOAD_NONE: |
433 | smps_request = IEEE80211_SMPS_AUTOMATIC; | 436 | smps_request = IEEE80211_SMPS_AUTOMATIC; |
@@ -447,6 +450,9 @@ static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work) | |||
447 | 450 | ||
448 | mutex_lock(&priv->mutex); | 451 | mutex_lock(&priv->mutex); |
449 | 452 | ||
453 | if (priv->cfg->ops->lib->update_chain_flags) | ||
454 | priv->cfg->ops->lib->update_chain_flags(priv); | ||
455 | |||
450 | if (smps_request != -1 && | 456 | if (smps_request != -1 && |
451 | priv->vif && priv->vif->type == NL80211_IFTYPE_STATION) | 457 | priv->vif && priv->vif->type == NL80211_IFTYPE_STATION) |
452 | ieee80211_request_smps(priv->vif, smps_request); | 458 | ieee80211_request_smps(priv->vif, smps_request); |
@@ -549,6 +555,7 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, | |||
549 | struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; | 555 | struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; |
550 | struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 }; | 556 | struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 }; |
551 | struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; | 557 | struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; |
558 | u8 last_traffic_load; | ||
552 | 559 | ||
553 | IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); | 560 | IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); |
554 | IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); | 561 | IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); |
@@ -556,16 +563,28 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, | |||
556 | IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", coex->bt_ci_compliance); | 563 | IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", coex->bt_ci_compliance); |
557 | iwlagn_print_uartmsg(priv, uart_msg); | 564 | iwlagn_print_uartmsg(priv, uart_msg); |
558 | 565 | ||
566 | last_traffic_load = priv->notif_bt_traffic_load; | ||
559 | priv->notif_bt_traffic_load = coex->bt_traffic_load; | 567 | priv->notif_bt_traffic_load = coex->bt_traffic_load; |
560 | |||
561 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { | 568 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { |
562 | if (coex->bt_traffic_load != priv->bt_traffic_load) { | 569 | if (priv->bt_status != coex->bt_status || |
563 | priv->bt_traffic_load = coex->bt_traffic_load; | 570 | last_traffic_load != coex->bt_traffic_load) { |
564 | 571 | if (coex->bt_status) { | |
572 | /* BT on */ | ||
573 | if (!priv->bt_ch_announce) | ||
574 | priv->bt_traffic_load = | ||
575 | IWL_BT_COEX_TRAFFIC_LOAD_HIGH; | ||
576 | else | ||
577 | priv->bt_traffic_load = | ||
578 | coex->bt_traffic_load; | ||
579 | } else { | ||
580 | /* BT off */ | ||
581 | priv->bt_traffic_load = | ||
582 | IWL_BT_COEX_TRAFFIC_LOAD_NONE; | ||
583 | } | ||
584 | priv->bt_status = coex->bt_status; | ||
565 | queue_work(priv->workqueue, | 585 | queue_work(priv->workqueue, |
566 | &priv->bt_traffic_change_work); | 586 | &priv->bt_traffic_change_work); |
567 | } | 587 | } |
568 | |||
569 | if (priv->bt_sco_active != | 588 | if (priv->bt_sco_active != |
570 | (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) { | 589 | (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) { |
571 | priv->bt_sco_active = uart_msg->frame3 & | 590 | priv->bt_sco_active = uart_msg->frame3 & |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 687b534d83d0..e78f3f0592d6 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); |
83 | static void rs_fill_link_cmd(struct iwl_priv *priv, | 83 | static 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); |
85 | static void rs_stay_in_table(struct iwl_lq_sta *lq_sta); | 85 | static 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 | */ |
1999 | static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) | 2008 | static 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. */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 989e4a702602..4410f820c2f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -2823,6 +2823,7 @@ static void __iwl_down(struct iwl_priv *priv) | |||
2823 | iwl_clear_driver_stations(priv); | 2823 | iwl_clear_driver_stations(priv); |
2824 | 2824 | ||
2825 | /* reset BT coex data */ | 2825 | /* reset BT coex data */ |
2826 | priv->bt_status = 0; | ||
2826 | priv->bt_traffic_load = priv->cfg->bt_init_traffic_load; | 2827 | priv->bt_traffic_load = priv->cfg->bt_init_traffic_load; |
2827 | priv->bt_sco_active = false; | 2828 | priv->bt_sco_active = false; |
2828 | priv->bt_full_concurrent = false; | 2829 | priv->bt_full_concurrent = false; |
@@ -3133,6 +3134,7 @@ static void iwl_bg_restart(struct work_struct *data) | |||
3133 | bool bt_sco, bt_full_concurrent; | 3134 | bool bt_sco, bt_full_concurrent; |
3134 | u8 bt_ci_compliance; | 3135 | u8 bt_ci_compliance; |
3135 | u8 bt_load; | 3136 | u8 bt_load; |
3137 | u8 bt_status; | ||
3136 | 3138 | ||
3137 | mutex_lock(&priv->mutex); | 3139 | mutex_lock(&priv->mutex); |
3138 | priv->vif = NULL; | 3140 | priv->vif = NULL; |
@@ -3151,6 +3153,7 @@ static void iwl_bg_restart(struct work_struct *data) | |||
3151 | bt_full_concurrent = priv->bt_full_concurrent; | 3153 | bt_full_concurrent = priv->bt_full_concurrent; |
3152 | bt_ci_compliance = priv->bt_ci_compliance; | 3154 | bt_ci_compliance = priv->bt_ci_compliance; |
3153 | bt_load = priv->bt_traffic_load; | 3155 | bt_load = priv->bt_traffic_load; |
3156 | bt_status = priv->bt_status; | ||
3154 | 3157 | ||
3155 | __iwl_down(priv); | 3158 | __iwl_down(priv); |
3156 | 3159 | ||
@@ -3158,6 +3161,7 @@ static void iwl_bg_restart(struct work_struct *data) | |||
3158 | priv->bt_full_concurrent = bt_full_concurrent; | 3161 | priv->bt_full_concurrent = bt_full_concurrent; |
3159 | priv->bt_ci_compliance = bt_ci_compliance; | 3162 | priv->bt_ci_compliance = bt_ci_compliance; |
3160 | priv->bt_traffic_load = bt_load; | 3163 | priv->bt_traffic_load = bt_load; |
3164 | priv->bt_status = bt_status; | ||
3161 | 3165 | ||
3162 | mutex_unlock(&priv->mutex); | 3166 | mutex_unlock(&priv->mutex); |
3163 | iwl_cancel_deferred_work(priv); | 3167 | iwl_cancel_deferred_work(priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 34cba38f1d0c..c43124c997cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -780,8 +780,12 @@ EXPORT_SYMBOL(iwl_set_rxon_ht); | |||
780 | */ | 780 | */ |
781 | static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) | 781 | static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) |
782 | { | 782 | { |
783 | if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { | 783 | if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent || |
784 | /* operated as 1x1 in full concurrency mode */ | 784 | priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { |
785 | /* | ||
786 | * only use chain 'A' in bt high traffic load or | ||
787 | * full concurrency mode | ||
788 | */ | ||
785 | return IWL_NUM_RX_CHAINS_SINGLE; | 789 | return IWL_NUM_RX_CHAINS_SINGLE; |
786 | } | 790 | } |
787 | /* # of Rx chains to use when expecting MIMO. */ | 791 | /* # of Rx chains to use when expecting MIMO. */ |
@@ -845,8 +849,12 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) | |||
845 | else | 849 | else |
846 | active_chains = priv->hw_params.valid_rx_ant; | 850 | active_chains = priv->hw_params.valid_rx_ant; |
847 | 851 | ||
848 | if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { | 852 | if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent || |
849 | /* operated as 1x1 in full concurrency mode */ | 853 | priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { |
854 | /* | ||
855 | * only use chain 'A' in bt high traffic load or | ||
856 | * full concurrency mode | ||
857 | */ | ||
850 | active_chains = first_antenna(active_chains); | 858 | active_chains = first_antenna(active_chains); |
851 | } | 859 | } |
852 | 860 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1adb68e92e8d..8d5201ac80f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1367,6 +1367,7 @@ struct iwl_priv { | |||
1367 | }; | 1367 | }; |
1368 | 1368 | ||
1369 | /* bt coex */ | 1369 | /* bt coex */ |
1370 | u8 bt_status; | ||
1370 | u8 bt_traffic_load, notif_bt_traffic_load; | 1371 | u8 bt_traffic_load, notif_bt_traffic_load; |
1371 | bool bt_ch_announce; | 1372 | bool bt_ch_announce; |
1372 | bool bt_sco_active; | 1373 | bool bt_sco_active; |