Commit | Line | Data |
---|---|---|
d319a7cf AS |
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> | |
1d4fd8d7 | 17 | #include <linux/netdevice.h> |
80969836 | 18 | #include <linux/module.h> |
d319a7cf | 19 | |
d319a7cf AS |
20 | #include <brcmu_wifi.h> |
21 | #include <brcmu_utils.h> | |
22 | #include "dhd.h" | |
d9cb2596 | 23 | #include "dhd_bus.h" |
80969836 | 24 | #include "dhd_dbg.h" |
e5483576 | 25 | #include "tracepoint.h" |
d319a7cf AS |
26 | |
27 | static struct dentry *root_folder; | |
28 | ||
29 | void brcmf_debugfs_init(void) | |
30 | { | |
31 | root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL); | |
32 | if (IS_ERR(root_folder)) | |
33 | root_folder = NULL; | |
34 | } | |
35 | ||
36 | void brcmf_debugfs_exit(void) | |
37 | { | |
38 | if (!root_folder) | |
39 | return; | |
40 | ||
41 | debugfs_remove_recursive(root_folder); | |
42 | root_folder = NULL; | |
43 | } | |
44 | ||
45 | int brcmf_debugfs_attach(struct brcmf_pub *drvr) | |
46 | { | |
d9cb2596 AS |
47 | struct device *dev = drvr->bus_if->dev; |
48 | ||
d319a7cf AS |
49 | if (!root_folder) |
50 | return -ENODEV; | |
51 | ||
d9cb2596 | 52 | drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); |
8c6ffba0 | 53 | return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); |
d319a7cf AS |
54 | } |
55 | ||
56 | void brcmf_debugfs_detach(struct brcmf_pub *drvr) | |
57 | { | |
58 | if (!IS_ERR_OR_NULL(drvr->dbgfs_dir)) | |
59 | debugfs_remove_recursive(drvr->dbgfs_dir); | |
60 | } | |
61 | ||
62 | struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) | |
63 | { | |
64 | return drvr->dbgfs_dir; | |
65 | } | |
80969836 AS |
66 | |
67 | static | |
68 | ssize_t brcmf_debugfs_sdio_counter_read(struct file *f, char __user *data, | |
69 | size_t count, loff_t *ppos) | |
70 | { | |
71 | struct brcmf_sdio_count *sdcnt = f->private_data; | |
72 | char buf[750]; | |
73 | int res; | |
74 | ||
75 | /* only allow read from start */ | |
76 | if (*ppos > 0) | |
77 | return 0; | |
78 | ||
79 | res = scnprintf(buf, sizeof(buf), | |
80 | "intrcount: %u\nlastintrs: %u\n" | |
81 | "pollcnt: %u\nregfails: %u\n" | |
82 | "tx_sderrs: %u\nfcqueued: %u\n" | |
83 | "rxrtx: %u\nrx_toolong: %u\n" | |
84 | "rxc_errors: %u\nrx_hdrfail: %u\n" | |
85 | "rx_badhdr: %u\nrx_badseq: %u\n" | |
86 | "fc_rcvd: %u\nfc_xoff: %u\n" | |
87 | "fc_xon: %u\nrxglomfail: %u\n" | |
88 | "rxglomframes: %u\nrxglompkts: %u\n" | |
89 | "f2rxhdrs: %u\nf2rxdata: %u\n" | |
90 | "f2txdata: %u\nf1regdata: %u\n" | |
91 | "tickcnt: %u\ntx_ctlerrs: %lu\n" | |
92 | "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n" | |
93 | "rx_ctlpkts: %lu\nrx_readahead: %lu\n", | |
94 | sdcnt->intrcount, sdcnt->lastintrs, | |
95 | sdcnt->pollcnt, sdcnt->regfails, | |
96 | sdcnt->tx_sderrs, sdcnt->fcqueued, | |
97 | sdcnt->rxrtx, sdcnt->rx_toolong, | |
98 | sdcnt->rxc_errors, sdcnt->rx_hdrfail, | |
99 | sdcnt->rx_badhdr, sdcnt->rx_badseq, | |
100 | sdcnt->fc_rcvd, sdcnt->fc_xoff, | |
101 | sdcnt->fc_xon, sdcnt->rxglomfail, | |
102 | sdcnt->rxglomframes, sdcnt->rxglompkts, | |
103 | sdcnt->f2rxhdrs, sdcnt->f2rxdata, | |
104 | sdcnt->f2txdata, sdcnt->f1regdata, | |
105 | sdcnt->tickcnt, sdcnt->tx_ctlerrs, | |
106 | sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs, | |
107 | sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt); | |
108 | ||
109 | return simple_read_from_buffer(data, count, ppos, buf, res); | |
110 | } | |
111 | ||
112 | static const struct file_operations brcmf_debugfs_sdio_counter_ops = { | |
113 | .owner = THIS_MODULE, | |
114 | .open = simple_open, | |
115 | .read = brcmf_debugfs_sdio_counter_read | |
116 | }; | |
117 | ||
118 | void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, | |
119 | struct brcmf_sdio_count *sdcnt) | |
120 | { | |
121 | struct dentry *dentry = drvr->dbgfs_dir; | |
122 | ||
123 | if (!IS_ERR_OR_NULL(dentry)) | |
124 | debugfs_create_file("counters", S_IRUGO, dentry, | |
125 | sdcnt, &brcmf_debugfs_sdio_counter_ops); | |
126 | } | |
349e7104 AS |
127 | |
128 | static | |
129 | ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data, | |
130 | size_t count, loff_t *ppos) | |
131 | { | |
132 | struct brcmf_fws_stats *fwstats = f->private_data; | |
84bcc0c3 | 133 | char buf[650]; |
349e7104 AS |
134 | int res; |
135 | ||
136 | /* only allow read from start */ | |
137 | if (*ppos > 0) | |
138 | return 0; | |
139 | ||
140 | res = scnprintf(buf, sizeof(buf), | |
3edc1cff AS |
141 | "header_pulls: %u\n" |
142 | "header_only_pkt: %u\n" | |
143 | "tlv_parse_failed: %u\n" | |
144 | "tlv_invalid_type: %u\n" | |
145 | "mac_update_fails: %u\n" | |
33753d47 AS |
146 | "ps_update_fails: %u\n" |
147 | "if_update_fails: %u\n" | |
3edc1cff AS |
148 | "pkt2bus: %u\n" |
149 | "generic_error: %u\n" | |
84bcc0c3 AS |
150 | "rollback_success: %u\n" |
151 | "rollback_failed: %u\n" | |
152 | "delayq_full: %u\n" | |
153 | "supprq_full: %u\n" | |
3edc1cff AS |
154 | "txs_indicate: %u\n" |
155 | "txs_discard: %u\n" | |
156 | "txs_suppr_core: %u\n" | |
157 | "txs_suppr_ps: %u\n" | |
158 | "txs_tossed: %u\n" | |
5631becb AS |
159 | "txs_host_tossed: %u\n" |
160 | "bus_flow_block: %u\n" | |
161 | "fws_flow_block: %u\n" | |
84bcc0c3 | 162 | "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n" |
5631becb | 163 | "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n", |
349e7104 AS |
164 | fwstats->header_pulls, |
165 | fwstats->header_only_pkt, | |
166 | fwstats->tlv_parse_failed, | |
ce814c1b | 167 | fwstats->tlv_invalid_type, |
3edc1cff | 168 | fwstats->mac_update_failed, |
33753d47 AS |
169 | fwstats->mac_ps_update_failed, |
170 | fwstats->if_update_failed, | |
3edc1cff AS |
171 | fwstats->pkt2bus, |
172 | fwstats->generic_error, | |
84bcc0c3 AS |
173 | fwstats->rollback_success, |
174 | fwstats->rollback_failed, | |
175 | fwstats->delayq_full_error, | |
176 | fwstats->supprq_full_error, | |
3edc1cff AS |
177 | fwstats->txs_indicate, |
178 | fwstats->txs_discard, | |
179 | fwstats->txs_supp_core, | |
180 | fwstats->txs_supp_ps, | |
181 | fwstats->txs_tossed, | |
5631becb AS |
182 | fwstats->txs_host_tossed, |
183 | fwstats->bus_flow_block, | |
184 | fwstats->fws_flow_block, | |
3edc1cff AS |
185 | fwstats->send_pkts[0], fwstats->send_pkts[1], |
186 | fwstats->send_pkts[2], fwstats->send_pkts[3], | |
84bcc0c3 | 187 | fwstats->send_pkts[4], |
fa587d4b HM |
188 | fwstats->requested_sent[0], |
189 | fwstats->requested_sent[1], | |
190 | fwstats->requested_sent[2], | |
191 | fwstats->requested_sent[3], | |
192 | fwstats->requested_sent[4]); | |
349e7104 AS |
193 | |
194 | return simple_read_from_buffer(data, count, ppos, buf, res); | |
195 | } | |
196 | ||
197 | static const struct file_operations brcmf_debugfs_fws_stats_ops = { | |
198 | .owner = THIS_MODULE, | |
199 | .open = simple_open, | |
200 | .read = brcmf_debugfs_fws_stats_read | |
201 | }; | |
202 | ||
203 | void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr, | |
204 | struct brcmf_fws_stats *stats) | |
205 | { | |
206 | struct dentry *dentry = drvr->dbgfs_dir; | |
207 | ||
208 | if (!IS_ERR_OR_NULL(dentry)) | |
209 | debugfs_create_file("fws_stats", S_IRUGO, dentry, | |
210 | stats, &brcmf_debugfs_fws_stats_ops); | |
211 | } |