aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
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
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')
-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;