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
);
44 static int brcmf_debugfs_chipinfo_read(struct seq_file
*seq
, void *data
)
46 struct brcmf_pub
*drvr
= seq
->private;
47 struct brcmf_bus
*bus
= drvr
->bus_if
;
49 seq_printf(seq
, "chip: %x(%u) rev %u\n",
50 bus
->chip
, bus
->chip
, bus
->chiprev
);
54 static int brcmf_debugfs_chipinfo_open(struct inode
*inode
, struct file
*f
)
56 return single_open(f
, brcmf_debugfs_chipinfo_read
, inode
->i_private
);
59 static const struct file_operations brcmf_debugfs_chipinfo_ops
= {
61 .open
= brcmf_debugfs_chipinfo_open
,
62 .release
= single_release
,
67 static int brcmf_debugfs_create_chipinfo(struct brcmf_pub
*drvr
)
69 struct dentry
*dentry
= drvr
->dbgfs_dir
;
71 if (!IS_ERR_OR_NULL(dentry
))
72 debugfs_create_file("chipinfo", S_IRUGO
, dentry
, drvr
,
73 &brcmf_debugfs_chipinfo_ops
);
77 int brcmf_debugfs_attach(struct brcmf_pub
*drvr
)
79 struct device
*dev
= drvr
->bus_if
->dev
;
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
);
89 void brcmf_debugfs_detach(struct brcmf_pub
*drvr
)
91 if (!IS_ERR_OR_NULL(drvr
->dbgfs_dir
))
92 debugfs_remove_recursive(drvr
->dbgfs_dir
);
95 struct dentry
*brcmf_debugfs_get_devdir(struct brcmf_pub
*drvr
)
97 return drvr
->dbgfs_dir
;
100 static int brcmf_debugfs_sdio_count_read(struct seq_file
*seq
, void *data
)
102 struct brcmf_sdio_count
*sdcnt
= seq
->private;
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
);
137 static int brcmf_debugfs_sdio_count_open(struct inode
*inode
, struct file
*f
)
139 return single_open(f
, brcmf_debugfs_sdio_count_read
, inode
->i_private
);
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
,
150 void brcmf_debugfs_create_sdio_count(struct brcmf_pub
*drvr
,
151 struct brcmf_sdio_count
*sdcnt
)
153 struct dentry
*dentry
= drvr
->dbgfs_dir
;
155 if (!IS_ERR_OR_NULL(dentry
))
156 debugfs_create_file("counters", S_IRUGO
, dentry
,
157 sdcnt
, &brcmf_debugfs_sdio_counter_ops
);
160 static int brcmf_debugfs_fws_stats_read(struct seq_file
*seq
, void *data
)
162 struct brcmf_fws_stats
*fwstats
= seq
->private;
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"
173 "generic_error: %u\n"
174 "rollback_success: %u\n"
175 "rollback_failed: %u\n"
180 "txs_suppr_core: %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
,
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
,
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]);
221 static int brcmf_debugfs_fws_stats_open(struct inode
*inode
, struct file
*f
)
223 return single_open(f
, brcmf_debugfs_fws_stats_read
, inode
->i_private
);
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
,
234 void brcmf_debugfs_create_fws_stats(struct brcmf_pub
*drvr
,
235 struct brcmf_fws_stats
*stats
)
237 struct dentry
*dentry
= drvr
->dbgfs_dir
;
239 if (!IS_ERR_OR_NULL(dentry
))
240 debugfs_create_file("fws_stats", S_IRUGO
, dentry
,
241 stats
, &brcmf_debugfs_fws_stats_ops
);