aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c27
3 files changed, 31 insertions, 3 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index e3b81cdc94b2..593e6c4144a7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -445,6 +445,7 @@ struct mac_device_info {
445 int multicast_filter_bins; 445 int multicast_filter_bins;
446 int unicast_filter_entries; 446 int unicast_filter_entries;
447 int mcast_bits_log2; 447 int mcast_bits_log2;
448 unsigned int rx_csum;
448}; 449};
449 450
450struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, 451struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index d8ef18786a1c..5efe60ea6526 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -58,7 +58,11 @@ static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw)
58 void __iomem *ioaddr = hw->pcsr; 58 void __iomem *ioaddr = hw->pcsr;
59 u32 value = readl(ioaddr + GMAC_CONTROL); 59 u32 value = readl(ioaddr + GMAC_CONTROL);
60 60
61 value |= GMAC_CONTROL_IPC; 61 if (hw->rx_csum)
62 value |= GMAC_CONTROL_IPC;
63 else
64 value &= ~GMAC_CONTROL_IPC;
65
62 writel(value, ioaddr + GMAC_CONTROL); 66 writel(value, ioaddr + GMAC_CONTROL);
63 67
64 value = readl(ioaddr + GMAC_CONTROL); 68 value = readl(ioaddr + GMAC_CONTROL);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 3d3db16c97d4..0ed8ac81238b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1673,6 +1673,7 @@ static int stmmac_hw_setup(struct net_device *dev)
1673 if (!ret) { 1673 if (!ret) {
1674 pr_warn(" RX IPC Checksum Offload disabled\n"); 1674 pr_warn(" RX IPC Checksum Offload disabled\n");
1675 priv->plat->rx_coe = STMMAC_RX_COE_NONE; 1675 priv->plat->rx_coe = STMMAC_RX_COE_NONE;
1676 priv->hw->rx_csum = 0;
1676 } 1677 }
1677 1678
1678 /* Enable the MAC Rx/Tx */ 1679 /* Enable the MAC Rx/Tx */
@@ -2111,7 +2112,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
2111 unsigned int entry = priv->cur_rx % rxsize; 2112 unsigned int entry = priv->cur_rx % rxsize;
2112 unsigned int next_entry; 2113 unsigned int next_entry;
2113 unsigned int count = 0; 2114 unsigned int count = 0;
2114 int coe = priv->plat->rx_coe; 2115 int coe = priv->hw->rx_csum;
2115 2116
2116 if (netif_msg_rx_status(priv)) { 2117 if (netif_msg_rx_status(priv)) {
2117 pr_debug("%s: descriptor ring:\n", __func__); 2118 pr_debug("%s: descriptor ring:\n", __func__);
@@ -2334,6 +2335,7 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
2334 features &= ~NETIF_F_RXCSUM; 2335 features &= ~NETIF_F_RXCSUM;
2335 else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1) 2336 else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1)
2336 features &= ~NETIF_F_IPV6_CSUM; 2337 features &= ~NETIF_F_IPV6_CSUM;
2338
2337 if (!priv->plat->tx_coe) 2339 if (!priv->plat->tx_coe)
2338 features &= ~NETIF_F_ALL_CSUM; 2340 features &= ~NETIF_F_ALL_CSUM;
2339 2341
@@ -2348,6 +2350,24 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
2348 return features; 2350 return features;
2349} 2351}
2350 2352
2353static int stmmac_set_features(struct net_device *netdev,
2354 netdev_features_t features)
2355{
2356 struct stmmac_priv *priv = netdev_priv(netdev);
2357
2358 /* Keep the COE Type in case of csum is supporting */
2359 if (features & NETIF_F_RXCSUM)
2360 priv->hw->rx_csum = priv->plat->rx_coe;
2361 else
2362 priv->hw->rx_csum = 0;
2363 /* No check needed because rx_coe has been set before and it will be
2364 * fixed in case of issue.
2365 */
2366 priv->hw->mac->rx_ipc(priv->hw);
2367
2368 return 0;
2369}
2370
2351/** 2371/**
2352 * stmmac_interrupt - main ISR 2372 * stmmac_interrupt - main ISR
2353 * @irq: interrupt number. 2373 * @irq: interrupt number.
@@ -2628,6 +2648,7 @@ static const struct net_device_ops stmmac_netdev_ops = {
2628 .ndo_stop = stmmac_release, 2648 .ndo_stop = stmmac_release,
2629 .ndo_change_mtu = stmmac_change_mtu, 2649 .ndo_change_mtu = stmmac_change_mtu,
2630 .ndo_fix_features = stmmac_fix_features, 2650 .ndo_fix_features = stmmac_fix_features,
2651 .ndo_set_features = stmmac_set_features,
2631 .ndo_set_rx_mode = stmmac_set_rx_mode, 2652 .ndo_set_rx_mode = stmmac_set_rx_mode,
2632 .ndo_tx_timeout = stmmac_tx_timeout, 2653 .ndo_tx_timeout = stmmac_tx_timeout,
2633 .ndo_do_ioctl = stmmac_ioctl, 2654 .ndo_do_ioctl = stmmac_ioctl,
@@ -2704,9 +2725,11 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
2704 /* To use alternate (extended) or normal descriptor structures */ 2725 /* To use alternate (extended) or normal descriptor structures */
2705 stmmac_selec_desc_mode(priv); 2726 stmmac_selec_desc_mode(priv);
2706 2727
2707 if (priv->plat->rx_coe) 2728 if (priv->plat->rx_coe) {
2729 priv->hw->rx_csum = priv->plat->rx_coe;
2708 pr_info(" RX Checksum Offload Engine supported (type %d)\n", 2730 pr_info(" RX Checksum Offload Engine supported (type %d)\n",
2709 priv->plat->rx_coe); 2731 priv->plat->rx_coe);
2732 }
2710 if (priv->plat->tx_coe) 2733 if (priv->plat->tx_coe)
2711 pr_info(" TX Checksum insertion supported\n"); 2734 pr_info(" TX Checksum insertion supported\n");
2712 2735