From: Ivo van Doorn <ivdoorn@gmail.com>
To: "John W. Linville" <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org
Subject: [PATCH 2/28] rt2x00: Add debugfs support
Date: Wed, 28 Feb 2007 15:07:13 +0100 [thread overview]
Message-ID: <200702281507.13953.IvDoorn@gmail.com> (raw)
Add support for debugfs file creation.
This will allow the CSR, EEPROM and BBP registers
of each device to be read and written.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
diff --git a/drivers/net/wireless/mac80211/rt2x00/Kconfig b/drivers/net/wireless/mac80211/rt2x00/Kconfig
index 2e520ed..7206cb6 100644
--- a/drivers/net/wireless/mac80211/rt2x00/Kconfig
+++ b/drivers/net/wireless/mac80211/rt2x00/Kconfig
@@ -81,3 +81,11 @@ config RT73USB_DEBUG
depends on RT73USB
---help---
Enable debugging output.
+
+config RT2X00_DEBUGFS
+ tristate "Ralink debugfs support"
+ depends on RT2X00 && DEBUG_FS
+ ---help---
+ Enable creation of debugfs files for the rt2x00 drivers.
+ These debugfs files support both reading and writing of the
+ most important register types of the rt2x00 devices.
diff --git a/drivers/net/wireless/mac80211/rt2x00/Makefile b/drivers/net/wireless/mac80211/rt2x00/Makefile
index 8051b41..df706c7 100644
--- a/drivers/net/wireless/mac80211/rt2x00/Makefile
+++ b/drivers/net/wireless/mac80211/rt2x00/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_RT2500PCI) += rt2500pci.o
obj-$(CONFIG_RT61PCI) += rt61pci.o
obj-$(CONFIG_RT2500USB) += rt2500usb.o
obj-$(CONFIG_RT73USB) += rt73usb.o
+obj-$(CONFIG_RT2X00_DEBUGFS) += rt2x00debug.o
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt2400pci.c b/drivers/net/wireless/mac80211/rt2x00/rt2400pci.c
index 84a459e..df1e569 100644
--- a/drivers/net/wireless/mac80211/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/mac80211/rt2x00/rt2400pci.c
@@ -244,6 +244,80 @@ static inline void rt2x00_desc_write(struct data_desc *desc,
desc->word[word] = cpu_to_le32(value);
}
+#ifdef CONFIG_RT2X00_DEBUGFS
+#define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
+
+static void rt2400pci_read_csr(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_register_read(rt2x00dev, CSR_OFFSET(word), data);
+}
+
+static void rt2400pci_write_csr(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_register_write(rt2x00dev, CSR_OFFSET(word), *((u32*)data));
+}
+
+static void rt2400pci_read_eeprom(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_eeprom_read(rt2x00dev, word, (u16*)data);
+}
+
+static void rt2400pci_write_eeprom(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_eeprom_write(rt2x00dev, word, *(u16*)data);
+}
+
+static void rt2400pci_read_bbp(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_bbp_read(rt2x00dev, word, ((u8*)data));
+}
+
+static void rt2400pci_write_bbp(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_bbp_write(rt2x00dev, word, *((u8*)data));
+}
+
+static void rt2400pci_open_debugfs(struct rt2x00_dev *rt2x00dev)
+{
+ struct rt2x00debug *debug = &rt2x00dev->debug;
+
+ debug->intf_name = wiphy_name(rt2x00dev->hw->wiphy);
+ debug->owner = THIS_MODULE;
+ debug->mod_name = DRV_NAME;
+ debug->mod_version = DRV_VERSION;
+ debug->reg_csr.read = rt2400pci_read_csr;
+ debug->reg_csr.write = rt2400pci_write_csr;
+ debug->reg_csr.word_size = sizeof(u32);
+ debug->reg_csr.length = CSR_REG_SIZE;
+ debug->reg_eeprom.read = rt2400pci_read_eeprom;
+ debug->reg_eeprom.write = rt2400pci_write_eeprom;
+ debug->reg_eeprom.word_size = sizeof(u16);
+ debug->reg_eeprom.length = EEPROM_SIZE;
+ debug->reg_bbp.read = rt2400pci_read_bbp;
+ debug->reg_bbp.write = rt2400pci_write_bbp;
+ debug->reg_bbp.word_size = sizeof(u8);
+ debug->reg_bbp.length = BBP_SIZE;
+ debug->rt2x00dev = rt2x00dev;
+
+ if (rt2x00debug_register(debug))
+ ERROR("Failed to register debug handler.\n");
+}
+
+static void rt2400pci_close_debugfs(struct rt2x00_dev *rt2x00dev)
+{
+ rt2x00debug_deregister(&rt2x00dev->debug);
+}
+#else /* CONFIG_RT2X00_DEBUGFS */
+static inline void rt2400pci_open_debugfs(struct rt2x00_dev *rt2x00dev){}
+static inline void rt2400pci_close_debugfs(struct rt2x00_dev *rt2x00dev){}
+#endif /* CONFIG_RT2X00_DEBUGFS */
+
/*
* Configuration handlers.
*/
@@ -2656,6 +2730,11 @@ static int rt2400pci_init_hw(struct rt2x00_dev *rt2x00dev)
static void rt2400pci_free_dev(struct rt2x00_dev *rt2x00dev)
{
/*
+ * Close debugfs entry.
+ */
+ rt2400pci_close_debugfs(rt2x00dev);
+
+ /*
* Free workqueue.
*/
if (likely(rt2x00dev->workqueue)) {
@@ -2754,6 +2833,11 @@ static int rt2400pci_alloc_dev(struct pci_dev *pci_dev,
goto exit;
}
+ /*
+ * Open the debugfs entry.
+ */
+ rt2400pci_open_debugfs(rt2x00dev);
+
return 0;
exit:
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt2400pci.h b/drivers/net/wireless/mac80211/rt2x00/rt2400pci.h
index db0301a..ab0bc97 100644
--- a/drivers/net/wireless/mac80211/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/mac80211/rt2x00/rt2400pci.h
@@ -50,6 +50,7 @@
#define CSR_REG_SIZE 0x014c
#define EEPROM_BASE 0x0000
#define EEPROM_SIZE 0x0100
+#define BBP_SIZE 0x0020
/*
* Control/Status Registers(CSR).
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt2500pci.c b/drivers/net/wireless/mac80211/rt2x00/rt2500pci.c
index e7233c8..3594dc5 100644
--- a/drivers/net/wireless/mac80211/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/mac80211/rt2x00/rt2500pci.c
@@ -244,6 +244,80 @@ static inline void rt2x00_desc_write(struct data_desc *desc,
desc->word[word] = cpu_to_le32(value);
}
+#ifdef CONFIG_RT2X00_DEBUGFS
+#define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
+
+static void rt2500pci_read_csr(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_register_read(rt2x00dev, CSR_OFFSET(word), data);
+}
+
+static void rt2500pci_write_csr(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_register_write(rt2x00dev, CSR_OFFSET(word), *((u32*)data));
+}
+
+static void rt2500pci_read_eeprom(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_eeprom_read(rt2x00dev, word, (u16*)data);
+}
+
+static void rt2500pci_write_eeprom(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_eeprom_write(rt2x00dev, word, *(u16*)data);
+}
+
+static void rt2500pci_read_bbp(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_bbp_read(rt2x00dev, word, ((u8*)data));
+}
+
+static void rt2500pci_write_bbp(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_bbp_write(rt2x00dev, word, *((u8*)data));
+}
+
+static void rt2500pci_open_debugfs(struct rt2x00_dev *rt2x00dev)
+{
+ struct rt2x00debug *debug = &rt2x00dev->debug;
+
+ debug->intf_name = wiphy_name(rt2x00dev->hw->wiphy);
+ debug->owner = THIS_MODULE;
+ debug->mod_name = DRV_NAME;
+ debug->mod_version = DRV_VERSION;
+ debug->reg_csr.read = rt2500pci_read_csr;
+ debug->reg_csr.write = rt2500pci_write_csr;
+ debug->reg_csr.word_size = sizeof(u32);
+ debug->reg_csr.length = CSR_REG_SIZE;
+ debug->reg_eeprom.read = rt2500pci_read_eeprom;
+ debug->reg_eeprom.write = rt2500pci_write_eeprom;
+ debug->reg_eeprom.word_size = sizeof(u16);
+ debug->reg_eeprom.length = EEPROM_SIZE;
+ debug->reg_bbp.read = rt2500pci_read_bbp;
+ debug->reg_bbp.write = rt2500pci_write_bbp;
+ debug->reg_bbp.word_size = sizeof(u8);
+ debug->reg_bbp.length = BBP_SIZE;
+ debug->rt2x00dev = rt2x00dev;
+
+ if (rt2x00debug_register(debug))
+ ERROR("Failed to register debug handler.\n");
+}
+
+static void rt2500pci_close_debugfs(struct rt2x00_dev *rt2x00dev)
+{
+ rt2x00debug_deregister(&rt2x00dev->debug);
+}
+#else /* CONFIG_RT2X00_DEBUGFS */
+static inline void rt2500pci_open_debugfs(struct rt2x00_dev *rt2x00dev){}
+static inline void rt2500pci_close_debugfs(struct rt2x00_dev *rt2x00dev){}
+#endif /* CONFIG_RT2X00_DEBUGFS */
+
/*
* Configuration handlers.
*/
@@ -2967,6 +3041,11 @@ static int rt2500pci_init_hw(struct rt2x00_dev *rt2x00dev)
static void rt2500pci_free_dev(struct rt2x00_dev *rt2x00dev)
{
/*
+ * Close debugfs entry.
+ */
+ rt2500pci_close_debugfs(rt2x00dev);
+
+ /*
* Free workqueue.
*/
if (likely(rt2x00dev->workqueue)) {
@@ -3066,6 +3145,11 @@ static int rt2500pci_alloc_dev(struct pci_dev *pci_dev,
goto exit;
}
+ /*
+ * Open the debugfs entry.
+ */
+ rt2500pci_open_debugfs(rt2x00dev);
+
return 0;
exit:
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt2500pci.h b/drivers/net/wireless/mac80211/rt2x00/rt2500pci.h
index 4dd7c10..fc4a865 100644
--- a/drivers/net/wireless/mac80211/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/mac80211/rt2x00/rt2500pci.h
@@ -61,6 +61,7 @@
#define CSR_REG_SIZE 0x0174
#define EEPROM_BASE 0x0000
#define EEPROM_SIZE 0x0200
+#define BBP_SIZE 0x0040
/*
* Control/Status Registers(CSR).
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt2500usb.c b/drivers/net/wireless/mac80211/rt2x00/rt2500usb.c
index c5e0773..0a0de18 100644
--- a/drivers/net/wireless/mac80211/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/mac80211/rt2x00/rt2500usb.c
@@ -298,6 +298,80 @@ static inline void rt2x00_desc_write(struct data_desc *desc,
desc->word[word] = cpu_to_le32(value);
}
+#ifdef CONFIG_RT2X00_DEBUGFS
+#define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u16)) )
+
+static void rt2500usb_read_csr(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_register_read(rt2x00dev, CSR_OFFSET(word), data);
+}
+
+static void rt2500usb_write_csr(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_register_write(rt2x00dev, CSR_OFFSET(word), *((u16*)data));
+}
+
+static void rt2500usb_read_eeprom(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_eeprom_read(rt2x00dev, word, (u16*)data);
+}
+
+static void rt2500usb_write_eeprom(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_eeprom_write(rt2x00dev, word, *(u16*)data);
+}
+
+static void rt2500usb_read_bbp(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_bbp_read(rt2x00dev, word, ((u8*)data));
+}
+
+static void rt2500usb_write_bbp(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_bbp_write(rt2x00dev, word, *((u8*)data));
+}
+
+static void rt2500usb_open_debugfs(struct rt2x00_dev *rt2x00dev)
+{
+ struct rt2x00debug *debug = &rt2x00dev->debug;
+
+ debug->intf_name = wiphy_name(rt2x00dev->hw->wiphy);
+ debug->owner = THIS_MODULE;
+ debug->mod_name = DRV_NAME;
+ debug->mod_version = DRV_VERSION;
+ debug->reg_csr.read = rt2500usb_read_csr;
+ debug->reg_csr.write = rt2500usb_write_csr;
+ debug->reg_csr.word_size = sizeof(u16);
+ debug->reg_csr.length = CSR_REG_SIZE;
+ debug->reg_eeprom.read = rt2500usb_read_eeprom;
+ debug->reg_eeprom.write = rt2500usb_write_eeprom;
+ debug->reg_eeprom.word_size = sizeof(u16);
+ debug->reg_eeprom.length = EEPROM_SIZE;
+ debug->reg_bbp.read = rt2500usb_read_bbp;
+ debug->reg_bbp.write = rt2500usb_write_bbp;
+ debug->reg_bbp.word_size = sizeof(u8);
+ debug->reg_bbp.length = BBP_SIZE;
+ debug->rt2x00dev = rt2x00dev;
+
+ if (rt2x00debug_register(debug))
+ ERROR("Failed to register debug handler.\n");
+}
+
+static void rt2500usb_close_debugfs(struct rt2x00_dev *rt2x00dev)
+{
+ rt2x00debug_deregister(&rt2x00dev->debug);
+}
+#else /* CONFIG_RT2X00_DEBUGFS */
+static inline void rt2500usb_open_debugfs(struct rt2x00_dev *rt2x00dev){}
+static inline void rt2500usb_close_debugfs(struct rt2x00_dev *rt2x00dev){}
+#endif /* CONFIG_RT2X00_DEBUGFS */
+
/*
* Configuration handlers.
*/
@@ -2810,6 +2884,11 @@ static int rt2500usb_init_hw(struct rt2x00_dev *rt2x00dev)
static void rt2500usb_free_dev(struct rt2x00_dev *rt2x00dev)
{
/*
+ * Close debugfs entry.
+ */
+ rt2500usb_close_debugfs(rt2x00dev);
+
+ /*
* Free workqueue.
*/
if (likely(rt2x00dev->workqueue)) {
@@ -2890,6 +2969,11 @@ static int rt2500usb_alloc_dev(struct usb_interface *usb_intf,
goto exit;
}
+ /*
+ * Open the debugfs entry.
+ */
+ rt2500usb_open_debugfs(rt2x00dev);
+
return 0;
exit:
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt2500usb.h b/drivers/net/wireless/mac80211/rt2x00/rt2500usb.h
index 4fb8f83..7f97799 100644
--- a/drivers/net/wireless/mac80211/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/mac80211/rt2x00/rt2500usb.h
@@ -54,6 +54,7 @@
#define CSR_REG_SIZE 0x0100
#define EEPROM_BASE 0x0000
#define EEPROM_SIZE 0x006a
+#define BBP_SIZE 0x0060
/*
* Control/Status Registers(CSR).
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt2x00.h b/drivers/net/wireless/mac80211/rt2x00/rt2x00.h
index 15fb225..e505032 100644
--- a/drivers/net/wireless/mac80211/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/mac80211/rt2x00/rt2x00.h
@@ -28,6 +28,11 @@
#ifndef RT2X00_H
#define RT2X00_H
+#if defined( CONFIG_RT2X00_DEBUGFS) || defined( CONFIG_RT2X00_DEBUGFS_MODULE)
+#define CONFIG_RT2X00_DEBUGFS
+#include "rt2x00debug.h"
+#endif /* CONFIG_RT2X00_DEBUGFS */
+
/*
* Module information.
*/
@@ -953,6 +958,13 @@ struct rt2x00_dev {
void __iomem *csr_addr;
/*
+ * If enabled, the structure for the debugfs files.
+ */
+#ifdef CONFIG_RT2X00_DEBUGFS
+ struct rt2x00debug debug;
+#endif /* CONFIG_RT2X00_DEBUGFS */
+
+ /*
* Queue for deferred work.
*/
struct workqueue_struct *workqueue;
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt61pci.c b/drivers/net/wireless/mac80211/rt2x00/rt61pci.c
index 6775a48..757cd9e 100644
--- a/drivers/net/wireless/mac80211/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/mac80211/rt2x00/rt61pci.c
@@ -276,6 +276,80 @@ static inline void rt2x00_desc_write(struct data_desc *desc,
desc->word[word] = cpu_to_le32(value);
}
+#ifdef CONFIG_RT2X00_DEBUGFS
+#define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
+
+static void rt61pci_read_csr(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_register_read(rt2x00dev, CSR_OFFSET(word), data);
+}
+
+static void rt61pci_write_csr(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_register_write(rt2x00dev, CSR_OFFSET(word), *((u32*)data));
+}
+
+static void rt61pci_read_eeprom(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_eeprom_read(rt2x00dev, word, (u16*)data);
+}
+
+static void rt61pci_write_eeprom(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_eeprom_write(rt2x00dev, word, *(u16*)data);
+}
+
+static void rt61pci_read_bbp(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_bbp_read(rt2x00dev, word, ((u8*)data));
+}
+
+static void rt61pci_write_bbp(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_bbp_write(rt2x00dev, word, *((u8*)data));
+}
+
+static void rt61pci_open_debugfs(struct rt2x00_dev *rt2x00dev)
+{
+ struct rt2x00debug *debug = &rt2x00dev->debug;
+
+ debug->intf_name = wiphy_name(rt2x00dev->hw->wiphy);
+ debug->owner = THIS_MODULE;
+ debug->mod_name = DRV_NAME;
+ debug->mod_version = DRV_VERSION;
+ debug->reg_csr.read = rt61pci_read_csr;
+ debug->reg_csr.write = rt61pci_write_csr;
+ debug->reg_csr.word_size = sizeof(u32);
+ debug->reg_csr.length = CSR_REG_SIZE;
+ debug->reg_eeprom.read = rt61pci_read_eeprom;
+ debug->reg_eeprom.write = rt61pci_write_eeprom;
+ debug->reg_eeprom.word_size = sizeof(u16);
+ debug->reg_eeprom.length = EEPROM_SIZE;
+ debug->reg_bbp.read = rt61pci_read_bbp;
+ debug->reg_bbp.write = rt61pci_write_bbp;
+ debug->reg_bbp.word_size = sizeof(u8);
+ debug->reg_bbp.length = BBP_SIZE;
+ debug->rt2x00dev = rt2x00dev;
+
+ if (rt2x00debug_register(debug))
+ ERROR("Failed to register debug handler.\n");
+}
+
+static void rt61pci_close_debugfs(struct rt2x00_dev *rt2x00dev)
+{
+ rt2x00debug_deregister(&rt2x00dev->debug);
+}
+#else /* CONFIG_RT2X00_DEBUGFS */
+static inline void rt61pci_open_debugfs(struct rt2x00_dev *rt2x00dev){}
+static inline void rt61pci_close_debugfs(struct rt2x00_dev *rt2x00dev){}
+#endif /* CONFIG_RT2X00_DEBUGFS */
+
/*
* Configuration handlers.
*/
@@ -3486,6 +3560,11 @@ static int rt61pci_init_hw(struct rt2x00_dev *rt2x00dev)
static void rt61pci_free_dev(struct rt2x00_dev *rt2x00dev)
{
/*
+ * Close debugfs entry.
+ */
+ rt61pci_close_debugfs(rt2x00dev);
+
+ /*
* Free workqueue.
*/
if (likely(rt2x00dev->workqueue)) {
@@ -3590,6 +3669,11 @@ static int rt61pci_alloc_dev(struct pci_dev *pci_dev,
goto exit;
}
+ /*
+ * Open the debugfs entry.
+ */
+ rt61pci_open_debugfs(rt2x00dev);
+
return 0;
exit:
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt61pci.h b/drivers/net/wireless/mac80211/rt2x00/rt61pci.h
index 9f1732f..6db5e9c 100644
--- a/drivers/net/wireless/mac80211/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/mac80211/rt2x00/rt61pci.h
@@ -54,6 +54,7 @@
#define CSR_REG_SIZE 0x04b0
#define EEPROM_BASE 0x0000
#define EEPROM_SIZE 0x0100
+#define BBP_SIZE 0x0080
/*
* PCI registers.
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt73usb.c b/drivers/net/wireless/mac80211/rt2x00/rt73usb.c
index fb56954..7311764 100644
--- a/drivers/net/wireless/mac80211/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/mac80211/rt2x00/rt73usb.c
@@ -283,6 +283,80 @@ static inline void rt2x00_desc_write(struct data_desc *desc,
desc->word[word] = cpu_to_le32(value);
}
+#ifdef CONFIG_RT2X00_DEBUGFS
+#define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
+
+static void rt73usb_read_csr(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_register_read(rt2x00dev, CSR_OFFSET(word), data);
+}
+
+static void rt73usb_write_csr(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_register_write(rt2x00dev, CSR_OFFSET(word), *((u32*)data));
+}
+
+static void rt73usb_read_eeprom(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_eeprom_read(rt2x00dev, word, (u16*)data);
+}
+
+static void rt73usb_write_eeprom(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_eeprom_write(rt2x00dev, word, *(u16*)data);
+}
+
+static void rt73usb_read_bbp(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_bbp_read(rt2x00dev, word, ((u8*)data));
+}
+
+static void rt73usb_write_bbp(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data)
+{
+ rt2x00_bbp_write(rt2x00dev, word, *((u8*)data));
+}
+
+static void rt73usb_open_debugfs(struct rt2x00_dev *rt2x00dev)
+{
+ struct rt2x00debug *debug = &rt2x00dev->debug;
+
+ debug->intf_name = wiphy_name(rt2x00dev->hw->wiphy);
+ debug->owner = THIS_MODULE;
+ debug->mod_name = DRV_NAME;
+ debug->mod_version = DRV_VERSION;
+ debug->reg_csr.read = rt73usb_read_csr;
+ debug->reg_csr.write = rt73usb_write_csr;
+ debug->reg_csr.word_size = sizeof(u32);
+ debug->reg_csr.length = CSR_REG_SIZE;
+ debug->reg_eeprom.read = rt73usb_read_eeprom;
+ debug->reg_eeprom.write = rt73usb_write_eeprom;
+ debug->reg_eeprom.word_size = sizeof(u16);
+ debug->reg_eeprom.length = EEPROM_SIZE;
+ debug->reg_bbp.read = rt73usb_read_bbp;
+ debug->reg_bbp.write = rt73usb_write_bbp;
+ debug->reg_bbp.word_size = sizeof(u8);
+ debug->reg_bbp.length = BBP_SIZE;
+ debug->rt2x00dev = rt2x00dev;
+
+ if (rt2x00debug_register(debug))
+ ERROR("Failed to register debug handler.\n");
+}
+
+static void rt73usb_close_debugfs(struct rt2x00_dev *rt2x00dev)
+{
+ rt2x00debug_deregister(&rt2x00dev->debug);
+}
+#else /* CONFIG_RT2X00_DEBUGFS */
+static inline void rt73usb_open_debugfs(struct rt2x00_dev *rt2x00dev){}
+static inline void rt73usb_close_debugfs(struct rt2x00_dev *rt2x00dev){}
+#endif /* CONFIG_RT2X00_DEBUGFS */
+
/*
* Configuration handlers.
*/
@@ -3142,6 +3216,11 @@ static int rt73usb_init_hw(struct rt2x00_dev *rt2x00dev)
static void rt73usb_free_dev(struct rt2x00_dev *rt2x00dev)
{
/*
+ * Close debugfs entry.
+ */
+ rt73usb_close_debugfs(rt2x00dev);
+
+ /*
* Free workqueue.
*/
if (likely(rt2x00dev->workqueue)) {
@@ -3227,6 +3306,11 @@ static int rt73usb_alloc_dev(struct usb_interface *usb_intf,
goto exit;
}
+ /*
+ * Open the debugfs entry.
+ */
+ rt73usb_open_debugfs(rt2x00dev);
+
return 0;
exit:
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt73usb.h b/drivers/net/wireless/mac80211/rt2x00/rt73usb.h
index 365ad60..4f7d338 100644
--- a/drivers/net/wireless/mac80211/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/mac80211/rt2x00/rt73usb.h
@@ -52,6 +52,7 @@
#define CSR_REG_SIZE 0x04b0
#define EEPROM_BASE 0x0000
#define EEPROM_SIZE 0x0100
+#define BBP_SIZE 0x0080
/*
* USB registers.
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt2x00debug.c b/drivers/net/wireless/mac80211/rt2x00/rt2x00debug.c
new file mode 100644
index 0000000..e037421
--- /dev/null
+++ b/drivers/net/wireless/mac80211/rt2x00/rt2x00debug.c
@@ -0,0 +1,406 @@
+/*
+ Copyright (C) 2004 - 2007 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ Module: rt2x00debug
+ Abstract: rt2x00debug specific routines.
+ Supported chipsets: RT2460, RT2560, RT2570,
+ rt2561, rt2561s, rt2661 & rt2573.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/debugfs.h>
+
+#include <asm/div64.h>
+#include <asm/uaccess.h>
+
+#include "rt2x00debug.h"
+
+#define PRINT_REG8_STR ( "0x%.2x\n" )
+#define PRINT_REG16_STR ( "0x%.4x\n" )
+#define PRINT_REG32_STR ( "0x%.8x\n" )
+#define PRINT_REG_LEN_MAX ( 16 )
+#define PRINT_LINE_LEN_MAX ( 32 )
+
+/*
+ * If this field is enabled, debugfs has been disabled in the kernel,
+ * and we should not return errors to the user about the failed registration.
+ */
+static unsigned int rt2x00_debugfs_disabled = 0;
+
+/*
+ * Main rt2x00 entry, this will create the "rt2x00" folder at the root
+ * of the debugfs folder.
+ */
+static struct dentry *rt2x00_entry;
+
+struct rt2x00debug_intf {
+ /*
+ * Reference to the rt2x00debug structure
+ * which can be used to communicate with
+ * the registers.
+ */
+ struct rt2x00debug *debug;
+
+ /*
+ * Debugfs entries for:
+ * - interface folder
+ * - driver file
+ * - chipset file
+ * - register offset/value files
+ * - eeprom offset/value files
+ * - bbp offset/value files
+ */
+ struct dentry *intf_entry;
+ struct dentry *driver_entry;
+ struct dentry *chipset_entry;
+ struct dentry *csr_off_entry;
+ struct dentry *csr_val_entry;
+ struct dentry *eeprom_off_entry;
+ struct dentry *eeprom_val_entry;
+ struct dentry *bbp_off_entry;
+ struct dentry *bbp_val_entry;
+
+ /*
+ * Driver and chipset files will use a data buffer
+ * that has been created in advance. This will simplify
+ * the code since we can use the debugfs functions.
+ */
+ struct debugfs_blob_wrapper driver_blob;
+ struct debugfs_blob_wrapper chipset_blob;
+
+ /*
+ * Requested offset for each register type.
+ */
+ unsigned int offset_csr;
+ unsigned int offset_eeprom;
+ unsigned int offset_bbp;
+};
+
+static int rt2x00debug_file_open(struct inode *inode, struct file *file)
+{
+ struct rt2x00debug_intf *intf;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+ file->private_data = inode->i_private;
+#else
+ file->private_data = inode->u.generic_ip;
+#endif
+
+ intf = file->private_data;
+
+ if (!try_module_get(intf->debug->owner))
+ return -EBUSY;
+
+ return 0;
+}
+
+static int rt2x00debug_file_release(struct inode *inode, struct file *file)
+{
+ struct rt2x00debug_intf *intf = file->private_data;
+
+ module_put(intf->debug->owner);
+
+ return 0;
+}
+
+static ssize_t rt2x00debug_file_read(void *device, char __user *buf,
+ loff_t *offset, unsigned int word, struct rt2x00debug_reg *reg)
+{
+ unsigned long value;
+ unsigned int size;
+ char *line;
+
+ if (*offset)
+ return 0;
+
+ line = kzalloc(PRINT_REG_LEN_MAX, GFP_KERNEL);
+ if (!line)
+ return -ENOMEM;
+
+ reg->read(device, word, &value);
+
+ if (reg->word_size == sizeof(u8))
+ size = sprintf(line, PRINT_REG8_STR, (u8)value);
+ else if (reg->word_size == sizeof(u16))
+ size = sprintf(line, PRINT_REG16_STR, (u16)value);
+ else
+ size = sprintf(line, PRINT_REG32_STR, (u32)value);
+
+ if (copy_to_user(buf, line, size))
+ goto exit;
+
+ kfree(line);
+
+ *offset += size;
+ return size;
+
+exit:
+ kfree(line);
+
+ return -EFAULT;
+}
+
+static ssize_t rt2x00debug_file_write(void *device, const char __user *buf,
+ loff_t *offset, unsigned int word, unsigned int length,
+ struct rt2x00debug_reg *reg)
+{
+ unsigned long value;
+ int size;
+ char *line;
+
+ line = kzalloc(length, GFP_KERNEL);
+ if (!line)
+ return -ENOMEM;
+
+ if (copy_from_user(line, buf, length))
+ goto exit;
+
+ size = strlen(line);
+ value = simple_strtoul(line, NULL, 0);
+
+ reg->write(device, word, &value);
+
+ kfree(line);
+
+ *offset += size;
+ return size;
+
+exit:
+ kfree(line);
+
+ return -EFAULT;
+}
+
+#define RT2X00DEBUGFS_OPS_READ(__name) \
+ static ssize_t rt2x00debug_read_##__name(struct file *file, \
+ char __user *buf, size_t length, loff_t *offset) \
+ { \
+ struct rt2x00debug_intf *intf = file->private_data; \
+ struct rt2x00debug *debug = intf->debug; \
+ struct rt2x00debug_reg *reg = &debug->reg_##__name; \
+ \
+ if (intf->offset_##__name > reg->length) \
+ return -EINVAL; \
+ \
+ return rt2x00debug_file_read(debug->rt2x00dev, buf, \
+ offset, intf->offset_##__name, reg); \
+ }
+
+RT2X00DEBUGFS_OPS_READ(csr);
+RT2X00DEBUGFS_OPS_READ(eeprom);
+RT2X00DEBUGFS_OPS_READ(bbp);
+
+#define RT2X00DEBUGFS_OPS_WRITE(__name) \
+ static ssize_t rt2x00debug_write_##__name(struct file *file, \
+ const char __user *buf, size_t length, loff_t *offset) \
+ { \
+ struct rt2x00debug_intf *intf = file->private_data; \
+ struct rt2x00debug *debug = intf->debug; \
+ struct rt2x00debug_reg *reg = &debug->reg_##__name; \
+ \
+ if (intf->offset_##__name > reg->length) \
+ return -EINVAL; \
+ \
+ return rt2x00debug_file_write(debug->rt2x00dev, buf, \
+ offset, intf->offset_##__name, length, reg); \
+ }
+
+RT2X00DEBUGFS_OPS_WRITE(csr);
+RT2X00DEBUGFS_OPS_WRITE(eeprom);
+RT2X00DEBUGFS_OPS_WRITE(bbp);
+
+#define RT2X00DEBUGFS_OPS(__name) \
+ static const struct file_operations rt2x00debug_fop_##__name = {\
+ .owner = THIS_MODULE, \
+ .read = rt2x00debug_read_##__name, \
+ .write = rt2x00debug_write_##__name, \
+ .open = rt2x00debug_file_open, \
+ .release = rt2x00debug_file_release, \
+ };
+
+RT2X00DEBUGFS_OPS(csr);
+RT2X00DEBUGFS_OPS(eeprom);
+RT2X00DEBUGFS_OPS(bbp);
+
+static struct dentry *rt2x00debug_create_file_driver(const char *name,
+ struct rt2x00debug_intf *intf, struct debugfs_blob_wrapper *blob)
+{
+ struct rt2x00debug *debug = intf->debug;
+ char *data;
+
+ data = kzalloc(3 * PRINT_LINE_LEN_MAX, GFP_KERNEL);
+ if (!data)
+ return NULL;
+
+ blob->data = data;
+ data += sprintf(data, "driver: %s\n", debug->mod_name);
+ data += sprintf(data, "version: %s\n", debug->mod_version);
+ data += sprintf(data, "compiled: %s %s\n", __DATE__, __TIME__);
+ blob->size = strlen(blob->data);
+
+ return debugfs_create_blob(name, S_IRUGO, intf->intf_entry, blob);
+}
+
+static struct dentry *rt2x00debug_create_file_chipset(const char *name,
+ struct rt2x00debug_intf *intf, struct debugfs_blob_wrapper *blob)
+{
+ struct rt2x00debug *debug = intf->debug;
+ char *data;
+
+ data = kzalloc(3 * PRINT_LINE_LEN_MAX, GFP_KERNEL);
+ if (!data)
+ return NULL;
+
+ blob->data = data;
+ data += sprintf(data, "csr length: %d\n", debug->reg_csr.length);
+ data += sprintf(data, "eeprom length: %d\n", debug->reg_eeprom.length);
+ data += sprintf(data, "bbp length: %d\n", debug->reg_bbp.length);
+ blob->size = strlen(blob->data);
+
+ return debugfs_create_blob(name, S_IRUGO, intf->intf_entry, blob);
+}
+
+int rt2x00debug_register(struct rt2x00debug *debug)
+{
+ struct rt2x00debug_intf *intf;
+
+ if (rt2x00_debugfs_disabled)
+ return 0;
+
+ intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL);
+ if (!intf)
+ return -ENOMEM;
+
+ intf->debug = debug;
+ debug->priv = intf;
+
+ intf->intf_entry = debugfs_create_dir(debug->intf_name, rt2x00_entry);
+ if (IS_ERR(intf->intf_entry))
+ goto exit;
+
+ intf->driver_entry = rt2x00debug_create_file_driver("driver",
+ intf, &intf->driver_blob);
+ if (IS_ERR(intf->driver_entry))
+ goto exit;
+
+ intf->chipset_entry = rt2x00debug_create_file_chipset("chipset",
+ intf, &intf->chipset_blob);
+ if (IS_ERR(intf->chipset_entry))
+ goto exit;
+
+ intf->csr_off_entry = debugfs_create_u32("csr_offset",
+ S_IRUGO | S_IWUSR, intf->intf_entry,
+ &intf->offset_csr);
+ if (IS_ERR(intf->csr_off_entry))
+ goto exit;
+
+ intf->csr_val_entry = debugfs_create_file("csr_value",
+ S_IRUGO | S_IWUSR, intf->intf_entry, intf,
+ &rt2x00debug_fop_csr);
+ if (IS_ERR(intf->csr_val_entry))
+ goto exit;
+
+ intf->eeprom_off_entry = debugfs_create_u32("eeprom_offset",
+ S_IRUGO | S_IWUSR, intf->intf_entry,
+ &intf->offset_eeprom);
+ if (IS_ERR(intf->eeprom_off_entry))
+ goto exit;
+
+ intf->eeprom_val_entry = debugfs_create_file("eeprom_value",
+ S_IRUGO | S_IWUSR, intf->intf_entry, intf,
+ &rt2x00debug_fop_eeprom);
+ if (IS_ERR(intf->eeprom_val_entry))
+ goto exit;
+
+ intf->bbp_off_entry = debugfs_create_u32("bbp_offset",
+ S_IRUGO | S_IWUSR, intf->intf_entry,
+ &intf->offset_bbp);
+ if (IS_ERR(intf->bbp_off_entry))
+ goto exit;
+
+ intf->bbp_val_entry = debugfs_create_file("bbp_value",
+ S_IRUGO | S_IWUSR, intf->intf_entry, intf,
+ &rt2x00debug_fop_bbp);
+ if (IS_ERR(intf->bbp_val_entry))
+ goto exit;
+
+ return 0;
+
+exit:
+ rt2x00debug_deregister(debug);
+
+ return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(rt2x00debug_register);
+
+void rt2x00debug_deregister(struct rt2x00debug *debug)
+{
+ struct rt2x00debug_intf *intf = debug->priv;
+
+ if (rt2x00_debugfs_disabled || !intf)
+ return;
+
+ debugfs_remove(intf->bbp_val_entry);
+ debugfs_remove(intf->bbp_off_entry);
+ debugfs_remove(intf->eeprom_val_entry);
+ debugfs_remove(intf->eeprom_off_entry);
+ debugfs_remove(intf->csr_val_entry);
+ debugfs_remove(intf->csr_off_entry);
+ debugfs_remove(intf->chipset_entry);
+ debugfs_remove(intf->driver_entry);
+ debugfs_remove(intf->intf_entry);
+ kfree(intf->chipset_blob.data);
+ kfree(intf->driver_blob.data);
+ kfree(intf);
+}
+EXPORT_SYMBOL_GPL(rt2x00debug_deregister);
+
+/*
+ * rt2x00debug module information.
+ */
+MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
+MODULE_VERSION("CVS");
+MODULE_DESCRIPTION("Debugfs support for rt2x00 drivers.");
+MODULE_LICENSE("GPL");
+
+static int __init rt2x00debug_init(void)
+{
+ rt2x00_entry = debugfs_create_dir("rt2x00", NULL);
+ if (IS_ERR(rt2x00_entry)) {
+ rt2x00_debugfs_disabled = 1;
+ if (PTR_ERR(rt2x00_entry) != -ENODEV)
+ return PTR_ERR(rt2x00_entry);
+ }
+
+ return 0;
+}
+
+static void __exit rt2x00debug_exit(void)
+{
+ if (!rt2x00_debugfs_disabled)
+ debugfs_remove(rt2x00_entry);
+}
+
+module_init(rt2x00debug_init);
+module_exit(rt2x00debug_exit);
diff --git a/drivers/net/wireless/mac80211/rt2x00/rt2x00debug.h b/drivers/net/wireless/mac80211/rt2x00/rt2x00debug.h
new file mode 100644
index 0000000..4527d0a
--- /dev/null
+++ b/drivers/net/wireless/mac80211/rt2x00/rt2x00debug.h
@@ -0,0 +1,84 @@
+/*
+ Copyright (C) 2004 - 2007 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ Module: rt2x00debug
+ Abstract: Data structures for the rt2x00debug module.
+ Supported chipsets: RT2460, RT2560, RT2570,
+ rt2561, rt2561s, rt2661 & rt2573.
+ */
+
+#ifndef RT2X00DEBUG_H
+#define RT2X00DEBUG_H
+
+struct rt2x00_dev;
+
+typedef void (debug_access_t)(struct rt2x00_dev *rt2x00dev,
+ const unsigned long word, void *data);
+
+struct rt2x00debug_reg {
+ debug_access_t *read;
+ debug_access_t *write;
+
+ unsigned int word_size;
+ unsigned int length;
+};
+
+struct rt2x00debug {
+ /*
+ * Name of the interface.
+ */
+ char intf_name[16];
+
+ /*
+ * Reference to the modules structure.
+ */
+ struct module *owner;
+
+ /*
+ * Driver module information
+ */
+ char *mod_name;
+ char *mod_version;
+
+ /*
+ * Register access information.
+ */
+ struct rt2x00debug_reg reg_csr;
+ struct rt2x00debug_reg reg_eeprom;
+ struct rt2x00debug_reg reg_bbp;
+
+ /*
+ * Pointer to driver structure where
+ * this debugfs entry belongs to.
+ */
+ struct rt2x00_dev *rt2x00dev;
+
+ /*
+ * Pointer to rt2x00debug private data,
+ * individual driver should not touch this.
+ */
+ void *priv;
+};
+
+extern int rt2x00debug_register(struct rt2x00debug *debug);
+extern void rt2x00debug_deregister(struct rt2x00debug *debug);
+
+#endif /* RT2X00DEBUG_H */
next reply other threads:[~2007-02-28 14:07 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-28 14:07 Ivo van Doorn [this message]
2007-02-28 16:16 ` [PATCH 2/28] rt2x00: Add debugfs support Johannes Berg
2007-02-28 16:26 ` Ivo van Doorn
2007-02-28 16:20 ` Johannes Berg
2007-02-28 16:32 ` Ivo van Doorn
2007-02-28 16:37 ` Johannes Berg
2007-02-28 16:52 ` Ivo van Doorn
2007-02-28 16:54 ` Johannes Berg
2007-02-28 17:09 ` Ivo van Doorn
2007-02-28 17:21 ` Robin Cornelius
2007-02-28 17:30 ` Johannes Berg
2007-02-28 20:02 ` Johannes Berg
2007-02-28 20:09 ` Johannes Berg
2007-02-28 17:16 ` Ivo van Doorn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200702281507.13953.IvDoorn@gmail.com \
--to=ivdoorn@gmail.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).