diff options
author | Giuseppe CAVALLARO <peppe.cavallaro@st.com> | 2014-09-01 03:17:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-02 00:51:29 -0400 |
commit | d2afb5bdffde3da175b9ced66f70a4b453103d71 (patch) | |
tree | 250714e39756cc16c9951c50b1c3347ff9f91721 /drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |
parent | 8a3cf39b72d12001d4cc67b69233a986921f190d (diff) |
stmmac: fix the rx csum feature
For new GMACs it is possible to turn-on/off the COE.
In the current driver, when disabled the Rx-checksum
via ethtool, the tool reported that csum was disabled
but the HW continued to set the IPC. Indeed this is
because the fix_features allows this. So the patch
fixes this problem by adding the set_features.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_main.c')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 27 |
1 files changed, 25 insertions, 2 deletions
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 | ||