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 any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /**
18  * DOC: wlan_hdd_sysfs_scan_config.c
19  *
20  * Implementation for creating sysfs file scan_config
21  */
22 
23 #include <wlan_hdd_includes.h>
24 #include "osif_psoc_sync.h"
25 #include <wlan_hdd_sysfs.h>
26 #include <wlan_hdd_sysfs_scan_config.h>
27 #include "wlan_policy_mgr_ucfg.h"
28 
29 static ssize_t
__hdd_sysfs_scan_config_store(struct hdd_context * hdd_ctx,struct kobj_attribute * attr,const char * buf,size_t count)30 __hdd_sysfs_scan_config_store(struct hdd_context *hdd_ctx,
31 			      struct kobj_attribute *attr,
32 			       const char *buf,
33 			       size_t count)
34 {
35 	uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
36 	char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
37 	char *sptr, *token;
38 	uint8_t val1, val2, val3;
39 	QDF_STATUS status;
40 	int ret;
41 
42 	if (!wlan_hdd_validate_modules_state(hdd_ctx))
43 		return -EINVAL;
44 
45 	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
46 					      buf, count);
47 
48 	if (ret) {
49 		hdd_err_rl("invalid input");
50 		return ret;
51 	}
52 
53 	sptr = buf_local;
54 	hdd_debug("set_scan_cfg: count %zu buf_local:(%s)",
55 		  count, buf_local);
56 
57 	/* Get val1 */
58 	token = strsep(&sptr, " ");
59 	if (!token)
60 		return -EINVAL;
61 	if (kstrtou8(token, 0, &val1))
62 		return -EINVAL;
63 
64 	/* Get val2 */
65 	token = strsep(&sptr, " ");
66 	if (!token)
67 		return -EINVAL;
68 	if (kstrtou8(token, 0, &val2))
69 		return -EINVAL;
70 
71 	/* Get val3 */
72 	token = strsep(&sptr, " ");
73 	if (!token)
74 		return -EINVAL;
75 	if (kstrtou8(token, 0, &val3))
76 		return -EINVAL;
77 
78 	hdd_debug("Sysfs to set dual mac scan config");
79 	status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
80 						      &dual_mac_feature);
81 	if (status != QDF_STATUS_SUCCESS)
82 		hdd_err("can't get dual mac feature val, use def");
83 	if (dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) {
84 		hdd_err("Dual mac feature is disabled from INI");
85 		return -EPERM;
86 	}
87 	hdd_debug("%d %d %d", val1, val2, val3);
88 	policy_mgr_set_dual_mac_scan_config(hdd_ctx->psoc,
89 					    val1, val2, val3);
90 
91 	return count;
92 }
93 
94 static ssize_t
hdd_sysfs_scan_config_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)95 hdd_sysfs_scan_config_store(struct kobject *kobj,
96 			    struct kobj_attribute *attr,
97 			    const char *buf,
98 			    size_t count)
99 {
100 	struct osif_psoc_sync *psoc_sync;
101 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
102 	ssize_t errno_size;
103 	int ret;
104 
105 	ret = wlan_hdd_validate_context(hdd_ctx);
106 	if (ret != 0)
107 		return ret;
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 = __hdd_sysfs_scan_config_store(hdd_ctx, attr,
115 						   buf, count);
116 
117 	osif_psoc_sync_op_stop(psoc_sync);
118 
119 	return errno_size;
120 }
121 
122 static struct kobj_attribute set_scan_cfg_attribute =
123 	__ATTR(scan_config, 0220, NULL,
124 	       hdd_sysfs_scan_config_store);
125 
hdd_sysfs_scan_config_create(struct kobject * driver_kobject)126 int hdd_sysfs_scan_config_create(struct kobject *driver_kobject)
127 {
128 	int error;
129 
130 	if (!driver_kobject) {
131 		hdd_err("could not get driver kobject!");
132 		return -EINVAL;
133 	}
134 
135 	error = sysfs_create_file(driver_kobject,
136 				  &set_scan_cfg_attribute.attr);
137 	if (error)
138 		hdd_err("could not create scan_config sysfs file");
139 
140 	return error;
141 }
142 
143 void
hdd_sysfs_scan_config_destroy(struct kobject * driver_kobject)144 hdd_sysfs_scan_config_destroy(struct kobject *driver_kobject)
145 {
146 	if (!driver_kobject) {
147 		hdd_err("could not get driver kobject!");
148 		return;
149 	}
150 	sysfs_remove_file(driver_kobject, &set_scan_cfg_attribute.attr);
151 }
152