1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
4  * All rights reserved.
5  */
6 
7 #if defined(WILC_DEBUGFS)
8 #include <linux/module.h>
9 #include <linux/debugfs.h>
10 
11 #include "wilc_wlan_if.h"
12 
13 static struct dentry *wilc_dir;
14 
15 #define DEBUG           BIT(0)
16 #define INFO            BIT(1)
17 #define WRN             BIT(2)
18 #define ERR             BIT(3)
19 
20 #define DBG_LEVEL_ALL	(DEBUG | INFO | WRN | ERR)
21 static atomic_t WILC_DEBUG_LEVEL = ATOMIC_INIT(ERR);
22 EXPORT_SYMBOL_GPL(WILC_DEBUG_LEVEL);
23 
wilc_debug_level_read(struct file * file,char __user * userbuf,size_t count,loff_t * ppos)24 static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf,
25 				     size_t count, loff_t *ppos)
26 {
27 	char buf[128];
28 	int res = 0;
29 
30 	/* only allow read from start */
31 	if (*ppos > 0)
32 		return 0;
33 
34 	res = scnprintf(buf, sizeof(buf), "Debug Level: %x\n",
35 			atomic_read(&WILC_DEBUG_LEVEL));
36 
37 	return simple_read_from_buffer(userbuf, count, ppos, buf, res);
38 }
39 
wilc_debug_level_write(struct file * filp,const char __user * buf,size_t count,loff_t * ppos)40 static ssize_t wilc_debug_level_write(struct file *filp,
41 				      const char __user *buf, size_t count,
42 				      loff_t *ppos)
43 {
44 	int flag = 0;
45 	int ret;
46 
47 	ret = kstrtouint_from_user(buf, count, 16, &flag);
48 	if (ret)
49 		return ret;
50 
51 	if (flag > DBG_LEVEL_ALL) {
52 		pr_info("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n",
53 			__func__, flag, atomic_read(&WILC_DEBUG_LEVEL));
54 		return -EINVAL;
55 	}
56 
57 	atomic_set(&WILC_DEBUG_LEVEL, (int)flag);
58 
59 	if (flag == 0)
60 		pr_info("Debug-level disabled\n");
61 	else
62 		pr_info("Debug-level enabled\n");
63 
64 	return count;
65 }
66 
67 #define FOPS(_open, _read, _write, _poll) { \
68 		.owner	= THIS_MODULE, \
69 		.open	= (_open), \
70 		.read	= (_read), \
71 		.write	= (_write), \
72 		.poll		= (_poll), \
73 }
74 
75 struct wilc_debugfs_info_t {
76 	const char *name;
77 	int perm;
78 	unsigned int data;
79 	const struct file_operations fops;
80 };
81 
82 static struct wilc_debugfs_info_t debugfs_info[] = {
83 	{
84 		"wilc_debug_level",
85 		0666,
86 		(DEBUG | ERR),
87 		FOPS(NULL, wilc_debug_level_read, wilc_debug_level_write, NULL),
88 	},
89 };
90 
wilc_debugfs_init(void)91 static int __init wilc_debugfs_init(void)
92 {
93 	int i;
94 	struct wilc_debugfs_info_t *info;
95 
96 	wilc_dir = debugfs_create_dir("wilc_wifi", NULL);
97 	for (i = 0; i < ARRAY_SIZE(debugfs_info); i++) {
98 		info = &debugfs_info[i];
99 		debugfs_create_file(info->name,
100 				    info->perm,
101 				    wilc_dir,
102 				    &info->data,
103 				    &info->fops);
104 	}
105 	return 0;
106 }
107 module_init(wilc_debugfs_init);
108 
wilc_debugfs_remove(void)109 static void __exit wilc_debugfs_remove(void)
110 {
111 	debugfs_remove_recursive(wilc_dir);
112 }
113 module_exit(wilc_debugfs_remove);
114 
115 #endif
116