diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2009-07-24 22:13:00 +0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-27 23:24:20 +0400 |
commit | e3139fe741b25a0f8a27fd2cdf2ad11734c3d4d3 (patch) | |
tree | 6691e85878072f6f4dd88a3457c30ededfdf39a0 /drivers/net/wireless/iwlwifi | |
parent | 21f5fc75deca63bc41c9d13007d35981d4485622 (diff) | |
download | linux-e3139fe741b25a0f8a27fd2cdf2ad11734c3d4d3.tar.xz |
iwlwifi: revert to active table when rate is not valid
When performing rate scaling, if detected that the new rate
index is invalid, clear the search_better_tbl flag
so it will not be stuck in the loop.
Since the search table is already set up in uCode,
we need to empty out the the search table;
revert back to the "active" rate and throughput info.
Also pass the "active" table setup to uCode to make
sure the rate scale is functioning correctly.
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 63280411fd58..40207dac6db5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2003,6 +2003,25 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) } /* + * setup rate table in uCode + * return rate_n_flags as used in the table + */ +static u32 rs_update_rate_tbl(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl, + int index, u8 is_green) +{ + u32 rate; + + /* Update uCode's rate table. */ + rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); + rs_fill_link_cmd(priv, lq_sta, rate); + iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); + + return rate; +} + +/* * Do rate scaling and search for new modulation mode. */ static void rs_rate_scale_perform(struct iwl_priv *priv, @@ -2098,6 +2117,16 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, if (!((1 << index) & rate_scale_index_msk)) { IWL_ERR(priv, "Current Rate is not valid\n"); + if (lq_sta->search_better_tbl) { + /* revert to active table if search table is not valid*/ + tbl->lq_type = LQ_NONE; + lq_sta->search_better_tbl = 0; + tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + /* get "active" rate info */ + index = iwl_hwrate_to_plcp_idx(tbl->current_rate); + rate = rs_update_rate_tbl(priv, lq_sta, + tbl, index, is_green); + } return; } @@ -2308,11 +2337,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, lq_update: /* Replace uCode's rate table for the destination station. */ - if (update_lq) { - rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); - rs_fill_link_cmd(priv, lq_sta, rate); - iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); - } + if (update_lq) + rate = rs_update_rate_tbl(priv, lq_sta, + tbl, index, is_green); /* Should we stay with this modulation mode, or search for a new one? */ rs_stay_in_table(lq_sta); |