2 * Copyright (c) 2012 Broadcom Corporation
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.
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.
16 #include <linux/debugfs.h>
17 #include <linux/netdevice.h>
18 #include <linux/module.h>
20 #include <brcmu_wifi.h>
21 #include <brcmu_utils.h>
26 static struct dentry
*root_folder
;
28 void brcmf_debugfs_init(void)
30 root_folder
= debugfs_create_dir(KBUILD_MODNAME
, NULL
);
31 if (IS_ERR(root_folder
))
35 void brcmf_debugfs_exit(void)
40 debugfs_remove_recursive(root_folder
);
45 ssize_t
brcmf_debugfs_chipinfo_read(struct file
*f
, char __user
*data
,
46 size_t count
, loff_t
*ppos
)
48 struct brcmf_pub
*drvr
= f
->private_data
;
49 struct brcmf_bus
*bus
= drvr
->bus_if
;
53 /* only allow read from start */
57 res
= scnprintf(buf
, sizeof(buf
), "chip: %x(%u) rev %u\n",
58 bus
->chip
, bus
->chip
, bus
->chiprev
);
59 return simple_read_from_buffer(data
, count
, ppos
, buf
, res
);
62 static const struct file_operations brcmf_debugfs_chipinfo_ops
= {
65 .read
= brcmf_debugfs_chipinfo_read
68 static int brcmf_debugfs_create_chipinfo(struct brcmf_pub
*drvr
)
70 struct dentry
*dentry
= drvr
->dbgfs_dir
;
72 if (!IS_ERR_OR_NULL(dentry
))
73 debugfs_create_file("chipinfo", S_IRUGO
, dentry
, drvr
,
74 &brcmf_debugfs_chipinfo_ops
);
78 int brcmf_debugfs_attach(struct brcmf_pub
*drvr
)
80 struct device
*dev
= drvr
->bus_if
->dev
;
85 drvr
->dbgfs_dir
= debugfs_create_dir(dev_name(dev
), root_folder
);
86 brcmf_debugfs_create_chipinfo(drvr
);
87 return PTR_ERR_OR_ZERO(drvr
->dbgfs_dir
);
90 void brcmf_debugfs_detach(struct brcmf_pub
*drvr
)
92 if (!IS_ERR_OR_NULL(drvr
->dbgfs_dir
))
93 debugfs_remove_recursive(drvr
->dbgfs_dir
);
96 struct dentry
*brcmf_debugfs_get_devdir(struct brcmf_pub
*drvr
)
98 return drvr
->dbgfs_dir
;
102 ssize_t
brcmf_debugfs_sdio_counter_read(struct file
*f
, char __user
*data
,
103 size_t count
, loff_t
*ppos
)
105 struct brcmf_sdio_count
*sdcnt
= f
->private_data
;
109 /* only allow read from start */
113 res
= scnprintf(buf
, sizeof(buf
),
114 "intrcount: %u\nlastintrs: %u\n"
115 "pollcnt: %u\nregfails: %u\n"
116 "tx_sderrs: %u\nfcqueued: %u\n"
117 "rxrtx: %u\nrx_toolong: %u\n"
118 "rxc_errors: %u\nrx_hdrfail: %u\n"
119 "rx_badhdr: %u\nrx_badseq: %u\n"
120 "fc_rcvd: %u\nfc_xoff: %u\n"
121 "fc_xon: %u\nrxglomfail: %u\n"
122 "rxglomframes: %u\nrxglompkts: %u\n"
123 "f2rxhdrs: %u\nf2rxdata: %u\n"
124 "f2txdata: %u\nf1regdata: %u\n"
125 "tickcnt: %u\ntx_ctlerrs: %lu\n"
126 "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n"
127 "rx_ctlpkts: %lu\nrx_readahead: %lu\n",
128 sdcnt
->intrcount
, sdcnt
->lastintrs
,
129 sdcnt
->pollcnt
, sdcnt
->regfails
,
130 sdcnt
->tx_sderrs
, sdcnt
->fcqueued
,
131 sdcnt
->rxrtx
, sdcnt
->rx_toolong
,
132 sdcnt
->rxc_errors
, sdcnt
->rx_hdrfail
,
133 sdcnt
->rx_badhdr
, sdcnt
->rx_badseq
,
134 sdcnt
->fc_rcvd
, sdcnt
->fc_xoff
,
135 sdcnt
->fc_xon
, sdcnt
->rxglomfail
,
136 sdcnt
->rxglomframes
, sdcnt
->rxglompkts
,
137 sdcnt
->f2rxhdrs
, sdcnt
->f2rxdata
,
138 sdcnt
->f2txdata
, sdcnt
->f1regdata
,
139 sdcnt
->tickcnt
, sdcnt
->tx_ctlerrs
,
140 sdcnt
->tx_ctlpkts
, sdcnt
->rx_ctlerrs
,
141 sdcnt
->rx_ctlpkts
, sdcnt
->rx_readahead_cnt
);
143 return simple_read_from_buffer(data
, count
, ppos
, buf
, res
);
146 static const struct file_operations brcmf_debugfs_sdio_counter_ops
= {
147 .owner
= THIS_MODULE
,
149 .read
= brcmf_debugfs_sdio_counter_read
152 void brcmf_debugfs_create_sdio_count(struct brcmf_pub
*drvr
,
153 struct brcmf_sdio_count
*sdcnt
)
155 struct dentry
*dentry
= drvr
->dbgfs_dir
;
157 if (!IS_ERR_OR_NULL(dentry
))
158 debugfs_create_file("counters", S_IRUGO
, dentry
,
159 sdcnt
, &brcmf_debugfs_sdio_counter_ops
);
163 ssize_t
brcmf_debugfs_fws_stats_read(struct file
*f
, char __user
*data
,
164 size_t count
, loff_t
*ppos
)
166 struct brcmf_fws_stats
*fwstats
= f
->private_data
;
170 /* only allow read from start */
174 res
= scnprintf(buf
, sizeof(buf
),
176 "header_only_pkt: %u\n"
177 "tlv_parse_failed: %u\n"
178 "tlv_invalid_type: %u\n"
179 "mac_update_fails: %u\n"
180 "ps_update_fails: %u\n"
181 "if_update_fails: %u\n"
183 "generic_error: %u\n"
184 "rollback_success: %u\n"
185 "rollback_failed: %u\n"
190 "txs_suppr_core: %u\n"
193 "txs_host_tossed: %u\n"
194 "bus_flow_block: %u\n"
195 "fws_flow_block: %u\n"
196 "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
197 "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
198 fwstats
->header_pulls
,
199 fwstats
->header_only_pkt
,
200 fwstats
->tlv_parse_failed
,
201 fwstats
->tlv_invalid_type
,
202 fwstats
->mac_update_failed
,
203 fwstats
->mac_ps_update_failed
,
204 fwstats
->if_update_failed
,
206 fwstats
->generic_error
,
207 fwstats
->rollback_success
,
208 fwstats
->rollback_failed
,
209 fwstats
->delayq_full_error
,
210 fwstats
->supprq_full_error
,
211 fwstats
->txs_indicate
,
212 fwstats
->txs_discard
,
213 fwstats
->txs_supp_core
,
214 fwstats
->txs_supp_ps
,
216 fwstats
->txs_host_tossed
,
217 fwstats
->bus_flow_block
,
218 fwstats
->fws_flow_block
,
219 fwstats
->send_pkts
[0], fwstats
->send_pkts
[1],
220 fwstats
->send_pkts
[2], fwstats
->send_pkts
[3],
221 fwstats
->send_pkts
[4],
222 fwstats
->requested_sent
[0],
223 fwstats
->requested_sent
[1],
224 fwstats
->requested_sent
[2],
225 fwstats
->requested_sent
[3],
226 fwstats
->requested_sent
[4]);
228 return simple_read_from_buffer(data
, count
, ppos
, buf
, res
);
231 static const struct file_operations brcmf_debugfs_fws_stats_ops
= {
232 .owner
= THIS_MODULE
,
234 .read
= brcmf_debugfs_fws_stats_read
237 void brcmf_debugfs_create_fws_stats(struct brcmf_pub
*drvr
,
238 struct brcmf_fws_stats
*stats
)
240 struct dentry
*dentry
= drvr
->dbgfs_dir
;
242 if (!IS_ERR_OR_NULL(dentry
))
243 debugfs_create_file("fws_stats", S_IRUGO
, dentry
,
244 stats
, &brcmf_debugfs_fws_stats_ops
);