diff options
| author | Giuseppe CAVALLARO <peppe.cavallaro@st.com> | 2011-09-01 17:51:39 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-09-15 15:40:01 -0400 |
| commit | 7ac2905511063376ef59baae0e570bfebeea8004 (patch) | |
| tree | 6182b9b0f08dd85907823ad83d0bd965778b85ae /drivers/net/ethernet/stmicro/stmmac | |
| parent | 1c901a46d576926287b05fc145bd3fd31a3e65de (diff) | |
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 <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac')
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 105 |
2 files changed, 112 insertions, 0 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index cda61e37c357..ae7f56312f08 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig | |||
| @@ -11,6 +11,13 @@ config STMMAC_ETH | |||
| 11 | 11 | ||
| 12 | if STMMAC_ETH | 12 | if STMMAC_ETH |
| 13 | 13 | ||
| 14 | config STMMAC_DEBUG_FS | ||
| 15 | bool "Enable monitoring via sysFS " | ||
| 16 | default n | ||
| 17 | depends on STMMAC_ETH && DEBUG_FS | ||
| 18 | -- help | ||
| 19 | The stmmac entry in /sys reports DMA TX/RX rings. | ||
| 20 | |||
| 14 | config STMMAC_DA | 21 | config STMMAC_DA |
| 15 | bool "STMMAC DMA arbitration scheme" | 22 | bool "STMMAC DMA arbitration scheme" |
| 16 | default n | 23 | default n |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index c28b90d35007..caaad7b14621 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
| @@ -48,6 +48,10 @@ | |||
| 48 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
| 49 | #include <linux/prefetch.h> | 49 | #include <linux/prefetch.h> |
| 50 | #include "stmmac.h" | 50 | #include "stmmac.h" |
| 51 | #ifdef CONFIG_STMMAC_DEBUG_FS | ||
| 52 | #include <linux/debugfs.h> | ||
| 53 | #include <linux/seq_file.h> | ||
| 54 | #endif | ||
| 51 | 55 | ||
| 52 | #define STMMAC_RESOURCE_NAME "stmmaceth" | 56 | #define STMMAC_RESOURCE_NAME "stmmaceth" |
| 53 | 57 | ||
| @@ -1425,6 +1429,96 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
| 1425 | return ret; | 1429 | return ret; |
| 1426 | } | 1430 | } |
| 1427 | 1431 | ||
| 1432 | #ifdef CONFIG_STMMAC_DEBUG_FS | ||
| 1433 | static struct dentry *stmmac_fs_dir; | ||
| 1434 | static struct dentry *stmmac_rings_status; | ||
| 1435 | |||
| 1436 | static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v) | ||
| 1437 | { | ||
| 1438 | struct tmp_s { | ||
| 1439 | u64 a; | ||
| 1440 | unsigned int b; | ||
| 1441 | unsigned int c; | ||
| 1442 | }; | ||
| 1443 | int i; | ||
| 1444 | struct net_device *dev = seq->private; | ||
| 1445 | struct stmmac_priv *priv = netdev_priv(dev); | ||
| 1446 | |||
| 1447 | seq_printf(seq, "=======================\n"); | ||
| 1448 | seq_printf(seq, " RX descriptor ring\n"); | ||
| 1449 | seq_printf(seq, "=======================\n"); | ||
| 1450 | |||
| 1451 | for (i = 0; i < priv->dma_rx_size; i++) { | ||
| 1452 | struct tmp_s *x = (struct tmp_s *)(priv->dma_rx + i); | ||
| 1453 | seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", | ||
| 1454 | i, (unsigned int)(x->a), | ||
| 1455 | (unsigned int)((x->a) >> 32), x->b, x->c); | ||
| 1456 | seq_printf(seq, "\n"); | ||
| 1457 | } | ||
| 1458 | |||
| 1459 | seq_printf(seq, "\n"); | ||
| 1460 | seq_printf(seq, "=======================\n"); | ||
| 1461 | seq_printf(seq, " TX descriptor ring\n"); | ||
| 1462 | seq_printf(seq, "=======================\n"); | ||
| 1463 | |||
| 1464 | for (i = 0; i < priv->dma_tx_size; i++) { | ||
| 1465 | struct tmp_s *x = (struct tmp_s *)(priv->dma_tx + i); | ||
| 1466 | seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", | ||
| 1467 | i, (unsigned int)(x->a), | ||
| 1468 | (unsigned int)((x->a) >> 32), x->b, x->c); | ||
| 1469 | seq_printf(seq, "\n"); | ||
| 1470 | } | ||
| 1471 | |||
| 1472 | return 0; | ||
| 1473 | } | ||
| 1474 | |||
| 1475 | static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file) | ||
| 1476 | { | ||
| 1477 | return single_open(file, stmmac_sysfs_ring_read, inode->i_private); | ||
| 1478 | } | ||
| 1479 | |||
| 1480 | static const struct file_operations stmmac_rings_status_fops = { | ||
| 1481 | .owner = THIS_MODULE, | ||
| 1482 | .open = stmmac_sysfs_ring_open, | ||
| 1483 | .read = seq_read, | ||
| 1484 | .llseek = seq_lseek, | ||
| 1485 | .release = seq_release, | ||
| 1486 | }; | ||
| 1487 | |||
| 1488 | static int stmmac_init_fs(struct net_device *dev) | ||
| 1489 | { | ||
| 1490 | /* Create debugfs entries */ | ||
| 1491 | stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); | ||
| 1492 | |||
| 1493 | if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { | ||
| 1494 | pr_err("ERROR %s, debugfs create directory failed\n", | ||
| 1495 | STMMAC_RESOURCE_NAME); | ||
| 1496 | |||
| 1497 | return -ENOMEM; | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | /* Entry to report DMA RX/TX rings */ | ||
| 1501 | stmmac_rings_status = debugfs_create_file("descriptors_status", | ||
| 1502 | S_IRUGO, stmmac_fs_dir, dev, | ||
| 1503 | &stmmac_rings_status_fops); | ||
| 1504 | |||
| 1505 | if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { | ||
| 1506 | pr_info("ERROR creating stmmac ring debugfs file\n"); | ||
| 1507 | debugfs_remove(stmmac_fs_dir); | ||
| 1508 | |||
| 1509 | return -ENOMEM; | ||
| 1510 | } | ||
| 1511 | |||
| 1512 | return 0; | ||
| 1513 | } | ||
| 1514 | |||
| 1515 | static void stmmac_exit_fs(void) | ||
| 1516 | { | ||
| 1517 | debugfs_remove(stmmac_rings_status); | ||
| 1518 | debugfs_remove(stmmac_fs_dir); | ||
| 1519 | } | ||
| 1520 | #endif /* CONFIG_STMMAC_DEBUG_FS */ | ||
| 1521 | |||
| 1428 | static const struct net_device_ops stmmac_netdev_ops = { | 1522 | static const struct net_device_ops stmmac_netdev_ops = { |
| 1429 | .ndo_open = stmmac_open, | 1523 | .ndo_open = stmmac_open, |
| 1430 | .ndo_start_xmit = stmmac_xmit, | 1524 | .ndo_start_xmit = stmmac_xmit, |
| @@ -1651,6 +1745,13 @@ static int stmmac_dvr_probe(struct platform_device *pdev) | |||
| 1651 | if (ret < 0) | 1745 | if (ret < 0) |
| 1652 | goto out_unregister; | 1746 | goto out_unregister; |
| 1653 | pr_debug("registered!\n"); | 1747 | pr_debug("registered!\n"); |
| 1748 | |||
| 1749 | #ifdef CONFIG_STMMAC_DEBUG_FS | ||
| 1750 | ret = stmmac_init_fs(ndev); | ||
| 1751 | if (ret < 0) | ||
| 1752 | pr_warning("\tFailed debugFS registration"); | ||
| 1753 | #endif | ||
| 1754 | |||
| 1654 | return 0; | 1755 | return 0; |
| 1655 | 1756 | ||
| 1656 | out_unregister: | 1757 | out_unregister: |
| @@ -1703,6 +1804,10 @@ static int stmmac_dvr_remove(struct platform_device *pdev) | |||
| 1703 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1804 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1704 | release_mem_region(res->start, resource_size(res)); | 1805 | release_mem_region(res->start, resource_size(res)); |
| 1705 | 1806 | ||
| 1807 | #ifdef CONFIG_STMMAC_DEBUG_FS | ||
| 1808 | stmmac_exit_fs(); | ||
| 1809 | #endif | ||
| 1810 | |||
| 1706 | free_netdev(ndev); | 1811 | free_netdev(ndev); |
| 1707 | 1812 | ||
| 1708 | return 0; | 1813 | return 0; |
