summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2013-05-28 23:12:47 +0300
committerJohannes Berg <johannes.berg@intel.com>2013-06-04 13:13:29 +0200
commit36946ce69abe8b5c7043708f832ca179dd6e4f64 (patch)
treed044328677187af167dcd2b81aad91375a5a2f75 /drivers/net/wireless/iwlwifi
parent7c8e4159bac47354ea9eee40ac7a0f713c0be5db (diff)
iwlwifi: mvm: don't enable MIMO when BT is active
Another step in the rate control / BT Coex integration Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c97
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h12
2 files changed, 108 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 20269994d8d..d6beec765d6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -1530,6 +1530,29 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
u8 update_search_tbl_counter = 0;
int ret;
+ switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ /* nothing */
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ /* avoid antenna B unless MIMO */
+ if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)
+ tbl->action = IWL_SISO_SWITCH_MIMO2_AB;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ /* avoid antenna B and MIMO */
+ valid_tx_ant =
+ first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
+ if (tbl->action != IWL_SISO_SWITCH_ANTENNA1)
+ tbl->action = IWL_SISO_SWITCH_ANTENNA1;
+ break;
+ default:
+ IWL_ERR(mvm, "Invalid BT load %d",
+ BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD));
+ break;
+ }
+
start_action = tbl->action;
while (1) {
lq_sta->action_counter++;
@@ -1543,7 +1566,9 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
tx_chains_num <= 2))
break;
- if (window->success_ratio >= IWL_RS_GOOD_RATIO)
+ if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
+ BT_MBOX_MSG(&mvm->last_bt_notif, 3,
+ TRAFFIC_LOAD) == 0)
break;
memcpy(search_tbl, tbl, sz);
@@ -1665,6 +1690,28 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
u8 update_search_tbl_counter = 0;
int ret;
+ switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ /* nothing */
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ /* avoid antenna B and MIMO */
+ if (tbl->action != IWL_MIMO2_SWITCH_SISO_A)
+ tbl->action = IWL_MIMO2_SWITCH_SISO_A;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ /* avoid antenna B unless MIMO */
+ if (tbl->action == IWL_MIMO2_SWITCH_SISO_B ||
+ tbl->action == IWL_MIMO2_SWITCH_SISO_C)
+ tbl->action = IWL_MIMO2_SWITCH_SISO_A;
+ break;
+ default:
+ IWL_ERR(mvm, "Invalid BT load %d",
+ BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD));
+ break;
+ }
+
start_action = tbl->action;
while (1) {
lq_sta->action_counter++;
@@ -1802,6 +1849,28 @@ static int rs_move_mimo3_to_other(struct iwl_mvm *mvm,
int ret;
u8 update_search_tbl_counter = 0;
+ switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ /* nothing */
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ /* avoid antenna B and MIMO */
+ if (tbl->action != IWL_MIMO3_SWITCH_SISO_A)
+ tbl->action = IWL_MIMO3_SWITCH_SISO_A;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ /* avoid antenna B unless MIMO */
+ if (tbl->action == IWL_MIMO3_SWITCH_SISO_B ||
+ tbl->action == IWL_MIMO3_SWITCH_SISO_C)
+ tbl->action = IWL_MIMO3_SWITCH_SISO_A;
+ break;
+ default:
+ IWL_ERR(mvm, "Invalid BT load %d",
+ BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD));
+ break;
+ }
+
start_action = tbl->action;
while (1) {
lq_sta->action_counter++;
@@ -2313,6 +2382,32 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
(current_tpt > (100 * tbl->expected_tpt[low]))))
scale_action = 0;
+ if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >=
+ IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
+ (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
+ if (lq_sta->last_bt_traffic >
+ BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
+ /*
+ * don't set scale_action, don't want to scale up if
+ * the rate scale doesn't otherwise think that is a
+ * good idea.
+ */
+ } else if (lq_sta->last_bt_traffic <=
+ BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
+ scale_action = -1;
+ }
+ }
+ lq_sta->last_bt_traffic =
+ BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD);
+
+ if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, 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) {
case -1:
/* Decrease starting rate, update uCode's rate table */
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index f66155a5723..cff4f6da773 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -358,6 +358,18 @@ struct iwl_lq_sta {
u8 last_bt_traffic;
};
+enum iwl_bt_coex_profile_traffic_load {
+ IWL_BT_COEX_TRAFFIC_LOAD_NONE = 0,
+ IWL_BT_COEX_TRAFFIC_LOAD_LOW = 1,
+ IWL_BT_COEX_TRAFFIC_LOAD_HIGH = 2,
+ IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS = 3,
+/*
+ * There are no more even though below is a u8, the
+ * indication from the BT device only has two bits.
+ */
+};
+
+
static inline u8 num_of_ant(u8 mask)
{
return !!((mask) & ANT_A) +