1 /*
2  * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: wlan_hdd_sysfs_scan_disable.c
21  *
22  * implementation for creating sysfs scan_disable
23  */
24 
25 #include <wlan_hdd_includes.h>
26 #include "osif_psoc_sync.h"
27 #include <wlan_hdd_sysfs.h>
28 #include <wlan_hdd_sysfs_scan_disable.h>
29 
30 static ssize_t
__hdd_sysfs_scan_disable_store(struct hdd_context * hdd_ctx,struct kobj_attribute * attr,const char * buf,size_t count)31 __hdd_sysfs_scan_disable_store(struct hdd_context *hdd_ctx,
32 			       struct kobj_attribute *attr,
33 			       const char *buf, size_t count)
34 {
35 	char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
36 	char *sptr, *token;
37 	uint32_t value;
38 	int ret;
39 
40 	if (!wlan_hdd_validate_modules_state(hdd_ctx))
41 		return -EINVAL;
42 
43 	if (!hdd_ctx->psoc)
44 		return -EINVAL;
45 
46 	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
47 					      buf, count);
48 	if (ret) {
49 		hdd_err_rl("invalid input");
50 		return ret;
51 	}
52 
53 	sptr = buf_local;
54 	hdd_debug("scan_disable: count %zu buf_local:(%s)",
55 		  count, buf_local);
56 
57 	/* Get value */
58 	token = strsep(&sptr, " ");
59 	if (!token)
60 		return -EINVAL;
61 	if (kstrtou32(token, 0, &value))
62 		return -EINVAL;
63 
64 	hdd_debug("%d", value);
65 
66 	if (value)
67 		ucfg_scan_psoc_set_disable(hdd_ctx->psoc, REASON_USER_SPACE);
68 	else
69 		ucfg_scan_psoc_set_enable(hdd_ctx->psoc, REASON_USER_SPACE);
70 
71 	return count;
72 }
73 
74 static ssize_t
hdd_sysfs_scan_disable_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)75 hdd_sysfs_scan_disable_store(struct kobject *kobj,
76 			     struct kobj_attribute *attr,
77 			     const char *buf, size_t count)
78 {
79 	struct osif_psoc_sync *psoc_sync;
80 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
81 	ssize_t errno_size;
82 	int ret;
83 
84 	ret = wlan_hdd_validate_context(hdd_ctx);
85 	if (ret)
86 		return ret;
87 
88 	errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
89 					     &psoc_sync);
90 	if (errno_size)
91 		return errno_size;
92 
93 	errno_size = __hdd_sysfs_scan_disable_store(hdd_ctx, attr,
94 						    buf, count);
95 
96 	osif_psoc_sync_op_stop(psoc_sync);
97 
98 	return errno_size;
99 }
100 
101 static struct kobj_attribute scan_disable_attribute =
102 	__ATTR(scan_disable, 0220, NULL,
103 	       hdd_sysfs_scan_disable_store);
104 
hdd_sysfs_scan_disable_create(struct kobject * driver_kobject)105 int hdd_sysfs_scan_disable_create(struct kobject *driver_kobject)
106 {
107 	int error;
108 
109 	if (!driver_kobject) {
110 		hdd_err("could not get driver kobject!");
111 		return -EINVAL;
112 	}
113 
114 	error = sysfs_create_file(driver_kobject,
115 				  &scan_disable_attribute.attr);
116 	if (error)
117 		hdd_err("could not create scan_disable sysfs file");
118 
119 	return error;
120 }
121 
122 void
hdd_sysfs_scan_disable_destroy(struct kobject * driver_kobject)123 hdd_sysfs_scan_disable_destroy(struct kobject *driver_kobject)
124 {
125 	if (!driver_kobject) {
126 		hdd_err("could not get driver kobject!");
127 		return;
128 	}
129 	sysfs_remove_file(driver_kobject, &scan_disable_attribute.attr);
130 }
131