diff options
author | Daniel C Halperin <daniel.c.halperin@intel.com> | 2009-08-28 12:44:47 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-31 14:42:10 -0400 |
commit | 31513be8a06874eb359908b7b735929837831a9a (patch) | |
tree | 1bb7bbff7fa671ae2169012cf81dc84ebd64722b /drivers/net/wireless | |
parent | b58ef214b7db57cfcbca0e1edae08566cdfd56b7 (diff) |
iwlwifi: use iwl_hwrate_get_mac80211_idx where appropriate
For HT packets, mac80211 expects the rate_idx to be an MCS number, which is the
lower byte of rate_n_flags. However, iwl_hwrate_to_plcp_idx takes the MCS
number and reduces it down to the range 0-8 (6 to 60 Mbps), removing the bits
that signify multiply streams, HT40 Duplicate mode, or unequal modulation.
This version is used for various internal purposes through the driver.
Add the function iwl_hwrate_get_mac80211_idx, an alternate version which takes
the rate and the band and returns the mac80211 index (MCS, for HT packets, and
PLCP rate, for legacy packets).
Signed-off-by: Daniel C Halperin <daniel.c.halperin@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 27 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 9 |
4 files changed, 35 insertions, 12 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 8239e5508cac..40b207aa8fef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -878,6 +878,12 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
878 | rs_index -= IWL_FIRST_OFDM_RATE; | 878 | rs_index -= IWL_FIRST_OFDM_RATE; |
879 | mac_flags = info->status.rates[0].flags; | 879 | mac_flags = info->status.rates[0].flags; |
880 | mac_index = info->status.rates[0].idx; | 880 | mac_index = info->status.rates[0].idx; |
881 | /* For HT packets, map MCS to PLCP */ | ||
882 | if (mac_flags & IEEE80211_TX_RC_MCS) { | ||
883 | mac_index &= RATE_MCS_CODE_MSK; /* Remove # of streams */ | ||
884 | if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE)) | ||
885 | mac_index++; | ||
886 | } | ||
881 | 887 | ||
882 | if ((mac_index < 0) || | 888 | if ((mac_index < 0) || |
883 | (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || | 889 | (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || |
@@ -886,8 +892,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
886 | (tbl_type.ant_type != info->antenna_sel_tx) || | 892 | (tbl_type.ant_type != info->antenna_sel_tx) || |
887 | (!!(tx_rate & RATE_MCS_HT_MSK) != !!(mac_flags & IEEE80211_TX_RC_MCS)) || | 893 | (!!(tx_rate & RATE_MCS_HT_MSK) != !!(mac_flags & IEEE80211_TX_RC_MCS)) || |
888 | (!!(tx_rate & RATE_MCS_GF_MSK) != !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || | 894 | (!!(tx_rate & RATE_MCS_GF_MSK) != !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || |
889 | rs_index != mac_index) { | 895 | (rs_index != mac_index)) { |
890 | IWL_DEBUG_RATE(priv, "initial rate does not match 0x%x\n", tx_rate); | 896 | IWL_DEBUG_RATE(priv, "initial rate %d does not match %d (0x%x)\n", mac_index, rs_index, tx_rate); |
891 | /* the last LQ command could failed so the LQ in ucode not | 897 | /* the last LQ command could failed so the LQ in ucode not |
892 | * the same in driver sync up | 898 | * the same in driver sync up |
893 | */ | 899 | */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 813582467ffb..acfd7b40afb8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -96,7 +96,6 @@ EXPORT_SYMBOL(iwl_rates); | |||
96 | void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | 96 | void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, |
97 | struct ieee80211_tx_info *info) | 97 | struct ieee80211_tx_info *info) |
98 | { | 98 | { |
99 | int rate_index; | ||
100 | struct ieee80211_tx_rate *r = &info->control.rates[0]; | 99 | struct ieee80211_tx_rate *r = &info->control.rates[0]; |
101 | 100 | ||
102 | info->antenna_sel_tx = | 101 | info->antenna_sel_tx = |
@@ -111,10 +110,7 @@ void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | |||
111 | r->flags |= IEEE80211_TX_RC_DUP_DATA; | 110 | r->flags |= IEEE80211_TX_RC_DUP_DATA; |
112 | if (rate_n_flags & RATE_MCS_SGI_MSK) | 111 | if (rate_n_flags & RATE_MCS_SGI_MSK) |
113 | r->flags |= IEEE80211_TX_RC_SHORT_GI; | 112 | r->flags |= IEEE80211_TX_RC_SHORT_GI; |
114 | rate_index = iwl_hwrate_to_plcp_idx(rate_n_flags); | 113 | r->idx = iwl_hwrate_to_mac80211_idx(rate_n_flags, info->band); |
115 | if (info->band == IEEE80211_BAND_5GHZ) | ||
116 | rate_index -= IWL_FIRST_OFDM_RATE; | ||
117 | r->idx = rate_index; | ||
118 | } | 114 | } |
119 | EXPORT_SYMBOL(iwl_hwrate_to_tx_control); | 115 | EXPORT_SYMBOL(iwl_hwrate_to_tx_control); |
120 | 116 | ||
@@ -149,6 +145,27 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) | |||
149 | } | 145 | } |
150 | EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); | 146 | EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); |
151 | 147 | ||
148 | int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band) | ||
149 | { | ||
150 | int idx = 0; | ||
151 | int band_offset = 0; | ||
152 | |||
153 | /* HT rate format: mac80211 wants an MCS number, which is just LSB */ | ||
154 | if (rate_n_flags & RATE_MCS_HT_MSK) { | ||
155 | idx = (rate_n_flags & 0xff); | ||
156 | return idx; | ||
157 | /* Legacy rate format, search for match in table */ | ||
158 | } else { | ||
159 | if (band == IEEE80211_BAND_5GHZ) | ||
160 | band_offset = IWL_FIRST_OFDM_RATE; | ||
161 | for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++) | ||
162 | if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) | ||
163 | return idx - band_offset; | ||
164 | } | ||
165 | |||
166 | return -1; | ||
167 | } | ||
168 | |||
152 | u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) | 169 | u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) |
153 | { | 170 | { |
154 | int i; | 171 | int i; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 62d90364b61d..c04d2a270819 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -423,6 +423,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); | |||
423 | void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | 423 | void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, |
424 | struct ieee80211_tx_info *info); | 424 | struct ieee80211_tx_info *info); |
425 | int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); | 425 | int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); |
426 | int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); | ||
426 | 427 | ||
427 | u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); | 428 | u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); |
428 | 429 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index e34d3fcb6c3d..8150c5c3a16b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -962,6 +962,9 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
962 | return; | 962 | return; |
963 | } | 963 | } |
964 | 964 | ||
965 | /* This will be used in several places later */ | ||
966 | rate_n_flags = le32_to_cpu(phy_res->rate_n_flags); | ||
967 | |||
965 | /* rx_status carries information about the packet to mac80211 */ | 968 | /* rx_status carries information about the packet to mac80211 */ |
966 | rx_status.mactime = le64_to_cpu(phy_res->timestamp); | 969 | rx_status.mactime = le64_to_cpu(phy_res->timestamp); |
967 | rx_status.freq = | 970 | rx_status.freq = |
@@ -969,10 +972,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
969 | rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | 972 | rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? |
970 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | 973 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; |
971 | rx_status.rate_idx = | 974 | rx_status.rate_idx = |
972 | iwl_hwrate_to_plcp_idx(le32_to_cpu(phy_res->rate_n_flags)); | 975 | iwl_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); |
973 | if (rx_status.band == IEEE80211_BAND_5GHZ) | ||
974 | rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; | ||
975 | |||
976 | rx_status.flag = 0; | 976 | rx_status.flag = 0; |
977 | 977 | ||
978 | /* TSF isn't reliable. In order to allow smooth user experience, | 978 | /* TSF isn't reliable. In order to allow smooth user experience, |
@@ -1034,7 +1034,6 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
1034 | rx_status.flag |= RX_FLAG_SHORTPRE; | 1034 | rx_status.flag |= RX_FLAG_SHORTPRE; |
1035 | 1035 | ||
1036 | /* Set up the HT phy flags */ | 1036 | /* Set up the HT phy flags */ |
1037 | rate_n_flags = le32_to_cpu(phy_res->rate_n_flags); | ||
1038 | if (rate_n_flags & RATE_MCS_HT_MSK) | 1037 | if (rate_n_flags & RATE_MCS_HT_MSK) |
1039 | rx_status.flag |= RX_FLAG_HT; | 1038 | rx_status.flag |= RX_FLAG_HT; |
1040 | if (rate_n_flags & RATE_MCS_HT40_MSK) | 1039 | if (rate_n_flags & RATE_MCS_HT40_MSK) |