aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c4
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c12
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/enh_desc.c13
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/norm_desc.c13
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c32
7 files changed, 58 insertions, 24 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 0319d640f728..eec8d34b6c88 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -228,7 +228,7 @@ struct stmmac_desc_ops {
228 int (*get_rx_owner) (struct dma_desc *p); 228 int (*get_rx_owner) (struct dma_desc *p);
229 void (*set_rx_owner) (struct dma_desc *p); 229 void (*set_rx_owner) (struct dma_desc *p);
230 /* Get the receive frame size */ 230 /* Get the receive frame size */
231 int (*get_rx_frame_len) (struct dma_desc *p); 231 int (*get_rx_frame_len) (struct dma_desc *p, int rx_coe_type);
232 /* Return the reception status looking at the RDES1 */ 232 /* Return the reception status looking at the RDES1 */
233 int (*rx_status) (void *data, struct stmmac_extra_stats *x, 233 int (*rx_status) (void *data, struct stmmac_extra_stats *x,
234 struct dma_desc *p); 234 struct dma_desc *p);
@@ -261,8 +261,8 @@ struct stmmac_dma_ops {
261struct stmmac_ops { 261struct stmmac_ops {
262 /* MAC core initialization */ 262 /* MAC core initialization */
263 void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned; 263 void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned;
264 /* Support checksum offload engine */ 264 /* Enable and verify that the IPC module is supported */
265 int (*rx_coe) (void __iomem *ioaddr); 265 int (*rx_ipc) (void __iomem *ioaddr);
266 /* Dump MAC registers */ 266 /* Dump MAC registers */
267 void (*dump_regs) (void __iomem *ioaddr); 267 void (*dump_regs) (void __iomem *ioaddr);
268 /* Handle extra events on specific interrupts hw dependent */ 268 /* Handle extra events on specific interrupts hw dependent */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index b1c48b975945..e7cbcd99c2cb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -46,7 +46,7 @@ static void dwmac1000_core_init(void __iomem *ioaddr)
46#endif 46#endif
47} 47}
48 48
49static int dwmac1000_rx_coe_supported(void __iomem *ioaddr) 49static int dwmac1000_rx_ipc_enable(void __iomem *ioaddr)
50{ 50{
51 u32 value = readl(ioaddr + GMAC_CONTROL); 51 u32 value = readl(ioaddr + GMAC_CONTROL);
52 52
@@ -211,7 +211,7 @@ static void dwmac1000_irq_status(void __iomem *ioaddr)
211 211
212static const struct stmmac_ops dwmac1000_ops = { 212static const struct stmmac_ops dwmac1000_ops = {
213 .core_init = dwmac1000_core_init, 213 .core_init = dwmac1000_core_init,
214 .rx_coe = dwmac1000_rx_coe_supported, 214 .rx_ipc = dwmac1000_rx_ipc_enable,
215 .dump_regs = dwmac1000_dump_regs, 215 .dump_regs = dwmac1000_dump_regs,
216 .host_irq_status = dwmac1000_irq_status, 216 .host_irq_status = dwmac1000_irq_status,
217 .set_filter = dwmac1000_set_filter, 217 .set_filter = dwmac1000_set_filter,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
index 138fb8dd1e87..efde50ff03f8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -43,11 +43,6 @@ static void dwmac100_core_init(void __iomem *ioaddr)
43#endif 43#endif
44} 44}
45 45
46static int dwmac100_rx_coe_supported(void __iomem *ioaddr)
47{
48 return 0;
49}
50
51static void dwmac100_dump_mac_regs(void __iomem *ioaddr) 46static void dwmac100_dump_mac_regs(void __iomem *ioaddr)
52{ 47{
53 pr_info("\t----------------------------------------------\n" 48 pr_info("\t----------------------------------------------\n"
@@ -72,6 +67,11 @@ static void dwmac100_dump_mac_regs(void __iomem *ioaddr)
72 readl(ioaddr + MAC_VLAN2)); 67 readl(ioaddr + MAC_VLAN2));
73} 68}
74 69
70static int dwmac100_rx_ipc_enable(void __iomem *ioaddr)
71{
72 return 0;
73}
74
75static void dwmac100_irq_status(void __iomem *ioaddr) 75static void dwmac100_irq_status(void __iomem *ioaddr)
76{ 76{
77 return; 77 return;
@@ -160,7 +160,7 @@ static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode)
160 160
161static const struct stmmac_ops dwmac100_ops = { 161static const struct stmmac_ops dwmac100_ops = {
162 .core_init = dwmac100_core_init, 162 .core_init = dwmac100_core_init,
163 .rx_coe = dwmac100_rx_coe_supported, 163 .rx_ipc = dwmac100_rx_ipc_enable,
164 .dump_regs = dwmac100_dump_mac_regs, 164 .dump_regs = dwmac100_dump_mac_regs,
165 .host_irq_status = dwmac100_irq_status, 165 .host_irq_status = dwmac100_irq_status,
166 .set_filter = dwmac100_set_filter, 166 .set_filter = dwmac100_set_filter,
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
index ad1b627f8ec2..2fc8ef95f97a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
@@ -22,6 +22,7 @@
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/ 23*******************************************************************************/
24 24
25#include <linux/stmmac.h>
25#include "common.h" 26#include "common.h"
26#include "descs_com.h" 27#include "descs_com.h"
27 28
@@ -309,9 +310,17 @@ static void enh_desc_close_tx_desc(struct dma_desc *p)
309 p->des01.etx.interrupt = 1; 310 p->des01.etx.interrupt = 1;
310} 311}
311 312
312static int enh_desc_get_rx_frame_len(struct dma_desc *p) 313static int enh_desc_get_rx_frame_len(struct dma_desc *p, int rx_coe_type)
313{ 314{
314 return p->des01.erx.frame_length; 315 /* The type-1 checksum offload engines append the checksum at
316 * the end of frame and the two bytes of checksum are added in
317 * the length.
318 * Adjust for that in the framelen for type-1 checksum offload
319 * engines. */
320 if (rx_coe_type == STMMAC_RX_COE_TYPE1)
321 return p->des01.erx.frame_length - 2;
322 else
323 return p->des01.erx.frame_length;
315} 324}
316 325
317const struct stmmac_desc_ops enh_desc_ops = { 326const struct stmmac_desc_ops enh_desc_ops = {
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
index 25953bb45a73..68962c549a2d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
@@ -22,6 +22,7 @@
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/ 23*******************************************************************************/
24 24
25#include <linux/stmmac.h>
25#include "common.h" 26#include "common.h"
26#include "descs_com.h" 27#include "descs_com.h"
27 28
@@ -201,9 +202,17 @@ static void ndesc_close_tx_desc(struct dma_desc *p)
201 p->des01.tx.interrupt = 1; 202 p->des01.tx.interrupt = 1;
202} 203}
203 204
204static int ndesc_get_rx_frame_len(struct dma_desc *p) 205static int ndesc_get_rx_frame_len(struct dma_desc *p, int rx_coe_type)
205{ 206{
206 return p->des01.rx.frame_length; 207 /* The type-1 checksum offload engines append the checksum at
208 * the end of frame and the two bytes of checksum are added in
209 * the length.
210 * Adjust for that in the framelen for type-1 checksum offload
211 * engines. */
212 if (rx_coe_type == STMMAC_RX_COE_TYPE1)
213 return p->des01.rx.frame_length - 2;
214 else
215 return p->des01.rx.frame_length;
207} 216}
208 217
209const struct stmmac_desc_ops ndesc_ops = { 218const struct stmmac_desc_ops ndesc_ops = {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index b4b095fdcf29..b65d787fee69 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -56,8 +56,6 @@ struct stmmac_priv {
56 56
57 struct stmmac_extra_stats xstats; 57 struct stmmac_extra_stats xstats;
58 struct napi_struct napi; 58 struct napi_struct napi;
59
60 int rx_coe;
61 int no_csum_insertion; 59 int no_csum_insertion;
62 60
63 struct phy_device *phydev; 61 struct phy_device *phydev;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 860519c4d9a1..84f6b348ec70 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1282,7 +1282,8 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
1282 struct sk_buff *skb; 1282 struct sk_buff *skb;
1283 int frame_len; 1283 int frame_len;
1284 1284
1285 frame_len = priv->hw->desc->get_rx_frame_len(p); 1285 frame_len = priv->hw->desc->get_rx_frame_len(p,
1286 priv->plat->rx_coe);
1286 /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 1287 /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
1287 * Type frames (LLC/LLC-SNAP) */ 1288 * Type frames (LLC/LLC-SNAP) */
1288 if (unlikely(status != llc_snap)) 1289 if (unlikely(status != llc_snap))
@@ -1318,7 +1319,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
1318#endif 1319#endif
1319 skb->protocol = eth_type_trans(skb, priv->dev); 1320 skb->protocol = eth_type_trans(skb, priv->dev);
1320 1321
1321 if (unlikely(!priv->rx_coe)) { 1322 if (unlikely(!priv->plat->rx_coe)) {
1322 /* No RX COE for old mac10/100 devices */ 1323 /* No RX COE for old mac10/100 devices */
1323 skb_checksum_none_assert(skb); 1324 skb_checksum_none_assert(skb);
1324 netif_receive_skb(skb); 1325 netif_receive_skb(skb);
@@ -1465,8 +1466,10 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
1465{ 1466{
1466 struct stmmac_priv *priv = netdev_priv(dev); 1467 struct stmmac_priv *priv = netdev_priv(dev);
1467 1468
1468 if (!priv->rx_coe) 1469 if (priv->plat->rx_coe == STMMAC_RX_COE_NONE)
1469 features &= ~NETIF_F_RXCSUM; 1470 features &= ~NETIF_F_RXCSUM;
1471 else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1)
1472 features &= ~NETIF_F_IPV6_CSUM;
1470 if (!priv->plat->tx_coe) 1473 if (!priv->plat->tx_coe)
1471 features &= ~NETIF_F_ALL_CSUM; 1474 features &= ~NETIF_F_ALL_CSUM;
1472 1475
@@ -1769,17 +1772,32 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
1769 * register (if supported). 1772 * register (if supported).
1770 */ 1773 */
1771 priv->plat->enh_desc = priv->dma_cap.enh_desc; 1774 priv->plat->enh_desc = priv->dma_cap.enh_desc;
1772 priv->plat->tx_coe = priv->dma_cap.tx_coe;
1773 priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; 1775 priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
1776
1777 priv->plat->tx_coe = priv->dma_cap.tx_coe;
1778
1779 if (priv->dma_cap.rx_coe_type2)
1780 priv->plat->rx_coe = STMMAC_RX_COE_TYPE2;
1781 else if (priv->dma_cap.rx_coe_type1)
1782 priv->plat->rx_coe = STMMAC_RX_COE_TYPE1;
1783
1774 } else 1784 } else
1775 pr_info(" No HW DMA feature register supported"); 1785 pr_info(" No HW DMA feature register supported");
1776 1786
1777 /* Select the enhnaced/normal descriptor structures */ 1787 /* Select the enhnaced/normal descriptor structures */
1778 stmmac_selec_desc_mode(priv); 1788 stmmac_selec_desc_mode(priv);
1779 1789
1780 priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); 1790 /* Enable the IPC (Checksum Offload) and check if the feature has been
1781 if (priv->rx_coe) 1791 * enabled during the core configuration. */
1782 pr_info(" RX Checksum Offload Engine supported\n"); 1792 ret = priv->hw->mac->rx_ipc(priv->ioaddr);
1793 if (!ret) {
1794 pr_warning(" RX IPC Checksum Offload not configured.\n");
1795 priv->plat->rx_coe = STMMAC_RX_COE_NONE;
1796 }
1797
1798 if (priv->plat->rx_coe)
1799 pr_info(" RX Checksum Offload Engine supported (type %d)\n",
1800 priv->plat->rx_coe);
1783 if (priv->plat->tx_coe) 1801 if (priv->plat->tx_coe)
1784 pr_info(" TX Checksum insertion supported\n"); 1802 pr_info(" TX Checksum insertion supported\n");
1785 1803