1 /*
2  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022 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_dump_in_progress.c
22  *
23  * Dump in progress sysfs implementation
24  */
25 
26 #include <linux/kobject.h>
27 
28 #include "wlan_hdd_includes.h"
29 #include "wlan_hdd_sysfs_dump_in_progress.h"
30 #include "wlan_hdd_sysfs.h"
31 #include "osif_sync.h"
32 
33 static ssize_t
__hdd_sysfs_dump_in_progress_store(struct hdd_context * hdd_ctx,struct kobj_attribute * attr,char const * buf,size_t count)34 __hdd_sysfs_dump_in_progress_store(struct hdd_context *hdd_ctx,
35 				   struct kobj_attribute *attr,
36 				   char const *buf, size_t count)
37 {
38 	char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
39 	char *sptr, *token;
40 	int value, ret;
41 
42 	if (!wlan_hdd_validate_modules_state(hdd_ctx))
43 		return -EINVAL;
44 
45 	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
46 					      buf, count);
47 	if (ret) {
48 		hdd_err_rl("invalid input");
49 		return ret;
50 	}
51 
52 	sptr = buf_local;
53 	/* Get value */
54 	token = strsep(&sptr, " ");
55 	if (!token)
56 		return -EINVAL;
57 	if (kstrtou32(token, 0, &value))
58 		return -EINVAL;
59 
60 	hdd_debug_rl("dump in progress %d", value);
61 	if (value < 0 || value > 1)
62 		return -EINVAL;
63 
64 	hdd_ctx->dump_in_progress = value;
65 
66 	return count;
67 }
68 
hdd_sysfs_dump_in_progress_store(struct kobject * kobj,struct kobj_attribute * attr,char const * buf,size_t count)69 static ssize_t hdd_sysfs_dump_in_progress_store(struct kobject *kobj,
70 						struct kobj_attribute *attr,
71 						char const *buf, size_t count)
72 {
73 	struct osif_psoc_sync *psoc_sync;
74 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
75 	ssize_t errno_size;
76 	int ret;
77 
78 	ret = wlan_hdd_validate_context(hdd_ctx);
79 	if (ret != 0)
80 		return ret;
81 
82 	errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
83 					     &psoc_sync);
84 	if (errno_size)
85 		return errno_size;
86 
87 	errno_size = __hdd_sysfs_dump_in_progress_store(hdd_ctx, attr,
88 							buf, count);
89 
90 	osif_psoc_sync_op_stop(psoc_sync);
91 
92 	return errno_size;
93 }
94 
__hdd_sysfs_dump_in_progress_show(struct hdd_context * hdd_ctx,struct kobj_attribute * attr,char * buf)95 static ssize_t  __hdd_sysfs_dump_in_progress_show(struct hdd_context *hdd_ctx,
96 						  struct kobj_attribute *attr,
97 						  char *buf)
98 {
99 	ssize_t ret_val;
100 
101 	hdd_debug_rl("dump in progress %d", hdd_ctx->dump_in_progress);
102 	ret_val = scnprintf(buf, PAGE_SIZE, "%d\n", hdd_ctx->dump_in_progress);
103 
104 	return ret_val;
105 }
106 
hdd_sysfs_dump_in_progress_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)107 static ssize_t hdd_sysfs_dump_in_progress_show(struct kobject *kobj,
108 					       struct kobj_attribute *attr,
109 					       char *buf)
110 {
111 	struct osif_psoc_sync *psoc_sync;
112 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
113 	ssize_t errno_size;
114 	int ret;
115 
116 	ret = wlan_hdd_validate_context(hdd_ctx);
117 	if (ret != 0)
118 		return ret;
119 
120 	errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
121 					     &psoc_sync);
122 	if (errno_size)
123 		return errno_size;
124 
125 	errno_size = __hdd_sysfs_dump_in_progress_show(hdd_ctx, attr, buf);
126 
127 	osif_psoc_sync_op_stop(psoc_sync);
128 
129 	return errno_size;
130 }
131 
132 static struct kobj_attribute dump_in_progress_attribute =
133 	__ATTR(dump_in_progress, 0660, hdd_sysfs_dump_in_progress_show,
134 	       hdd_sysfs_dump_in_progress_store);
135 
hdd_sysfs_create_dump_in_progress_interface(struct kobject * wifi_kobject)136 void hdd_sysfs_create_dump_in_progress_interface(struct kobject *wifi_kobject)
137 {
138 	int error;
139 
140 	if (!wifi_kobject) {
141 		hdd_err("could not get wifi kobject!");
142 		return;
143 	}
144 	error = sysfs_create_file(wifi_kobject,
145 				  &dump_in_progress_attribute.attr);
146 	if (error)
147 		hdd_err("could not create dump in progress sysfs file");
148 }
149 
hdd_sysfs_destroy_dump_in_progress_interface(struct kobject * wifi_kobject)150 void hdd_sysfs_destroy_dump_in_progress_interface(struct kobject *wifi_kobject)
151 {
152 	if (!wifi_kobject) {
153 		hdd_err("could not get wifi kobject!");
154 		return;
155 	}
156 
157 	sysfs_remove_file(wifi_kobject,
158 			  &dump_in_progress_attribute.attr);
159 }
160 
161