brcmfmac: make use of seq_file API for debugfs entries
[deliverable/linux.git] / drivers / net / wireless / brcm80211 / brcmfmac / dhd_dbg.c
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/netdevice.h>
18 #include <linux/module.h>
19
20 #include <brcmu_wifi.h>
21 #include <brcmu_utils.h>
22 #include "dhd.h"
23 #include "dhd_bus.h"
24 #include "dhd_dbg.h"
25
26 static struct dentry *root_folder;
27
28 void brcmf_debugfs_init(void)
29 {
30 root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
31 if (IS_ERR(root_folder))
32 root_folder = NULL;
33 }
34
35 void brcmf_debugfs_exit(void)
36 {
37 if (!root_folder)
38 return;
39
40 debugfs_remove_recursive(root_folder);
41 root_folder = NULL;
42 }
43
44 static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data)
45 {
46 struct brcmf_pub *drvr = seq->private;
47 struct brcmf_bus *bus = drvr->bus_if;
48
49 seq_printf(seq, "chip: %x(%u) rev %u\n",
50 bus->chip, bus->chip, bus->chiprev);
51 return 0;
52 }
53
54 static int brcmf_debugfs_chipinfo_open(struct inode *inode, struct file *f)
55 {
56 return single_open(f, brcmf_debugfs_chipinfo_read, inode->i_private);
57 }
58
59 static const struct file_operations brcmf_debugfs_chipinfo_ops = {
60 .owner = THIS_MODULE,
61 .open = brcmf_debugfs_chipinfo_open,
62 .release = single_release,
63 .read = seq_read,
64 .llseek = seq_lseek
65 };
66
67 static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr)
68 {
69 struct dentry *dentry = drvr->dbgfs_dir;
70
71 if (!IS_ERR_OR_NULL(dentry))
72 debugfs_create_file("chipinfo", S_IRUGO, dentry, drvr,
73 &brcmf_debugfs_chipinfo_ops);
74 return 0;
75 }
76
77 int brcmf_debugfs_attach(struct brcmf_pub *drvr)
78 {
79 struct device *dev = drvr->bus_if->dev;
80
81 if (!root_folder)
82 return -ENODEV;
83
84 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
85 brcmf_debugfs_create_chipinfo(drvr);
86 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
87 }
88
89 void brcmf_debugfs_detach(struct brcmf_pub *drvr)
90 {
91 if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
92 debugfs_remove_recursive(drvr->dbgfs_dir);
93 }
94
95 struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr)
96 {
97 return drvr->dbgfs_dir;
98 }
99
100 static int brcmf_debugfs_sdio_count_read(struct seq_file *seq, void *data)
101 {
102 struct brcmf_sdio_count *sdcnt = seq->private;
103
104 seq_printf(seq,
105 "intrcount: %u\nlastintrs: %u\n"
106 "pollcnt: %u\nregfails: %u\n"
107 "tx_sderrs: %u\nfcqueued: %u\n"
108 "rxrtx: %u\nrx_toolong: %u\n"
109 "rxc_errors: %u\nrx_hdrfail: %u\n"
110 "rx_badhdr: %u\nrx_badseq: %u\n"
111 "fc_rcvd: %u\nfc_xoff: %u\n"
112 "fc_xon: %u\nrxglomfail: %u\n"
113 "rxglomframes: %u\nrxglompkts: %u\n"
114 "f2rxhdrs: %u\nf2rxdata: %u\n"
115 "f2txdata: %u\nf1regdata: %u\n"
116 "tickcnt: %u\ntx_ctlerrs: %lu\n"
117 "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n"
118 "rx_ctlpkts: %lu\nrx_readahead: %lu\n",
119 sdcnt->intrcount, sdcnt->lastintrs,
120 sdcnt->pollcnt, sdcnt->regfails,
121 sdcnt->tx_sderrs, sdcnt->fcqueued,
122 sdcnt->rxrtx, sdcnt->rx_toolong,
123 sdcnt->rxc_errors, sdcnt->rx_hdrfail,
124 sdcnt->rx_badhdr, sdcnt->rx_badseq,
125 sdcnt->fc_rcvd, sdcnt->fc_xoff,
126 sdcnt->fc_xon, sdcnt->rxglomfail,
127 sdcnt->rxglomframes, sdcnt->rxglompkts,
128 sdcnt->f2rxhdrs, sdcnt->f2rxdata,
129 sdcnt->f2txdata, sdcnt->f1regdata,
130 sdcnt->tickcnt, sdcnt->tx_ctlerrs,
131 sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs,
132 sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt);
133
134 return 0;
135 }
136
137 static int brcmf_debugfs_sdio_count_open(struct inode *inode, struct file *f)
138 {
139 return single_open(f, brcmf_debugfs_sdio_count_read, inode->i_private);
140 }
141
142 static const struct file_operations brcmf_debugfs_sdio_counter_ops = {
143 .owner = THIS_MODULE,
144 .open = brcmf_debugfs_sdio_count_open,
145 .release = single_release,
146 .read = seq_read,
147 .llseek = seq_lseek
148 };
149
150 void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
151 struct brcmf_sdio_count *sdcnt)
152 {
153 struct dentry *dentry = drvr->dbgfs_dir;
154
155 if (!IS_ERR_OR_NULL(dentry))
156 debugfs_create_file("counters", S_IRUGO, dentry,
157 sdcnt, &brcmf_debugfs_sdio_counter_ops);
158 }
159
160 static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data)
161 {
162 struct brcmf_fws_stats *fwstats = seq->private;
163
164 seq_printf(seq,
165 "header_pulls: %u\n"
166 "header_only_pkt: %u\n"
167 "tlv_parse_failed: %u\n"
168 "tlv_invalid_type: %u\n"
169 "mac_update_fails: %u\n"
170 "ps_update_fails: %u\n"
171 "if_update_fails: %u\n"
172 "pkt2bus: %u\n"
173 "generic_error: %u\n"
174 "rollback_success: %u\n"
175 "rollback_failed: %u\n"
176 "delayq_full: %u\n"
177 "supprq_full: %u\n"
178 "txs_indicate: %u\n"
179 "txs_discard: %u\n"
180 "txs_suppr_core: %u\n"
181 "txs_suppr_ps: %u\n"
182 "txs_tossed: %u\n"
183 "txs_host_tossed: %u\n"
184 "bus_flow_block: %u\n"
185 "fws_flow_block: %u\n"
186 "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
187 "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
188 fwstats->header_pulls,
189 fwstats->header_only_pkt,
190 fwstats->tlv_parse_failed,
191 fwstats->tlv_invalid_type,
192 fwstats->mac_update_failed,
193 fwstats->mac_ps_update_failed,
194 fwstats->if_update_failed,
195 fwstats->pkt2bus,
196 fwstats->generic_error,
197 fwstats->rollback_success,
198 fwstats->rollback_failed,
199 fwstats->delayq_full_error,
200 fwstats->supprq_full_error,
201 fwstats->txs_indicate,
202 fwstats->txs_discard,
203 fwstats->txs_supp_core,
204 fwstats->txs_supp_ps,
205 fwstats->txs_tossed,
206 fwstats->txs_host_tossed,
207 fwstats->bus_flow_block,
208 fwstats->fws_flow_block,
209 fwstats->send_pkts[0], fwstats->send_pkts[1],
210 fwstats->send_pkts[2], fwstats->send_pkts[3],
211 fwstats->send_pkts[4],
212 fwstats->requested_sent[0],
213 fwstats->requested_sent[1],
214 fwstats->requested_sent[2],
215 fwstats->requested_sent[3],
216 fwstats->requested_sent[4]);
217
218 return 0;
219 }
220
221 static int brcmf_debugfs_fws_stats_open(struct inode *inode, struct file *f)
222 {
223 return single_open(f, brcmf_debugfs_fws_stats_read, inode->i_private);
224 }
225
226 static const struct file_operations brcmf_debugfs_fws_stats_ops = {
227 .owner = THIS_MODULE,
228 .open = brcmf_debugfs_fws_stats_open,
229 .release = single_release,
230 .read = seq_read,
231 .llseek = seq_lseek
232 };
233
234 void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
235 struct brcmf_fws_stats *stats)
236 {
237 struct dentry *dentry = drvr->dbgfs_dir;
238
239 if (!IS_ERR_OR_NULL(dentry))
240 debugfs_create_file("fws_stats", S_IRUGO, dentry,
241 stats, &brcmf_debugfs_fws_stats_ops);
242 }
This page took 0.055308 seconds and 5 git commands to generate.