diff options
author | Sujith <Sujith.Manoharan@atheros.com> | 2009-07-27 02:38:16 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-29 15:46:09 -0400 |
commit | fec247c0d5bfbaa0861774ce31d515bbd48f7fce (patch) | |
tree | cb1ca3defc39851cecaa44bbf47e8bfb39b093c9 /drivers/net/wireless | |
parent | 0ee9c13c7c92581ab005d80795cf65897213b249 (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/net/wireless')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 85 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.h | 54 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 34 |
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 3a978bfa246e..bda0f302340c 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 9f99f00c1447..9e369208f7dc 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 | |||
499 | static 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 | |||
533 | void 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 | |||
561 | static const struct file_operations fops_xmit = { | ||
562 | .read = read_file_xmit, | ||
563 | .open = ath9k_debugfs_open, | ||
564 | .owner = THIS_MODULE | ||
565 | }; | ||
489 | 566 | ||
490 | int ath9k_init_debug(struct ath_softc *sc) | 567 | int 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; |
533 | err: | 617 | err: |
534 | ath9k_exit_debug(sc); | 618 | ath9k_exit_debug(sc); |
@@ -537,6 +621,7 @@ err: | |||
537 | 621 | ||
538 | void ath9k_exit_debug(struct ath_softc *sc) | 622 | void 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 edda15bf2c15..5e56b79d0cb0 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 | ||
38 | struct ath_txq; | ||
39 | struct 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 | */ | ||
118 | struct 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 | |||
90 | struct ath_stats { | 134 | struct 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 | ||
95 | struct ath9k_debug { | 140 | struct 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); | |||
110 | void ath9k_debug_remove_root(void); | 156 | void ath9k_debug_remove_root(void); |
111 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | 157 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); |
112 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb); | 158 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb); |
159 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, | ||
160 | struct ath_buf *bf); | ||
113 | void ath_debug_stat_retries(struct ath_softc *sc, int rix, | 161 | void 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 | ||
199 | static inline void ath_debug_stat_tx(struct ath_softc *sc, | ||
200 | struct ath_txq *txq, | ||
201 | struct ath_buf *bf) | ||
202 | { | ||
203 | } | ||
204 | |||
151 | static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, | 205 | static 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 6eb2927c8aec..b7806e2ca0e1 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); |
61 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 61 | static 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); |
64 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | 65 | static 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 | ||
223 | static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf) | 224 | static 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 | ||
571 | static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | 574 | static 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 | ||
1275 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | 1281 | static 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 | ||
1288 | static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | 1295 | static 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 | ||
1810 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 1817 | static 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 | ||