svn commit: r207237 - in stable/7/sys/dev: age alc ale fxp msk nfe
Pyun YongHyeon
yongari at FreeBSD.org
Mon Apr 26 18:04:34 UTC 2010
Author: yongari
Date: Mon Apr 26 18:04:33 2010
New Revision: 207237
URL: http://svn.freebsd.org/changeset/base/207237
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/7/sys/dev/age/if_age.c
stable/7/sys/dev/alc/if_alc.c
stable/7/sys/dev/ale/if_ale.c
stable/7/sys/dev/fxp/if_fxp.c
stable/7/sys/dev/msk/if_msk.c
stable/7/sys/dev/nfe/if_nfe.c
Directory Properties:
stable/7/sys/ (props changed)
stable/7/sys/cddl/contrib/opensolaris/ (props changed)
stable/7/sys/contrib/dev/acpica/ (props changed)
stable/7/sys/contrib/pf/ (props changed)
Modified: stable/7/sys/dev/age/if_age.c
==============================================================================
--- stable/7/sys/dev/age/if_age.c Mon Apr 26 18:02:12 2010 (r207236)
+++ stable/7/sys/dev/age/if_age.c Mon Apr 26 18:04:33 2010 (r207237)
@@ -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/7/sys/dev/alc/if_alc.c
==============================================================================
--- stable/7/sys/dev/alc/if_alc.c Mon Apr 26 18:02:12 2010 (r207236)
+++ stable/7/sys/dev/alc/if_alc.c Mon Apr 26 18:04:33 2010 (r207237)
@@ -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/7/sys/dev/ale/if_ale.c
==============================================================================
--- stable/7/sys/dev/ale/if_ale.c Mon Apr 26 18:02:12 2010 (r207236)
+++ stable/7/sys/dev/ale/if_ale.c Mon Apr 26 18:04:33 2010 (r207237)
@@ -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/7/sys/dev/fxp/if_fxp.c
==============================================================================
--- stable/7/sys/dev/fxp/if_fxp.c Mon Apr 26 18:02:12 2010 (r207236)
+++ stable/7/sys/dev/fxp/if_fxp.c Mon Apr 26 18:04:33 2010 (r207237)
@@ -1418,60 +1418,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
@@ -1540,6 +1486,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/7/sys/dev/msk/if_msk.c
==============================================================================
--- stable/7/sys/dev/msk/if_msk.c Mon Apr 26 18:02:12 2010 (r207236)
+++ stable/7/sys/dev/msk/if_msk.c Mon Apr 26 18:04:33 2010 (r207237)
@@ -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/7/sys/dev/nfe/if_nfe.c
==============================================================================
--- stable/7/sys/dev/nfe/if_nfe.c Mon Apr 26 18:02:12 2010 (r207236)
+++ stable/7/sys/dev/nfe/if_nfe.c Mon Apr 26 18:04:33 2010 (r207237)
@@ -2357,7 +2357,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)
@@ -2365,12 +2370,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) {
More information about the svn-src-stable-7
mailing list