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