iwlagn: improve rate scale table search

iwlagn rate scaling will periodically search other rate scale
tables to switch to the best table regarding performance. In the past
the number of search tables were 3. Every time the rate scale algorithm
goes through these available tables in will stay in current table for
some time before start searching again. Recent driver support more
feature and antenna, so we have more tables to search. This patch make
sure we go through all available tables.

Signed-off-by: Mohamed Abbas <mohamed.abbas@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Mohamed Abbas 2009-05-08 13:44:39 -07:00 committed by John W. Linville
parent 7af2c46078
commit d6e933993f
2 changed files with 40 additions and 9 deletions

View File

@ -100,6 +100,7 @@ struct iwl_scale_tbl_info {
u8 is_fat; /* 1 = 40 MHz channel width */ u8 is_fat; /* 1 = 40 MHz channel width */
u8 is_dup; /* 1 = duplicated data streams */ u8 is_dup; /* 1 = duplicated data streams */
u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
u8 max_search; /* maximun number of tables we can search */
s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
u32 current_rate; /* rate_n_flags, uCode API format */ u32 current_rate; /* rate_n_flags, uCode API format */
struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
@ -579,6 +580,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
tbl->is_dup = 0; tbl->is_dup = 0;
tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS); tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
tbl->lq_type = LQ_NONE; tbl->lq_type = LQ_NONE;
tbl->max_search = IWL_MAX_SEARCH;
/* legacy rate format */ /* legacy rate format */
if (!(rate_n_flags & RATE_MCS_HT_MSK)) { if (!(rate_n_flags & RATE_MCS_HT_MSK)) {
@ -612,10 +614,12 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
tbl->lq_type = LQ_MIMO2; tbl->lq_type = LQ_MIMO2;
/* MIMO3 */ /* MIMO3 */
} else { } else {
if (num_of_ant == 3) if (num_of_ant == 3) {
tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
tbl->lq_type = LQ_MIMO3; tbl->lq_type = LQ_MIMO3;
} }
} }
}
return 0; return 0;
} }
@ -771,6 +775,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
tbl->is_fat = 0; tbl->is_fat = 0;
tbl->is_SGI = 0; tbl->is_SGI = 0;
tbl->max_search = IWL_MAX_SEARCH;
} }
rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type); rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type);
@ -1026,6 +1031,7 @@ static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
lq_sta->total_failed = 0; lq_sta->total_failed = 0;
lq_sta->total_success = 0; lq_sta->total_success = 0;
lq_sta->flush_timer = jiffies; lq_sta->flush_timer = jiffies;
lq_sta->action_counter = 0;
} }
/* /*
@ -1205,6 +1211,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
tbl->lq_type = LQ_MIMO2; tbl->lq_type = LQ_MIMO2;
tbl->is_dup = lq_sta->is_dup; tbl->is_dup = lq_sta->is_dup;
tbl->action = 0; tbl->action = 0;
tbl->max_search = IWL_MAX_SEARCH;
rate_mask = lq_sta->active_mimo2_rate; rate_mask = lq_sta->active_mimo2_rate;
if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
@ -1270,6 +1277,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
tbl->lq_type = LQ_MIMO3; tbl->lq_type = LQ_MIMO3;
tbl->is_dup = lq_sta->is_dup; tbl->is_dup = lq_sta->is_dup;
tbl->action = 0; tbl->action = 0;
tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
rate_mask = lq_sta->active_mimo3_rate; rate_mask = lq_sta->active_mimo3_rate;
if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
@ -1328,6 +1336,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
tbl->is_dup = lq_sta->is_dup; tbl->is_dup = lq_sta->is_dup;
tbl->lq_type = LQ_SISO; tbl->lq_type = LQ_SISO;
tbl->action = 0; tbl->action = 0;
tbl->max_search = IWL_MAX_SEARCH;
rate_mask = lq_sta->active_siso_rate; rate_mask = lq_sta->active_siso_rate;
if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
@ -1384,15 +1393,15 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num; u8 tx_chains_num = priv->hw_params.tx_chains_num;
int ret = 0; int ret = 0;
u8 update_search_tbl_counter = 0;
for (; ;) { for (; ;) {
lq_sta->action_counter++;
switch (tbl->action) { switch (tbl->action) {
case IWL_LEGACY_SWITCH_ANTENNA1: case IWL_LEGACY_SWITCH_ANTENNA1:
case IWL_LEGACY_SWITCH_ANTENNA2: case IWL_LEGACY_SWITCH_ANTENNA2:
IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n"); IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n");
lq_sta->action_counter++;
if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 && if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 &&
tx_chains_num <= 1) || tx_chains_num <= 1) ||
(tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 && (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&
@ -1408,6 +1417,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
if (rs_toggle_antenna(valid_tx_ant, if (rs_toggle_antenna(valid_tx_ant,
&search_tbl->current_rate, search_tbl)) { &search_tbl->current_rate, search_tbl)) {
update_search_tbl_counter = 1;
rs_set_expected_tpt_table(lq_sta, search_tbl); rs_set_expected_tpt_table(lq_sta, search_tbl);
goto out; goto out;
} }
@ -1489,6 +1499,8 @@ out:
tbl->action++; tbl->action++;
if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC) if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
if (update_search_tbl_counter)
search_tbl->action = tbl->action;
return 0; return 0;
} }
@ -1511,6 +1523,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
u8 start_action = tbl->action; u8 start_action = tbl->action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num; u8 tx_chains_num = priv->hw_params.tx_chains_num;
u8 update_search_tbl_counter = 0;
int ret; int ret;
for (;;) { for (;;) {
@ -1531,8 +1544,10 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
memcpy(search_tbl, tbl, sz); memcpy(search_tbl, tbl, sz);
if (rs_toggle_antenna(valid_tx_ant, if (rs_toggle_antenna(valid_tx_ant,
&search_tbl->current_rate, search_tbl)) &search_tbl->current_rate, search_tbl)) {
update_search_tbl_counter = 1;
goto out; goto out;
}
break; break;
case IWL_SISO_SWITCH_MIMO2_AB: case IWL_SISO_SWITCH_MIMO2_AB:
case IWL_SISO_SWITCH_MIMO2_AC: case IWL_SISO_SWITCH_MIMO2_AC:
@ -1586,6 +1601,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
search_tbl->current_rate = search_tbl->current_rate =
rate_n_flags_from_tbl(priv, search_tbl, rate_n_flags_from_tbl(priv, search_tbl,
index, is_green); index, is_green);
update_search_tbl_counter = 1;
goto out; goto out;
case IWL_SISO_SWITCH_MIMO3_ABC: case IWL_SISO_SWITCH_MIMO3_ABC:
IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n"); IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n");
@ -1617,6 +1633,9 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
tbl->action++; tbl->action++;
if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC) if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC)
tbl->action = IWL_SISO_SWITCH_ANTENNA1; tbl->action = IWL_SISO_SWITCH_ANTENNA1;
if (update_search_tbl_counter)
search_tbl->action = tbl->action;
return 0; return 0;
} }
@ -1638,6 +1657,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
u8 start_action = tbl->action; u8 start_action = tbl->action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num; u8 tx_chains_num = priv->hw_params.tx_chains_num;
u8 update_search_tbl_counter = 0;
int ret; int ret;
for (;;) { for (;;) {
@ -1655,8 +1675,10 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
memcpy(search_tbl, tbl, sz); memcpy(search_tbl, tbl, sz);
if (rs_toggle_antenna(valid_tx_ant, if (rs_toggle_antenna(valid_tx_ant,
&search_tbl->current_rate, search_tbl)) &search_tbl->current_rate, search_tbl)) {
update_search_tbl_counter = 1;
goto out; goto out;
}
break; break;
case IWL_MIMO2_SWITCH_SISO_A: case IWL_MIMO2_SWITCH_SISO_A:
case IWL_MIMO2_SWITCH_SISO_B: case IWL_MIMO2_SWITCH_SISO_B:
@ -1713,6 +1735,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
search_tbl->current_rate = search_tbl->current_rate =
rate_n_flags_from_tbl(priv, search_tbl, rate_n_flags_from_tbl(priv, search_tbl,
index, is_green); index, is_green);
update_search_tbl_counter = 1;
goto out; goto out;
case IWL_MIMO2_SWITCH_MIMO3_ABC: case IWL_MIMO2_SWITCH_MIMO3_ABC:
@ -1745,6 +1768,9 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
tbl->action++; tbl->action++;
if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC) if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
if (update_search_tbl_counter)
search_tbl->action = tbl->action;
return 0; return 0;
} }
@ -1768,6 +1794,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num; u8 tx_chains_num = priv->hw_params.tx_chains_num;
int ret; int ret;
u8 update_search_tbl_counter = 0;
for (;;) { for (;;) {
lq_sta->action_counter++; lq_sta->action_counter++;
@ -1866,6 +1893,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
search_tbl->current_rate = search_tbl->current_rate =
rate_n_flags_from_tbl(priv, search_tbl, rate_n_flags_from_tbl(priv, search_tbl,
index, is_green); index, is_green);
update_search_tbl_counter = 1;
goto out; goto out;
} }
tbl->action++; tbl->action++;
@ -1882,6 +1910,9 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
tbl->action++; tbl->action++;
if (tbl->action > IWL_MIMO3_SWITCH_GI) if (tbl->action > IWL_MIMO3_SWITCH_GI)
tbl->action = IWL_MIMO3_SWITCH_ANTENNA1; tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
if (update_search_tbl_counter)
search_tbl->action = tbl->action;
return 0; return 0;
} }
@ -2326,8 +2357,7 @@ lq_update:
* before next round of mode comparisons. */ * before next round of mode comparisons. */
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) && if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) &&
lq_sta->action_counter >= 1) { lq_sta->action_counter > tbl1->max_search) {
lq_sta->action_counter = 0;
IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n"); IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n");
rs_set_stay_in_table(priv, 1, lq_sta); rs_set_stay_in_table(priv, 1, lq_sta);
} }
@ -2336,7 +2366,7 @@ lq_update:
* have been tried and compared, stay in this best modulation * have been tried and compared, stay in this best modulation
* mode for a while before next round of mode comparisons. */ * mode for a while before next round of mode comparisons. */
if (lq_sta->enable_counter && if (lq_sta->enable_counter &&
(lq_sta->action_counter >= IWL_ACTION_LIMIT)) { (lq_sta->action_counter >= tbl1->max_search)) {
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) && (lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != MAX_TID_COUNT)) { (tid != MAX_TID_COUNT)) {
@ -2350,7 +2380,6 @@ lq_update:
lq_sta, sta); lq_sta, sta);
} }
} }
lq_sta->action_counter = 0;
rs_set_stay_in_table(priv, 0, lq_sta); rs_set_stay_in_table(priv, 0, lq_sta);
} }
} }

View File

@ -275,6 +275,8 @@ enum {
#define IWL_MIMO3_SWITCH_GI 8 #define IWL_MIMO3_SWITCH_GI 8
#define IWL_MAX_11N_MIMO3_SEARCH IWL_MIMO3_SWITCH_GI
#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_MIMO3_ABC
/*FIXME:RS:add possible actions for MIMO3*/ /*FIXME:RS:add possible actions for MIMO3*/