Commit da5dbb97 authored by Wey-Yi Guy's avatar Wey-Yi Guy Committed by John W. Linville

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: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent f37837c9
...@@ -428,6 +428,9 @@ static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work) ...@@ -428,6 +428,9 @@ static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work)
container_of(work, struct iwl_priv, bt_traffic_change_work); container_of(work, struct iwl_priv, bt_traffic_change_work);
int smps_request = -1; int smps_request = -1;
IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n",
priv->bt_traffic_load);
switch (priv->bt_traffic_load) { switch (priv->bt_traffic_load) {
case IWL_BT_COEX_TRAFFIC_LOAD_NONE: case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
smps_request = IEEE80211_SMPS_AUTOMATIC; smps_request = IEEE80211_SMPS_AUTOMATIC;
...@@ -447,6 +450,9 @@ static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work) ...@@ -447,6 +450,9 @@ static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work)
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
if (priv->cfg->ops->lib->update_chain_flags)
priv->cfg->ops->lib->update_chain_flags(priv);
if (smps_request != -1 && if (smps_request != -1 &&
priv->vif && priv->vif->type == NL80211_IFTYPE_STATION) priv->vif && priv->vif->type == NL80211_IFTYPE_STATION)
ieee80211_request_smps(priv->vif, smps_request); ieee80211_request_smps(priv->vif, smps_request);
...@@ -549,6 +555,7 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, ...@@ -549,6 +555,7 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv,
struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 }; struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 };
struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
u8 last_traffic_load;
IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n");
IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); 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,16 +563,28 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv,
IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", coex->bt_ci_compliance); IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", coex->bt_ci_compliance);
iwlagn_print_uartmsg(priv, uart_msg); iwlagn_print_uartmsg(priv, uart_msg);
last_traffic_load = priv->notif_bt_traffic_load;
priv->notif_bt_traffic_load = coex->bt_traffic_load; priv->notif_bt_traffic_load = coex->bt_traffic_load;
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
if (coex->bt_traffic_load != priv->bt_traffic_load) { if (priv->bt_status != coex->bt_status ||
priv->bt_traffic_load = coex->bt_traffic_load; last_traffic_load != coex->bt_traffic_load) {
if (coex->bt_status) {
/* BT on */
if (!priv->bt_ch_announce)
priv->bt_traffic_load =
IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
else
priv->bt_traffic_load =
coex->bt_traffic_load;
} else {
/* BT off */
priv->bt_traffic_load =
IWL_BT_COEX_TRAFFIC_LOAD_NONE;
}
priv->bt_status = coex->bt_status;
queue_work(priv->workqueue, queue_work(priv->workqueue,
&priv->bt_traffic_change_work); &priv->bt_traffic_change_work);
} }
if (priv->bt_sco_active != if (priv->bt_sco_active !=
(uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) { (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) {
priv->bt_sco_active = uart_msg->frame3 & priv->bt_sco_active = uart_msg->frame3 &
......
...@@ -82,7 +82,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, ...@@ -82,7 +82,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta); struct iwl_lq_sta *lq_sta);
static void rs_fill_link_cmd(struct iwl_priv *priv, static void rs_fill_link_cmd(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta, u32 rate_n_flags); struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
static void rs_stay_in_table(struct iwl_lq_sta *lq_sta); static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
#ifdef CONFIG_MAC80211_DEBUGFS #ifdef CONFIG_MAC80211_DEBUGFS
...@@ -900,7 +900,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, ...@@ -900,7 +900,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
* no matching table found, let's by-pass the data collection * no matching table found, let's by-pass the data collection
* and continue to perform rate scale to find the rate table * and continue to perform rate scale to find the rate table
*/ */
rs_stay_in_table(lq_sta); rs_stay_in_table(lq_sta, true);
goto done; goto done;
} }
...@@ -1334,15 +1334,17 @@ static int rs_move_legacy_other(struct iwl_priv *priv, ...@@ -1334,15 +1334,17 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
break; break;
case IWL_BT_COEX_TRAFFIC_LOAD_LOW: case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
/* avoid antenna B unless MIMO */ /* avoid antenna B unless MIMO */
valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2) if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2)
tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
break; break;
case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
/* avoid antenna B and MIMO */ /* avoid antenna B and MIMO */
valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 &&
tbl->action != IWL_LEGACY_SWITCH_SISO) tbl->action != IWL_LEGACY_SWITCH_SISO)
tbl->action = IWL_SISO_SWITCH_ANTENNA1; tbl->action = IWL_LEGACY_SWITCH_SISO;
break; break;
default: default:
IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); 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,6 +1364,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
tbl->action = IWL_LEGACY_SWITCH_SISO; tbl->action = IWL_LEGACY_SWITCH_SISO;
valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
} }
start_action = tbl->action; start_action = tbl->action;
...@@ -1379,7 +1382,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv, ...@@ -1379,7 +1382,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
break; break;
/* Don't change antenna if success has been great */ /* Don't change antenna if success has been great */
if (window->success_ratio >= IWL_RS_GOOD_RATIO) if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
!priv->bt_full_concurrent &&
priv->bt_traffic_load ==
IWL_BT_COEX_TRAFFIC_LOAD_NONE)
break; break;
/* Set up search table to try other antenna */ /* Set up search table to try other antenna */
...@@ -1503,14 +1509,15 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, ...@@ -1503,14 +1509,15 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
break; break;
case IWL_BT_COEX_TRAFFIC_LOAD_LOW: case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
/* avoid antenna B unless MIMO */ /* avoid antenna B unless MIMO */
valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
if (tbl->action == IWL_SISO_SWITCH_ANTENNA2) if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)
tbl->action = IWL_SISO_SWITCH_ANTENNA1; tbl->action = IWL_SISO_SWITCH_ANTENNA1;
break; break;
case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
/* avoid antenna B and MIMO */ /* avoid antenna B and MIMO */
if (tbl->action >= IWL_SISO_SWITCH_ANTENNA2 && valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
tbl->action != IWL_SISO_SWITCH_GI) if (tbl->action != IWL_SISO_SWITCH_ANTENNA1)
tbl->action = IWL_SISO_SWITCH_ANTENNA1; tbl->action = IWL_SISO_SWITCH_ANTENNA1;
break; break;
default: default:
...@@ -1525,9 +1532,11 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, ...@@ -1525,9 +1532,11 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
} }
/* configure as 1x1 if bt full concurrency */ /* configure as 1x1 if bt full concurrency */
if (priv->bt_full_concurrent && if (priv->bt_full_concurrent) {
tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
tbl->action = IWL_SISO_SWITCH_ANTENNA1; tbl->action = IWL_SISO_SWITCH_ANTENNA1;
}
start_action = tbl->action; start_action = tbl->action;
for (;;) { for (;;) {
...@@ -1536,14 +1545,16 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, ...@@ -1536,14 +1545,16 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
case IWL_SISO_SWITCH_ANTENNA1: case IWL_SISO_SWITCH_ANTENNA1:
case IWL_SISO_SWITCH_ANTENNA2: case IWL_SISO_SWITCH_ANTENNA2:
IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n"); IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n");
if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 && if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
tx_chains_num <= 1) || tx_chains_num <= 1) ||
(tbl->action == IWL_SISO_SWITCH_ANTENNA2 && (tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
tx_chains_num <= 2)) tx_chains_num <= 2))
break; break;
if (window->success_ratio >= IWL_RS_GOOD_RATIO) if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
!priv->bt_full_concurrent &&
priv->bt_traffic_load ==
IWL_BT_COEX_TRAFFIC_LOAD_NONE)
break; break;
memcpy(search_tbl, tbl, sz); memcpy(search_tbl, tbl, sz);
...@@ -1670,13 +1681,13 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, ...@@ -1670,13 +1681,13 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
/* avoid antenna B and MIMO */ /* avoid antenna B and MIMO */
if (tbl->action == IWL_MIMO2_SWITCH_MIMO3_ABC) if (tbl->action != IWL_MIMO2_SWITCH_SISO_A)
tbl->action = IWL_SISO_SWITCH_ANTENNA1; tbl->action = IWL_MIMO2_SWITCH_SISO_A;
break;
case IWL_BT_COEX_TRAFFIC_LOAD_LOW: case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
/* avoid antenna B unless MIMO */ /* avoid antenna B unless MIMO */
if (tbl->action == IWL_MIMO2_SWITCH_ANTENNA2) if (tbl->action == IWL_MIMO2_SWITCH_SISO_B ||
tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; tbl->action == IWL_MIMO2_SWITCH_SISO_C)
else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B)
tbl->action = IWL_MIMO2_SWITCH_SISO_A; tbl->action = IWL_MIMO2_SWITCH_SISO_A;
break; break;
default: default:
...@@ -1840,16 +1851,14 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, ...@@ -1840,16 +1851,14 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
/* avoid antenna B and MIMO */ /* avoid antenna B and MIMO */
if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB || if (tbl->action != IWL_MIMO3_SWITCH_SISO_A)
tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC ||
tbl->action == IWL_MIMO3_SWITCH_MIMO2_BC)
tbl->action = IWL_MIMO3_SWITCH_SISO_A; tbl->action = IWL_MIMO3_SWITCH_SISO_A;
break;
case IWL_BT_COEX_TRAFFIC_LOAD_LOW: case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
/* avoid antenna B unless MIMO */ /* avoid antenna B unless MIMO */
if (tbl->action == IWL_MIMO3_SWITCH_SISO_B) if (tbl->action == IWL_MIMO3_SWITCH_SISO_B ||
tbl->action == IWL_MIMO3_SWITCH_SISO_C)
tbl->action = IWL_MIMO3_SWITCH_SISO_A; tbl->action = IWL_MIMO3_SWITCH_SISO_A;
else if (tbl->action == IWL_MIMO3_SWITCH_ANTENNA2)
tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
break; break;
default: default:
IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); 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,7 +2005,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
* 2) # times calling this function * 2) # times calling this function
* 3) elapsed time in this mode (not used, for now) * 3) elapsed time in this mode (not used, for now)
*/ */
static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
{ {
struct iwl_scale_tbl_info *tbl; struct iwl_scale_tbl_info *tbl;
int i; int i;
...@@ -2027,7 +2036,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) ...@@ -2027,7 +2036,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
* allow a new search. Also (below) reset all bitmaps and * allow a new search. Also (below) reset all bitmaps and
* stats in active history. * stats in active history.
*/ */
if ((lq_sta->total_failed > lq_sta->max_failure_limit) || if (force_search ||
(lq_sta->total_failed > lq_sta->max_failure_limit) ||
(lq_sta->total_success > lq_sta->max_success_limit) || (lq_sta->total_success > lq_sta->max_success_limit) ||
((!lq_sta->search_better_tbl) && (lq_sta->flush_timer) ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
&& (flush_interval_passed))) { && (flush_interval_passed))) {
...@@ -2243,7 +2253,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, ...@@ -2243,7 +2253,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
/* Should we stay with this modulation mode, /* Should we stay with this modulation mode,
* or search for a new one? */ * or search for a new one? */
rs_stay_in_table(lq_sta); rs_stay_in_table(lq_sta, false);
goto out; goto out;
} }
...@@ -2392,17 +2402,26 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, ...@@ -2392,17 +2402,26 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
(is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type)))
scale_action = -1; scale_action = -1;
if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
(is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
if (lq_sta->last_bt_traffic > priv->bt_traffic_load) { if (lq_sta->last_bt_traffic > priv->bt_traffic_load) {
lq_sta->last_bt_traffic = priv->bt_traffic_load;
/* /*
* don't set scale_action, don't want to scale up if * don't set scale_action, don't want to scale up if
* the rate scale doesn't otherwise think that is a * the rate scale doesn't otherwise think that is a
* good idea. * good idea.
*/ */
} else if (lq_sta->last_bt_traffic < priv->bt_traffic_load) { } else if (lq_sta->last_bt_traffic <= priv->bt_traffic_load) {
lq_sta->last_bt_traffic = priv->bt_traffic_load;
scale_action = -1; scale_action = -1;
} }
}
lq_sta->last_bt_traffic = priv->bt_traffic_load;
if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
(is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
/* search for a new modulation */
rs_stay_in_table(lq_sta, true);
goto lq_update;
}
switch (scale_action) { switch (scale_action) {
case -1: case -1:
...@@ -2440,7 +2459,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, ...@@ -2440,7 +2459,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) { if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) {
/* Should we stay with this modulation mode, /* Should we stay with this modulation mode,
* or search for a new one? */ * or search for a new one? */
rs_stay_in_table(lq_sta); rs_stay_in_table(lq_sta, false);
} }
/* /*
* Search for new modulation mode if we're: * Search for new modulation mode if we're:
...@@ -2786,6 +2805,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, ...@@ -2786,6 +2805,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
&tbl_type, &rate_idx); &tbl_type, &rate_idx);
if (priv && priv->bt_full_concurrent) {
/* 1x1 only */
tbl_type.ant_type =
first_antenna(priv->hw_params.valid_tx_ant);
}
/* How many times should we repeat the initial rate? */ /* How many times should we repeat the initial rate? */
if (is_legacy(tbl_type.lq_type)) { if (is_legacy(tbl_type.lq_type)) {
ant_toggle_cnt = 1; ant_toggle_cnt = 1;
...@@ -2800,8 +2825,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, ...@@ -2800,8 +2825,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
/* Fill 1st table entry (index 0) */ /* Fill 1st table entry (index 0) */
lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate); lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate);
if (num_of_ant(tbl_type.ant_type) == 1 || if (num_of_ant(tbl_type.ant_type) == 1) {
(priv && priv->bt_full_concurrent)) {
lq_cmd->general_params.single_stream_ant_msk = lq_cmd->general_params.single_stream_ant_msk =
tbl_type.ant_type; tbl_type.ant_type;
} else if (num_of_ant(tbl_type.ant_type) == 2) { } 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,7 +2835,6 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
index++; index++;
repeat_rate--; repeat_rate--;
if (priv) { if (priv) {
if (priv->bt_full_concurrent) if (priv->bt_full_concurrent)
valid_tx_ant = ANT_A; valid_tx_ant = ANT_A;
...@@ -2832,7 +2855,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, ...@@ -2832,7 +2855,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
rs_toggle_antenna(valid_tx_ant, rs_toggle_antenna(valid_tx_ant,
&new_rate, &tbl_type)) &new_rate, &tbl_type))
ant_toggle_cnt = 1; ant_toggle_cnt = 1;
} }
/* Override next rate if needed for debug purposes */ /* Override next rate if needed for debug purposes */
rs_dbgfs_set_mcs(lq_sta, &new_rate, index); rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
...@@ -2847,6 +2870,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, ...@@ -2847,6 +2870,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,
&rate_idx); &rate_idx);
if (priv && priv->bt_full_concurrent) {
/* 1x1 only */
tbl_type.ant_type =
first_antenna(priv->hw_params.valid_tx_ant);
}
/* Indicate to uCode which entries might be MIMO. /* Indicate to uCode which entries might be MIMO.
* If initial rate was MIMO, this will finally end up * If initial rate was MIMO, this will finally end up
* as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
......
...@@ -2823,6 +2823,7 @@ static void __iwl_down(struct iwl_priv *priv) ...@@ -2823,6 +2823,7 @@ static void __iwl_down(struct iwl_priv *priv)
iwl_clear_driver_stations(priv); iwl_clear_driver_stations(priv);
/* reset BT coex data */ /* reset BT coex data */
priv->bt_status = 0;
priv->bt_traffic_load = priv->cfg->bt_init_traffic_load; priv->bt_traffic_load = priv->cfg->bt_init_traffic_load;
priv->bt_sco_active = false; priv->bt_sco_active = false;
priv->bt_full_concurrent = false; priv->bt_full_concurrent = false;
...@@ -3133,6 +3134,7 @@ static void iwl_bg_restart(struct work_struct *data) ...@@ -3133,6 +3134,7 @@ static void iwl_bg_restart(struct work_struct *data)
bool bt_sco, bt_full_concurrent; bool bt_sco, bt_full_concurrent;
u8 bt_ci_compliance; u8 bt_ci_compliance;
u8 bt_load; u8 bt_load;
u8 bt_status;
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
priv->vif = NULL; priv->vif = NULL;
...@@ -3151,6 +3153,7 @@ static void iwl_bg_restart(struct work_struct *data) ...@@ -3151,6 +3153,7 @@ static void iwl_bg_restart(struct work_struct *data)
bt_full_concurrent = priv->bt_full_concurrent; bt_full_concurrent = priv->bt_full_concurrent;
bt_ci_compliance = priv->bt_ci_compliance; bt_ci_compliance = priv->bt_ci_compliance;
bt_load = priv->bt_traffic_load; bt_load = priv->bt_traffic_load;
bt_status = priv->bt_status;
__iwl_down(priv); __iwl_down(priv);
...@@ -3158,6 +3161,7 @@ static void iwl_bg_restart(struct work_struct *data) ...@@ -3158,6 +3161,7 @@ static void iwl_bg_restart(struct work_struct *data)
priv->bt_full_concurrent = bt_full_concurrent; priv->bt_full_concurrent = bt_full_concurrent;
priv->bt_ci_compliance = bt_ci_compliance; priv->bt_ci_compliance = bt_ci_compliance;
priv->bt_traffic_load = bt_load; priv->bt_traffic_load = bt_load;
priv->bt_status = bt_status;
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
iwl_cancel_deferred_work(priv); iwl_cancel_deferred_work(priv);
......
...@@ -780,8 +780,12 @@ EXPORT_SYMBOL(iwl_set_rxon_ht); ...@@ -780,8 +780,12 @@ EXPORT_SYMBOL(iwl_set_rxon_ht);
*/ */
static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
{ {
if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent ||
/* operated as 1x1 in full concurrency mode */ priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
/*
* only use chain 'A' in bt high traffic load or
* full concurrency mode
*/
return IWL_NUM_RX_CHAINS_SINGLE; return IWL_NUM_RX_CHAINS_SINGLE;
} }
/* # of Rx chains to use when expecting MIMO. */ /* # of Rx chains to use when expecting MIMO. */
...@@ -845,8 +849,12 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) ...@@ -845,8 +849,12 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
else else
active_chains = priv->hw_params.valid_rx_ant; active_chains = priv->hw_params.valid_rx_ant;
if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent ||
/* operated as 1x1 in full concurrency mode */ priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
/*
* only use chain 'A' in bt high traffic load or
* full concurrency mode
*/
active_chains = first_antenna(active_chains); active_chains = first_antenna(active_chains);
} }
......
...@@ -1367,6 +1367,7 @@ struct iwl_priv { ...@@ -1367,6 +1367,7 @@ struct iwl_priv {
}; };
/* bt coex */ /* bt coex */
u8 bt_status;
u8 bt_traffic_load, notif_bt_traffic_load; u8 bt_traffic_load, notif_bt_traffic_load;
bool bt_ch_announce; bool bt_ch_announce;
bool bt_sco_active; bool bt_sco_active;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment