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 &
......
This diff is collapsed.
...@@ -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