xref: /linux/drivers/net/wireless/ti/wlcore/debugfs.c (revision 6dfafbd0299a60bfb5d5e277fdf100037c7ded07)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * This file is part of wl1271
4  *
5  * Copyright (C) 2009 Nokia Corporation
6  *
7  * Contact: Luciano Coelho <luciano.coelho@nokia.com>
8  */
9 
10 #include "debugfs.h"
11 
12 #include <linux/skbuff.h>
13 #include <linux/slab.h>
14 #include <linux/module.h>
15 #include <linux/pm_runtime.h>
16 
17 #include "wlcore.h"
18 #include "debug.h"
19 #include "acx.h"
20 #include "ps.h"
21 #include "io.h"
22 #include "tx.h"
23 #include "hw_ops.h"
24 
25 /* ms */
26 #define WL1271_DEBUGFS_STATS_LIFETIME 1000
27 
28 #define WLCORE_MAX_BLOCK_SIZE ((size_t)(4*PAGE_SIZE))
29 
30 /* debugfs macros idea from mac80211 */
31 int wl1271_format_buffer(char __user *userbuf, size_t count,
32 			 loff_t *ppos, char *fmt, ...)
33 {
34 	va_list args;
35 	char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
36 	int res;
37 
38 	va_start(args, fmt);
39 	res = vscnprintf(buf, sizeof(buf), fmt, args);
40 	va_end(args);
41 
42 	return simple_read_from_buffer(userbuf, count, ppos, buf, res);
43 }
44 EXPORT_SYMBOL_GPL(wl1271_format_buffer);
45 
46 void wl1271_debugfs_update_stats(struct wl1271 *wl)
47 {
48 	int ret;
49 
50 	mutex_lock(&wl->mutex);
51 
52 	if (unlikely(wl->state != WLCORE_STATE_ON))
53 		goto out;
54 
55 	ret = pm_runtime_resume_and_get(wl->dev);
56 	if (ret < 0)
57 		goto out;
58 
59 	if (!wl->plt &&
60 	    time_after(jiffies, wl->stats.fw_stats_update +
61 		       msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) {
62 		wl1271_acx_statistics(wl, wl->stats.fw_stats);
63 		wl->stats.fw_stats_update = jiffies;
64 	}
65 
66 	pm_runtime_put_autosuspend(wl->dev);
67 
68 out:
69 	mutex_unlock(&wl->mutex);
70 }
71 EXPORT_SYMBOL_GPL(wl1271_debugfs_update_stats);
72 
73 DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count);
74 DEBUGFS_READONLY_FILE(excessive_retries, "%u",
75 		      wl->stats.excessive_retries);
76 
77 static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
78 				 size_t count, loff_t *ppos)
79 {
80 	struct wl1271 *wl = file->private_data;
81 	u32 queue_len;
82 	char buf[20];
83 	int res;
84 
85 	queue_len = wl1271_tx_total_queue_count(wl);
86 
87 	res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
88 	return simple_read_from_buffer(userbuf, count, ppos, buf, res);
89 }
90 
91 static const struct file_operations tx_queue_len_ops = {
92 	.read = tx_queue_len_read,
93 	.open = simple_open,
94 	.llseek = default_llseek,
95 };
96 
97 static void chip_op_handler(struct wl1271 *wl, unsigned long value,
98 			    void *arg)
99 {
100 	int ret;
101 	int (*chip_op) (struct wl1271 *wl);
102 
103 	if (!arg) {
104 		wl1271_warning("debugfs chip_op_handler with no callback");
105 		return;
106 	}
107 
108 	ret = pm_runtime_resume_and_get(wl->dev);
109 	if (ret < 0)
110 		return;
111 
112 	chip_op = arg;
113 	chip_op(wl);
114 
115 	pm_runtime_put_autosuspend(wl->dev);
116 }
117 
118 #define WL12XX_CONF_DEBUGFS(param, conf_sub_struct,			\
119 			    min_val, max_val, write_handler_locked,	\
120 			    write_handler_arg)				\
121 	static ssize_t param##_read(struct file *file,			\
122 				      char __user *user_buf,		\
123 				      size_t count, loff_t *ppos)	\
124 	{								\
125 	struct wl1271 *wl = file->private_data;				\
126 	return wl1271_format_buffer(user_buf, count,			\
127 				    ppos, "%d\n",			\
128 				    wl->conf.conf_sub_struct.param);	\
129 	}								\
130 									\
131 	static ssize_t param##_write(struct file *file,			\
132 				     const char __user *user_buf,	\
133 				     size_t count, loff_t *ppos)	\
134 	{								\
135 	struct wl1271 *wl = file->private_data;				\
136 	unsigned long value;						\
137 	int ret;							\
138 									\
139 	ret = kstrtoul_from_user(user_buf, count, 10, &value);		\
140 	if (ret < 0) {							\
141 		wl1271_warning("illegal value for " #param);		\
142 		return -EINVAL;						\
143 	}								\
144 									\
145 	if (value < min_val || value > max_val) {			\
146 		wl1271_warning(#param " is not in valid range");	\
147 		return -ERANGE;						\
148 	}								\
149 									\
150 	mutex_lock(&wl->mutex);						\
151 	wl->conf.conf_sub_struct.param = value;				\
152 									\
153 	write_handler_locked(wl, value, write_handler_arg);		\
154 									\
155 	mutex_unlock(&wl->mutex);					\
156 	return count;							\
157 	}								\
158 									\
159 	static const struct file_operations param##_ops = {		\
160 		.read = param##_read,					\
161 		.write = param##_write,					\
162 		.open = simple_open,					\
163 		.llseek = default_llseek,				\
164 	};
165 
166 WL12XX_CONF_DEBUGFS(irq_pkt_threshold, rx, 0, 65535,
167 		    chip_op_handler, wl1271_acx_init_rx_interrupt)
168 WL12XX_CONF_DEBUGFS(irq_blk_threshold, rx, 0, 65535,
169 		    chip_op_handler, wl1271_acx_init_rx_interrupt)
170 WL12XX_CONF_DEBUGFS(irq_timeout, rx, 0, 100,
171 		    chip_op_handler, wl1271_acx_init_rx_interrupt)
172 
173 static ssize_t gpio_power_read(struct file *file, char __user *user_buf,
174 			  size_t count, loff_t *ppos)
175 {
176 	struct wl1271 *wl = file->private_data;
177 	bool state = test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
178 
179 	int res;
180 	char buf[10];
181 
182 	res = scnprintf(buf, sizeof(buf), "%d\n", state);
183 
184 	return simple_read_from_buffer(user_buf, count, ppos, buf, res);
185 }
186 
187 static ssize_t gpio_power_write(struct file *file,
188 			   const char __user *user_buf,
189 			   size_t count, loff_t *ppos)
190 {
191 	struct wl1271 *wl = file->private_data;
192 	unsigned long value;
193 	int ret;
194 
195 	ret = kstrtoul_from_user(user_buf, count, 10, &value);
196 	if (ret < 0) {
197 		wl1271_warning("illegal value in gpio_power");
198 		return -EINVAL;
199 	}
200 
201 	mutex_lock(&wl->mutex);
202 
203 	if (value)
204 		wl1271_power_on(wl);
205 	else
206 		wl1271_power_off(wl);
207 
208 	mutex_unlock(&wl->mutex);
209 	return count;
210 }
211 
212 static const struct file_operations gpio_power_ops = {
213 	.read = gpio_power_read,
214 	.write = gpio_power_write,
215 	.open = simple_open,
216 	.llseek = default_llseek,
217 };
218 
219 static ssize_t start_recovery_write(struct file *file,
220 				    const char __user *user_buf,
221 				    size_t count, loff_t *ppos)
222 {
223 	struct wl1271 *wl = file->private_data;
224 
225 	mutex_lock(&wl->mutex);
226 	wl12xx_queue_recovery_work(wl);
227 	mutex_unlock(&wl->mutex);
228 
229 	return count;
230 }
231 
232 static const struct file_operations start_recovery_ops = {
233 	.write = start_recovery_write,
234 	.open = simple_open,
235 	.llseek = default_llseek,
236 };
237 
238 static ssize_t dynamic_ps_timeout_read(struct file *file, char __user *user_buf,
239 			  size_t count, loff_t *ppos)
240 {
241 	struct wl1271 *wl = file->private_data;
242 
243 	return wl1271_format_buffer(user_buf, count,
244 				    ppos, "%d\n",
245 				    wl->conf.conn.dynamic_ps_timeout);
246 }
247 
248 static ssize_t dynamic_ps_timeout_write(struct file *file,
249 				    const char __user *user_buf,
250 				    size_t count, loff_t *ppos)
251 {
252 	struct wl1271 *wl = file->private_data;
253 	struct wl12xx_vif *wlvif;
254 	unsigned long value;
255 	int ret;
256 
257 	ret = kstrtoul_from_user(user_buf, count, 10, &value);
258 	if (ret < 0) {
259 		wl1271_warning("illegal value in dynamic_ps");
260 		return -EINVAL;
261 	}
262 
263 	if (value < 1 || value > 65535) {
264 		wl1271_warning("dynamic_ps_timeout is not in valid range");
265 		return -ERANGE;
266 	}
267 
268 	mutex_lock(&wl->mutex);
269 
270 	wl->conf.conn.dynamic_ps_timeout = value;
271 
272 	if (unlikely(wl->state != WLCORE_STATE_ON))
273 		goto out;
274 
275 	ret = pm_runtime_resume_and_get(wl->dev);
276 	if (ret < 0)
277 		goto out;
278 
279 	/* In case we're already in PSM, trigger it again to set new timeout
280 	 * immediately without waiting for re-association
281 	 */
282 
283 	wl12xx_for_each_wlvif_sta(wl, wlvif) {
284 		if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags))
285 			wl1271_ps_set_mode(wl, wlvif, STATION_AUTO_PS_MODE);
286 	}
287 
288 	pm_runtime_put_autosuspend(wl->dev);
289 
290 out:
291 	mutex_unlock(&wl->mutex);
292 	return count;
293 }
294 
295 static const struct file_operations dynamic_ps_timeout_ops = {
296 	.read = dynamic_ps_timeout_read,
297 	.write = dynamic_ps_timeout_write,
298 	.open = simple_open,
299 	.llseek = default_llseek,
300 };
301 
302 static ssize_t forced_ps_read(struct file *file, char __user *user_buf,
303 			  size_t count, loff_t *ppos)
304 {
305 	struct wl1271 *wl = file->private_data;
306 
307 	return wl1271_format_buffer(user_buf, count,
308 				    ppos, "%d\n",
309 				    wl->conf.conn.forced_ps);
310 }
311 
312 static ssize_t forced_ps_write(struct file *file,
313 				    const char __user *user_buf,
314 				    size_t count, loff_t *ppos)
315 {
316 	struct wl1271 *wl = file->private_data;
317 	struct wl12xx_vif *wlvif;
318 	unsigned long value;
319 	int ret, ps_mode;
320 
321 	ret = kstrtoul_from_user(user_buf, count, 10, &value);
322 	if (ret < 0) {
323 		wl1271_warning("illegal value in forced_ps");
324 		return -EINVAL;
325 	}
326 
327 	if (value != 1 && value != 0) {
328 		wl1271_warning("forced_ps should be either 0 or 1");
329 		return -ERANGE;
330 	}
331 
332 	mutex_lock(&wl->mutex);
333 
334 	if (wl->conf.conn.forced_ps == value)
335 		goto out;
336 
337 	wl->conf.conn.forced_ps = value;
338 
339 	if (unlikely(wl->state != WLCORE_STATE_ON))
340 		goto out;
341 
342 	ret = pm_runtime_resume_and_get(wl->dev);
343 	if (ret < 0)
344 		goto out;
345 
346 	/* In case we're already in PSM, trigger it again to switch mode
347 	 * immediately without waiting for re-association
348 	 */
349 
350 	ps_mode = value ? STATION_POWER_SAVE_MODE : STATION_AUTO_PS_MODE;
351 
352 	wl12xx_for_each_wlvif_sta(wl, wlvif) {
353 		if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags))
354 			wl1271_ps_set_mode(wl, wlvif, ps_mode);
355 	}
356 
357 	pm_runtime_put_autosuspend(wl->dev);
358 
359 out:
360 	mutex_unlock(&wl->mutex);
361 	return count;
362 }
363 
364 static const struct file_operations forced_ps_ops = {
365 	.read = forced_ps_read,
366 	.write = forced_ps_write,
367 	.open = simple_open,
368 	.llseek = default_llseek,
369 };
370 
371 static ssize_t split_scan_timeout_read(struct file *file, char __user *user_buf,
372 			  size_t count, loff_t *ppos)
373 {
374 	struct wl1271 *wl = file->private_data;
375 
376 	return wl1271_format_buffer(user_buf, count,
377 				    ppos, "%d\n",
378 				    wl->conf.scan.split_scan_timeout / 1000);
379 }
380 
381 static ssize_t split_scan_timeout_write(struct file *file,
382 				    const char __user *user_buf,
383 				    size_t count, loff_t *ppos)
384 {
385 	struct wl1271 *wl = file->private_data;
386 	unsigned long value;
387 	int ret;
388 
389 	ret = kstrtoul_from_user(user_buf, count, 10, &value);
390 	if (ret < 0) {
391 		wl1271_warning("illegal value in split_scan_timeout");
392 		return -EINVAL;
393 	}
394 
395 	if (value == 0)
396 		wl1271_info("split scan will be disabled");
397 
398 	mutex_lock(&wl->mutex);
399 
400 	wl->conf.scan.split_scan_timeout = value * 1000;
401 
402 	mutex_unlock(&wl->mutex);
403 	return count;
404 }
405 
406 static const struct file_operations split_scan_timeout_ops = {
407 	.read = split_scan_timeout_read,
408 	.write = split_scan_timeout_write,
409 	.open = simple_open,
410 	.llseek = default_llseek,
411 };
412 
413 static ssize_t driver_state_read(struct file *file, char __user *user_buf,
414 				 size_t count, loff_t *ppos)
415 {
416 	struct wl1271 *wl = file->private_data;
417 	int res = 0;
418 	ssize_t ret;
419 	char *buf;
420 	struct wl12xx_vif *wlvif;
421 
422 #define DRIVER_STATE_BUF_LEN 1024
423 
424 	buf = kmalloc(DRIVER_STATE_BUF_LEN, GFP_KERNEL);
425 	if (!buf)
426 		return -ENOMEM;
427 
428 	mutex_lock(&wl->mutex);
429 
430 #define DRIVER_STATE_PRINT(x, fmt)   \
431 	(res += scnprintf(buf + res, DRIVER_STATE_BUF_LEN - res,\
432 			  #x " = " fmt "\n", wl->x))
433 
434 #define DRIVER_STATE_PRINT_GENERIC(x, fmt, args...)   \
435 	(res += scnprintf(buf + res, DRIVER_STATE_BUF_LEN - res,\
436 			  #x " = " fmt "\n", args))
437 
438 #define DRIVER_STATE_PRINT_LONG(x) DRIVER_STATE_PRINT(x, "%ld")
439 #define DRIVER_STATE_PRINT_INT(x)  DRIVER_STATE_PRINT(x, "%d")
440 #define DRIVER_STATE_PRINT_STR(x)  DRIVER_STATE_PRINT(x, "%s")
441 #define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx")
442 #define DRIVER_STATE_PRINT_HEX(x)  DRIVER_STATE_PRINT(x, "0x%x")
443 
444 	wl12xx_for_each_wlvif_sta(wl, wlvif) {
445 		if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
446 			continue;
447 
448 		DRIVER_STATE_PRINT_GENERIC(channel, "%d (%s)", wlvif->channel,
449 					   wlvif->p2p ? "P2P-CL" : "STA");
450 	}
451 
452 	wl12xx_for_each_wlvif_ap(wl, wlvif)
453 		DRIVER_STATE_PRINT_GENERIC(channel, "%d (%s)", wlvif->channel,
454 					   wlvif->p2p ? "P2P-GO" : "AP");
455 
456 	DRIVER_STATE_PRINT_INT(tx_blocks_available);
457 	DRIVER_STATE_PRINT_INT(tx_allocated_blocks);
458 	DRIVER_STATE_PRINT_INT(tx_allocated_pkts[0]);
459 	DRIVER_STATE_PRINT_INT(tx_allocated_pkts[1]);
460 	DRIVER_STATE_PRINT_INT(tx_allocated_pkts[2]);
461 	DRIVER_STATE_PRINT_INT(tx_allocated_pkts[3]);
462 	DRIVER_STATE_PRINT_INT(tx_frames_cnt);
463 	DRIVER_STATE_PRINT_LHEX(tx_frames_map[0]);
464 	DRIVER_STATE_PRINT_INT(tx_queue_count[0]);
465 	DRIVER_STATE_PRINT_INT(tx_queue_count[1]);
466 	DRIVER_STATE_PRINT_INT(tx_queue_count[2]);
467 	DRIVER_STATE_PRINT_INT(tx_queue_count[3]);
468 	DRIVER_STATE_PRINT_INT(tx_packets_count);
469 	DRIVER_STATE_PRINT_INT(tx_results_count);
470 	DRIVER_STATE_PRINT_LHEX(flags);
471 	DRIVER_STATE_PRINT_INT(tx_blocks_freed);
472 	DRIVER_STATE_PRINT_INT(rx_counter);
473 	DRIVER_STATE_PRINT_INT(state);
474 	DRIVER_STATE_PRINT_INT(band);
475 	DRIVER_STATE_PRINT_INT(power_level);
476 	DRIVER_STATE_PRINT_INT(sg_enabled);
477 	DRIVER_STATE_PRINT_INT(enable_11a);
478 	DRIVER_STATE_PRINT_INT(noise);
479 	DRIVER_STATE_PRINT_LHEX(ap_fw_ps_map);
480 	DRIVER_STATE_PRINT_LHEX(ap_ps_map);
481 	DRIVER_STATE_PRINT_HEX(quirks);
482 	DRIVER_STATE_PRINT_HEX(irq);
483 	/* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */
484 	DRIVER_STATE_PRINT_HEX(hw_pg_ver);
485 	DRIVER_STATE_PRINT_HEX(irq_flags);
486 	DRIVER_STATE_PRINT_HEX(chip.id);
487 	DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
488 	DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
489 	DRIVER_STATE_PRINT_INT(recovery_count);
490 
491 #undef DRIVER_STATE_PRINT_INT
492 #undef DRIVER_STATE_PRINT_LONG
493 #undef DRIVER_STATE_PRINT_HEX
494 #undef DRIVER_STATE_PRINT_LHEX
495 #undef DRIVER_STATE_PRINT_STR
496 #undef DRIVER_STATE_PRINT
497 #undef DRIVER_STATE_BUF_LEN
498 
499 	mutex_unlock(&wl->mutex);
500 
501 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, res);
502 	kfree(buf);
503 	return ret;
504 }
505 
506 static const struct file_operations driver_state_ops = {
507 	.read = driver_state_read,
508 	.open = simple_open,
509 	.llseek = default_llseek,
510 };
511 
512 static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
513 				 size_t count, loff_t *ppos)
514 {
515 	struct wl1271 *wl = file->private_data;
516 	struct wl12xx_vif *wlvif;
517 	int ret, res = 0;
518 	const int buf_size = 4096;
519 	char *buf;
520 	char tmp_buf[64];
521 
522 	buf = kzalloc(buf_size, GFP_KERNEL);
523 	if (!buf)
524 		return -ENOMEM;
525 
526 	mutex_lock(&wl->mutex);
527 
528 #define VIF_STATE_PRINT(x, fmt)				\
529 	(res += scnprintf(buf + res, buf_size - res,	\
530 			  #x " = " fmt "\n", wlvif->x))
531 
532 #define VIF_STATE_PRINT_LONG(x)  VIF_STATE_PRINT(x, "%ld")
533 #define VIF_STATE_PRINT_INT(x)   VIF_STATE_PRINT(x, "%d")
534 #define VIF_STATE_PRINT_STR(x)   VIF_STATE_PRINT(x, "%s")
535 #define VIF_STATE_PRINT_LHEX(x)  VIF_STATE_PRINT(x, "0x%lx")
536 #define VIF_STATE_PRINT_LLHEX(x) VIF_STATE_PRINT(x, "0x%llx")
537 #define VIF_STATE_PRINT_HEX(x)   VIF_STATE_PRINT(x, "0x%x")
538 
539 #define VIF_STATE_PRINT_NSTR(x, len)				\
540 	do {							\
541 		memset(tmp_buf, 0, sizeof(tmp_buf));		\
542 		memcpy(tmp_buf, wlvif->x,			\
543 		       min_t(u8, len, sizeof(tmp_buf) - 1));	\
544 		res += scnprintf(buf + res, buf_size - res,	\
545 				 #x " = %s\n", tmp_buf);	\
546 	} while (0)
547 
548 	wl12xx_for_each_wlvif(wl, wlvif) {
549 		VIF_STATE_PRINT_INT(role_id);
550 		VIF_STATE_PRINT_INT(bss_type);
551 		VIF_STATE_PRINT_LHEX(flags);
552 		VIF_STATE_PRINT_INT(p2p);
553 		VIF_STATE_PRINT_INT(dev_role_id);
554 		VIF_STATE_PRINT_INT(dev_hlid);
555 
556 		if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
557 		    wlvif->bss_type == BSS_TYPE_IBSS) {
558 			VIF_STATE_PRINT_INT(sta.hlid);
559 			VIF_STATE_PRINT_INT(sta.basic_rate_idx);
560 			VIF_STATE_PRINT_INT(sta.ap_rate_idx);
561 			VIF_STATE_PRINT_INT(sta.p2p_rate_idx);
562 			VIF_STATE_PRINT_INT(sta.qos);
563 		} else {
564 			VIF_STATE_PRINT_INT(ap.global_hlid);
565 			VIF_STATE_PRINT_INT(ap.bcast_hlid);
566 			VIF_STATE_PRINT_LHEX(ap.sta_hlid_map[0]);
567 			VIF_STATE_PRINT_INT(ap.mgmt_rate_idx);
568 			VIF_STATE_PRINT_INT(ap.bcast_rate_idx);
569 			VIF_STATE_PRINT_INT(ap.ucast_rate_idx[0]);
570 			VIF_STATE_PRINT_INT(ap.ucast_rate_idx[1]);
571 			VIF_STATE_PRINT_INT(ap.ucast_rate_idx[2]);
572 			VIF_STATE_PRINT_INT(ap.ucast_rate_idx[3]);
573 		}
574 		VIF_STATE_PRINT_INT(last_tx_hlid);
575 		VIF_STATE_PRINT_INT(tx_queue_count[0]);
576 		VIF_STATE_PRINT_INT(tx_queue_count[1]);
577 		VIF_STATE_PRINT_INT(tx_queue_count[2]);
578 		VIF_STATE_PRINT_INT(tx_queue_count[3]);
579 		VIF_STATE_PRINT_LHEX(links_map[0]);
580 		VIF_STATE_PRINT_NSTR(ssid, wlvif->ssid_len);
581 		VIF_STATE_PRINT_INT(band);
582 		VIF_STATE_PRINT_INT(channel);
583 		VIF_STATE_PRINT_HEX(bitrate_masks[0]);
584 		VIF_STATE_PRINT_HEX(bitrate_masks[1]);
585 		VIF_STATE_PRINT_HEX(basic_rate_set);
586 		VIF_STATE_PRINT_HEX(basic_rate);
587 		VIF_STATE_PRINT_HEX(rate_set);
588 		VIF_STATE_PRINT_INT(beacon_int);
589 		VIF_STATE_PRINT_INT(default_key);
590 		VIF_STATE_PRINT_INT(aid);
591 		VIF_STATE_PRINT_INT(psm_entry_retry);
592 		VIF_STATE_PRINT_INT(power_level);
593 		VIF_STATE_PRINT_INT(rssi_thold);
594 		VIF_STATE_PRINT_INT(last_rssi_event);
595 		VIF_STATE_PRINT_INT(ba_support);
596 		VIF_STATE_PRINT_INT(ba_allowed);
597 		VIF_STATE_PRINT_LLHEX(total_freed_pkts);
598 	}
599 
600 #undef VIF_STATE_PRINT_INT
601 #undef VIF_STATE_PRINT_LONG
602 #undef VIF_STATE_PRINT_HEX
603 #undef VIF_STATE_PRINT_LHEX
604 #undef VIF_STATE_PRINT_LLHEX
605 #undef VIF_STATE_PRINT_STR
606 #undef VIF_STATE_PRINT_NSTR
607 #undef VIF_STATE_PRINT
608 
609 	mutex_unlock(&wl->mutex);
610 
611 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, res);
612 	kfree(buf);
613 	return ret;
614 }
615 
616 static const struct file_operations vifs_state_ops = {
617 	.read = vifs_state_read,
618 	.open = simple_open,
619 	.llseek = default_llseek,
620 };
621 
622 static ssize_t dtim_interval_read(struct file *file, char __user *user_buf,
623 				  size_t count, loff_t *ppos)
624 {
625 	struct wl1271 *wl = file->private_data;
626 	u8 value;
627 
628 	if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_DTIM ||
629 	    wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM)
630 		value = wl->conf.conn.listen_interval;
631 	else
632 		value = 0;
633 
634 	return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
635 }
636 
637 static ssize_t dtim_interval_write(struct file *file,
638 				   const char __user *user_buf,
639 				   size_t count, loff_t *ppos)
640 {
641 	struct wl1271 *wl = file->private_data;
642 	unsigned long value;
643 	int ret;
644 
645 	ret = kstrtoul_from_user(user_buf, count, 10, &value);
646 	if (ret < 0) {
647 		wl1271_warning("illegal value for dtim_interval");
648 		return -EINVAL;
649 	}
650 
651 	if (value < 1 || value > 10) {
652 		wl1271_warning("dtim value is not in valid range");
653 		return -ERANGE;
654 	}
655 
656 	mutex_lock(&wl->mutex);
657 
658 	wl->conf.conn.listen_interval = value;
659 	/* for some reason there are different event types for 1 and >1 */
660 	if (value == 1)
661 		wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_DTIM;
662 	else
663 		wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM;
664 
665 	/*
666 	 * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
667 	 * take effect on the next time we enter psm.
668 	 */
669 	mutex_unlock(&wl->mutex);
670 	return count;
671 }
672 
673 static const struct file_operations dtim_interval_ops = {
674 	.read = dtim_interval_read,
675 	.write = dtim_interval_write,
676 	.open = simple_open,
677 	.llseek = default_llseek,
678 };
679 
680 
681 
682 static ssize_t suspend_dtim_interval_read(struct file *file,
683 					  char __user *user_buf,
684 					  size_t count, loff_t *ppos)
685 {
686 	struct wl1271 *wl = file->private_data;
687 	u8 value;
688 
689 	if (wl->conf.conn.suspend_wake_up_event == CONF_WAKE_UP_EVENT_DTIM ||
690 	    wl->conf.conn.suspend_wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM)
691 		value = wl->conf.conn.suspend_listen_interval;
692 	else
693 		value = 0;
694 
695 	return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
696 }
697 
698 static ssize_t suspend_dtim_interval_write(struct file *file,
699 					   const char __user *user_buf,
700 					   size_t count, loff_t *ppos)
701 {
702 	struct wl1271 *wl = file->private_data;
703 	unsigned long value;
704 	int ret;
705 
706 	ret = kstrtoul_from_user(user_buf, count, 10, &value);
707 	if (ret < 0) {
708 		wl1271_warning("illegal value for suspend_dtim_interval");
709 		return -EINVAL;
710 	}
711 
712 	if (value < 1 || value > 10) {
713 		wl1271_warning("suspend_dtim value is not in valid range");
714 		return -ERANGE;
715 	}
716 
717 	mutex_lock(&wl->mutex);
718 
719 	wl->conf.conn.suspend_listen_interval = value;
720 	/* for some reason there are different event types for 1 and >1 */
721 	if (value == 1)
722 		wl->conf.conn.suspend_wake_up_event = CONF_WAKE_UP_EVENT_DTIM;
723 	else
724 		wl->conf.conn.suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM;
725 
726 	mutex_unlock(&wl->mutex);
727 	return count;
728 }
729 
730 
731 static const struct file_operations suspend_dtim_interval_ops = {
732 	.read = suspend_dtim_interval_read,
733 	.write = suspend_dtim_interval_write,
734 	.open = simple_open,
735 	.llseek = default_llseek,
736 };
737 
738 static ssize_t beacon_interval_read(struct file *file, char __user *user_buf,
739 				    size_t count, loff_t *ppos)
740 {
741 	struct wl1271 *wl = file->private_data;
742 	u8 value;
743 
744 	if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_BEACON ||
745 	    wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_BEACONS)
746 		value = wl->conf.conn.listen_interval;
747 	else
748 		value = 0;
749 
750 	return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
751 }
752 
753 static ssize_t beacon_interval_write(struct file *file,
754 				     const char __user *user_buf,
755 				     size_t count, loff_t *ppos)
756 {
757 	struct wl1271 *wl = file->private_data;
758 	unsigned long value;
759 	int ret;
760 
761 	ret = kstrtoul_from_user(user_buf, count, 10, &value);
762 	if (ret < 0) {
763 		wl1271_warning("illegal value for beacon_interval");
764 		return -EINVAL;
765 	}
766 
767 	if (value < 1 || value > 255) {
768 		wl1271_warning("beacon interval value is not in valid range");
769 		return -ERANGE;
770 	}
771 
772 	mutex_lock(&wl->mutex);
773 
774 	wl->conf.conn.listen_interval = value;
775 	/* for some reason there are different event types for 1 and >1 */
776 	if (value == 1)
777 		wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_BEACON;
778 	else
779 		wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_BEACONS;
780 
781 	/*
782 	 * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
783 	 * take effect on the next time we enter psm.
784 	 */
785 	mutex_unlock(&wl->mutex);
786 	return count;
787 }
788 
789 static const struct file_operations beacon_interval_ops = {
790 	.read = beacon_interval_read,
791 	.write = beacon_interval_write,
792 	.open = simple_open,
793 	.llseek = default_llseek,
794 };
795 
796 static ssize_t rx_streaming_interval_write(struct file *file,
797 			   const char __user *user_buf,
798 			   size_t count, loff_t *ppos)
799 {
800 	struct wl1271 *wl = file->private_data;
801 	struct wl12xx_vif *wlvif;
802 	unsigned long value;
803 	int ret;
804 
805 	ret = kstrtoul_from_user(user_buf, count, 10, &value);
806 	if (ret < 0) {
807 		wl1271_warning("illegal value in rx_streaming_interval!");
808 		return -EINVAL;
809 	}
810 
811 	/* valid values: 0, 10-100 */
812 	if (value && (value < 10 || value > 100)) {
813 		wl1271_warning("value is not in range!");
814 		return -ERANGE;
815 	}
816 
817 	mutex_lock(&wl->mutex);
818 
819 	wl->conf.rx_streaming.interval = value;
820 
821 	ret = pm_runtime_resume_and_get(wl->dev);
822 	if (ret < 0)
823 		goto out;
824 
825 	wl12xx_for_each_wlvif_sta(wl, wlvif) {
826 		wl1271_recalc_rx_streaming(wl, wlvif);
827 	}
828 
829 	pm_runtime_put_autosuspend(wl->dev);
830 out:
831 	mutex_unlock(&wl->mutex);
832 	return count;
833 }
834 
835 static ssize_t rx_streaming_interval_read(struct file *file,
836 			    char __user *userbuf,
837 			    size_t count, loff_t *ppos)
838 {
839 	struct wl1271 *wl = file->private_data;
840 	return wl1271_format_buffer(userbuf, count, ppos,
841 				    "%d\n", wl->conf.rx_streaming.interval);
842 }
843 
844 static const struct file_operations rx_streaming_interval_ops = {
845 	.read = rx_streaming_interval_read,
846 	.write = rx_streaming_interval_write,
847 	.open = simple_open,
848 	.llseek = default_llseek,
849 };
850 
851 static ssize_t rx_streaming_always_write(struct file *file,
852 			   const char __user *user_buf,
853 			   size_t count, loff_t *ppos)
854 {
855 	struct wl1271 *wl = file->private_data;
856 	struct wl12xx_vif *wlvif;
857 	unsigned long value;
858 	int ret;
859 
860 	ret = kstrtoul_from_user(user_buf, count, 10, &value);
861 	if (ret < 0) {
862 		wl1271_warning("illegal value in rx_streaming_write!");
863 		return -EINVAL;
864 	}
865 
866 	/* valid values: 0, 10-100 */
867 	if (!(value == 0 || value == 1)) {
868 		wl1271_warning("value is not in valid!");
869 		return -EINVAL;
870 	}
871 
872 	mutex_lock(&wl->mutex);
873 
874 	wl->conf.rx_streaming.always = value;
875 
876 	ret = pm_runtime_resume_and_get(wl->dev);
877 	if (ret < 0)
878 		goto out;
879 
880 	wl12xx_for_each_wlvif_sta(wl, wlvif) {
881 		wl1271_recalc_rx_streaming(wl, wlvif);
882 	}
883 
884 	pm_runtime_put_autosuspend(wl->dev);
885 out:
886 	mutex_unlock(&wl->mutex);
887 	return count;
888 }
889 
890 static ssize_t rx_streaming_always_read(struct file *file,
891 			    char __user *userbuf,
892 			    size_t count, loff_t *ppos)
893 {
894 	struct wl1271 *wl = file->private_data;
895 	return wl1271_format_buffer(userbuf, count, ppos,
896 				    "%d\n", wl->conf.rx_streaming.always);
897 }
898 
899 static const struct file_operations rx_streaming_always_ops = {
900 	.read = rx_streaming_always_read,
901 	.write = rx_streaming_always_write,
902 	.open = simple_open,
903 	.llseek = default_llseek,
904 };
905 
906 static ssize_t beacon_filtering_write(struct file *file,
907 				      const char __user *user_buf,
908 				      size_t count, loff_t *ppos)
909 {
910 	struct wl1271 *wl = file->private_data;
911 	struct wl12xx_vif *wlvif;
912 	unsigned long value;
913 	int ret;
914 
915 	ret = kstrtoul_from_user(user_buf, count, 0, &value);
916 	if (ret < 0) {
917 		wl1271_warning("illegal value for beacon_filtering!");
918 		return -EINVAL;
919 	}
920 
921 	mutex_lock(&wl->mutex);
922 
923 	ret = pm_runtime_resume_and_get(wl->dev);
924 	if (ret < 0)
925 		goto out;
926 
927 	wl12xx_for_each_wlvif(wl, wlvif) {
928 		ret = wl1271_acx_beacon_filter_opt(wl, wlvif, !!value);
929 	}
930 
931 	pm_runtime_put_autosuspend(wl->dev);
932 out:
933 	mutex_unlock(&wl->mutex);
934 	return count;
935 }
936 
937 static const struct file_operations beacon_filtering_ops = {
938 	.write = beacon_filtering_write,
939 	.open = simple_open,
940 	.llseek = default_llseek,
941 };
942 
943 static ssize_t fw_stats_raw_read(struct file *file,
944 				 char __user *userbuf,
945 				 size_t count, loff_t *ppos)
946 {
947 	struct wl1271 *wl = file->private_data;
948 
949 	wl1271_debugfs_update_stats(wl);
950 
951 	return simple_read_from_buffer(userbuf, count, ppos,
952 				       wl->stats.fw_stats,
953 				       wl->stats.fw_stats_len);
954 }
955 
956 static const struct file_operations fw_stats_raw_ops = {
957 	.read = fw_stats_raw_read,
958 	.open = simple_open,
959 	.llseek = default_llseek,
960 };
961 
962 static ssize_t sleep_auth_read(struct file *file, char __user *user_buf,
963 			       size_t count, loff_t *ppos)
964 {
965 	struct wl1271 *wl = file->private_data;
966 
967 	return wl1271_format_buffer(user_buf, count,
968 				    ppos, "%d\n",
969 				    wl->sleep_auth);
970 }
971 
972 static ssize_t sleep_auth_write(struct file *file,
973 				const char __user *user_buf,
974 				size_t count, loff_t *ppos)
975 {
976 	struct wl1271 *wl = file->private_data;
977 	unsigned long value;
978 	int ret;
979 
980 	ret = kstrtoul_from_user(user_buf, count, 0, &value);
981 	if (ret < 0) {
982 		wl1271_warning("illegal value in sleep_auth");
983 		return -EINVAL;
984 	}
985 
986 	if (value > WL1271_PSM_MAX) {
987 		wl1271_warning("sleep_auth must be between 0 and %d",
988 			       WL1271_PSM_MAX);
989 		return -ERANGE;
990 	}
991 
992 	mutex_lock(&wl->mutex);
993 
994 	wl->conf.conn.sta_sleep_auth = value;
995 
996 	if (unlikely(wl->state != WLCORE_STATE_ON)) {
997 		/* this will show up on "read" in case we are off */
998 		wl->sleep_auth = value;
999 		goto out;
1000 	}
1001 
1002 	ret = pm_runtime_resume_and_get(wl->dev);
1003 	if (ret < 0)
1004 		goto out;
1005 
1006 	ret = wl1271_acx_sleep_auth(wl, value);
1007 	if (ret < 0)
1008 		goto out_sleep;
1009 
1010 out_sleep:
1011 	pm_runtime_put_autosuspend(wl->dev);
1012 out:
1013 	mutex_unlock(&wl->mutex);
1014 	return count;
1015 }
1016 
1017 static const struct file_operations sleep_auth_ops = {
1018 	.read = sleep_auth_read,
1019 	.write = sleep_auth_write,
1020 	.open = simple_open,
1021 	.llseek = default_llseek,
1022 };
1023 
1024 static ssize_t dev_mem_read(struct file *file,
1025 	     char __user *user_buf, size_t count,
1026 	     loff_t *ppos)
1027 {
1028 	struct wl1271 *wl = file->private_data;
1029 	struct wlcore_partition_set part, old_part;
1030 	size_t bytes = count;
1031 	int ret;
1032 	char *buf;
1033 
1034 	/* only requests of dword-aligned size and offset are supported */
1035 	if (bytes % 4)
1036 		return -EINVAL;
1037 
1038 	if (*ppos % 4)
1039 		return -EINVAL;
1040 
1041 	/* function should return in reasonable time */
1042 	bytes = min(bytes, WLCORE_MAX_BLOCK_SIZE);
1043 
1044 	if (bytes == 0)
1045 		return -EINVAL;
1046 
1047 	memset(&part, 0, sizeof(part));
1048 	part.mem.start = *ppos;
1049 	part.mem.size = bytes;
1050 
1051 	buf = kmalloc(bytes, GFP_KERNEL);
1052 	if (!buf)
1053 		return -ENOMEM;
1054 
1055 	mutex_lock(&wl->mutex);
1056 
1057 	if (unlikely(wl->state == WLCORE_STATE_OFF)) {
1058 		ret = -EFAULT;
1059 		goto skip_read;
1060 	}
1061 
1062 	/*
1063 	 * Don't fail if elp_wakeup returns an error, so the device's memory
1064 	 * could be read even if the FW crashed
1065 	 */
1066 	pm_runtime_get_sync(wl->dev);
1067 
1068 	/* store current partition and switch partition */
1069 	memcpy(&old_part, &wl->curr_part, sizeof(old_part));
1070 	ret = wlcore_set_partition(wl, &part);
1071 	if (ret < 0)
1072 		goto part_err;
1073 
1074 	ret = wlcore_raw_read(wl, 0, buf, bytes, false);
1075 	if (ret < 0)
1076 		goto read_err;
1077 
1078 read_err:
1079 	/* recover partition */
1080 	ret = wlcore_set_partition(wl, &old_part);
1081 	if (ret < 0)
1082 		goto part_err;
1083 
1084 part_err:
1085 	pm_runtime_put_autosuspend(wl->dev);
1086 
1087 skip_read:
1088 	mutex_unlock(&wl->mutex);
1089 
1090 	if (ret == 0) {
1091 		ret = copy_to_user(user_buf, buf, bytes);
1092 		if (ret < bytes) {
1093 			bytes -= ret;
1094 			*ppos += bytes;
1095 			ret = 0;
1096 		} else {
1097 			ret = -EFAULT;
1098 		}
1099 	}
1100 
1101 	kfree(buf);
1102 
1103 	return ((ret == 0) ? bytes : ret);
1104 }
1105 
1106 static ssize_t dev_mem_write(struct file *file, const char __user *user_buf,
1107 		size_t count, loff_t *ppos)
1108 {
1109 	struct wl1271 *wl = file->private_data;
1110 	struct wlcore_partition_set part, old_part;
1111 	size_t bytes = count;
1112 	int ret;
1113 	char *buf;
1114 
1115 	/* only requests of dword-aligned size and offset are supported */
1116 	if (bytes % 4)
1117 		return -EINVAL;
1118 
1119 	if (*ppos % 4)
1120 		return -EINVAL;
1121 
1122 	/* function should return in reasonable time */
1123 	bytes = min(bytes, WLCORE_MAX_BLOCK_SIZE);
1124 
1125 	if (bytes == 0)
1126 		return -EINVAL;
1127 
1128 	memset(&part, 0, sizeof(part));
1129 	part.mem.start = *ppos;
1130 	part.mem.size = bytes;
1131 
1132 	buf = memdup_user(user_buf, bytes);
1133 	if (IS_ERR(buf))
1134 		return PTR_ERR(buf);
1135 
1136 	mutex_lock(&wl->mutex);
1137 
1138 	if (unlikely(wl->state == WLCORE_STATE_OFF)) {
1139 		ret = -EFAULT;
1140 		goto skip_write;
1141 	}
1142 
1143 	/*
1144 	 * Don't fail if elp_wakeup returns an error, so the device's memory
1145 	 * could be read even if the FW crashed
1146 	 */
1147 	pm_runtime_get_sync(wl->dev);
1148 
1149 	/* store current partition and switch partition */
1150 	memcpy(&old_part, &wl->curr_part, sizeof(old_part));
1151 	ret = wlcore_set_partition(wl, &part);
1152 	if (ret < 0)
1153 		goto part_err;
1154 
1155 	ret = wlcore_raw_write(wl, 0, buf, bytes, false);
1156 	if (ret < 0)
1157 		goto write_err;
1158 
1159 write_err:
1160 	/* recover partition */
1161 	ret = wlcore_set_partition(wl, &old_part);
1162 	if (ret < 0)
1163 		goto part_err;
1164 
1165 part_err:
1166 	pm_runtime_put_autosuspend(wl->dev);
1167 
1168 skip_write:
1169 	mutex_unlock(&wl->mutex);
1170 
1171 	if (ret == 0)
1172 		*ppos += bytes;
1173 
1174 	kfree(buf);
1175 
1176 	return ((ret == 0) ? bytes : ret);
1177 }
1178 
1179 static loff_t dev_mem_seek(struct file *file, loff_t offset, int orig)
1180 {
1181 	/* only requests of dword-aligned size and offset are supported */
1182 	if (offset % 4)
1183 		return -EINVAL;
1184 
1185 	return no_seek_end_llseek(file, offset, orig);
1186 }
1187 
1188 static const struct file_operations dev_mem_ops = {
1189 	.open = simple_open,
1190 	.read = dev_mem_read,
1191 	.write = dev_mem_write,
1192 	.llseek = dev_mem_seek,
1193 };
1194 
1195 static ssize_t fw_logger_read(struct file *file, char __user *user_buf,
1196 			      size_t count, loff_t *ppos)
1197 {
1198 	struct wl1271 *wl = file->private_data;
1199 
1200 	return wl1271_format_buffer(user_buf, count,
1201 					ppos, "%d\n",
1202 					wl->conf.fwlog.output);
1203 }
1204 
1205 static ssize_t fw_logger_write(struct file *file,
1206 			       const char __user *user_buf,
1207 			       size_t count, loff_t *ppos)
1208 {
1209 	struct wl1271 *wl = file->private_data;
1210 	unsigned long value;
1211 	int ret;
1212 
1213 	ret = kstrtoul_from_user(user_buf, count, 0, &value);
1214 	if (ret < 0) {
1215 		wl1271_warning("illegal value in fw_logger");
1216 		return -EINVAL;
1217 	}
1218 
1219 	if ((value > 2) || (value == 0)) {
1220 		wl1271_warning("fw_logger value must be 1-UART 2-SDIO");
1221 		return -ERANGE;
1222 	}
1223 
1224 	if (wl->conf.fwlog.output == 0) {
1225 		wl1271_warning("invalid operation - fw logger disabled by default, please change mode via wlconf");
1226 		return -EINVAL;
1227 	}
1228 
1229 	mutex_lock(&wl->mutex);
1230 	ret = pm_runtime_resume_and_get(wl->dev);
1231 	if (ret < 0) {
1232 		count = ret;
1233 		goto out;
1234 	}
1235 
1236 	wl->conf.fwlog.output = value;
1237 
1238 	ret = wl12xx_cmd_config_fwlog(wl);
1239 
1240 	pm_runtime_put_autosuspend(wl->dev);
1241 
1242 out:
1243 	mutex_unlock(&wl->mutex);
1244 	return count;
1245 }
1246 
1247 static const struct file_operations fw_logger_ops = {
1248 	.open = simple_open,
1249 	.read = fw_logger_read,
1250 	.write = fw_logger_write,
1251 	.llseek = default_llseek,
1252 };
1253 
1254 static void wl1271_debugfs_add_files(struct wl1271 *wl,
1255 				     struct dentry *rootdir)
1256 {
1257 	struct dentry *streaming;
1258 
1259 	DEBUGFS_ADD(tx_queue_len, rootdir);
1260 	DEBUGFS_ADD(retry_count, rootdir);
1261 	DEBUGFS_ADD(excessive_retries, rootdir);
1262 
1263 	DEBUGFS_ADD(gpio_power, rootdir);
1264 	DEBUGFS_ADD(start_recovery, rootdir);
1265 	DEBUGFS_ADD(driver_state, rootdir);
1266 	DEBUGFS_ADD(vifs_state, rootdir);
1267 	DEBUGFS_ADD(dtim_interval, rootdir);
1268 	DEBUGFS_ADD(suspend_dtim_interval, rootdir);
1269 	DEBUGFS_ADD(beacon_interval, rootdir);
1270 	DEBUGFS_ADD(beacon_filtering, rootdir);
1271 	DEBUGFS_ADD(dynamic_ps_timeout, rootdir);
1272 	DEBUGFS_ADD(forced_ps, rootdir);
1273 	DEBUGFS_ADD(split_scan_timeout, rootdir);
1274 	DEBUGFS_ADD(irq_pkt_threshold, rootdir);
1275 	DEBUGFS_ADD(irq_blk_threshold, rootdir);
1276 	DEBUGFS_ADD(irq_timeout, rootdir);
1277 	DEBUGFS_ADD(fw_stats_raw, rootdir);
1278 	DEBUGFS_ADD(sleep_auth, rootdir);
1279 	DEBUGFS_ADD(fw_logger, rootdir);
1280 
1281 	streaming = debugfs_create_dir("rx_streaming", rootdir);
1282 
1283 	DEBUGFS_ADD_PREFIX(rx_streaming, interval, streaming);
1284 	DEBUGFS_ADD_PREFIX(rx_streaming, always, streaming);
1285 
1286 	DEBUGFS_ADD_PREFIX(dev, mem, rootdir);
1287 }
1288 
1289 void wl1271_debugfs_reset(struct wl1271 *wl)
1290 {
1291 	if (!wl->stats.fw_stats)
1292 		return;
1293 
1294 	memset(wl->stats.fw_stats, 0, wl->stats.fw_stats_len);
1295 	wl->stats.retry_count = 0;
1296 	wl->stats.excessive_retries = 0;
1297 }
1298 
1299 int wl1271_debugfs_init(struct wl1271 *wl)
1300 {
1301 	int ret;
1302 	struct dentry *rootdir;
1303 
1304 	rootdir = debugfs_create_dir(KBUILD_MODNAME,
1305 				     wl->hw->wiphy->debugfsdir);
1306 
1307 	wl->stats.fw_stats = kzalloc(wl->stats.fw_stats_len, GFP_KERNEL);
1308 	if (!wl->stats.fw_stats) {
1309 		ret = -ENOMEM;
1310 		goto out_remove;
1311 	}
1312 
1313 	wl->stats.fw_stats_update = jiffies;
1314 
1315 	wl1271_debugfs_add_files(wl, rootdir);
1316 
1317 	ret = wlcore_debugfs_init(wl, rootdir);
1318 	if (ret < 0)
1319 		goto out_exit;
1320 
1321 	goto out;
1322 
1323 out_exit:
1324 	wl1271_debugfs_exit(wl);
1325 
1326 out_remove:
1327 	debugfs_remove_recursive(rootdir);
1328 
1329 out:
1330 	return ret;
1331 }
1332 
1333 void wl1271_debugfs_exit(struct wl1271 *wl)
1334 {
1335 	kfree(wl->stats.fw_stats);
1336 	wl->stats.fw_stats = NULL;
1337 }
1338