ath9k: extend DFS detector stats in dfs_debugfs
[pandora-kernel.git] / drivers / net / wireless / ath / ath9k / dfs_debug.c
index 4364c10..55d2807 100644 (file)
 #include "ath9k.h"
 #include "dfs_debug.h"
 
+
+struct ath_dfs_pool_stats global_dfs_pool_stats = { 0 };
+
 #define ATH9K_DFS_STAT(s, p) \
        len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \
                        sc->debug.stats.dfs_stats.p);
+#define ATH9K_DFS_POOL_STAT(s, p) \
+       len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \
+                       global_dfs_pool_stats.p);
 
 static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
                             size_t count, loff_t *ppos)
@@ -43,6 +49,9 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
                        hw_ver->macVersion, hw_ver->macRev,
                        (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_DFS) ?
                                        "enabled" : "disabled");
+       len += snprintf(buf + len, size - len, "Pulse detector statistics:\n");
+       ATH9K_DFS_STAT("pulse events reported   ", pulses_total);
+       ATH9K_DFS_STAT("invalid pulse events    ", pulses_no_dfs);
        ATH9K_DFS_STAT("DFS pulses detected     ", pulses_detected);
        ATH9K_DFS_STAT("Datalen discards        ", datalen_discards);
        ATH9K_DFS_STAT("RSSI discards           ", rssi_discards);
@@ -50,6 +59,18 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
        ATH9K_DFS_STAT("Primary channel pulses  ", pri_phy_errors);
        ATH9K_DFS_STAT("Secondary channel pulses", ext_phy_errors);
        ATH9K_DFS_STAT("Dual channel pulses     ", dc_phy_errors);
+       len += snprintf(buf + len, size - len, "Radar detector statistics "
+                       "(current DFS region: %d)\n", sc->dfs_detector->region);
+       ATH9K_DFS_STAT("Pulse events processed  ", pulses_processed);
+       ATH9K_DFS_STAT("Radars detected         ", radar_detected);
+       len += snprintf(buf + len, size - len, "Global Pool statistics:\n");
+       ATH9K_DFS_POOL_STAT("Pool references         ", pool_reference);
+       ATH9K_DFS_POOL_STAT("Pulses allocated        ", pulse_allocated);
+       ATH9K_DFS_POOL_STAT("Pulses alloc error      ", pulse_alloc_error);
+       ATH9K_DFS_POOL_STAT("Pulses in use           ", pulse_used);
+       ATH9K_DFS_POOL_STAT("Seqs. allocated         ", pseq_allocated);
+       ATH9K_DFS_POOL_STAT("Seqs. alloc error       ", pseq_alloc_error);
+       ATH9K_DFS_POOL_STAT("Seqs. in use            ", pseq_used);
 
        if (len > size)
                len = size;
@@ -60,8 +81,33 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
        return retval;
 }
 
+/* magic number to prevent accidental reset of DFS statistics */
+#define DFS_STATS_RESET_MAGIC  0x80000000
+static ssize_t write_file_dfs(struct file *file, const char __user *user_buf,
+                             size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       unsigned long val;
+       char buf[32];
+       ssize_t len;
+
+       len = min(count, sizeof(buf) - 1);
+       if (copy_from_user(buf, user_buf, len))
+               return -EFAULT;
+
+       buf[len] = '\0';
+       if (strict_strtoul(buf, 0, &val))
+               return -EINVAL;
+
+       if (val == DFS_STATS_RESET_MAGIC)
+               memset(&sc->debug.stats.dfs_stats, 0,
+                      sizeof(sc->debug.stats.dfs_stats));
+       return count;
+}
+
 static const struct file_operations fops_dfs_stats = {
        .read = read_file_dfs,
+       .write = write_file_dfs,
        .open = simple_open,
        .owner = THIS_MODULE,
        .llseek = default_llseek,