summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2015-10-26 22:22:47 +0100
committerBjørn Mork <bjorn@mork.no>2015-10-26 23:57:05 +0100
commit42fafa3886f5fc971369e073dfc4430f810d72a3 (patch)
tree97ae83d45a2644680cd00b79e4cadc49b4a07db5
parente2ca3c395c3d03019bc0e00332f008a6f61d9054 (diff)
mwlwifi: add debugfs to version 10.3.0.3
Signed-off-by: Bjørn Mork <bjorn@mork.no>
-rw-r--r--Makefile1
-rw-r--r--Makefile.external1
-rw-r--r--Makefile.kernel1
-rw-r--r--debugfs.c287
-rw-r--r--debugfs.h24
-rw-r--r--dev.h7
-rw-r--r--main.c13
7 files changed, 332 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index f5e7e74..6b48566 100644
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,7 @@ mwlwifi-objs += fwcmd.o
mwlwifi-objs += tx.o
mwlwifi-objs += rx.o
mwlwifi-objs += isr.o
+mwlwifi-$(CONFIG_DEBUG_FS) += debugfs.o
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
diff --git a/Makefile.external b/Makefile.external
index f5e7e74..6b48566 100644
--- a/Makefile.external
+++ b/Makefile.external
@@ -7,6 +7,7 @@ mwlwifi-objs += fwcmd.o
mwlwifi-objs += tx.o
mwlwifi-objs += rx.o
mwlwifi-objs += isr.o
+mwlwifi-$(CONFIG_DEBUG_FS) += debugfs.o
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
diff --git a/Makefile.kernel b/Makefile.kernel
index c6e03a3..8f751c3 100644
--- a/Makefile.kernel
+++ b/Makefile.kernel
@@ -7,3 +7,4 @@ mwlwifi-objs += fwcmd.o
mwlwifi-objs += tx.o
mwlwifi-objs += rx.o
mwlwifi-objs += isr.o
+mwlwifi-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/debugfs.c b/debugfs.c
new file mode 100644
index 0000000..b4bf7d0
--- /dev/null
+++ b/debugfs.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+/* Description: This file implements debug fs related functions. */
+
+#include <linux/debugfs.h>
+
+#include "sysadpt.h"
+#include "dev.h"
+#include "fwcmd.h"
+#include "debugfs.h"
+
+#define MWLWIFI_DEBUGFS_ADD_FILE(name) do { \
+ if (!debugfs_create_file(#name, 0644, priv->debugfs_phy, \
+ priv, &mwl_debugfs_##name##_fops)) \
+ return; \
+} while (0)
+
+#define MWLWIFI_DEBUGFS_FILE_OPS(name) \
+static const struct file_operations mwl_debugfs_##name##_fops = { \
+ .read = mwl_debugfs_##name##_read, \
+ .write = mwl_debugfs_##name##_write, \
+ .open = simple_open, \
+}
+
+#define MWLWIFI_DEBUGFS_FILE_READ_OPS(name) \
+static const struct file_operations mwl_debugfs_##name##_fops = { \
+ .read = mwl_debugfs_##name##_read, \
+ .open = simple_open, \
+}
+
+#define MWLWIFI_DEBUGFS_FILE_WRITE_OPS(name) \
+static const struct file_operations mwl_debugfs_##name##_fops = { \
+ .write = mwl_debugfs_##name##_write, \
+ .open = simple_open, \
+}
+
+static int dump_data(char *p, u8 *data, int len, char *title)
+{
+ char *str = p;
+ int cur_byte = 0;
+ int i;
+
+ str += sprintf(str, "%s\n", title);
+ for (cur_byte = 0; cur_byte < len; cur_byte += 8) {
+ if ((cur_byte + 8) < len) {
+ for (i = 0; i < 8; i++)
+ str += sprintf(str, "0x%02x ",
+ *(data+cur_byte+i));
+ str += sprintf(str, "\n");
+ } else {
+ for (i = 0; i < (len - cur_byte); i++)
+ str += sprintf(str, "0x%02x ",
+ *(data+cur_byte+i));
+ str += sprintf(str, "\n");
+ break;
+ }
+ }
+
+ return str-p;
+}
+
+static ssize_t mwl_debugfs_info_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct mwl_priv *priv = (struct mwl_priv *)file->private_data;
+ unsigned long page = get_zeroed_page(GFP_KERNEL);
+ char *p = (char *)page;
+ ssize_t ret;
+
+ if (!p)
+ return -ENOMEM;
+
+ p += sprintf(p, "\n");
+ p += sprintf(p, "driver name: %s\n", MWL_DRV_NAME);
+ p += sprintf(p, "chip type: %s\n",
+ (priv->chip_type == MWL8864) ? "88W8864" : "88W8897");
+ p += sprintf(p, "hw version: %X\n", priv->hw_data.hw_version);
+ p += sprintf(p, "driver version: %s\n", MWL_DRV_VERSION);
+ p += sprintf(p, "firmware version: 0x%08x\n",
+ priv->hw_data.fw_release_num);
+ p += sprintf(p, "mac address: %pM\n", priv->hw_data.mac_addr);
+ p += sprintf(p, "2g: %s\n", priv->disable_2g ? "disable" : "enable");
+ p += sprintf(p, "5g: %s\n", priv->disable_5g ? "disable" : "enable");
+ p += sprintf(p, "antenna: %d %d\n",
+ (priv->antenna_tx == ANTENNA_TX_4_AUTO) ? 4 : 2,
+ (priv->antenna_rx == ANTENNA_TX_4_AUTO) ? 4 : 2);
+ p += sprintf(p, "irq number: %d\n", priv->irq);
+ p += sprintf(p, "iobase0: %p\n", priv->iobase0);
+ p += sprintf(p, "iobase1: %p\n", priv->iobase1);
+ p += sprintf(p, "tx limit: %d\n", priv->txq_limit);
+ p += sprintf(p, "rx limit: %d\n", priv->recv_limit);
+ p += sprintf(p, "ap macid support: %08x\n",
+ priv->ap_macids_supported);
+ p += sprintf(p, "sta macid support: %08x\n",
+ priv->sta_macids_supported);
+ p += sprintf(p, "macid used: %08x\n", priv->macids_used);
+ p += sprintf(p, "\n");
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
+ (unsigned long) p - page);
+ free_page(page);
+
+ return ret;
+}
+
+static ssize_t mwl_debugfs_vif_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct mwl_priv *priv = (struct mwl_priv *)file->private_data;
+ unsigned long page = get_zeroed_page(GFP_KERNEL);
+ char *p = (char *)page;
+ struct mwl_vif *mwl_vif;
+ struct ieee80211_vif *vif;
+ char ssid[IEEE80211_MAX_SSID_LEN+1];
+ ssize_t ret;
+
+ if (!p)
+ return -ENOMEM;
+
+ p += sprintf(p, "\n");
+ spin_lock_bh(&priv->vif_lock);
+ list_for_each_entry(mwl_vif, &priv->vif_list, list) {
+ vif = container_of((char *)mwl_vif, struct ieee80211_vif,
+ drv_priv[0]);
+ p += sprintf(p, "macid: %d\n", mwl_vif->macid);
+ switch (vif->type) {
+ case NL80211_IFTYPE_AP:
+ p += sprintf(p, "type: ap\n");
+ memcpy(ssid, vif->bss_conf.ssid,
+ vif->bss_conf.ssid_len);
+ ssid[vif->bss_conf.ssid_len] = 0;
+ p += sprintf(p, "ssid: %s\n", ssid);
+ p += sprintf(p, "mac address: %pM\n", mwl_vif->bssid);
+ break;
+ case NL80211_IFTYPE_STATION:
+ p += sprintf(p, "type: sta\n");
+ p += sprintf(p, "mac address: %pM\n", mwl_vif->sta_mac);
+ break;
+ default:
+ p += sprintf(p, "type: unknown\n");
+ break;
+ }
+ p += sprintf(p, "hw_crypto_enabled: %s\n",
+ mwl_vif->is_hw_crypto_enabled ? "true" : "false");
+ p += sprintf(p, "key idx: %d\n", mwl_vif->keyidx);
+ p += sprintf(p, "IV: %08x%04x\n", mwl_vif->iv32, mwl_vif->iv16);
+ p += dump_data(p, mwl_vif->beacon_info.ie_wmm_ptr,
+ mwl_vif->beacon_info.ie_wmm_len, "WMM:");
+ p += dump_data(p, mwl_vif->beacon_info.ie_rsn_ptr,
+ mwl_vif->beacon_info.ie_rsn_len, "RSN:");
+ p += dump_data(p, mwl_vif->beacon_info.ie_rsn48_ptr,
+ mwl_vif->beacon_info.ie_rsn48_len, "RSN48:");
+ p += dump_data(p, mwl_vif->beacon_info.ie_ht_ptr,
+ mwl_vif->beacon_info.ie_ht_len, "HT:");
+ p += dump_data(p, mwl_vif->beacon_info.ie_vht_ptr,
+ mwl_vif->beacon_info.ie_vht_len, "VHT:");
+ p += sprintf(p, "\n");
+ }
+ spin_unlock_bh(&priv->vif_lock);
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
+ (unsigned long) p - page);
+ free_page(page);
+
+ return ret;
+}
+
+static ssize_t mwl_debugfs_sta_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct mwl_priv *priv = (struct mwl_priv *)file->private_data;
+ unsigned long page = get_zeroed_page(GFP_KERNEL);
+ char *p = (char *)page;
+ struct mwl_sta *sta_info;
+ struct ieee80211_sta *sta;
+ ssize_t ret;
+
+ if (!p)
+ return -ENOMEM;
+
+ p += sprintf(p, "\n");
+ spin_lock_bh(&priv->sta_lock);
+ list_for_each_entry(sta_info, &priv->sta_list, list) {
+ sta = container_of((char *)sta_info, struct ieee80211_sta,
+ drv_priv[0]);
+ p += sprintf(p, "mac address: %pM\n", sta->addr);
+ p += sprintf(p, "aid: %u\n", sta->aid);
+ p += sprintf(p, "ampdu: %s\n",
+ sta_info->is_ampdu_allowed ? "true" : "false");
+ p += sprintf(p, "amsdu: %s\n",
+ sta_info->is_amsdu_allowed ? "true" : "false");
+ if (sta_info->is_amsdu_allowed) {
+ p += sprintf(p, "amsdu cap: 0x%02x\n",
+ sta_info->amsdu_ctrl.cap);
+ }
+ p += sprintf(p, "IV: %08x%04x\n",
+ sta_info->iv32, sta_info->iv16);
+ p += sprintf(p, "HT (%ssupported) cap: 0x%04x\n", sta->ht_cap.ht_supported ? "" : "un", sta->ht_cap.cap);
+ p += sprintf(p, "VHT (%ssupported) cap: 0x%08x\n", sta->vht_cap.vht_supported ? "" : "un", sta->vht_cap.cap);
+ p += sprintf(p, "\n");
+ }
+ spin_unlock_bh(&priv->sta_lock);
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
+ (unsigned long) p - page);
+ free_page(page);
+
+ return ret;
+}
+
+static ssize_t mwl_debugfs_ampdu_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct mwl_priv *priv = (struct mwl_priv *)file->private_data;
+ unsigned long page = get_zeroed_page(GFP_KERNEL);
+ char *p = (char *)page;
+ struct mwl_ampdu_stream *stream;
+ int i;
+ ssize_t ret;
+
+ if (!p)
+ return -ENOMEM;
+
+ p += sprintf(p, "\n");
+ spin_lock_bh(&priv->stream_lock);
+ for (i = 0; i < SYSADPT_TX_AMPDU_QUEUES; i++) {
+ stream = &priv->ampdu[i];
+ p += sprintf(p, "stream: %d\n", i);
+ p += sprintf(p, "idx: %u\n", stream->idx);
+ p += sprintf(p, "state: %u\n", stream->state);
+ if (stream->sta) {
+ p += sprintf(p, "mac address: %pM\n", stream->sta->addr);
+ p += sprintf(p, "tid: %u\n", stream->tid);
+ }
+ }
+ spin_unlock_bh(&priv->stream_lock);
+ p += sprintf(p, "\n");
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
+ (unsigned long) p - page);
+ free_page(page);
+
+ return ret;
+}
+
+MWLWIFI_DEBUGFS_FILE_READ_OPS(info);
+MWLWIFI_DEBUGFS_FILE_READ_OPS(vif);
+MWLWIFI_DEBUGFS_FILE_READ_OPS(sta);
+MWLWIFI_DEBUGFS_FILE_READ_OPS(ampdu);
+
+void mwl_debugfs_init(struct ieee80211_hw *hw)
+{
+ struct mwl_priv *priv = hw->priv;
+
+ if (!priv->debugfs_phy)
+ priv->debugfs_phy = debugfs_create_dir("mwlwifi",
+ hw->wiphy->debugfsdir);
+
+ if (!priv->debugfs_phy)
+ return;
+
+ MWLWIFI_DEBUGFS_ADD_FILE(info);
+ MWLWIFI_DEBUGFS_ADD_FILE(vif);
+ MWLWIFI_DEBUGFS_ADD_FILE(sta);
+ MWLWIFI_DEBUGFS_ADD_FILE(ampdu);
+}
+
+void mwl_debugfs_remove(struct ieee80211_hw *hw)
+{
+ struct mwl_priv *priv = hw->priv;
+
+ debugfs_remove(priv->debugfs_phy);
+ priv->debugfs_phy = NULL;
+}
diff --git a/debugfs.h b/debugfs.h
new file mode 100644
index 0000000..dfc2a3c
--- /dev/null
+++ b/debugfs.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+/* Description: This file defines debug fs related functions. */
+
+#ifndef _debugfs_h_
+#define _debugfs_h_
+
+void mwl_debugfs_init(struct ieee80211_hw *hw);
+void mwl_debugfs_remove(struct ieee80211_hw *hw);
+
+#endif /* _debugfs_h_ */
diff --git a/dev.h b/dev.h
index c2c5a06..577b47c 100644
--- a/dev.h
+++ b/dev.h
@@ -19,6 +19,9 @@
#include <linux/bitops.h>
#include <net/mac80211.h>
+#define MWL_DRV_NAME KBUILD_MODNAME
+#define MWL_DRV_VERSION "10.3.0.3"
+
/* Map to 0x80000000 (Bus control) on BAR0 */
#define MACREG_REG_H2A_INTERRUPT_EVENTS 0x00000C18 /* (From host to ARM) */
#define MACREG_REG_H2A_INTERRUPT_CAUSE 0x00000C1C /* (From host to ARM) */
@@ -317,6 +320,10 @@ struct mwl_priv {
spinlock_t stream_lock; /* for ampdu stream */
struct mwl_ampdu_stream ampdu[SYSADPT_TX_AMPDU_QUEUES];
struct work_struct watchdog_ba_handle;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_phy;
+#endif
};
struct beacon_info {
diff --git a/main.c b/main.c
index 99b88b7..ae41c2d 100644
--- a/main.c
+++ b/main.c
@@ -20,11 +20,12 @@
#include "rx.h"
#include "mac80211.h"
#include "isr.h"
+#ifdef CONFIG_DEBUG_FS
+#include "debugfs.h"
+#endif
#define MWL_DESC "Marvell 802.11ac Wireless Network Driver"
#define MWL_DEV_NAME "Marvell 802.11ac Adapter"
-#define MWL_DRV_NAME KBUILD_MODNAME
-#define MWL_DRV_VERSION "10.3.0.3"
#define FILE_PATH_LEN 64
#define CMD_BUF_SIZE 0x4000
@@ -814,6 +815,10 @@ static int mwl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_wl_init;
}
+#ifdef CONFIG_DEBUG_FS
+ mwl_debugfs_init(hw);
+#endif
+
return rc;
err_wl_init:
@@ -842,6 +847,10 @@ static void mwl_remove(struct pci_dev *pdev)
if (!hw)
return;
+#ifdef CONFIG_DEBUG_FS
+ mwl_debugfs_init(hw);
+#endif
+
priv = hw->priv;
mwl_wl_deinit(priv);