iwl3945: Fix rate scale for B-mode connection
This patch make sure we use only CCK rate for B only network. For 3945 driver, it sets REPLY_RATE_SCALE command every time we connect to a new network. In this command we set for every rate the number of try and next rate. The problem mac80211 reports same mode for both B and G mode as IEEE80211_BAND_2GHZ which will cause using invalid rate other than CCK in B only network. THis patch on association will examine sta valid rate on association, if no OFDM rate in valid available rates it considers it as B only mode so we can set REPLY_RATE_SCALE command with valid B only network and only choose CCK rate in rate scaling. 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>
This commit is contained in:
committed by
John W. Linville
parent
00e540b376
commit
7262796ab7
@@ -335,10 +335,11 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband,
|
static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
|
||||||
struct ieee80211_sta *sta, void *priv_sta)
|
struct ieee80211_sta *sta, void *priv_sta)
|
||||||
{
|
{
|
||||||
struct iwl3945_rs_sta *rs_sta = priv_sta;
|
struct iwl3945_rs_sta *rs_sta = priv_sta;
|
||||||
|
struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
IWL_DEBUG_RATE("enter\n");
|
IWL_DEBUG_RATE("enter\n");
|
||||||
@@ -348,16 +349,21 @@ static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband,
|
|||||||
* previous packets? Need to have IEEE 802.1X auth succeed immediately
|
* previous packets? Need to have IEEE 802.1X auth succeed immediately
|
||||||
* after assoc.. */
|
* after assoc.. */
|
||||||
|
|
||||||
for (i = IWL_RATE_COUNT - 1; i >= 0; i--) {
|
for (i = sband->n_bitrates - 1; i >= 0; i--) {
|
||||||
if (sta->supp_rates[sband->band] & (1 << i)) {
|
if (sta->supp_rates[sband->band] & (1 << i)) {
|
||||||
rs_sta->last_txrate_idx = i;
|
rs_sta->last_txrate_idx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->sta_supp_rates = sta->supp_rates[sband->band];
|
||||||
/* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */
|
/* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */
|
||||||
if (sband->band == IEEE80211_BAND_5GHZ)
|
if (sband->band == IEEE80211_BAND_5GHZ) {
|
||||||
rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
|
rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
|
||||||
|
priv->sta_supp_rates = priv->sta_supp_rates <<
|
||||||
|
IWL_FIRST_OFDM_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
IWL_DEBUG_RATE("leave\n");
|
IWL_DEBUG_RATE("leave\n");
|
||||||
}
|
}
|
||||||
|
@@ -277,12 +277,14 @@ int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
|
|||||||
else if (rate == IWL_RATE_6M_INDEX)
|
else if (rate == IWL_RATE_6M_INDEX)
|
||||||
next_rate = IWL_RATE_6M_INDEX;
|
next_rate = IWL_RATE_6M_INDEX;
|
||||||
break;
|
break;
|
||||||
/* XXX cannot be invoked in current mac80211 so not a regression
|
case IEEE80211_BAND_2GHZ:
|
||||||
case MODE_IEEE80211B:
|
if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
|
||||||
if (rate == IWL_RATE_11M_INDEX_TABLE)
|
iwl3945_is_associated(priv)) {
|
||||||
next_rate = IWL_RATE_5M_INDEX_TABLE;
|
if (rate == IWL_RATE_11M_INDEX)
|
||||||
|
next_rate = IWL_RATE_5M_INDEX;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2378,7 +2380,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
|
|||||||
iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0);
|
iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0);
|
||||||
table[index].try_cnt = priv->retry_rate;
|
table[index].try_cnt = priv->retry_rate;
|
||||||
prev_index = iwl3945_get_prev_ieee_rate(i);
|
prev_index = iwl3945_get_prev_ieee_rate(i);
|
||||||
table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index;
|
table[index].next_rate_index =
|
||||||
|
iwl3945_rates[prev_index].table_rs_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (priv->band) {
|
switch (priv->band) {
|
||||||
@@ -2386,11 +2389,14 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
|
|||||||
IWL_DEBUG_RATE("Select A mode rate scale\n");
|
IWL_DEBUG_RATE("Select A mode rate scale\n");
|
||||||
/* If one of the following CCK rates is used,
|
/* If one of the following CCK rates is used,
|
||||||
* have it fall back to the 6M OFDM rate */
|
* have it fall back to the 6M OFDM rate */
|
||||||
for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++)
|
for (i = IWL_RATE_1M_INDEX_TABLE;
|
||||||
table[i].next_rate_index = iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
|
i <= IWL_RATE_11M_INDEX_TABLE; i++)
|
||||||
|
table[i].next_rate_index =
|
||||||
|
iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
|
||||||
|
|
||||||
/* Don't fall back to CCK rates */
|
/* Don't fall back to CCK rates */
|
||||||
table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = IWL_RATE_9M_INDEX_TABLE;
|
table[IWL_RATE_12M_INDEX_TABLE].next_rate_index =
|
||||||
|
IWL_RATE_9M_INDEX_TABLE;
|
||||||
|
|
||||||
/* Don't drop out of OFDM rates */
|
/* Don't drop out of OFDM rates */
|
||||||
table[IWL_RATE_6M_INDEX_TABLE].next_rate_index =
|
table[IWL_RATE_6M_INDEX_TABLE].next_rate_index =
|
||||||
@@ -2401,11 +2407,20 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
|
|||||||
IWL_DEBUG_RATE("Select B/G mode rate scale\n");
|
IWL_DEBUG_RATE("Select B/G mode rate scale\n");
|
||||||
/* If an OFDM rate is used, have it fall back to the
|
/* If an OFDM rate is used, have it fall back to the
|
||||||
* 1M CCK rates */
|
* 1M CCK rates */
|
||||||
for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++)
|
|
||||||
table[i].next_rate_index = iwl3945_rates[IWL_FIRST_CCK_RATE].table_rs_index;
|
|
||||||
|
|
||||||
/* CCK shouldn't fall back to OFDM... */
|
if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
|
||||||
table[IWL_RATE_11M_INDEX_TABLE].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
|
iwl3945_is_associated(priv)) {
|
||||||
|
|
||||||
|
index = IWL_FIRST_CCK_RATE;
|
||||||
|
for (i = IWL_RATE_6M_INDEX_TABLE;
|
||||||
|
i <= IWL_RATE_54M_INDEX_TABLE; i++)
|
||||||
|
table[i].next_rate_index =
|
||||||
|
iwl3945_rates[index].table_rs_index;
|
||||||
|
|
||||||
|
index = IWL_RATE_11M_INDEX_TABLE;
|
||||||
|
/* CCK shouldn't fall back to OFDM... */
|
||||||
|
table[index].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@@ -810,6 +810,8 @@ struct iwl3945_priv {
|
|||||||
u16 active_rate;
|
u16 active_rate;
|
||||||
u16 active_rate_basic;
|
u16 active_rate_basic;
|
||||||
|
|
||||||
|
u32 sta_supp_rates;
|
||||||
|
|
||||||
u8 call_post_assoc_from_beacon;
|
u8 call_post_assoc_from_beacon;
|
||||||
/* Rate scaling data */
|
/* Rate scaling data */
|
||||||
s8 data_retry_limit;
|
s8 data_retry_limit;
|
||||||
|
Reference in New Issue
Block a user