blob: 2e57b0db686310f5dcae9b04e89a0a39191c5171 [file] [log] [blame]
Paul Zhang2236ab72019-12-04 17:37:40 +08001/*
2 * Copyright (c) 2019 The Linux Foundation. All rights reserved.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/**
20 * DOC: wlan_hdd_debugfs_config.c
21 *
22 * WLAN Host Device Driver implementation to update
23 * debugfs with ini configs
24 */
25
26#include "wlan_hdd_main.h"
27#include "osif_psoc_sync.h"
28#include "cfg_ucfg_api.h"
29#include "wlan_hdd_debugfs_config.h"
30
31#define DEBUGFS_CONFIG_BUF_SIZE (4096 * 8)
32
33/**
34 * struct ini_config_buf - the buffer struct to save ini configs
35 * @len: buffer len
36 * @result: the pointer to buffer
37 */
38struct ini_config_buf {
39 ssize_t len;
40 uint8_t result[DEBUGFS_CONFIG_BUF_SIZE];
41};
42
43/**
44 * wlan_hdd_config_update() - Update userspace with local statistics buffer
45 * @buf: userspace buffer (to which data is being copied into)
46 * @count: max data that can be copied into buf
47 * @pos: offset (where data should be copied into)
48 * @ini_config: buffer structure for ini config info
49 *
50 * This function should copies ini configs into debugfs entry.
51 *
52 * Return: number of characters copied; 0 on no-copy
53 */
54static ssize_t wlan_hdd_config_update(char __user *buf, size_t count,
55 loff_t *pos,
56 struct ini_config_buf *ini_config)
57{
58 ssize_t ret_cnt;
59
60 ret_cnt = simple_read_from_buffer(buf, count, pos, ini_config->result,
61 ini_config->len);
62 hdd_debug("ini config read req: count: %zu, pos: %lld", count, *pos);
63
64 return ret_cnt;
65}
66
67/**
68 * wlan_hdd_config_get() - Function to save ini config to buffer
69 * @hdd_ctx: hdd context used to register the debugfs file
70 * @ini_config: buffer structure for ini config info
71 *
72 * Return: Errno
73 */
74static int wlan_hdd_config_get(struct hdd_context *hdd_ctx,
75 struct ini_config_buf *ini_config)
76{
77 QDF_STATUS status;
78
79 status = ucfg_cfg_ini_config_print(hdd_ctx->psoc, ini_config->result,
80 &ini_config->len,
81 DEBUGFS_CONFIG_BUF_SIZE);
82 return qdf_status_to_os_return(status);
83}
84
85/**
86 * __wlan_hdd_read_config_debugfs() - function to get ini conifg
87 * @file: file pointer
88 * @buf: buffer
89 * @count: count
90 * @pos: position pointer
91 *
92 * Return: Number of bytes read on success, error number otherwise
93 */
94static ssize_t __wlan_hdd_read_config_debugfs(struct file *file,
95 char __user *buf, size_t count,
96 loff_t *pos)
97{
98 struct ini_config_buf *ini_config;
99 ssize_t err_size;
100
101 ini_config = (struct ini_config_buf *)file->private_data;
102 if (!ini_config)
103 return -ENOMEM;
104
105 err_size = wlan_hdd_config_update(buf, count, pos, ini_config);
106
107 return err_size;
108}
109
110/**
111 * wlan_hdd_read_config_debugfs() - wrapper function to get ini conifg
112 * @file: file pointer
113 * @buf: buffer
114 * @count: count
115 * @pos: position pointer
116 *
117 * Return: Number of bytes read on success, error number otherwise
118 */
119static ssize_t wlan_hdd_read_config_debugfs(struct file *file,
120 char __user *buf, size_t count,
121 loff_t *pos)
122{
123 struct hdd_context *hdd_ctx = file_inode(file)->i_private;
124 struct osif_psoc_sync *psoc_sync;
125 ssize_t err_size;
126
127 err_size = wlan_hdd_validate_context(hdd_ctx);
128 if (err_size)
129 return err_size;
130
131 err_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
132 &psoc_sync);
133 if (err_size)
134 return err_size;
135
136 err_size = __wlan_hdd_read_config_debugfs(file, buf, count, pos);
137
138 osif_psoc_sync_op_stop(psoc_sync);
139
140 return err_size;
141}
142
143/**
144 * __wlan_hdd_open_config_debugfs() - function to open config debugfs
145 * @inode: Pointer to inode structure
146 * @file: file pointer
147 *
148 * Return: Errno
149 */
150static int __wlan_hdd_open_config_debugfs(struct inode *inode,
151 struct file *file)
152{
153 struct hdd_context *hdd_ctx = file_inode(file)->i_private;
154 struct ini_config_buf *ini_config;
155 ssize_t errno;
156 void *buf;
157
158 buf = qdf_mem_malloc(sizeof(*ini_config));
159 if (!buf)
160 return -ENOMEM;
161
162 ini_config = (struct ini_config_buf *)buf;
163 errno = wlan_hdd_config_get(hdd_ctx, ini_config);
164 if (errno) {
165 qdf_mem_free(buf);
166 return errno;
167 }
168
169 file->private_data = buf;
170 return 0;
171}
172
173/**
174 * wlan_hdd_open_config_debugfs() - wrapper function to open config debugfs
175 * @inode: Pointer to inode structure
176 * @file: file pointer
177 *
178 * Return: Errno
179 */
180static int wlan_hdd_open_config_debugfs(struct inode *inode, struct file *file)
181{
182 struct hdd_context *hdd_ctx = file_inode(file)->i_private;
183 struct osif_psoc_sync *psoc_sync;
184 ssize_t errno;
185
186 errno = wlan_hdd_validate_context(hdd_ctx);
187 if (errno)
188 return errno;
189
190 errno = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
191 &psoc_sync);
192 if (errno)
193 return errno;
194
195 errno = __wlan_hdd_open_config_debugfs(inode, file);
196
197 osif_psoc_sync_op_stop(psoc_sync);
198 return errno;
199}
200
201/**
202 * wlan_hdd_release_config_debugfs() - wrapper to release
203 * @inode: Pointer to inode structure
204 * @file: file pointer
205 *
206 * Return: Errno
207 */
208static int wlan_hdd_release_config_debugfs(struct inode *inode,
209 struct file *file)
210{
211 qdf_mem_free(file->private_data);
212 file->private_data = NULL;
213
214 return 0;
215}
216
217static const struct file_operations fops_config_debugfs = {
218 .read = wlan_hdd_read_config_debugfs,
219 .open = wlan_hdd_open_config_debugfs,
220 .release = wlan_hdd_release_config_debugfs,
221 .owner = THIS_MODULE,
222 .llseek = default_llseek,
223};
224
225int hdd_debugfs_ini_config_init(struct hdd_context *hdd_ctx)
226{
227 if (!debugfs_create_file("ini_config", 0444, qdf_debugfs_get_root(),
228 hdd_ctx, &fops_config_debugfs))
229 return -EINVAL;
230
231 return 0;
232}
233
234void hdd_debugfs_ini_config_deinit(struct hdd_context *hdd_ctx)
235{
236 /*
237 * Config ini doesn't have a directory it is removed
238 * as part of qdf remove
239 */
240}