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