diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-04-19 13:57:34 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-20 11:50:54 -0400 |
commit | 3bb065a7420c90421d6bbea5f7cffe36bd79a048 (patch) | |
tree | 3a62f8d64abd83ffa55b11c0272ab69f5b58a481 | |
parent | c666387682faaec7d7b4a8afd30b0b6bc0816ddb (diff) |
ath9k: initialize the number of tx/rx streams correctly
AR9300 based hardware can 3x3 MCS rates, this should be set in the
HT capabilities.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 5adc2e335cff..351538cd8e4c 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -173,6 +173,18 @@ static const struct ath_ops ath9k_common_ops = { | |||
173 | .write = ath9k_iowrite32, | 173 | .write = ath9k_iowrite32, |
174 | }; | 174 | }; |
175 | 175 | ||
176 | static int count_streams(unsigned int chainmask, int max) | ||
177 | { | ||
178 | int streams = 0; | ||
179 | |||
180 | do { | ||
181 | if (++streams == max) | ||
182 | break; | ||
183 | } while ((chainmask = chainmask & (chainmask - 1))); | ||
184 | |||
185 | return streams; | ||
186 | } | ||
187 | |||
176 | /**************************/ | 188 | /**************************/ |
177 | /* Initialization */ | 189 | /* Initialization */ |
178 | /**************************/ | 190 | /**************************/ |
@@ -180,8 +192,10 @@ static const struct ath_ops ath9k_common_ops = { | |||
180 | static void setup_ht_cap(struct ath_softc *sc, | 192 | static void setup_ht_cap(struct ath_softc *sc, |
181 | struct ieee80211_sta_ht_cap *ht_info) | 193 | struct ieee80211_sta_ht_cap *ht_info) |
182 | { | 194 | { |
183 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 195 | struct ath_hw *ah = sc->sc_ah; |
196 | struct ath_common *common = ath9k_hw_common(ah); | ||
184 | u8 tx_streams, rx_streams; | 197 | u8 tx_streams, rx_streams; |
198 | int i, max_streams; | ||
185 | 199 | ||
186 | ht_info->ht_supported = true; | 200 | ht_info->ht_supported = true; |
187 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | 201 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | |
@@ -195,25 +209,28 @@ static void setup_ht_cap(struct ath_softc *sc, | |||
195 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | 209 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; |
196 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | 210 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; |
197 | 211 | ||
212 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
213 | max_streams = 3; | ||
214 | else | ||
215 | max_streams = 2; | ||
216 | |||
198 | /* set up supported mcs set */ | 217 | /* set up supported mcs set */ |
199 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | 218 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); |
200 | tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ? | 219 | tx_streams = count_streams(common->tx_chainmask, max_streams); |
201 | 1 : 2; | 220 | rx_streams = count_streams(common->rx_chainmask, max_streams); |
202 | rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ? | 221 | |
203 | 1 : 2; | 222 | ath_print(common, ATH_DBG_CONFIG, |
223 | "TX streams %d, RX streams: %d\n", | ||
224 | tx_streams, rx_streams); | ||
204 | 225 | ||
205 | if (tx_streams != rx_streams) { | 226 | if (tx_streams != rx_streams) { |
206 | ath_print(common, ATH_DBG_CONFIG, | ||
207 | "TX streams %d, RX streams: %d\n", | ||
208 | tx_streams, rx_streams); | ||
209 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | 227 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; |
210 | ht_info->mcs.tx_params |= ((tx_streams - 1) << | 228 | ht_info->mcs.tx_params |= ((tx_streams - 1) << |
211 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | 229 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); |
212 | } | 230 | } |
213 | 231 | ||
214 | ht_info->mcs.rx_mask[0] = 0xff; | 232 | for (i = 0; i < rx_streams; i++) |
215 | if (rx_streams >= 2) | 233 | ht_info->mcs.rx_mask[i] = 0xff; |
216 | ht_info->mcs.rx_mask[1] = 0xff; | ||
217 | 234 | ||
218 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; | 235 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; |
219 | } | 236 | } |