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