Module Name:    src
Committed By:   tsutsui
Date:           Sun May 31 05:10:47 UTC 2009

Modified Files:
        src/sys/dev/ic: rtl8169.c

Log Message:
Two fixes for RX hwcsum on DESCV2 chips:
 * On checking TCPv4/UDPv4 RX checksum on DESCV2 chips, also check
   RE_RDESC_VLANCTL_IPV4 bit because those DESCV2 chips may also recognize
   IPv6 packets and set RE_PROTOID_TCPIP or RE_PROTOID_UDPIP bits for
   TCPv6/UDPv6 packets.  This may fix PR kern/40605.
 * According to Realtek's Linux driver, DESCV2 chips don't set RE_PROTOID_IP
   for non-TCP/UDP IP packets (set only RE_RDESC_VLANCTL_IPV[46]) so
   remove PROTOID check for IPv4 RX cheksum on DESCV2 chips.


To generate a diff of this commit:
cvs rdiff -u -r1.120 -r1.121 src/sys/dev/ic/rtl8169.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ic/rtl8169.c
diff -u src/sys/dev/ic/rtl8169.c:1.120 src/sys/dev/ic/rtl8169.c:1.121
--- src/sys/dev/ic/rtl8169.c:1.120	Tue May 12 14:25:18 2009
+++ src/sys/dev/ic/rtl8169.c	Sun May 31 05:10:47 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtl8169.c,v 1.120 2009/05/12 14:25:18 cegger Exp $	*/
+/*	$NetBSD: rtl8169.c,v 1.121 2009/05/31 05:10:47 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998-2003
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtl8169.c,v 1.120 2009/05/12 14:25:18 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtl8169.c,v 1.121 2009/05/31 05:10:47 tsutsui Exp $");
 /* $FreeBSD: /repoman/r/ncvs/src/sys/dev/re/if_re.c,v 1.20 2004/04/11 20:34:08 ru Exp $ */
 
 /*
@@ -1251,25 +1251,49 @@
 		m->m_pkthdr.rcvif = ifp;
 
 		/* Do RX checksumming */
-
-		/* Check IP header checksum */
-		if ((rxstat & RE_RDESC_STAT_PROTOID) != 0 &&
-		    ((sc->sc_quirk & RTKQ_DESCV2) == 0 ||
-		     (rxvlan & RE_RDESC_VLANCTL_IPV4) != 0)) {
-			m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
-			if (rxstat & RE_RDESC_STAT_IPSUMBAD)
-				m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;
-		}
-
-		/* Check TCP/UDP checksum */
-		if (RE_TCPPKT(rxstat)) {
-			m->m_pkthdr.csum_flags |= M_CSUM_TCPv4;
-			if (rxstat & RE_RDESC_STAT_TCPSUMBAD)
-				m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
-		} else if (RE_UDPPKT(rxstat)) {
-			m->m_pkthdr.csum_flags |= M_CSUM_UDPv4;
-			if (rxstat & RE_RDESC_STAT_UDPSUMBAD)
-				m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
+		if ((sc->sc_quirk & RTKQ_DESCV2) == 0) {
+			/* Check IP header checksum */
+			if ((rxstat & RE_RDESC_STAT_PROTOID) != 0) {
+				m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
+				if (rxstat & RE_RDESC_STAT_IPSUMBAD)
+					m->m_pkthdr.csum_flags |=
+					    M_CSUM_IPv4_BAD;
+
+				/* Check TCP/UDP checksum */
+				if (RE_TCPPKT(rxstat)) {
+					m->m_pkthdr.csum_flags |= M_CSUM_TCPv4;
+					if (rxstat & RE_RDESC_STAT_TCPSUMBAD)
+						m->m_pkthdr.csum_flags |=
+						    M_CSUM_TCP_UDP_BAD;
+				} else if (RE_UDPPKT(rxstat)) {
+					m->m_pkthdr.csum_flags |= M_CSUM_UDPv4;
+					if (rxstat & RE_RDESC_STAT_UDPSUMBAD)
+						m->m_pkthdr.csum_flags |=
+						    M_CSUM_TCP_UDP_BAD;
+				}
+			}
+		} else {
+			/* Check IPv4 header checksum */
+			if ((rxvlan & RE_RDESC_VLANCTL_IPV4) != 0) {
+				m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
+				if (rxstat & RE_RDESC_STAT_IPSUMBAD)
+					m->m_pkthdr.csum_flags |=
+					    M_CSUM_IPv4_BAD;
+
+				/* Check TCPv4/UDPv4 checksum */
+				if (RE_TCPPKT(rxstat)) {
+					m->m_pkthdr.csum_flags |= M_CSUM_TCPv4;
+					if (rxstat & RE_RDESC_STAT_TCPSUMBAD)
+						m->m_pkthdr.csum_flags |=
+						    M_CSUM_TCP_UDP_BAD;
+				} else if (RE_UDPPKT(rxstat)) {
+					m->m_pkthdr.csum_flags |= M_CSUM_UDPv4;
+					if (rxstat & RE_RDESC_STAT_UDPSUMBAD)
+						m->m_pkthdr.csum_flags |=
+						    M_CSUM_TCP_UDP_BAD;
+				}
+			}
+			/* XXX Check TCPv6/UDPv6 checksum? */
 		}
 
 		if (rxvlan & RE_RDESC_VLANCTL_TAG) {

Reply via email to