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

iwlwifi: allow user to set max rate

allow user to set max rate through #iwconfig <inteface> rate XXX.
mac80211 will try to force this if user set it, but driver is not
in sync which cause mac80211 to report wrong current rate. This
patch will check if max rate is set and force it in rate scaling
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 3cbb5dd7
...@@ -651,6 +651,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, ...@@ -651,6 +651,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
u16 fc; u16 fc;
u16 rate_mask = 0; u16 rate_mask = 0;
s8 max_rate_idx = -1;
struct iwl_priv *priv = (struct iwl_priv *)priv_r; struct iwl_priv *priv = (struct iwl_priv *)priv_r;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
...@@ -675,6 +676,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, ...@@ -675,6 +676,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
return; return;
} }
/* get user max rate if set */
max_rate_idx = txrc->max_rate_idx;
if ((sband->band == IEEE80211_BAND_5GHZ) && (max_rate_idx != -1))
max_rate_idx += IWL_FIRST_OFDM_RATE;
if ((max_rate_idx < 0) || (max_rate_idx >= IWL_RATE_COUNT))
max_rate_idx = -1;
index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT_3945 - 1); index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT_3945 - 1);
if (sband->band == IEEE80211_BAND_5GHZ) if (sband->band == IEEE80211_BAND_5GHZ)
...@@ -706,6 +714,12 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, ...@@ -706,6 +714,12 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
rs_sta->start_rate = IWL_RATE_INVALID; rs_sta->start_rate = IWL_RATE_INVALID;
} }
/* force user max rate if set by user */
if ((max_rate_idx != -1) && (max_rate_idx < index)) {
if (rate_mask & (1 << max_rate_idx))
index = max_rate_idx;
}
window = &(rs_sta->win[index]); window = &(rs_sta->win[index]);
fail_count = window->counter - window->success_counter; fail_count = window->counter - window->success_counter;
...@@ -732,6 +746,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, ...@@ -732,6 +746,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
low = high_low & 0xff; low = high_low & 0xff;
high = (high_low >> 8) & 0xff; high = (high_low >> 8) & 0xff;
/* If user set max rate, dont allow higher than user constrain */
if ((max_rate_idx != -1) && (max_rate_idx < high))
high = IWL_RATE_INVALID;
if (low != IWL_RATE_INVALID) if (low != IWL_RATE_INVALID)
low_tpt = rs_sta->win[low].average_tpt; low_tpt = rs_sta->win[low].average_tpt;
......
...@@ -148,6 +148,7 @@ struct iwl_lq_sta { ...@@ -148,6 +148,7 @@ struct iwl_lq_sta {
u16 active_mimo2_rate; u16 active_mimo2_rate;
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 */
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" */
...@@ -1759,6 +1760,15 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, ...@@ -1759,6 +1760,15 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
return; return;
} }
/* force user max rate if set by user */
if ((lq_sta->max_rate_idx != -1) &&
(lq_sta->max_rate_idx < index)) {
index = lq_sta->max_rate_idx;
update_lq = 1;
window = &(tbl->win[index]);
goto lq_update;
}
window = &(tbl->win[index]); window = &(tbl->win[index]);
/* /*
...@@ -1850,6 +1860,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, ...@@ -1850,6 +1860,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
low = high_low & 0xff; low = high_low & 0xff;
high = (high_low >> 8) & 0xff; high = (high_low >> 8) & 0xff;
/* If user set max rate, dont allow higher than user constrain */
if ((lq_sta->max_rate_idx != -1) &&
(lq_sta->max_rate_idx < high))
high = IWL_RATE_INVALID;
sr = window->success_ratio; sr = window->success_ratio;
/* Collect measured throughputs for current and adjacent rates */ /* Collect measured throughputs for current and adjacent rates */
...@@ -2110,6 +2125,17 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, ...@@ -2110,6 +2125,17 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
/* Get max rate if user set max rate */
if (lq_sta) {
lq_sta->max_rate_idx = txrc->max_rate_idx;
if ((sband->band == IEEE80211_BAND_5GHZ) &&
(lq_sta->max_rate_idx != -1))
lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE;
if ((lq_sta->max_rate_idx < 0) ||
(lq_sta->max_rate_idx >= IWL_RATE_COUNT))
lq_sta->max_rate_idx = -1;
}
if (sta) if (sta)
mask_bit = sta->supp_rates[sband->band]; mask_bit = sta->supp_rates[sband->band];
...@@ -2220,6 +2246,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, ...@@ -2220,6 +2246,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->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;
......
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