wlcore: add a debugfs entry to allow changing the sleep mode by hand
[cascardo/linux.git] / drivers / net / wireless / ti / wlcore / debugfs.c
index d5aea1f..91e43de 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/skbuff.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "wlcore.h"
 #include "debug.h"
 #include "ps.h"
 #include "io.h"
 #include "tx.h"
+#include "hw_ops.h"
 
 /* ms */
 #define WL1271_DEBUGFS_STATS_LIFETIME 1000
 
 /* debugfs macros idea from mac80211 */
-#define DEBUGFS_FORMAT_BUFFER_SIZE 100
-static int wl1271_format_buffer(char __user *userbuf, size_t count,
-                                   loff_t *ppos, char *fmt, ...)
+int wl1271_format_buffer(char __user *userbuf, size_t count,
+                        loff_t *ppos, char *fmt, ...)
 {
        va_list args;
        char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
@@ -51,59 +52,9 @@ static int wl1271_format_buffer(char __user *userbuf, size_t count,
 
        return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 }
+EXPORT_SYMBOL_GPL(wl1271_format_buffer);
 
-#define DEBUGFS_READONLY_FILE(name, fmt, value...)                     \
-static ssize_t name## _read(struct file *file, char __user *userbuf,   \
-                           size_t count, loff_t *ppos)                 \
-{                                                                      \
-       struct wl1271 *wl = file->private_data;                         \
-       return wl1271_format_buffer(userbuf, count, ppos,               \
-                                   fmt "\n", ##value);                 \
-}                                                                      \
-                                                                       \
-static const struct file_operations name## _ops = {                    \
-       .read = name## _read,                                           \
-       .open = simple_open,                                            \
-       .llseek = generic_file_llseek,                                  \
-};
-
-#define DEBUGFS_ADD(name, parent)                                      \
-       entry = debugfs_create_file(#name, 0400, parent,                \
-                                   wl, &name## _ops);                  \
-       if (!entry || IS_ERR(entry))                                    \
-               goto err;                                               \
-
-#define DEBUGFS_ADD_PREFIX(prefix, name, parent)                       \
-       do {                                                            \
-               entry = debugfs_create_file(#name, 0400, parent,        \
-                                   wl, &prefix## _## name## _ops);     \
-               if (!entry || IS_ERR(entry))                            \
-                       goto err;                                       \
-       } while (0);
-
-#define DEBUGFS_FWSTATS_FILE(sub, name, fmt)                           \
-static ssize_t sub## _ ##name## _read(struct file *file,               \
-                                     char __user *userbuf,             \
-                                     size_t count, loff_t *ppos)       \
-{                                                                      \
-       struct wl1271 *wl = file->private_data;                         \
-                                                                       \
-       wl1271_debugfs_update_stats(wl);                                \
-                                                                       \
-       return wl1271_format_buffer(userbuf, count, ppos, fmt "\n",     \
-                                   wl->stats.fw_stats->sub.name);      \
-}                                                                      \
-                                                                       \
-static const struct file_operations sub## _ ##name## _ops = {          \
-       .read = sub## _ ##name## _read,                                 \
-       .open = simple_open,                                            \
-       .llseek = generic_file_llseek,                                  \
-};
-
-#define DEBUGFS_FWSTATS_ADD(sub, name)                         \
-       DEBUGFS_ADD(sub## _ ##name, stats)
-
-static void wl1271_debugfs_update_stats(struct wl1271 *wl)
+void wl1271_debugfs_update_stats(struct wl1271 *wl)
 {
        int ret;
 
@@ -125,97 +76,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl)
 out:
        mutex_unlock(&wl->mutex);
 }
