Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Apr 2010 18:02:12 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r207236 - in stable/8/sys/dev: age alc ale fxp msk nfe
Message-ID:  <201004261802.o3QI2CmO058308@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Mon Apr 26 18:02:12 2010
New Revision: 207236
URL: http://svn.freebsd.org/changeset/base/207236

Log:
  MFC r206876:
    With r206844, CSUM_TCP is also set for CSUM_TSO case. Modify
    drivers to take into account for the change. Basically CSUM_TSO
    should be checked before checking CSUM_TCP.

Modified:
  stable/8/sys/dev/age/if_age.c
  stable/8/sys/dev/alc/if_alc.c
  stable/8/sys/dev/ale/if_ale.c
  stable/8/sys/dev/fxp/if_fxp.c
  stable/8/sys/dev/msk/if_msk.c
  stable/8/sys/dev/nfe/if_nfe.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/geom/sched/   (props changed)

Modified: stable/8/sys/dev/age/if_age.c
==============================================================================
--- stable/8/sys/dev/age/if_age.c	Mon Apr 26 17:57:08 2010	(r207235)
+++ stable/8/sys/dev/age/if_age.c	Mon Apr 26 18:02:12 2010	(r207236)
@@ -1629,22 +1629,8 @@ age_encap(struct age_softc *sc, struct m
 	}
 
 	m = *m_head;
