1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-24 11:29:10 +00:00

Disable TX IP/TCP/UDP checksum offloading for RTL8168C/RTL8168CP.

Previously only TX IP checksum offloading was disabled but it's
reported that TX checksum offloading for UDP datagrams with IP
options also generates corrupted frames.  Reporter's controller is
RTL8168CP but I guess RTL8168C also have the same issue since it
shall share the same core.

Reported and tested by:	tuexen
This commit is contained in:
Pyun YongHyeon 2014-05-13 05:19:29 +00:00
parent c732cd1af1
commit 74a034464e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=265943

View File

@ -1619,16 +1619,18 @@ re_attach(device_t dev)
ifp->if_start = re_start; ifp->if_start = re_start;
/* /*
* RTL8168/8111C generates wrong IP checksummed frame if the * RTL8168/8111C generates wrong IP checksummed frame if the
* packet has IP options so disable TX IP checksum offloading. * packet has IP options so disable TX checksum offloading.
*/ */
if (sc->rl_hwrev->rl_rev == RL_HWREV_8168C || if (sc->rl_hwrev->rl_rev == RL_HWREV_8168C ||
sc->rl_hwrev->rl_rev == RL_HWREV_8168C_SPIN2 || sc->rl_hwrev->rl_rev == RL_HWREV_8168C_SPIN2 ||
sc->rl_hwrev->rl_rev == RL_HWREV_8168CP) sc->rl_hwrev->rl_rev == RL_HWREV_8168CP) {
ifp->if_hwassist = CSUM_TCP | CSUM_UDP; ifp->if_hwassist = 0;
else ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_TSO4;
} else {
ifp->if_hwassist = CSUM_IP | CSUM_TCP | CSUM_UDP; ifp->if_hwassist = CSUM_IP | CSUM_TCP | CSUM_UDP;
ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4;
}
ifp->if_hwassist |= CSUM_TSO; ifp->if_hwassist |= CSUM_TSO;
ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4;
ifp->if_capenable = ifp->if_capabilities; ifp->if_capenable = ifp->if_capabilities;
ifp->if_init = re_init; ifp->if_init = re_init;
IFQ_SET_MAXLEN(&ifp->if_snd, RL_IFQ_MAXLEN); IFQ_SET_MAXLEN(&ifp->if_snd, RL_IFQ_MAXLEN);
@ -3364,7 +3366,6 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
struct rl_softc *sc = ifp->if_softc; struct rl_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *) data; struct ifreq *ifr = (struct ifreq *) data;
struct mii_data *mii; struct mii_data *mii;
uint32_t rev;
int error = 0; int error = 0;
switch (command) { switch (command) {
@ -3453,15 +3454,9 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if ((mask & IFCAP_TXCSUM) != 0 && if ((mask & IFCAP_TXCSUM) != 0 &&
(ifp->if_capabilities & IFCAP_TXCSUM) != 0) { (ifp->if_capabilities & IFCAP_TXCSUM) != 0) {
ifp->if_capenable ^= IFCAP_TXCSUM; ifp->if_capenable ^= IFCAP_TXCSUM;
if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) { if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
rev = sc->rl_hwrev->rl_rev; ifp->if_hwassist |= RE_CSUM_FEATURES;
if (rev == RL_HWREV_8168C || else
rev == RL_HWREV_8168C_SPIN2 ||
rev == RL_HWREV_8168CP)
ifp->if_hwassist |= CSUM_TCP | CSUM_UDP;
else
ifp->if_hwassist |= RE_CSUM_FEATURES;
} else
ifp->if_hwassist &= ~RE_CSUM_FEATURES; ifp->if_hwassist &= ~RE_CSUM_FEATURES;
reinit = 1; reinit = 1;
} }