diff options
author | Abbas, Mohamed <mohamed.abbas@intel.com> | 2008-12-05 10:58:37 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-12-12 13:48:21 -0500 |
commit | 7262796ab726fcefad9b588a44d1d5a9f221051f (patch) | |
tree | 92187f0ee5d569b7c61a764f3201cdcd8cc93c32 | |
parent | 00e540b3768c96a5e2a9d5d39524fef98b2cd981 (diff) |
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>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 41 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.h | 2 |
3 files changed, 39 insertions, 16 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index b03dd06ceabf..047317f26483 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c | |||
@@ -335,10 +335,11 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, | |||
335 | 335 | ||
336 | } | 336 | } |
337 | 337 | ||
338 | static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband, | 338 | static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, |
339 | struct ieee80211_sta *sta, void *priv_sta) | 339 | struct ieee80211_sta *sta, void *priv_sta) |
340 | { | 340 | { |
341 | struct iwl3945_rs_sta *rs_sta = priv_sta; | 341 | struct iwl3945_rs_sta *rs_sta = priv_sta; |
342 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r; | ||
342 | int i; | 343 | int i; |
343 | 344 | ||
344 | IWL_DEBUG_RATE("enter\n"); | 345 | IWL_DEBUG_RATE("enter\n"); |
@@ -348,16 +349,21 @@ static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
348 | * previous packets? Need to have IEEE 802.1X auth succeed immediately | 349 | * previous packets? Need to have IEEE 802.1X auth succeed immediately |
349 | * after assoc.. */ | 350 | * after assoc.. */ |
350 | 351 | ||
351 | for (i = IWL_RATE_COUNT - 1; i >= 0; i--) { | 352 | for (i = sband->n_bitrates - 1; i >= 0; i--) { |
352 | if (sta->supp_rates[sband->band] & (1 << i)) { | 353 | if (sta->supp_rates[sband->band] & (1 << i)) { |
353 | rs_sta->last_txrate_idx = i; | 354 | rs_sta->last_txrate_idx = i; |
354 | break; | 355 | break; |
355 | } | 356 | } |
356 | } | 357 | } |
357 | 358 | ||
359 | priv->sta_supp_rates = sta->supp_rates[sband->band]; | ||
358 | /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ | 360 | /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ |
359 | if (sband->band == IEEE80211_BAND_5GHZ) | 361 | if (sband->band == IEEE80211_BAND_5GHZ) { |
360 | rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; | 362 | rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
363 | priv->sta_supp_rates = priv->sta_supp_rates << | ||
364 | IWL_FIRST_OFDM_RATE; | ||
365 | } | ||
366 | |||
361 | 367 | ||
362 | IWL_DEBUG_RATE("leave\n"); | 368 | IWL_DEBUG_RATE("leave\n"); |
363 | } | 369 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 4e6b7154c223..4e9e592b1cab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -277,12 +277,14 @@ int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate) | |||
277 | else if (rate == IWL_RATE_6M_INDEX) | 277 | else if (rate == IWL_RATE_6M_INDEX) |
278 | next_rate = IWL_RATE_6M_INDEX; | 278 | next_rate = IWL_RATE_6M_INDEX; |
279 | break; | 279 | break; |
280 | /* XXX cannot be invoked in current mac80211 so not a regression | 280 | case IEEE80211_BAND_2GHZ: |
281 | case MODE_IEEE80211B: | 281 | if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) && |
282 | if (rate == IWL_RATE_11M_INDEX_TABLE) | 282 | iwl3945_is_associated(priv)) { |
283 | next_rate = IWL_RATE_5M_INDEX_TABLE; | 283 | if (rate == IWL_RATE_11M_INDEX) |
284 | next_rate = IWL_RATE_5M_INDEX; | ||
285 | } | ||
284 | break; | 286 | break; |
285 | */ | 287 | |
286 | default: | 288 | default: |
287 | break; | 289 | break; |
288 | } | 290 | } |
@@ -2378,7 +2380,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | |||
2378 | iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0); | 2380 | iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0); |
2379 | table[index].try_cnt = priv->retry_rate; | 2381 | table[index].try_cnt = priv->retry_rate; |
2380 | prev_index = iwl3945_get_prev_ieee_rate(i); | 2382 | prev_index = iwl3945_get_prev_ieee_rate(i); |
2381 | table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index; | 2383 | table[index].next_rate_index = |
2384 | iwl3945_rates[prev_index].table_rs_index; | ||
2382 | } | 2385 | } |
2383 | 2386 | ||
2384 | switch (priv->band) { | 2387 | switch (priv->band) { |
@@ -2386,11 +2389,14 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | |||
2386 | IWL_DEBUG_RATE("Select A mode rate scale\n"); | 2389 | IWL_DEBUG_RATE("Select A mode rate scale\n"); |
2387 | /* If one of the following CCK rates is used, | 2390 | /* If one of the following CCK rates is used, |
2388 | * have it fall back to the 6M OFDM rate */ | 2391 | * have it fall back to the 6M OFDM rate */ |
2389 | for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) | 2392 | for (i = IWL_RATE_1M_INDEX_TABLE; |
2390 | table[i].next_rate_index = iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; | 2393 | i <= IWL_RATE_11M_INDEX_TABLE; i++) |
2394 | table[i].next_rate_index = | ||
2395 | iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; | ||
2391 | 2396 | ||
2392 | /* Don't fall back to CCK rates */ | 2397 | /* Don't fall back to CCK rates */ |
2393 | table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = IWL_RATE_9M_INDEX_TABLE; | 2398 | table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = |
2399 | IWL_RATE_9M_INDEX_TABLE; | ||
2394 | 2400 | ||
2395 | /* Don't drop out of OFDM rates */ | 2401 | /* Don't drop out of OFDM rates */ |
2396 | table[IWL_RATE_6M_INDEX_TABLE].next_rate_index = | 2402 | table[IWL_RATE_6M_INDEX_TABLE].next_rate_index = |
@@ -2401,11 +2407,20 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | |||
2401 | IWL_DEBUG_RATE("Select B/G mode rate scale\n"); | 2407 | IWL_DEBUG_RATE("Select B/G mode rate scale\n"); |
2402 | /* If an OFDM rate is used, have it fall back to the | 2408 | /* If an OFDM rate is used, have it fall back to the |
2403 | * 1M CCK rates */ | 2409 | * 1M CCK rates */ |
2404 | for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++) | ||
2405 | table[i].next_rate_index = iwl3945_rates[IWL_FIRST_CCK_RATE].table_rs_index; | ||
2406 | 2410 | ||
2407 | /* CCK shouldn't fall back to OFDM... */ | 2411 | if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) && |
2408 | table[IWL_RATE_11M_INDEX_TABLE].next_rate_index = IWL_RATE_5M_INDEX_TABLE; | 2412 | iwl3945_is_associated(priv)) { |
2413 | |||
2414 | index = IWL_FIRST_CCK_RATE; | ||
2415 | for (i = IWL_RATE_6M_INDEX_TABLE; | ||
2416 | i <= IWL_RATE_54M_INDEX_TABLE; i++) | ||
2417 | table[i].next_rate_index = | ||
2418 | iwl3945_rates[index].table_rs_index; | ||
2419 | |||
2420 | index = IWL_RATE_11M_INDEX_TABLE; | ||
2421 | /* CCK shouldn't fall back to OFDM... */ | ||
2422 | table[index].next_rate_index = IWL_RATE_5M_INDEX_TABLE; | ||
2423 | } | ||
2409 | break; | 2424 | break; |
2410 | 2425 | ||
2411 | default: | 2426 | default: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 5c2c15e65a63..d7d13a9e22bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -810,6 +810,8 @@ struct iwl3945_priv { | |||
810 | u16 active_rate; | 810 | u16 active_rate; |
811 | u16 active_rate_basic; | 811 | u16 active_rate_basic; |
812 | 812 | ||
813 | u32 sta_supp_rates; | ||
814 | |||
813 | u8 call_post_assoc_from_beacon; | 815 | u8 call_post_assoc_from_beacon; |
814 | /* Rate scaling data */ | 816 | /* Rate scaling data */ |
815 | s8 data_retry_limit; | 817 | s8 data_retry_limit; |