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