aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig13
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile2
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c24
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c20
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h11
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c38
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c38
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h15
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c172
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c433
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h15
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c140
17 files changed, 503 insertions, 469 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 006364f76bb4..03a1106ad725 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -23,17 +23,12 @@ config ATH9K
23 23
24 If you choose to build a module, it'll be called ath9k. 24 If you choose to build a module, it'll be called ath9k.
25 25
26if ATH_DEBUG 26config ATH9K_DEBUGFS
27
28config ATH9K_DEBUG
29 bool "Atheros ath9k debugging" 27 bool "Atheros ath9k debugging"
30 depends on ATH9K 28 depends on ATH9K
31 ---help--- 29 ---help---
32 Say Y, if you need ath9k to display debug messages. 30 Say Y, if you need access to ath9k's statistics for
33 Pass the debug mask as a module parameter: 31 interrupts, rate control, etc.
34
35 modprobe ath9k debug=0x00000200
36 32
37 Look in ath9k/debug.h for possible debug masks 33 Also required for changing debug message flags at run time.
38 34
39endif # ATH_DEBUG
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index e53f9680a385..4985b2b1b0a9 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -7,7 +7,7 @@ ath9k-y += beacon.o \
7 7
8ath9k-$(CONFIG_PCI) += pci.o 8ath9k-$(CONFIG_PCI) += pci.o
9ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o 9ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
10ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o 10ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
11 11
12obj-$(CONFIG_ATH9K) += ath9k.o 12obj-$(CONFIG_ATH9K) += ath9k.o
13 13
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 2a40fa2cd914..e2cef2ff5d8f 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
@@ -330,6 +329,7 @@ void ath_beacon_tasklet(unsigned long data);
330void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); 329void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
331int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif); 330int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif);
332void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); 331void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
332int ath_beaconq_config(struct ath_softc *sc);
333 333
334/*******/ 334/*******/
335/* ANI */ 335/* ANI */
@@ -421,8 +421,11 @@ struct ath_led {
421#define SC_OP_WAIT_FOR_TX_ACK BIT(18) 421#define SC_OP_WAIT_FOR_TX_ACK BIT(18)
422#define SC_OP_BEACON_SYNC BIT(19) 422#define SC_OP_BEACON_SYNC BIT(19)
423#define SC_OP_BT_PRIORITY_DETECTED BIT(21) 423#define SC_OP_BT_PRIORITY_DETECTED BIT(21)
424#define SC_OP_NULLFUNC_COMPLETED BIT(22)
425#define SC_OP_PS_ENABLED BIT(23)
424 426
425struct ath_wiphy; 427struct ath_wiphy;
428struct ath_rate_table;
426 429
427struct ath_softc { 430struct ath_softc {
428 struct ieee80211_hw *hw; 431 struct ieee80211_hw *hw;
@@ -467,9 +470,8 @@ struct ath_softc {
467 struct ath_rx rx; 470 struct ath_rx rx;
468 struct ath_tx tx; 471 struct ath_tx tx;
469 struct ath_beacon beacon; 472 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; 473 const struct ath_rate_table *cur_rate_table;
474 enum wireless_mode cur_rate_mode;
473 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 475 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
474 476
475 struct ath_led radio_led; 477 struct ath_led radio_led;
@@ -484,7 +486,7 @@ struct ath_softc {
484 486
485 int beacon_interval; 487 int beacon_interval;
486 488
487#ifdef CONFIG_ATH9K_DEBUG 489#ifdef CONFIG_ATH9K_DEBUGFS
488 struct ath9k_debug debug; 490 struct ath9k_debug debug;
489#endif 491#endif
490 struct ath_beacon_config cur_beacon_conf; 492 struct ath_beacon_config cur_beacon_conf;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index b10c884f2933..1660ef17aaf5 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -23,11 +23,12 @@
23 * the operating mode of the station (AP or AdHoc). Parameters are AIFS 23 * the operating mode of the station (AP or AdHoc). Parameters are AIFS
24 * settings and channel width min/max 24 * settings and channel width min/max
25*/ 25*/
26static int ath_beaconq_config(struct ath_softc *sc) 26int ath_beaconq_config(struct ath_softc *sc)
27{ 27{
28 struct ath_hw *ah = sc->sc_ah; 28 struct ath_hw *ah = sc->sc_ah;
29 struct ath_common *common = ath9k_hw_common(ah); 29 struct ath_common *common = ath9k_hw_common(ah);
30 struct ath9k_tx_queue_info qi; 30 struct ath9k_tx_queue_info qi, qi_be;
31 int qnum;
31 32
32 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi); 33 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
33 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { 34 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
@@ -37,9 +38,12 @@ static int ath_beaconq_config(struct ath_softc *sc)
37 qi.tqi_cwmax = 0; 38 qi.tqi_cwmax = 0;
38 } else { 39 } else {
39 /* Adhoc mode; important thing is to use 2x cwmin. */ 40 /* Adhoc mode; important thing is to use 2x cwmin. */
40 qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs; 41 qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA,
41 qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin; 42 ATH9K_WME_AC_BE);
42 qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax; 43 ath9k_hw_get_txq_props(ah, qnum, &qi_be);
44 qi.tqi_aifs = qi_be.tqi_aifs;
45 qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
46 qi.tqi_cwmax = qi_be.tqi_cwmax;
43 } 47 }
44 48
45 if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) { 49 if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
@@ -65,9 +69,9 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
65 struct ath_common *common = ath9k_hw_common(ah); 69 struct ath_common *common = ath9k_hw_common(ah);
66 struct ath_desc *ds; 70 struct ath_desc *ds;
67 struct ath9k_11n_rate_series series[4]; 71 struct ath9k_11n_rate_series series[4];
68 const struct ath_rate_table *rt;
69 int flags, antenna, ctsrate = 0, ctsduration = 0; 72 int flags, antenna, ctsrate = 0, ctsduration = 0;
70 u8 rate; 73 struct ieee80211_supported_band *sband;
74 u8 rate = 0;
71 75
72 ds = bf->bf_desc; 76 ds = bf->bf_desc;
73 flags = ATH9K_TXDESC_NOACK; 77 flags = ATH9K_TXDESC_NOACK;
@@ -91,10 +95,10 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
91 95
92 ds->ds_data = bf->bf_buf_addr; 96 ds->ds_data = bf->bf_buf_addr;
93 97
94 rt = sc->cur_rate_table; 98 sband = &sc->sbands[common->hw->conf.channel->band];
95 rate = rt->info[0].ratecode; 99 rate = sband->bitrates[0].hw_value;
96 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) 100 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
97 rate |= rt->info[0].short_preamble; 101 rate |= sband->bitrates[0].hw_value_short;
98 102
99 ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN, 103 ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
100 ATH9K_PKT_TYPE_BEACON, 104 ATH9K_PKT_TYPE_BEACON,
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 4a13632e3e4d..4d775ae141db 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -181,8 +181,6 @@ static void ath9k_process_rssi(struct ath_common *common,
181 ATH_RSSI_EP_MULTIPLIER); 181 ATH_RSSI_EP_MULTIPLIER);
182 if (rx_stats->rs_rssi < 0) 182 if (rx_stats->rs_rssi < 0)
183 rx_stats->rs_rssi = 0; 183 rx_stats->rs_rssi = 0;
184 else if (rx_stats->rs_rssi > 127)
185 rx_stats->rs_rssi = 127;
186 184
187 /* Update Beacon RSSI, this is used by ANI. */ 185 /* Update Beacon RSSI, this is used by ANI. */
188 if (ieee80211_is_beacon(fc)) 186 if (ieee80211_is_beacon(fc))
@@ -238,16 +236,8 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
238 /* see if any padding is done by the hw and remove it */ 236 /* see if any padding is done by the hw and remove it */
239 hdr = (struct ieee80211_hdr *) skb->data; 237 hdr = (struct ieee80211_hdr *) skb->data;
240 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 238 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
241 padpos = 24;
242 fc = hdr->frame_control; 239 fc = hdr->frame_control;
243 if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) == 240 padpos = ath9k_cmn_padpos(hdr->frame_control);
244 cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) {
245 padpos += 6; /* ETH_ALEN */
246 }
247 if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) ==
248 cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) {
249 padpos += 2;
250 }
251 241
252 /* The MAC header is padded to have 32-bit boundary if the 242 /* The MAC header is padded to have 32-bit boundary if the
253 * packet payload is non-zero. The general calculation for 243 * packet payload is non-zero. The general calculation for
@@ -282,6 +272,20 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
282} 272}
283EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess); 273EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess);
284 274
275int ath9k_cmn_padpos(__le16 frame_control)
276{
277 int padpos = 24;
278 if (ieee80211_has_a4(frame_control)) {
279 padpos += ETH_ALEN;
280 }
281 if (ieee80211_is_data_qos(frame_control)) {
282 padpos += IEEE80211_QOS_CTL_LEN;
283 }
284
285 return padpos;
286}
287EXPORT_SYMBOL(ath9k_cmn_padpos);
288
285static int __init ath9k_cmn_init(void) 289static int __init ath9k_cmn_init(void)
286{ 290{
287 return 0; 291 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 4e1176029356..042999c2fe9c 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -78,6 +78,7 @@ struct ath_buf {
78 dma_addr_t bf_daddr; /* physical addr of desc */ 78 dma_addr_t bf_daddr; /* physical addr of desc */
79 dma_addr_t bf_buf_addr; /* physical addr of data buffer */ 79 dma_addr_t bf_buf_addr; /* physical addr of data buffer */
80 bool bf_stale; 80 bool bf_stale;
81 bool bf_isnullfunc;
81 u16 bf_flags; 82 u16 bf_flags;
82 struct ath_buf_state bf_state; 83 struct ath_buf_state bf_state;
83 dma_addr_t bf_dmacontext; 84 dma_addr_t bf_dmacontext;
@@ -122,3 +123,5 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
122 struct ath_rx_status *rx_stats, 123 struct ath_rx_status *rx_stats,
123 struct ieee80211_rx_status *rxs, 124 struct ieee80211_rx_status *rxs,
124 bool decrypt_error); 125 bool decrypt_error);
126
127int ath9k_cmn_padpos(__le16 frame_control);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 06f1fcfb03e9..b66f72dbf7b9 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -31,6 +31,8 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file)
31 return 0; 31 return 0;
32} 32}
33 33
34#ifdef CONFIG_ATH_DEBUG
35
34static ssize_t read_file_debug(struct file *file, char __user *user_buf, 36static ssize_t read_file_debug(struct file *file, char __user *user_buf,
35 size_t count, loff_t *ppos) 37 size_t count, loff_t *ppos)
36{ 38{
@@ -71,6 +73,8 @@ static const struct file_operations fops_debug = {
71 .owner = THIS_MODULE 73 .owner = THIS_MODULE
72}; 74};
73 75
76#endif
77
74static ssize_t read_file_dma(struct file *file, char __user *user_buf, 78static ssize_t read_file_dma(struct file *file, char __user *user_buf,
75 size_t count, loff_t *ppos) 79 size_t count, loff_t *ppos)
76{ 80{
@@ -255,21 +259,11 @@ static const struct file_operations fops_interrupt = {
255 .owner = THIS_MODULE 259 .owner = THIS_MODULE
256}; 260};
257 261
258void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) 262void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
259{ 263{
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; 264 struct ath_rc_stats *stats;
264 265
265 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 266 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++; 267 stats->success++;
274} 268}
275 269
@@ -573,10 +567,12 @@ int ath9k_init_debug(struct ath_hw *ah)
573 if (!sc->debug.debugfs_phy) 567 if (!sc->debug.debugfs_phy)
574 goto err; 568 goto err;
575 569
570#ifdef CONFIG_ATH_DEBUG
576 sc->debug.debugfs_debug = debugfs_create_file("debug", 571 sc->debug.debugfs_debug = debugfs_create_file("debug",
577 S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug); 572 S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug);
578 if (!sc->debug.debugfs_debug) 573 if (!sc->debug.debugfs_debug)
579 goto err; 574 goto err;
575#endif
580 576
581 sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR, 577 sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR,
582 sc->debug.debugfs_phy, sc, &fops_dma); 578 sc->debug.debugfs_phy, sc, &fops_dma);
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 749e85d57551..536663e3ee11 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -18,17 +18,18 @@
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;
24 25
25#ifdef CONFIG_ATH9K_DEBUG 26#ifdef CONFIG_ATH9K_DEBUGFS
26#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++ 27#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
27#else 28#else
28#define TX_STAT_INC(q, c) do { } while (0) 29#define TX_STAT_INC(q, c) do { } while (0)
29#endif 30#endif
30 31
31#ifdef CONFIG_ATH9K_DEBUG 32#ifdef CONFIG_ATH9K_DEBUGFS
32 33
33/** 34/**
34 * struct ath_interrupt_stats - Contains statistics about interrupts 35 * struct ath_interrupt_stats - Contains statistics about interrupts
@@ -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
@@ -185,6 +186,6 @@ static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
185{ 186{
186} 187}
187 188
188#endif /* CONFIG_ATH9K_DEBUG */ 189#endif /* CONFIG_ATH9K_DEBUGFS */
189 190
190#endif /* DEBUG_H */ 191#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 53a7b980d8f6..2ec61f08cfdb 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 }
@@ -922,6 +918,11 @@ int ath9k_hw_init(struct ath_hw *ah)
922 ath_print(common, ATH_DBG_RESET, "serialize_regmode is %d\n", 918 ath_print(common, ATH_DBG_RESET, "serialize_regmode is %d\n",
923 ah->config.serialize_regmode); 919 ah->config.serialize_regmode);
924 920
921 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
922 ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1;
923 else
924 ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
925
925 if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) { 926 if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) {
926 ath_print(common, ATH_DBG_FATAL, 927 ath_print(common, ATH_DBG_FATAL,
927 "Mac Chip Rev 0x%02x.%x is not supported by " 928 "Mac Chip Rev 0x%02x.%x is not supported by "
@@ -975,7 +976,10 @@ int ath9k_hw_init(struct ath_hw *ah)
975 return r; 976 return r;
976 977
977 ath9k_hw_init_mode_gain_regs(ah); 978 ath9k_hw_init_mode_gain_regs(ah);
978 ath9k_hw_fill_cap_info(ah); 979 r = ath9k_hw_fill_cap_info(ah);
980 if (r)
981 return r;
982
979 ath9k_hw_init_11a_eeprom_fix(ah); 983 ath9k_hw_init_11a_eeprom_fix(ah);
980 984
981 r = ath9k_hw_init_macaddr(ah); 985 r = ath9k_hw_init_macaddr(ah);
@@ -3111,7 +3115,7 @@ EXPORT_SYMBOL(ath9k_hw_set_sta_beacon_timers);
3111/* HW Capabilities */ 3115/* HW Capabilities */
3112/*******************/ 3116/*******************/
3113 3117
3114void ath9k_hw_fill_cap_info(struct ath_hw *ah) 3118int ath9k_hw_fill_cap_info(struct ath_hw *ah)
3115{ 3119{
3116 struct ath9k_hw_capabilities *pCap = &ah->caps; 3120 struct ath9k_hw_capabilities *pCap = &ah->caps;
3117 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 3121 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -3142,6 +3146,12 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
3142 } 3146 }
3143 3147
3144 eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); 3148 eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
3149 if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) {
3150 ath_print(common, ATH_DBG_FATAL,
3151 "no band has been marked as supported in EEPROM.\n");
3152 return -EINVAL;
3153 }
3154
3145 bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX); 3155 bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
3146 3156
3147 if (eeval & AR5416_OPFLAGS_11A) { 3157 if (eeval & AR5416_OPFLAGS_11A) {
@@ -3228,7 +3238,11 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
3228 pCap->keycache_size = AR_KEYTABLE_SIZE; 3238 pCap->keycache_size = AR_KEYTABLE_SIZE;
3229 3239
3230 pCap->hw_caps |= ATH9K_HW_CAP_FASTCC; 3240 pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
3231 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; 3241
3242 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
3243 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1;
3244 else
3245 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
3232 3246
3233 if (AR_SREV_9285_10_OR_LATER(ah)) 3247 if (AR_SREV_9285_10_OR_LATER(ah))
3234 pCap->num_gpio_pins = AR9285_NUM_GPIO; 3248 pCap->num_gpio_pins = AR9285_NUM_GPIO;
@@ -3301,6 +3315,8 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
3301 } else { 3315 } else {
3302 btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; 3316 btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
3303 } 3317 }
3318
3319 return 0;
3304} 3320}
3305 3321
3306bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, 3322bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index f8f5e997162c..e2b0c73a616f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -60,7 +60,7 @@
60 60
61#define ATH_DEFAULT_NOISE_FLOOR -95 61#define ATH_DEFAULT_NOISE_FLOOR -95
62 62
63#define ATH9K_RSSI_BAD 0x80 63#define ATH9K_RSSI_BAD -128
64 64
65/* Register read/write primitives */ 65/* Register read/write primitives */
66#define REG_WRITE(_ah, _reg, _val) \ 66#define REG_WRITE(_ah, _reg, _val) \
@@ -226,6 +226,7 @@ struct ath9k_ops_config {
226#define AR_SPUR_FEEQ_BOUND_HT20 10 226#define AR_SPUR_FEEQ_BOUND_HT20 10
227 int spurmode; 227 int spurmode;
228 u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; 228 u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
229 u8 max_txtrig_level;
229}; 230};
230 231
231enum ath9k_int { 232enum ath9k_int {
@@ -619,7 +620,7 @@ void ath9k_hw_detach(struct ath_hw *ah);
619int ath9k_hw_init(struct ath_hw *ah); 620int ath9k_hw_init(struct ath_hw *ah);
620int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, 621int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
621 bool bChannelChange); 622 bool bChannelChange);
622void ath9k_hw_fill_cap_info(struct ath_hw *ah); 623int ath9k_hw_fill_cap_info(struct ath_hw *ah);
623bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, 624bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
624 u32 capability, u32 *result); 625 u32 capability, u32 *result);
625bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, 626bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
@@ -647,7 +648,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); 648u32 ath9k_hw_reverse_bits(u32 val, u32 n);
648bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high); 649bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
649u16 ath9k_hw_computetxtime(struct ath_hw *ah, 650u16 ath9k_hw_computetxtime(struct ath_hw *ah,
650 const struct ath_rate_table *rates, 651 u8 phy, int kbps,
651 u32 frameLen, u16 rateix, bool shortPreamble); 652 u32 frameLen, u16 rateix, bool shortPreamble);
652void ath9k_hw_get_channel_centers(struct ath_hw *ah, 653void ath9k_hw_get_channel_centers(struct ath_hw *ah,
653 struct ath9k_channel *chan, 654 struct ath9k_channel *chan,
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 46466ffebcb0..71b84d91dcff 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -70,12 +70,37 @@ u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
70} 70}
71EXPORT_SYMBOL(ath9k_hw_numtxpending); 71EXPORT_SYMBOL(ath9k_hw_numtxpending);
72 72
73/**
74 * ath9k_hw_updatetxtriglevel - adjusts the frame trigger level
75 *
76 * @ah: atheros hardware struct
77 * @bIncTrigLevel: whether or not the frame trigger level should be updated
78 *
79 * The frame trigger level specifies the minimum number of bytes,
80 * in units of 64 bytes, that must be DMA'ed into the PCU TX FIFO
81 * before the PCU will initiate sending the frame on the air. This can
82 * mean we initiate transmit before a full frame is on the PCU TX FIFO.
83 * Resets to 0x1 (meaning 64 bytes or a full frame, whichever occurs
84 * first)
85 *
86 * Caution must be taken to ensure to set the frame trigger level based
87 * on the DMA request size. For example if the DMA request size is set to
88 * 128 bytes the trigger level cannot exceed 6 * 64 = 384. This is because
89 * there need to be enough space in the tx FIFO for the requested transfer
90 * size. Hence the tx FIFO will stop with 512 - 128 = 384 bytes. If we set
91 * the threshold to a value beyond 6, then the transmit will hang.
92 *
93 * Current dual stream devices have a PCU TX FIFO size of 8 KB.
94 * Current single stream devices have a PCU TX FIFO size of 4 KB, however,
95 * there is a hardware issue which forces us to use 2 KB instead so the
96 * frame trigger level must not exceed 2 KB for these chipsets.
97 */
73bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel) 98bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
74{ 99{
75 u32 txcfg, curLevel, newLevel; 100 u32 txcfg, curLevel, newLevel;
76 enum ath9k_int omask; 101 enum ath9k_int omask;
77 102
78 if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD) 103 if (ah->tx_trig_level >= ah->config.max_txtrig_level)
79 return false; 104 return false;
80 105
81 omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL); 106 omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
@@ -84,7 +109,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
84 curLevel = MS(txcfg, AR_FTRIG); 109 curLevel = MS(txcfg, AR_FTRIG);
85 newLevel = curLevel; 110 newLevel = curLevel;
86 if (bIncTrigLevel) { 111 if (bIncTrigLevel) {
87 if (curLevel < MAX_TX_FIFO_THRESHOLD) 112 if (curLevel < ah->config.max_txtrig_level)
88 newLevel++; 113 newLevel++;
89 } else if (curLevel > MIN_TX_FIFO_THRESHOLD) 114 } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
90 newLevel--; 115 newLevel--;
@@ -231,6 +256,8 @@ int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
231 ds->ds_txstat.ts_status = 0; 256 ds->ds_txstat.ts_status = 0;
232 ds->ds_txstat.ts_flags = 0; 257 ds->ds_txstat.ts_flags = 0;
233 258
259 if (ads->ds_txstatus1 & AR_FrmXmitOK)
260 ds->ds_txstat.ts_status |= ATH9K_TX_ACKED;
234 if (ads->ds_txstatus1 & AR_ExcessiveRetries) 261 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
235 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY; 262 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
236 if (ads->ds_txstatus1 & AR_Filtered) 263 if (ads->ds_txstatus1 & AR_Filtered)
@@ -926,6 +953,13 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
926} 953}
927EXPORT_SYMBOL(ath9k_hw_setuprxdesc); 954EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
928 955
956/*
957 * This can stop or re-enables RX.
958 *
959 * If bool is set this will kill any frame which is currently being
960 * transferred between the MAC and baseband and also prevent any new
961 * frames from getting started.
962 */
929bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set) 963bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
930{ 964{
931 u32 reg; 965 u32 reg;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index fefb65dafb1c..0c87771383f0 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -76,6 +76,7 @@
76#define ATH9K_TXERR_FIFO 0x04 76#define ATH9K_TXERR_FIFO 0x04
77#define ATH9K_TXERR_XTXOP 0x08 77#define ATH9K_TXERR_XTXOP 0x08
78#define ATH9K_TXERR_TIMER_EXPIRED 0x10 78#define ATH9K_TXERR_TIMER_EXPIRED 0x10
79#define ATH9K_TX_ACKED 0x20
79 80
80#define ATH9K_TX_BA 0x01 81#define ATH9K_TX_BA 0x01
81#define ATH9K_TX_PWRMGMT 0x02 82#define ATH9K_TX_PWRMGMT 0x02
@@ -85,9 +86,15 @@
85#define ATH9K_TX_SW_ABORTED 0x40 86#define ATH9K_TX_SW_ABORTED 0x40
86#define ATH9K_TX_SW_FILTERED 0x80 87#define ATH9K_TX_SW_FILTERED 0x80
87 88
89/* 64 bytes */
88#define MIN_TX_FIFO_THRESHOLD 0x1 90#define MIN_TX_FIFO_THRESHOLD 0x1
91
92/*
93 * Single stream device AR9285 and AR9271 require 2 KB
94 * to work around a hardware issue, all other devices
95 * have can use the max 4 KB limit.
96 */
89#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1) 97#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1)
90#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD
91 98
92struct ath_tx_status { 99struct ath_tx_status {
93 u32 ts_tstamp; 100 u32 ts_tstamp;
@@ -380,6 +387,11 @@ struct ar5416_desc {
380#define AR_TxBaStatus 0x40000000 387#define AR_TxBaStatus 0x40000000
381#define AR_TxStatusRsvd01 0x80000000 388#define AR_TxStatusRsvd01 0x80000000
382 389
390/*
391 * AR_FrmXmitOK - Frame transmission success flag. If set, the frame was
392 * transmitted successfully. If clear, no ACK or BA was received to indicate
393 * successful transmission when we were expecting an ACK or BA.
394 */
383#define AR_FrmXmitOK 0x00000001 395#define AR_FrmXmitOK 0x00000001
384#define AR_ExcessiveRetries 0x00000002 396#define AR_ExcessiveRetries 0x00000002
385#define AR_FIFOUnderrun 0x00000004 397#define AR_FIFOUnderrun 0x00000004
@@ -616,7 +628,6 @@ enum ath9k_cipher {
616 628
617struct ath_hw; 629struct ath_hw;
618struct ath9k_channel; 630struct ath9k_channel;
619struct ath_rate_table;
620 631
621u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q); 632u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
622void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp); 633void 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..c48743452515 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
@@ -1826,20 +1793,25 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
1826 1793
1827 /* setup channels and rates */ 1794 /* setup channels and rates */
1828 1795
1829 sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; 1796 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
1830 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = 1797 sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
1831 sc->rates[IEEE80211_BAND_2GHZ]; 1798 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
1832 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; 1799 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
1833 sc->sbands[IEEE80211_BAND_2GHZ].n_channels = 1800 ARRAY_SIZE(ath9k_2ghz_chantable);
1834 ARRAY_SIZE(ath9k_2ghz_chantable); 1801 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
1802 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
1803 ARRAY_SIZE(ath9k_legacy_rates);
1804 }
1835 1805
1836 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { 1806 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
1837 sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; 1807 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; 1808 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
1841 sc->sbands[IEEE80211_BAND_5GHZ].n_channels = 1809 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
1842 ARRAY_SIZE(ath9k_5ghz_chantable); 1810 ARRAY_SIZE(ath9k_5ghz_chantable);
1811 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
1812 ath9k_legacy_rates + 4;
1813 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
1814 ARRAY_SIZE(ath9k_legacy_rates) - 4;
1843 } 1815 }
1844 1816
1845 switch (ah->btcoex_hw.scheme) { 1817 switch (ah->btcoex_hw.scheme) {
@@ -1906,8 +1878,9 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
1906 1878
1907 hw->rate_control_algorithm = "ath9k_rate_control"; 1879 hw->rate_control_algorithm = "ath9k_rate_control";
1908 1880
1909 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 1881 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
1910 &sc->sbands[IEEE80211_BAND_2GHZ]; 1882 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
1883 &sc->sbands[IEEE80211_BAND_2GHZ];
1911 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) 1884 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
1912 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 1885 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
1913 &sc->sbands[IEEE80211_BAND_5GHZ]; 1886 &sc->sbands[IEEE80211_BAND_5GHZ];
@@ -1946,9 +1919,12 @@ int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
1946 reg = &common->regulatory; 1919 reg = &common->regulatory;
1947 1920
1948 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) { 1921 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
1949 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); 1922 if (test_bit(ATH9K_MODE_11G, ah->caps.wireless_modes))
1923 setup_ht_cap(sc,
1924 &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
1950 if (test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) 1925 if (test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes))
1951 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); 1926 setup_ht_cap(sc,
1927 &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
1952 } 1928 }
1953 1929
1954 /* initialize tx/rx engine */ 1930 /* initialize tx/rx engine */
@@ -2394,7 +2370,8 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2394 struct ath_softc *sc = aphy->sc; 2370 struct ath_softc *sc = aphy->sc;
2395 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 2371 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2396 struct ath_tx_control txctl; 2372 struct ath_tx_control txctl;
2397 int hdrlen, padsize; 2373 int padpos, padsize;
2374 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2398 2375
2399 if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { 2376 if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
2400 ath_print(common, ATH_DBG_XMIT, 2377 ath_print(common, ATH_DBG_XMIT,
@@ -2404,7 +2381,6 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2404 } 2381 }
2405 2382
2406 if (sc->ps_enabled) { 2383 if (sc->ps_enabled) {
2407 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2408 /* 2384 /*
2409 * mac80211 does not set PM field for normal data frames, so we 2385 * mac80211 does not set PM field for normal data frames, so we
2410 * need to update that based on the current PS mode. 2386 * need to update that based on the current PS mode.
@@ -2424,7 +2400,6 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2424 * power save mode. Need to wake up hardware for the TX to be 2400 * power save mode. Need to wake up hardware for the TX to be
2425 * completed and if needed, also for RX of buffered frames. 2401 * completed and if needed, also for RX of buffered frames.
2426 */ 2402 */
2427 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2428 ath9k_ps_wakeup(sc); 2403 ath9k_ps_wakeup(sc);
2429 ath9k_hw_setrxabort(sc->sc_ah, 0); 2404 ath9k_hw_setrxabort(sc->sc_ah, 0);
2430 if (ieee80211_is_pspoll(hdr->frame_control)) { 2405 if (ieee80211_is_pspoll(hdr->frame_control)) {
@@ -2452,7 +2427,6 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2452 * BSSes. 2427 * BSSes.
2453 */ 2428 */
2454 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 2429 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
2455 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2456 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) 2430 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
2457 sc->tx.seq_no += 0x10; 2431 sc->tx.seq_no += 0x10;
2458 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 2432 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
@@ -2460,13 +2434,13 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2460 } 2434 }
2461 2435
2462 /* Add the padding after the header if this is not already done */ 2436 /* Add the padding after the header if this is not already done */
2463 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 2437 padpos = ath9k_cmn_padpos(hdr->frame_control);
2464 if (hdrlen & 3) { 2438 padsize = padpos & 3;
2465 padsize = hdrlen % 4; 2439 if (padsize && skb->len>padpos) {
2466 if (skb_headroom(skb) < padsize) 2440 if (skb_headroom(skb) < padsize)
2467 return -1; 2441 return -1;
2468 skb_push(skb, padsize); 2442 skb_push(skb, padsize);
2469 memmove(skb->data, skb->data + padsize, hdrlen); 2443 memmove(skb->data, skb->data + padsize, padpos);
2470 } 2444 }
2471 2445
2472 /* Check if a tx queue is available */ 2446 /* Check if a tx queue is available */
@@ -2731,8 +2705,15 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2731 } 2705 }
2732 } 2706 }
2733 2707
2708 /*
2709 * We just prepare to enable PS. We have to wait until our AP has
2710 * ACK'd our null data frame to disable RX otherwise we'll ignore
2711 * those ACKs and end up retransmitting the same null data frames.
2712 * IEEE80211_CONF_CHANGE_PS is only passed by mac80211 for STA mode.
2713 */
2734 if (changed & IEEE80211_CONF_CHANGE_PS) { 2714 if (changed & IEEE80211_CONF_CHANGE_PS) {
2735 if (conf->flags & IEEE80211_CONF_PS) { 2715 if (conf->flags & IEEE80211_CONF_PS) {
2716 sc->sc_flags |= SC_OP_PS_ENABLED;
2736 if (!(ah->caps.hw_caps & 2717 if (!(ah->caps.hw_caps &
2737 ATH9K_HW_CAP_AUTOSLEEP)) { 2718 ATH9K_HW_CAP_AUTOSLEEP)) {
2738 if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { 2719 if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
@@ -2740,11 +2721,20 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2740 ath9k_hw_set_interrupts(sc->sc_ah, 2721 ath9k_hw_set_interrupts(sc->sc_ah,
2741 sc->imask); 2722 sc->imask);
2742 } 2723 }
2743 ath9k_hw_setrxabort(sc->sc_ah, 1);
2744 } 2724 }
2745 sc->ps_enabled = true; 2725 /*
2726 * At this point we know hardware has received an ACK
2727 * of a previously sent null data frame.
2728 */
2729 if ((sc->sc_flags & SC_OP_NULLFUNC_COMPLETED)) {
2730 sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED;
2731 sc->ps_enabled = true;
2732 ath9k_hw_setrxabort(sc->sc_ah, 1);
2733 }
2746 } else { 2734 } else {
2747 sc->ps_enabled = false; 2735 sc->ps_enabled = false;
2736 sc->sc_flags &= ~(SC_OP_PS_ENABLED |
2737 SC_OP_NULLFUNC_COMPLETED);
2748 ath9k_setpower(sc, ATH9K_PM_AWAKE); 2738 ath9k_setpower(sc, ATH9K_PM_AWAKE);
2749 if (!(ah->caps.hw_caps & 2739 if (!(ah->caps.hw_caps &
2750 ATH9K_HW_CAP_AUTOSLEEP)) { 2740 ATH9K_HW_CAP_AUTOSLEEP)) {
@@ -2898,6 +2888,10 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
2898 if (ret) 2888 if (ret)
2899 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); 2889 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
2900 2890
2891 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
2892 if ((qnum == sc->tx.hwq_map[ATH9K_WME_AC_BE]) && !ret)
2893 ath_beaconq_config(sc);
2894
2901 mutex_unlock(&sc->mutex); 2895 mutex_unlock(&sc->mutex);
2902 2896
2903 return ret; 2897 return ret;
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 1d96777b4cd2..c915954d4d5b 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -19,133 +19,92 @@
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, 12, 0, 0, 0, 0, 0 },
25 0, 0, 0, 0, 0, 0 },
26 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 26 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
27 7800, 0x0f, 0x00, 18, 27 7800, 1, 18, 0, 1, 1, 1, 1 },
28 0, 1, 1, 1, 1, 0 },
29 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 28 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
30 10000, 0x0a, 0x00, 24, 29 10000, 2, 24, 2, 2, 2, 2, 2 },
31 2, 2, 2, 2, 2, 0 },
32 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 30 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
33 13900, 0x0e, 0x00, 36, 31 13900, 3, 36, 2, 3, 3, 3, 3 },
34 2, 3, 3, 3, 3, 0 },
35 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 32 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
36 17300, 0x09, 0x00, 48, 33 17300, 4, 48, 4, 4, 4, 4, 4 },
37 4, 4, 4, 4, 4, 0 },
38 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 34 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
39 23000, 0x0d, 0x00, 72, 35 23000, 5, 72, 4, 5, 5, 5, 5 },
40 4, 5, 5, 5, 5, 0 },
41 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 36 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
42 27400, 0x08, 0x00, 96, 37 27400, 6, 96, 4, 6, 6, 6, 6 },
43 4, 6, 6, 6, 6, 0 },
44 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 38 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
45 29300, 0x0c, 0x00, 108, 39 29300, 7, 108, 4, 7, 7, 7, 7 },
46 4, 7, 7, 7, 7, 0 },
47 { VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 40 { VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
48 6400, 0x80, 0x00, 0, 41 6400, 0, 0, 0, 8, 24, 8, 24 },
49 0, 8, 24, 8, 24, 3216 },
50 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 42 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
51 12700, 0x81, 0x00, 1, 43 12700, 1, 1, 2, 9, 25, 9, 25 },
52 2, 9, 25, 9, 25, 6434 },
53 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 44 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
54 18800, 0x82, 0x00, 2, 45 18800, 2, 2, 2, 10, 26, 10, 26 },
55 2, 10, 26, 10, 26, 9650 },
56 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 46 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
57 25000, 0x83, 0x00, 3, 47 25000, 3, 3, 4, 11, 27, 11, 27 },
58 4, 11, 27, 11, 27, 12868 },
59 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 48 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
60 36700, 0x84, 0x00, 4, 49 36700, 4, 4, 4, 12, 28, 12, 28 },
61 4, 12, 28, 12, 28, 19304 },
62 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 50 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
63 48100, 0x85, 0x00, 5, 51 48100, 5, 5, 4, 13, 29, 13, 29 },
64 4, 13, 29, 13, 29, 25740 },
65 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 52 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
66 53500, 0x86, 0x00, 6, 53 53500, 6, 6, 4, 14, 30, 14, 30 },
67 4, 14, 30, 14, 30, 28956 },
68 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 54 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
69 59000, 0x87, 0x00, 7, 55 59000, 7, 7, 4, 15, 31, 15, 32 },
70 4, 15, 31, 15, 32, 32180 },
71 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 56 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
72 12700, 0x88, 0x00, 57 12700, 8, 8, 3, 16, 33, 16, 33 },
73 8, 3, 16, 33, 16, 33, 6430 },
74 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 58 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
75 24800, 0x89, 0x00, 9, 59 24800, 9, 9, 2, 17, 34, 17, 34 },
76 2, 17, 34, 17, 34, 12860 },
77 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 60 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
78 36600, 0x8a, 0x00, 10, 61 36600, 10, 10, 2, 18, 35, 18, 35 },
79 2, 18, 35, 18, 35, 19300 },
80 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 62 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
81 48100, 0x8b, 0x00, 11, 63 48100, 11, 11, 4, 19, 36, 19, 36 },
82 4, 19, 36, 19, 36, 25736 },
83 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 64 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
84 69500, 0x8c, 0x00, 12, 65 69500, 12, 12, 4, 20, 37, 20, 37 },
85 4, 20, 37, 20, 37, 38600 },
86 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 66 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
87 89500, 0x8d, 0x00, 13, 67 89500, 13, 13, 4, 21, 38, 21, 38 },
88 4, 21, 38, 21, 38, 51472 },
89 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 68 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
90 98900, 0x8e, 0x00, 14, 69 98900, 14, 14, 4, 22, 39, 22, 39 },
91 4, 22, 39, 22, 39, 57890 },
92 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 70 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
93 108300, 0x8f, 0x00, 15, 71 108300, 15, 15, 4, 23, 40, 23, 41 },
94 4, 23, 40, 23, 41, 64320 },
95 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 72 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
96 13200, 0x80, 0x00, 0, 73 13200, 0, 0, 0, 8, 24, 24, 24 },
97 0, 8, 24, 24, 24, 6684 },
98 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 74 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
99 25900, 0x81, 0x00, 1, 75 25900, 1, 1, 2, 9, 25, 25, 25 },
100 2, 9, 25, 25, 25, 13368 },
101 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 76 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
102 38600, 0x82, 0x00, 2, 77 38600, 2, 2, 2, 10, 26, 26, 26 },
103 2, 10, 26, 26, 26, 20052 },
104 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 78 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
105 49800, 0x83, 0x00, 3, 79 49800, 3, 3, 4, 11, 27, 27, 27 },
106 4, 11, 27, 27, 27, 26738 },
107 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 80 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
108 72200, 0x84, 0x00, 4, 81 72200, 4, 4, 4, 12, 28, 28, 28 },
109 4, 12, 28, 28, 28, 40104 },
110 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 82 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
111 92900, 0x85, 0x00, 5, 83 92900, 5, 5, 4, 13, 29, 29, 29 },
112 4, 13, 29, 29, 29, 53476 },
113 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ 84 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
114 102700, 0x86, 0x00, 6, 85 102700, 6, 6, 4, 14, 30, 30, 30 },
115 4, 14, 30, 30, 30, 60156 },
116 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 86 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
117 112000, 0x87, 0x00, 7, 87 112000, 7, 7, 4, 15, 31, 32, 32 },
118 4, 15, 31, 32, 32, 66840 },
119 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ 88 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
120 122000, 0x87, 0x00, 7, 89 122000, 7, 7, 4, 15, 31, 32, 32 },
121 4, 15, 31, 32, 32, 74200 },
122 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 90 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
123 25800, 0x88, 0x00, 8, 91 25800, 8, 8, 0, 16, 33, 33, 33 },
124 0, 16, 33, 33, 33, 13360 },
125 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 92 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
126 49800, 0x89, 0x00, 9, 93 49800, 9, 9, 2, 17, 34, 34, 34 },
127 2, 17, 34, 34, 34, 26720 },
128 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 94 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
129 71900, 0x8a, 0x00, 10, 95 71900, 10, 10, 2, 18, 35, 35, 35 },
130 2, 18, 35, 35, 35, 40080 },
131 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 96 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
132 92500, 0x8b, 0x00, 11, 97 92500, 11, 11, 4, 19, 36, 36, 36 },
133 4, 19, 36, 36, 36, 53440 },
134 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 98 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
135 130300, 0x8c, 0x00, 12, 99 130300, 12, 12, 4, 20, 37, 37, 37 },
136 4, 20, 37, 37, 37, 80160 },
137 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 100 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
138 162800, 0x8d, 0x00, 13, 101 162800, 13, 13, 4, 21, 38, 38, 38 },
139 4, 21, 38, 38, 38, 106880 },
140 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 102 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
141 178200, 0x8e, 0x00, 14, 103 178200, 14, 14, 4, 22, 39, 39, 39 },
142 4, 22, 39, 39, 39, 120240 },
143 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 104 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
144 192100, 0x8f, 0x00, 15, 105 192100, 15, 15, 4, 23, 40, 41, 41 },
145 4, 23, 40, 41, 41, 133600 },
146 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ 106 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
147 207000, 0x8f, 0x00, 15, 107 207000, 15, 15, 4, 23, 40, 41, 41 },
148 4, 23, 40, 41, 41, 148400 },
149 }, 108 },
150 50, /* probe interval */ 109 50, /* probe interval */
151 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 110 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
@@ -156,177 +115,125 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
156 115
157static const struct ath_rate_table ar5416_11ng_ratetable = { 116static const struct ath_rate_table ar5416_11ng_ratetable = {
158 46, 117 46,
118 12, /* MCS start */
159 { 119 {
160 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 120 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
161 900, 0x1b, 0x00, 2, 121 900, 0, 2, 0, 0, 0, 0, 0 },
162 0, 0, 0, 0, 0, 0 },
163 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 122 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
164 1900, 0x1a, 0x04, 4, 123 1900, 1, 4, 1, 1, 1, 1, 1 },
165 1, 1, 1, 1, 1, 0 },
166 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 124 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
167 4900, 0x19, 0x04, 11, 125 4900, 2, 11, 2, 2, 2, 2, 2 },
168 2, 2, 2, 2, 2, 0 },
169 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 126 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
170 8100, 0x18, 0x04, 22, 127 8100, 3, 22, 3, 3, 3, 3, 3 },
171 3, 3, 3, 3, 3, 0 },
172 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 128 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
173 5400, 0x0b, 0x00, 12, 129 5400, 4, 12, 4, 4, 4, 4, 4 },
174 4, 4, 4, 4, 4, 0 },
175 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 130 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
176 7800, 0x0f, 0x00, 18, 131 7800, 5, 18, 4, 5, 5, 5, 5 },
177 4, 5, 5, 5, 5, 0 },
178 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 132 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
179 10100, 0x0a, 0x00, 24, 133 10100, 6, 24, 6, 6, 6, 6, 6 },
180 6, 6, 6, 6, 6, 0 },
181 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 134 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
182 14100, 0x0e, 0x00, 36, 135 14100, 7, 36, 6, 7, 7, 7, 7 },
183 6, 7, 7, 7, 7, 0 },
184 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 136 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
185 17700, 0x09, 0x00, 48, 137 17700, 8, 48, 8, 8, 8, 8, 8 },
186 8, 8, 8, 8, 8, 0 },
187 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 138 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
188 23700, 0x0d, 0x00, 72, 139 23700, 9, 72, 8, 9, 9, 9, 9 },
189 8, 9, 9, 9, 9, 0 },
190 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 140 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
191 27400, 0x08, 0x00, 96, 141 27400, 10, 96, 8, 10, 10, 10, 10 },
192 8, 10, 10, 10, 10, 0 },
193 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 142 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
194 30900, 0x0c, 0x00, 108, 143 30900, 11, 108, 8, 11, 11, 11, 11 },
195 8, 11, 11, 11, 11, 0 },
196 { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 144 { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
197 6400, 0x80, 0x00, 0, 145 6400, 0, 0, 4, 12, 28, 12, 28 },
198 4, 12, 28, 12, 28, 3216 },
199 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 146 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
200 12700, 0x81, 0x00, 1, 147 12700, 1, 1, 6, 13, 29, 13, 29 },
201 6, 13, 29, 13, 29, 6434 },
202 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 148 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
203 18800, 0x82, 0x00, 2, 149 18800, 2, 2, 6, 14, 30, 14, 30 },
204 6, 14, 30, 14, 30, 9650 },
205 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 150 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
206 25000, 0x83, 0x00, 3, 151 25000, 3, 3, 8, 15, 31, 15, 31 },
207 8, 15, 31, 15, 31, 12868 },
208 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 152 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
209 36700, 0x84, 0x00, 4, 153 36700, 4, 4, 8, 16, 32, 16, 32 },
210 8, 16, 32, 16, 32, 19304 },
211 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 154 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
212 48100, 0x85, 0x00, 5, 155 48100, 5, 5, 8, 17, 33, 17, 33 },
213 8, 17, 33, 17, 33, 25740 },
214 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 156 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
215 53500, 0x86, 0x00, 6, 157 53500, 6, 6, 8, 18, 34, 18, 34 },
216 8, 18, 34, 18, 34, 28956 },
217 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 158 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
218 59000, 0x87, 0x00, 7, 159 59000, 7, 7, 8, 19, 35, 19, 36 },
219 8, 19, 35, 19, 36, 32180 },
220 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 160 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
221 12700, 0x88, 0x00, 8, 161 12700, 8, 8, 4, 20, 37, 20, 37 },
222 4, 20, 37, 20, 37, 6430 },
223 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 162 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
224 24800, 0x89, 0x00, 9, 163 24800, 9, 9, 6, 21, 38, 21, 38 },
225 6, 21, 38, 21, 38, 12860 },
226 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 164 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
227 36600, 0x8a, 0x00, 10, 165 36600, 10, 10, 6, 22, 39, 22, 39 },
228 6, 22, 39, 22, 39, 19300 },
229 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 166 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
230 48100, 0x8b, 0x00, 11, 167 48100, 11, 11, 8, 23, 40, 23, 40 },
231 8, 23, 40, 23, 40, 25736 },
232 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 168 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
233 69500, 0x8c, 0x00, 12, 169 69500, 12, 12, 8, 24, 41, 24, 41 },
234 8, 24, 41, 24, 41, 38600 },
235 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 170 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
236 89500, 0x8d, 0x00, 13, 171 89500, 13, 13, 8, 25, 42, 25, 42 },
237 8, 25, 42, 25, 42, 51472 },
238 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 172 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
239 98900, 0x8e, 0x00, 14, 173 98900, 14, 14, 8, 26, 43, 26, 44 },
240 8, 26, 43, 26, 44, 57890 },
241 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 174 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
242 108300, 0x8f, 0x00, 15, 175 108300, 15, 15, 8, 27, 44, 27, 45 },
243 8, 27, 44, 27, 45, 64320 },
244 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 176 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
245 13200, 0x80, 0x00, 0, 177 13200, 0, 0, 8, 12, 28, 28, 28 },
246 8, 12, 28, 28, 28, 6684 },
247 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 178 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
248 25900, 0x81, 0x00, 1, 179 25900, 1, 1, 8, 13, 29, 29, 29 },
249 8, 13, 29, 29, 29, 13368 },
250 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 180 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
251 38600, 0x82, 0x00, 2, 181 38600, 2, 2, 8, 14, 30, 30, 30 },
252 8, 14, 30, 30, 30, 20052 },
253 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 182 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
254 49800, 0x83, 0x00, 3, 183 49800, 3, 3, 8, 15, 31, 31, 31 },
255 8, 15, 31, 31, 31, 26738 },
256 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 184 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
257 72200, 0x84, 0x00, 4, 185 72200, 4, 4, 8, 16, 32, 32, 32 },
258 8, 16, 32, 32, 32, 40104 },
259 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 186 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
260 92900, 0x85, 0x00, 5, 187 92900, 5, 5, 8, 17, 33, 33, 33 },
261 8, 17, 33, 33, 33, 53476 },
262 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ 188 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
263 102700, 0x86, 0x00, 6, 189 102700, 6, 6, 8, 18, 34, 34, 34 },
264 8, 18, 34, 34, 34, 60156 },
265 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 190 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
266 112000, 0x87, 0x00, 7, 191 112000, 7, 7, 8, 19, 35, 36, 36 },
267 8, 19, 35, 36, 36, 66840 },
268 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ 192 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
269 122000, 0x87, 0x00, 7, 193 122000, 7, 7, 8, 19, 35, 36, 36 },
270 8, 19, 35, 36, 36, 74200 },
271 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 194 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
272 25800, 0x88, 0x00, 8, 195 25800, 8, 8, 8, 20, 37, 37, 37 },
273 8, 20, 37, 37, 37, 13360 },
274 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 196 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
275 49800, 0x89, 0x00, 9, 197 49800, 9, 9, 8, 21, 38, 38, 38 },
276 8, 21, 38, 38, 38, 26720 },
277 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 198 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
278 71900, 0x8a, 0x00, 10, 199 71900, 10, 10, 8, 22, 39, 39, 39 },
279 8, 22, 39, 39, 39, 40080 },
280 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 200 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
281 92500, 0x8b, 0x00, 11, 201 92500, 11, 11, 8, 23, 40, 40, 40 },
282 8, 23, 40, 40, 40, 53440 },
283 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 202 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
284 130300, 0x8c, 0x00, 12, 203 130300, 12, 12, 8, 24, 41, 41, 41 },
285 8, 24, 41, 41, 41, 80160 },
286 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 204 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
287 162800, 0x8d, 0x00, 13, 205 162800, 13, 13, 8, 25, 42, 42, 42 },
288 8, 25, 42, 42, 42, 106880 },
289 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 206 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
290 178200, 0x8e, 0x00, 14, 207 178200, 14, 14, 8, 26, 43, 43, 43 },
291 8, 26, 43, 43, 43, 120240 },
292 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 208 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
293 192100, 0x8f, 0x00, 15, 209 192100, 15, 15, 8, 27, 44, 45, 45 },
294 8, 27, 44, 45, 45, 133600 },
295 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ 210 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
296 207000, 0x8f, 0x00, 15, 211 207000, 15, 15, 8, 27, 44, 45, 45 },
297 8, 27, 44, 45, 45, 148400 }, 212 },
298 },
299 50, /* probe interval */ 213 50, /* probe interval */
300 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 214 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
301}; 215};
302 216
303static const struct ath_rate_table ar5416_11a_ratetable = { 217static const struct ath_rate_table ar5416_11a_ratetable = {
304 8, 218 8,
219 0,
305 { 220 {
306 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 221 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
307 5400, 0x0b, 0x00, (0x80|12), 222 5400, 0, 12, 0, 0, 0 },
308 0, 0, 0 },
309 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 223 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
310 7800, 0x0f, 0x00, 18, 224 7800, 1, 18, 0, 1, 0 },
311 0, 1, 0 },
312 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 225 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
313 10000, 0x0a, 0x00, (0x80|24), 226 10000, 2, 24, 2, 2, 0 },
314 2, 2, 0 },
315 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 227 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
316 13900, 0x0e, 0x00, 36, 228 13900, 3, 36, 2, 3, 0 },
317 2, 3, 0 },
318 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 229 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
319 17300, 0x09, 0x00, (0x80|48), 230 17300, 4, 48, 4, 4, 0 },
320 4, 4, 0 },
321 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 231 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
322 23000, 0x0d, 0x00, 72, 232 23000, 5, 72, 4, 5, 0 },
323 4, 5, 0 },
324 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 233 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
325 27400, 0x08, 0x00, 96, 234 27400, 6, 96, 4, 6, 0 },
326 4, 6, 0 },
327 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 235 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
328 29300, 0x0c, 0x00, 108, 236 29300, 7, 108, 4, 7, 0 },
329 4, 7, 0 },
330 }, 237 },
331 50, /* probe interval */ 238 50, /* probe interval */
332 0, /* Phy rates allowed initially */ 239 0, /* Phy rates allowed initially */
@@ -334,48 +241,51 @@ static const struct ath_rate_table ar5416_11a_ratetable = {
334 241
335static const struct ath_rate_table ar5416_11g_ratetable = { 242static const struct ath_rate_table ar5416_11g_ratetable = {
336 12, 243 12,
244 0,
337 { 245 {
338 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 246 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
339 900, 0x1b, 0x00, 2, 247 900, 0, 2, 0, 0, 0 },
340 0, 0, 0 },
341 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 248 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
342 1900, 0x1a, 0x04, 4, 249 1900, 1, 4, 1, 1, 0 },
343 1, 1, 0 },
344 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 250 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
345 4900, 0x19, 0x04, 11, 251 4900, 2, 11, 2, 2, 0 },
346 2, 2, 0 },
347 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 252 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
348 8100, 0x18, 0x04, 22, 253 8100, 3, 22, 3, 3, 0 },
349 3, 3, 0 },
350 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 254 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
351 5400, 0x0b, 0x00, 12, 255 5400, 4, 12, 4, 4, 0 },
352 4, 4, 0 },
353 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 256 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
354 7800, 0x0f, 0x00, 18, 257 7800, 5, 18, 4, 5, 0 },
355 4, 5, 0 },
356 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 258 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
357 10000, 0x0a, 0x00, 24, 259 10000, 6, 24, 6, 6, 0 },
358 6, 6, 0 },
359 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 260 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
360 13900, 0x0e, 0x00, 36, 261 13900, 7, 36, 6, 7, 0 },
361 6, 7, 0 },
362 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 262 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
363 17300, 0x09, 0x00, 48, 263 17300, 8, 48, 8, 8, 0 },
364 8, 8, 0 },
365 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 264 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
366 23000, 0x0d, 0x00, 72, 265 23000, 9, 72, 8, 9, 0 },
367 8, 9, 0 },
368 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 266 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
369 27400, 0x08, 0x00, 96, 267 27400, 10, 96, 8, 10, 0 },
370 8, 10, 0 },
371 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 268 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
372 29300, 0x0c, 0x00, 108, 269 29300, 11, 108, 8, 11, 0 },
373 8, 11, 0 },
374 }, 270 },
375 50, /* probe interval */ 271 50, /* probe interval */
376 0, /* Phy rates allowed initially */ 272 0, /* Phy rates allowed initially */
377}; 273};
378 274
275static const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX] = {
276 [ATH9K_MODE_11A] = &ar5416_11a_ratetable,
277 [ATH9K_MODE_11G] = &ar5416_11g_ratetable,
278 [ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable,
279 [ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable,
280 [ATH9K_MODE_11NA_HT40PLUS] = &ar5416_11na_ratetable,
281 [ATH9K_MODE_11NA_HT40MINUS] = &ar5416_11na_ratetable,
282 [ATH9K_MODE_11NG_HT40PLUS] = &ar5416_11ng_ratetable,
283 [ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable,
284};
285
286static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
287 struct ieee80211_tx_rate *rate);
288
379static inline int8_t median(int8_t a, int8_t b, int8_t c) 289static inline int8_t median(int8_t a, int8_t b, int8_t c)
380{ 290{
381 if (a >= b) { 291 if (a >= b) {
@@ -534,7 +444,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
534 * capflag matches one of the validity 444 * capflag matches one of the validity
535 * (VALID/VALID_20/VALID_40) flags */ 445 * (VALID/VALID_20/VALID_40) flags */
536 446
537 if (((rate & 0x7F) == (dot11rate & 0x7F)) && 447 if ((rate == dot11rate) &&
538 ((valid & WLAN_RC_CAP_MODE(capflag)) == 448 ((valid & WLAN_RC_CAP_MODE(capflag)) ==
539 WLAN_RC_CAP_MODE(capflag)) && 449 WLAN_RC_CAP_MODE(capflag)) &&
540 !WLAN_RC_PHY_HT(phy)) { 450 !WLAN_RC_PHY_HT(phy)) {
@@ -576,8 +486,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
576 u8 rate = rateset->rs_rates[i]; 486 u8 rate = rateset->rs_rates[i];
577 u8 dot11rate = rate_table->info[j].dot11rate; 487 u8 dot11rate = rate_table->info[j].dot11rate;
578 488
579 if (((rate & 0x7F) != (dot11rate & 0x7F)) || 489 if ((rate != dot11rate) || !WLAN_RC_PHY_HT(phy) ||
580 !WLAN_RC_PHY_HT(phy) ||
581 !WLAN_RC_PHY_HT_VALID(valid, capflag)) 490 !WLAN_RC_PHY_HT_VALID(valid, capflag))
582 continue; 491 continue;
583 492
@@ -696,18 +605,20 @@ static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
696 u8 tries, u8 rix, int rtsctsenable) 605 u8 tries, u8 rix, int rtsctsenable)
697{ 606{
698 rate->count = tries; 607 rate->count = tries;
699 rate->idx = rix; 608 rate->idx = rate_table->info[rix].ratecode;
700 609
701 if (txrc->short_preamble) 610 if (txrc->short_preamble)
702 rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; 611 rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
703 if (txrc->rts || rtsctsenable) 612 if (txrc->rts || rtsctsenable)
704 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; 613 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
705 if (WLAN_RC_PHY_40(rate_table->info[rix].phy)) 614
706 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; 615 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; 616 rate->flags |= IEEE80211_TX_RC_MCS;
617 if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
618 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
619 if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
620 rate->flags |= IEEE80211_TX_RC_SHORT_GI;
621 }
711} 622}
712 623
713static void ath_rc_rate_set_rtscts(struct ath_softc *sc, 624static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
@@ -720,7 +631,7 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
720 /* get the cix for the lowest valid rix */ 631 /* get the cix for the lowest valid rix */
721 for (i = 3; i >= 0; i--) { 632 for (i = 3; i >= 0; i--) {
722 if (rates[i].count && (rates[i].idx >= 0)) { 633 if (rates[i].count && (rates[i].idx >= 0)) {
723 rix = rates[i].idx; 634 rix = ath_rc_get_rateindex(rate_table, &rates[i]);
724 break; 635 break;
725 } 636 }
726 } 637 }
@@ -1080,15 +991,19 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
1080{ 991{
1081 int rix; 992 int rix;
1082 993
994 if (!(rate->flags & IEEE80211_TX_RC_MCS))
995 return rate->idx;
996
997 rix = rate->idx + rate_table->mcs_start;
1083 if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && 998 if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
1084 (rate->flags & IEEE80211_TX_RC_SHORT_GI)) 999 (rate->flags & IEEE80211_TX_RC_SHORT_GI))
1085 rix = rate_table->info[rate->idx].ht_index; 1000 rix = rate_table->info[rix].ht_index;
1086 else if (rate->flags & IEEE80211_TX_RC_SHORT_GI) 1001 else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
1087 rix = rate_table->info[rate->idx].sgi_index; 1002 rix = rate_table->info[rix].sgi_index;
1088 else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 1003 else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1089 rix = rate_table->info[rate->idx].cw40index; 1004 rix = rate_table->info[rix].cw40index;
1090 else 1005 else
1091 rix = rate_table->info[rate->idx].base_index; 1006 rix = rate_table->info[rix].base_index;
1092 1007
1093 return rix; 1008 return rix;
1094} 1009}
@@ -1183,7 +1098,9 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
1183 1098
1184 ath_print(common, ATH_DBG_CONFIG, 1099 ath_print(common, ATH_DBG_CONFIG,
1185 "Choosing rate table for mode: %d\n", mode); 1100 "Choosing rate table for mode: %d\n", mode);
1186 return sc->hw_rate_table[mode]; 1101
1102 sc->cur_rate_mode = mode;
1103 return hw_rate_table[mode];
1187} 1104}
1188 1105
1189static void ath_rc_init(struct ath_softc *sc, 1106static void ath_rc_init(struct ath_softc *sc,
@@ -1197,12 +1114,6 @@ static void ath_rc_init(struct ath_softc *sc,
1197 u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates; 1114 u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
1198 u8 i, j, k, hi = 0, hthi = 0; 1115 u8 i, j, k, hi = 0, hthi = 0;
1199 1116
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 1117 /* Initial rate table size. Will change depending
1207 * on the working rate set */ 1118 * on the working rate set */
1208 ath_rc_priv->rate_table_size = RATE_TABLE_SIZE; 1119 ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
@@ -1324,10 +1235,14 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1324 return; 1235 return;
1325 1236
1326 /* 1237 /*
1327 * If underrun error is seen assume it as an excessive retry only 1238 * If an underrun error is seen assume it as an excessive retry only
1328 * if prefetch trigger level have reached the max (0x3f for 5416) 1239 * if max frame trigger level has been reached (2 KB for singel stream,
1329 * Adjust the long retry as if the frame was tried hw->max_rate_tries 1240 * and 4 KB for dual stream). Adjust the long retry as if the frame was
1330 * times. This affects how ratectrl updates PER for the failed rate. 1241 * tried hw->max_rate_tries times to affect how ratectrl updates PER for
1242 * the failed rate. In case of congestion on the bus penalizing these
1243 * type of underruns should help hardware actually transmit new frames
1244 * successfully by eventually preferring slower rates. This itself
1245 * should also alleviate congestion on the bus.
1331 */ 1246 */
1332 if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) && 1247 if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) &&
1333 (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) { 1248 (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) {
@@ -1357,7 +1272,8 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1357 } 1272 }
1358 } 1273 }
1359 1274
1360 ath_debug_stat_rc(sc, skb); 1275 ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table,
1276 &tx_info->status.rates[final_ts_idx]));
1361} 1277}
1362 1278
1363static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, 1279static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
@@ -1365,7 +1281,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1365{ 1281{
1366 struct ath_softc *sc = priv; 1282 struct ath_softc *sc = priv;
1367 struct ath_rate_priv *ath_rc_priv = priv_sta; 1283 struct ath_rate_priv *ath_rc_priv = priv_sta;
1368 const struct ath_rate_table *rate_table = NULL; 1284 const struct ath_rate_table *rate_table;
1369 bool is_cw40, is_sgi40; 1285 bool is_cw40, is_sgi40;
1370 int i, j = 0; 1286 int i, j = 0;
1371 1287
@@ -1397,11 +1313,9 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1397 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) || 1313 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
1398 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) { 1314 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
1399 rate_table = ath_choose_rate_table(sc, sband->band, 1315 rate_table = ath_choose_rate_table(sc, sband->band,
1400 sta->ht_cap.ht_supported, 1316 sta->ht_cap.ht_supported, is_cw40);
1401 is_cw40); 1317 } else {
1402 } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { 1318 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 } 1319 }
1406 1320
1407 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40); 1321 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
@@ -1445,6 +1359,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, 1359 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
1446 "Operating HT Bandwidth changed to: %d\n", 1360 "Operating HT Bandwidth changed to: %d\n",
1447 sc->hw->conf.channel_type); 1361 sc->hw->conf.channel_type);
1362 sc->cur_rate_table = hw_rate_table[sc->cur_rate_mode];
1448 } 1363 }
1449 } 1364 }
1450} 1365}
@@ -1497,26 +1412,6 @@ static struct rate_control_ops ath_rate_ops = {
1497 .free_sta = ath_rate_free_sta, 1412 .free_sta = ath_rate_free_sta,
1498}; 1413};
1499 1414
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) 1415int ath_rate_control_register(void)
1521{ 1416{
1522 return ieee80211_rate_control_register(&ath_rate_ops); 1417 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..9eb96f506998 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;
@@ -111,14 +112,12 @@ struct ath_rate_table {
111 u32 ratekbps; 112 u32 ratekbps;
112 u32 user_ratekbps; 113 u32 user_ratekbps;
113 u8 ratecode; 114 u8 ratecode;
114 u8 short_preamble;
115 u8 dot11rate; 115 u8 dot11rate;
116 u8 ctrl_rate; 116 u8 ctrl_rate;
117 u8 base_index; 117 u8 base_index;
118 u8 cw40index; 118 u8 cw40index;
119 u8 sgi_index; 119 u8 sgi_index;
120 u8 ht_index; 120 u8 ht_index;
121 u32 max_4ms_framelen;
122 } info[RATE_TABLE_SIZE]; 121 } info[RATE_TABLE_SIZE];
123 u32 probe_interval; 122 u32 probe_interval;
124 u8 initial_ratemax; 123 u8 initial_ratemax;
@@ -179,8 +178,6 @@ enum ath9k_internal_frame_type {
179 ATH9K_INT_UNPAUSE 178 ATH9K_INT_UNPAUSE
180}; 179};
181 180
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); 181int ath_rate_control_register(void);
185void ath_rate_control_unregister(void); 182void ath_rate_control_unregister(void);
186 183
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 49ec25f020f0..8e653fb937a1 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1332,13 +1332,22 @@ enum {
1332#define AR_MCAST_FIL0 0x8040 1332#define AR_MCAST_FIL0 0x8040
1333#define AR_MCAST_FIL1 0x8044 1333#define AR_MCAST_FIL1 0x8044
1334 1334
1335/*
1336 * AR_DIAG_SW - Register which can be used for diagnostics and testing purposes.
1337 *
1338 * The force RX abort (AR_DIAG_RX_ABORT, bit 25) can be used in conjunction with
1339 * RX block (AR_DIAG_RX_DIS, bit 5) to help fast channel change to shut down
1340 * receive. The force RX abort bit will kill any frame which is currently being
1341 * transferred between the MAC and baseband. The RX block bit (AR_DIAG_RX_DIS)
1342 * will prevent any new frames from getting started.
1343 */
1335#define AR_DIAG_SW 0x8048 1344#define AR_DIAG_SW 0x8048
1336#define AR_DIAG_CACHE_ACK 0x00000001 1345#define AR_DIAG_CACHE_ACK 0x00000001
1337#define AR_DIAG_ACK_DIS 0x00000002 1346#define AR_DIAG_ACK_DIS 0x00000002
1338#define AR_DIAG_CTS_DIS 0x00000004 1347#define AR_DIAG_CTS_DIS 0x00000004
1339#define AR_DIAG_ENCRYPT_DIS 0x00000008 1348#define AR_DIAG_ENCRYPT_DIS 0x00000008
1340#define AR_DIAG_DECRYPT_DIS 0x00000010 1349#define AR_DIAG_DECRYPT_DIS 0x00000010
1341#define AR_DIAG_RX_DIS 0x00000020 1350#define AR_DIAG_RX_DIS 0x00000020 /* RX block */
1342#define AR_DIAG_LOOP_BACK 0x00000040 1351#define AR_DIAG_LOOP_BACK 0x00000040
1343#define AR_DIAG_CORR_FCS 0x00000080 1352#define AR_DIAG_CORR_FCS 0x00000080
1344#define AR_DIAG_CHAN_INFO 0x00000100 1353#define AR_DIAG_CHAN_INFO 0x00000100
@@ -1347,12 +1356,12 @@ enum {
1347#define AR_DIAG_FRAME_NV0 0x00020000 1356#define AR_DIAG_FRAME_NV0 0x00020000
1348#define AR_DIAG_OBS_PT_SEL1 0x000C0000 1357#define AR_DIAG_OBS_PT_SEL1 0x000C0000
1349#define AR_DIAG_OBS_PT_SEL1_S 18 1358#define AR_DIAG_OBS_PT_SEL1_S 18
1350#define AR_DIAG_FORCE_RX_CLEAR 0x00100000 1359#define AR_DIAG_FORCE_RX_CLEAR 0x00100000 /* force rx_clear high */
1351#define AR_DIAG_IGNORE_VIRT_CS 0x00200000 1360#define AR_DIAG_IGNORE_VIRT_CS 0x00200000
1352#define AR_DIAG_FORCE_CH_IDLE_HIGH 0x00400000 1361#define AR_DIAG_FORCE_CH_IDLE_HIGH 0x00400000
1353#define AR_DIAG_EIFS_CTRL_ENA 0x00800000 1362#define AR_DIAG_EIFS_CTRL_ENA 0x00800000
1354#define AR_DIAG_DUAL_CHAIN_INFO 0x01000000 1363#define AR_DIAG_DUAL_CHAIN_INFO 0x01000000
1355#define AR_DIAG_RX_ABORT 0x02000000 1364#define AR_DIAG_RX_ABORT 0x02000000 /* Force RX abort */
1356#define AR_DIAG_SATURATE_CYCLE_CNT 0x04000000 1365#define AR_DIAG_SATURATE_CYCLE_CNT 0x04000000
1357#define AR_DIAG_OBS_PT_SEL2 0x08000000 1366#define AR_DIAG_OBS_PT_SEL2 0x08000000
1358#define AR_DIAG_RX_CLEAR_CTL_LOW 0x10000000 1367#define AR_DIAG_RX_CLEAR_CTL_LOW 0x10000000
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 745d91995d78..564c6cb1c2b4 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 */
@@ -1554,6 +1596,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1554 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1596 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1555 int hdrlen; 1597 int hdrlen;
1556 __le16 fc; 1598 __le16 fc;
1599 int padpos, padsize;
1557 1600
1558 tx_info->pad[0] = 0; 1601 tx_info->pad[0] = 0;
1559 switch (txctl->frame_type) { 1602 switch (txctl->frame_type) {
@@ -1572,7 +1615,13 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1572 ATH_TXBUF_RESET(bf); 1615 ATH_TXBUF_RESET(bf);
1573 1616
1574 bf->aphy = aphy; 1617 bf->aphy = aphy;
1575 bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); 1618 bf->bf_frmlen = skb->len + FCS_LEN;
1619 /* Remove the padding size from bf_frmlen, if any */
1620 padpos = ath9k_cmn_padpos(hdr->frame_control);
1621 padsize = padpos & 3;
1622 if (padsize && skb->len>padpos+padsize) {
1623 bf->bf_frmlen -= padsize;
1624 }
1576 1625
1577 if (conf_is_ht(&hw->conf) && !is_pae(skb)) 1626 if (conf_is_ht(&hw->conf) && !is_pae(skb))
1578 bf->bf_state.bf_type |= BUF_HT; 1627 bf->bf_state.bf_type |= BUF_HT;
@@ -1602,6 +1651,14 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1602 } 1651 }
1603 1652
1604 bf->bf_buf_addr = bf->bf_dmacontext; 1653 bf->bf_buf_addr = bf->bf_dmacontext;
1654
1655 /* tag if this is a nullfunc frame to enable PS when AP acks it */
1656 if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) {
1657 bf->bf_isnullfunc = true;
1658 sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED;
1659 } else
1660 bf->bf_isnullfunc = false;
1661
1605 return 0; 1662 return 0;
1606} 1663}
1607 1664
@@ -1920,8 +1977,10 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
1920 } 1977 }
1921 } 1978 }
1922 1979
1923 for (i = tx_rateindex + 1; i < hw->max_rates; i++) 1980 for (i = tx_rateindex + 1; i < hw->max_rates; i++) {
1924 tx_info->status.rates[i].count = 0; 1981 tx_info->status.rates[i].count = 0;
1982 tx_info->status.rates[i].idx = -1;
1983 }
1925 1984
1926 tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1; 1985 tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
1927} 1986}
@@ -1995,6 +2054,19 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1995 } 2054 }
1996 2055
1997 /* 2056 /*
2057 * We now know the nullfunc frame has been ACKed so we
2058 * can disable RX.
2059 */
2060 if (bf->bf_isnullfunc &&
2061 (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) {
2062 if ((sc->sc_flags & SC_OP_PS_ENABLED)) {
2063 sc->ps_enabled = true;
2064 ath9k_hw_setrxabort(sc->sc_ah, 1);
2065 } else
2066 sc->sc_flags |= SC_OP_NULLFUNC_COMPLETED;
2067 }
2068
2069 /*
1998 * Remove ath_buf's of the same transmit unit from txq, 2070 * Remove ath_buf's of the same transmit unit from txq,
1999 * however leave the last descriptor back as the holding 2071 * however leave the last descriptor back as the holding
2000 * descriptor for hw. 2072 * descriptor for hw.