diff options
author | Jouni Malinen <jouni@qca.qualcomm.com> | 2011-10-11 10:31:53 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2011-11-11 05:50:56 -0500 |
commit | e8091281f588812b128e102307e13acd9e917a5b (patch) | |
tree | 6290a4d46c05771be873d9a4c25c93907048e949 /drivers/net | |
parent | 6981ffdc2f5d59aac75c8446363c474e33f18b31 (diff) |
ath6kl: Add endpoint_stats debugfs file
This file can be used to fetch endpoint statistics counters and
to clear them by writing 0 to it.
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/debug.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index ba3f23d71150..b9bf28d72844 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c | |||
@@ -595,6 +595,105 @@ static const struct file_operations fops_credit_dist_stats = { | |||
595 | .llseek = default_llseek, | 595 | .llseek = default_llseek, |
596 | }; | 596 | }; |
597 | 597 | ||
598 | static unsigned int print_endpoint_stat(struct htc_target *target, char *buf, | ||
599 | unsigned int buf_len, unsigned int len, | ||
600 | int offset, const char *name) | ||
601 | { | ||
602 | int i; | ||
603 | struct htc_endpoint_stats *ep_st; | ||
604 | u32 *counter; | ||
605 | |||
606 | len += scnprintf(buf + len, buf_len - len, "%s:", name); | ||
607 | for (i = 0; i < ENDPOINT_MAX; i++) { | ||
608 | ep_st = &target->endpoint[i].ep_st; | ||
609 | counter = ((u32 *) ep_st) + (offset / 4); | ||
610 | len += scnprintf(buf + len, buf_len - len, " %u", *counter); | ||
611 | } | ||
612 | len += scnprintf(buf + len, buf_len - len, "\n"); | ||
613 | |||
614 | return len; | ||
615 | } | ||
616 | |||
617 | static ssize_t ath6kl_endpoint_stats_read(struct file *file, | ||
618 | char __user *user_buf, | ||
619 | size_t count, loff_t *ppos) | ||
620 | { | ||
621 | struct ath6kl *ar = file->private_data; | ||
622 | struct htc_target *target = ar->htc_target; | ||
623 | char *buf; | ||
624 | unsigned int buf_len, len = 0; | ||
625 | ssize_t ret_cnt; | ||
626 | |||
627 | buf_len = 1000 + ENDPOINT_MAX * 100; | ||
628 | buf = kzalloc(buf_len, GFP_KERNEL); | ||
629 | if (!buf) | ||
630 | return -ENOMEM; | ||
631 | |||
632 | #define EPSTAT(name) \ | ||
633 | len = print_endpoint_stat(target, buf, buf_len, len, \ | ||
634 | offsetof(struct htc_endpoint_stats, name), \ | ||
635 | #name) | ||
636 | EPSTAT(cred_low_indicate); | ||
637 | EPSTAT(tx_issued); | ||
638 | EPSTAT(tx_pkt_bundled); | ||
639 | EPSTAT(tx_bundles); | ||
640 | EPSTAT(tx_dropped); | ||
641 | EPSTAT(tx_cred_rpt); | ||
642 | EPSTAT(cred_rpt_from_rx); | ||
643 | EPSTAT(cred_rpt_ep0); | ||
644 | EPSTAT(cred_from_rx); | ||
645 | EPSTAT(cred_from_other); | ||
646 | EPSTAT(cred_from_ep0); | ||
647 | EPSTAT(cred_cosumd); | ||
648 | EPSTAT(cred_retnd); | ||
649 | EPSTAT(rx_pkts); | ||
650 | EPSTAT(rx_lkahds); | ||
651 | EPSTAT(rx_bundl); | ||
652 | EPSTAT(rx_bundle_lkahd); | ||
653 | EPSTAT(rx_bundle_from_hdr); | ||
654 | EPSTAT(rx_alloc_thresh_hit); | ||
655 | EPSTAT(rxalloc_thresh_byte); | ||
656 | #undef EPSTAT | ||
657 | |||
658 | if (len > buf_len) | ||
659 | len = buf_len; | ||
660 | |||
661 | ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
662 | kfree(buf); | ||
663 | return ret_cnt; | ||
664 | } | ||
665 | |||
666 | static ssize_t ath6kl_endpoint_stats_write(struct file *file, | ||
667 | const char __user *user_buf, | ||
668 | size_t count, loff_t *ppos) | ||
669 | { | ||
670 | struct ath6kl *ar = file->private_data; | ||
671 | struct htc_target *target = ar->htc_target; | ||
672 | int ret, i; | ||
673 | u32 val; | ||
674 | struct htc_endpoint_stats *ep_st; | ||
675 | |||
676 | ret = kstrtou32_from_user(user_buf, count, 0, &val); | ||
677 | if (ret) | ||
678 | return ret; | ||
679 | if (val == 0) { | ||
680 | for (i = 0; i < ENDPOINT_MAX; i++) { | ||
681 | ep_st = &target->endpoint[i].ep_st; | ||
682 | memset(ep_st, 0, sizeof(*ep_st)); | ||
683 | } | ||
684 | } | ||
685 | |||
686 | return count; | ||
687 | } | ||
688 | |||
689 | static const struct file_operations fops_endpoint_stats = { | ||
690 | .open = ath6kl_debugfs_open, | ||
691 | .read = ath6kl_endpoint_stats_read, | ||
692 | .write = ath6kl_endpoint_stats_write, | ||
693 | .owner = THIS_MODULE, | ||
694 | .llseek = default_llseek, | ||
695 | }; | ||
696 | |||
598 | static unsigned long ath6kl_get_num_reg(void) | 697 | static unsigned long ath6kl_get_num_reg(void) |
599 | { | 698 | { |
600 | int i; | 699 | int i; |
@@ -901,6 +1000,9 @@ int ath6kl_debug_init(struct ath6kl *ar) | |||
901 | debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar, | 1000 | debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar, |
902 | &fops_credit_dist_stats); | 1001 | &fops_credit_dist_stats); |
903 | 1002 | ||
1003 | debugfs_create_file("endpoint_stats", S_IRUSR | S_IWUSR, | ||
1004 | ar->debugfs_phy, ar, &fops_endpoint_stats); | ||
1005 | |||
904 | debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar, | 1006 | debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar, |
905 | &fops_fwlog); | 1007 | &fops_fwlog); |
906 | 1008 | ||