diff options
author | Simon Guinot <simon.guinot@sequanux.org> | 2015-06-30 10:20:22 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-07-10 12:49:33 -0400 |
commit | bfa06e6258be556d44aad030fe1babeed4f92240 (patch) | |
tree | baa8b18c6801dc038b15f3039da7fabdc1e6ef3f /drivers/net/ethernet | |
parent | 5c40e8bf8f8239a5e1fe85ceeb8c6d930f28ef8e (diff) |
net: mvneta: disable IP checksum with jumbo frames for Armada 370
[ Upstream commit b65657fc240ae6c1d2a1e62db9a0e61ac9631d7a ]
The Ethernet controller found in the Armada 370, 380 and 385 SoCs don't
support TCP/IP checksumming with frame sizes larger than 1600 bytes.
This patch fixes the issue by disabling the features NETIF_F_IP_CSUM and
NETIF_F_TSO for the Armada 370 and compatibles SoCs when the MTU is set
to a value greater than 1600 bytes.
Signed-off-by: Simon Guinot <simon.guinot@sequanux.org>
Fixes: c5aff18204da ("net: mvneta: driver for Marvell Armada 370/XP network unit")
Cc: <stable@vger.kernel.org> # v3.8+
Acked-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/marvell/mvneta.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 4fb27eac6ce5..74d0389bf233 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c | |||
@@ -310,6 +310,7 @@ struct mvneta_port { | |||
310 | unsigned int link; | 310 | unsigned int link; |
311 | unsigned int duplex; | 311 | unsigned int duplex; |
312 | unsigned int speed; | 312 | unsigned int speed; |
313 | unsigned int tx_csum_limit; | ||
313 | int use_inband_status:1; | 314 | int use_inband_status:1; |
314 | }; | 315 | }; |
315 | 316 | ||
@@ -2508,8 +2509,10 @@ static int mvneta_change_mtu(struct net_device *dev, int mtu) | |||
2508 | 2509 | ||
2509 | dev->mtu = mtu; | 2510 | dev->mtu = mtu; |
2510 | 2511 | ||
2511 | if (!netif_running(dev)) | 2512 | if (!netif_running(dev)) { |
2513 | netdev_update_features(dev); | ||
2512 | return 0; | 2514 | return 0; |
2515 | } | ||
2513 | 2516 | ||
2514 | /* The interface is running, so we have to force a | 2517 | /* The interface is running, so we have to force a |
2515 | * reallocation of the queues | 2518 | * reallocation of the queues |
@@ -2538,9 +2541,26 @@ static int mvneta_change_mtu(struct net_device *dev, int mtu) | |||
2538 | mvneta_start_dev(pp); | 2541 | mvneta_start_dev(pp); |
2539 | mvneta_port_up(pp); | 2542 | mvneta_port_up(pp); |
2540 | 2543 | ||
2544 | netdev_update_features(dev); | ||
2545 | |||
2541 | return 0; | 2546 | return 0; |
2542 | } | 2547 | } |
2543 | 2548 | ||
2549 | static netdev_features_t mvneta_fix_features(struct net_device *dev, | ||
2550 | netdev_features_t features) | ||
2551 | { | ||
2552 | struct mvneta_port *pp = netdev_priv(dev); | ||
2553 | |||
2554 | if (pp->tx_csum_limit && dev->mtu > pp->tx_csum_limit) { | ||
2555 | features &= ~(NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
2556 | netdev_info(dev, | ||
2557 | "Disable IP checksum for MTU greater than %dB\n", | ||
2558 | pp->tx_csum_limit); | ||
2559 | } | ||
2560 | |||
2561 | return features; | ||
2562 | } | ||
2563 | |||
2544 | /* Get mac address */ | 2564 | /* Get mac address */ |
2545 | static void mvneta_get_mac_addr(struct mvneta_port *pp, unsigned char *addr) | 2565 | static void mvneta_get_mac_addr(struct mvneta_port *pp, unsigned char *addr) |
2546 | { | 2566 | { |
@@ -2862,6 +2882,7 @@ static const struct net_device_ops mvneta_netdev_ops = { | |||
2862 | .ndo_set_rx_mode = mvneta_set_rx_mode, | 2882 | .ndo_set_rx_mode = mvneta_set_rx_mode, |
2863 | .ndo_set_mac_address = mvneta_set_mac_addr, | 2883 | .ndo_set_mac_address = mvneta_set_mac_addr, |
2864 | .ndo_change_mtu = mvneta_change_mtu, | 2884 | .ndo_change_mtu = mvneta_change_mtu, |
2885 | .ndo_fix_features = mvneta_fix_features, | ||
2865 | .ndo_get_stats64 = mvneta_get_stats64, | 2886 | .ndo_get_stats64 = mvneta_get_stats64, |
2866 | .ndo_do_ioctl = mvneta_ioctl, | 2887 | .ndo_do_ioctl = mvneta_ioctl, |
2867 | }; | 2888 | }; |
@@ -3107,6 +3128,9 @@ static int mvneta_probe(struct platform_device *pdev) | |||
3107 | } | 3128 | } |
3108 | } | 3129 | } |
3109 | 3130 | ||
3131 | if (of_device_is_compatible(dn, "marvell,armada-370-neta")) | ||
3132 | pp->tx_csum_limit = 1600; | ||
3133 | |||
3110 | pp->tx_ring_size = MVNETA_MAX_TXD; | 3134 | pp->tx_ring_size = MVNETA_MAX_TXD; |
3111 | pp->rx_ring_size = MVNETA_MAX_RXD; | 3135 | pp->rx_ring_size = MVNETA_MAX_RXD; |
3112 | 3136 | ||