2 * Copyright (c) 2012 Broadcom Corporation
3 * Copyright (c) 2012 Canonical Ltd.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <linux/debugfs.h>
18 #include <linux/if_ether.h>
20 #include <linux/net.h>
21 #include <linux/netdevice.h>
22 #include <linux/ieee80211.h>
23 #include <linux/module.h>
24 #include <net/mac80211.h>
27 #include <brcmu_wifi.h>
28 #include <brcmu_utils.h>
32 #include "brcms_trace_events.h"
33 #include "phy/phy_int.h"
35 static struct dentry
*root_folder
;
37 void brcms_debugfs_init(void)
39 root_folder
= debugfs_create_dir(KBUILD_MODNAME
, NULL
);
40 if (IS_ERR(root_folder
))
44 void brcms_debugfs_exit(void)
49 debugfs_remove_recursive(root_folder
);
53 int brcms_debugfs_attach(struct brcms_pub
*drvr
)
58 drvr
->dbgfs_dir
= debugfs_create_dir(
59 dev_name(&drvr
->wlc
->hw
->d11core
->dev
), root_folder
);
60 return PTR_ERR_OR_ZERO(drvr
->dbgfs_dir
);
63 void brcms_debugfs_detach(struct brcms_pub
*drvr
)
65 if (!IS_ERR_OR_NULL(drvr
->dbgfs_dir
))
66 debugfs_remove_recursive(drvr
->dbgfs_dir
);
69 struct dentry
*brcms_debugfs_get_devdir(struct brcms_pub
*drvr
)
71 return drvr
->dbgfs_dir
;
75 int brcms_debugfs_hardware_read(struct seq_file
*s
, void *data
)
77 struct brcms_pub
*drvr
= s
->private;
78 struct brcms_hardware
*hw
= drvr
->wlc
->hw
;
79 struct bcma_device
*core
= hw
->d11core
;
80 struct bcma_bus
*bus
= core
->bus
;
81 char boardrev
[BRCMU_BOARDREV_LEN
];
83 seq_printf(s
, "chipnum 0x%x\n"
98 bus
->chipinfo
.id
, bus
->chipinfo
.rev
, bus
->chipinfo
.pkg
,
99 core
->id
.rev
, bus
->boardinfo
.type
, bus
->boardinfo
.vendor
,
100 brcmu_boardrev_str(hw
->boardrev
, boardrev
),
101 drvr
->wlc
->hw
->boardflags
, drvr
->wlc
->hw
->boardflags2
,
102 drvr
->wlc
->ucode_rev
, hw
->band
->radiorev
,
103 hw
->band
->phytype
, hw
->band
->phyrev
, hw
->band
->pi
->ana_rev
,
108 static int brcms_debugfs_macstat_read(struct seq_file
*s
, void *data
)
110 struct brcms_pub
*drvr
= s
->private;
111 struct brcms_info
*wl
= drvr
->ieee_hw
->priv
;
112 struct macstat stats
;
115 spin_lock_bh(&wl
->lock
);
116 stats
= *(drvr
->wlc
->core
->macstat_snapshot
);
117 spin_unlock_bh(&wl
->lock
);
119 seq_printf(s
, "txallfrm: %d\n", stats
.txallfrm
);
120 seq_printf(s
, "txrtsfrm: %d\n", stats
.txrtsfrm
);
121 seq_printf(s
, "txctsfrm: %d\n", stats
.txctsfrm
);
122 seq_printf(s
, "txackfrm: %d\n", stats
.txackfrm
);
123 seq_printf(s
, "txdnlfrm: %d\n", stats
.txdnlfrm
);
124 seq_printf(s
, "txbcnfrm: %d\n", stats
.txbcnfrm
);
125 seq_printf(s
, "txfunfl[8]:");
126 for (i
= 0; i
< ARRAY_SIZE(stats
.txfunfl
); i
++)
127 seq_printf(s
, " %d", stats
.txfunfl
[i
]);
128 seq_printf(s
, "\ntxtplunfl: %d\n", stats
.txtplunfl
);
129 seq_printf(s
, "txphyerr: %d\n", stats
.txphyerr
);
130 seq_printf(s
, "pktengrxducast: %d\n", stats
.pktengrxducast
);
131 seq_printf(s
, "pktengrxdmcast: %d\n", stats
.pktengrxdmcast
);
132 seq_printf(s
, "rxfrmtoolong: %d\n", stats
.rxfrmtoolong
);
133 seq_printf(s
, "rxfrmtooshrt: %d\n", stats
.rxfrmtooshrt
);
134 seq_printf(s
, "rxinvmachdr: %d\n", stats
.rxinvmachdr
);
135 seq_printf(s
, "rxbadfcs: %d\n", stats
.rxbadfcs
);
136 seq_printf(s
, "rxbadplcp: %d\n", stats
.rxbadplcp
);
137 seq_printf(s
, "rxcrsglitch: %d\n", stats
.rxcrsglitch
);
138 seq_printf(s
, "rxstrt: %d\n", stats
.rxstrt
);
139 seq_printf(s
, "rxdfrmucastmbss: %d\n", stats
.rxdfrmucastmbss
);
140 seq_printf(s
, "rxmfrmucastmbss: %d\n", stats
.rxmfrmucastmbss
);
141 seq_printf(s
, "rxcfrmucast: %d\n", stats
.rxcfrmucast
);
142 seq_printf(s
, "rxrtsucast: %d\n", stats
.rxrtsucast
);
143 seq_printf(s
, "rxctsucast: %d\n", stats
.rxctsucast
);
144 seq_printf(s
, "rxackucast: %d\n", stats
.rxackucast
);
145 seq_printf(s
, "rxdfrmocast: %d\n", stats
.rxdfrmocast
);
146 seq_printf(s
, "rxmfrmocast: %d\n", stats
.rxmfrmocast
);
147 seq_printf(s
, "rxcfrmocast: %d\n", stats
.rxcfrmocast
);
148 seq_printf(s
, "rxrtsocast: %d\n", stats
.rxrtsocast
);
149 seq_printf(s
, "rxctsocast: %d\n", stats
.rxctsocast
);
150 seq_printf(s
, "rxdfrmmcast: %d\n", stats
.rxdfrmmcast
);
151 seq_printf(s
, "rxmfrmmcast: %d\n", stats
.rxmfrmmcast
);
152 seq_printf(s
, "rxcfrmmcast: %d\n", stats
.rxcfrmmcast
);
153 seq_printf(s
, "rxbeaconmbss: %d\n", stats
.rxbeaconmbss
);
154 seq_printf(s
, "rxdfrmucastobss: %d\n", stats
.rxdfrmucastobss
);
155 seq_printf(s
, "rxbeaconobss: %d\n", stats
.rxbeaconobss
);
156 seq_printf(s
, "rxrsptmout: %d\n", stats
.rxrsptmout
);
157 seq_printf(s
, "bcntxcancl: %d\n", stats
.bcntxcancl
);
158 seq_printf(s
, "rxf0ovfl: %d\n", stats
.rxf0ovfl
);
159 seq_printf(s
, "rxf1ovfl: %d\n", stats
.rxf1ovfl
);
160 seq_printf(s
, "rxf2ovfl: %d\n", stats
.rxf2ovfl
);
161 seq_printf(s
, "txsfovfl: %d\n", stats
.txsfovfl
);
162 seq_printf(s
, "pmqovfl: %d\n", stats
.pmqovfl
);
163 seq_printf(s
, "rxcgprqfrm: %d\n", stats
.rxcgprqfrm
);
164 seq_printf(s
, "rxcgprsqovfl: %d\n", stats
.rxcgprsqovfl
);
165 seq_printf(s
, "txcgprsfail: %d\n", stats
.txcgprsfail
);
166 seq_printf(s
, "txcgprssuc: %d\n", stats
.txcgprssuc
);
167 seq_printf(s
, "prs_timeout: %d\n", stats
.prs_timeout
);
168 seq_printf(s
, "rxnack: %d\n", stats
.rxnack
);
169 seq_printf(s
, "frmscons: %d\n", stats
.frmscons
);
170 seq_printf(s
, "txnack: %d\n", stats
.txnack
);
171 seq_printf(s
, "txglitch_nack: %d\n", stats
.txglitch_nack
);
172 seq_printf(s
, "txburst: %d\n", stats
.txburst
);
173 seq_printf(s
, "bphy_rxcrsglitch: %d\n", stats
.bphy_rxcrsglitch
);
174 seq_printf(s
, "phywatchdog: %d\n", stats
.phywatchdog
);
175 seq_printf(s
, "bphy_badplcp: %d\n", stats
.bphy_badplcp
);
179 struct brcms_debugfs_entry
{
180 int (*read
)(struct seq_file
*seq
, void *data
);
181 struct brcms_pub
*drvr
;
184 static int brcms_debugfs_entry_open(struct inode
*inode
, struct file
*f
)
186 struct brcms_debugfs_entry
*entry
= inode
->i_private
;
188 return single_open(f
, entry
->read
, entry
->drvr
);
191 static const struct file_operations brcms_debugfs_def_ops
= {
192 .owner
= THIS_MODULE
,
193 .open
= brcms_debugfs_entry_open
,
194 .release
= single_release
,
200 brcms_debugfs_add_entry(struct brcms_pub
*drvr
, const char *fn
,
201 int (*read_fn
)(struct seq_file
*seq
, void *data
))
203 struct device
*dev
= &drvr
->wlc
->hw
->d11core
->dev
;
204 struct dentry
*dentry
= drvr
->dbgfs_dir
;
205 struct brcms_debugfs_entry
*entry
;
207 if (IS_ERR_OR_NULL(dentry
))
210 entry
= devm_kzalloc(dev
, sizeof(*entry
), GFP_KERNEL
);
214 entry
->read
= read_fn
;
217 dentry
= debugfs_create_file(fn
, 0444, dentry
, entry
,
218 &brcms_debugfs_def_ops
);
220 return PTR_ERR_OR_ZERO(dentry
);
223 void brcms_debugfs_create_files(struct brcms_pub
*drvr
)
225 if (IS_ERR_OR_NULL(drvr
->dbgfs_dir
))
228 brcms_debugfs_add_entry(drvr
, "hardware", brcms_debugfs_hardware_read
);
229 brcms_debugfs_add_entry(drvr
, "macstat", brcms_debugfs_macstat_read
);
232 #define __brcms_fn(fn) \
233 void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \
235 struct va_format vaf = { \
240 va_start(args, fmt); \
242 dev_ ##fn(dev, "%pV", &vaf); \
243 trace_brcms_ ##fn(&vaf); \
252 #if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING)
253 void __brcms_dbg(struct device
*dev
, u32 level
, const char *func
,
254 const char *fmt
, ...)
256 struct va_format vaf
= {
263 #ifdef CONFIG_BRCMDBG
264 if ((brcm_msg_level
& level
) && net_ratelimit())
265 dev_err(dev
, "%s %pV", func
, &vaf
);
267 trace_brcms_dbg(level
, func
, &vaf
);