re: Disable IP header checksum offloading on 8168C/8168CP
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 29 Mar 2013 02:22:16 +0000 (10:22 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 29 Mar 2013 02:24:55 +0000 (10:24 +0800)
These chips will generate wrong IP header checksum if IP options exist.

Obtained-from: FreeBSD

sys/dev/netif/re/if_re.c
sys/dev/netif/re/if_revar.h

index 1eaf5bf..04902c6 100644 (file)
 #include <dev/netif/re/if_rereg.h>
 #include <dev/netif/re/if_revar.h>
 
-#define RE_CSUM_FEATURES    (CSUM_IP | CSUM_TCP | CSUM_UDP)
-
 /*
  * Various supported device vendors/types and their names.
  */
@@ -1602,10 +1600,18 @@ re_attach(device_t dev)
                ifp->if_capabilities |= IFCAP_HWCSUM;
 
        ifp->if_capenable = ifp->if_capabilities;
-       if (ifp->if_capabilities & IFCAP_HWCSUM)
-               ifp->if_hwassist = RE_CSUM_FEATURES;
-       else
-               ifp->if_hwassist = 0;
+       if (ifp->if_capabilities & IFCAP_HWCSUM) {
+               /*
+                * RTL8168/8111C generates wrong IP checksummed frame if the
+                * packet has IP options so disable TX IP checksum offloading.
+                */ 
+               if (sc->re_hwrev == RE_HWREV_8168CP ||
+                   sc->re_hwrev == RE_HWREV_8168C)
+                       sc->re_hwassist = CSUM_TCP | CSUM_UDP;
+               else
+                       sc->re_hwassist = CSUM_IP | CSUM_TCP | CSUM_UDP;
+       }
+       ifp->if_hwassist = sc->re_hwassist;
 
        /*
         * Call MI attach routine.
@@ -2814,7 +2820,7 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
 
                if (mask & IFCAP_HWCSUM) {
                        if (ifp->if_capenable & IFCAP_TXCSUM)
-                               ifp->if_hwassist = RE_CSUM_FEATURES;
+                               ifp->if_hwassist = sc->re_hwassist;
                        else
                                ifp->if_hwassist = 0;
                }
index b416a2d..44efa9e 100644 (file)
@@ -193,6 +193,7 @@ struct re_softc {
        uint32_t                re_flags;       /* see RE_F_ */
        int                     re_if_flags;    /* saved ifnet.if_flags */
 
+       u_long                  re_hwassist;
        struct sysctl_ctx_list  re_sysctl_ctx;
        struct sysctl_oid       *re_sysctl_tree;
        uint16_t                re_intrs;