net: lan78xx: Use s/w csum check on VLANs without tag stripping
authorDave Stevenson <dave.stevenson@raspberrypi.org>
Mon, 25 Jun 2018 14:07:15 +0000 (15:07 +0100)
committerDavid S. Miller <davem@davemloft.net>
Tue, 26 Jun 2018 13:53:29 +0000 (22:53 +0900)
Observations of VLANs dropping packets due to invalid
checksums when not offloading VLAN tag receive.
With VLAN tag stripping enabled no issue is observed.

Drop back to s/w checksums if VLAN offload is disabled.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/usb/lan78xx.c

index 28da296f8cf7cfd1f135ec24e169c36fe4825b72..2e4130746c40caf6a2a5dbf51fd0ece84fb6da85 100644 (file)
@@ -3052,8 +3052,13 @@ static void lan78xx_rx_csum_offload(struct lan78xx_net *dev,
                                    struct sk_buff *skb,
                                    u32 rx_cmd_a, u32 rx_cmd_b)
 {
+       /* HW Checksum offload appears to be flawed if used when not stripping
+        * VLAN headers. Drop back to S/W checksums under these conditions.
+        */
        if (!(dev->net->features & NETIF_F_RXCSUM) ||
-           unlikely(rx_cmd_a & RX_CMD_A_ICSM_)) {
+           unlikely(rx_cmd_a & RX_CMD_A_ICSM_) ||
+           ((rx_cmd_a & RX_CMD_A_FVTG_) &&
+            !(dev->net->features & NETIF_F_HW_VLAN_CTAG_RX))) {
                skb->ip_summed = CHECKSUM_NONE;
        } else {
                skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT_));