1 /*
2  * Copyright (c) 2020 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: wlan_hdd_debugfs_unit_test.c
22  *
23  * WLAN Host Device Driver implementation to create debugfs
24  * unit_test_host/unit_test_target/wlan_suspend/wlan_resume
25  */
26 #include "wlan_hdd_main.h"
27 #include "osif_psoc_sync.h"
28 #include "osif_vdev_sync.h"
29 #include "wlan_dsc_test.h"
30 #include "wlan_hdd_unit_test.h"
31 #include "wlan_hdd_debugfs_unit_test.h"
32 #include "wma.h"
33 
34 #ifdef WLAN_UNIT_TEST
35 /* strlen("all") + 1(\n) */
36 #define MIN_USER_COMMAND_SIZE_UNIT_TEST_HOST 4
37 #define MAX_USER_COMMAND_SIZE_UNIT_TEST_HOST 32
38 
39 /**
40  * __wlan_hdd_write_unit_test_host_debugfs()
41  *    - host unit test debugfs handler
42  *
43  * @hdd_ctx: HDD context used to register the debugfs file
44  * @buf: text being written to the debugfs
45  * @count: size of @buf
46  * @ppos: (unused) offset into the virtual file system
47  *
48  * Return: number of bytes processed or errno
49  */
__wlan_hdd_write_unit_test_host_debugfs(struct hdd_context * hdd_ctx,const char __user * buf,size_t count,loff_t * ppos)50 static ssize_t __wlan_hdd_write_unit_test_host_debugfs(
51 		struct hdd_context *hdd_ctx,
52 		const char __user *buf, size_t count,
53 		loff_t *ppos)
54 {
55 	char name[MAX_USER_COMMAND_SIZE_UNIT_TEST_HOST + 1];
56 	int ret;
57 
58 	if (count < MIN_USER_COMMAND_SIZE_UNIT_TEST_HOST ||
59 	    count > MAX_USER_COMMAND_SIZE_UNIT_TEST_HOST) {
60 		hdd_err_rl("Command length (%zu) is invalid, expected [%d, %d]",
61 			   count,
62 			   MIN_USER_COMMAND_SIZE_UNIT_TEST_HOST,
63 			   MAX_USER_COMMAND_SIZE_UNIT_TEST_HOST);
64 		return -EINVAL;
65 	}
66 
67 	/* Get command from user */
68 	if (copy_from_user(name, buf, count))
69 		return -EFAULT;
70 	/* default 'echo' cmd takes new line character to here*/
71 	if (name[count - 1] == '\n')
72 		name[count - 1] = '\0';
73 	else
74 		name[count] = '\0';
75 
76 	hdd_nofl_info("unit_test: count %zu name: %s", count, name);
77 
78 	ret = wlan_hdd_unit_test(hdd_ctx, name);
79 	if (ret != 0)
80 		return ret;
81 
82 	return count;
83 }
84 
85 /**
86  * wlan_hdd_write_unit_test_host_debugfs()
87  *    - wrapper for __wlan_hdd_write_unit_test_host_debugfs
88  *
89  * @file: file pointer
90  * @buf: buffer
91  * @count: count
92  * @ppos: position pointer
93  *
94  * Return: number of bytes processed or errno
95  */
wlan_hdd_write_unit_test_host_debugfs(struct file * file,const char __user * buf,size_t count,loff_t * ppos)96 static ssize_t wlan_hdd_write_unit_test_host_debugfs(
97 		struct file *file,
98 		const char __user *buf,
99 		size_t count, loff_t *ppos)
100 {
101 	struct hdd_context *hdd_ctx = file_inode(file)->i_private;
102 	struct osif_psoc_sync *psoc_sync;
103 	ssize_t errno_size;
104 
105 	errno_size = wlan_hdd_validate_context(hdd_ctx);
106 	if (errno_size)
107 		return errno_size;
108 
109 	errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
110 					     &psoc_sync);
111 	if (errno_size)
112 		return errno_size;
113 
114 	errno_size = __wlan_hdd_write_unit_test_host_debugfs(
115 				hdd_ctx, buf, count, ppos);
116 	if (errno_size < 0)
117 		hdd_err_rl("err_size %zd", errno_size);
118 
119 	osif_psoc_sync_op_stop(psoc_sync);
120 	return errno_size;
121 }
122 
123 static const struct file_operations fops_unit_test_host_debugfs = {
124 	.write = wlan_hdd_write_unit_test_host_debugfs,
125 	.owner = THIS_MODULE,
126 	.llseek = default_llseek,
127 };
128 
wlan_hdd_debugfs_unit_test_host_create(struct hdd_context * hdd_ctx)129 int wlan_hdd_debugfs_unit_test_host_create(struct hdd_context *hdd_ctx)
130 {
131 	if (!debugfs_create_file("unit_test_host", 00400 | 00200,
132 				 qdf_debugfs_get_root(),
133 				 hdd_ctx, &fops_unit_test_host_debugfs))
134 		return -EINVAL;
135 
136 	return 0;
137 }
138 #endif /* WLAN_UNIT_TEST */
139