xref: /wlan-dirver/qcacld-3.0/core/hdd/src/wlan_hdd_sysfs.c (revision 263d0d22964f82bb97b269d96e2b995b107f2e72)
1 /*
2  * Copyright (c) 2017-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
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  *  DOC: wlan_hdd_sysfs.c
22  *
23  *  WLAN Host Device Driver implementation
24  *
25  */
26 
27 #include <linux/module.h>
28 #include <linux/kobject.h>
29 #include <linux/fs.h>
30 #include <linux/string.h>
31 #include "wlan_hdd_includes.h"
32 #include "wlan_hdd_sysfs.h"
33 #include "qwlan_version.h"
34 #include "cds_api.h"
35 #include <wlan_osif_request_manager.h>
36 #include <qdf_mem.h>
37 #ifdef WLAN_POWER_DEBUG
38 #include <sir_api.h>
39 #endif
40 #include "osif_sync.h"
41 #include "wlan_hdd_sysfs_sta_info.h"
42 #include "wlan_hdd_sysfs_channel.h"
43 #include <wlan_hdd_sysfs_fw_mode_config.h>
44 #include <wlan_hdd_sysfs_reassoc.h>
45 #include <wlan_hdd_sysfs_mem_stats.h>
46 #include "wlan_hdd_sysfs_crash_inject.h"
47 #include "wlan_hdd_sysfs_suspend_resume.h"
48 #include "wlan_hdd_sysfs_unit_test.h"
49 #include "wlan_hdd_sysfs_modify_acl.h"
50 #include "wlan_hdd_sysfs_connect_info.h"
51 #include <wlan_hdd_sysfs_scan_disable.h>
52 #include "wlan_hdd_sysfs_dcm.h"
53 #include <wlan_hdd_sysfs_wow_ito.h>
54 #include <wlan_hdd_sysfs_wowl_add_ptrn.h>
55 #include <wlan_hdd_sysfs_wowl_del_ptrn.h>
56 #include <wlan_hdd_sysfs_tx_stbc.h>
57 #include <wlan_hdd_sysfs_wlan_dbg.h>
58 #include <wlan_hdd_sysfs_txrx_fw_st_rst.h>
59 #include <wlan_hdd_sysfs_gtx_bw_mask.h>
60 #include <wlan_hdd_sysfs_scan_config.h>
61 #include <wlan_hdd_sysfs_monitor_mode_channel.h>
62 #include <wlan_hdd_sysfs_range_ext.h>
63 #include <wlan_hdd_sysfs_radar.h>
64 #include <wlan_hdd_sysfs_rts_cts.h>
65 #include <wlan_hdd_sysfs_he_bss_color.h>
66 #include <wlan_hdd_sysfs_txrx_fw_stats.h>
67 #include <wlan_hdd_sysfs_txrx_stats.h>
68 #include <wlan_hdd_sysfs_dp_trace.h>
69 #include <wlan_hdd_sysfs_stats.h>
70 #include <wlan_hdd_sysfs_tdls_peers.h>
71 #include <wlan_hdd_sysfs_temperature.h>
72 #include <wlan_hdd_sysfs_thermal_cfg.h>
73 #include <wlan_hdd_sysfs_motion_detection.h>
74 #include <wlan_hdd_sysfs_ipa.h>
75 #include <wlan_hdd_sysfs_pkt_log.h>
76 #include <wlan_hdd_sysfs_policy_mgr.h>
77 #include <wlan_hdd_sysfs_dp_aggregation.h>
78 #include <wlan_hdd_sysfs_dl_modes.h>
79 #include <wlan_hdd_sysfs_swlm.h>
80 #include <wlan_hdd_sysfs_dump_in_progress.h>
81 #include <wlan_hdd_sysfs_txrx_stats_console.h>
82 #include <wlan_hdd_sysfs_add_timestamp.h>
83 #include "wma_api.h"
84 #include "wlan_hdd_eht.h"
85 #include <wlan_hdd_sysfs_bmiss.h>
86 #include <wlan_hdd_sysfs_get_freq_for_pwr.h>
87 #include <wlan_hdd_sysfs_dp_tx_delay_stats.h>
88 #include <wlan_hdd_sysfs_wifi_features.h>
89 #include <wlan_hdd_sysfs_dp_traffic_end_indication.h>
90 #include <wlan_hdd_sysfs_eht_rate.h>
91 #include <wlan_hdd_sysfs_direct_link_ut_cmd.h>
92 #include <wlan_hdd_sysfs_runtime_pm.h>
93 #include <wlan_hdd_sysfs_log_buffer.h>
94 #include <wlan_hdd_sysfs_dfsnol.h>
95 
96 #define MAX_PSOC_ID_SIZE 10
97 
98 #ifdef MULTI_IF_NAME
99 #define DRIVER_NAME MULTI_IF_NAME
100 #else
101 #define DRIVER_NAME "wifi"
102 #endif
103 
104 static struct kobject *wlan_kobject;
105 static struct kobject *driver_kobject;
106 static struct kobject *fw_kobject;
107 static struct kobject *psoc_kobject;
108 static struct kobject *wifi_kobject;
109 
110 int
111 hdd_sysfs_validate_and_copy_buf(char *dest_buf, size_t dest_buf_size,
112 				char const *source_buf, size_t source_buf_size)
113 {
114 	if (source_buf_size > (dest_buf_size - 1)) {
115 		hdd_err_rl("Command length is larger than %zu bytes",
116 			   dest_buf_size);
117 		return -EINVAL;
118 	}
119 
120 	/* sysfs already provides kernel space buffer so copy from user
121 	 * is not needed. Doing this extra copy operation just to ensure
122 	 * the local buf is properly null-terminated.
123 	 */
124 	strlcpy(dest_buf, source_buf, dest_buf_size);
125 	/* default 'echo' cmd takes new line character to here */
126 	if (dest_buf[source_buf_size - 1] == '\n')
127 		dest_buf[source_buf_size - 1] = '\0';
128 
129 	return 0;
130 }
131 
132 static ssize_t __show_driver_version(char *buf)
133 {
134 	return scnprintf(buf, PAGE_SIZE, QWLAN_VERSIONSTR);
135 }
136 
137 static ssize_t show_driver_version(struct kobject *kobj,
138 				   struct kobj_attribute *attr,
139 				   char *buf)
140 {
141 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
142 	struct osif_psoc_sync *psoc_sync;
143 	ssize_t length;
144 	int errno;
145 
146 	errno = wlan_hdd_validate_context(hdd_ctx);
147 	if (errno)
148 		return errno;
149 
150 	errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync);
151 	if (errno)
152 		return errno;
153 
154 	length = __show_driver_version(buf);
155 
156 	osif_psoc_sync_op_stop(psoc_sync);
157 
158 	return length;
159 }
160 
161 static ssize_t __show_fw_version(struct hdd_context *hdd_ctx,
162 				 char *buf)
163 {
164 	hdd_debug("Rcvd req for FW version");
165 
166 	return scnprintf(buf, PAGE_SIZE,
167 			 "FW:%d.%d.%d.%d.%d.%d HW:%s Board version: %x Ref design id: %x Customer id: %x Project id: %x Board Data Rev: %x\n",
168 			 hdd_ctx->fw_version_info.major_spid,
169 			 hdd_ctx->fw_version_info.minor_spid,
170 			 hdd_ctx->fw_version_info.siid,
171 			 hdd_ctx->fw_version_info.rel_id,
172 			 hdd_ctx->fw_version_info.crmid,
173 			 hdd_ctx->fw_version_info.sub_id,
174 			 hdd_ctx->target_hw_name,
175 			 hdd_ctx->hw_bd_info.bdf_version,
176 			 hdd_ctx->hw_bd_info.ref_design_id,
177 			 hdd_ctx->hw_bd_info.customer_id,
178 			 hdd_ctx->hw_bd_info.project_id,
179 			 hdd_ctx->hw_bd_info.board_data_rev);
180 }
181 
182 static ssize_t show_fw_version(struct kobject *kobj,
183 			       struct kobj_attribute *attr,
184 			       char *buf)
185 {
186 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
187 	struct osif_psoc_sync *psoc_sync;
188 	ssize_t length;
189 	int errno;
190 
191 	errno = wlan_hdd_validate_context(hdd_ctx);
192 	if (errno)
193 		return errno;
194 
195 	errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync);
196 	if (errno)
197 		return errno;
198 
199 	length = __show_fw_version(hdd_ctx, buf);
200 
201 	osif_psoc_sync_op_stop(psoc_sync);
202 
203 	return length;
204 };
205 
206 #ifdef WLAN_POWER_DEBUG
207 struct power_stats_priv {
208 	struct power_stats_response power_stats;
209 };
210 
211 static void hdd_power_debugstats_dealloc(void *priv)
212 {
213 	struct power_stats_priv *stats = priv;
214 
215 	qdf_mem_free(stats->power_stats.debug_registers);
216 	stats->power_stats.debug_registers = NULL;
217 }
218 
219 static void hdd_power_debugstats_cb(struct power_stats_response *response,
220 				    void *context)
221 {
222 	struct osif_request *request;
223 	struct power_stats_priv *priv;
224 	uint32_t *debug_registers;
225 	uint32_t debug_registers_len;
226 
227 	hdd_enter();
228 
229 	request = osif_request_get(context);
230 	if (!request) {
231 		hdd_err("Obsolete request");
232 		return;
233 	}
234 
235 	priv = osif_request_priv(request);
236 
237 	/* copy fixed-sized data */
238 	priv->power_stats = *response;
239 
240 	/* copy variable-size data */
241 	if (response->num_debug_register) {
242 		debug_registers_len = (sizeof(response->debug_registers[0]) *
243 				       response->num_debug_register);
244 		debug_registers = qdf_mem_malloc(debug_registers_len);
245 		priv->power_stats.debug_registers = debug_registers;
246 		if (debug_registers) {
247 			qdf_mem_copy(debug_registers,
248 				     response->debug_registers,
249 				     debug_registers_len);
250 		} else {
251 			hdd_err("Power stats memory alloc fails!");
252 			priv->power_stats.num_debug_register = 0;
253 		}
254 	}
255 	osif_request_complete(request);
256 	osif_request_put(request);
257 	hdd_exit();
258 }
259 
260 static ssize_t __show_device_power_stats(struct hdd_context *hdd_ctx,
261 					 char *buf)
262 {
263 	QDF_STATUS status;
264 	struct power_stats_response *chip_power_stats;
265 	ssize_t ret_cnt = 0;
266 	int j;
267 	void *cookie;
268 	struct osif_request *request;
269 	struct power_stats_priv *priv;
270 	static const struct osif_request_params params = {
271 		.priv_size = sizeof(*priv),
272 		.timeout_ms = WLAN_WAIT_TIME_STATS,
273 		.dealloc = hdd_power_debugstats_dealloc,
274 	};
275 
276 	hdd_enter();
277 
278 	request = osif_request_alloc(&params);
279 	if (!request) {
280 		hdd_err("Request allocation failure");
281 		return -ENOMEM;
282 	}
283 	cookie = osif_request_cookie(request);
284 
285 	status = sme_power_debug_stats_req(hdd_ctx->mac_handle,
286 					   hdd_power_debugstats_cb,
287 					   cookie);
288 	if (QDF_IS_STATUS_ERROR(status)) {
289 		hdd_err("chip power stats request failed");
290 		ret_cnt = qdf_status_to_os_return(status);
291 		goto cleanup;
292 	}
293 
294 	ret_cnt = osif_request_wait_for_response(request);
295 	if (ret_cnt) {
296 		hdd_err("Target response timed out Power stats");
297 		sme_reset_power_debug_stats_cb(hdd_ctx->mac_handle);
298 		ret_cnt = -ETIMEDOUT;
299 		goto cleanup;
300 	}
301 	priv = osif_request_priv(request);
302 	chip_power_stats = &priv->power_stats;
303 
304 	ret_cnt += scnprintf(buf, PAGE_SIZE,
305 			"POWER DEBUG STATS\n=================\n"
306 			"cumulative_sleep_time_ms: %d\n"
307 			"cumulative_total_on_time_ms: %d\n"
308 			"deep_sleep_enter_counter: %d\n"
309 			"last_deep_sleep_enter_tstamp_ms: %d\n"
310 			"debug_register_fmt: %d\n"
311 			"num_debug_register: %d\n",
312 			chip_power_stats->cumulative_sleep_time_ms,
313 			chip_power_stats->cumulative_total_on_time_ms,
314 			chip_power_stats->deep_sleep_enter_counter,
315 			chip_power_stats->last_deep_sleep_enter_tstamp_ms,
316 			chip_power_stats->debug_register_fmt,
317 			chip_power_stats->num_debug_register);
318 
319 	for (j = 0; j < chip_power_stats->num_debug_register; j++) {
320 		if ((PAGE_SIZE - ret_cnt) > 0)
321 			ret_cnt += scnprintf(buf + ret_cnt,
322 					PAGE_SIZE - ret_cnt,
323 					"debug_registers[%d]: 0x%x\n", j,
324 					chip_power_stats->debug_registers[j]);
325 		else
326 			j = chip_power_stats->num_debug_register;
327 	}
328 
329 cleanup:
330 	osif_request_put(request);
331 	hdd_exit();
332 	return ret_cnt;
333 }
334 
335 static ssize_t show_device_power_stats(struct kobject *kobj,
336 				       struct kobj_attribute *attr,
337 				       char *buf)
338 {
339 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
340 	struct osif_psoc_sync *psoc_sync;
341 	ssize_t length;
342 	int errno;
343 
344 	errno = wlan_hdd_validate_context(hdd_ctx);
345 	if (errno)
346 		return errno;
347 
348 	errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync);
349 	if (errno)
350 		return errno;
351 
352 	length = __show_device_power_stats(hdd_ctx, buf);
353 
354 	osif_psoc_sync_op_stop(psoc_sync);
355 
356 	return length;
357 }
358 #endif
359 
360 #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS
361 struct beacon_reception_stats_priv {
362 	struct bcn_reception_stats_rsp beacon_stats;
363 };
364 
365 static void hdd_beacon_debugstats_cb(struct bcn_reception_stats_rsp
366 				     *response,
367 				     void *context)
368 {
369 	struct osif_request *request;
370 	struct beacon_reception_stats_priv *priv;
371 
372 	hdd_enter();
373 
374 	request = osif_request_get(context);
375 	if (!request) {
376 		hdd_err("Obsolete request");
377 		return;
378 	}
379 
380 	priv = osif_request_priv(request);
381 
382 	/* copy fixed-sized data */
383 	priv->beacon_stats = *response;
384 
385 	osif_request_complete(request);
386 	osif_request_put(request);
387 	hdd_exit();
388 }
389 
390 static ssize_t __show_beacon_reception_stats(struct net_device *net_dev,
391 					     char *buf)
392 {
393 	struct hdd_adapter *adapter = netdev_priv(net_dev);
394 	struct bcn_reception_stats_rsp *beacon_stats;
395 	int ret_val, j;
396 	void *cookie;
397 	struct osif_request *request;
398 	struct beacon_reception_stats_priv *priv;
399 	static const struct osif_request_params params = {
400 		.priv_size = sizeof(*priv),
401 		.timeout_ms = WLAN_WAIT_TIME_STATS,
402 	};
403 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
404 	QDF_STATUS status;
405 
406 	ret_val = wlan_hdd_validate_context(hdd_ctx);
407 	if (ret_val)
408 		return ret_val;
409 
410 	if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
411 		hdd_err("Invalid adapter or adapter has invalid magic");
412 		return -EINVAL;
413 	}
414 
415 	if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
416 		hdd_err("Interface is not enabled");
417 		return -EINVAL;
418 	}
419 
420 	if (!(adapter->device_mode == QDF_STA_MODE ||
421 	      adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
422 		hdd_err("Beacon Reception Stats only supported in STA or P2P CLI modes!");
423 		return -ENOTSUPP;
424 	}
425 
426 	if (!hdd_cm_is_vdev_associated(adapter->deflink)) {
427 		hdd_err("Adapter is not in connected state");
428 		return -EINVAL;
429 	}
430 
431 	request = osif_request_alloc(&params);
432 	if (!request) {
433 		hdd_err("Request allocation failure");
434 		return -ENOMEM;
435 	}
436 	cookie = osif_request_cookie(request);
437 
438 	status = sme_beacon_debug_stats_req(hdd_ctx->mac_handle,
439 					    adapter->deflink->vdev_id,
440 					   hdd_beacon_debugstats_cb,
441 					   cookie);
442 	if (QDF_IS_STATUS_ERROR(status)) {
443 		hdd_err("chip power stats request failed");
444 		ret_val = -EINVAL;
445 		goto cleanup;
446 	}
447 
448 	ret_val = osif_request_wait_for_response(request);
449 	if (ret_val) {
450 		hdd_err("Target response timed out Power stats");
451 		ret_val = -ETIMEDOUT;
452 		goto cleanup;
453 	}
454 	priv = osif_request_priv(request);
455 	beacon_stats = &priv->beacon_stats;
456 
457 	ret_val += scnprintf(buf, PAGE_SIZE,
458 			"BEACON RECEPTION STATS\n=================\n"
459 			"vdev id: %u\n"
460 			"Total Beacon Count: %u\n"
461 			"Total Beacon Miss Count: %u\n",
462 			beacon_stats->vdev_id,
463 			beacon_stats->total_bcn_cnt,
464 			beacon_stats->total_bmiss_cnt);
465 
466 	ret_val += scnprintf(buf + ret_val, PAGE_SIZE - ret_val,
467 			     "Beacon Miss Bit map ");
468 
469 	for (j = 0; j < MAX_BCNMISS_BITMAP; j++) {
470 		if ((PAGE_SIZE - ret_val) > 0) {
471 			ret_val += scnprintf(buf + ret_val,
472 					     PAGE_SIZE - ret_val,
473 					     "[0x%x] ",
474 					     beacon_stats->bmiss_bitmap[j]);
475 		}
476 	}
477 
478 	if ((PAGE_SIZE - ret_val) > 0)
479 		ret_val += scnprintf(buf + ret_val,
480 				     PAGE_SIZE - ret_val,
481 				     "\n");
482 cleanup:
483 	osif_request_put(request);
484 	hdd_exit();
485 	return ret_val;
486 }
487 
488 static ssize_t show_beacon_reception_stats(struct device *dev,
489 					   struct device_attribute *attr,
490 					   char *buf)
491 {
492 	struct net_device *net_dev = container_of(dev, struct net_device, dev);
493 	struct osif_vdev_sync *vdev_sync;
494 	ssize_t err_size;
495 
496 	err_size = osif_vdev_sync_op_start(net_dev, &vdev_sync);
497 	if (err_size)
498 		return err_size;
499 
500 	err_size = __show_beacon_reception_stats(net_dev, buf);
501 
502 	osif_vdev_sync_op_stop(vdev_sync);
503 
504 	return err_size;
505 }
506 
507 static DEVICE_ATTR(beacon_stats, 0444,
508 		   show_beacon_reception_stats, NULL);
509 #endif
510 
511 static struct kobj_attribute dr_ver_attribute =
512 	__ATTR(driver_version, 0440, show_driver_version, NULL);
513 static struct kobj_attribute fw_ver_attribute =
514 	__ATTR(version, 0440, show_fw_version, NULL);
515 #ifdef WLAN_POWER_DEBUG
516 static struct kobj_attribute power_stats_attribute =
517 	__ATTR(power_stats, 0444, show_device_power_stats, NULL);
518 #endif
519 
520 static void hdd_sysfs_create_version_interface(struct wlan_objmgr_psoc *psoc)
521 {
522 	int error = 0;
523 	uint32_t psoc_id;
524 	char buf[MAX_PSOC_ID_SIZE];
525 
526 	if (!driver_kobject || !wlan_kobject) {
527 		hdd_err("could not get driver kobject!");
528 		return;
529 	}
530 
531 	error = sysfs_create_file(wlan_kobject, &dr_ver_attribute.attr);
532 	if (error) {
533 		hdd_err("could not create wlan sysfs file");
534 		return;
535 	}
536 
537 	fw_kobject = kobject_create_and_add("fw", wlan_kobject);
538 	if (!fw_kobject) {
539 		hdd_err("could not allocate fw kobject");
540 		goto free_fw_kobj;
541 	}
542 
543 	psoc_id = wlan_psoc_get_nif_phy_version(psoc);
544 	scnprintf(buf, PAGE_SIZE, "%d", psoc_id);
545 
546 	psoc_kobject = kobject_create_and_add(buf, fw_kobject);
547 	if (!psoc_kobject) {
548 		hdd_err("could not allocate psoc kobject");
549 		goto free_fw_kobj;
550 	}
551 
552 	error = sysfs_create_file(psoc_kobject, &fw_ver_attribute.attr);
553 	if (error) {
554 		hdd_err("could not create fw sysfs file");
555 		goto free_psoc_kobj;
556 	}
557 
558 	return;
559 
560 free_psoc_kobj:
561 	kobject_put(psoc_kobject);
562 	psoc_kobject = NULL;
563 
564 free_fw_kobj:
565 	kobject_put(fw_kobject);
566 	fw_kobject = NULL;
567 }
568 
569 static void hdd_sysfs_destroy_version_interface(void)
570 {
571 	if (psoc_kobject) {
572 		kobject_put(psoc_kobject);
573 		psoc_kobject = NULL;
574 		kobject_put(fw_kobject);
575 		fw_kobject = NULL;
576 	}
577 }
578 
579 #ifdef WLAN_POWER_DEBUG
580 static void hdd_sysfs_create_powerstats_interface(void)
581 {
582 	int error;
583 
584 	if (!driver_kobject) {
585 		hdd_err("could not get driver kobject!");
586 		return;
587 	}
588 
589 	error = sysfs_create_file(driver_kobject, &power_stats_attribute.attr);
590 	if (error)
591 		hdd_err("could not create power_stats sysfs file");
592 }
593 
594 static void hdd_sysfs_destroy_powerstats_interface(void)
595 {
596 	if (!driver_kobject) {
597 		hdd_err("could not get driver kobject!");
598 		return;
599 	}
600 	sysfs_remove_file(driver_kobject, &power_stats_attribute.attr);
601 }
602 #else
603 static void hdd_sysfs_create_powerstats_interface(void)
604 {
605 }
606 
607 static void hdd_sysfs_destroy_powerstats_interface(void)
608 {
609 }
610 #endif
611 
612 static ssize_t
613 hdd_sysfs_wakeup_logs_to_console_store(struct kobject *kobj,
614 				       struct kobj_attribute *attr,
615 				       char const *buf, size_t count)
616 {
617 	char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
618 	int ret, value;
619 	char *sptr, *token;
620 
621 	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
622 					      buf, count);
623 	if (ret) {
624 		hdd_err_rl("invalid input");
625 		return ret;
626 	}
627 
628 	sptr = buf_local;
629 	token = strsep(&sptr, " ");
630 	if (!token)
631 		return -EINVAL;
632 	if (kstrtou32(token, 0, &value))
633 		return -EINVAL;
634 
635 	wma_set_wakeup_logs_to_console(value);
636 
637 	return count;
638 }
639 
640 static struct kobj_attribute wakeup_logs_to_console_attribute =
641 	__ATTR(wakeup_logs_to_console, 0220, NULL,
642 	       hdd_sysfs_wakeup_logs_to_console_store);
643 
644 static void hdd_sysfs_create_wakeup_logs_to_console(void)
645 {
646 	int error;
647 
648 	if (!driver_kobject) {
649 		hdd_err("could not get driver kobject!");
650 		return;
651 	}
652 
653 	error = sysfs_create_file(driver_kobject,
654 				  &wakeup_logs_to_console_attribute.attr);
655 	if (error)
656 		hdd_err("could not create power_stats sysfs file");
657 }
658 
659 static void hdd_sysfs_destroy_wakeup_logs_to_console(void)
660 {
661 	if (!driver_kobject) {
662 		hdd_err("could not get driver kobject!");
663 		return;
664 	}
665 	sysfs_remove_file(driver_kobject,
666 			  &wakeup_logs_to_console_attribute.attr);
667 }
668 
669 static void hdd_sysfs_create_driver_root_obj(void)
670 {
671 	driver_kobject = kobject_create_and_add(DRIVER_NAME, kernel_kobj);
672 	if (!driver_kobject) {
673 		hdd_err("could not allocate driver kobject");
674 		return;
675 	}
676 
677 	wlan_kobject = kobject_create_and_add("wlan", driver_kobject);
678 	if (!wlan_kobject) {
679 		hdd_err("could not allocate wlan kobject");
680 		kobject_put(driver_kobject);
681 		driver_kobject = NULL;
682 	}
683 }
684 
685 static void hdd_sysfs_destroy_driver_root_obj(void)
686 {
687 	if (wlan_kobject) {
688 		kobject_put(wlan_kobject);
689 		wlan_kobject = NULL;
690 	}
691 
692 	if (driver_kobject) {
693 		kobject_put(driver_kobject);
694 		driver_kobject = NULL;
695 	}
696 }
697 
698 void hdd_sysfs_create_wifi_root_obj(void)
699 {
700 	if (wifi_kobject) {
701 		hdd_debug("wifi kobj already created");
702 		return;
703 	}
704 	wifi_kobject = pld_get_wifi_kobj(NULL);
705 	if (wifi_kobject) {
706 		hdd_debug("wifi_kobject created by platform");
707 		return;
708 	}
709 	wifi_kobject = kobject_create_and_add("wifi", NULL);
710 	if (!wifi_kobject)
711 		hdd_err("could not allocate wifi kobject");
712 }
713 
714 void hdd_sysfs_destroy_wifi_root_obj(void)
715 {
716 	if (pld_get_wifi_kobj(NULL)) {
717 		hdd_debug("wifi_kobject created by platform");
718 		wifi_kobject = NULL;
719 		return;
720 	}
721 
722 	if (!wifi_kobject) {
723 		hdd_err("could not get wifi kobject!");
724 		return;
725 	}
726 	kobject_put(wifi_kobject);
727 	wifi_kobject = NULL;
728 }
729 
730 void hdd_create_wifi_feature_interface_sysfs_file(void)
731 {
732 	hdd_sysfs_create_wifi_feature_interface(wifi_kobject);
733 }
734 
735 void hdd_destroy_wifi_feature_interface_sysfs_file(void)
736 {
737 	hdd_sysfs_destroy_wifi_feature_interface(wifi_kobject);
738 }
739 
740 int hdd_sysfs_print(void *ctx, const char *fmt, ...)
741 {
742 	va_list args;
743 	int ret = -1;
744 	struct hdd_sysfs_print_ctx *p_ctx = ctx;
745 
746 	va_start(args, fmt);
747 
748 	if (ctx) {
749 		ret = vscnprintf(p_ctx->buf + p_ctx->idx,
750 				 PAGE_SIZE - p_ctx->idx, fmt, args);
751 		p_ctx->idx += ret;
752 		if (p_ctx->new_line) {
753 			ret += scnprintf(p_ctx->buf + p_ctx->idx,
754 					  PAGE_SIZE - p_ctx->idx,
755 					  "\n");
756 			p_ctx->idx += ret;
757 		}
758 	}
759 
760 	va_end(args);
761 	return ret;
762 }
763 
764 #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS
765 static int hdd_sysfs_create_bcn_reception_interface(struct hdd_adapter
766 						     *adapter)
767 {
768 	int error;
769 
770 	error = device_create_file(&adapter->dev->dev, &dev_attr_beacon_stats);
771 	if (error)
772 		hdd_err("could not create beacon stats sysfs file");
773 
774 	return error;
775 }
776 
777 static void hdd_sysfs_destroy_bcn_reception_interface(struct hdd_adapter
778 						      *adapter)
779 {
780 	device_remove_file(&adapter->dev->dev, &dev_attr_beacon_stats);
781 }
782 #else /* !WLAN_FEATURE_BEACON_RECEPTION_STATS */
783 static inline int
784 hdd_sysfs_create_bcn_reception_interface(struct hdd_adapter *adapter)
785 {
786 	return 0;
787 }
788 
789 static inline void
790 hdd_sysfs_destroy_bcn_reception_interface(struct hdd_adapter *adapter)
791 {
792 }
793 
794 #endif /* WLAN_FEATURE_BEACON_RECEPTION_STATS */
795 
796 static void
797 hdd_sysfs_create_sta_adapter_root_obj(struct hdd_adapter *adapter)
798 {
799 	hdd_sysfs_create_bcn_reception_interface(adapter);
800 	hdd_sysfs_reassoc_create(adapter);
801 	hdd_sysfs_crash_inject_create(adapter);
802 	hdd_sysfs_suspend_create(adapter);
803 	hdd_sysfs_resume_create(adapter);
804 	hdd_sysfs_unit_test_target_create(adapter);
805 	hdd_sysfs_connect_info_interface_create(adapter);
806 	hdd_sysfs_dcm_create(adapter);
807 	hdd_sysfs_wowl_add_ptrn_create(adapter);
808 	hdd_sysfs_wowl_del_ptrn_create(adapter);
809 	hdd_sysfs_tx_stbc_create(adapter);
810 	hdd_sysfs_txrx_fw_st_rst_create(adapter);
811 	hdd_sysfs_gtx_bw_mask_create(adapter);
812 	hdd_sysfs_rts_cts_create(adapter);
813 	hdd_sysfs_stats_create(adapter);
814 	hdd_sysfs_txrx_fw_stats_create(adapter);
815 	hdd_sysfs_txrx_stats_create(adapter);
816 	hdd_sysfs_tdls_peers_interface_create(adapter);
817 	hdd_sysfs_temperature_create(adapter);
818 	hdd_sysfs_motion_detection_create(adapter);
819 	hdd_sysfs_range_ext_create(adapter);
820 	hdd_sysfs_dl_modes_create(adapter);
821 	hdd_sysfs_11be_rate_create(adapter);
822 	hdd_sysfs_bmiss_create(adapter);
823 	hdd_sysfs_dp_tx_delay_stats_create(adapter);
824 }
825 
826 static void
827 hdd_sysfs_destroy_sta_adapter_root_obj(struct hdd_adapter *adapter)
828 {
829 	hdd_sysfs_dp_tx_delay_stats_destroy(adapter);
830 	hdd_sysfs_bmiss_destroy(adapter);
831 	hdd_sysfs_11be_rate_destroy(adapter);
832 	hdd_sysfs_dl_modes_destroy(adapter);
833 	hdd_sysfs_range_ext_destroy(adapter);
834 	hdd_sysfs_motion_detection_destroy(adapter);
835 	hdd_sysfs_temperature_destroy(adapter);
836 	hdd_sysfs_tdls_peers_interface_destroy(adapter);
837 	hdd_sysfs_txrx_stats_destroy(adapter);
838 	hdd_sysfs_txrx_fw_stats_destroy(adapter);
839 	hdd_sysfs_stats_destroy(adapter);
840 	hdd_sysfs_rts_cts_destroy(adapter);
841 	hdd_sysfs_gtx_bw_mask_destroy(adapter);
842 	hdd_sysfs_txrx_fw_st_rst_destroy(adapter);
843 	hdd_sysfs_tx_stbc_destroy(adapter);
844 	hdd_sysfs_wowl_del_ptrn_destroy(adapter);
845 	hdd_sysfs_wowl_add_ptrn_destroy(adapter);
846 	hdd_sysfs_dcm_destroy(adapter);
847 	hdd_sysfs_connect_info_interface_destroy(adapter);
848 	hdd_sysfs_unit_test_target_destroy(adapter);
849 	hdd_sysfs_resume_destroy(adapter);
850 	hdd_sysfs_suspend_destroy(adapter);
851 	hdd_sysfs_crash_inject_destroy(adapter);
852 	hdd_sysfs_reassoc_destroy(adapter);
853 	hdd_sysfs_destroy_bcn_reception_interface(adapter);
854 }
855 
856 static void
857 hdd_sysfs_create_sap_adapter_root_obj(struct hdd_adapter *adapter)
858 {
859 	hdd_sysfs_channel_interface_create(adapter);
860 	hdd_sysfs_sta_info_interface_create(adapter);
861 	hdd_sysfs_crash_inject_create(adapter);
862 	hdd_sysfs_suspend_create(adapter);
863 	hdd_sysfs_resume_create(adapter);
864 	hdd_sysfs_unit_test_target_create(adapter);
865 	hdd_sysfs_modify_acl_create(adapter);
866 	hdd_sysfs_connect_info_interface_create(adapter);
867 	hdd_sysfs_tx_stbc_create(adapter);
868 	hdd_sysfs_txrx_fw_st_rst_create(adapter);
869 	hdd_sysfs_gtx_bw_mask_create(adapter);
870 	hdd_sysfs_dcm_create(adapter);
871 	hdd_sysfs_radar_create(adapter);
872 	hdd_sysfs_rts_cts_create(adapter);
873 	hdd_sysfs_stats_create(adapter);
874 	hdd_sysfs_he_bss_color_create(adapter);
875 	hdd_sysfs_txrx_fw_stats_create(adapter);
876 	hdd_sysfs_txrx_stats_create(adapter);
877 	hdd_sysfs_temperature_create(adapter);
878 	hdd_sysfs_range_ext_create(adapter);
879 	hdd_sysfs_ipa_create(adapter);
880 	hdd_sysfs_dl_modes_create(adapter);
881 	hdd_sysfs_11be_rate_create(adapter);
882 	hdd_sysfs_dp_tx_delay_stats_create(adapter);
883 	hdd_sysfs_dp_traffic_end_indication_create(adapter);
884 	hdd_sysfs_direct_link_ut_cmd_create(adapter);
885 	hdd_sysfs_dfsnol_create(adapter);
886 }
887 
888 static void
889 hdd_sysfs_destroy_sap_adapter_root_obj(struct hdd_adapter *adapter)
890 {
891 	hdd_sysfs_dfsnol_destroy(adapter);
892 	hdd_sysfs_direct_link_ut_destroy(adapter);
893 	hdd_sysfs_dp_traffic_end_indication_destroy(adapter);
894 	hdd_sysfs_dp_tx_delay_stats_destroy(adapter);
895 	hdd_sysfs_11be_rate_destroy(adapter);
896 	hdd_sysfs_dl_modes_destroy(adapter);
897 	hdd_sysfs_ipa_destroy(adapter);
898 	hdd_sysfs_range_ext_destroy(adapter);
899 	hdd_sysfs_temperature_destroy(adapter);
900 	hdd_sysfs_txrx_stats_destroy(adapter);
901 	hdd_sysfs_txrx_fw_stats_destroy(adapter);
902 	hdd_sysfs_he_bss_color_destroy(adapter);
903 	hdd_sysfs_stats_destroy(adapter);
904 	hdd_sysfs_rts_cts_destroy(adapter);
905 	hdd_sysfs_radar_destroy(adapter);
906 	hdd_sysfs_dcm_destroy(adapter);
907 	hdd_sysfs_gtx_bw_mask_destroy(adapter);
908 	hdd_sysfs_txrx_fw_st_rst_destroy(adapter);
909 	hdd_sysfs_tx_stbc_destroy(adapter);
910 	hdd_sysfs_connect_info_interface_destroy(adapter);
911 	hdd_sysfs_modify_acl_destroy(adapter);
912 	hdd_sysfs_unit_test_target_destroy(adapter);
913 	hdd_sysfs_resume_destroy(adapter);
914 	hdd_sysfs_suspend_destroy(adapter);
915 	hdd_sysfs_crash_inject_destroy(adapter);
916 	hdd_sysfs_sta_info_interface_destroy(adapter);
917 	hdd_sysfs_channel_interface_destroy(adapter);
918 }
919 
920 static void
921 hdd_sysfs_create_monitor_adapter_root_obj(struct hdd_adapter *adapter)
922 {
923 	hdd_sysfs_monitor_mode_channel_create(adapter);
924 }
925 
926 static void
927 hdd_sysfs_destroy_monitor_adapter_root_obj(struct hdd_adapter *adapter)
928 {
929 	hdd_sysfs_monitor_mode_channel_destroy(adapter);
930 }
931 
932 void hdd_create_sysfs_files(struct hdd_context *hdd_ctx)
933 {
934 	hdd_sysfs_create_driver_root_obj();
935 	hdd_sysfs_create_version_interface(hdd_ctx->psoc);
936 	hdd_sysfs_mem_stats_create(wlan_kobject);
937 	if  (QDF_GLOBAL_MISSION_MODE == hdd_get_conparam()) {
938 		hdd_sysfs_create_powerstats_interface();
939 		hdd_sysfs_create_dump_in_progress_interface(wifi_kobject);
940 		hdd_sysfs_fw_mode_config_create(driver_kobject);
941 		hdd_sysfs_scan_disable_create(driver_kobject);
942 		hdd_sysfs_wow_ito_create(driver_kobject);
943 		hdd_sysfs_wlan_dbg_create(driver_kobject);
944 		hdd_sysfs_scan_config_create(driver_kobject);
945 		hdd_sysfs_dp_trace_create(driver_kobject);
946 		hdd_sysfs_thermal_cfg_create(driver_kobject);
947 		hdd_sysfs_pktlog_create(driver_kobject);
948 		hdd_sysfs_pm_cinfo_create(driver_kobject);
949 		hdd_sysfs_pm_pcl_create(driver_kobject);
950 		hdd_sysfs_dp_aggregation_create(driver_kobject);
951 		hdd_sysfs_dp_swlm_create(driver_kobject);
952 		hdd_sysfs_create_wakeup_logs_to_console();
953 		hdd_sysfs_dp_txrx_stats_sysfs_create(driver_kobject);
954 		hdd_sysfs_get_valid_freq_for_power_create(driver_kobject);
955 		hdd_sysfs_dp_pkt_add_ts_create(driver_kobject);
956 		hdd_sysfs_runtime_pm_create(driver_kobject);
957 		hdd_sysfs_log_buffer_create(driver_kobject);
958 	}
959 }
960 
961 void hdd_destroy_sysfs_files(void)
962 {
963 	if  (QDF_GLOBAL_MISSION_MODE == hdd_get_conparam()) {
964 		hdd_sysfs_log_buffer_destroy(driver_kobject);
965 		hdd_sysfs_runtime_pm_destroy(driver_kobject);
966 		hdd_sysfs_dp_pkt_add_ts_destroy(driver_kobject);
967 		hdd_sysfs_get_valid_freq_for_power_destroy(driver_kobject);
968 		hdd_sysfs_dp_txrx_stats_sysfs_destroy(driver_kobject);
969 		hdd_sysfs_destroy_wakeup_logs_to_console();
970 		hdd_sysfs_dp_swlm_destroy(driver_kobject);
971 		hdd_sysfs_dp_aggregation_destroy(driver_kobject);
972 		hdd_sysfs_pm_pcl_destroy(driver_kobject);
973 		hdd_sysfs_pm_cinfo_destroy(driver_kobject);
974 		hdd_sysfs_pktlog_destroy(driver_kobject);
975 		hdd_sysfs_thermal_cfg_destroy(driver_kobject);
976 		hdd_sysfs_dp_trace_destroy(driver_kobject);
977 		hdd_sysfs_scan_config_destroy(driver_kobject);
978 		hdd_sysfs_wlan_dbg_destroy(driver_kobject);
979 		hdd_sysfs_wow_ito_destroy(driver_kobject);
980 		hdd_sysfs_scan_disable_destroy(driver_kobject);
981 		hdd_sysfs_fw_mode_config_destroy(driver_kobject);
982 		hdd_sysfs_destroy_dump_in_progress_interface(wifi_kobject);
983 		hdd_sysfs_destroy_powerstats_interface();
984 	}
985 	hdd_sysfs_mem_stats_destroy(wlan_kobject);
986 	hdd_sysfs_destroy_version_interface();
987 	hdd_sysfs_destroy_driver_root_obj();
988 }
989 
990 static
991 void hdd_sysfs_create_ftm_adapter_root_obj(struct hdd_adapter *adapter)
992 {
993 	hdd_sysfs_unit_test_target_create(adapter);
994 }
995 
996 void hdd_create_adapter_sysfs_files(struct hdd_adapter *adapter)
997 {
998 	int device_mode = adapter->device_mode;
999 
1000 	if (hdd_adapter_is_link_adapter(adapter)) {
1001 		hdd_err("link adapter returning!!");
1002 		return;
1003 	}
1004 
1005 	switch (device_mode){
1006 	case QDF_STA_MODE:
1007 	case QDF_P2P_DEVICE_MODE:
1008 	case QDF_P2P_CLIENT_MODE:
1009 		hdd_sysfs_create_sta_adapter_root_obj(adapter);
1010 		break;
1011 	case QDF_SAP_MODE:
1012 	case QDF_P2P_GO_MODE:
1013 		hdd_sysfs_create_sap_adapter_root_obj(adapter);
1014 		break;
1015 	case QDF_MONITOR_MODE:
1016 		hdd_sysfs_create_monitor_adapter_root_obj(adapter);
1017 		break;
1018 	case QDF_FTM_MODE:
1019 		hdd_sysfs_create_ftm_adapter_root_obj(adapter);
1020 		break;
1021 	default:
1022 		break;
1023 	}
1024 }
1025 
1026 static
1027 void hdd_sysfs_destroy_ftm_adapter_root_obj(struct hdd_adapter *adapter)
1028 {
1029 	hdd_sysfs_unit_test_target_destroy(adapter);
1030 }
1031 
1032 void hdd_destroy_adapter_sysfs_files(struct hdd_adapter *adapter)
1033 {
1034 	int device_mode = adapter->device_mode;
1035 
1036 	if (hdd_adapter_is_link_adapter(adapter)) {
1037 		hdd_err("link adapter returning!!");
1038 		return;
1039 	}
1040 	switch (device_mode){
1041 	case QDF_STA_MODE:
1042 	case QDF_P2P_DEVICE_MODE:
1043 	case QDF_P2P_CLIENT_MODE:
1044 		hdd_sysfs_destroy_sta_adapter_root_obj(adapter);
1045 		break;
1046 	case QDF_SAP_MODE:
1047 	case QDF_P2P_GO_MODE:
1048 		hdd_sysfs_destroy_sap_adapter_root_obj(adapter);
1049 		break;
1050 	case QDF_MONITOR_MODE:
1051 		hdd_sysfs_destroy_monitor_adapter_root_obj(adapter);
1052 		break;
1053 	case QDF_FTM_MODE:
1054 		hdd_sysfs_destroy_ftm_adapter_root_obj(adapter);
1055 		break;
1056 	default:
1057 		break;
1058 	}
1059 }
1060