1 /*
2  * Copyright (c) 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 #include <wlan_hdd_includes.h>
20 #include <wlan_hdd_sysfs.h>
21 #include <osif_psoc_sync.h>
22 #include <wlan_hdd_sysfs_swlm.h>
23 
24 static ssize_t
__hdd_sysfs_dp_swlm_show(struct hdd_context * hdd_ctx,struct kobj_attribute * attr,char * buf)25 __hdd_sysfs_dp_swlm_show(struct hdd_context *hdd_ctx,
26 			 struct kobj_attribute *attr, char *buf)
27 {
28 	ol_txrx_soc_handle soc_hdl = cds_get_context(QDF_MODULE_ID_SOC);
29 
30 	if (!wlan_hdd_validate_modules_state(hdd_ctx))
31 		return -EINVAL;
32 
33 	return scnprintf(buf, PAGE_SIZE, "dp_swlm enable: %d\n",
34 			 cdp_soc_is_swlm_enabled(soc_hdl));
35 }
36 
hdd_sysfs_dp_swlm_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)37 static ssize_t hdd_sysfs_dp_swlm_show(struct kobject *kobj,
38 				      struct kobj_attribute *attr,
39 				      char *buf)
40 {
41 	struct osif_psoc_sync *psoc_sync;
42 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
43 	ssize_t errno_size;
44 	int ret;
45 
46 	ret = wlan_hdd_validate_context(hdd_ctx);
47 	if (ret != 0)
48 		return ret;
49 
50 	errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
51 					     &psoc_sync);
52 	if (errno_size)
53 		return errno_size;
54 
55 	errno_size = __hdd_sysfs_dp_swlm_show(hdd_ctx, attr, buf);
56 
57 	osif_psoc_sync_op_stop(psoc_sync);
58 
59 	return errno_size;
60 }
61 
62 static ssize_t
__hdd_sysfs_dp_swlm_store(struct hdd_context * hdd_ctx,struct kobj_attribute * attr,const char * buf,size_t count)63 __hdd_sysfs_dp_swlm_store(struct hdd_context *hdd_ctx,
64 			  struct kobj_attribute *attr, const char *buf,
65 			  size_t count)
66 {
67 	char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
68 	char *sptr, *token;
69 	uint32_t value;
70 	int ret;
71 	ol_txrx_soc_handle dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
72 
73 	if (!wlan_hdd_validate_modules_state(hdd_ctx) || !dp_soc)
74 		return -EINVAL;
75 
76 	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
77 					      buf, count);
78 
79 	if (ret) {
80 		hdd_err_rl("invalid input");
81 		return ret;
82 	}
83 
84 	sptr = buf_local;
85 	token = strsep(&sptr, " ");
86 	if (!token)
87 		return -EINVAL;
88 	if (kstrtou32(token, 0, &value))
89 		return -EINVAL;
90 
91 	hdd_debug("dp_swlm: %d", value);
92 
93 	cdp_soc_set_swlm_enable(dp_soc, value);
94 
95 	return count;
96 }
97 
98 static ssize_t
hdd_sysfs_dp_swlm_store(struct kobject * kobj,struct kobj_attribute * attr,char const * buf,size_t count)99 hdd_sysfs_dp_swlm_store(struct kobject *kobj,
100 			struct kobj_attribute *attr,
101 			char const *buf, size_t count)
102 {
103 	struct osif_psoc_sync *psoc_sync;
104 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
105 	ssize_t errno_size;
106 	int ret;
107 
108 	ret = wlan_hdd_validate_context(hdd_ctx);
109 	if (ret != 0)
110 		return ret;
111 
112 	errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
113 					     &psoc_sync);
114 	if (errno_size)
115 		return errno_size;
116 
117 	errno_size = __hdd_sysfs_dp_swlm_store(hdd_ctx, attr,
118 					       buf, count);
119 
120 	osif_psoc_sync_op_stop(psoc_sync);
121 
122 	return errno_size;
123 }
124 
125 static struct kobj_attribute dp_swlm_attribute =
126 	__ATTR(dp_swlm, 0664, hdd_sysfs_dp_swlm_show,
127 	       hdd_sysfs_dp_swlm_store);
128 
hdd_sysfs_dp_swlm_create(struct kobject * driver_kobject)129 int hdd_sysfs_dp_swlm_create(struct kobject *driver_kobject)
130 {
131 	int error;
132 
133 	if (!driver_kobject) {
134 		hdd_err("could not get driver kobject!");
135 		return -EINVAL;
136 	}
137 
138 	error = sysfs_create_file(driver_kobject,
139 				  &dp_swlm_attribute.attr);
140 	if (error)
141 		hdd_err("could not create dp_swlm sysfs file");
142 
143 	return error;
144 }
145 
hdd_sysfs_dp_swlm_destroy(struct kobject * driver_kobject)146 void hdd_sysfs_dp_swlm_destroy(struct kobject *driver_kobject)
147 {
148 	if (!driver_kobject) {
149 		hdd_err("could not get driver kobject!");
150 		return;
151 	}
152 
153 	sysfs_remove_file(driver_kobject, &dp_swlm_attribute.attr);
154 }
155