blob: 27c653a0cdf9444d0722de87f613bf3a940dae94 [file] [log] [blame]
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001/*
2 * NewportMedia WiFi chipset driver test tools - wilc-debug
3 * Copyright (c) 2012 NewportMedia Inc.
4 * Author: SSW <sswd@wilcsemic.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12#if defined(WILC_DEBUGFS)
13#include <linux/module.h>
14#include <linux/debugfs.h>
15#include <linux/poll.h>
16#include <linux/sched.h>
17
18#include "wilc_wlan_if.h"
19
20
21static struct dentry *wilc_dir;
22
23/*
24 * --------------------------------------------------------------------------------
25 */
26
27#define DBG_REGION_ALL (GENERIC_DBG | HOSTAPD_DBG | HOSTINF_DBG | CORECONFIG_DBG | CFG80211_DBG | INT_DBG | TX_DBG | RX_DBG | LOCK_DBG | INIT_DBG | BUS_DBG | MEM_DBG)
28#define DBG_LEVEL_ALL (DEBUG | INFO | WRN | ERR)
Arnd Bergmann0e1af732015-11-16 15:04:54 +010029atomic_t WILC_REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | CFG80211_DBG | FIRM_DBG | HOSTAPD_DBG);
Arnd Bergmann750ffe92015-11-16 15:05:08 +010030EXPORT_SYMBOL_GPL(WILC_REGION);
Arnd Bergmann0e1af732015-11-16 15:04:54 +010031atomic_t WILC_DEBUG_LEVEL = ATOMIC_INIT(ERR);
Arnd Bergmann750ffe92015-11-16 15:05:08 +010032EXPORT_SYMBOL_GPL(WILC_DEBUG_LEVEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +090033
34/*
35 * --------------------------------------------------------------------------------
36 */
37
38
39static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos)
40{
41 char buf[128];
42 int res = 0;
43
44 /* only allow read from start */
45 if (*ppos > 0)
46 return 0;
47
Arnd Bergmann0e1af732015-11-16 15:04:54 +010048 res = scnprintf(buf, sizeof(buf), "Debug Level: %x\n", atomic_read(&WILC_DEBUG_LEVEL));
Johnny Kimc5c77ba2015-05-11 14:30:56 +090049
50 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
51}
52
Chandra S Gorentla6e3f05b2015-08-15 12:23:31 +053053static ssize_t wilc_debug_level_write(struct file *filp, const char __user *buf,
54 size_t count, loff_t *ppos)
Johnny Kimc5c77ba2015-05-11 14:30:56 +090055{
Johnny Kimc5c77ba2015-05-11 14:30:56 +090056 int flag = 0;
Chandra S Gorentla6e3f05b2015-08-15 12:23:31 +053057 int ret;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090058
Chandra S Gorentla6e3f05b2015-08-15 12:23:31 +053059 ret = kstrtouint_from_user(buf, count, 16, &flag);
60 if (ret)
61 return ret;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090062
63 if (flag > DBG_LEVEL_ALL) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +010064 printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&WILC_DEBUG_LEVEL));
Chandra S Gorentla6e3f05b2015-08-15 12:23:31 +053065 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090066 }
67
Arnd Bergmann0e1af732015-11-16 15:04:54 +010068 atomic_set(&WILC_DEBUG_LEVEL, (int)flag);
Johnny Kimc5c77ba2015-05-11 14:30:56 +090069
Chandra S Gorentla78174ad2015-08-08 17:41:36 +053070 if (flag == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +090071 printk("Debug-level disabled\n");
Chandra S Gorentla78174ad2015-08-08 17:41:36 +053072 else
Johnny Kimc5c77ba2015-05-11 14:30:56 +090073 printk("Debug-level enabled\n");
Chandra S Gorentla6e3f05b2015-08-15 12:23:31 +053074
Johnny Kimc5c77ba2015-05-11 14:30:56 +090075 return count;
76}
77
78static ssize_t wilc_debug_region_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos)
79{
80 char buf[128];
81 int res = 0;
82
83 /* only allow read from start */
84 if (*ppos > 0)
85 return 0;
86
Arnd Bergmann0e1af732015-11-16 15:04:54 +010087 res = scnprintf(buf, sizeof(buf), "Debug region: %x\n", atomic_read(&WILC_REGION));
Johnny Kimc5c77ba2015-05-11 14:30:56 +090088
89 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
90}
91
92static ssize_t wilc_debug_region_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
93{
94 char buffer[128] = {};
95 int flag;
96
Dan Carpenter9ee81442015-06-04 11:59:34 +030097 if (count > sizeof(buffer))
98 return -EINVAL;
99
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900100 if (copy_from_user(buffer, buf, count)) {
101 return -EFAULT;
102 }
103
104 flag = buffer[0] - '0';
105
106 if (flag > DBG_REGION_ALL) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100107 printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&WILC_REGION));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900108 return -EFAULT;
109 }
110
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100111 atomic_set(&WILC_REGION, (int)flag);
112 printk("new debug-region is %x\n", atomic_read(&WILC_REGION));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900113
114 return count;
115}
116
117/*
118 * --------------------------------------------------------------------------------
119 */
120
121#define FOPS(_open, _read, _write, _poll) { \
122 .owner = THIS_MODULE, \
123 .open = (_open), \
124 .read = (_read), \
125 .write = (_write), \
126 .poll = (_poll), \
127}
128
129struct wilc_debugfs_info_t {
130 const char *name;
131 int perm;
132 unsigned int data;
133 struct file_operations fops;
134};
135
136static struct wilc_debugfs_info_t debugfs_info[] = {
137 { "wilc_debug_level", 0666, (DEBUG | ERR), FOPS(NULL, wilc_debug_level_read, wilc_debug_level_write, NULL), },
138 { "wilc_debug_region", 0666, (INIT_DBG | GENERIC_DBG | CFG80211_DBG), FOPS(NULL, wilc_debug_region_read, wilc_debug_region_write, NULL), },
139};
140
Arnd Bergmannc94f05e2015-11-16 15:05:09 +0100141static int __init wilc_debugfs_init(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900142{
143 int i;
144
145 struct dentry *debugfs_files;
146 struct wilc_debugfs_info_t *info;
147
148 wilc_dir = debugfs_create_dir("wilc_wifi", NULL);
149 if (wilc_dir == ERR_PTR(-ENODEV)) {
150 /* it's not error. the debugfs is just not being enabled. */
151 printk("ERR, kernel has built without debugfs support\n");
152 return 0;
153 }
154
155 if (!wilc_dir) {
156 printk("ERR, debugfs create dir\n");
157 return -1;
158 }
159
160 for (i = 0; i < ARRAY_SIZE(debugfs_info); i++) {
161 info = &debugfs_info[i];
162 debugfs_files = debugfs_create_file(info->name,
163 info->perm,
164 wilc_dir,
165 &info->data,
166 &info->fops);
167
168 if (!debugfs_files) {
169 printk("ERR fail to create the debugfs file, %s\n", info->name);
170 debugfs_remove_recursive(wilc_dir);
171 return -1;
172 }
173 }
174 return 0;
175}
Arnd Bergmannc94f05e2015-11-16 15:05:09 +0100176module_init(wilc_debugfs_init);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900177
Arnd Bergmannc94f05e2015-11-16 15:05:09 +0100178static void __exit wilc_debugfs_remove(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900179{
180 debugfs_remove_recursive(wilc_dir);
181}
Arnd Bergmannc94f05e2015-11-16 15:05:09 +0100182module_exit(wilc_debugfs_remove);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900183
184#endif
185