From 7ac2905511063376ef59baae0e570bfebeea8004 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Thu, 1 Sep 2011 21:51:39 +0000 Subject: [PATCH] stmmac: export DMA TX/RX rings via debugfs (v3) This patch adds the following debugFs entry to dump the RX/TX DMA rings: /sys/kernel/debug/stmmaceth/descriptors_status This is an example: ======================= RX descriptor ring ======================= [0] DES0=0x85ee0320 DES1=0x1fff1fff BUF1=0x5fae2022 BUF2=0x0 [1] DES0=0x85ee0320 DES1=0x1fff1fff BUF1=0x5fae0022 BUF2=0x0 [2] DES0=0x81460320 DES1=0x1fff1fff BUF1=0x5f9dd022 BUF2=0x0 Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/Kconfig | 7 ++ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 105 ++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index cda61e37c35..ae7f56312f0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -11,6 +11,13 @@ config STMMAC_ETH if STMMAC_ETH +config STMMAC_DEBUG_FS + bool "Enable monitoring via sysFS " + default n + depends on STMMAC_ETH && DEBUG_FS + -- help + The stmmac entry in /sys reports DMA TX/RX rings. + config STMMAC_DA bool "STMMAC DMA arbitration scheme" default n diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index c28b90d3500..caaad7b1462 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -48,6 +48,10 @@ #include #include #include "stmmac.h" +#ifdef CONFIG_STMMAC_DEBUG_FS +#include +#include +#endif #define STMMAC_RESOURCE_NAME "stmmaceth" @@ -1425,6 +1429,96 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return ret; } +#ifdef CONFIG_STMMAC_DEBUG_FS +static struct dentry *stmmac_fs_dir; +static struct dentry *stmmac_rings_status; + +static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v) +{ + struct tmp_s { + u64 a; + unsigned int b; + unsigned int c; + }; + int i; + struct net_device *dev = seq->private; + struct stmmac_priv *priv = netdev_priv(dev); + + seq_printf(seq, "=======================\n"); + seq_printf(seq, " RX descriptor ring\n"); + seq_printf(seq, "=======================\n"); + + for (i = 0; i < priv->dma_rx_size; i++) { + struct tmp_s *x = (struct tmp_s *)(priv->dma_rx + i); + seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", + i, (unsigned int)(x->a), + (unsigned int)((x->a) >> 32), x->b, x->c); + seq_printf(seq, "\n"); + } + + seq_printf(seq, "\n"); + seq_printf(seq, "=======================\n"); + seq_printf(seq, " TX descriptor ring\n"); + seq_printf(seq, "=======================\n"); + + for (i = 0; i < priv->dma_tx_size; i++) { + struct tmp_s *x = (struct tmp_s *)(priv->dma_tx + i); + seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", + i, (unsigned int)(x->a), + (unsigned int)((x->a) >> 32), x->b, x->c); + seq_printf(seq, "\n"); + } + + return 0; +} + +static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file) +{ + return single_open(file, stmmac_sysfs_ring_read, inode->i_private); +} + +static const struct file_operations stmmac_rings_status_fops = { + .owner = THIS_MODULE, + .open = stmmac_sysfs_ring_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int stmmac_init_fs(struct net_device *dev) +{ + /* Create debugfs entries */ + stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); + + if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { + pr_err("ERROR %s, debugfs create directory failed\n", + STMMAC_RESOURCE_NAME); + + return -ENOMEM; + } + + /* Entry to report DMA RX/TX rings */ + stmmac_rings_status = debugfs_create_file("descriptors_status", + S_IRUGO, stmmac_fs_dir, dev, + &stmmac_rings_status_fops); + + if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { + pr_info("ERROR creating stmmac ring debugfs file\n"); + debugfs_remove(stmmac_fs_dir); + + return -ENOMEM; + } + + return 0; +} + +static void stmmac_exit_fs(void) +{ + debugfs_remove(stmmac_rings_status); + debugfs_remove(stmmac_fs_dir); +} +#endif /* CONFIG_STMMAC_DEBUG_FS */ + static const struct net_device_ops stmmac_netdev_ops = { .ndo_open = stmmac_open, .ndo_start_xmit = stmmac_xmit, @@ -1651,6 +1745,13 @@ static int stmmac_dvr_probe(struct platform_device *pdev) if (ret < 0) goto out_unregister; pr_debug("registered!\n"); + +#ifdef CONFIG_STMMAC_DEBUG_FS + ret = stmmac_init_fs(ndev); + if (ret < 0) + pr_warning("\tFailed debugFS registration"); +#endif + return 0; out_unregister: @@ -1703,6 +1804,10 @@ static int stmmac_dvr_remove(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); +#ifdef CONFIG_STMMAC_DEBUG_FS + stmmac_exit_fs(); +#endif + free_netdev(ndev); return 0; -- 2.46.0