Commit 7d049e5a authored by Abbas, Mohamed's avatar Abbas, Mohamed Committed by John W. Linville

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: default avatarmohamed abbas <mohamed.abbas@intel.com>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c6ec7a9b
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */ #define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */
#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */ #define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
/* max allowed rate miss before sync LQ cmd */
#define IWL_MISSED_RATE_MAX 15
/* max time to accum history 2 seconds */ /* max time to accum history 2 seconds */
#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ) #define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ)
...@@ -149,6 +151,7 @@ struct iwl_lq_sta { ...@@ -149,6 +151,7 @@ struct iwl_lq_sta {
u16 active_mimo3_rate; u16 active_mimo3_rate;
u16 active_rate_basic; u16 active_rate_basic;
s8 max_rate_idx; /* Max rate set by user */ s8 max_rate_idx; /* Max rate set by user */
u8 missed_rate_counter;
struct iwl_link_quality_cmd lq; struct iwl_link_quality_cmd lq;
struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ 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,10 +844,15 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
/* the last LQ command could failed so the LQ in ucode not /* the last LQ command could failed so the LQ in ucode not
* the same in driver sync up * the same in driver sync up
*/ */
iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); lq_sta->missed_rate_counter++;
if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
lq_sta->missed_rate_counter = 0;
iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
}
goto out; goto out;
} }
lq_sta->missed_rate_counter = 0;
/* Update frame history window with "failure" for each Tx retry. */ /* Update frame history window with "failure" for each Tx retry. */
while (retries) { while (retries) {
/* Look up the rate and other info used for each tx attempt. /* 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,6 +2220,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
struct ieee80211_conf *conf = &priv->hw->conf; struct ieee80211_conf *conf = &priv->hw->conf;
struct iwl_lq_sta *lq_sta = priv_sta; struct iwl_lq_sta *lq_sta = priv_sta;
u16 mask_bit = 0; u16 mask_bit = 0;
int count;
int start_rate = 0;
lq_sta->flush_timer = 0; lq_sta->flush_timer = 0;
lq_sta->supp_rates = sta->supp_rates[sband->band]; 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,6 +2257,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
lq_sta->is_dup = 0; lq_sta->is_dup = 0;
lq_sta->max_rate_idx = -1; lq_sta->max_rate_idx = -1;
lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
lq_sta->is_green = rs_use_green(priv, conf); lq_sta->is_green = rs_use_green(priv, conf);
lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
lq_sta->active_rate_basic = priv->active_rate_basic; 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,16 +2296,20 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
lq_sta->drv = priv; lq_sta->drv = priv;
/* Find highest tx rate supported by hardware and destination station */ /* Find highest tx rate supported by hardware and destination station */
mask_bit = sta->supp_rates[sband->band] & lq_sta->active_legacy_rate; mask_bit = sta->supp_rates[sband->band];
lq_sta->last_txrate_idx = 3; count = sband->n_bitrates;
for (i = 0; i < sband->n_bitrates; i++) if (sband->band == IEEE80211_BAND_5GHZ) {
count += IWL_FIRST_OFDM_RATE;
start_rate = IWL_FIRST_OFDM_RATE;
mask_bit <<= IWL_FIRST_OFDM_RATE;
}
mask_bit = mask_bit & lq_sta->active_legacy_rate;
lq_sta->last_txrate_idx = 4;
for (i = start_rate; i < count; i++)
if (mask_bit & BIT(i)) if (mask_bit & BIT(i))
lq_sta->last_txrate_idx = i; lq_sta->last_txrate_idx = i;
/* For MODE_IEEE80211A, skip over cck rates in global rate table */
if (sband->band == IEEE80211_BAND_5GHZ)
lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
rs_initialize_lq(priv, conf, sta, lq_sta); rs_initialize_lq(priv, conf, sta, lq_sta);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment