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