aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
diff options
context:
space:
mode:
authorAbbas, Mohamed <mohamed.abbas@intel.com>2009-01-21 00:33:53 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-29 16:01:05 -0500
commit7d049e5abe77c82d6f11a4e5869203f7b2838380 (patch)
treede26eb20e8bf6d83ca2b04e02e5d0546d8315d57 /drivers/net/wireless/iwlwifi/iwl-agn-rs.c
parentc6ec7a9b17875e3a5a9cdd23f7914d74069316c8 (diff)
iwlagn: fix agn rate scaling
Sometime Tx reply rate different than what rate scale expecting causing rate scale to bail out. This could cause failing to commit LQ cmd. This patch will try to solve this instead of just bail out. It also make sure we start with a valid rate. 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>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-rs.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 12c5e5d6e910..13039a024473 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -49,6 +49,8 @@
49#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */ 49#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */
50#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */ 50#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
51 51
52/* max allowed rate miss before sync LQ cmd */
53#define IWL_MISSED_RATE_MAX 15
52/* max time to accum history 2 seconds */ 54/* max time to accum history 2 seconds */
53#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ) 55#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ)
54 56
@@ -149,6 +151,7 @@ struct iwl_lq_sta {
149 u16 active_mimo3_rate; 151 u16 active_mimo3_rate;
150 u16 active_rate_basic; 152 u16 active_rate_basic;
151 s8 max_rate_idx; /* Max rate set by user */ 153 s8 max_rate_idx; /* Max rate set by user */
154 u8 missed_rate_counter;
152 155
153 struct iwl_link_quality_cmd lq; 156 struct iwl_link_quality_cmd lq;
154 struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ 157 struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
@@ -841,10 +844,15 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
841 /* the last LQ command could failed so the LQ in ucode not 844 /* the last LQ command could failed so the LQ in ucode not
842 * the same in driver sync up 845 * the same in driver sync up
843 */ 846 */
844 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 847 lq_sta->missed_rate_counter++;
848 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
849 lq_sta->missed_rate_counter = 0;
850 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
851 }
845 goto out; 852 goto out;
846 } 853 }
847 854
855 lq_sta->missed_rate_counter = 0;
848 /* Update frame history window with "failure" for each Tx retry. */ 856 /* Update frame history window with "failure" for each Tx retry. */
849 while (retries) { 857 while (retries) {
850 /* Look up the rate and other info used for each tx attempt. 858 /* Look up the rate and other info used for each tx attempt.
@@ -2212,6 +2220,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2212 struct ieee80211_conf *conf = &priv->hw->conf; 2220 struct ieee80211_conf *conf = &priv->hw->conf;
2213 struct iwl_lq_sta *lq_sta = priv_sta; 2221 struct iwl_lq_sta *lq_sta = priv_sta;
2214 u16 mask_bit = 0; 2222 u16 mask_bit = 0;
2223 int count;
2224 int start_rate = 0;
2215 2225
2216 lq_sta->flush_timer = 0; 2226 lq_sta->flush_timer = 0;
2217 lq_sta->supp_rates = sta->supp_rates[sband->band]; 2227 lq_sta->supp_rates = sta->supp_rates[sband->band];
@@ -2247,6 +2257,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2247 2257
2248 lq_sta->is_dup = 0; 2258 lq_sta->is_dup = 0;
2249 lq_sta->max_rate_idx = -1; 2259 lq_sta->max_rate_idx = -1;
2260 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
2250 lq_sta->is_green = rs_use_green(priv, conf); 2261 lq_sta->is_green = rs_use_green(priv, conf);
2251 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); 2262 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
2252 lq_sta->active_rate_basic = priv->active_rate_basic; 2263 lq_sta->active_rate_basic = priv->active_rate_basic;
@@ -2285,16 +2296,20 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2285 lq_sta->drv = priv; 2296 lq_sta->drv = priv;
2286 2297
2287 /* Find highest tx rate supported by hardware and destination station */ 2298 /* Find highest tx rate supported by hardware and destination station */
2288 mask_bit = sta->supp_rates[sband->band] & lq_sta->active_legacy_rate; 2299 mask_bit = sta->supp_rates[sband->band];
2289 lq_sta->last_txrate_idx = 3; 2300 count = sband->n_bitrates;
2290 for (i = 0; i < sband->n_bitrates; i++) 2301 if (sband->band == IEEE80211_BAND_5GHZ) {
2302 count += IWL_FIRST_OFDM_RATE;
2303 start_rate = IWL_FIRST_OFDM_RATE;
2304 mask_bit <<= IWL_FIRST_OFDM_RATE;
2305 }
2306
2307 mask_bit = mask_bit & lq_sta->active_legacy_rate;
2308 lq_sta->last_txrate_idx = 4;
2309 for (i = start_rate; i < count; i++)
2291 if (mask_bit & BIT(i)) 2310 if (mask_bit & BIT(i))
2292 lq_sta->last_txrate_idx = i; 2311 lq_sta->last_txrate_idx = i;
2293 2312
2294 /* For MODE_IEEE80211A, skip over cck rates in global rate table */
2295 if (sband->band == IEEE80211_BAND_5GHZ)
2296 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
2297
2298 rs_initialize_lq(priv, conf, sta, lq_sta); 2313 rs_initialize_lq(priv, conf, sta, lq_sta);
2299} 2314}
2300 2315