diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-rs.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 113 |
1 files changed, 71 insertions, 42 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 687b534d83d0..e78f3f0592d6 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, struct iwl_lq_sta *lq_sta); static void rs_fill_link_cmd(struct iwl_priv *priv, 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 @@ -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 * 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; } @@ -1334,15 +1334,17 @@ static int rs_move_legacy_other(struct iwl_priv *priv, break; case IWL_BT_COEX_TRAFFIC_LOAD_LOW: /* avoid antenna B unless MIMO */ + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2) tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; 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(priv->hw_params.valid_tx_ant); if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && tbl->action != IWL_LEGACY_SWITCH_SISO) - tbl->action = IWL_SISO_SWITCH_ANTENNA1; + tbl->action = IWL_LEGACY_SWITCH_SISO; break; default: 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, tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) tbl->action = IWL_LEGACY_SWITCH_SISO; + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); } start_action = tbl->action; @@ -1379,7 +1382,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv, break; /* 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; /* Set up search table to try other antenna */ @@ -1503,14 +1509,15 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, break; case IWL_BT_COEX_TRAFFIC_LOAD_LOW: /* avoid antenna B unless MIMO */ + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); if (tbl->action == IWL_SISO_SWITCH_ANTENNA2) tbl->action = IWL_SISO_SWITCH_ANTENNA1; break; case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: /* avoid antenna B and MIMO */ - if (tbl->action >= IWL_SISO_SWITCH_ANTENNA2 && - tbl->action != IWL_SISO_SWITCH_GI) + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); + if (tbl->action != IWL_SISO_SWITCH_ANTENNA1) tbl->action = IWL_SISO_SWITCH_ANTENNA1; break; default: @@ -1525,9 +1532,11 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, } /* configure as 1x1 if bt full concurrency */ - if (priv->bt_full_concurrent && - tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) - tbl->action = IWL_SISO_SWITCH_ANTENNA1; + if (priv->bt_full_concurrent) { + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); + if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + } start_action = tbl->action; for (;;) { @@ -1536,14 +1545,16 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, case IWL_SISO_SWITCH_ANTENNA1: case IWL_SISO_SWITCH_ANTENNA2: IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n"); - if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 && - tx_chains_num <= 1) || + tx_chains_num <= 1) || (tbl->action == IWL_SISO_SWITCH_ANTENNA2 && - tx_chains_num <= 2)) + tx_chains_num <= 2)) 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; memcpy(search_tbl, tbl, sz); @@ -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_CONTINUOUS: /* avoid antenna B and MIMO */ - if (tbl->action == IWL_MIMO2_SWITCH_MIMO3_ABC) - tbl->action = IWL_SISO_SWITCH_ANTENNA1; + 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_ANTENNA2) - tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; - else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B) + if (tbl->action == IWL_MIMO2_SWITCH_SISO_B || + tbl->action == IWL_MIMO2_SWITCH_SISO_C) tbl->action = IWL_MIMO2_SWITCH_SISO_A; break; default: @@ -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_CONTINUOUS: /* avoid antenna B and MIMO */ - if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB || - tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC || - tbl->action == IWL_MIMO3_SWITCH_MIMO2_BC) + 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) + if (tbl->action == IWL_MIMO3_SWITCH_SISO_B || + tbl->action == IWL_MIMO3_SWITCH_SISO_C) tbl->action = IWL_MIMO3_SWITCH_SISO_A; - else if (tbl->action == IWL_MIMO3_SWITCH_ANTENNA2) - tbl->action = IWL_MIMO3_SWITCH_ANTENNA1; break; default: 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, * 2) # times calling this function * 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; int i; @@ -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 * 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->search_better_tbl) && (lq_sta->flush_timer) && (flush_interval_passed))) { @@ -2243,7 +2253,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, /* Should we stay with this modulation mode, * or search for a new one? */ - rs_stay_in_table(lq_sta); + rs_stay_in_table(lq_sta, false); goto out; } @@ -2392,16 +2402,25 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) scale_action = -1; - 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 - * the rate scale doesn't otherwise think that is a - * good idea. - */ - } else if (lq_sta->last_bt_traffic < priv->bt_traffic_load) { - lq_sta->last_bt_traffic = priv->bt_traffic_load; - 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) { + /* + * 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 <= priv->bt_traffic_load) { + 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) { @@ -2440,7 +2459,7 @@ lq_update: if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) { /* Should we stay with this modulation mode, * 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: @@ -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, &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? */ if (is_legacy(tbl_type.lq_type)) { ant_toggle_cnt = 1; @@ -2800,8 +2825,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, /* Fill 1st table entry (index 0) */ lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate); - if (num_of_ant(tbl_type.ant_type) == 1 || - (priv && priv->bt_full_concurrent)) { + if (num_of_ant(tbl_type.ant_type) == 1) { lq_cmd->general_params.single_stream_ant_msk = tbl_type.ant_type; } else if (num_of_ant(tbl_type.ant_type) == 2) { @@ -2811,7 +2835,6 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, index++; repeat_rate--; - if (priv) { if (priv->bt_full_concurrent) valid_tx_ant = ANT_A; @@ -2832,7 +2855,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, rs_toggle_antenna(valid_tx_ant, &new_rate, &tbl_type)) ant_toggle_cnt = 1; -} + } /* Override next rate if needed for debug purposes */ rs_dbgfs_set_mcs(lq_sta, &new_rate, index); @@ -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, &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. * If initial rate was MIMO, this will finally end up * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ |