aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c112
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c311
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c110
11 files changed, 291 insertions, 294 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 2a40fa2cd914..9ff53c9c4119 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -21,7 +21,6 @@
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/leds.h> 22#include <linux/leds.h>
23 23
24#include "rc.h"
25#include "debug.h" 24#include "debug.h"
26#include "common.h" 25#include "common.h"
27 26
@@ -423,6 +422,7 @@ struct ath_led {
423#define SC_OP_BT_PRIORITY_DETECTED BIT(21) 422#define SC_OP_BT_PRIORITY_DETECTED BIT(21)
424 423
425struct ath_wiphy; 424struct ath_wiphy;
425struct ath_rate_table;
426 426
427struct ath_softc { 427struct ath_softc {
428 struct ieee80211_hw *hw; 428 struct ieee80211_hw *hw;
@@ -467,9 +467,8 @@ struct ath_softc {
467 struct ath_rx rx; 467 struct ath_rx rx;
468 struct ath_tx tx; 468 struct ath_tx tx;
469 struct ath_beacon beacon; 469 struct ath_beacon beacon;
470 struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
471 const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
472 const struct ath_rate_table *cur_rate_table; 470 const struct ath_rate_table *cur_rate_table;
471 enum wireless_mode cur_rate_mode;
473 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 472 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
474 473
475 struct ath_led radio_led; 474 struct ath_led radio_led;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index b10c884f2933..cb774cc828a3 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -65,9 +65,9 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
65 struct ath_common *common = ath9k_hw_common(ah); 65 struct ath_common *common = ath9k_hw_common(ah);
66 struct ath_desc *ds; 66 struct ath_desc *ds;
67 struct ath9k_11n_rate_series series[4]; 67 struct ath9k_11n_rate_series series[4];
68 const struct ath_rate_table *rt;
69 int flags, antenna, ctsrate = 0, ctsduration = 0; 68 int flags, antenna, ctsrate = 0, ctsduration = 0;
70 u8 rate; 69 struct ieee80211_supported_band *sband;
70 u8 rate = 0;
71 71
72 ds = bf->bf_desc; 72 ds = bf->bf_desc;
73 flags = ATH9K_TXDESC_NOACK; 73 flags = ATH9K_TXDESC_NOACK;
@@ -91,10 +91,10 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
91 91
92 ds->ds_data = bf->bf_buf_addr; 92 ds->ds_data = bf->bf_buf_addr;
93 93
94 rt = sc->cur_rate_table; 94 sband = &sc->sbands[common->hw->conf.channel->band];
95 rate = rt->info[0].ratecode; 95 rate = sband->bitrates[0].hw_value;
96 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) 96 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
97 rate |= rt->info[0].short_preamble; 97 rate |= sband->bitrates[0].hw_value_short;
98 98
99 ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN, 99 ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
100 ATH9K_PKT_TYPE_BEACON, 100 ATH9K_PKT_TYPE_BEACON,
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 06f1fcfb03e9..608fa06e531c 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -255,21 +255,11 @@ static const struct file_operations fops_interrupt = {
255 .owner = THIS_MODULE 255 .owner = THIS_MODULE
256}; 256};
257 257
258void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) 258void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
259{ 259{
260 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
261 struct ieee80211_tx_rate *rates = tx_info->status.rates;
262 int final_ts_idx = 0, idx, i;
263 struct ath_rc_stats *stats; 260 struct ath_rc_stats *stats;
264 261
265 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 262 stats = &sc->debug.stats.rcstats[final_rate];
266 if (!rates[i].count)
267 break;
268
269 final_ts_idx = i;
270 }
271 idx = rates[final_ts_idx].idx;
272 stats = &sc->debug.stats.rcstats[idx];
273 stats->success++; 263 stats->success++;
274} 264}
275 265
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 749e85d57551..f282eeef669b 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -18,6 +18,7 @@
18#define DEBUG_H 18#define DEBUG_H
19 19
20#include "hw.h" 20#include "hw.h"
21#include "rc.h"
21 22
22struct ath_txq; 23struct ath_txq;
23struct ath_buf; 24struct ath_buf;
@@ -138,7 +139,7 @@ void ath9k_exit_debug(struct ath_hw *ah);
138int ath9k_debug_create_root(void); 139int ath9k_debug_create_root(void);
139void ath9k_debug_remove_root(void); 140void ath9k_debug_remove_root(void);
140void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); 141void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
141void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb); 142void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
142void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 143void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
143 struct ath_buf *bf); 144 struct ath_buf *bf);
144void ath_debug_stat_retries(struct ath_softc *sc, int rix, 145void ath_debug_stat_retries(struct ath_softc *sc, int rix,
@@ -170,7 +171,7 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
170} 171}
171 172
172static inline void ath_debug_stat_rc(struct ath_softc *sc, 173static inline void ath_debug_stat_rc(struct ath_softc *sc,
173 struct sk_buff *skb) 174 int final_rate)
174{ 175{
175} 176}
176 177
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 53a7b980d8f6..63d84613dc96 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -148,22 +148,19 @@ bool ath9k_get_channel_edges(struct ath_hw *ah,
148} 148}
149 149
150u16 ath9k_hw_computetxtime(struct ath_hw *ah, 150u16 ath9k_hw_computetxtime(struct ath_hw *ah,
151 const struct ath_rate_table *rates, 151 u8 phy, int kbps,
152 u32 frameLen, u16 rateix, 152 u32 frameLen, u16 rateix,
153 bool shortPreamble) 153 bool shortPreamble)
154{ 154{
155 u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime; 155 u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
156 u32 kbps;
157
158 kbps = rates->info[rateix].ratekbps;
159 156
160 if (kbps == 0) 157 if (kbps == 0)
161 return 0; 158 return 0;
162 159
163 switch (rates->info[rateix].phy) { 160 switch (phy) {
164 case WLAN_RC_PHY_CCK: 161 case WLAN_RC_PHY_CCK:
165 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; 162 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
166 if (shortPreamble && rates->info[rateix].short_preamble) 163 if (shortPreamble)
167 phyTime >>= 1; 164 phyTime >>= 1;
168 numBits = frameLen << 3; 165 numBits = frameLen << 3;
169 txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps); 166 txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
@@ -194,8 +191,7 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah,
194 break; 191 break;
195 default: 192 default:
196 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, 193 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
197 "Unknown phy %u (rate ix %u)\n", 194 "Unknown phy %u (rate ix %u)\n", phy, rateix);
198 rates->info[rateix].phy, rateix);
199 txTime = 0; 195 txTime = 0;
200 break; 196 break;
201 } 197 }
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index a22ed766b6ae..b12634262d97 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -647,7 +647,7 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
647u32 ath9k_hw_reverse_bits(u32 val, u32 n); 647u32 ath9k_hw_reverse_bits(u32 val, u32 n);
648bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high); 648bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
649u16 ath9k_hw_computetxtime(struct ath_hw *ah, 649u16 ath9k_hw_computetxtime(struct ath_hw *ah,
650 const struct ath_rate_table *rates, 650 u8 phy, int kbps,
651 u32 frameLen, u16 rateix, bool shortPreamble); 651 u32 frameLen, u16 rateix, bool shortPreamble);
652void ath9k_hw_get_channel_centers(struct ath_hw *ah, 652void ath9k_hw_get_channel_centers(struct ath_hw *ah,
653 struct ath9k_channel *chan, 653 struct ath9k_channel *chan,
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index fefb65dafb1c..29dfe14751a7 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -616,7 +616,6 @@ enum ath9k_cipher {
616 616
617struct ath_hw; 617struct ath_hw;
618struct ath9k_channel; 618struct ath9k_channel;
619struct ath_rate_table;
620 619
621u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q); 620u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
622void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp); 621void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index cbf5d2a1bb26..bd1e2de3a1f9 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -104,37 +104,55 @@ static struct ieee80211_channel ath9k_5ghz_chantable[] = {
104 CHAN5G(5825, 37), /* Channel 165 */ 104 CHAN5G(5825, 37), /* Channel 165 */
105}; 105};
106 106
107/* Atheros hardware rate code addition for short premble */
108#define SHPCHECK(__hw_rate, __flags) \
109 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
110
111#define RATE(_bitrate, _hw_rate, _flags) { \
112 .bitrate = (_bitrate), \
113 .flags = (_flags), \
114 .hw_value = (_hw_rate), \
115 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
116}
117
118static struct ieee80211_rate ath9k_legacy_rates[] = {
119 RATE(10, 0x1b, 0),
120 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
121 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
122 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
123 RATE(60, 0x0b, 0),
124 RATE(90, 0x0f, 0),
125 RATE(120, 0x0a, 0),
126 RATE(180, 0x0e, 0),
127 RATE(240, 0x09, 0),
128 RATE(360, 0x0d, 0),
129 RATE(480, 0x08, 0),
130 RATE(540, 0x0c, 0),
131};
132
107static void ath_cache_conf_rate(struct ath_softc *sc, 133static void ath_cache_conf_rate(struct ath_softc *sc,
108 struct ieee80211_conf *conf) 134 struct ieee80211_conf *conf)
109{ 135{
110 switch (conf->channel->band) { 136 switch (conf->channel->band) {
111 case IEEE80211_BAND_2GHZ: 137 case IEEE80211_BAND_2GHZ:
112 if (conf_is_ht20(conf)) 138 if (conf_is_ht20(conf))
113 sc->cur_rate_table = 139 sc->cur_rate_mode = ATH9K_MODE_11NG_HT20;
114 sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
115 else if (conf_is_ht40_minus(conf)) 140 else if (conf_is_ht40_minus(conf))
116 sc->cur_rate_table = 141 sc->cur_rate_mode = ATH9K_MODE_11NG_HT40MINUS;
117 sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
118 else if (conf_is_ht40_plus(conf)) 142 else if (conf_is_ht40_plus(conf))
119 sc->cur_rate_table = 143 sc->cur_rate_mode = ATH9K_MODE_11NG_HT40PLUS;
120 sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
121 else 144 else
122 sc->cur_rate_table = 145 sc->cur_rate_mode = ATH9K_MODE_11G;
123 sc->hw_rate_table[ATH9K_MODE_11G];
124 break; 146 break;
125 case IEEE80211_BAND_5GHZ: 147 case IEEE80211_BAND_5GHZ:
126 if (conf_is_ht20(conf)) 148 if (conf_is_ht20(conf))
127 sc->cur_rate_table = 149 sc->cur_rate_mode = ATH9K_MODE_11NA_HT20;
128 sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
129 else if (conf_is_ht40_minus(conf)) 150 else if (conf_is_ht40_minus(conf))
130 sc->cur_rate_table = 151 sc->cur_rate_mode = ATH9K_MODE_11NA_HT40MINUS;
131 sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
132 else if (conf_is_ht40_plus(conf)) 152 else if (conf_is_ht40_plus(conf))
133 sc->cur_rate_table = 153 sc->cur_rate_mode = ATH9K_MODE_11NA_HT40PLUS;
134 sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
135 else 154 else
136 sc->cur_rate_table = 155 sc->cur_rate_mode = ATH9K_MODE_11A;
137 sc->hw_rate_table[ATH9K_MODE_11A];
138 break; 156 break;
139 default: 157 default:
140 BUG_ON(1); 158 BUG_ON(1);
@@ -190,51 +208,6 @@ static u8 parse_mpdudensity(u8 mpdudensity)
190 } 208 }
191} 209}
192 210
193static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
194{
195 const struct ath_rate_table *rate_table = NULL;
196 struct ieee80211_supported_band *sband;
197 struct ieee80211_rate *rate;
198 int i, maxrates;
199
200 switch (band) {
201 case IEEE80211_BAND_2GHZ:
202 rate_table = sc->hw_rate_table[ATH9K_MODE_11G];
203 break;
204 case IEEE80211_BAND_5GHZ:
205 rate_table = sc->hw_rate_table[ATH9K_MODE_11A];
206 break;
207 default:
208 break;
209 }
210
211 if (rate_table == NULL)
212 return;
213
214 sband = &sc->sbands[band];
215 rate = sc->rates[band];
216
217 if (rate_table->rate_cnt > ATH_RATE_MAX)
218 maxrates = ATH_RATE_MAX;
219 else
220 maxrates = rate_table->rate_cnt;
221
222 for (i = 0; i < maxrates; i++) {
223 rate[i].bitrate = rate_table->info[i].ratekbps / 100;
224 rate[i].hw_value = rate_table->info[i].ratecode;
225 if (rate_table->info[i].short_preamble) {
226 rate[i].hw_value_short = rate_table->info[i].ratecode |
227 rate_table->info[i].short_preamble;
228 rate[i].flags = IEEE80211_RATE_SHORT_PREAMBLE;
229 }
230 sband->n_bitrates++;
231
232 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
233 "Rate: %2dMbps, ratecode: %2d\n",
234 rate[i].bitrate / 10, rate[i].hw_value);
235 }
236}
237
238static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc, 211static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc,
239 struct ieee80211_hw *hw) 212 struct ieee80211_hw *hw)
240{ 213{
@@ -1701,12 +1674,6 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
1701 /* default to MONITOR mode */ 1674 /* default to MONITOR mode */
1702 sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; 1675 sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
1703 1676
1704 /* Setup rate tables */
1705
1706 ath_rate_attach(sc);
1707 ath_setup_rates(sc, IEEE80211_BAND_2GHZ);
1708 ath_setup_rates(sc, IEEE80211_BAND_5GHZ);
1709
1710 /* 1677 /*
1711 * Allocate hardware transmit queues: one queue for 1678 * Allocate hardware transmit queues: one queue for
1712 * beacon frames and one data queue for each QoS 1679 * beacon frames and one data queue for each QoS
@@ -1827,19 +1794,22 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
1827 /* setup channels and rates */ 1794 /* setup channels and rates */
1828 1795
1829 sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; 1796 sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
1830 sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
1831 sc->rates[IEEE80211_BAND_2GHZ];
1832 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; 1797 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
1833 sc->sbands[IEEE80211_BAND_2GHZ].n_channels = 1798 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
1834 ARRAY_SIZE(ath9k_2ghz_chantable); 1799 ARRAY_SIZE(ath9k_2ghz_chantable);
1800 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
1801 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
1802 ARRAY_SIZE(ath9k_legacy_rates);
1835 1803
1836 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { 1804 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
1837 sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; 1805 sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
1838 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
1839 sc->rates[IEEE80211_BAND_5GHZ];
1840 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; 1806 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
1841 sc->sbands[IEEE80211_BAND_5GHZ].n_channels = 1807 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
1842 ARRAY_SIZE(ath9k_5ghz_chantable); 1808 ARRAY_SIZE(ath9k_5ghz_chantable);
1809 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
1810 ath9k_legacy_rates + 4;
1811 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
1812 ARRAY_SIZE(ath9k_legacy_rates) - 4;
1843 } 1813 }
1844 1814
1845 switch (ah->btcoex_hw.scheme) { 1815 switch (ah->btcoex_hw.scheme) {
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 1d96777b4cd2..66d3004af2bc 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -19,132 +19,133 @@
19 19
20static const struct ath_rate_table ar5416_11na_ratetable = { 20static const struct ath_rate_table ar5416_11na_ratetable = {
21 42, 21 42,
22 8, /* MCS start */
22 { 23 {
23 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 24 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
24 5400, 0x0b, 0x00, 12, 25 5400, 0, 0x00, 12,
25 0, 0, 0, 0, 0, 0 }, 26 0, 0, 0, 0, 0, 0 },
26 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 27 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
27 7800, 0x0f, 0x00, 18, 28 7800, 1, 0x00, 18,
28 0, 1, 1, 1, 1, 0 }, 29 0, 1, 1, 1, 1, 0 },
29 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 30 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
30 10000, 0x0a, 0x00, 24, 31 10000, 2, 0x00, 24,
31 2, 2, 2, 2, 2, 0 }, 32 2, 2, 2, 2, 2, 0 },
32 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 33 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
33 13900, 0x0e, 0x00, 36, 34 13900, 3, 0x00, 36,
34 2, 3, 3, 3, 3, 0 }, 35 2, 3, 3, 3, 3, 0 },
35 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 36 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
36 17300, 0x09, 0x00, 48, 37 17300, 4, 0x00, 48,
37 4, 4, 4, 4, 4, 0 }, 38 4, 4, 4, 4, 4, 0 },
38 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 39 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
39 23000, 0x0d, 0x00, 72, 40 23000, 5, 0x00, 72,
40 4, 5, 5, 5, 5, 0 }, 41 4, 5, 5, 5, 5, 0 },
41 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 42 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
42 27400, 0x08, 0x00, 96, 43 27400, 6, 0x00, 96,
43 4, 6, 6, 6, 6, 0 }, 44 4, 6, 6, 6, 6, 0 },
44 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 45 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
45 29300, 0x0c, 0x00, 108, 46 29300, 7, 0x00, 108,
46 4, 7, 7, 7, 7, 0 }, 47 4, 7, 7, 7, 7, 0 },
47 { VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 48 { VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
48 6400, 0x80, 0x00, 0, 49 6400, 0, 0x00, 0,
49 0, 8, 24, 8, 24, 3216 }, 50 0, 8, 24, 8, 24, 3216 },
50 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 51 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
51 12700, 0x81, 0x00, 1, 52 12700, 1, 0x00, 1,
52 2, 9, 25, 9, 25, 6434 }, 53 2, 9, 25, 9, 25, 6434 },
53 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 54 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
54 18800, 0x82, 0x00, 2, 55 18800, 2, 0x00, 2,
55 2, 10, 26, 10, 26, 9650 }, 56 2, 10, 26, 10, 26, 9650 },
56 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 57 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
57 25000, 0x83, 0x00, 3, 58 25000, 3, 0x00, 3,
58 4, 11, 27, 11, 27, 12868 }, 59 4, 11, 27, 11, 27, 12868 },
59 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 60 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
60 36700, 0x84, 0x00, 4, 61 36700, 4, 0x00, 4,
61 4, 12, 28, 12, 28, 19304 }, 62 4, 12, 28, 12, 28, 19304 },
62 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 63 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
63 48100, 0x85, 0x00, 5, 64 48100, 5, 0x00, 5,
64 4, 13, 29, 13, 29, 25740 }, 65 4, 13, 29, 13, 29, 25740 },
65 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 66 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
66 53500, 0x86, 0x00, 6, 67 53500, 6, 0x00, 6,
67 4, 14, 30, 14, 30, 28956 }, 68 4, 14, 30, 14, 30, 28956 },
68 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 69 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
69 59000, 0x87, 0x00, 7, 70 59000, 7, 0x00, 7,
70 4, 15, 31, 15, 32, 32180 }, 71 4, 15, 31, 15, 32, 32180 },
71 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 72 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
72 12700, 0x88, 0x00, 73 12700, 8, 0x00,
73 8, 3, 16, 33, 16, 33, 6430 }, 74 8, 3, 16, 33, 16, 33, 6430 },
74 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 75 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
75 24800, 0x89, 0x00, 9, 76 24800, 9, 0x00, 9,
76 2, 17, 34, 17, 34, 12860 }, 77 2, 17, 34, 17, 34, 12860 },
77 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 78 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
78 36600, 0x8a, 0x00, 10, 79 36600, 10, 0x00, 10,
79 2, 18, 35, 18, 35, 19300 }, 80 2, 18, 35, 18, 35, 19300 },
80 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 81 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
81 48100, 0x8b, 0x00, 11, 82 48100, 11, 0x00, 11,
82 4, 19, 36, 19, 36, 25736 }, 83 4, 19, 36, 19, 36, 25736 },
83 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 84 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
84 69500, 0x8c, 0x00, 12, 85 69500, 12, 0x00, 12,
85 4, 20, 37, 20, 37, 38600 }, 86 4, 20, 37, 20, 37, 38600 },
86 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 87 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
87 89500, 0x8d, 0x00, 13, 88 89500, 13, 0x00, 13,
88 4, 21, 38, 21, 38, 51472 }, 89 4, 21, 38, 21, 38, 51472 },
89 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 90 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
90 98900, 0x8e, 0x00, 14, 91 98900, 14, 0x00, 14,
91 4, 22, 39, 22, 39, 57890 }, 92 4, 22, 39, 22, 39, 57890 },
92 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 93 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
93 108300, 0x8f, 0x00, 15, 94 108300, 15, 0x00, 15,
94 4, 23, 40, 23, 41, 64320 }, 95 4, 23, 40, 23, 41, 64320 },
95 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 96 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
96 13200, 0x80, 0x00, 0, 97 13200, 0, 0x00, 0,
97 0, 8, 24, 24, 24, 6684 }, 98 0, 8, 24, 24, 24, 6684 },
98 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 99 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
99 25900, 0x81, 0x00, 1, 100 25900, 1, 0x00, 1,
100 2, 9, 25, 25, 25, 13368 }, 101 2, 9, 25, 25, 25, 13368 },
101 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 102 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
102 38600, 0x82, 0x00, 2, 103 38600, 2, 0x00, 2,
103 2, 10, 26, 26, 26, 20052 }, 104 2, 10, 26, 26, 26, 20052 },
104 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 105 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
105 49800, 0x83, 0x00, 3, 106 49800, 3, 0x00, 3,
106 4, 11, 27, 27, 27, 26738 }, 107 4, 11, 27, 27, 27, 26738 },
107 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 108 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
108 72200, 0x84, 0x00, 4, 109 72200, 4, 0x00, 4,
109 4, 12, 28, 28, 28, 40104 }, 110 4, 12, 28, 28, 28, 40104 },
110 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 111 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
111 92900, 0x85, 0x00, 5, 112 92900, 5, 0x00, 5,
112 4, 13, 29, 29, 29, 53476 }, 113 4, 13, 29, 29, 29, 53476 },
113 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ 114 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
114 102700, 0x86, 0x00, 6, 115 102700, 6, 0x00, 6,
115 4, 14, 30, 30, 30, 60156 }, 116 4, 14, 30, 30, 30, 60156 },
116 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 117 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
117 112000, 0x87, 0x00, 7, 118 112000, 7, 0x00, 7,
118 4, 15, 31, 32, 32, 66840 }, 119 4, 15, 31, 32, 32, 66840 },
119 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ 120 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
120 122000, 0x87, 0x00, 7, 121 122000, 7, 0x00, 7,
121 4, 15, 31, 32, 32, 74200 }, 122 4, 15, 31, 32, 32, 74200 },
122 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 123 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
123 25800, 0x88, 0x00, 8, 124 25800, 8, 0x00, 8,
124 0, 16, 33, 33, 33, 13360 }, 125 0, 16, 33, 33, 33, 13360 },
125 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 126 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
126 49800, 0x89, 0x00, 9, 127 49800, 9, 0x00, 9,
127 2, 17, 34, 34, 34, 26720 }, 128 2, 17, 34, 34, 34, 26720 },
128 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 129 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
129 71900, 0x8a, 0x00, 10, 130 71900, 10, 0x00, 10,
130 2, 18, 35, 35, 35, 40080 }, 131 2, 18, 35, 35, 35, 40080 },
131 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 132 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
132 92500, 0x8b, 0x00, 11, 133 92500, 11, 0x00, 11,
133 4, 19, 36, 36, 36, 53440 }, 134 4, 19, 36, 36, 36, 53440 },
134 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 135 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
135 130300, 0x8c, 0x00, 12, 136 130300, 12, 0x00, 12,
136 4, 20, 37, 37, 37, 80160 }, 137 4, 20, 37, 37, 37, 80160 },
137 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 138 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
138 162800, 0x8d, 0x00, 13, 139 162800, 13, 0x00, 13,
139 4, 21, 38, 38, 38, 106880 }, 140 4, 21, 38, 38, 38, 106880 },
140 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 141 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
141 178200, 0x8e, 0x00, 14, 142 178200, 14, 0x00, 14,
142 4, 22, 39, 39, 39, 120240 }, 143 4, 22, 39, 39, 39, 120240 },
143 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 144 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
144 192100, 0x8f, 0x00, 15, 145 192100, 15, 0x00, 15,
145 4, 23, 40, 41, 41, 133600 }, 146 4, 23, 40, 41, 41, 133600 },
146 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ 147 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
147 207000, 0x8f, 0x00, 15, 148 207000, 15, 0x00, 15,
148 4, 23, 40, 41, 41, 148400 }, 149 4, 23, 40, 41, 41, 148400 },
149 }, 150 },
150 50, /* probe interval */ 151 50, /* probe interval */
@@ -156,144 +157,145 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
156 157
157static const struct ath_rate_table ar5416_11ng_ratetable = { 158static const struct ath_rate_table ar5416_11ng_ratetable = {
158 46, 159 46,
160 12, /* MCS start */
159 { 161 {
160 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 162 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
161 900, 0x1b, 0x00, 2, 163 900, 0, 0x00, 2,
162 0, 0, 0, 0, 0, 0 }, 164 0, 0, 0, 0, 0, 0 },
163 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 165 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
164 1900, 0x1a, 0x04, 4, 166 1900, 1, 0x04, 4,
165 1, 1, 1, 1, 1, 0 }, 167 1, 1, 1, 1, 1, 0 },
166 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 168 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
167 4900, 0x19, 0x04, 11, 169 4900, 2, 0x04, 11,
168 2, 2, 2, 2, 2, 0 }, 170 2, 2, 2, 2, 2, 0 },
169 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 171 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
170 8100, 0x18, 0x04, 22, 172 8100, 3, 0x04, 22,
171 3, 3, 3, 3, 3, 0 }, 173 3, 3, 3, 3, 3, 0 },
172 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 174 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
173 5400, 0x0b, 0x00, 12, 175 5400, 4, 0x00, 12,
174 4, 4, 4, 4, 4, 0 }, 176 4, 4, 4, 4, 4, 0 },
175 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 177 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
176 7800, 0x0f, 0x00, 18, 178 7800, 5, 0x00, 18,
177 4, 5, 5, 5, 5, 0 }, 179 4, 5, 5, 5, 5, 0 },
178 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 180 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
179 10100, 0x0a, 0x00, 24, 181 10100, 6, 0x00, 24,
180 6, 6, 6, 6, 6, 0 }, 182 6, 6, 6, 6, 6, 0 },
181 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 183 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
182 14100, 0x0e, 0x00, 36, 184 14100, 7, 0x00, 36,
183 6, 7, 7, 7, 7, 0 }, 185 6, 7, 7, 7, 7, 0 },
184 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 186 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
185 17700, 0x09, 0x00, 48, 187 17700, 8, 0x00, 48,
186 8, 8, 8, 8, 8, 0 }, 188 8, 8, 8, 8, 8, 0 },
187 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 189 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
188 23700, 0x0d, 0x00, 72, 190 23700, 9, 0x00, 72,
189 8, 9, 9, 9, 9, 0 }, 191 8, 9, 9, 9, 9, 0 },
190 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 192 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
191 27400, 0x08, 0x00, 96, 193 27400, 10, 0x00, 96,
192 8, 10, 10, 10, 10, 0 }, 194 8, 10, 10, 10, 10, 0 },
193 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 195 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
194 30900, 0x0c, 0x00, 108, 196 30900, 11, 0x00, 108,
195 8, 11, 11, 11, 11, 0 }, 197 8, 11, 11, 11, 11, 0 },
196 { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 198 { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
197 6400, 0x80, 0x00, 0, 199 6400, 0, 0x00, 0,
198 4, 12, 28, 12, 28, 3216 }, 200 4, 12, 28, 12, 28, 3216 },
199 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 201 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
200 12700, 0x81, 0x00, 1, 202 12700, 1, 0x00, 1,
201 6, 13, 29, 13, 29, 6434 }, 203 6, 13, 29, 13, 29, 6434 },
202 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 204 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
203 18800, 0x82, 0x00, 2, 205 18800, 2, 0x00, 2,
204 6, 14, 30, 14, 30, 9650 }, 206 6, 14, 30, 14, 30, 9650 },
205 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 207 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
206 25000, 0x83, 0x00, 3, 208 25000, 3, 0x00, 3,
207 8, 15, 31, 15, 31, 12868 }, 209 8, 15, 31, 15, 31, 12868 },
208 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 210 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
209 36700, 0x84, 0x00, 4, 211 36700, 4, 0x00, 4,
210 8, 16, 32, 16, 32, 19304 }, 212 8, 16, 32, 16, 32, 19304 },
211 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 213 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
212 48100, 0x85, 0x00, 5, 214 48100, 5, 0x00, 5,
213 8, 17, 33, 17, 33, 25740 }, 215 8, 17, 33, 17, 33, 25740 },
214 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 216 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
215 53500, 0x86, 0x00, 6, 217 53500, 6, 0x00, 6,
216 8, 18, 34, 18, 34, 28956 }, 218 8, 18, 34, 18, 34, 28956 },
217 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 219 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
218 59000, 0x87, 0x00, 7, 220 59000, 7, 0x00, 7,
219 8, 19, 35, 19, 36, 32180 }, 221 8, 19, 35, 19, 36, 32180 },
220 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 222 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
221 12700, 0x88, 0x00, 8, 223 12700, 8, 0x00, 8,
222 4, 20, 37, 20, 37, 6430 }, 224 4, 20, 37, 20, 37, 6430 },
223 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 225 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
224 24800, 0x89, 0x00, 9, 226 24800, 9, 0x00, 9,
225 6, 21, 38, 21, 38, 12860 }, 227 6, 21, 38, 21, 38, 12860 },
226 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 228 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
227 36600, 0x8a, 0x00, 10, 229 36600, 10, 0x00, 10,
228 6, 22, 39, 22, 39, 19300 }, 230 6, 22, 39, 22, 39, 19300 },
229 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 231 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
230 48100, 0x8b, 0x00, 11, 232 48100, 11, 0x00, 11,
231 8, 23, 40, 23, 40, 25736 }, 233 8, 23, 40, 23, 40, 25736 },
232 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 234 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
233 69500, 0x8c, 0x00, 12, 235 69500, 12, 0x00, 12,
234 8, 24, 41, 24, 41, 38600 }, 236 8, 24, 41, 24, 41, 38600 },
235 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 237 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
236 89500, 0x8d, 0x00, 13, 238 89500, 13, 0x00, 13,
237 8, 25, 42, 25, 42, 51472 }, 239 8, 25, 42, 25, 42, 51472 },
238 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 240 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
239 98900, 0x8e, 0x00, 14, 241 98900, 14, 0x00, 14,
240 8, 26, 43, 26, 44, 57890 }, 242 8, 26, 43, 26, 44, 57890 },
241 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 243 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
242 108300, 0x8f, 0x00, 15, 244 108300, 15, 0x00, 15,
243 8, 27, 44, 27, 45, 64320 }, 245 8, 27, 44, 27, 45, 64320 },
244 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 246 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
245 13200, 0x80, 0x00, 0, 247 13200, 0, 0x00, 0,
246 8, 12, 28, 28, 28, 6684 }, 248 8, 12, 28, 28, 28, 6684 },
247 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 249 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
248 25900, 0x81, 0x00, 1, 250 25900, 1, 0x00, 1,
249 8, 13, 29, 29, 29, 13368 }, 251 8, 13, 29, 29, 29, 13368 },
250 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 252 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
251 38600, 0x82, 0x00, 2, 253 38600, 2, 0x00, 2,
252 8, 14, 30, 30, 30, 20052 }, 254 8, 14, 30, 30, 30, 20052 },
253 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 255 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
254 49800, 0x83, 0x00, 3, 256 49800, 3, 0x00, 3,
255 8, 15, 31, 31, 31, 26738 }, 257 8, 15, 31, 31, 31, 26738 },
256 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 258 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
257 72200, 0x84, 0x00, 4, 259 72200, 4, 0x00, 4,
258 8, 16, 32, 32, 32, 40104 }, 260 8, 16, 32, 32, 32, 40104 },
259 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 261 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
260 92900, 0x85, 0x00, 5, 262 92900, 5, 0x00, 5,
261 8, 17, 33, 33, 33, 53476 }, 263 8, 17, 33, 33, 33, 53476 },
262 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ 264 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
263 102700, 0x86, 0x00, 6, 265 102700, 6, 0x00, 6,
264 8, 18, 34, 34, 34, 60156 }, 266 8, 18, 34, 34, 34, 60156 },
265 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 267 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
266 112000, 0x87, 0x00, 7, 268 112000, 7, 0x00, 7,
267 8, 19, 35, 36, 36, 66840 }, 269 8, 19, 35, 36, 36, 66840 },
268 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ 270 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
269 122000, 0x87, 0x00, 7, 271 122000, 7, 0x00, 7,
270 8, 19, 35, 36, 36, 74200 }, 272 8, 19, 35, 36, 36, 74200 },
271 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 273 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
272 25800, 0x88, 0x00, 8, 274 25800, 8, 0x00, 8,
273 8, 20, 37, 37, 37, 13360 }, 275 8, 20, 37, 37, 37, 13360 },
274 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 276 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
275 49800, 0x89, 0x00, 9, 277 49800, 9, 0x00, 9,
276 8, 21, 38, 38, 38, 26720 }, 278 8, 21, 38, 38, 38, 26720 },
277 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 279 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
278 71900, 0x8a, 0x00, 10, 280 71900, 10, 0x00, 10,
279 8, 22, 39, 39, 39, 40080 }, 281 8, 22, 39, 39, 39, 40080 },
280 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 282 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
281 92500, 0x8b, 0x00, 11, 283 92500, 11, 0x00, 11,
282 8, 23, 40, 40, 40, 53440 }, 284 8, 23, 40, 40, 40, 53440 },
283 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 285 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
284 130300, 0x8c, 0x00, 12, 286 130300, 12, 0x00, 12,
285 8, 24, 41, 41, 41, 80160 }, 287 8, 24, 41, 41, 41, 80160 },
286 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 288 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
287 162800, 0x8d, 0x00, 13, 289 162800, 13, 0x00, 13,
288 8, 25, 42, 42, 42, 106880 }, 290 8, 25, 42, 42, 42, 106880 },
289 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 291 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
290 178200, 0x8e, 0x00, 14, 292 178200, 14, 0x00, 14,
291 8, 26, 43, 43, 43, 120240 }, 293 8, 26, 43, 43, 43, 120240 },
292 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 294 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
293 192100, 0x8f, 0x00, 15, 295 192100, 15, 0x00, 15,
294 8, 27, 44, 45, 45, 133600 }, 296 8, 27, 44, 45, 45, 133600 },
295 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ 297 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
296 207000, 0x8f, 0x00, 15, 298 207000, 15, 0x00, 15,
297 8, 27, 44, 45, 45, 148400 }, 299 8, 27, 44, 45, 45, 148400 },
298 }, 300 },
299 50, /* probe interval */ 301 50, /* probe interval */
@@ -302,30 +304,31 @@ static const struct ath_rate_table ar5416_11ng_ratetable = {
302 304
303static const struct ath_rate_table ar5416_11a_ratetable = { 305static const struct ath_rate_table ar5416_11a_ratetable = {
304 8, 306 8,
307 0,
305 { 308 {
306 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 309 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
307 5400, 0x0b, 0x00, (0x80|12), 310 5400, 0, 0x00, 12,
308 0, 0, 0 }, 311 0, 0, 0 },
309 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 312 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
310 7800, 0x0f, 0x00, 18, 313 7800, 1, 0x00, 18,
311 0, 1, 0 }, 314 0, 1, 0 },
312 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 315 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
313 10000, 0x0a, 0x00, (0x80|24), 316 10000, 2, 0x00, 24,
314 2, 2, 0 }, 317 2, 2, 0 },
315 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 318 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
316 13900, 0x0e, 0x00, 36, 319 13900, 3, 0x00, 36,
317 2, 3, 0 }, 320 2, 3, 0 },
318 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 321 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
319 17300, 0x09, 0x00, (0x80|48), 322 17300, 4, 0x00, 48,
320 4, 4, 0 }, 323 4, 4, 0 },
321 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 324 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
322 23000, 0x0d, 0x00, 72, 325 23000, 5, 0x00, 72,
323 4, 5, 0 }, 326 4, 5, 0 },
324 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 327 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
325 27400, 0x08, 0x00, 96, 328 27400, 6, 0x00, 96,
326 4, 6, 0 }, 329 4, 6, 0 },
327 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 330 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
328 29300, 0x0c, 0x00, 108, 331 29300, 7, 0x00, 108,
329 4, 7, 0 }, 332 4, 7, 0 },
330 }, 333 },
331 50, /* probe interval */ 334 50, /* probe interval */
@@ -334,48 +337,63 @@ static const struct ath_rate_table ar5416_11a_ratetable = {
334 337
335static const struct ath_rate_table ar5416_11g_ratetable = { 338static const struct ath_rate_table ar5416_11g_ratetable = {
336 12, 339 12,
340 0,
337 { 341 {
338 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 342 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
339 900, 0x1b, 0x00, 2, 343 900, 0, 0x00, 2,
340 0, 0, 0 }, 344 0, 0, 0 },
341 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 345 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
342 1900, 0x1a, 0x04, 4, 346 1900, 1, 0x04, 4,
343 1, 1, 0 }, 347 1, 1, 0 },
344 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 348 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
345 4900, 0x19, 0x04, 11, 349 4900, 2, 0x04, 11,
346 2, 2, 0 }, 350 2, 2, 0 },
347 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 351 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
348 8100, 0x18, 0x04, 22, 352 8100, 3, 0x04, 22,
349 3, 3, 0 }, 353 3, 3, 0 },
350 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 354 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
351 5400, 0x0b, 0x00, 12, 355 5400, 4, 0x00, 12,
352 4, 4, 0 }, 356 4, 4, 0 },
353 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 357 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
354 7800, 0x0f, 0x00, 18, 358 7800, 5, 0x00, 18,
355 4, 5, 0 }, 359 4, 5, 0 },
356 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 360 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
357 10000, 0x0a, 0x00, 24, 361 10000, 6, 0x00, 24,
358 6, 6, 0 }, 362 6, 6, 0 },
359 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 363 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
360 13900, 0x0e, 0x00, 36, 364 13900, 7, 0x00, 36,
361 6, 7, 0 }, 365 6, 7, 0 },
362 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 366 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
363 17300, 0x09, 0x00, 48, 367 17300, 8, 0x00, 48,
364 8, 8, 0 }, 368 8, 8, 0 },
365 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 369 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
366 23000, 0x0d, 0x00, 72, 370 23000, 9, 0x00, 72,
367 8, 9, 0 }, 371 8, 9, 0 },
368 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 372 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
369 27400, 0x08, 0x00, 96, 373 27400, 10, 0x00, 96,
370 8, 10, 0 }, 374 8, 10, 0 },
371 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 375 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
372 29300, 0x0c, 0x00, 108, 376 29300, 11, 0x00, 108,
373 8, 11, 0 }, 377 8, 11, 0 },
374 }, 378 },
375 50, /* probe interval */ 379 50, /* probe interval */
376 0, /* Phy rates allowed initially */ 380 0, /* Phy rates allowed initially */
377}; 381};
378 382
383static const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX] = {
384 [ATH9K_MODE_11A] = &ar5416_11a_ratetable,
385 [ATH9K_MODE_11G] = &ar5416_11g_ratetable,
386 [ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable,
387 [ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable,
388 [ATH9K_MODE_11NA_HT40PLUS] = &ar5416_11na_ratetable,
389 [ATH9K_MODE_11NA_HT40MINUS] = &ar5416_11na_ratetable,
390 [ATH9K_MODE_11NG_HT40PLUS] = &ar5416_11ng_ratetable,
391 [ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable,
392};
393
394static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
395 struct ieee80211_tx_rate *rate);
396
379static inline int8_t median(int8_t a, int8_t b, int8_t c) 397static inline int8_t median(int8_t a, int8_t b, int8_t c)
380{ 398{
381 if (a >= b) { 399 if (a >= b) {
@@ -534,7 +552,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
534 * capflag matches one of the validity 552 * capflag matches one of the validity
535 * (VALID/VALID_20/VALID_40) flags */ 553 * (VALID/VALID_20/VALID_40) flags */
536 554
537 if (((rate & 0x7F) == (dot11rate & 0x7F)) && 555 if ((rate == dot11rate) &&
538 ((valid & WLAN_RC_CAP_MODE(capflag)) == 556 ((valid & WLAN_RC_CAP_MODE(capflag)) ==
539 WLAN_RC_CAP_MODE(capflag)) && 557 WLAN_RC_CAP_MODE(capflag)) &&
540 !WLAN_RC_PHY_HT(phy)) { 558 !WLAN_RC_PHY_HT(phy)) {
@@ -576,8 +594,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
576 u8 rate = rateset->rs_rates[i]; 594 u8 rate = rateset->rs_rates[i];
577 u8 dot11rate = rate_table->info[j].dot11rate; 595 u8 dot11rate = rate_table->info[j].dot11rate;
578 596
579 if (((rate & 0x7F) != (dot11rate & 0x7F)) || 597 if ((rate != dot11rate) || !WLAN_RC_PHY_HT(phy) ||
580 !WLAN_RC_PHY_HT(phy) ||
581 !WLAN_RC_PHY_HT_VALID(valid, capflag)) 598 !WLAN_RC_PHY_HT_VALID(valid, capflag))
582 continue; 599 continue;
583 600
@@ -696,18 +713,20 @@ static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
696 u8 tries, u8 rix, int rtsctsenable) 713 u8 tries, u8 rix, int rtsctsenable)
697{ 714{
698 rate->count = tries; 715 rate->count = tries;
699 rate->idx = rix; 716 rate->idx = rate_table->info[rix].ratecode;
700 717
701 if (txrc->short_preamble) 718 if (txrc->short_preamble)
702 rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; 719 rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
703 if (txrc->rts || rtsctsenable) 720 if (txrc->rts || rtsctsenable)
704 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; 721 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
705 if (WLAN_RC_PHY_40(rate_table->info[rix].phy)) 722
706 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; 723 if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) {
707 if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
708 rate->flags |= IEEE80211_TX_RC_SHORT_GI;
709 if (WLAN_RC_PHY_HT(rate_table->info[rix].phy))
710 rate->flags |= IEEE80211_TX_RC_MCS; 724 rate->flags |= IEEE80211_TX_RC_MCS;
725 if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
726 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
727 if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
728 rate->flags |= IEEE80211_TX_RC_SHORT_GI;
729 }
711} 730}
712 731
713static void ath_rc_rate_set_rtscts(struct ath_softc *sc, 732static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
@@ -720,7 +739,7 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
720 /* get the cix for the lowest valid rix */ 739 /* get the cix for the lowest valid rix */
721 for (i = 3; i >= 0; i--) { 740 for (i = 3; i >= 0; i--) {
722 if (rates[i].count && (rates[i].idx >= 0)) { 741 if (rates[i].count && (rates[i].idx >= 0)) {
723 rix = rates[i].idx; 742 rix = ath_rc_get_rateindex(rate_table, &rates[i]);
724 break; 743 break;
725 } 744 }
726 } 745 }
@@ -1080,15 +1099,19 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
1080{ 1099{
1081 int rix; 1100 int rix;
1082 1101
1102 if (!(rate->flags & IEEE80211_TX_RC_MCS))
1103 return rate->idx;
1104
1105 rix = rate->idx + rate_table->mcs_start;
1083 if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && 1106 if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
1084 (rate->flags & IEEE80211_TX_RC_SHORT_GI)) 1107 (rate->flags & IEEE80211_TX_RC_SHORT_GI))
1085 rix = rate_table->info[rate->idx].ht_index; 1108 rix = rate_table->info[rix].ht_index;
1086 else if (rate->flags & IEEE80211_TX_RC_SHORT_GI) 1109 else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
1087 rix = rate_table->info[rate->idx].sgi_index; 1110 rix = rate_table->info[rix].sgi_index;
1088 else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 1111 else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1089 rix = rate_table->info[rate->idx].cw40index; 1112 rix = rate_table->info[rix].cw40index;
1090 else 1113 else
1091 rix = rate_table->info[rate->idx].base_index; 1114 rix = rate_table->info[rix].base_index;
1092 1115
1093 return rix; 1116 return rix;
1094} 1117}
@@ -1183,7 +1206,9 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
1183 1206
1184 ath_print(common, ATH_DBG_CONFIG, 1207 ath_print(common, ATH_DBG_CONFIG,
1185 "Choosing rate table for mode: %d\n", mode); 1208 "Choosing rate table for mode: %d\n", mode);
1186 return sc->hw_rate_table[mode]; 1209
1210 sc->cur_rate_mode = mode;
1211 return hw_rate_table[mode];
1187} 1212}
1188 1213
1189static void ath_rc_init(struct ath_softc *sc, 1214static void ath_rc_init(struct ath_softc *sc,
@@ -1197,12 +1222,6 @@ static void ath_rc_init(struct ath_softc *sc,
1197 u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates; 1222 u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
1198 u8 i, j, k, hi = 0, hthi = 0; 1223 u8 i, j, k, hi = 0, hthi = 0;
1199 1224
1200 if (!rate_table) {
1201 ath_print(common, ATH_DBG_FATAL,
1202 "Rate table not initialized\n");
1203 return;
1204 }
1205
1206 /* Initial rate table size. Will change depending 1225 /* Initial rate table size. Will change depending
1207 * on the working rate set */ 1226 * on the working rate set */
1208 ath_rc_priv->rate_table_size = RATE_TABLE_SIZE; 1227 ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
@@ -1357,7 +1376,8 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1357 } 1376 }
1358 } 1377 }
1359 1378
1360 ath_debug_stat_rc(sc, skb); 1379 ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table,
1380 &tx_info->status.rates[final_ts_idx]));
1361} 1381}
1362 1382
1363static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, 1383static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
@@ -1365,7 +1385,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1365{ 1385{
1366 struct ath_softc *sc = priv; 1386 struct ath_softc *sc = priv;
1367 struct ath_rate_priv *ath_rc_priv = priv_sta; 1387 struct ath_rate_priv *ath_rc_priv = priv_sta;
1368 const struct ath_rate_table *rate_table = NULL; 1388 const struct ath_rate_table *rate_table;
1369 bool is_cw40, is_sgi40; 1389 bool is_cw40, is_sgi40;
1370 int i, j = 0; 1390 int i, j = 0;
1371 1391
@@ -1397,11 +1417,9 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1397 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) || 1417 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
1398 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) { 1418 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
1399 rate_table = ath_choose_rate_table(sc, sband->band, 1419 rate_table = ath_choose_rate_table(sc, sband->band,
1400 sta->ht_cap.ht_supported, 1420 sta->ht_cap.ht_supported, is_cw40);
1401 is_cw40); 1421 } else {
1402 } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { 1422 rate_table = hw_rate_table[sc->cur_rate_mode];
1403 /* cur_rate_table would be set on init through config() */
1404 rate_table = sc->cur_rate_table;
1405 } 1423 }
1406 1424
1407 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40); 1425 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
@@ -1445,6 +1463,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1445 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, 1463 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
1446 "Operating HT Bandwidth changed to: %d\n", 1464 "Operating HT Bandwidth changed to: %d\n",
1447 sc->hw->conf.channel_type); 1465 sc->hw->conf.channel_type);
1466 sc->cur_rate_table = hw_rate_table[sc->cur_rate_mode];
1448 } 1467 }
1449 } 1468 }
1450} 1469}
@@ -1497,26 +1516,6 @@ static struct rate_control_ops ath_rate_ops = {
1497 .free_sta = ath_rate_free_sta, 1516 .free_sta = ath_rate_free_sta,
1498}; 1517};
1499 1518
1500void ath_rate_attach(struct ath_softc *sc)
1501{
1502 sc->hw_rate_table[ATH9K_MODE_11A] =
1503 &ar5416_11a_ratetable;
1504 sc->hw_rate_table[ATH9K_MODE_11G] =
1505 &ar5416_11g_ratetable;
1506 sc->hw_rate_table[ATH9K_MODE_11NA_HT20] =
1507 &ar5416_11na_ratetable;
1508 sc->hw_rate_table[ATH9K_MODE_11NG_HT20] =
1509 &ar5416_11ng_ratetable;
1510 sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] =
1511 &ar5416_11na_ratetable;
1512 sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] =
1513 &ar5416_11na_ratetable;
1514 sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] =
1515 &ar5416_11ng_ratetable;
1516 sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
1517 &ar5416_11ng_ratetable;
1518}
1519
1520int ath_rate_control_register(void) 1519int ath_rate_control_register(void)
1521{ 1520{
1522 return ieee80211_rate_control_register(&ath_rate_ops); 1521 return ieee80211_rate_control_register(&ath_rate_ops);
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 51f85ecbe88d..d68bc946bb3a 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -104,6 +104,7 @@ enum {
104 */ 104 */
105struct ath_rate_table { 105struct ath_rate_table {
106 int rate_cnt; 106 int rate_cnt;
107 int mcs_start;
107 struct { 108 struct {
108 int valid; 109 int valid;
109 int valid_single_stream; 110 int valid_single_stream;
@@ -179,8 +180,6 @@ enum ath9k_internal_frame_type {
179 ATH9K_INT_UNPAUSE 180 ATH9K_INT_UNPAUSE
180}; 181};
181 182
182void ath_rate_attach(struct ath_softc *sc);
183u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate);
184int ath_rate_control_register(void); 183int ath_rate_control_register(void);
185void ath_rate_control_unregister(void); 184void ath_rate_control_unregister(void);
186 185
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 745d91995d78..2bb8c91bf4f9 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -70,6 +70,29 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
70static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, 70static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
71 int nbad, int txok, bool update_rc); 71 int nbad, int txok, bool update_rc);
72 72
73enum {
74 MCS_DEFAULT,
75 MCS_HT40,
76 MCS_HT40_SGI,
77};
78
79static int ath_max_4ms_framelen[3][16] = {
80 [MCS_DEFAULT] = {
81 3216, 6434, 9650, 12868, 19304, 25740, 28956, 32180,
82 6430, 12860, 19300, 25736, 38600, 51472, 57890, 64320,
83 },
84 [MCS_HT40] = {
85 6684, 13368, 20052, 26738, 40104, 53476, 60156, 66840,
86 13360, 26720, 40080, 53440, 80160, 106880, 120240, 133600,
87 },
88 [MCS_HT40_SGI] = {
89 /* TODO: Only MCS 7 and 15 updated, recalculate the rest */
90 6684, 13368, 20052, 26738, 40104, 53476, 60156, 74200,
91 13360, 26720, 40080, 53440, 80160, 106880, 120240, 148400,
92 }
93};
94
95
73/*********************/ 96/*********************/
74/* Aggregation logic */ 97/* Aggregation logic */
75/*********************/ 98/*********************/
@@ -459,7 +482,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
459static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, 482static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
460 struct ath_atx_tid *tid) 483 struct ath_atx_tid *tid)
461{ 484{
462 const struct ath_rate_table *rate_table = sc->cur_rate_table;
463 struct sk_buff *skb; 485 struct sk_buff *skb;
464 struct ieee80211_tx_info *tx_info; 486 struct ieee80211_tx_info *tx_info;
465 struct ieee80211_tx_rate *rates; 487 struct ieee80211_tx_rate *rates;
@@ -480,12 +502,20 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
480 502
481 for (i = 0; i < 4; i++) { 503 for (i = 0; i < 4; i++) {
482 if (rates[i].count) { 504 if (rates[i].count) {
483 if (!WLAN_RC_PHY_HT(rate_table->info[rates[i].idx].phy)) { 505 int modeidx;
506 if (!(rates[i].flags & IEEE80211_TX_RC_MCS)) {
484 legacy = 1; 507 legacy = 1;
485 break; 508 break;
486 } 509 }
487 510
488 frmlen = rate_table->info[rates[i].idx].max_4ms_framelen; 511 if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
512 modeidx = MCS_HT40_SGI;
513 else if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
514 modeidx = MCS_HT40;
515 else
516 modeidx = MCS_DEFAULT;
517
518 frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx];
489 max_4ms_framelen = min(max_4ms_framelen, frmlen); 519 max_4ms_framelen = min(max_4ms_framelen, frmlen);
490 } 520 }
491 } 521 }
@@ -523,12 +553,11 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
523static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, 553static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
524 struct ath_buf *bf, u16 frmlen) 554 struct ath_buf *bf, u16 frmlen)
525{ 555{
526 const struct ath_rate_table *rt = sc->cur_rate_table;
527 struct sk_buff *skb = bf->bf_mpdu; 556 struct sk_buff *skb = bf->bf_mpdu;
528 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 557 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
529 u32 nsymbits, nsymbols; 558 u32 nsymbits, nsymbols;
530 u16 minlen; 559 u16 minlen;
531 u8 rc, flags, rix; 560 u8 flags, rix;
532 int width, half_gi, ndelim, mindelim; 561 int width, half_gi, ndelim, mindelim;
533 562
534 /* Select standard number of delimiters based on frame length alone */ 563 /* Select standard number of delimiters based on frame length alone */
@@ -558,7 +587,6 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
558 587
559 rix = tx_info->control.rates[0].idx; 588 rix = tx_info->control.rates[0].idx;
560 flags = tx_info->control.rates[0].flags; 589 flags = tx_info->control.rates[0].flags;
561 rc = rt->info[rix].ratecode;
562 width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0; 590 width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0;
563 half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0; 591 half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0;
564 592
@@ -570,7 +598,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
570 if (nsymbols == 0) 598 if (nsymbols == 0)
571 nsymbols = 1; 599 nsymbols = 1;
572 600
573 nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width]; 601 nsymbits = bits_per_symbol[rix][width];
574 minlen = (nsymbols * nsymbits) / BITS_PER_BYTE; 602 minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
575 603
576 if (frmlen < minlen) { 604 if (frmlen < minlen) {
@@ -1425,22 +1453,14 @@ static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
1425static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, 1453static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
1426 int width, int half_gi, bool shortPreamble) 1454 int width, int half_gi, bool shortPreamble)
1427{ 1455{
1428 const struct ath_rate_table *rate_table = sc->cur_rate_table;
1429 u32 nbits, nsymbits, duration, nsymbols; 1456 u32 nbits, nsymbits, duration, nsymbols;
1430 u8 rc;
1431 int streams, pktlen; 1457 int streams, pktlen;
1432 1458
1433 pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; 1459 pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
1434 rc = rate_table->info[rix].ratecode;
1435
1436 /* for legacy rates, use old function to compute packet duration */
1437 if (!IS_HT_RATE(rc))
1438 return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen,
1439 rix, shortPreamble);
1440 1460
1441 /* find number of symbols: PLCP + data */ 1461 /* find number of symbols: PLCP + data */
1442 nbits = (pktlen << 3) + OFDM_PLCP_BITS; 1462 nbits = (pktlen << 3) + OFDM_PLCP_BITS;
1443 nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width]; 1463 nsymbits = bits_per_symbol[rix][width];
1444 nsymbols = (nbits + nsymbits - 1) / nsymbits; 1464 nsymbols = (nbits + nsymbits - 1) / nsymbits;
1445 1465
1446 if (!half_gi) 1466 if (!half_gi)
@@ -1449,7 +1469,7 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
1449 duration = SYMBOL_TIME_HALFGI(nsymbols); 1469 duration = SYMBOL_TIME_HALFGI(nsymbols);
1450 1470
1451 /* addup duration for legacy/ht training and signal fields */ 1471 /* addup duration for legacy/ht training and signal fields */
1452 streams = HT_RC_2_STREAMS(rc); 1472 streams = HT_RC_2_STREAMS(rix);
1453 duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); 1473 duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
1454 1474
1455 return duration; 1475 return duration;
@@ -1458,11 +1478,11 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
1458static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) 1478static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1459{ 1479{
1460 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1480 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1461 const struct ath_rate_table *rt = sc->cur_rate_table;
1462 struct ath9k_11n_rate_series series[4]; 1481 struct ath9k_11n_rate_series series[4];
1463 struct sk_buff *skb; 1482 struct sk_buff *skb;
1464 struct ieee80211_tx_info *tx_info; 1483 struct ieee80211_tx_info *tx_info;
1465 struct ieee80211_tx_rate *rates; 1484 struct ieee80211_tx_rate *rates;
1485 const struct ieee80211_rate *rate;
1466 struct ieee80211_hdr *hdr; 1486 struct ieee80211_hdr *hdr;
1467 int i, flags = 0; 1487 int i, flags = 0;
1468 u8 rix = 0, ctsrate = 0; 1488 u8 rix = 0, ctsrate = 0;
@@ -1481,11 +1501,10 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1481 * checking the BSS's global flag. 1501 * checking the BSS's global flag.
1482 * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. 1502 * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
1483 */ 1503 */
1504 rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info);
1505 ctsrate = rate->hw_value;
1484 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) 1506 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
1485 ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode | 1507 ctsrate |= rate->hw_value_short;
1486 rt->info[tx_info->control.rts_cts_rate_idx].short_preamble;
1487 else
1488 ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode;
1489 1508
1490 /* 1509 /*
1491 * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. 1510 * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
@@ -1508,6 +1527,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1508 flags &= ~(ATH9K_TXDESC_RTSENA); 1527 flags &= ~(ATH9K_TXDESC_RTSENA);
1509 1528
1510 for (i = 0; i < 4; i++) { 1529 for (i = 0; i < 4; i++) {
1530 bool is_40, is_sgi, is_sp;
1531 int phy;
1532
1511 if (!rates[i].count || (rates[i].idx < 0)) 1533 if (!rates[i].count || (rates[i].idx < 0))
1512 continue; 1534 continue;
1513 1535
@@ -1515,12 +1537,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1515 series[i].Tries = rates[i].count; 1537 series[i].Tries = rates[i].count;
1516 series[i].ChSel = common->tx_chainmask; 1538 series[i].ChSel = common->tx_chainmask;
1517 1539
1518 if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1519 series[i].Rate = rt->info[rix].ratecode |
1520 rt->info[rix].short_preamble;
1521 else
1522 series[i].Rate = rt->info[rix].ratecode;
1523
1524 if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) 1540 if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
1525 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; 1541 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
1526 if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 1542 if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
@@ -1528,10 +1544,36 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1528 if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) 1544 if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
1529 series[i].RateFlags |= ATH9K_RATESERIES_HALFGI; 1545 series[i].RateFlags |= ATH9K_RATESERIES_HALFGI;
1530 1546
1531 series[i].PktDuration = ath_pkt_duration(sc, rix, bf, 1547 is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI);
1532 (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0, 1548 is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH);
1533 (rates[i].flags & IEEE80211_TX_RC_SHORT_GI), 1549 is_sp = !!(rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
1534 (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)); 1550
1551 if (rates[i].flags & IEEE80211_TX_RC_MCS) {
1552 /* MCS rates */
1553 series[i].Rate = rix | 0x80;
1554 series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
1555 is_40, is_sgi, is_sp);
1556 continue;
1557 }
1558
1559 /* legcay rates */
1560 if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
1561 !(rate->flags & IEEE80211_RATE_ERP_G))
1562 phy = WLAN_RC_PHY_CCK;
1563 else
1564 phy = WLAN_RC_PHY_OFDM;
1565
1566 rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
1567 series[i].Rate = rate->hw_value;
1568 if (rate->hw_value_short) {
1569 if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1570 series[i].Rate |= rate->hw_value_short;
1571 } else {
1572 is_sp = false;
1573 }
1574
1575 series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
1576 phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp);
1535 } 1577 }
1536 1578
1537 /* set dur_update_en for l-sig computation except for PS-Poll frames */ 1579 /* set dur_update_en for l-sig computation except for PS-Poll frames */
@@ -1920,8 +1962,10 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
1920 } 1962 }
1921 } 1963 }
1922 1964
1923 for (i = tx_rateindex + 1; i < hw->max_rates; i++) 1965 for (i = tx_rateindex + 1; i < hw->max_rates; i++) {
1924 tx_info->status.rates[i].count = 0; 1966 tx_info->status.rates[i].count = 0;
1967 tx_info->status.rates[i].idx = -1;
1968 }
1925 1969
1926 tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1; 1970 tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
1927} 1971}