dhd_dbg.c revision 81f5dcb8083077ca9bca10ca8e34bc8daf768dce
1/* 2 * Copyright (c) 2012 Broadcom Corporation 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16#include <linux/debugfs.h> 17#include <linux/if_ether.h> 18#include <linux/if.h> 19#include <linux/ieee80211.h> 20#include <linux/module.h> 21#include <linux/netdevice.h> 22 23#include <defs.h> 24#include <brcmu_wifi.h> 25#include <brcmu_utils.h> 26#include "dhd.h" 27#include "dhd_bus.h" 28#include "dhd_dbg.h" 29 30static struct dentry *root_folder; 31 32void brcmf_debugfs_init(void) 33{ 34 root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL); 35 if (IS_ERR(root_folder)) 36 root_folder = NULL; 37} 38 39void brcmf_debugfs_exit(void) 40{ 41 if (!root_folder) 42 return; 43 44 debugfs_remove_recursive(root_folder); 45 root_folder = NULL; 46} 47 48int brcmf_debugfs_attach(struct brcmf_pub *drvr) 49{ 50 if (!root_folder) 51 return -ENODEV; 52 53 drvr->dbgfs_dir = debugfs_create_dir(dev_name(drvr->dev), root_folder); 54 return PTR_RET(drvr->dbgfs_dir); 55} 56 57void brcmf_debugfs_detach(struct brcmf_pub *drvr) 58{ 59 if (!IS_ERR_OR_NULL(drvr->dbgfs_dir)) 60 debugfs_remove_recursive(drvr->dbgfs_dir); 61} 62 63struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) 64{ 65 return drvr->dbgfs_dir; 66} 67 68static 69ssize_t brcmf_debugfs_sdio_counter_read(struct file *f, char __user *data, 70 size_t count, loff_t *ppos) 71{ 72 struct brcmf_sdio_count *sdcnt = f->private_data; 73 char buf[750]; 74 int res; 75 76 /* only allow read from start */ 77 if (*ppos > 0) 78 return 0; 79 80 res = scnprintf(buf, sizeof(buf), 81 "intrcount: %u\nlastintrs: %u\n" 82 "pollcnt: %u\nregfails: %u\n" 83 "tx_sderrs: %u\nfcqueued: %u\n" 84 "rxrtx: %u\nrx_toolong: %u\n" 85 "rxc_errors: %u\nrx_hdrfail: %u\n" 86 "rx_badhdr: %u\nrx_badseq: %u\n" 87 "fc_rcvd: %u\nfc_xoff: %u\n" 88 "fc_xon: %u\nrxglomfail: %u\n" 89 "rxglomframes: %u\nrxglompkts: %u\n" 90 "f2rxhdrs: %u\nf2rxdata: %u\n" 91 "f2txdata: %u\nf1regdata: %u\n" 92 "tickcnt: %u\ntx_ctlerrs: %lu\n" 93 "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n" 94 "rx_ctlpkts: %lu\nrx_readahead: %lu\n", 95 sdcnt->intrcount, sdcnt->lastintrs, 96 sdcnt->pollcnt, sdcnt->regfails, 97 sdcnt->tx_sderrs, sdcnt->fcqueued, 98 sdcnt->rxrtx, sdcnt->rx_toolong, 99 sdcnt->rxc_errors, sdcnt->rx_hdrfail, 100 sdcnt->rx_badhdr, sdcnt->rx_badseq, 101 sdcnt->fc_rcvd, sdcnt->fc_xoff, 102 sdcnt->fc_xon, sdcnt->rxglomfail, 103 sdcnt->rxglomframes, sdcnt->rxglompkts, 104 sdcnt->f2rxhdrs, sdcnt->f2rxdata, 105 sdcnt->f2txdata, sdcnt->f1regdata, 106 sdcnt->tickcnt, sdcnt->tx_ctlerrs, 107 sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs, 108 sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt); 109 110 return simple_read_from_buffer(data, count, ppos, buf, res); 111} 112 113static const struct file_operations brcmf_debugfs_sdio_counter_ops = { 114 .owner = THIS_MODULE, 115 .open = simple_open, 116 .read = brcmf_debugfs_sdio_counter_read 117}; 118 119void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, 120 struct brcmf_sdio_count *sdcnt) 121{ 122 struct dentry *dentry = drvr->dbgfs_dir; 123 124 if (!IS_ERR_OR_NULL(dentry)) 125 debugfs_create_file("counters", S_IRUGO, dentry, 126 sdcnt, &brcmf_debugfs_sdio_counter_ops); 127} 128