-	/* Configure Tx IP/TCP/UDP checksum offload. */
-	if ((m->m_pkthdr.csum_flags & AGE_CSUM_FEATURES) != 0) {
-		cflags |= AGE_TD_CSUM;
-		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
-			cflags |= AGE_TD_TCPCSUM;
-		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
-			cflags |= AGE_TD_UDPCSUM;
-		/* Set checksum start offset. */
-		cflags |= (poff << AGE_TD_CSUM_PLOADOFFSET_SHIFT);
-		/* Set checksum insertion position of TCP/UDP. */
-		cflags |= ((poff + m->m_pkthdr.csum_data) <<
-		    AGE_TD_CSUM_XSUMOFFSET_SHIFT);
-	}
-
-	/* Configure TSO. */
 	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+		/* Configure TSO. */
 		if (poff + (tcp->th_off << 2) == m->m_pkthdr.len) {
 			/* Not TSO but IP/TCP checksum offload. */
 			cflags |= AGE_TD_IPCSUM | AGE_TD_TCPCSUM;
@@ -1660,6 +1646,18 @@ age_encap(struct age_softc *sc, struct m
 		/* Set IP/TCP header size. */
 		cflags |= ip->ip_hl << AGE_TD_IPHDR_LEN_SHIFT;
 		cflags |= tcp->th_off << AGE_TD_TSO_TCPHDR_LEN_SHIFT;
+	} else if ((m->m_pkthdr.csum_flags & AGE_CSUM_FEATURES) != 0) {
+		/* Configure Tx IP/TCP/UDP checksum offload. */
+		cflags |= AGE_TD_CSUM;
+		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
+			cflags |= AGE_TD_TCPCSUM;
+		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
+			cflags |= AGE_TD_UDPCSUM;
+		/* Set checksum start offset. */
+		cflags |= (poff << AGE_TD_CSUM_PLOADOFFSET_SHIFT);
+		/* Set checksum insertion position of TCP/UDP. */
+		cflags |= ((poff + m->m_pkthdr.csum_data) <<
+		    AGE_TD_CSUM_XSUMOFFSET_SHIFT);
 	}
 
 	/* Configure VLAN hardware tag insertion. */

Modified: stable/8/sys/dev/alc/if_alc.c
==============================================================================
--- stable/8/sys/dev/alc/if_alc.c	Mon Apr 26 17:57:08 2010	(r207235)
+++ stable/8/sys/dev/alc/if_alc.c	Mon Apr 26 18:02:12 2010	(r207236)
@@ -1908,28 +1908,7 @@ alc_encap(struct alc_softc *sc, struct m
 		vtag = (vtag << TD_VLAN_SHIFT) & TD_VLAN_MASK;
 		cflags |= TD_INS_VLAN_TAG;
 	}
-	/* Configure Tx checksum offload. */
-	if ((m->m_pkthdr.csum_flags & ALC_CSUM_FEATURES) != 0) {
-#ifdef ALC_USE_CUSTOM_CSUM
-		cflags |= TD_CUSTOM_CSUM;
-		/* Set checksum start offset. */
-		cflags |= ((poff >> 1) << TD_PLOAD_OFFSET_SHIFT) &
-		    TD_PLOAD_OFFSET_MASK;
-		/* Set checksum insertion position of TCP/UDP. */
-		cflags |= (((poff + m->m_pkthdr.csum_data) >> 1) <<
-		    TD_CUSTOM_CSUM_OFFSET_SHIFT) & TD_CUSTOM_CSUM_OFFSET_MASK;
-#else
-		if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
-			cflags |= TD_IPCSUM;
-		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
-			cflags |= TD_TCPCSUM;
-		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
-			cflags |= TD_UDPCSUM;
-		/* Set TCP/UDP header offset. */
-		cflags |= (poff << TD_L4HDR_OFFSET_SHIFT) &
-		    TD_L4HDR_OFFSET_MASK;
-#endif
-	} else if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
 		/* Request TSO and set MSS. */
 		cflags |= TD_TSO | TD_TSO_DESCV1;
 		cflags |= ((uint32_t)m->m_pkthdr.tso_segsz << TD_MSS_SHIFT) &
@@ -1961,6 +1940,27 @@ alc_encap(struct alc_softc *sc, struct m
 		}
 		/* Handle remaining fragments. */
 		idx = 1;
+	} else if ((m->m_pkthdr.csum_flags & ALC_CSUM_FEATURES) != 0) {
+		/* Configure Tx checksum offload. */
+#ifdef ALC_USE_CUSTOM_CSUM
+		cflags |= TD_CUSTOM_CSUM;
+		/* Set checksum start offset. */
+		cflags |= ((poff >> 1) << TD_PLOAD_OFFSET_SHIFT) &
+		    TD_PLOAD_OFFSET_MASK;
+		/* Set checksum insertion position of TCP/UDP. */
+		cflags |= (((poff + m->m_pkthdr.csum_data) >> 1) <<
+		    TD_CUSTOM_CSUM_OFFSET_SHIFT) & TD_CUSTOM_CSUM_OFFSET_MASK;
+#else
+		if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
+			cflags |= TD_IPCSUM;
+		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
+			cflags |= TD_TCPCSUM;
+		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
+			cflags |= TD_UDPCSUM;
+		/* Set TCP/UDP header offset. */
+		cflags |= (poff << TD_L4HDR_OFFSET_SHIFT) &
+		    TD_L4HDR_OFFSET_MASK;
+#endif
 	}
 	for (; idx < nsegs; idx++) {
 		desc = &sc->alc_rdata.alc_tx_ring[prod];

Modified: stable/8/sys/dev/ale/if_ale.c
==============================================================================
--- stable/8/sys/dev/ale/if_ale.c	Mon Apr 26 17:57:08 2010	(r207235)
+++ stable/8/sys/dev/ale/if_ale.c	Mon Apr 26 18:02:12 2010	(r207236)
@@ -1737,8 +1737,14 @@ ale_encap(struct ale_softc *sc, struct m
 	bus_dmamap_sync(sc->ale_cdata.ale_tx_tag, map, BUS_DMASYNC_PREWRITE);
 
 	m = *m_head;
-	/* Configure Tx checksum offload. */
-	if ((m->m_pkthdr.csum_flags & ALE_CSUM_FEATURES) != 0) {
+	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+		/* Request TSO and set MSS. */
+		cflags |= ALE_TD_TSO;
+		cflags |= ((uint32_t)m->m_pkthdr.tso_segsz << ALE_TD_MSS_SHIFT);
+		/* Set IP/TCP header size. */
+		cflags |= ip->ip_hl << ALE_TD_IPHDR_LEN_SHIFT;
+		cflags |= tcp->th_off << ALE_TD_TCPHDR_LEN_SHIFT;
+	} else if ((m->m_pkthdr.csum_flags & ALE_CSUM_FEATURES) != 0) {
 		/*
 		 * AR81xx supports Tx custom checksum offload feature
 		 * that offloads single 16bit checksum computation.
@@ -1769,15 +1775,6 @@ ale_encap(struct ale_softc *sc, struct m
 		    ALE_TD_CSUM_XSUMOFFSET_SHIFT);
 	}
 
-	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
-		/* Request TSO and set MSS. */
-		cflags |= ALE_TD_TSO;
-		cflags |= ((uint32_t)m->m_pkthdr.tso_segsz << ALE_TD_MSS_SHIFT);
-		/* Set IP/TCP header size. */
-		cflags |= ip->ip_hl << ALE_TD_IPHDR_LEN_SHIFT;
-		cflags |= tcp->th_off << ALE_TD_TCPHDR_LEN_SHIFT;
-	}
-
 	/* Configure VLAN hardware tag insertion. */
 	if ((m->m_flags & M_VLANTAG) != 0) {
 		vtag = ALE_TX_VLAN_TAG(m->m_pkthdr.ether_vtag);

Modified: stable/8/sys/dev/fxp/if_fxp.c
==============================================================================
--- stable/8/sys/dev/fxp/if_fxp.c	Mon Apr 26 17:57:08 2010	(r207235)
+++ stable/8/sys/dev/fxp/if_fxp.c	Mon Apr 26 18:02:12 2010	(r207236)
@@ -1417,60 +1417,6 @@ fxp_encap(struct fxp_softc *sc, struct m
 		    FXP_IPCB_HARDWAREPARSING_ENABLE;
 
 	m = *m_head;
-	/*
-	 * Deal with TCP/IP checksum offload. Note that
-	 * in order for TCP checksum offload to work,
-	 * the pseudo header checksum must have already
-	 * been computed and stored in the checksum field
-	 * in the TCP header. The stack should have
-	 * already done this for us.
-	 */
-	if (m->m_pkthdr.csum_flags & FXP_CSUM_FEATURES) {
-		txp->tx_cb->ipcb_ip_schedule = FXP_IPCB_TCPUDP_CHECKSUM_ENABLE;
-		if (m->m_pkthdr.csum_flags & CSUM_TCP)
-			txp->tx_cb->ipcb_ip_schedule |= FXP_IPCB_TCP_PACKET;
-
-#ifdef FXP_IP_CSUM_WAR
-		/*
-		 * XXX The 82550 chip appears to have trouble
-		 * dealing with IP header checksums in very small
-		 * datagrams, namely fragments from 1 to 3 bytes
-		 * in size. For example, say you want to transmit
-		 * a UDP packet of 1473 bytes. The packet will be
-		 * fragmented over two IP datagrams, the latter
-		 * containing only one byte of data. The 82550 will
-		 * botch the header checksum on the 1-byte fragment.
-		 * As long as the datagram contains 4 or more bytes
-		 * of data, you're ok.
-		 *
-                 * The following code attempts to work around this
-		 * problem: if the datagram is less than 38 bytes
-		 * in size (14 bytes ether header, 20 bytes IP header,
-		 * plus 4 bytes of data), we punt and compute the IP
-		 * header checksum by hand. This workaround doesn't
-		 * work very well, however, since it can be fooled
-		 * by things like VLAN tags and IP options that make
-		 * the header sizes/offsets vary.
-		 */
-
-		if (m->m_pkthdr.csum_flags & CSUM_IP) {
-			if (m->m_pkthdr.len < 38) {
-				struct ip *ip;
-				m->m_data += ETHER_HDR_LEN;
-				ip = mtod(m, struct ip *);
-				ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
-				m->m_data -= ETHER_HDR_LEN;
-				m->m_pkthdr.csum_flags &= ~CSUM_IP;
-			} else {
-				txp->tx_cb->ipcb_ip_activation_high =
-				    FXP_IPCB_HARDWAREPARSING_ENABLE;
-				txp->tx_cb->ipcb_ip_schedule |=
-				    FXP_IPCB_IP_CHECKSUM_ENABLE;
-			}
-		}
-#endif
-	}
-
 	if (m->m_pkthdr.csum_flags & CSUM_TSO) {
 		/*
 		 * 82550/82551 requires ethernet/IP/TCP headers must be
@@ -1539,6 +1485,58 @@ fxp_encap(struct fxp_softc *sc, struct m
 		tcp_payload = m->m_pkthdr.len - ip_off - (ip->ip_hl << 2);
 		tcp_payload -= tcp->th_off << 2;
 		*m_head = m;
+	} else if (m->m_pkthdr.csum_flags & FXP_CSUM_FEATURES) {
+		/*
+		 * Deal with TCP/IP checksum offload. Note that
+		 * in order for TCP checksum offload to work,
+		 * the pseudo header checksum must have already
+		 * been computed and stored in the checksum field
+		 * in the TCP header. The stack should have
+		 * already done this for us.
+		 */
+		txp->tx_cb->ipcb_ip_schedule = FXP_IPCB_TCPUDP_CHECKSUM_ENABLE;
+		if (m->m_pkthdr.csum_flags & CSUM_TCP)
+			txp->tx_cb->ipcb_ip_schedule |= FXP_IPCB_TCP_PACKET;
+
+#ifdef FXP_IP_CSUM_WAR
+		/*
+		 * XXX The 82550 chip appears to have trouble
+		 * dealing with IP header checksums in very small
+		 * datagrams, namely fragments from 1 to 3 bytes
+		 * in size. For example, say you want to transmit
+		 * a UDP packet of 1473 bytes. The packet will be
+		 * fragmented over two IP datagrams, the latter
+		 * containing only one byte of data. The 82550 will
+		 * botch the header checksum on the 1-byte fragment.
+		 * As long as the datagram contains 4 or more bytes
+		 * of data, you're ok.
+		 *
+                 * The following code attempts to work around this
+		 * problem: if the datagram is less than 38 bytes
+		 * in size (14 bytes ether header, 20 bytes IP header,
+		 * plus 4 bytes of data), we punt and compute the IP
+		 * header checksum by hand. This workaround doesn't
+		 * work very well, however, since it can be fooled
+		 * by things like VLAN tags and IP options that make
+		 * the header sizes/offsets vary.
+		 */
+
+		if (m->m_pkthdr.csum_flags & CSUM_IP) {
+			if (m->m_pkthdr.len < 38) {
+				struct ip *ip;
+				m->m_data += ETHER_HDR_LEN;
+				ip = mtod(m, struct ip *);
+				ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
+				m->m_data -= ETHER_HDR_LEN;
+				m->m_pkthdr.csum_flags &= ~CSUM_IP;
+			} else {
+				txp->tx_cb->ipcb_ip_activation_high =
+				    FXP_IPCB_HARDWAREPARSING_ENABLE;
+				txp->tx_cb->ipcb_ip_schedule |=
+				    FXP_IPCB_IP_CHECKSUM_ENABLE;
+			}
+		}
+#endif
 	}
 
 	error = bus_dmamap_load_mbuf_sg(sc->fxp_txmtag, txp->tx_map, *m_head,

Modified: stable/8/sys/dev/msk/if_msk.c
==============================================================================
--- stable/8/sys/dev/msk/if_msk.c	Mon Apr 26 17:57:08 2010	(r207235)
+++ stable/8/sys/dev/msk/if_msk.c	Mon Apr 26 18:02:12 2010	(r207236)
@@ -2529,23 +2529,32 @@ msk_encap(struct msk_if_softc *sc_if, st
 		ip = (struct ip *)(mtod(m, char *) + offset);
 		offset += (ip->ip_hl << 2);
 		tcp_offset = offset;
-		/*
-		 * It seems that Yukon II has Tx checksum offload bug for
-		 * small TCP packets that's less than 60 bytes in size
-		 * (e.g. TCP window probe packet, pure ACK packet).
-		 * Common work around like padding with zeros to make the
-		 * frame minimum ethernet frame size didn't work at all.
-		 * Instead of disabling checksum offload completely we
-		 * resort to S/W checksum routine when we encounter short
-		 * TCP frames.
-		 * Short UDP packets appear to be handled correctly by
-		 * Yukon II. Also I assume this bug does not happen on
-		 * controllers that use newer descriptor format or
-		 * automatic Tx checksum calaulcation.
-		 */
-		if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) == 0 &&
+		if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+			m = m_pullup(m, offset + sizeof(struct tcphdr));
+			if (m == NULL) {
+				*m_head = NULL;
+				return (ENOBUFS);
+			}
+			tcp = (struct tcphdr *)(mtod(m, char *) + offset);
+			offset += (tcp->th_off << 2);
+		} else if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) == 0 &&
 		    (m->m_pkthdr.len < MSK_MIN_FRAMELEN) &&
 		    (m->m_pkthdr.csum_flags & CSUM_TCP) != 0) {
+			/*
+			 * It seems that Yukon II has Tx checksum offload bug
+			 * for small TCP packets that's less than 60 bytes in
+			 * size (e.g. TCP window probe packet, pure ACK packet).
+			 * Common work around like padding with zeros to make
+			 * the frame minimum ethernet frame size didn't work at
+			 * all.
+			 * Instead of disabling checksum offload completely we
+			 * resort to S/W checksum routine when we encounter
+			 * short TCP frames.
+			 * Short UDP packets appear to be handled correctly by
+			 * Yukon II. Also I assume this bug does not happen on
+			 * controllers that use newer descriptor format or
+			 * automatic Tx checksum calaulcation.
+			 */
 			m = m_pullup(m, offset + sizeof(struct tcphdr));
 			if (m == NULL) {
 				*m_head = NULL;
@@ -2556,15 +2565,6 @@ msk_encap(struct msk_if_softc *sc_if, st
 			    m->m_pkthdr.len, offset);
 			m->m_pkthdr.csum_flags &= ~CSUM_TCP;
 		}
-		if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
-			m = m_pullup(m, offset + sizeof(struct tcphdr));
-			if (m == NULL) {
-				*m_head = NULL;
-				return (ENOBUFS);
-			}
-			tcp = (struct tcphdr *)(mtod(m, char *) + offset);
-			offset += (tcp->th_off << 2);
-		}
 		*m_head = m;
 	}
 

Modified: stable/8/sys/dev/nfe/if_nfe.c
==============================================================================
--- stable/8/sys/dev/nfe/if_nfe.c	Mon Apr 26 17:57:08 2010	(r207235)
+++ stable/8/sys/dev/nfe/if_nfe.c	Mon Apr 26 18:02:12 2010	(r207236)
@@ -2367,7 +2367,12 @@ nfe_encap(struct nfe_softc *sc, struct m
 	m = *m_head;
 	cflags = flags = 0;
 	tso_segsz = 0;
-	if ((m->m_pkthdr.csum_flags & NFE_CSUM_FEATURES) != 0) {
+	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+		tso_segsz = (uint32_t)m->m_pkthdr.tso_segsz <<
+		    NFE_TX_TSO_SHIFT;
+		cflags &= ~(NFE_TX_IP_CSUM | NFE_TX_TCP_UDP_CSUM);
+		cflags |= NFE_TX_TSO;
+	} else if ((m->m_pkthdr.csum_flags & NFE_CSUM_FEATURES) != 0) {
 		if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
 			cflags |= NFE_TX_IP_CSUM;
 		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
@@ -2375,12 +2380,6 @@ nfe_encap(struct nfe_softc *sc, struct m
 		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
 			cflags |= NFE_TX_TCP_UDP_CSUM;
 	}
-	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
-		tso_segsz = (uint32_t)m->m_pkthdr.tso_segsz <<
-		    NFE_TX_TSO_SHIFT;
-		cflags &= ~(NFE_TX_IP_CSUM | NFE_TX_TCP_UDP_CSUM);
-		cflags |= NFE_TX_TSO;
-	}
 
 	for (i = 0; i < nsegs; i++) {
 		if (sc->nfe_flags & NFE_40BIT_ADDR) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004261802.o3QI2CmO058308>