1 /*
2  * Copyright (c) 2011-2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <wlan_hdd_main.h>
19 #include <wlan_hdd_sysfs.h>
20 #include <wlan_hdd_sysfs_policy_mgr.h>
21 #include "osif_sync.h"
22 #include <wlan_policy_mgr_api.h>
23 #include <wma_api.h>
24 #include <wlan_policy_mgr_ucfg.h>
25 
hdd_pm_cinfo_show(struct hdd_context * hdd_ctx)26 static ssize_t hdd_pm_cinfo_show(struct hdd_context *hdd_ctx)
27 {
28 	struct policy_mgr_conc_connection_info *conn_info;
29 	uint32_t i = 0, len = 0;
30 
31 	hdd_enter();
32 
33 	if (!wlan_hdd_validate_modules_state(hdd_ctx))
34 		return -EINVAL;
35 
36 	conn_info = policy_mgr_get_conn_info(&len);
37 	pr_info("+--------------------------+\n");
38 	for (i = 0; i < len; i++) {
39 		if (!conn_info->in_use)
40 			continue;
41 
42 		pr_info("|table_index[%d]\t\t\n", i);
43 		pr_info("|\t|vdev_id - %-10d|\n", conn_info->vdev_id);
44 		pr_info("|\t|freq    - %-10d|\n", conn_info->freq);
45 		pr_info("|\t|bw      - %-10d|\n", conn_info->bw);
46 		pr_info("|\t|mode    - %-10d|\n", conn_info->mode);
47 		pr_info("|\t|mac_id  - %-10d|\n", conn_info->mac);
48 		pr_info("|\t|in_use  - %-10d|\n", conn_info->in_use);
49 		pr_info("+--------------------------+\n");
50 		conn_info++;
51 	}
52 
53 	pr_info("|\t|current state dbs - %-10d, sbs - %-10d|\n",
54 		policy_mgr_is_current_hwmode_dbs(hdd_ctx->psoc),
55 		policy_mgr_is_current_hwmode_sbs(hdd_ctx->psoc));
56 
57 	hdd_exit();
58 	return 0;
59 }
60 
hdd_sysfs_pm_cminfo_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)61 static ssize_t hdd_sysfs_pm_cminfo_show(struct kobject *kobj,
62 					struct kobj_attribute *attr,
63 					char *buf)
64 {
65 	struct osif_psoc_sync *psoc_sync;
66 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
67 	ssize_t err_size;
68 
69 	if (wlan_hdd_validate_context(hdd_ctx))
70 		return 0;
71 
72 	err_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
73 					   &psoc_sync);
74 	if (err_size)
75 		return err_size;
76 
77 	err_size = hdd_pm_cinfo_show(hdd_ctx);
78 
79 	osif_psoc_sync_op_stop(psoc_sync);
80 	return err_size;
81 }
82 
83 static ssize_t
__hdd_sysfs_pm_pcl_store(struct hdd_context * hdd_ctx,struct kobj_attribute * attr,const char * buf,size_t count)84 __hdd_sysfs_pm_pcl_store(struct hdd_context *hdd_ctx,
85 			 struct kobj_attribute *attr,
86 			 const char *buf,
87 			 size_t count)
88 {
89 	char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
90 	uint8_t weight_list[NUM_CHANNELS] = {0};
91 	uint32_t pcl[NUM_CHANNELS] = {0};
92 	uint32_t pcl_len = 0, val, i = 0;
93 	char *sptr, *token;
94 	QDF_STATUS status;
95 	int ret;
96 
97 	if (!wlan_hdd_validate_modules_state(hdd_ctx))
98 		return -EINVAL;
99 
100 	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
101 					      buf, count);
102 
103 	if (ret) {
104 		hdd_err_rl("invalid input");
105 		return ret;
106 	}
107 
108 	sptr = buf_local;
109 	hdd_debug("pm_pcl: count %zu buf_local:(%s)",
110 		  count, buf_local);
111 
112 	/* Get val */
113 	token = strsep(&sptr, " ");
114 	if (!token)
115 		return -EINVAL;
116 	if (kstrtou32(token, 0, &val))
117 		return -EINVAL;
118 
119 	if (!hdd_ctx->config->is_unit_test_framework_enabled) {
120 		hdd_warn_rl("UT framework is disabled");
121 		return -EINVAL;
122 	}
123 
124 	status = policy_mgr_get_pcl(hdd_ctx->psoc, val,
125 				    pcl, &pcl_len,
126 				    weight_list, QDF_ARRAY_SIZE(weight_list),
127 				    WLAN_INVALID_VDEV_ID);
128 
129 	if (status != QDF_STATUS_SUCCESS)
130 		hdd_err("can't get pcl policy manager");
131 
132 	hdd_debug("PCL Freq list for role[%d] is {", val);
133 	for (i = 0 ; i < pcl_len; i++)
134 		hdd_debug(" %d, ", pcl[i]);
135 	hdd_debug("}--------->\n");
136 
137 	return count;
138 }
139 
140 static ssize_t
hdd_sysfs_pm_pcl_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)141 hdd_sysfs_pm_pcl_store(struct kobject *kobj,
142 		       struct kobj_attribute *attr,
143 		       const char *buf,
144 		       size_t count)
145 {
146 	struct osif_psoc_sync *psoc_sync;
147 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
148 	ssize_t errno_size;
149 	int ret;
150 
151 	ret = wlan_hdd_validate_context(hdd_ctx);
152 	if (ret != 0)
153 		return ret;
154 
155 	errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
156 					     &psoc_sync);
157 	if (errno_size)
158 		return errno_size;
159 
160 	errno_size = __hdd_sysfs_pm_pcl_store(hdd_ctx, attr,
161 					      buf, count);
162 
163 	osif_psoc_sync_op_stop(psoc_sync);
164 
165 	return errno_size;
166 }
167 
168 static struct kobj_attribute pm_pcl_attribute =
169 	__ATTR(pm_pcl, 0220, NULL,
170 	       hdd_sysfs_pm_pcl_store);
171 
172 static struct kobj_attribute pm_cinfo_attribute =
173 	__ATTR(pm_cinfo, 0440,
174 	       hdd_sysfs_pm_cminfo_show, NULL);
175 
hdd_sysfs_pm_pcl_create(struct kobject * driver_kobject)176 int hdd_sysfs_pm_pcl_create(struct kobject *driver_kobject)
177 {
178 	int error;
179 
180 	if (!driver_kobject) {
181 		hdd_err("could not get driver kobject!");
182 		return -EINVAL;
183 	}
184 
185 	error = sysfs_create_file(driver_kobject,
186 				  &pm_pcl_attribute.attr);
187 	if (error)
188 		hdd_err("could not create pm_pcl sysfs file");
189 
190 	return error;
191 }
192 
193 void
hdd_sysfs_pm_pcl_destroy(struct kobject * driver_kobject)194 hdd_sysfs_pm_pcl_destroy(struct kobject *driver_kobject)
195 {
196 	if (!driver_kobject) {
197 		hdd_err("could not get driver kobject!");
198 		return;
199 	}
200 	sysfs_remove_file(driver_kobject, &pm_pcl_attribute.attr);
201 }
202 
hdd_sysfs_pm_cinfo_create(struct kobject * driver_kobject)203 void hdd_sysfs_pm_cinfo_create(struct kobject *driver_kobject)
204 {
205 	if (sysfs_create_file(driver_kobject, &pm_cinfo_attribute.attr))
206 		hdd_err("Failed to create pktlog sysfs entry");
207 }
208 
hdd_sysfs_pm_cinfo_destroy(struct kobject * driver_kobject)209 void hdd_sysfs_pm_cinfo_destroy(struct kobject *driver_kobject)
210 {
211 	sysfs_remove_file(driver_kobject, &pm_cinfo_attribute.attr);
212 }
213 
214