svn commit: r218289 - head/sys/dev/re

Pyun YongHyeon yongari at FreeBSD.org
Fri Feb 4 17:49:55 UTC 2011


Author: yongari
Date: Fri Feb  4 17:49:55 2011
New Revision: 218289
URL: http://svn.freebsd.org/changeset/base/218289

Log:
  Disable TX IP checksum offloading for RTL8168C controllers.  The
  controller in question generates frames with bad IP checksum value
  if packets contain IP options.  For instance, packets generated by
  ping(8) with record route option have wrong IP checksum value. The
  controller correctly computes checksum for normal TCP/UDP packets
  though.
  There are two known RTL8168/8111C variants in market and the issue
  I observed happened on RL_HWREV_8168C_SPIN2. I'm not sure
  RL_HWREV_8168C also has the same issue but it would be better to
  assume it has the same issue since they shall share same core.
  RTL8102E which is supposed to be released at the time of
  RTL8168/8111C announcement does not have the issue.
  
  Tested by:	Konstantin V. Krotov ( kkv <> insysnet dot ru )

Modified:
  head/sys/dev/re/if_re.c

Modified: head/sys/dev/re/if_re.c
==============================================================================
--- head/sys/dev/re/if_re.c	Fri Feb  4 17:26:44 2011	(r218288)
+++ head/sys/dev/re/if_re.c	Fri Feb  4 17:49:55 2011	(r218289)
@@ -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 comma
 	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 comma
 		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;
 		}


More information about the svn-src-head mailing list