diff options
author | Sujith Manoharan <c_manoha@qca.qualcomm.com> | 2012-11-21 07:43:11 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-11-21 14:16:03 -0500 |
commit | 78ef731ce549dd9baf6eba8cf52f61727613690a (patch) | |
tree | 7ea204e511e1fc1d95f6036b4a7374fbc5ae41ed | |
parent | bea843c73854becf998047a83af22a90de3fd19b (diff) |
ath9k: Fix the 'xmit' debugfs file
The 'xmit' debugfs file has become big and unwieldy, fix
multiple issues with its usage:
* Store TX counters/statistics only for the 4 Access Categories.
Use IEEE80211_NUM_ACS instead of ATH9K_NUM_TX_QUEUES.
* Move various utility macros to debug.h, they can be reused
elsewhere.
* Remove tx_complete_poll_work_seen.
* Remove code that accesses various internal queue-specific
variables without any locking whatsoever. HW/SW queue details
will be handled in a subsequent patch.
* Do not print internal values like txq_headidx and txq_headidx.
They were mostly unused anyway, considering code like:
PRX("txq_tailidx: ", txq_headidx);
* Handle 'txprocdesc' for EDMA too.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 104 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.h | 17 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/link.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 2 |
6 files changed, 23 insertions, 105 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 3c1cebe55f69..e739b56db533 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -725,7 +725,6 @@ struct ath_softc { | |||
725 | struct ath9k_debug debug; | 725 | struct ath9k_debug debug; |
726 | spinlock_t nodes_lock; | 726 | spinlock_t nodes_lock; |
727 | struct list_head nodes; /* basically, stations */ | 727 | struct list_head nodes; /* basically, stations */ |
728 | unsigned int tx_complete_poll_work_seen; | ||
729 | #endif | 728 | #endif |
730 | struct ath_beacon_config cur_beacon_conf; | 729 | struct ath_beacon_config cur_beacon_conf; |
731 | struct delayed_work tx_complete_work; | 730 | struct delayed_work tx_complete_work; |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 957e38646fdc..f9df82bdd213 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -512,62 +512,19 @@ static const struct file_operations fops_interrupt = { | |||
512 | .llseek = default_llseek, | 512 | .llseek = default_llseek, |
513 | }; | 513 | }; |
514 | 514 | ||
515 | #define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum | ||
516 | #define PR(str, elem) \ | ||
517 | do { \ | ||
518 | len += snprintf(buf + len, size - len, \ | ||
519 | "%s%13u%11u%10u%10u\n", str, \ | ||
520 | sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem, \ | ||
521 | sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].elem, \ | ||
522 | sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].elem, \ | ||
523 | sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].elem); \ | ||
524 | if (len >= size) \ | ||
525 | goto done; \ | ||
526 | } while(0) | ||
527 | |||
528 | #define PRX(str, elem) \ | ||
529 | do { \ | ||
530 | len += snprintf(buf + len, size - len, \ | ||
531 | "%s%13u%11u%10u%10u\n", str, \ | ||
532 | (unsigned int)(sc->tx.txq_map[IEEE80211_AC_BE]->elem), \ | ||
533 | (unsigned int)(sc->tx.txq_map[IEEE80211_AC_BK]->elem), \ | ||
534 | (unsigned int)(sc->tx.txq_map[IEEE80211_AC_VI]->elem), \ | ||
535 | (unsigned int)(sc->tx.txq_map[IEEE80211_AC_VO]->elem)); \ | ||
536 | if (len >= size) \ | ||
537 | goto done; \ | ||
538 | } while(0) | ||
539 | |||
540 | #define PRQLE(str, elem) \ | ||
541 | do { \ | ||
542 | len += snprintf(buf + len, size - len, \ | ||
543 | "%s%13i%11i%10i%10i\n", str, \ | ||
544 | list_empty(&sc->tx.txq_map[IEEE80211_AC_BE]->elem), \ | ||
545 | list_empty(&sc->tx.txq_map[IEEE80211_AC_BK]->elem), \ | ||
546 | list_empty(&sc->tx.txq_map[IEEE80211_AC_VI]->elem), \ | ||
547 | list_empty(&sc->tx.txq_map[IEEE80211_AC_VO]->elem)); \ | ||
548 | if (len >= size) \ | ||
549 | goto done; \ | ||
550 | } while (0) | ||
551 | |||
552 | static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | 515 | static ssize_t read_file_xmit(struct file *file, char __user *user_buf, |
553 | size_t count, loff_t *ppos) | 516 | size_t count, loff_t *ppos) |
554 | { | 517 | { |
555 | struct ath_softc *sc = file->private_data; | 518 | struct ath_softc *sc = file->private_data; |
556 | char *buf; | 519 | char *buf; |
557 | unsigned int len = 0, size = 8000; | 520 | unsigned int len = 0, size = 2048; |
558 | int i; | ||
559 | ssize_t retval = 0; | 521 | ssize_t retval = 0; |
560 | char tmp[32]; | ||
561 | 522 | ||
562 | buf = kzalloc(size, GFP_KERNEL); | 523 | buf = kzalloc(size, GFP_KERNEL); |
563 | if (buf == NULL) | 524 | if (buf == NULL) |
564 | return -ENOMEM; | 525 | return -ENOMEM; |
565 | 526 | ||
566 | len += sprintf(buf, "Num-Tx-Queues: %i tx-queues-setup: 0x%x" | 527 | len += sprintf(buf, "%30s %10s%10s%10s\n\n", |
567 | " poll-work-seen: %u\n" | ||
568 | "%30s %10s%10s%10s\n\n", | ||
569 | ATH9K_NUM_TX_QUEUES, sc->tx.txqsetup, | ||
570 | sc->tx_complete_poll_work_seen, | ||
571 | "BE", "BK", "VI", "VO"); | 528 | "BE", "BK", "VI", "VO"); |
572 | 529 | ||
573 | PR("MPDUs Queued: ", queued); | 530 | PR("MPDUs Queued: ", queued); |
@@ -587,62 +544,11 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | |||
587 | PR("DELIM Underrun: ", delim_underrun); | 544 | PR("DELIM Underrun: ", delim_underrun); |
588 | PR("TX-Pkts-All: ", tx_pkts_all); | 545 | PR("TX-Pkts-All: ", tx_pkts_all); |
589 | PR("TX-Bytes-All: ", tx_bytes_all); | 546 | PR("TX-Bytes-All: ", tx_bytes_all); |
590 | PR("hw-put-tx-buf: ", puttxbuf); | 547 | PR("HW-put-tx-buf: ", puttxbuf); |
591 | PR("hw-tx-start: ", txstart); | 548 | PR("HW-tx-start: ", txstart); |
592 | PR("hw-tx-proc-desc: ", txprocdesc); | 549 | PR("HW-tx-proc-desc: ", txprocdesc); |
593 | PR("TX-Failed: ", txfailed); | 550 | PR("TX-Failed: ", txfailed); |
594 | len += snprintf(buf + len, size - len, | ||
595 | "%s%11p%11p%10p%10p\n", "txq-memory-address:", | ||
596 | sc->tx.txq_map[IEEE80211_AC_BE], | ||
597 | sc->tx.txq_map[IEEE80211_AC_BK], | ||
598 | sc->tx.txq_map[IEEE80211_AC_VI], | ||
599 | sc->tx.txq_map[IEEE80211_AC_VO]); | ||
600 | if (len >= size) | ||
601 | goto done; | ||
602 | |||
603 | PRX("axq-qnum: ", axq_qnum); | ||
604 | PRX("axq-depth: ", axq_depth); | ||
605 | PRX("axq-ampdu_depth: ", axq_ampdu_depth); | ||
606 | PRX("axq-stopped ", stopped); | ||
607 | PRX("tx-in-progress ", axq_tx_inprogress); | ||
608 | PRX("pending-frames ", pending_frames); | ||
609 | PRX("txq_headidx: ", txq_headidx); | ||
610 | PRX("txq_tailidx: ", txq_headidx); | ||
611 | |||
612 | PRQLE("axq_q empty: ", axq_q); | ||
613 | PRQLE("axq_acq empty: ", axq_acq); | ||
614 | for (i = 0; i < ATH_TXFIFO_DEPTH; i++) { | ||
615 | snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i); | ||
616 | PRQLE(tmp, txq_fifo[i]); | ||
617 | } | ||
618 | |||
619 | /* Print out more detailed queue-info */ | ||
620 | for (i = 0; i <= IEEE80211_AC_BK; i++) { | ||
621 | struct ath_txq *txq = &(sc->tx.txq[i]); | ||
622 | struct ath_atx_ac *ac; | ||
623 | struct ath_atx_tid *tid; | ||
624 | if (len >= size) | ||
625 | goto done; | ||
626 | spin_lock_bh(&txq->axq_lock); | ||
627 | if (!list_empty(&txq->axq_acq)) { | ||
628 | ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, | ||
629 | list); | ||
630 | len += snprintf(buf + len, size - len, | ||
631 | "txq[%i] first-ac: %p sched: %i\n", | ||
632 | i, ac, ac->sched); | ||
633 | if (list_empty(&ac->tid_q) || (len >= size)) | ||
634 | goto done_for; | ||
635 | tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, | ||
636 | list); | ||
637 | len += snprintf(buf + len, size - len, | ||
638 | " first-tid: %p sched: %i paused: %i\n", | ||
639 | tid, tid->sched, tid->paused); | ||
640 | } | ||
641 | done_for: | ||
642 | spin_unlock_bh(&txq->axq_lock); | ||
643 | } | ||
644 | 551 | ||
645 | done: | ||
646 | if (len > size) | 552 | if (len > size) |
647 | len = size; | 553 | len = size; |
648 | 554 | ||
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 61341cda1313..f9bee18de5a0 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -179,6 +179,21 @@ struct ath_tx_stats { | |||
179 | u32 txfailed; | 179 | u32 txfailed; |
180 | }; | 180 | }; |
181 | 181 | ||
182 | /* | ||
183 | * Various utility macros to print TX/Queue counters. | ||
184 | */ | ||
185 | #define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum | ||
186 | #define TXSTATS sc->debug.stats.txstats | ||
187 | #define PR(str, elem) \ | ||
188 | do { \ | ||
189 | len += snprintf(buf + len, size - len, \ | ||
190 | "%s%13u%11u%10u%10u\n", str, \ | ||
191 | TXSTATS[PR_QNUM(IEEE80211_AC_BE)].elem, \ | ||
192 | TXSTATS[PR_QNUM(IEEE80211_AC_BK)].elem, \ | ||
193 | TXSTATS[PR_QNUM(IEEE80211_AC_VI)].elem, \ | ||
194 | TXSTATS[PR_QNUM(IEEE80211_AC_VO)].elem); \ | ||
195 | } while(0) | ||
196 | |||
182 | #define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++) | 197 | #define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++) |
183 | 198 | ||
184 | /** | 199 | /** |
@@ -227,7 +242,7 @@ struct ath_rx_stats { | |||
227 | 242 | ||
228 | struct ath_stats { | 243 | struct ath_stats { |
229 | struct ath_interrupt_stats istats; | 244 | struct ath_interrupt_stats istats; |
230 | struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; | 245 | struct ath_tx_stats txstats[IEEE80211_NUM_ACS]; |
231 | struct ath_rx_stats rxstats; | 246 | struct ath_rx_stats rxstats; |
232 | struct ath_dfs_stats dfs_stats; | 247 | struct ath_dfs_stats dfs_stats; |
233 | u32 reset[__RESET_TYPE_MAX]; | 248 | u32 reset[__RESET_TYPE_MAX]; |
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index 227fdb814817..fc6b075ad635 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -27,9 +27,6 @@ void ath_tx_complete_poll_work(struct work_struct *work) | |||
27 | struct ath_txq *txq; | 27 | struct ath_txq *txq; |
28 | int i; | 28 | int i; |
29 | bool needreset = false; | 29 | bool needreset = false; |
30 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
31 | sc->tx_complete_poll_work_seen++; | ||
32 | #endif | ||
33 | 30 | ||
34 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | 31 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
35 | if (ATH_TXQ_SETUP(sc, i)) { | 32 | if (ATH_TXQ_SETUP(sc, i)) { |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index f8b3cacaeace..6a809bfd5aa5 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1953,7 +1953,6 @@ static int ath9k_get_et_sset_count(struct ieee80211_hw *hw, | |||
1953 | return 0; | 1953 | return 0; |
1954 | } | 1954 | } |
1955 | 1955 | ||
1956 | #define PR_QNUM(_n) (sc->tx.txq_map[_n]->axq_qnum) | ||
1957 | #define AWDATA(elem) \ | 1956 | #define AWDATA(elem) \ |
1958 | do { \ | 1957 | do { \ |
1959 | data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \ | 1958 | data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \ |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index ae7f2897c1a3..34130943f9de 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2319,6 +2319,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2319 | 2319 | ||
2320 | ath_txq_lock(sc, txq); | 2320 | ath_txq_lock(sc, txq); |
2321 | 2321 | ||
2322 | TX_STAT_INC(txq->axq_qnum, txprocdesc); | ||
2323 | |||
2322 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { | 2324 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { |
2323 | ath_txq_unlock(sc, txq); | 2325 | ath_txq_unlock(sc, txq); |
2324 | return; | 2326 | return; |