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.c294
1 files changed, 259 insertions, 35 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index a4563389bad..57629fba3a7 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
@@ -301,7 +301,19 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
301 struct ieee80211_sta *sta) 301 struct ieee80211_sta *sta)
302{ 302{
303 int ret = -EAGAIN; 303 int ret = -EAGAIN;
304 u32 load = rs_tl_get_load(lq_data, tid); 304 u32 load;
305
306 /*
307 * Don't create TX aggregation sessions when in high
308 * BT traffic, as they would just be disrupted by BT.
309 */
310 if (priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) {
311 IWL_ERR(priv, "BT traffic (%d), no aggregation allowed\n",
312 priv->bt_traffic_load);
313 return ret;
314 }
315
316 load = rs_tl_get_load(lq_data, tid);
305 317
306 if (load > IWL_AGG_LOAD_THRESHOLD) { 318 if (load > IWL_AGG_LOAD_THRESHOLD) {
307 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", 319 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
@@ -590,11 +602,13 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
590 * Green-field mode is valid if the station supports it and 602 * Green-field mode is valid if the station supports it and
591 * there are no non-GF stations present in the BSS. 603 * there are no non-GF stations present in the BSS.
592 */ 604 */
593static inline u8 rs_use_green(struct ieee80211_sta *sta, 605static bool rs_use_green(struct ieee80211_sta *sta)
594 struct iwl_ht_config *ht_conf)
595{ 606{
607 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
608 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
609
596 return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && 610 return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
597 !(ht_conf->non_GF_STA_present); 611 !(ctx->ht.non_gf_sta_present);
598} 612}
599 613
600/** 614/**
@@ -746,6 +760,32 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a,
746 (a->is_SGI == b->is_SGI); 760 (a->is_SGI == b->is_SGI);
747} 761}
748 762
763static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
764 struct iwl_lq_sta *lq_sta)
765{
766 struct iwl_scale_tbl_info *tbl;
767 bool full_concurrent;
768 unsigned long flags;
769
770 spin_lock_irqsave(&priv->lock, flags);
771 if (priv->bt_ci_compliance && priv->bt_ant_couple_ok)
772 full_concurrent = true;
773 else
774 full_concurrent = false;
775 spin_unlock_irqrestore(&priv->lock, flags);
776
777 if (priv->bt_full_concurrent != full_concurrent) {
778 priv->bt_full_concurrent = full_concurrent;
779
780 /* Update uCode's rate table. */
781 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
782 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
783 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
784
785 queue_work(priv->workqueue, &priv->bt_full_concurrency);
786 }
787}
788
749/* 789/*
750 * mac80211 sends us Tx status 790 * mac80211 sends us Tx status
751 */ 791 */
@@ -765,6 +805,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
765 u32 tx_rate; 805 u32 tx_rate;
766 struct iwl_scale_tbl_info tbl_type; 806 struct iwl_scale_tbl_info tbl_type;
767 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; 807 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
808 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
809 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
768 810
769 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); 811 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
770 812
@@ -831,7 +873,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
831 lq_sta->missed_rate_counter++; 873 lq_sta->missed_rate_counter++;
832 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { 874 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
833 lq_sta->missed_rate_counter = 0; 875 lq_sta->missed_rate_counter = 0;
834 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); 876 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
835 } 877 }
836 /* Regardless, ignore this status info for outdated rate */ 878 /* Regardless, ignore this status info for outdated rate */
837 return; 879 return;
@@ -862,7 +904,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
862 * no matching table found, let's by-pass the data collection 904 * no matching table found, let's by-pass the data collection
863 * and continue to perform rate scale to find the rate table 905 * and continue to perform rate scale to find the rate table
864 */ 906 */
865 rs_stay_in_table(lq_sta); 907 rs_stay_in_table(lq_sta, true);
866 goto done; 908 goto done;
867 } 909 }
868 910
@@ -928,6 +970,10 @@ done:
928 /* See if there's a better rate or modulation mode to try. */ 970 /* See if there's a better rate or modulation mode to try. */
929 if (sta && sta->supp_rates[sband->band]) 971 if (sta && sta->supp_rates[sband->band])
930 rs_rate_scale_perform(priv, skb, sta, lq_sta); 972 rs_rate_scale_perform(priv, skb, sta, lq_sta);
973
974 /* Is there a need to switch between full concurrency and 3-wire? */
975 if (priv->bt_ant_couple_ok)
976 rs_bt_update_lq(priv, ctx, lq_sta);
931} 977}
932 978
933/* 979/*
@@ -1121,6 +1167,8 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
1121 u16 rate_mask; 1167 u16 rate_mask;
1122 s32 rate; 1168 s32 rate;
1123 s8 is_green = lq_sta->is_green; 1169 s8 is_green = lq_sta->is_green;
1170 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
1171 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
1124 1172
1125 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) 1173 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
1126 return -1; 1174 return -1;
@@ -1141,7 +1189,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
1141 tbl->max_search = IWL_MAX_SEARCH; 1189 tbl->max_search = IWL_MAX_SEARCH;
1142 rate_mask = lq_sta->active_mimo2_rate; 1190 rate_mask = lq_sta->active_mimo2_rate;
1143 1191
1144 if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap)) 1192 if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
1145 tbl->is_ht40 = 1; 1193 tbl->is_ht40 = 1;
1146 else 1194 else
1147 tbl->is_ht40 = 0; 1195 tbl->is_ht40 = 0;
@@ -1175,6 +1223,8 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
1175 u16 rate_mask; 1223 u16 rate_mask;
1176 s32 rate; 1224 s32 rate;
1177 s8 is_green = lq_sta->is_green; 1225 s8 is_green = lq_sta->is_green;
1226 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
1227 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
1178 1228
1179 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) 1229 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
1180 return -1; 1230 return -1;
@@ -1195,7 +1245,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
1195 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH; 1245 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
1196 rate_mask = lq_sta->active_mimo3_rate; 1246 rate_mask = lq_sta->active_mimo3_rate;
1197 1247
1198 if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap)) 1248 if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
1199 tbl->is_ht40 = 1; 1249 tbl->is_ht40 = 1;
1200 else 1250 else
1201 tbl->is_ht40 = 0; 1251 tbl->is_ht40 = 0;
@@ -1230,6 +1280,8 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
1230 u16 rate_mask; 1280 u16 rate_mask;
1231 u8 is_green = lq_sta->is_green; 1281 u8 is_green = lq_sta->is_green;
1232 s32 rate; 1282 s32 rate;
1283 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
1284 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
1233 1285
1234 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) 1286 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
1235 return -1; 1287 return -1;
@@ -1242,7 +1294,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
1242 tbl->max_search = IWL_MAX_SEARCH; 1294 tbl->max_search = IWL_MAX_SEARCH;
1243 rate_mask = lq_sta->active_siso_rate; 1295 rate_mask = lq_sta->active_siso_rate;
1244 1296
1245 if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap)) 1297 if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
1246 tbl->is_ht40 = 1; 1298 tbl->is_ht40 = 1;
1247 else 1299 else
1248 tbl->is_ht40 = 0; 1300 tbl->is_ht40 = 0;
@@ -1286,12 +1338,45 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1286 int ret = 0; 1338 int ret = 0;
1287 u8 update_search_tbl_counter = 0; 1339 u8 update_search_tbl_counter = 0;
1288 1340
1341 switch (priv->bt_traffic_load) {
1342 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1343 /* nothing */
1344 break;
1345 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1346 /* avoid antenna B unless MIMO */
1347 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1348 if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2)
1349 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1350 break;
1351 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1352 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1353 /* avoid antenna B and MIMO */
1354 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1355 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 &&
1356 tbl->action != IWL_LEGACY_SWITCH_SISO)
1357 tbl->action = IWL_LEGACY_SWITCH_SISO;
1358 break;
1359 default:
1360 IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
1361 break;
1362 }
1363
1289 if (!iwl_ht_enabled(priv)) 1364 if (!iwl_ht_enabled(priv))
1290 /* stay in Legacy */ 1365 /* stay in Legacy */
1291 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; 1366 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1292 else if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE && 1367 else if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&
1293 tbl->action > IWL_LEGACY_SWITCH_SISO) 1368 tbl->action > IWL_LEGACY_SWITCH_SISO)
1294 tbl->action = IWL_LEGACY_SWITCH_SISO; 1369 tbl->action = IWL_LEGACY_SWITCH_SISO;
1370
1371 /* configure as 1x1 if bt full concurrency */
1372 if (priv->bt_full_concurrent) {
1373 if (!iwl_ht_enabled(priv))
1374 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1375 else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
1376 tbl->action = IWL_LEGACY_SWITCH_SISO;
1377 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1378 }
1379
1295 start_action = tbl->action; 1380 start_action = tbl->action;
1296 for (; ;) { 1381 for (; ;) {
1297 lq_sta->action_counter++; 1382 lq_sta->action_counter++;
@@ -1307,7 +1392,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1307 break; 1392 break;
1308 1393
1309 /* Don't change antenna if success has been great */ 1394 /* Don't change antenna if success has been great */
1310 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1395 if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
1396 !priv->bt_full_concurrent &&
1397 priv->bt_traffic_load ==
1398 IWL_BT_COEX_TRAFFIC_LOAD_NONE)
1311 break; 1399 break;
1312 1400
1313 /* Set up search table to try other antenna */ 1401 /* Set up search table to try other antenna */
@@ -1425,11 +1513,41 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1425 u8 update_search_tbl_counter = 0; 1513 u8 update_search_tbl_counter = 0;
1426 int ret; 1514 int ret;
1427 1515
1516 switch (priv->bt_traffic_load) {
1517 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1518 /* nothing */
1519 break;
1520 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1521 /* avoid antenna B unless MIMO */
1522 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1523 if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)
1524 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1525 break;
1526 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1527 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1528 /* avoid antenna B and MIMO */
1529 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1530 if (tbl->action != IWL_SISO_SWITCH_ANTENNA1)
1531 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1532 break;
1533 default:
1534 IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
1535 break;
1536 }
1537
1428 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE && 1538 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&
1429 tbl->action > IWL_SISO_SWITCH_ANTENNA2) { 1539 tbl->action > IWL_SISO_SWITCH_ANTENNA2) {
1430 /* stay in SISO */ 1540 /* stay in SISO */
1431 tbl->action = IWL_SISO_SWITCH_ANTENNA1; 1541 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1432 } 1542 }
1543
1544 /* configure as 1x1 if bt full concurrency */
1545 if (priv->bt_full_concurrent) {
1546 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1547 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
1548 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1549 }
1550
1433 start_action = tbl->action; 1551 start_action = tbl->action;
1434 for (;;) { 1552 for (;;) {
1435 lq_sta->action_counter++; 1553 lq_sta->action_counter++;
@@ -1437,14 +1555,16 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1437 case IWL_SISO_SWITCH_ANTENNA1: 1555 case IWL_SISO_SWITCH_ANTENNA1:
1438 case IWL_SISO_SWITCH_ANTENNA2: 1556 case IWL_SISO_SWITCH_ANTENNA2:
1439 IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n"); 1557 IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n");
1440
1441 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 && 1558 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
1442 tx_chains_num <= 1) || 1559 tx_chains_num <= 1) ||
1443 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 && 1560 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
1444 tx_chains_num <= 2)) 1561 tx_chains_num <= 2))
1445 break; 1562 break;
1446 1563
1447 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1564 if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
1565 !priv->bt_full_concurrent &&
1566 priv->bt_traffic_load ==
1567 IWL_BT_COEX_TRAFFIC_LOAD_NONE)
1448 break; 1568 break;
1449 1569
1450 memcpy(search_tbl, tbl, sz); 1570 memcpy(search_tbl, tbl, sz);
@@ -1564,12 +1684,40 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
1564 u8 update_search_tbl_counter = 0; 1684 u8 update_search_tbl_counter = 0;
1565 int ret; 1685 int ret;
1566 1686
1687 switch (priv->bt_traffic_load) {
1688 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1689 /* nothing */
1690 break;
1691 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1692 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1693 /* avoid antenna B and MIMO */
1694 if (tbl->action != IWL_MIMO2_SWITCH_SISO_A)
1695 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1696 break;
1697 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1698 /* avoid antenna B unless MIMO */
1699 if (tbl->action == IWL_MIMO2_SWITCH_SISO_B ||
1700 tbl->action == IWL_MIMO2_SWITCH_SISO_C)
1701 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1702 break;
1703 default:
1704 IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
1705 break;
1706 }
1707
1567 if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) && 1708 if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&
1568 (tbl->action < IWL_MIMO2_SWITCH_SISO_A || 1709 (tbl->action < IWL_MIMO2_SWITCH_SISO_A ||
1569 tbl->action > IWL_MIMO2_SWITCH_SISO_C)) { 1710 tbl->action > IWL_MIMO2_SWITCH_SISO_C)) {
1570 /* switch in SISO */ 1711 /* switch in SISO */
1571 tbl->action = IWL_MIMO2_SWITCH_SISO_A; 1712 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1572 } 1713 }
1714
1715 /* configure as 1x1 if bt full concurrency */
1716 if (priv->bt_full_concurrent &&
1717 (tbl->action < IWL_MIMO2_SWITCH_SISO_A ||
1718 tbl->action > IWL_MIMO2_SWITCH_SISO_C))
1719 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1720
1573 start_action = tbl->action; 1721 start_action = tbl->action;
1574 for (;;) { 1722 for (;;) {
1575 lq_sta->action_counter++; 1723 lq_sta->action_counter++;
@@ -1706,12 +1854,40 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1706 int ret; 1854 int ret;
1707 u8 update_search_tbl_counter = 0; 1855 u8 update_search_tbl_counter = 0;
1708 1856
1857 switch (priv->bt_traffic_load) {
1858 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1859 /* nothing */
1860 break;
1861 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1862 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1863 /* avoid antenna B and MIMO */
1864 if (tbl->action != IWL_MIMO3_SWITCH_SISO_A)
1865 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1866 break;
1867 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1868 /* avoid antenna B unless MIMO */
1869 if (tbl->action == IWL_MIMO3_SWITCH_SISO_B ||
1870 tbl->action == IWL_MIMO3_SWITCH_SISO_C)
1871 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1872 break;
1873 default:
1874 IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
1875 break;
1876 }
1877
1709 if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) && 1878 if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&
1710 (tbl->action < IWL_MIMO3_SWITCH_SISO_A || 1879 (tbl->action < IWL_MIMO3_SWITCH_SISO_A ||
1711 tbl->action > IWL_MIMO3_SWITCH_SISO_C)) { 1880 tbl->action > IWL_MIMO3_SWITCH_SISO_C)) {
1712 /* switch in SISO */ 1881 /* switch in SISO */
1713 tbl->action = IWL_MIMO3_SWITCH_SISO_A; 1882 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1714 } 1883 }
1884
1885 /* configure as 1x1 if bt full concurrency */
1886 if (priv->bt_full_concurrent &&
1887 (tbl->action < IWL_MIMO3_SWITCH_SISO_A ||
1888 tbl->action > IWL_MIMO3_SWITCH_SISO_C))
1889 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1890
1715 start_action = tbl->action; 1891 start_action = tbl->action;
1716 for (;;) { 1892 for (;;) {
1717 lq_sta->action_counter++; 1893 lq_sta->action_counter++;
@@ -1839,7 +2015,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1839 * 2) # times calling this function 2015 * 2) # times calling this function
1840 * 3) elapsed time in this mode (not used, for now) 2016 * 3) elapsed time in this mode (not used, for now)
1841 */ 2017 */
1842static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) 2018static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1843{ 2019{
1844 struct iwl_scale_tbl_info *tbl; 2020 struct iwl_scale_tbl_info *tbl;
1845 int i; 2021 int i;
@@ -1870,7 +2046,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
1870 * allow a new search. Also (below) reset all bitmaps and 2046 * allow a new search. Also (below) reset all bitmaps and
1871 * stats in active history. 2047 * stats in active history.
1872 */ 2048 */
1873 if ((lq_sta->total_failed > lq_sta->max_failure_limit) || 2049 if (force_search ||
2050 (lq_sta->total_failed > lq_sta->max_failure_limit) ||
1874 (lq_sta->total_success > lq_sta->max_success_limit) || 2051 (lq_sta->total_success > lq_sta->max_success_limit) ||
1875 ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer) 2052 ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
1876 && (flush_interval_passed))) { 2053 && (flush_interval_passed))) {
@@ -1919,6 +2096,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
1919 * return rate_n_flags as used in the table 2096 * return rate_n_flags as used in the table
1920 */ 2097 */
1921static u32 rs_update_rate_tbl(struct iwl_priv *priv, 2098static u32 rs_update_rate_tbl(struct iwl_priv *priv,
2099 struct iwl_rxon_context *ctx,
1922 struct iwl_lq_sta *lq_sta, 2100 struct iwl_lq_sta *lq_sta,
1923 struct iwl_scale_tbl_info *tbl, 2101 struct iwl_scale_tbl_info *tbl,
1924 int index, u8 is_green) 2102 int index, u8 is_green)
@@ -1928,7 +2106,7 @@ static u32 rs_update_rate_tbl(struct iwl_priv *priv,
1928 /* Update uCode's rate table. */ 2106 /* Update uCode's rate table. */
1929 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); 2107 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
1930 rs_fill_link_cmd(priv, lq_sta, rate); 2108 rs_fill_link_cmd(priv, lq_sta, rate);
1931 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); 2109 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
1932 2110
1933 return rate; 2111 return rate;
1934} 2112}
@@ -1967,6 +2145,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1967 s32 sr; 2145 s32 sr;
1968 u8 tid = MAX_TID_COUNT; 2146 u8 tid = MAX_TID_COUNT;
1969 struct iwl_tid_data *tid_data; 2147 struct iwl_tid_data *tid_data;
2148 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
2149 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
1970 2150
1971 IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n"); 2151 IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
1972 2152
@@ -2005,7 +2185,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2005 if (is_legacy(tbl->lq_type)) 2185 if (is_legacy(tbl->lq_type))
2006 lq_sta->is_green = 0; 2186 lq_sta->is_green = 0;
2007 else 2187 else
2008 lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config); 2188 lq_sta->is_green = rs_use_green(sta);
2009 is_green = lq_sta->is_green; 2189 is_green = lq_sta->is_green;
2010 2190
2011 /* current tx rate */ 2191 /* current tx rate */
@@ -2044,7 +2224,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2044 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 2224 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2045 /* get "active" rate info */ 2225 /* get "active" rate info */
2046 index = iwl_hwrate_to_plcp_idx(tbl->current_rate); 2226 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
2047 rate = rs_update_rate_tbl(priv, lq_sta, 2227 rate = rs_update_rate_tbl(priv, ctx, lq_sta,
2048 tbl, index, is_green); 2228 tbl, index, is_green);
2049 } 2229 }
2050 return; 2230 return;
@@ -2086,7 +2266,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2086 2266
2087 /* Should we stay with this modulation mode, 2267 /* Should we stay with this modulation mode,
2088 * or search for a new one? */ 2268 * or search for a new one? */
2089 rs_stay_in_table(lq_sta); 2269 rs_stay_in_table(lq_sta, false);
2090 2270
2091 goto out; 2271 goto out;
2092 } 2272 }
@@ -2234,6 +2414,28 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2234 if (iwl_tx_ant_restriction(priv) != IWL_ANT_OK_MULTI && 2414 if (iwl_tx_ant_restriction(priv) != IWL_ANT_OK_MULTI &&
2235 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) 2415 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type)))
2236 scale_action = -1; 2416 scale_action = -1;
2417
2418 if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
2419 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
2420 if (lq_sta->last_bt_traffic > priv->bt_traffic_load) {
2421 /*
2422 * don't set scale_action, don't want to scale up if
2423 * the rate scale doesn't otherwise think that is a
2424 * good idea.
2425 */
2426 } else if (lq_sta->last_bt_traffic <= priv->bt_traffic_load) {
2427 scale_action = -1;
2428 }
2429 }
2430 lq_sta->last_bt_traffic = priv->bt_traffic_load;
2431
2432 if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
2433 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
2434 /* search for a new modulation */
2435 rs_stay_in_table(lq_sta, true);
2436 goto lq_update;
2437 }
2438
2237 switch (scale_action) { 2439 switch (scale_action) {
2238 case -1: 2440 case -1:
2239 /* Decrease starting rate, update uCode's rate table */ 2441 /* Decrease starting rate, update uCode's rate table */
@@ -2264,13 +2466,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2264lq_update: 2466lq_update:
2265 /* Replace uCode's rate table for the destination station. */ 2467 /* Replace uCode's rate table for the destination station. */
2266 if (update_lq) 2468 if (update_lq)
2267 rate = rs_update_rate_tbl(priv, lq_sta, 2469 rate = rs_update_rate_tbl(priv, ctx, lq_sta,
2268 tbl, index, is_green); 2470 tbl, index, is_green);
2269 2471
2270 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) { 2472 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) {
2271 /* Should we stay with this modulation mode, 2473 /* Should we stay with this modulation mode,
2272 * or search for a new one? */ 2474 * or search for a new one? */
2273 rs_stay_in_table(lq_sta); 2475 rs_stay_in_table(lq_sta, false);
2274 } 2476 }
2275 /* 2477 /*
2276 * Search for new modulation mode if we're: 2478 * Search for new modulation mode if we're:
@@ -2306,7 +2508,7 @@ lq_update:
2306 IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n", 2508 IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n",
2307 tbl->current_rate, index); 2509 tbl->current_rate, index);
2308 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); 2510 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
2309 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); 2511 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
2310 } else 2512 } else
2311 done_search = 1; 2513 done_search = 1;
2312 } 2514 }
@@ -2376,12 +2578,17 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2376 int rate_idx; 2578 int rate_idx;
2377 int i; 2579 int i;
2378 u32 rate; 2580 u32 rate;
2379 u8 use_green = rs_use_green(sta, &priv->current_ht_config); 2581 u8 use_green = rs_use_green(sta);
2380 u8 active_tbl = 0; 2582 u8 active_tbl = 0;
2381 u8 valid_tx_ant; 2583 u8 valid_tx_ant;
2584 struct iwl_station_priv *sta_priv;
2585 struct iwl_rxon_context *ctx;
2382 2586
2383 if (!sta || !lq_sta) 2587 if (!sta || !lq_sta)
2384 goto out; 2588 return;
2589
2590 sta_priv = (void *)sta->drv_priv;
2591 ctx = sta_priv->common.ctx;
2385 2592
2386 i = lq_sta->last_txrate_idx; 2593 i = lq_sta->last_txrate_idx;
2387 2594
@@ -2413,9 +2620,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2413 rs_set_expected_tpt_table(lq_sta, tbl); 2620 rs_set_expected_tpt_table(lq_sta, tbl);
2414 rs_fill_link_cmd(NULL, lq_sta, rate); 2621 rs_fill_link_cmd(NULL, lq_sta, rate);
2415 priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq; 2622 priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq;
2416 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_SYNC, true); 2623 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_SYNC, true);
2417 out:
2418 return;
2419} 2624}
2420 2625
2421static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, 2626static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
@@ -2543,7 +2748,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
2543 lq_sta->is_dup = 0; 2748 lq_sta->is_dup = 0;
2544 lq_sta->max_rate_idx = -1; 2749 lq_sta->max_rate_idx = -1;
2545 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; 2750 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
2546 lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config); 2751 lq_sta->is_green = rs_use_green(sta);
2547 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); 2752 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
2548 lq_sta->band = priv->band; 2753 lq_sta->band = priv->band;
2549 /* 2754 /*
@@ -2616,6 +2821,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2616 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, 2821 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
2617 &tbl_type, &rate_idx); 2822 &tbl_type, &rate_idx);
2618 2823
2824 if (priv && priv->bt_full_concurrent) {
2825 /* 1x1 only */
2826 tbl_type.ant_type =
2827 first_antenna(priv->hw_params.valid_tx_ant);
2828 }
2829
2619 /* How many times should we repeat the initial rate? */ 2830 /* How many times should we repeat the initial rate? */
2620 if (is_legacy(tbl_type.lq_type)) { 2831 if (is_legacy(tbl_type.lq_type)) {
2621 ant_toggle_cnt = 1; 2832 ant_toggle_cnt = 1;
@@ -2640,9 +2851,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2640 2851
2641 index++; 2852 index++;
2642 repeat_rate--; 2853 repeat_rate--;
2643 2854 if (priv) {
2644 if (priv) 2855 if (priv->bt_full_concurrent)
2645 valid_tx_ant = priv->hw_params.valid_tx_ant; 2856 valid_tx_ant = ANT_A;
2857 else
2858 valid_tx_ant = priv->hw_params.valid_tx_ant;
2859 }
2646 2860
2647 /* Fill rest of rate table */ 2861 /* Fill rest of rate table */
2648 while (index < LINK_QUAL_MAX_RETRY_NUM) { 2862 while (index < LINK_QUAL_MAX_RETRY_NUM) {
@@ -2657,7 +2871,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2657 rs_toggle_antenna(valid_tx_ant, 2871 rs_toggle_antenna(valid_tx_ant,
2658 &new_rate, &tbl_type)) 2872 &new_rate, &tbl_type))
2659 ant_toggle_cnt = 1; 2873 ant_toggle_cnt = 1;
2660} 2874 }
2661 2875
2662 /* Override next rate if needed for debug purposes */ 2876 /* Override next rate if needed for debug purposes */
2663 rs_dbgfs_set_mcs(lq_sta, &new_rate, index); 2877 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
@@ -2672,6 +2886,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2672 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, 2886 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,
2673 &rate_idx); 2887 &rate_idx);
2674 2888
2889 if (priv && priv->bt_full_concurrent) {
2890 /* 1x1 only */
2891 tbl_type.ant_type =
2892 first_antenna(priv->hw_params.valid_tx_ant);
2893 }
2894
2675 /* Indicate to uCode which entries might be MIMO. 2895 /* Indicate to uCode which entries might be MIMO.
2676 * If initial rate was MIMO, this will finally end up 2896 * If initial rate was MIMO, this will finally end up
2677 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ 2897 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
@@ -2788,6 +3008,9 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2788 char buf[64]; 3008 char buf[64];
2789 int buf_size; 3009 int buf_size;
2790 u32 parsed_rate; 3010 u32 parsed_rate;
3011 struct iwl_station_priv *sta_priv =
3012 container_of(lq_sta, struct iwl_station_priv, lq_sta);
3013 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
2791 3014
2792 priv = lq_sta->drv; 3015 priv = lq_sta->drv;
2793 memset(buf, 0, sizeof(buf)); 3016 memset(buf, 0, sizeof(buf));
@@ -2810,7 +3033,8 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2810 3033
2811 if (lq_sta->dbg_fixed_rate) { 3034 if (lq_sta->dbg_fixed_rate) {
2812 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); 3035 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
2813 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false); 3036 iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC,
3037 false);
2814 } 3038 }
2815 3039
2816 return count; 3040 return count;