aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c113
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h1
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 ebf0c7ecef4..30dc1f33420 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 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. */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 989e4a70260..4410f820c2f 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 34cba38f1d0..c43124c997c 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 */
781static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) 781static 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 1adb68e92e8..8d5201ac80f 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;