GNU Linux-libre 4.19.207-gnu1
[releases.git] / drivers / net / wireless / ti / wlcore / debugfs.c
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 int wl1271_debugfs_add_files(struct wl1271 *wl,
1305                                     struct dentry *rootdir)
1306 {
1307         int ret = 0;
1308         struct dentry *entry, *streaming;
1309
1310         DEBUGFS_ADD(tx_queue_len, rootdir);
1311         DEBUGFS_ADD(retry_count, rootdir);
1312         DEBUGFS_ADD(excessive_retries, rootdir);
1313
1314         DEBUGFS_ADD(gpio_power, rootdir);
1315         DEBUGFS_ADD(start_recovery, rootdir);
1316         DEBUGFS_ADD(driver_state, rootdir);
1317         DEBUGFS_ADD(vifs_state, rootdir);
1318         DEBUGFS_ADD(dtim_interval, rootdir);
1319         DEBUGFS_ADD(suspend_dtim_interval, rootdir);
1320         DEBUGFS_ADD(beacon_interval, rootdir);
1321         DEBUGFS_ADD(beacon_filtering, rootdir);
1322         DEBUGFS_ADD(dynamic_ps_timeout, rootdir);
1323         DEBUGFS_ADD(forced_ps, rootdir);
1324         DEBUGFS_ADD(split_scan_timeout, rootdir);
1325         DEBUGFS_ADD(irq_pkt_threshold, rootdir);
1326         DEBUGFS_ADD(irq_blk_threshold, rootdir);
1327         DEBUGFS_ADD(irq_timeout, rootdir);
1328         DEBUGFS_ADD(fw_stats_raw, rootdir);
1329         DEBUGFS_ADD(sleep_auth, rootdir);
1330         DEBUGFS_ADD(fw_logger, rootdir);
1331
1332         streaming = debugfs_create_dir("rx_streaming", rootdir);
1333         if (!streaming || IS_ERR(streaming))
1334                 goto err;
1335
1336         DEBUGFS_ADD_PREFIX(rx_streaming, interval, streaming);
1337         DEBUGFS_ADD_PREFIX(rx_streaming, always, streaming);
1338
1339         DEBUGFS_ADD_PREFIX(dev, mem, rootdir);
1340
1341         return 0;
1342
1343 err:
1344         if (IS_ERR(entry))
1345                 ret = PTR_ERR(entry);
1346         else
1347                 ret = -ENOMEM;
1348
1349         return ret;
1350 }
1351
1352 void wl1271_debugfs_reset(struct wl1271 *wl)
1353 {
1354         if (!wl->stats.fw_stats)
1355                 return;
1356
1357         memset(wl->stats.fw_stats, 0, wl->stats.fw_stats_len);
1358         wl->stats.retry_count = 0;
1359         wl->stats.excessive_retries = 0;
1360 }
1361
1362 int wl1271_debugfs_init(struct wl1271 *wl)
1363 {
1364         int ret;
1365         struct dentry *rootdir;
1366
1367         rootdir = debugfs_create_dir(KBUILD_MODNAME,
1368                                      wl->hw->wiphy->debugfsdir);
1369
1370         if (IS_ERR(rootdir)) {
1371                 ret = PTR_ERR(rootdir);
1372                 goto out;
1373         }
1374
1375         wl->stats.fw_stats = kzalloc(wl->stats.fw_stats_len, GFP_KERNEL);
1376         if (!wl->stats.fw_stats) {
1377                 ret = -ENOMEM;
1378                 goto out_remove;
1379         }
1380
1381         wl->stats.fw_stats_update = jiffies;
1382
1383         ret = wl1271_debugfs_add_files(wl, rootdir);
1384         if (ret < 0)
1385                 goto out_exit;
1386
1387         ret = wlcore_debugfs_init(wl, rootdir);
1388         if (ret < 0)
1389                 goto out_exit;
1390
1391         goto out;
1392
1393 out_exit:
1394         wl1271_debugfs_exit(wl);
1395
1396 out_remove:
1397         debugfs_remove_recursive(rootdir);
1398
1399 out:
1400         return ret;
1401 }
1402
1403 void wl1271_debugfs_exit(struct wl1271 *wl)
1404 {
1405         kfree(wl->stats.fw_stats);
1406         wl->stats.fw_stats = NULL;
1407 }