aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorDaniel C Halperin <daniel.c.halperin@intel.com>2009-08-28 12:44:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-31 14:42:10 -0400
commit31513be8a06874eb359908b7b735929837831a9a (patch)
tree1bb7bbff7fa671ae2169012cf81dc84ebd64722b /drivers/net/wireless/iwlwifi
parentb58ef214b7db57cfcbca0e1edae08566cdfd56b7 (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/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c9
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);
96void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, 96void 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}
119EXPORT_SYMBOL(iwl_hwrate_to_tx_control); 115EXPORT_SYMBOL(iwl_hwrate_to_tx_control);
120 116
@@ -149,6 +145,27 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
149} 145}
150EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); 146EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
151 147
148int 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
152u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) 169u8 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);
423void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, 423void 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);
425int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); 425int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
426int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
426 427
427u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); 428u8 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)