From 7c94102d6e85a8a99b8456294627f2af90c6ea77 Mon Sep 17 00:00:00 2001 From: Mohamed Abbas Date: Mon, 27 Aug 2007 10:35:23 +0800 Subject: [PATCH 29/31] iwlwifi: fix rs_get_best_rate to pick up the right rate Fix rs_get_best_rate to pick up the right SISO/MIMO rate. Signed-off-by: Mohamed Abbas Signed-off-by: Zhu Yi --- drivers/net/wireless/iwl-4965-rs.c | 49 ++++++++++++++++++++++-------------- 1 files changed, 30 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/iwl-4965-rs.c b/drivers/net/wireless/iwl-4965-rs.c index ba08d04..0e2bf1f 100644 --- a/drivers/net/wireless/iwl-4965-rs.c +++ b/drivers/net/wireless/iwl-4965-rs.c @@ -861,13 +861,13 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, { struct iwl_scale_tbl_info *active_tbl = &(lq_data->lq_info[lq_data->active_tbl]); - s32 new_rate, high, low; + s32 new_rate, high, low, start_hi; s32 active_sr = active_tbl->win[index].success_ratio; s32 *tpt_tbl = tbl->expected_tpt; s32 active_tpt = active_tbl->expected_tpt[index]; u16 high_low; - new_rate = high = low = IWL_RATE_INVALID; + new_rate = high = low = start_hi = IWL_RATE_INVALID; for (; ;) { high_low = rs_get_adjacent_rate(rate, rate_mask, tbl->lq_type); @@ -881,6 +881,11 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, (tpt_tbl[rate] <= active_tpt))) || ((active_sr >= IWL_RATE_SCALE_SWITCH) && (tpt_tbl[rate] > active_tpt))) { + + if (start_hi != IWL_RATE_INVALID) { + new_rate = start_hi; + break; + } new_rate = rate; if (low != IWL_RATE_INVALID) rate = low; @@ -889,10 +894,13 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, } else { if (new_rate != IWL_RATE_INVALID) break; - else if (high != IWL_RATE_INVALID) + else if (high != IWL_RATE_INVALID) { + start_hi = high; rate = high; - else + } else { + new_rate = rate; break; + } } } @@ -949,7 +957,7 @@ static int rs_switch_to_mimo(struct iwl_priv *priv, rs_get_expected_tpt_table(lq_data, tbl); - rate = rs_get_best_rate(priv, lq_data, tbl, rate_mask, index, 4); + rate = rs_get_best_rate(priv, lq_data, tbl, rate_mask, index, index); IWL_DEBUG_HT("LQ: MIMO best rate %d mask %X\n", rate, rate_mask); if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) @@ -1003,7 +1011,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, tbl->is_SGI = 0; rs_get_expected_tpt_table(lq_data, tbl); - rate = rs_get_best_rate(priv, lq_data, tbl, rate_mask, index, 4); + rate = rs_get_best_rate(priv, lq_data, tbl, rate_mask, index, index); IWL_DEBUG_HT("LQ: get best rate %d mask %X\n", rate, rate_mask); if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) { @@ -1032,7 +1040,8 @@ static int rs_move_legacy_other(struct iwl_priv *priv, u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action = tbl->action; - for (; ; ) { + + for (; ;) { switch (tbl->action) { case IWL_LEGACY_SWITCH_ANTENNA: IWL_DEBUG_HT("LQ Legacy switch Antenna\n"); @@ -1059,8 +1068,8 @@ static int rs_move_legacy_other(struct iwl_priv *priv, search_tbl->lq_type = LQ_SISO; search_tbl->is_SGI = 0; search_tbl->is_fat = 0; - rc = rs_switch_to_siso(priv, lq_data, - search_tbl, index); + rc = rs_switch_to_siso(priv, lq_data, search_tbl, + index); if (!rc) { lq_data->search_better_tbl = 1; lq_data->action_counter = 0; @@ -1076,8 +1085,8 @@ static int rs_move_legacy_other(struct iwl_priv *priv, search_tbl->is_SGI = 0; search_tbl->is_fat = 0; search_tbl->antenna_type = ANT_BOTH; - rc = rs_switch_to_mimo(priv, lq_data, - search_tbl, index); + rc = rs_switch_to_mimo(priv, lq_data, search_tbl, + index); if (!rc) { lq_data->search_better_tbl = 1; lq_data->action_counter = 0; @@ -1150,8 +1159,8 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, search_tbl->is_SGI = 0; search_tbl->is_fat = 0; search_tbl->antenna_type = ANT_BOTH; - rc = rs_switch_to_mimo(priv, lq_data, - search_tbl, index); + rc = rs_switch_to_mimo(priv, lq_data, search_tbl, + index); if (!rc) lq_data->search_better_tbl = 1; @@ -1232,8 +1241,8 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, else search_tbl->antenna_type = ANT_AUX; - rc = rs_switch_to_siso(priv, lq_data, - search_tbl, index); + rc = rs_switch_to_siso(priv, lq_data, search_tbl, + index); if (!rc) { lq_data->search_better_tbl = 1; goto out; @@ -1438,8 +1447,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, if (((fail_count < IWL_RATE_MIN_FAILURE_TH) && (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) || (tbl->expected_tpt == NULL)) { - IWL_DEBUG_RATE("LQ: still below TH succ %d total %d\n", - window->success_counter, window->counter); + IWL_DEBUG_RATE("LQ: still below TH succ %d total %d " + "for index %d\n", + window->success_counter, window->counter, index); window->average_tpt = IWL_INVALID_VALUE; rs_stay_in_table(lq_data); if (update_lq) { @@ -1561,8 +1571,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, break; } - IWL_DEBUG_HT("choose rate scale index %d action %d low %d high %d\n", - index, scale_action, low, high); + IWL_DEBUG_HT("choose rate scale index %d action %d low %d " + "high %d type %d\n", + index, scale_action, low, high, tbl->lq_type); lq_update: if (update_lq) { -- 1.5.2