1/*
2 * Copyright (c) 2012 Broadcom Corporation
3 * Copyright (c) 2012 Canonical Ltd.
4 *
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.
8 *
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.
16 */
17#include <linux/debugfs.h>
18#include <linux/if_ether.h>
19#include <linux/if.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>
25
26#include <defs.h>
27#include <brcmu_wifi.h>
28#include <brcmu_utils.h>
29#include "types.h"
30#include "main.h"
31#include "debug.h"
32#include "brcms_trace_events.h"
33
34static struct dentry *root_folder;
35
36void brcms_debugfs_init(void)
37{
38	root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
39	if (IS_ERR(root_folder))
40		root_folder = NULL;
41}
42
43void brcms_debugfs_exit(void)
44{
45	if (!root_folder)
46		return;
47
48	debugfs_remove_recursive(root_folder);
49	root_folder = NULL;
50}
51
52int brcms_debugfs_attach(struct brcms_pub *drvr)
53{
54	if (!root_folder)
55		return -ENODEV;
56
57	drvr->dbgfs_dir = debugfs_create_dir(
58		 dev_name(&drvr->wlc->hw->d11core->dev), root_folder);
59	return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
60}
61
62void brcms_debugfs_detach(struct brcms_pub *drvr)
63{
64	if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
65		debugfs_remove_recursive(drvr->dbgfs_dir);
66}
67
68struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr)
69{
70	return drvr->dbgfs_dir;
71}
72
73static
74ssize_t brcms_debugfs_hardware_read(struct file *f, char __user *data,
75					size_t count, loff_t *ppos)
76{
77	char buf[128];
78	int res;
79	struct brcms_pub *drvr = f->private_data;
80
81	/* only allow read from start */
82	if (*ppos > 0)
83		return 0;
84
85	res = scnprintf(buf, sizeof(buf),
86		"board vendor: %x\n"
87		"board type: %x\n"
88		"board revision: %x\n"
89		"board flags: %x\n"
90		"board flags2: %x\n"
91		"firmware revision: %x\n",
92		drvr->wlc->hw->d11core->bus->boardinfo.vendor,
93		drvr->wlc->hw->d11core->bus->boardinfo.type,
94		drvr->wlc->hw->boardrev,
95		drvr->wlc->hw->boardflags,
96		drvr->wlc->hw->boardflags2,
97		drvr->wlc->ucode_rev
98		);
99
100	return simple_read_from_buffer(data, count, ppos, buf, res);
101}
102
103static const struct file_operations brcms_debugfs_hardware_ops = {
104	.owner = THIS_MODULE,
105	.open = simple_open,
106	.read = brcms_debugfs_hardware_read
107};
108
109void brcms_debugfs_create_files(struct brcms_pub *drvr)
110{
111	struct dentry *dentry = drvr->dbgfs_dir;
112
113	if (!IS_ERR_OR_NULL(dentry))
114		debugfs_create_file("hardware", S_IRUGO, dentry,
115				    drvr, &brcms_debugfs_hardware_ops);
116}
117
118#define __brcms_fn(fn)						\
119void __brcms_ ##fn(struct device *dev, const char *fmt, ...)	\
120{								\
121	struct va_format vaf = {				\
122		.fmt = fmt,					\
123	};							\
124	va_list args;						\
125								\
126	va_start(args, fmt);					\
127	vaf.va = &args;						\
128	dev_ ##fn(dev, "%pV", &vaf);				\
129	trace_brcms_ ##fn(&vaf);				\
130	va_end(args);						\
131}
132
133__brcms_fn(info)
134__brcms_fn(warn)
135__brcms_fn(err)
136__brcms_fn(crit)
137
138#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING)
139void __brcms_dbg(struct device *dev, u32 level, const char *func,
140		 const char *fmt, ...)
141{
142	struct va_format vaf = {
143		.fmt = fmt,
144	};
145	va_list args;
146
147	va_start(args, fmt);
148	vaf.va = &args;
149#ifdef CONFIG_BRCMDBG
150	if ((brcm_msg_level & level) && net_ratelimit())
151		dev_err(dev, "%s %pV", func, &vaf);
152#endif
153	trace_brcms_dbg(level, func, &vaf);
154	va_end(args);
155}
156#endif
157