aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2009-07-27 02:38:16 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-29 15:46:09 -0400
commitfec247c0d5bfbaa0861774ce31d515bbd48f7fce (patch)
treecb1ca3defc39851cecaa44bbf47e8bfb39b093c9 /drivers
parent0ee9c13c7c92581ab005d80795cf65897213b249 (diff)
ath9k: Add debug counters for TX
Location: ath9k/phy#/xmit Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c85
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h54
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c34
4 files changed, 160 insertions, 14 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 3a978bfa246..bda0f302340 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -237,7 +237,6 @@ struct ath_txq {
237 spinlock_t axq_lock; 237 spinlock_t axq_lock;
238 u32 axq_depth; 238 u32 axq_depth;
239 u8 axq_aggr_depth; 239 u8 axq_aggr_depth;
240 u32 axq_totalqueued;
241 bool stopped; 240 bool stopped;
242 bool axq_tx_inprogress; 241 bool axq_tx_inprogress;
243 struct ath_buf *axq_linkbuf; 242 struct ath_buf *axq_linkbuf;
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 9f99f00c144..9e369208f7d 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -486,6 +486,83 @@ static const struct file_operations fops_wiphy = {
486 .owner = THIS_MODULE 486 .owner = THIS_MODULE
487}; 487};
488 488
489#define PR(str, elem) \
490 do { \
491 len += snprintf(buf + len, size - len, \
492 "%s%13u%11u%10u%10u\n", str, \
493 sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BE]].elem, \
494 sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BK]].elem, \
495 sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VI]].elem, \
496 sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VO]].elem); \
497} while(0)
498
499static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
500 size_t count, loff_t *ppos)
501{
502 struct ath_softc *sc = file->private_data;
503 char *buf;
504 unsigned int len = 0, size = 2048;
505 ssize_t retval = 0;
506
507 buf = kzalloc(size, GFP_KERNEL);
508 if (buf == NULL)
509 return 0;
510
511 len += sprintf(buf, "%30s %10s%10s%10s\n\n", "BE", "BK", "VI", "VO");
512
513 PR("MPDUs Queued: ", queued);
514 PR("MPDUs Completed: ", completed);
515 PR("Aggregates: ", a_aggr);
516 PR("AMPDUs Queued: ", a_queued);
517 PR("AMPDUs Completed:", a_completed);
518 PR("AMPDUs Retried: ", a_retries);
519 PR("AMPDUs XRetried: ", a_xretries);
520 PR("FIFO Underrun: ", fifo_underrun);
521 PR("TXOP Exceeded: ", xtxop);
522 PR("TXTIMER Expiry: ", timer_exp);
523 PR("DESC CFG Error: ", desc_cfg_err);
524 PR("DATA Underrun: ", data_underrun);
525 PR("DELIM Underrun: ", delim_underrun);
526
527 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
528 kfree(buf);
529
530 return retval;
531}
532
533void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
534 struct ath_buf *bf)
535{
536 struct ath_desc *ds = bf->bf_desc;
537
538 if (bf_isampdu(bf)) {
539 if (bf_isxretried(bf))
540 TX_STAT_INC(txq->axq_qnum, a_xretries);
541 else
542 TX_STAT_INC(txq->axq_qnum, a_completed);
543 } else {
544 TX_STAT_INC(txq->axq_qnum, completed);
545 }
546
547 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO)
548 TX_STAT_INC(txq->axq_qnum, fifo_underrun);
549 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XTXOP)
550 TX_STAT_INC(txq->axq_qnum, xtxop);
551 if (ds->ds_txstat.ts_status & ATH9K_TXERR_TIMER_EXPIRED)
552 TX_STAT_INC(txq->axq_qnum, timer_exp);
553 if (ds->ds_txstat.ts_flags & ATH9K_TX_DESC_CFG_ERR)
554 TX_STAT_INC(txq->axq_qnum, desc_cfg_err);
555 if (ds->ds_txstat.ts_flags & ATH9K_TX_DATA_UNDERRUN)
556 TX_STAT_INC(txq->axq_qnum, data_underrun);
557 if (ds->ds_txstat.ts_flags & ATH9K_TX_DELIM_UNDERRUN)
558 TX_STAT_INC(txq->axq_qnum, delim_underrun);
559}
560
561static const struct file_operations fops_xmit = {
562 .read = read_file_xmit,
563 .open = ath9k_debugfs_open,
564 .owner = THIS_MODULE
565};
489 566
490int ath9k_init_debug(struct ath_softc *sc) 567int ath9k_init_debug(struct ath_softc *sc)
491{ 568{
@@ -529,6 +606,13 @@ int ath9k_init_debug(struct ath_softc *sc)
529 if (!sc->debug.debugfs_wiphy) 606 if (!sc->debug.debugfs_wiphy)
530 goto err; 607 goto err;
531 608
609 sc->debug.debugfs_xmit = debugfs_create_file("xmit",
610 S_IRUSR,
611 sc->debug.debugfs_phy,
612 sc, &fops_xmit);
613 if (!sc->debug.debugfs_xmit)
614 goto err;
615
532 return 0; 616 return 0;
533err: 617err:
534 ath9k_exit_debug(sc); 618 ath9k_exit_debug(sc);
@@ -537,6 +621,7 @@ err:
537 621
538void ath9k_exit_debug(struct ath_softc *sc) 622void ath9k_exit_debug(struct ath_softc *sc)
539{ 623{
624 debugfs_remove(sc->debug.debugfs_xmit);
540 debugfs_remove(sc->debug.debugfs_wiphy); 625 debugfs_remove(sc->debug.debugfs_wiphy);
541 debugfs_remove(sc->debug.debugfs_rcstat); 626 debugfs_remove(sc->debug.debugfs_rcstat);
542 debugfs_remove(sc->debug.debugfs_interrupt); 627 debugfs_remove(sc->debug.debugfs_interrupt);
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index edda15bf2c1..5e56b79d0cb 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -35,6 +35,15 @@ enum ATH_DEBUG {
35 35
36#define DBG_DEFAULT (ATH_DBG_FATAL) 36#define DBG_DEFAULT (ATH_DBG_FATAL)
37 37
38struct ath_txq;
39struct ath_buf;
40
41#ifdef CONFIG_ATH9K_DEBUG
42#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
43#else
44#define TX_STAT_INC(q, c) do { } while (0)
45#endif
46
38#ifdef CONFIG_ATH9K_DEBUG 47#ifdef CONFIG_ATH9K_DEBUG
39 48
40/** 49/**
@@ -87,9 +96,45 @@ struct ath_rc_stats {
87 u8 per; 96 u8 per;
88}; 97};
89 98
99/**
100 * struct ath_tx_stats - Statistics about TX
101 * @queued: Total MPDUs (non-aggr) queued
102 * @completed: Total MPDUs (non-aggr) completed
103 * @a_aggr: Total no. of aggregates queued
104 * @a_queued: Total AMPDUs queued
105 * @a_completed: Total AMPDUs completed
106 * @a_retries: No. of AMPDUs retried (SW)
107 * @a_xretries: No. of AMPDUs dropped due to xretries
108 * @fifo_underrun: FIFO underrun occurrences
109 Valid only for:
110 - non-aggregate condition.
111 - first packet of aggregate.
112 * @xtxop: No. of frames filtered because of TXOP limit
113 * @timer_exp: Transmit timer expiry
114 * @desc_cfg_err: Descriptor configuration errors
115 * @data_urn: TX data underrun errors
116 * @delim_urn: TX delimiter underrun errors
117 */
118struct ath_tx_stats {
119 u32 queued;
120 u32 completed;
121 u32 a_aggr;
122 u32 a_queued;
123 u32 a_completed;
124 u32 a_retries;
125 u32 a_xretries;
126 u32 fifo_underrun;
127 u32 xtxop;
128 u32 timer_exp;
129 u32 desc_cfg_err;
130 u32 data_underrun;
131 u32 delim_underrun;
132};
133
90struct ath_stats { 134struct ath_stats {
91 struct ath_interrupt_stats istats; 135 struct ath_interrupt_stats istats;
92 struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; 136 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
137 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
93}; 138};
94 139
95struct ath9k_debug { 140struct ath9k_debug {
@@ -100,6 +145,7 @@ struct ath9k_debug {
100 struct dentry *debugfs_interrupt; 145 struct dentry *debugfs_interrupt;
101 struct dentry *debugfs_rcstat; 146 struct dentry *debugfs_rcstat;
102 struct dentry *debugfs_wiphy; 147 struct dentry *debugfs_wiphy;
148 struct dentry *debugfs_xmit;
103 struct ath_stats stats; 149 struct ath_stats stats;
104}; 150};
105 151
@@ -110,6 +156,8 @@ int ath9k_debug_create_root(void);
110void ath9k_debug_remove_root(void); 156void ath9k_debug_remove_root(void);
111void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); 157void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
112void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb); 158void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
159void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
160 struct ath_buf *bf);
113void ath_debug_stat_retries(struct ath_softc *sc, int rix, 161void ath_debug_stat_retries(struct ath_softc *sc, int rix,
114 int xretries, int retries, u8 per); 162 int xretries, int retries, u8 per);
115 163
@@ -148,6 +196,12 @@ static inline void ath_debug_stat_rc(struct ath_softc *sc,
148{ 196{
149} 197}
150 198
199static inline void ath_debug_stat_tx(struct ath_softc *sc,
200 struct ath_txq *txq,
201 struct ath_buf *bf)
202{
203}
204
151static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, 205static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
152 int xretries, int retries, u8 per) 206 int xretries, int retries, u8 per)
153{ 207{
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 6eb2927c8ae..b7806e2ca0e 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -59,6 +59,7 @@ static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
59 struct ath_atx_tid *tid, 59 struct ath_atx_tid *tid,
60 struct list_head *bf_head); 60 struct list_head *bf_head);
61static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 61static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
62 struct ath_txq *txq,
62 struct list_head *bf_q, 63 struct list_head *bf_q,
63 int txok, int sendbar); 64 int txok, int sendbar);
64static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, 65static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
@@ -212,7 +213,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
212 ath_tx_update_baw(sc, tid, bf->bf_seqno); 213 ath_tx_update_baw(sc, tid, bf->bf_seqno);
213 214
214 spin_unlock(&txq->axq_lock); 215 spin_unlock(&txq->axq_lock);
215 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); 216 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0);
216 spin_lock(&txq->axq_lock); 217 spin_lock(&txq->axq_lock);
217 } 218 }
218 219
@@ -220,13 +221,15 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
220 tid->baw_tail = tid->baw_head; 221 tid->baw_tail = tid->baw_head;
221} 222}
222 223
223static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf) 224static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
225 struct ath_buf *bf)
224{ 226{
225 struct sk_buff *skb; 227 struct sk_buff *skb;
226 struct ieee80211_hdr *hdr; 228 struct ieee80211_hdr *hdr;
227 229
228 bf->bf_state.bf_type |= BUF_RETRY; 230 bf->bf_state.bf_type |= BUF_RETRY;
229 bf->bf_retries++; 231 bf->bf_retries++;
232 TX_STAT_INC(txq->axq_qnum, a_retries);
230 233
231 skb = bf->bf_mpdu; 234 skb = bf->bf_mpdu;
232 hdr = (struct ieee80211_hdr *)skb->data; 235 hdr = (struct ieee80211_hdr *)skb->data;
@@ -328,7 +331,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
328 if (!(tid->state & AGGR_CLEANUP) && 331 if (!(tid->state & AGGR_CLEANUP) &&
329 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { 332 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
330 if (bf->bf_retries < ATH_MAX_SW_RETRIES) { 333 if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
331 ath_tx_set_retry(sc, bf); 334 ath_tx_set_retry(sc, txq, bf);
332 txpending = 1; 335 txpending = 1;
333 } else { 336 } else {
334 bf->bf_state.bf_type |= BUF_XRETRY; 337 bf->bf_state.bf_type |= BUF_XRETRY;
@@ -375,7 +378,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
375 ath_tx_rc_status(bf, ds, nbad, txok, false); 378 ath_tx_rc_status(bf, ds, nbad, txok, false);
376 } 379 }
377 380
378 ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar); 381 ath_tx_complete_buf(sc, bf, txq, &bf_head, !txfail, sendbar);
379 } else { 382 } else {
380 /* retry the un-acked ones */ 383 /* retry the un-acked ones */
381 if (bf->bf_next == NULL && bf_last->bf_stale) { 384 if (bf->bf_next == NULL && bf_last->bf_stale) {
@@ -395,8 +398,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
395 bf->bf_state.bf_type |= BUF_XRETRY; 398 bf->bf_state.bf_type |= BUF_XRETRY;
396 ath_tx_rc_status(bf, ds, nbad, 399 ath_tx_rc_status(bf, ds, nbad,
397 0, false); 400 0, false);
398 ath_tx_complete_buf(sc, bf, &bf_head, 401 ath_tx_complete_buf(sc, bf, txq,
399 0, 0); 402 &bf_head, 0, 0);
400 break; 403 break;
401 } 404 }
402 405
@@ -569,6 +572,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
569} 572}
570 573
571static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, 574static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
575 struct ath_txq *txq,
572 struct ath_atx_tid *tid, 576 struct ath_atx_tid *tid,
573 struct list_head *bf_q) 577 struct list_head *bf_q)
574{ 578{
@@ -633,6 +637,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
633 bf_prev->bf_desc->ds_link = bf->bf_daddr; 637 bf_prev->bf_desc->ds_link = bf->bf_daddr;
634 } 638 }
635 bf_prev = bf; 639 bf_prev = bf;
640
636 } while (!list_empty(&tid->buf_q)); 641 } while (!list_empty(&tid->buf_q));
637 642
638 bf_first->bf_al = al; 643 bf_first->bf_al = al;
@@ -655,7 +660,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
655 660
656 INIT_LIST_HEAD(&bf_q); 661 INIT_LIST_HEAD(&bf_q);
657 662
658 status = ath_tx_form_aggr(sc, tid, &bf_q); 663 status = ath_tx_form_aggr(sc, txq, tid, &bf_q);
659 664
660 /* 665 /*
661 * no frames picked up to be aggregated; 666 * no frames picked up to be aggregated;
@@ -686,6 +691,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
686 691
687 txq->axq_aggr_depth++; 692 txq->axq_aggr_depth++;
688 ath_tx_txqaddbuf(sc, txq, &bf_q); 693 ath_tx_txqaddbuf(sc, txq, &bf_q);
694 TX_STAT_INC(txq->axq_qnum, a_aggr);
689 695
690 } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH && 696 } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
691 status != ATH_AGGR_BAW_CLOSED); 697 status != ATH_AGGR_BAW_CLOSED);
@@ -737,7 +743,7 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
737 } 743 }
738 list_move_tail(&bf->list, &bf_head); 744 list_move_tail(&bf->list, &bf_head);
739 ath_tx_update_baw(sc, txtid, bf->bf_seqno); 745 ath_tx_update_baw(sc, txtid, bf->bf_seqno);
740 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); 746 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0);
741 } 747 }
742 spin_unlock_bh(&txq->axq_lock); 748 spin_unlock_bh(&txq->axq_lock);
743 749
@@ -859,7 +865,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
859 spin_lock_init(&txq->axq_lock); 865 spin_lock_init(&txq->axq_lock);
860 txq->axq_depth = 0; 866 txq->axq_depth = 0;
861 txq->axq_aggr_depth = 0; 867 txq->axq_aggr_depth = 0;
862 txq->axq_totalqueued = 0;
863 txq->axq_linkbuf = NULL; 868 txq->axq_linkbuf = NULL;
864 txq->axq_tx_inprogress = false; 869 txq->axq_tx_inprogress = false;
865 sc->tx.txqsetup |= 1<<qnum; 870 sc->tx.txqsetup |= 1<<qnum;
@@ -1025,7 +1030,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1025 if (bf_isampdu(bf)) 1030 if (bf_isampdu(bf))
1026 ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0); 1031 ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0);
1027 else 1032 else
1028 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); 1033 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0);
1029 } 1034 }
1030 1035
1031 spin_lock_bh(&txq->axq_lock); 1036 spin_lock_bh(&txq->axq_lock);
@@ -1176,7 +1181,6 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
1176 1181
1177 list_splice_tail_init(head, &txq->axq_q); 1182 list_splice_tail_init(head, &txq->axq_q);
1178 txq->axq_depth++; 1183 txq->axq_depth++;
1179 txq->axq_totalqueued++;
1180 txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); 1184 txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
1181 1185
1182 DPRINTF(sc, ATH_DBG_QUEUE, 1186 DPRINTF(sc, ATH_DBG_QUEUE,
@@ -1224,6 +1228,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
1224 1228
1225 bf = list_first_entry(bf_head, struct ath_buf, list); 1229 bf = list_first_entry(bf_head, struct ath_buf, list);
1226 bf->bf_state.bf_type |= BUF_AMPDU; 1230 bf->bf_state.bf_type |= BUF_AMPDU;
1231 TX_STAT_INC(txctl->txq->axq_qnum, a_queued);
1227 1232
1228 /* 1233 /*
1229 * Do not queue to h/w when any of the following conditions is true: 1234 * Do not queue to h/w when any of the following conditions is true:
@@ -1270,6 +1275,7 @@ static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
1270 bf->bf_lastbf = bf; 1275 bf->bf_lastbf = bf;
1271 ath_buf_set_rate(sc, bf); 1276 ath_buf_set_rate(sc, bf);
1272 ath_tx_txqaddbuf(sc, txq, bf_head); 1277 ath_tx_txqaddbuf(sc, txq, bf_head);
1278 TX_STAT_INC(txq->axq_qnum, queued);
1273} 1279}
1274 1280
1275static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, 1281static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
@@ -1283,6 +1289,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
1283 bf->bf_nframes = 1; 1289 bf->bf_nframes = 1;
1284 ath_buf_set_rate(sc, bf); 1290 ath_buf_set_rate(sc, bf);
1285 ath_tx_txqaddbuf(sc, txq, bf_head); 1291 ath_tx_txqaddbuf(sc, txq, bf_head);
1292 TX_STAT_INC(txq->axq_qnum, queued);
1286} 1293}
1287 1294
1288static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) 1295static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
@@ -1808,6 +1815,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1808} 1815}
1809 1816
1810static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 1817static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1818 struct ath_txq *txq,
1811 struct list_head *bf_q, 1819 struct list_head *bf_q,
1812 int txok, int sendbar) 1820 int txok, int sendbar)
1813{ 1821{
@@ -1815,7 +1823,6 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1815 unsigned long flags; 1823 unsigned long flags;
1816 int tx_flags = 0; 1824 int tx_flags = 0;
1817 1825
1818
1819 if (sendbar) 1826 if (sendbar)
1820 tx_flags = ATH_TX_BAR; 1827 tx_flags = ATH_TX_BAR;
1821 1828
@@ -1828,6 +1835,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1828 1835
1829 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); 1836 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
1830 ath_tx_complete(sc, skb, tx_flags); 1837 ath_tx_complete(sc, skb, tx_flags);
1838 ath_debug_stat_tx(sc, txq, bf);
1831 1839
1832 /* 1840 /*
1833 * Return the list of ath_buf of this mpdu to free queue 1841 * Return the list of ath_buf of this mpdu to free queue
@@ -2015,7 +2023,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2015 if (bf_isampdu(bf)) 2023 if (bf_isampdu(bf))
2016 ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok); 2024 ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok);
2017 else 2025 else
2018 ath_tx_complete_buf(sc, bf, &bf_head, txok, 0); 2026 ath_tx_complete_buf(sc, bf, txq, &bf_head, txok, 0);
2019 2027
2020 ath_wake_mac80211_queue(sc, txq); 2028 ath_wake_mac80211_queue(sc, txq);
2021 2029