diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index 9b889e7d1d68..8c7d29506c4d 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -1527,7 +1527,16 @@ re_attach(device_t dev) ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = re_ioctl; ifp->if_start = re_start; - ifp->if_hwassist = RE_CSUM_FEATURES | CSUM_TSO; + /* + * RTL8168/8111C generates wrong IP checksummed frame if the + * packet has IP options so disable TX IP checksum offloading. + */ + if (sc->rl_hwrev->rl_rev == RL_HWREV_8168C || + sc->rl_hwrev->rl_rev == RL_HWREV_8168C_SPIN2) + ifp->if_hwassist = CSUM_TCP | CSUM_UDP; + else + ifp->if_hwassist = CSUM_IP | CSUM_TCP | CSUM_UDP; + ifp->if_hwassist |= CSUM_TSO; ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4; ifp->if_capenable = ifp->if_capabilities; ifp->if_init = re_init; @@ -3209,6 +3218,7 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data) struct rl_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; + uint32_t rev; int error = 0; switch (command) { @@ -3294,9 +3304,14 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if ((mask & IFCAP_TXCSUM) != 0 && (ifp->if_capabilities & IFCAP_TXCSUM) != 0) { ifp->if_capenable ^= IFCAP_TXCSUM; - if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) - ifp->if_hwassist |= RE_CSUM_FEATURES; - else + if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) { + rev = sc->rl_hwrev->rl_rev; + if (rev == RL_HWREV_8168C || + rev == RL_HWREV_8168C_SPIN2) + ifp->if_hwassist |= CSUM_TCP | CSUM_UDP; + else + ifp->if_hwassist |= RE_CSUM_FEATURES; + } else ifp->if_hwassist &= ~RE_CSUM_FEATURES; reinit = 1; }