diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 9fda0c7aa9c7..f3180cf63843 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -921,6 +921,24 @@ u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm, return LINK_QUAL_AGG_TIME_LIMIT_BT_ACT; } +bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm, + struct ieee80211_sta *sta) +{ + struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; + + if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < + BT_HIGH_TRAFFIC) + return true; + + /* + * In Tight, BT can't Rx while we Tx, so use both antennas since BT is + * already killed. + * In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while we + * Tx. + */ + return iwl_get_coex_type(mvm, mvmsta->vif) == BT_COEX_TIGHT_LUT; +} + void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm) { if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX)) diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 5b1c91c009b0..28d93051af2c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -820,6 +820,9 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm); u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm, struct ieee80211_sta *sta); +bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm, + struct ieee80211_sta *sta); + enum iwl_bt_kill_msk { BT_KILL_MSK_DEFAULT, BT_KILL_MSK_SCO_HID_A2DP, diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 0faeecc0ab1c..a0b4cc8d9c3b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -1402,29 +1402,9 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm, u8 update_search_tbl_counter = 0; int ret; - switch (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)) { - case IWL_BT_COEX_TRAFFIC_LOAD_NONE: - /* nothing */ - break; - case IWL_BT_COEX_TRAFFIC_LOAD_LOW: - /* avoid switching to antenna B but allow MIMO */ - if (tbl->action == IWL_SISO_SWITCH_ANTENNA && - tbl->ant_type == ANT_A) - tbl->action = IWL_SISO_SWITCH_MIMO2; - break; - case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: - case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: - /* A - avoid antenna B and MIMO. B - switch to A */ - if (tbl->ant_type == ANT_A) - valid_tx_ant = - first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); + if (tbl->action == IWL_SISO_SWITCH_MIMO2 && + !iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) tbl->action = IWL_SISO_SWITCH_ANTENNA; - break; - default: - IWL_ERR(mvm, "Invalid BT load %d", - le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)); - break; - } start_action = tbl->action; while (1) { @@ -1519,27 +1499,6 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm, u8 update_search_tbl_counter = 0; int ret; - switch (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)) { - 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_A; - break; - default: - IWL_ERR(mvm, "Invalid BT load %d", - le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)); - break; - } - start_action = tbl->action; while (1) { lq_sta->action_counter++;