diff options
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/common.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 27 |
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 | ||
450 | struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, | 451 | struct 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 | ||
2353 | static 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 | ||