diff options
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/common.h | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 32 |
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 { | |||
261 | struct stmmac_ops { | 261 | struct 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 | ||
49 | static int dwmac1000_rx_coe_supported(void __iomem *ioaddr) | 49 | static 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 | ||
212 | static const struct stmmac_ops dwmac1000_ops = { | 212 | static 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 | ||
46 | static int dwmac100_rx_coe_supported(void __iomem *ioaddr) | ||
47 | { | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | static void dwmac100_dump_mac_regs(void __iomem *ioaddr) | 46 | static 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 | ||
70 | static int dwmac100_rx_ipc_enable(void __iomem *ioaddr) | ||
71 | { | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static void dwmac100_irq_status(void __iomem *ioaddr) | 75 | static 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 | ||
161 | static const struct stmmac_ops dwmac100_ops = { | 161 | static 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 | ||
312 | static int enh_desc_get_rx_frame_len(struct dma_desc *p) | 313 | static 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 | ||
317 | const struct stmmac_desc_ops enh_desc_ops = { | 326 | const 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 | ||
204 | static int ndesc_get_rx_frame_len(struct dma_desc *p) | 205 | static 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 | ||
209 | const struct stmmac_desc_ops ndesc_ops = { | 218 | const 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 | ||