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_roam_trigger_bitmap.h>
21 
__hdd_sysfs_roam_trigger_bitmap_show(struct hdd_context * hdd_ctx,struct kobj_attribute * attr,char * buf)22 static ssize_t __hdd_sysfs_roam_trigger_bitmap_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, "0x%x",
34 			ucfg_mlme_get_roaming_triggers(hdd_ctx->psoc));
35 
36 	return ret;
37 }
38 
hdd_sysfs_roam_trigger_bitmap_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)39 static ssize_t hdd_sysfs_roam_trigger_bitmap_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_roam_trigger_bitmap_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_roam_trigger_bitmap_store(struct hdd_context * hdd_ctx,struct kobj_attribute * attr,const char * buf,size_t count)65 __hdd_sysfs_roam_trigger_bitmap_store(struct hdd_context *hdd_ctx,
66 				      struct kobj_attribute *attr,
67 				      const char *buf,
68 				      size_t count)
69 {
70 	char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
71 	char *sptr, *token;
72 	uint32_t value;
73 	int ret = 0;
74 
75 	if (!hdd_ctx || !hdd_ctx->psoc) {
76 		hdd_err_rl("invalid hdd ctx");
77 		return ret;
78 	}
79 
80 	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
81 					      buf, count);
82 
83 	if (ret) {
84 		hdd_err_rl("invalid input");
85 		return ret;
86 	}
87 
88 	sptr = buf_local;
89 	token = strsep(&sptr, " ");
90 	if (!token)
91 		return -EINVAL;
92 	if (kstrtou32(token, 0, &value))
93 		return -EINVAL;
94 
95 	hdd_debug("roam_trigger_bitmap: 0x%x", value);
96 
97 	ucfg_mlme_set_roaming_triggers(hdd_ctx->psoc, value);
98 
99 	return count;
100 }
101 
102 static ssize_t
hdd_sysfs_roam_trigger_bitmap_store(struct kobject * kobj,struct kobj_attribute * attr,char const * buf,size_t count)103 hdd_sysfs_roam_trigger_bitmap_store(struct kobject *kobj,
104 				    struct kobj_attribute *attr,
105 				    char const *buf, size_t count)
106 {
107 	struct osif_psoc_sync *psoc_sync;
108 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
109 	ssize_t errno_size;
110 
111 	if (!hdd_ctx) {
112 		hdd_err_rl("invalid input");
113 		return -EINVAL;
114 	}
115 
116 	errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
117 					     &psoc_sync);
118 	if (errno_size)
119 		return errno_size;
120 
121 	errno_size = __hdd_sysfs_roam_trigger_bitmap_store(hdd_ctx, attr,
122 							   buf, count);
123 
124 	osif_psoc_sync_op_stop(psoc_sync);
125 
126 	return errno_size;
127 }
128 
129 static struct kobj_attribute roam_trigger_bitmap_attribute =
130 	__ATTR(roam_trigger_bitmap, 0664, hdd_sysfs_roam_trigger_bitmap_show,
131 	       hdd_sysfs_roam_trigger_bitmap_store);
132 
hdd_sysfs_roam_trigger_bitmap_create(struct kobject * driver_kobject)133 int hdd_sysfs_roam_trigger_bitmap_create(struct kobject *driver_kobject)
134 {
135 	int error;
136 
137 	if (!driver_kobject) {
138 		hdd_err("could not get driver kobject!");
139 		return -EINVAL;
140 	}
141 
142 	error = sysfs_create_file(driver_kobject,
143 				  &roam_trigger_bitmap_attribute.attr);
144 	if (error)
145 		hdd_err("could not create roam_trigger_bitmap sysfs file");
146 
147 	return error;
148 }
149 
150 void
hdd_sysfs_roam_trigger_bitmap_destroy(struct kobject * driver_kobject)151 hdd_sysfs_roam_trigger_bitmap_destroy(struct kobject *driver_kobject)
152 {
153 	if (!driver_kobject) {
154 		hdd_err("could not get driver kobject!");
155 		return;
156 	}
157 	sysfs_remove_file(driver_kobject, &roam_trigger_bitmap_attribute.attr);
158 }
159