aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/stmicro/stmmac
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2011-09-01 17:51:41 -0400
committerDavid S. Miller <davem@davemloft.net>2011-09-15 15:40:01 -0400
commite7434821411b5fc24ab23e55cb11ea793248cb6b (patch)
treed6ea9d683e56916c5d9a7f59cafc4866deb07655 /drivers/net/ethernet/stmicro/stmmac
parentf0b9d7865a95fdcb18319a678c616156be74cdfb (diff)
stmmac: add HW DMA feature register (v3)
New GMAC chips have an extra register to indicate the presence of the optional features/functions of the DMA core. This patch adds this support and all the HW cap are exported via debugfs. 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/Kconfig3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h33
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c131
6 files changed, 174 insertions, 1 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index ae7f56312f0..2e35be7ccfa 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -16,7 +16,8 @@ config STMMAC_DEBUG_FS
16 default n 16 default n
17 depends on STMMAC_ETH && DEBUG_FS 17 depends on STMMAC_ETH && DEBUG_FS
18 -- help 18 -- help
19 The stmmac entry in /sys reports DMA TX/RX rings. 19 The stmmac entry in /sys reports DMA TX/RX rings
20 or (if supported) the HW cap register.
20 21
21config STMMAC_DA 22config STMMAC_DA
22 bool "STMMAC DMA arbitration scheme" 23 bool "STMMAC DMA arbitration scheme"
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 65b1e56a97c..22c61b2ebfa 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -116,6 +116,37 @@ enum tx_dma_irq_status {
116 handle_tx_rx = 3, 116 handle_tx_rx = 3,
117}; 117};
118 118
119/* DMA HW capabilities */
120struct dma_features {
121 unsigned int mbps_10_100;
122 unsigned int mbps_1000;
123 unsigned int half_duplex;
124 unsigned int hash_filter;
125 unsigned int multi_addr;
126 unsigned int pcs;
127 unsigned int sma_mdio;
128 unsigned int pmt_remote_wake_up;
129 unsigned int pmt_magic_frame;
130 unsigned int rmon;
131 /* IEEE 1588-2002*/
132 unsigned int time_stamp;
133 /* IEEE 1588-2008*/
134 unsigned int atime_stamp;
135 /* 802.3az - Energy-Efficient Ethernet (EEE) */
136 unsigned int eee;
137 unsigned int av;
138 /* TX and RX csum */
139 unsigned int tx_coe;
140 unsigned int rx_coe_type1;
141 unsigned int rx_coe_type2;
142 unsigned int rxfifo_over_2048;
143 /* TX and RX number of channels */
144 unsigned int number_rx_channel;
145 unsigned int number_tx_channel;
146 /* Alternate (enhanced) DESC mode*/
147 unsigned int enh_desc;
148};
149
119/* GMAC TX FIFO is 8K, Rx FIFO is 16K */ 150/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
120#define BUF_SIZE_16KiB 16384 151#define BUF_SIZE_16KiB 16384
121#define BUF_SIZE_8KiB 8192 152#define BUF_SIZE_8KiB 8192
@@ -188,6 +219,8 @@ struct stmmac_dma_ops {
188 void (*stop_rx) (void __iomem *ioaddr); 219 void (*stop_rx) (void __iomem *ioaddr);
189 int (*dma_interrupt) (void __iomem *ioaddr, 220 int (*dma_interrupt) (void __iomem *ioaddr,
190 struct stmmac_extra_stats *x); 221 struct stmmac_extra_stats *x);
222 /* If supported then get the optional core features */
223 unsigned int (*get_hw_feature) (void __iomem *ioaddr);
191}; 224};
192 225
193struct stmmac_ops { 226struct stmmac_ops {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index a89384c0751..da66ac511c4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -132,6 +132,11 @@ static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
132 } 132 }
133} 133}
134 134
135static unsigned int dwmac1000_get_hw_feature(void __iomem *ioaddr)
136{
137 return readl(ioaddr + DMA_HW_FEATURE);
138}
139
135const struct stmmac_dma_ops dwmac1000_dma_ops = { 140const struct stmmac_dma_ops dwmac1000_dma_ops = {
136 .init = dwmac1000_dma_init, 141 .init = dwmac1000_dma_init,
137 .dump_regs = dwmac1000_dump_dma_regs, 142 .dump_regs = dwmac1000_dump_dma_regs,
@@ -144,4 +149,5 @@ const struct stmmac_dma_ops dwmac1000_dma_ops = {
144 .start_rx = dwmac_dma_start_rx, 149 .start_rx = dwmac_dma_start_rx,
145 .stop_rx = dwmac_dma_stop_rx, 150 .stop_rx = dwmac_dma_stop_rx,
146 .dma_interrupt = dwmac_dma_interrupt, 151 .dma_interrupt = dwmac_dma_interrupt,
152 .get_hw_feature = dwmac1000_get_hw_feature,
147}; 153};
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index da3f5ccf83d..437edacd602 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -34,6 +34,7 @@
34#define DMA_MISSED_FRAME_CTR 0x00001020 /* Missed Frame Counter */ 34#define DMA_MISSED_FRAME_CTR 0x00001020 /* Missed Frame Counter */
35#define DMA_CUR_TX_BUF_ADDR 0x00001050 /* Current Host Tx Buffer */ 35#define DMA_CUR_TX_BUF_ADDR 0x00001050 /* Current Host Tx Buffer */
36#define DMA_CUR_RX_BUF_ADDR 0x00001054 /* Current Host Rx Buffer */ 36#define DMA_CUR_RX_BUF_ADDR 0x00001054 /* Current Host Rx Buffer */
37#define DMA_HW_FEATURE 0x00001058 /* HW Feature Register */
37 38
38/* DMA Control register defines */ 39/* DMA Control register defines */
39#define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */ 40#define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index ef037965493..c3a2da71d1e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -78,6 +78,7 @@ struct stmmac_priv {
78#endif 78#endif
79 struct plat_stmmacenet_data *plat; 79 struct plat_stmmacenet_data *plat;
80 struct stmmac_counters mmc; 80 struct stmmac_counters mmc;
81 struct dma_features dma_cap;
81}; 82};
82 83
83extern int stmmac_mdio_unregister(struct net_device *ndev); 84extern int stmmac_mdio_unregister(struct net_device *ndev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index eb210ca2497..d0fbc5477d1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -780,6 +780,49 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
780 } 780 }
781 return 0; 781 return 0;
782} 782}
783
784/* New GMAC chips support a new register to indicate the
785 * presence of the optional feature/functions.
786 */
787static int stmmac_get_hw_features(struct stmmac_priv *priv)
788{
789 u32 hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr);
790
791 if (likely(hw_cap)) {
792 priv->dma_cap.mbps_10_100 = (hw_cap & 0x1);
793 priv->dma_cap.mbps_1000 = (hw_cap & 0x2) >> 1;
794 priv->dma_cap.half_duplex = (hw_cap & 0x4) >> 2;
795 priv->dma_cap.hash_filter = (hw_cap & 0x10) >> 4;
796 priv->dma_cap.multi_addr = (hw_cap & 0x20) >> 5;
797 priv->dma_cap.pcs = (hw_cap & 0x40) >> 6;
798 priv->dma_cap.sma_mdio = (hw_cap & 0x100) >> 8;
799 priv->dma_cap.pmt_remote_wake_up = (hw_cap & 0x200) >> 9;
800 priv->dma_cap.pmt_magic_frame = (hw_cap & 0x400) >> 10;
801 priv->dma_cap.rmon = (hw_cap & 0x800) >> 11; /* MMC */
802 /* IEEE 1588-2002*/
803 priv->dma_cap.time_stamp = (hw_cap & 0x1000) >> 12;
804 /* IEEE 1588-2008*/
805 priv->dma_cap.atime_stamp = (hw_cap & 0x2000) >> 13;
806 /* 802.3az - Energy-Efficient Ethernet (EEE) */
807 priv->dma_cap.eee = (hw_cap & 0x4000) >> 14;
808 priv->dma_cap.av = (hw_cap & 0x8000) >> 15;
809 /* TX and RX csum */
810 priv->dma_cap.tx_coe = (hw_cap & 0x10000) >> 16;
811 priv->dma_cap.rx_coe_type1 = (hw_cap & 0x20000) >> 17;
812 priv->dma_cap.rx_coe_type2 = (hw_cap & 0x40000) >> 18;
813 priv->dma_cap.rxfifo_over_2048 = (hw_cap & 0x80000) >> 19;
814 /* TX and RX number of channels */
815 priv->dma_cap.number_rx_channel = (hw_cap & 0x300000) >> 20;
816 priv->dma_cap.number_tx_channel = (hw_cap & 0xc00000) >> 22;
817 /* Alternate (enhanced) DESC mode*/
818 priv->dma_cap.enh_desc = (hw_cap & 0x1000000) >> 24;
819
820 } else
821 pr_debug("\tNo HW DMA feature register supported");
822
823 return hw_cap;
824}
825
783/** 826/**
784 * stmmac_open - open entry point of the driver 827 * stmmac_open - open entry point of the driver
785 * @dev : pointer to the device structure. 828 * @dev : pointer to the device structure.
@@ -854,6 +897,8 @@ static int stmmac_open(struct net_device *dev)
854 897
855 stmmac_get_synopsys_id(priv); 898 stmmac_get_synopsys_id(priv);
856 899
900 stmmac_get_hw_features(priv);
901
857 if (priv->rx_coe) 902 if (priv->rx_coe)
858 pr_info("stmmac: Rx Checksum Offload Engine supported\n"); 903 pr_info("stmmac: Rx Checksum Offload Engine supported\n");
859 if (priv->plat->tx_coe) 904 if (priv->plat->tx_coe)
@@ -1450,6 +1495,7 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1450#ifdef CONFIG_STMMAC_DEBUG_FS 1495#ifdef CONFIG_STMMAC_DEBUG_FS
1451static struct dentry *stmmac_fs_dir; 1496static struct dentry *stmmac_fs_dir;
1452static struct dentry *stmmac_rings_status; 1497static struct dentry *stmmac_rings_status;
1498static struct dentry *stmmac_dma_cap;
1453 1499
1454static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v) 1500static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v)
1455{ 1501{
@@ -1503,6 +1549,78 @@ static const struct file_operations stmmac_rings_status_fops = {
1503 .release = seq_release, 1549 .release = seq_release,
1504}; 1550};
1505 1551
1552static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)
1553{
1554 struct net_device *dev = seq->private;
1555 struct stmmac_priv *priv = netdev_priv(dev);
1556
1557 if (!stmmac_get_hw_features(priv)) {
1558 seq_printf(seq, "DMA HW features not supported\n");
1559 return 0;
1560 }
1561
1562 seq_printf(seq, "==============================\n");
1563 seq_printf(seq, "\tDMA HW features\n");
1564 seq_printf(seq, "==============================\n");
1565
1566 seq_printf(seq, "\t10/100 Mbps %s\n",
1567 (priv->dma_cap.mbps_10_100) ? "Y" : "N");
1568 seq_printf(seq, "\t1000 Mbps %s\n",
1569 (priv->dma_cap.mbps_1000) ? "Y" : "N");
1570 seq_printf(seq, "\tHalf duple %s\n",
1571 (priv->dma_cap.half_duplex) ? "Y" : "N");
1572 seq_printf(seq, "\tHash Filter: %s\n",
1573 (priv->dma_cap.hash_filter) ? "Y" : "N");
1574 seq_printf(seq, "\tMultiple MAC address registers: %s\n",
1575 (priv->dma_cap.multi_addr) ? "Y" : "N");
1576 seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n",
1577 (priv->dma_cap.pcs) ? "Y" : "N");
1578 seq_printf(seq, "\tSMA (MDIO) Interface: %s\n",
1579 (priv->dma_cap.sma_mdio) ? "Y" : "N");
1580 seq_printf(seq, "\tPMT Remote wake up: %s\n",
1581 (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N");
1582 seq_printf(seq, "\tPMT Magic Frame: %s\n",
1583 (priv->dma_cap.pmt_magic_frame) ? "Y" : "N");
1584 seq_printf(seq, "\tRMON module: %s\n",
1585 (priv->dma_cap.rmon) ? "Y" : "N");
1586 seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n",
1587 (priv->dma_cap.time_stamp) ? "Y" : "N");
1588 seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n",
1589 (priv->dma_cap.atime_stamp) ? "Y" : "N");
1590 seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n",
1591 (priv->dma_cap.eee) ? "Y" : "N");
1592 seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N");
1593 seq_printf(seq, "\tChecksum Offload in TX: %s\n",
1594 (priv->dma_cap.tx_coe) ? "Y" : "N");
1595 seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n",
1596 (priv->dma_cap.rx_coe_type1) ? "Y" : "N");
1597 seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n",
1598 (priv->dma_cap.rx_coe_type2) ? "Y" : "N");
1599 seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n",
1600 (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N");
1601 seq_printf(seq, "\tNumber of Additional RX channel: %d\n",
1602 priv->dma_cap.number_rx_channel);
1603 seq_printf(seq, "\tNumber of Additional TX channel: %d\n",
1604 priv->dma_cap.number_tx_channel);
1605 seq_printf(seq, "\tEnhanced descriptors: %s\n",
1606 (priv->dma_cap.enh_desc) ? "Y" : "N");
1607
1608 return 0;
1609}
1610
1611static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file)
1612{
1613 return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private);
1614}
1615
1616static const struct file_operations stmmac_dma_cap_fops = {
1617 .owner = THIS_MODULE,
1618 .open = stmmac_sysfs_dma_cap_open,
1619 .read = seq_read,
1620 .llseek = seq_lseek,
1621 .release = seq_release,
1622};
1623
1506static int stmmac_init_fs(struct net_device *dev) 1624static int stmmac_init_fs(struct net_device *dev)
1507{ 1625{
1508 /* Create debugfs entries */ 1626 /* Create debugfs entries */
@@ -1527,12 +1645,25 @@ static int stmmac_init_fs(struct net_device *dev)
1527 return -ENOMEM; 1645 return -ENOMEM;
1528 } 1646 }
1529 1647
1648 /* Entry to report the DMA HW features */
1649 stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
1650 dev, &stmmac_dma_cap_fops);
1651
1652 if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
1653 pr_info("ERROR creating stmmac MMC debugfs file\n");
1654 debugfs_remove(stmmac_rings_status);
1655 debugfs_remove(stmmac_fs_dir);
1656
1657 return -ENOMEM;
1658 }
1659
1530 return 0; 1660 return 0;
1531} 1661}
1532 1662
1533static void stmmac_exit_fs(void) 1663static void stmmac_exit_fs(void)
1534{ 1664{
1535 debugfs_remove(stmmac_rings_status); 1665 debugfs_remove(stmmac_rings_status);
1666 debugfs_remove(stmmac_dma_cap);
1536 debugfs_remove(stmmac_fs_dir); 1667 debugfs_remove(stmmac_fs_dir);
1537} 1668}
1538#endif /* CONFIG_STMMAC_DEBUG_FS */ 1669#endif /* CONFIG_STMMAC_DEBUG_FS */