aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/stmmac/common.h4
-rw-r--r--drivers/net/stmmac/dwmac1000.h2
-rw-r--r--drivers/net/stmmac/dwmac1000_core.c13
-rw-r--r--drivers/net/stmmac/dwmac100_core.c6
-rw-r--r--drivers/net/stmmac/stmmac.h4
-rw-r--r--drivers/net/stmmac/stmmac_ethtool.c2
-rw-r--r--drivers/net/stmmac/stmmac_main.c66
-rw-r--r--include/linux/stmmac.h2
8 files changed, 60 insertions, 39 deletions
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
index e8cbcb5c206..673ef86a063 100644
--- a/drivers/net/stmmac/common.h
+++ b/drivers/net/stmmac/common.h
@@ -102,8 +102,6 @@ struct stmmac_extra_stats {
102 102
103#define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */ 103#define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */
104 104
105#define HW_CSUM 1
106#define NO_HW_CSUM 0
107enum rx_frame_status { /* IPC status */ 105enum rx_frame_status { /* IPC status */
108 good_frame = 0, 106 good_frame = 0,
109 discard_frame = 1, 107 discard_frame = 1,
@@ -205,6 +203,8 @@ struct stmmac_dma_ops {
205struct stmmac_ops { 203struct stmmac_ops {
206 /* MAC core initialization */ 204 /* MAC core initialization */
207 void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned; 205 void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned;
206 /* Support checksum offload engine */
207 int (*rx_coe) (void __iomem *ioaddr);
208 /* Dump MAC registers */ 208 /* Dump MAC registers */
209 void (*dump_regs) (void __iomem *ioaddr); 209 void (*dump_regs) (void __iomem *ioaddr);
210 /* Handle extra events on specific interrupts hw dependent */ 210 /* Handle extra events on specific interrupts hw dependent */
diff --git a/drivers/net/stmmac/dwmac1000.h b/drivers/net/stmmac/dwmac1000.h
index 8b20b19971c..81ee4fd0438 100644
--- a/drivers/net/stmmac/dwmac1000.h
+++ b/drivers/net/stmmac/dwmac1000.h
@@ -99,7 +99,7 @@ enum inter_frame_gap {
99#define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */ 99#define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */
100 100
101#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \ 101#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \
102 GMAC_CONTROL_IPC | GMAC_CONTROL_JE | GMAC_CONTROL_BE) 102 GMAC_CONTROL_JE | GMAC_CONTROL_BE)
103 103
104/* GMAC Frame Filter defines */ 104/* GMAC Frame Filter defines */
105#define GMAC_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */ 105#define GMAC_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */
diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c
index f1f426146f4..c18c8599317 100644
--- a/drivers/net/stmmac/dwmac1000_core.c
+++ b/drivers/net/stmmac/dwmac1000_core.c
@@ -50,6 +50,18 @@ static void dwmac1000_core_init(void __iomem *ioaddr)
50#endif 50#endif
51} 51}
52 52
53static int dwmac1000_rx_coe_supported(void __iomem *ioaddr)
54{
55 u32 value = readl(ioaddr + GMAC_CONTROL);
56
57 value |= GMAC_CONTROL_IPC;
58 writel(value, ioaddr + GMAC_CONTROL);
59
60 value = readl(ioaddr + GMAC_CONTROL);
61
62 return !!(value & GMAC_CONTROL_IPC);
63}
64
53static void dwmac1000_dump_regs(void __iomem *ioaddr) 65static void dwmac1000_dump_regs(void __iomem *ioaddr)
54{ 66{
55 int i; 67 int i;
@@ -202,6 +214,7 @@ static void dwmac1000_irq_status(void __iomem *ioaddr)
202 214
203struct stmmac_ops dwmac1000_ops = { 215struct stmmac_ops dwmac1000_ops = {
204 .core_init = dwmac1000_core_init, 216 .core_init = dwmac1000_core_init,
217 .rx_coe = dwmac1000_rx_coe_supported,
205 .dump_regs = dwmac1000_dump_regs, 218 .dump_regs = dwmac1000_dump_regs,
206 .host_irq_status = dwmac1000_irq_status, 219 .host_irq_status = dwmac1000_irq_status,
207 .set_filter = dwmac1000_set_filter, 220 .set_filter = dwmac1000_set_filter,
diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c
index db06c04ce48..58a914b2700 100644
--- a/drivers/net/stmmac/dwmac100_core.c
+++ b/drivers/net/stmmac/dwmac100_core.c
@@ -42,6 +42,11 @@ static void dwmac100_core_init(void __iomem *ioaddr)
42#endif 42#endif
43} 43}
44 44
45static int dwmac100_rx_coe_supported(void __iomem *ioaddr)
46{
47 return 0;
48}
49
45static void dwmac100_dump_mac_regs(void __iomem *ioaddr) 50static void dwmac100_dump_mac_regs(void __iomem *ioaddr)
46{ 51{
47 pr_info("\t----------------------------------------------\n" 52 pr_info("\t----------------------------------------------\n"
@@ -165,6 +170,7 @@ static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode)
165 170
166struct stmmac_ops dwmac100_ops = { 171struct stmmac_ops dwmac100_ops = {
167 .core_init = dwmac100_core_init, 172 .core_init = dwmac100_core_init,
173 .rx_coe = dwmac100_rx_coe_supported,
168 .dump_regs = dwmac100_dump_mac_regs, 174 .dump_regs = dwmac100_dump_mac_regs,
169 .host_irq_status = dwmac100_irq_status, 175 .host_irq_status = dwmac100_irq_status,
170 .set_filter = dwmac100_set_filter, 176 .set_filter = dwmac100_set_filter,
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
index 12d1cb00c0d..92154ff7d70 100644
--- a/drivers/net/stmmac/stmmac.h
+++ b/drivers/net/stmmac/stmmac.h
@@ -51,7 +51,6 @@ struct stmmac_priv {
51 int is_gmac; 51 int is_gmac;
52 dma_addr_t dma_rx_phy; 52 dma_addr_t dma_rx_phy;
53 unsigned int dma_rx_size; 53 unsigned int dma_rx_size;
54 int rx_csum;
55 unsigned int dma_buf_sz; 54 unsigned int dma_buf_sz;
56 struct device *device; 55 struct device *device;
57 struct mac_device_info *hw; 56 struct mac_device_info *hw;
@@ -92,6 +91,9 @@ struct stmmac_priv {
92 struct vlan_group *vlgrp; 91 struct vlan_group *vlgrp;
93#endif 92#endif
94 int enh_desc; 93 int enh_desc;
94 int rx_coe;
95 int bugged_jumbo;
96 int no_csum_insertion;
95}; 97};
96 98
97#ifdef CONFIG_STM_DRIVERS 99#ifdef CONFIG_STM_DRIVERS
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
index 63b68e61afc..b32c16ae55c 100644
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -209,7 +209,7 @@ u32 stmmac_ethtool_get_rx_csum(struct net_device *dev)
209{ 209{
210 struct stmmac_priv *priv = netdev_priv(dev); 210 struct stmmac_priv *priv = netdev_priv(dev);
211 211
212 return priv->rx_csum; 212 return priv->rx_coe;
213} 213}
214 214
215static void 215static void
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index a169b1441d5..a908f7201aa 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -134,13 +134,6 @@ static int buf_sz = DMA_BUFFER_SIZE;
134module_param(buf_sz, int, S_IRUGO | S_IWUSR); 134module_param(buf_sz, int, S_IRUGO | S_IWUSR);
135MODULE_PARM_DESC(buf_sz, "DMA buffer size"); 135MODULE_PARM_DESC(buf_sz, "DMA buffer size");
136 136
137/* In case of Giga ETH, we can enable/disable the COE for the
138 * transmit HW checksum computation.
139 * Note that, if tx csum is off in HW, SG will be still supported. */
140static int tx_coe = HW_CSUM;
141module_param(tx_coe, int, S_IRUGO | S_IWUSR);
142MODULE_PARM_DESC(tx_coe, "GMAC COE type 2 [on/off]");
143
144static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | 137static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
145 NETIF_MSG_LINK | NETIF_MSG_IFUP | 138 NETIF_MSG_LINK | NETIF_MSG_IFUP |
146 NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); 139 NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
@@ -569,29 +562,22 @@ static void free_dma_desc_resources(struct stmmac_priv *priv)
569 * stmmac_dma_operation_mode - HW DMA operation mode 562 * stmmac_dma_operation_mode - HW DMA operation mode
570 * @priv : pointer to the private device structure. 563 * @priv : pointer to the private device structure.
571 * Description: it sets the DMA operation mode: tx/rx DMA thresholds 564 * Description: it sets the DMA operation mode: tx/rx DMA thresholds
572 * or Store-And-Forward capability. It also verifies the COE for the 565 * or Store-And-Forward capability.
573 * transmission in case of Giga ETH.
574 */ 566 */
575static void stmmac_dma_operation_mode(struct stmmac_priv *priv) 567static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
576{ 568{
577 if (!priv->is_gmac) { 569 if (likely((priv->tx_coe) && (!priv->no_csum_insertion))) {
578 /* MAC 10/100 */ 570 /* In case of GMAC, SF mode has to be enabled
579 priv->hw->dma->dma_mode(priv->ioaddr, tc, 0); 571 * to perform the TX COE. This depends on:
580 priv->tx_coe = NO_HW_CSUM; 572 * 1) TX COE if actually supported
581 } else { 573 * 2) There is no bugged Jumbo frame support
582 if ((priv->dev->mtu <= ETH_DATA_LEN) && (tx_coe)) { 574 * that needs to not insert csum in the TDES.
583 priv->hw->dma->dma_mode(priv->ioaddr, 575 */
584 SF_DMA_MODE, SF_DMA_MODE); 576 priv->hw->dma->dma_mode(priv->ioaddr,
585 tc = SF_DMA_MODE; 577 SF_DMA_MODE, SF_DMA_MODE);
586 priv->tx_coe = HW_CSUM; 578 tc = SF_DMA_MODE;
587 } else { 579 } else
588 /* Checksum computation is performed in software. */ 580 priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
589 priv->hw->dma->dma_mode(priv->ioaddr, tc,
590 SF_DMA_MODE);
591 priv->tx_coe = NO_HW_CSUM;
592 }
593 }
594 tx_coe = priv->tx_coe;
595} 581}
596 582
597/** 583/**
@@ -858,6 +844,12 @@ static int stmmac_open(struct net_device *dev)
858 /* Initialize the MAC Core */ 844 /* Initialize the MAC Core */
859 priv->hw->mac->core_init(priv->ioaddr); 845 priv->hw->mac->core_init(priv->ioaddr);
860 846
847 priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
848 if (priv->rx_coe)
849 pr_info("stmmac: Rx Checksum Offload Engine supported\n");
850 if (priv->tx_coe)
851 pr_info("\tTX Checksum insertion supported\n");
852
861 priv->shutdown = 0; 853 priv->shutdown = 0;
862 854
863 /* Initialise the MMC (if present) to disable all interrupts. */ 855 /* Initialise the MMC (if present) to disable all interrupts. */
@@ -1066,7 +1058,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
1066 return stmmac_sw_tso(priv, skb); 1058 return stmmac_sw_tso(priv, skb);
1067 1059
1068 if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) { 1060 if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) {
1069 if (likely(priv->tx_coe == NO_HW_CSUM)) 1061 if (unlikely((!priv->tx_coe) || (priv->no_csum_insertion)))
1070 skb_checksum_help(skb); 1062 skb_checksum_help(skb);
1071 else 1063 else
1072 csum_insertion = 1; 1064 csum_insertion = 1;
@@ -1390,6 +1382,15 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
1390 return -EINVAL; 1382 return -EINVAL;
1391 } 1383 }
1392 1384
1385 /* Some GMAC devices have a bugged Jumbo frame support that
1386 * needs to have the Tx COE disabled for oversized frames
1387 * (due to limited buffer sizes). In this case we disable
1388 * the TX csum insertionin the TDES and not use SF. */
1389 if ((priv->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN))
1390 priv->no_csum_insertion = 1;
1391 else
1392 priv->no_csum_insertion = 0;
1393
1393 dev->mtu = new_mtu; 1394 dev->mtu = new_mtu;
1394 1395
1395 return 0; 1396 return 0;
@@ -1510,9 +1511,6 @@ static int stmmac_probe(struct net_device *dev)
1510#endif 1511#endif
1511 priv->msg_enable = netif_msg_init(debug, default_msg_level); 1512 priv->msg_enable = netif_msg_init(debug, default_msg_level);
1512 1513
1513 if (priv->is_gmac)
1514 priv->rx_csum = 1;
1515
1516 if (flow_ctrl) 1514 if (flow_ctrl)
1517 priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ 1515 priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */
1518 1516
@@ -1662,7 +1660,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
1662 ret = -ENODEV; 1660 ret = -ENODEV;
1663 goto out; 1661 goto out;
1664 } 1662 }
1665 pr_info("done!\n"); 1663 pr_info("\tdone!\n");
1666 1664
1667 if (!request_mem_region(res->start, resource_size(res), 1665 if (!request_mem_region(res->start, resource_size(res),
1668 pdev->name)) { 1666 pdev->name)) {
@@ -1705,6 +1703,8 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
1705 priv->bus_id = plat_dat->bus_id; 1703 priv->bus_id = plat_dat->bus_id;
1706 priv->pbl = plat_dat->pbl; /* TLI */ 1704 priv->pbl = plat_dat->pbl; /* TLI */
1707 priv->mii_clk_csr = plat_dat->clk_csr; 1705 priv->mii_clk_csr = plat_dat->clk_csr;
1706 priv->tx_coe = plat_dat->tx_coe;
1707 priv->bugged_jumbo = plat_dat->bugged_jumbo;
1708 priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */ 1708 priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */
1709 priv->enh_desc = plat_dat->enh_desc; 1709 priv->enh_desc = plat_dat->enh_desc;
1710 priv->ioaddr = addr; 1710 priv->ioaddr = addr;
@@ -1966,8 +1966,6 @@ static int __init stmmac_cmdline_opt(char *str)
1966 strict_strtoul(opt + 7, 0, (unsigned long *)&buf_sz); 1966 strict_strtoul(opt + 7, 0, (unsigned long *)&buf_sz);
1967 else if (!strncmp(opt, "tc:", 3)) 1967 else if (!strncmp(opt, "tc:", 3))
1968 strict_strtoul(opt + 3, 0, (unsigned long *)&tc); 1968 strict_strtoul(opt + 3, 0, (unsigned long *)&tc);
1969 else if (!strncmp(opt, "tx_coe:", 7))
1970 strict_strtoul(opt + 7, 0, (unsigned long *)&tx_coe);
1971 else if (!strncmp(opt, "watchdog:", 9)) 1969 else if (!strncmp(opt, "watchdog:", 9))
1972 strict_strtoul(opt + 9, 0, (unsigned long *)&watchdog); 1970 strict_strtoul(opt + 9, 0, (unsigned long *)&watchdog);
1973 else if (!strncmp(opt, "flow_ctrl:", 10)) 1971 else if (!strncmp(opt, "flow_ctrl:", 10))
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index c87c88ccffc..1d8baf71921 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -35,6 +35,8 @@ struct plat_stmmacenet_data {
35 int clk_csr; 35 int clk_csr;
36 int has_gmac; 36 int has_gmac;
37 int enh_desc; 37 int enh_desc;
38 int tx_coe;
39 int bugged_jumbo;
38 void (*fix_mac_speed)(void *priv, unsigned int speed); 40 void (*fix_mac_speed)(void *priv, unsigned int speed);
39 void (*bus_setup)(void __iomem *ioaddr); 41 void (*bus_setup)(void __iomem *ioaddr);
40#ifdef CONFIG_STM_DRIVERS 42#ifdef CONFIG_STM_DRIVERS