summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/net/wireless/ath/wil6210/debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/net/wireless/ath/wil6210/debugfs.c')
-rw-r--r--kernel/drivers/net/wireless/ath/wil6210/debugfs.c172
1 files changed, 130 insertions, 42 deletions
diff --git a/kernel/drivers/net/wireless/ath/wil6210/debugfs.c b/kernel/drivers/net/wireless/ath/wil6210/debugfs.c
index bbc22d88f..97bc186f9 100644
--- a/kernel/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/kernel/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2015 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -24,6 +24,7 @@
#include "wil6210.h"
#include "wmi.h"
#include "txrx.h"
+#include "pmc.h"
/* Nasty hack. Better have per device instances */
static u32 mem_addr;
@@ -61,7 +62,7 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
seq_printf(s, " swhead = %d\n", vring->swhead);
seq_printf(s, " hwtail = [0x%08x] -> ", vring->hwtail);
if (x) {
- v = ioread32(x);
+ v = readl(x);
seq_printf(s, "0x%08x = %d\n", v, v);
} else {
seq_puts(s, "???\n");
@@ -123,15 +124,17 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
if (cid < WIL6210_MAX_CID)
seq_printf(s,
- "\n%pM CID %d TID %d BACK([%u] %u TU A%s) [%3d|%3d] idle %s\n",
+ "\n%pM CID %d TID %d 1x%s BACK([%u] %u TU A%s) [%3d|%3d] idle %s\n",
wil->sta[cid].addr, cid, tid,
+ txdata->dot1x_open ? "+" : "-",
txdata->agg_wsize,
txdata->agg_timeout,
txdata->agg_amsdu ? "+" : "-",
used, avail, sidle);
else
seq_printf(s,
- "\nBroadcast [%3d|%3d] idle %s\n",
+ "\nBroadcast 1x%s [%3d|%3d] idle %s\n",
+ txdata->dot1x_open ? "+" : "-",
used, avail, sidle);
wil_print_vring(s, wil, name, vring, '_', 'H');
@@ -153,6 +156,12 @@ static const struct file_operations fops_vring = {
.llseek = seq_lseek,
};
+static void wil_seq_hexdump(struct seq_file *s, void *p, int len,
+ const char *prefix)
+{
+ seq_hex_dump(s, prefix, DUMP_PREFIX_NONE, 16, 1, p, len, false);
+}
+
static void wil_print_ring(struct seq_file *s, const char *prefix,
void __iomem *off)
{
@@ -209,8 +218,6 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
le16_to_cpu(hdr.seq), len,
le16_to_cpu(hdr.type), hdr.flags);
if (len <= MAX_MBOXITEM_SIZE) {
- int n = 0;
- char printbuf[16 * 3 + 2];
unsigned char databuf[MAX_MBOXITEM_SIZE];
void __iomem *src = wmi_buffer(wil, d.addr) +
sizeof(struct wil6210_mbox_hdr);
@@ -220,16 +227,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
* reading header
*/
wil_memcpy_fromio_32(databuf, src, len);
- while (n < len) {
- int l = min(len - n, 16);
-
- hex_dump_to_buffer(databuf + n, l,
- 16, 1, printbuf,
- sizeof(printbuf),
- false);
- seq_printf(s, " : %s\n", printbuf);
- n += l;
- }
+ wil_seq_hexdump(s, databuf, len, " : ");
}
} else {
seq_puts(s, "\n");
@@ -265,7 +263,7 @@ static const struct file_operations fops_mbox = {
static int wil_debugfs_iomem_x32_set(void *data, u64 val)
{
- iowrite32(val, (void __iomem *)data);
+ writel(val, (void __iomem *)data);
wmb(); /* make sure write propagated to HW */
return 0;
@@ -273,7 +271,7 @@ static int wil_debugfs_iomem_x32_set(void *data, u64 val)
static int wil_debugfs_iomem_x32_get(void *data, u64 *val)
{
- *val = ioread32((void __iomem *)data);
+ *val = readl((void __iomem *)data);
return 0;
}
@@ -303,7 +301,7 @@ static int wil_debugfs_ulong_get(void *data, u64 *val)
}
DEFINE_SIMPLE_ATTRIBUTE(wil_fops_ulong, wil_debugfs_ulong_get,
- wil_debugfs_ulong_set, "%llu\n");
+ wil_debugfs_ulong_set, "0x%llx\n");
static struct dentry *wil_debugfs_create_ulong(const char *name, umode_t mode,
struct dentry *parent,
@@ -474,7 +472,7 @@ static int wil_memread_debugfs_show(struct seq_file *s, void *data)
void __iomem *a = wmi_buffer(wil, cpu_to_le32(mem_addr));
if (a)
- seq_printf(s, "[0x%08x] = 0x%08x\n", mem_addr, ioread32(a));
+ seq_printf(s, "[0x%08x] = 0x%08x\n", mem_addr, readl(a));
else
seq_printf(s, "[0x%08x] = INVALID\n", mem_addr);
@@ -702,6 +700,89 @@ static const struct file_operations fops_back = {
.open = simple_open,
};
+/* pmc control, write:
+ * - "alloc <num descriptors> <descriptor_size>" to allocate PMC
+ * - "free" to release memory allocated for PMC
+ */
+static ssize_t wil_write_pmccfg(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ struct wil6210_priv *wil = file->private_data;
+ int rc;
+ char *kbuf = kmalloc(len + 1, GFP_KERNEL);
+ char cmd[9];
+ int num_descs, desc_size;
+
+ if (!kbuf)
+ return -ENOMEM;
+
+ rc = simple_write_to_buffer(kbuf, len, ppos, buf, len);
+ if (rc != len) {
+ kfree(kbuf);
+ return rc >= 0 ? -EIO : rc;
+ }
+
+ kbuf[len] = '\0';
+ rc = sscanf(kbuf, "%8s %d %d", cmd, &num_descs, &desc_size);
+ kfree(kbuf);
+
+ if (rc < 0)
+ return rc;
+
+ if (rc < 1) {
+ wil_err(wil, "pmccfg: no params given\n");
+ return -EINVAL;
+ }
+
+ if (0 == strcmp(cmd, "alloc")) {
+ if (rc != 3) {
+ wil_err(wil, "pmccfg: alloc requires 2 params\n");
+ return -EINVAL;
+ }
+ wil_pmc_alloc(wil, num_descs, desc_size);
+ } else if (0 == strcmp(cmd, "free")) {
+ if (rc != 1) {
+ wil_err(wil, "pmccfg: free does not have any params\n");
+ return -EINVAL;
+ }
+ wil_pmc_free(wil, true);
+ } else {
+ wil_err(wil, "pmccfg: Unrecognized command \"%s\"\n", cmd);
+ return -EINVAL;
+ }
+
+ return len;
+}
+
+static ssize_t wil_read_pmccfg(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wil6210_priv *wil = file->private_data;
+ char text[256];
+ char help[] = "pmc control, write:\n"
+ " - \"alloc <num descriptors> <descriptor_size>\" to allocate pmc\n"
+ " - \"free\" to free memory allocated for pmc\n";
+
+ sprintf(text, "Last command status: %d\n\n%s",
+ wil_pmc_last_cmd_status(wil),
+ help);
+
+ return simple_read_from_buffer(user_buf, count, ppos, text,
+ strlen(text) + 1);
+}
+
+static const struct file_operations fops_pmccfg = {
+ .read = wil_read_pmccfg,
+ .write = wil_write_pmccfg,
+ .open = simple_open,
+};
+
+static const struct file_operations fops_pmcdata = {
+ .open = simple_open,
+ .read = wil_pmc_read,
+ .llseek = wil_pmc_llseek,
+};
+
/*---tx_mgmt---*/
/* Write mgmt frame to this file to send it */
static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf,
@@ -781,22 +862,6 @@ static const struct file_operations fops_wmi = {
.open = simple_open,
};
-static void wil_seq_hexdump(struct seq_file *s, void *p, int len,
- const char *prefix)
-{
- char printbuf[16 * 3 + 2];
- int i = 0;
-
- while (i < len) {
- int l = min(len - i, 16);
-
- hex_dump_to_buffer(p + i, l, 16, 1, printbuf,
- sizeof(printbuf), false);
- seq_printf(s, "%s%s\n", prefix, printbuf);
- i += l;
- }
-}
-
static void wil_seq_print_skb(struct seq_file *s, struct sk_buff *skb)
{
int i = 0;
@@ -1111,8 +1176,7 @@ static int wil_link_debugfs_show(struct seq_file *s, void *data)
status = "connected";
break;
}
- seq_printf(s, "[%d] %pM %s%s\n", i, p->addr, status,
- (p->data_port_open ? " data_port_open" : ""));
+ seq_printf(s, "[%d] %pM %s\n", i, p->addr, status);
if (p->status == wil_sta_connected) {
rc = wil_cid_fill_sinfo(wil, i, &sinfo);
@@ -1259,6 +1323,7 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
{
int i;
u16 index = ((r->head_seq_num - r->ssn) & 0xfff) % r->buf_size;
+ unsigned long long drop_dup = r->drop_dup, drop_old = r->drop_old;
seq_printf(s, "([%2d] %3d TU) 0x%03x [", r->buf_size, r->timeout,
r->head_seq_num);
@@ -1268,14 +1333,17 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
else
seq_printf(s, "%c", r->reorder_buf[i] ? '*' : '_');
}
- seq_printf(s, "] last drop 0x%03x\n", r->ssn_last_drop);
+ seq_printf(s,
+ "] total %llu drop %llu (dup %llu + old %llu) last 0x%03x\n",
+ r->total, drop_dup + drop_old, drop_dup, drop_old,
+ r->ssn_last_drop);
}
static int wil_sta_debugfs_show(struct seq_file *s, void *data)
__acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
{
struct wil6210_priv *wil = s->private;
- int i, tid;
+ int i, tid, mcs;
for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
struct wil_sta_info *p = &wil->sta[i];
@@ -1292,8 +1360,7 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
status = "connected";
break;
}
- seq_printf(s, "[%d] %pM %s%s\n", i, p->addr, status,
- (p->data_port_open ? " data_port_open" : ""));
+ seq_printf(s, "[%d] %pM %s\n", i, p->addr, status);
if (p->status == wil_sta_connected) {
spin_lock_bh(&p->tid_rx_lock);
@@ -1306,6 +1373,18 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
}
}
spin_unlock_bh(&p->tid_rx_lock);
+ seq_printf(s,
+ "Rx invalid frame: non-data %lu, short %lu, large %lu\n",
+ p->stats.rx_non_data_frame,
+ p->stats.rx_short_frame,
+ p->stats.rx_large_frame);
+
+ seq_puts(s, "Rx/MCS:");
+ for (mcs = 0; mcs < ARRAY_SIZE(p->stats.rx_per_mcs);
+ mcs++)
+ seq_printf(s, " %lld",
+ p->stats.rx_per_mcs[mcs]);
+ seq_puts(s, "\n");
}
}
@@ -1363,6 +1442,8 @@ static const struct {
{"tx_mgmt", S_IWUSR, &fops_txmgmt},
{"wmi_send", S_IWUSR, &fops_wmi},
{"back", S_IRUGO | S_IWUSR, &fops_back},
+ {"pmccfg", S_IRUGO | S_IWUSR, &fops_pmccfg},
+ {"pmcdata", S_IRUGO, &fops_pmcdata},
{"temp", S_IRUGO, &fops_temp},
{"freq", S_IRUGO, &fops_freq},
{"link", S_IRUGO, &fops_link},
@@ -1440,6 +1521,8 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
if (IS_ERR_OR_NULL(dbg))
return -ENODEV;
+ wil_pmc_init(wil);
+
wil6210_debugfs_init_files(wil, dbg);
wil6210_debugfs_init_isr(wil, dbg);
wil6210_debugfs_init_blobs(wil, dbg);
@@ -1459,4 +1542,9 @@ void wil6210_debugfs_remove(struct wil6210_priv *wil)
{
debugfs_remove_recursive(wil->debug);
wil->debug = NULL;
+
+ /* free pmc memory without sending command to fw, as it will
+ * be reset on the way down anyway
+ */
+ wil_pmc_free(wil, false);
}