-
-DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u");
-
-DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u");
-DEBUGFS_FWSTATS_FILE(rx, dropped, "%u");
-DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u");
-DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u");
-DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u");
-DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u");
-
-DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u");
-DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u");
-
-DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u");
-DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u");
-DEBUGFS_FWSTATS_FILE(isr, irqs, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u");
-DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u");
-DEBUGFS_FWSTATS_FILE(isr, commands, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u");
-DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u");
-DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u");
-DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u");
-DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u");
-DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u");
-
-DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u");
-DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u");
-/* skipping wep.reserved */
-DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u");
-DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u");
-DEBUGFS_FWSTATS_FILE(wep, packets, "%u");
-DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u");
-
-DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u");
-/* skipping cont_miss_bcns_spread for now */
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u");
-
-DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u");
-DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u");
-
-DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u");
-
-DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u");
-DEBUGFS_FWSTATS_FILE(event, calibration, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u");
-DEBUGFS_FWSTATS_FILE(event, oom_late, "%u");
-DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u");
-DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u");
-
-DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u");
-
-DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u");
+EXPORT_SYMBOL_GPL(wl1271_debugfs_update_stats);
 
 DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count);
 DEBUGFS_READONLY_FILE(excessive_retries, "%u",
@@ -241,6 +102,89 @@ static const struct file_operations tx_queue_len_ops = {
        .llseek = default_llseek,
 };
 
+static void chip_op_handler(struct wl1271 *wl, unsigned long value,
+                           void *arg)
+{
+       int ret;
+       int (*chip_op) (struct wl1271 *wl);
+
+       if (!arg) {
+               wl1271_warning("debugfs chip_op_handler with no callback");
+               return;
+       }
+
+       ret = wl1271_ps_elp_wakeup(wl);
+       if (ret < 0)
+               return;
+
+       chip_op = arg;
+       chip_op(wl);
+
+       wl1271_ps_elp_sleep(wl);
+}
+
+
+static inline void no_write_handler(struct wl1271 *wl,
+                                   unsigned long value,
+                                   unsigned long param)
+{
+}
+
+#define WL12XX_CONF_DEBUGFS(param, conf_sub_struct,                    \
+                           min_val, max_val, write_handler_locked,     \
+                           write_handler_arg)                          \
+       static ssize_t param##_read(struct file *file,                  \
+                                     char __user *user_buf,            \
+                                     size_t count, loff_t *ppos)       \
+       {                                                               \
+       struct wl1271 *wl = file->private_data;                         \
+       return wl1271_format_buffer(user_buf, count,                    \
+                                   ppos, "%d\n",                       \
+                                   wl->conf.conf_sub_struct.param);    \
+       }                                                               \
+                                                                       \
+       static ssize_t param##_write(struct file *file,                 \
+                                    const char __user *user_buf,       \
+                                    size_t count, loff_t *ppos)        \
+       {                                                               \
+       struct wl1271 *wl = file->private_data;                         \
+       unsigned long value;                                            \
+       int ret;                                                        \
+                                                                       \
+       ret = kstrtoul_from_user(user_buf, count, 10, &value);          \
+       if (ret < 0) {                                                  \
+               wl1271_warning("illegal value for " #param);            \
+               return -EINVAL;                                         \
+       }                                                               \
+                                                                       \
+       if (value < min_val || value > max_val) {                       \
+               wl1271_warning(#param " is not in valid range");        \
+               return -ERANGE;                                         \
+       }                                                               \
+                                                                       \
+       mutex_lock(&wl->mutex);                                         \
+       wl->conf.conf_sub_struct.param = value;                         \
+                                                                       \
+       write_handler_locked(wl, value, write_handler_arg);             \
+                                                                       \
+       mutex_unlock(&wl->mutex);                                       \
+       return count;                                                   \
+       }                                                               \
+                                                                       \
+       static const struct file_operations param##_ops = {             \
+               .read = param##_read,                                   \
+               .write = param##_write,                                 \
+               .open = simple_open,                                    \
+               .llseek = default_llseek,                               \
+       };
+
+WL12XX_CONF_DEBUGFS(irq_pkt_threshold, rx, 0, 65535,
+                   chip_op_handler, wl1271_acx_init_rx_interrupt)
+WL12XX_CONF_DEBUGFS(irq_blk_threshold, rx, 0, 65535,
+                   chip_op_handler, wl1271_acx_init_rx_interrupt)
+WL12XX_CONF_DEBUGFS(irq_timeout, rx, 0, 100,
+                   chip_op_handler, wl1271_acx_init_rx_interrupt)
+
 static ssize_t gpio_power_read(struct file *file, char __user *user_buf,
                          size_t count, loff_t *ppos)
 {
@@ -535,8 +479,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
        DRIVER_STATE_PRINT_LHEX(ap_ps_map);
        DRIVER_STATE_PRINT_HEX(quirks);
        DRIVER_STATE_PRINT_HEX(irq);
-       DRIVER_STATE_PRINT_HEX(ref_clock);
-       DRIVER_STATE_PRINT_HEX(tcxo_clock);
+       /* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */
        DRIVER_STATE_PRINT_HEX(hw_pg_ver);
        DRIVER_STATE_PRINT_HEX(platform_quirks);
        DRIVER_STATE_PRINT_HEX(chip.id);
@@ -647,7 +590,6 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
                VIF_STATE_PRINT_INT(last_rssi_event);
                VIF_STATE_PRINT_INT(ba_support);
                VIF_STATE_PRINT_INT(ba_allowed);
-               VIF_STATE_PRINT_INT(is_gem);
                VIF_STATE_PRINT_LLHEX(tx_security_seq);
                VIF_STATE_PRINT_INT(tx_security_last_seq_lsb);
        }
@@ -1002,108 +944,87 @@ static const struct file_operations beacon_filtering_ops = {
        .llseek = default_llseek,
 };
 
-static int wl1271_debugfs_add_files(struct wl1271 *wl,
-                                    struct dentry *rootdir)
+static ssize_t fw_stats_raw_read(struct file *file,
+                                char __user *userbuf,
+                                size_t count, loff_t *ppos)
 {
-       int ret = 0;
-       struct dentry *entry, *stats, *streaming;
+       struct wl1271 *wl = file->private_data;
 
-       stats = debugfs_create_dir("fw-statistics", rootdir);
-       if (!stats || IS_ERR(stats)) {
-               entry = stats;
-               goto err;
+       wl1271_debugfs_update_stats(wl);
+
+       return simple_read_from_buffer(userbuf, count, ppos,
+                                      wl->stats.fw_stats,
+                                      wl->stats.fw_stats_len);
+}
+
+static const struct file_operations fw_stats_raw_ops = {
+       .read = fw_stats_raw_read,
+       .open = simple_open,
+       .llseek = default_llseek,
+};
+
+static ssize_t sleep_auth_read(struct file *file, char __user *user_buf,
+                              size_t count, loff_t *ppos)
+{
+       struct wl1271 *wl = file->private_data;
+
+       return wl1271_format_buffer(user_buf, count,
+                                   ppos, "%d\n",
+                                   wl->sleep_auth);
+}
+
+static ssize_t sleep_auth_write(struct file *file,
+                               const char __user *user_buf,
+                               size_t count, loff_t *ppos)
+{
+       struct wl1271 *wl = file->private_data;
+       unsigned long value;
+       int ret;
+
+       ret = kstrtoul_from_user(user_buf, count, 0, &value);
+       if (ret < 0) {
+               wl1271_warning("illegal value in sleep_auth");
+               return -EINVAL;
        }
 
-       DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
-
-       DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
-       DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
-       DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
-       DEBUGFS_FWSTATS_ADD(rx, dropped);
-       DEBUGFS_FWSTATS_ADD(rx, fcs_err);
-       DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
-       DEBUGFS_FWSTATS_ADD(rx, path_reset);
-       DEBUGFS_FWSTATS_ADD(rx, reset_counter);
-
-       DEBUGFS_FWSTATS_ADD(dma, rx_requested);
-       DEBUGFS_FWSTATS_ADD(dma, rx_errors);
-       DEBUGFS_FWSTATS_ADD(dma, tx_requested);
-       DEBUGFS_FWSTATS_ADD(dma, tx_errors);
-
-       DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
-       DEBUGFS_FWSTATS_ADD(isr, fiqs);
-       DEBUGFS_FWSTATS_ADD(isr, rx_headers);
-       DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
-       DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
-       DEBUGFS_FWSTATS_ADD(isr, irqs);
-       DEBUGFS_FWSTATS_ADD(isr, tx_procs);
-       DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
-       DEBUGFS_FWSTATS_ADD(isr, dma0_done);
-       DEBUGFS_FWSTATS_ADD(isr, dma1_done);
-       DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
-       DEBUGFS_FWSTATS_ADD(isr, commands);
-       DEBUGFS_FWSTATS_ADD(isr, rx_procs);
-       DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
-       DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
-       DEBUGFS_FWSTATS_ADD(isr, pci_pm);
-       DEBUGFS_FWSTATS_ADD(isr, wakeups);
-       DEBUGFS_FWSTATS_ADD(isr, low_rssi);
-
-       DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
-       DEBUGFS_FWSTATS_ADD(wep, default_key_count);
-       /* skipping wep.reserved */
-       DEBUGFS_FWSTATS_ADD(wep, key_not_found);
-       DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
-       DEBUGFS_FWSTATS_ADD(wep, packets);
-       DEBUGFS_FWSTATS_ADD(wep, interrupt);
-
-       DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
-       DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
-       DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
-       DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
-       DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
-       DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
-       DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
-       DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
-       DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
-       DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
-       DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
-       DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
-       /* skipping cont_miss_bcns_spread for now */
-       DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
-
-       DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
-       DEBUGFS_FWSTATS_ADD(mic, calc_failure);
-
-       DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
-       DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
-       DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
-       DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
-       DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
-       DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
-
-       DEBUGFS_FWSTATS_ADD(event, heart_beat);
-       DEBUGFS_FWSTATS_ADD(event, calibration);
-       DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
-       DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
-       DEBUGFS_FWSTATS_ADD(event, rx_pool);
-       DEBUGFS_FWSTATS_ADD(event, oom_late);
-       DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
-       DEBUGFS_FWSTATS_ADD(event, tx_stuck);
-
-       DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
-       DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
-       DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
-       DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
-       DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
-       DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
-       DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
-
-       DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
-       DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
-       DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
-       DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
-       DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
+       if (value < 0 || value > WL1271_PSM_MAX) {
+               wl1271_warning("sleep_auth must be between 0 and %d",
+                              WL1271_PSM_MAX);
+               return -ERANGE;
+       }
+
+       mutex_lock(&wl->mutex);
+
+       if (wl->state == WL1271_STATE_OFF)
+               goto out;
+
+       ret = wl1271_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       ret = wl1271_acx_sleep_auth(wl, value);
+       if (ret < 0)
+               goto out_sleep;
+
+out_sleep:
+       wl1271_ps_elp_sleep(wl);
+out:
+       mutex_unlock(&wl->mutex);
+       return count;
+}
+
+static const struct file_operations sleep_auth_ops = {
+       .read = sleep_auth_read,
+       .write = sleep_auth_write,
+       .open = simple_open,
+       .llseek = default_llseek,
+};
+
+static int wl1271_debugfs_add_files(struct wl1271 *wl,
+                                   struct dentry *rootdir)
+{
+       int ret = 0;
+       struct dentry *entry, *streaming;
 
        DEBUGFS_ADD(tx_queue_len, rootdir);
        DEBUGFS_ADD(retry_count, rootdir);
@@ -1120,6 +1041,11 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
        DEBUGFS_ADD(dynamic_ps_timeout, rootdir);
        DEBUGFS_ADD(forced_ps, rootdir);
        DEBUGFS_ADD(split_scan_timeout, rootdir);
+       DEBUGFS_ADD(irq_pkt_threshold, rootdir);
+       DEBUGFS_ADD(irq_blk_threshold, rootdir);
+       DEBUGFS_ADD(irq_timeout, rootdir);
+       DEBUGFS_ADD(fw_stats_raw, rootdir);
+       DEBUGFS_ADD(sleep_auth, rootdir);
 
        streaming = debugfs_create_dir("rx_streaming", rootdir);
        if (!streaming || IS_ERR(streaming))
@@ -1145,7 +1071,7 @@ void wl1271_debugfs_reset(struct wl1271 *wl)
        if (!wl->stats.fw_stats)
                return;
 
-       memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+       memset(wl->stats.fw_stats, 0, wl->stats.fw_stats_len);
        wl->stats.retry_count = 0;
        wl->stats.excessive_retries = 0;
 }
@@ -1160,34 +1086,34 @@ int wl1271_debugfs_init(struct wl1271 *wl)
 
        if (IS_ERR(rootdir)) {
                ret = PTR_ERR(rootdir);
-               goto err;
+               goto out;
        }
 
-       wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
-                                     GFP_KERNEL);
-
+       wl->stats.fw_stats = kzalloc(wl->stats.fw_stats_len, GFP_KERNEL);
        if (!wl->stats.fw_stats) {
                ret = -ENOMEM;
-               goto err_fw;
+               goto out_remove;
        }
 
        wl->stats.fw_stats_update = jiffies;
 
        ret = wl1271_debugfs_add_files(wl, rootdir);
+       if (ret < 0)
+               goto out_exit;
 
+       ret = wlcore_debugfs_init(wl, rootdir);
        if (ret < 0)
-               goto err_file;
+               goto out_exit;
 
-       return 0;
+       goto out;
 
-err_file:
-       kfree(wl->stats.fw_stats);
-       wl->stats.fw_stats = NULL;
+out_exit:
+       wl1271_debugfs_exit(wl);
 
-err_fw:
+out_remove:
        debugfs_remove_recursive(rootdir);
 
-err:
+out:
        return ret;
 }