aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index a1b0ff56bc3..23a58b00f18 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -270,6 +270,8 @@ const static struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
270 {"60", "64QAM 5/6"} 270 {"60", "64QAM 5/6"}
271}; 271};
272 272
273#define MCS_INDEX_PER_STREAM (8)
274
273static inline u8 rs_extract_rate(u32 rate_n_flags) 275static inline u8 rs_extract_rate(u32 rate_n_flags)
274{ 276{
275 return (u8)(rate_n_flags & 0xFF); 277 return (u8)(rate_n_flags & 0xFF);
@@ -2518,12 +2520,33 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2518 } 2520 }
2519 } 2521 }
2520 2522
2521 if (rate_idx < 0 || rate_idx > IWL_RATE_COUNT) 2523 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {
2522 rate_idx = rate_lowest_index(sband, sta);
2523 else if (sband->band == IEEE80211_BAND_5GHZ)
2524 rate_idx -= IWL_FIRST_OFDM_RATE; 2524 rate_idx -= IWL_FIRST_OFDM_RATE;
2525 2525 /* 6M and 9M shared same MCS index */
2526 rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0;
2527 if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
2528 IWL_RATE_MIMO3_6M_PLCP)
2529 rate_idx = rate_idx + (2 * MCS_INDEX_PER_STREAM);
2530 else if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
2531 IWL_RATE_MIMO2_6M_PLCP)
2532 rate_idx = rate_idx + MCS_INDEX_PER_STREAM;
2533 info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
2534 if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK)
2535 info->control.rates[0].flags |= IEEE80211_TX_RC_SHORT_GI;
2536 if (lq_sta->last_rate_n_flags & RATE_MCS_DUP_MSK)
2537 info->control.rates[0].flags |= IEEE80211_TX_RC_DUP_DATA;
2538 if (lq_sta->last_rate_n_flags & RATE_MCS_FAT_MSK)
2539 info->control.rates[0].flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
2540 if (lq_sta->last_rate_n_flags & RATE_MCS_GF_MSK)
2541 info->control.rates[0].flags |= IEEE80211_TX_RC_GREEN_FIELD;
2542 } else {
2543 if (rate_idx < 0 || rate_idx > IWL_RATE_COUNT)
2544 rate_idx = rate_lowest_index(sband, sta);
2545 else if (sband->band == IEEE80211_BAND_5GHZ)
2546 rate_idx -= IWL_FIRST_OFDM_RATE;
2547 }
2526 info->control.rates[0].idx = rate_idx; 2548 info->control.rates[0].idx = rate_idx;
2549
2527} 2550}
2528 2551
2529static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, 2552static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,