diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/stmmac/common.h | 4 | ||||
-rw-r--r-- | drivers/net/stmmac/dwmac1000.h | 2 | ||||
-rw-r--r-- | drivers/net/stmmac/dwmac1000_core.c | 13 | ||||
-rw-r--r-- | drivers/net/stmmac/dwmac100_core.c | 6 | ||||
-rw-r--r-- | drivers/net/stmmac/stmmac.h | 4 | ||||
-rw-r--r-- | drivers/net/stmmac/stmmac_ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/stmmac/stmmac_main.c | 66 |
7 files changed, 58 insertions, 39 deletions
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h index e8cbcb5c206e..673ef86a063f 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 | ||
107 | enum rx_frame_status { /* IPC status */ | 105 | enum 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 { | |||
205 | struct stmmac_ops { | 203 | struct 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 8b20b19971cb..81ee4fd04386 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 f1f426146f40..c18c85993179 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 | ||
53 | static 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 | |||
53 | static void dwmac1000_dump_regs(void __iomem *ioaddr) | 65 | static 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 | ||
203 | struct stmmac_ops dwmac1000_ops = { | 215 | struct 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 db06c04ce480..58a914b27003 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 | ||
45 | static int dwmac100_rx_coe_supported(void __iomem *ioaddr) | ||
46 | { | ||
47 | return 0; | ||
48 | } | ||
49 | |||
45 | static void dwmac100_dump_mac_regs(void __iomem *ioaddr) | 50 | static 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 | ||
166 | struct stmmac_ops dwmac100_ops = { | 171 | struct 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 12d1cb00c0d7..92154ff7d702 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 63b68e61afce..b32c16ae55c6 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 | ||
215 | static void | 215 | static void |
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index a169b1441d50..a908f7201aae 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; | |||
134 | module_param(buf_sz, int, S_IRUGO | S_IWUSR); | 134 | module_param(buf_sz, int, S_IRUGO | S_IWUSR); |
135 | MODULE_PARM_DESC(buf_sz, "DMA buffer size"); | 135 | MODULE_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. */ | ||
140 | static int tx_coe = HW_CSUM; | ||
141 | module_param(tx_coe, int, S_IRUGO | S_IWUSR); | ||
142 | MODULE_PARM_DESC(tx_coe, "GMAC COE type 2 [on/off]"); | ||
143 | |||
144 | static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | | 137 | static 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 | */ |
575 | static void stmmac_dma_operation_mode(struct stmmac_priv *priv) | 567 | static 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)) |