svn commit: r237799 - head/sys/dev/cxgbe
Navdeep Parhar
np at FreeBSD.org
Fri Jun 29 16:50:53 UTC 2012
Author: np
Date: Fri Jun 29 16:50:52 2012
New Revision: 237799
URL: http://svn.freebsd.org/changeset/base/237799
Log:
cxgbe(4): support for IPv6 hardware checksumming (rx and tx).
Modified:
head/sys/dev/cxgbe/t4_main.c
head/sys/dev/cxgbe/t4_sge.c
Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c Fri Jun 29 16:30:15 2012 (r237798)
+++ head/sys/dev/cxgbe/t4_main.c Fri Jun 29 16:50:52 2012 (r237799)
@@ -822,7 +822,7 @@ cxgbe_probe(device_t dev)
#define T4_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | \
IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO | \
- IFCAP_VLAN_HWTSO)
+ IFCAP_VLAN_HWTSO | IFCAP_HWCSUM_IPV6)
#define T4_CAP_ENABLE (T4_CAP & ~IFCAP_TSO6)
static int
@@ -856,7 +856,8 @@ cxgbe_attach(device_t dev)
ifp->if_capabilities |= IFCAP_TOE4;
#endif
ifp->if_capenable = T4_CAP_ENABLE;
- ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO;
+ ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO |
+ CSUM_UDP_IPV6 | CSUM_TCP_IPV6;
/* Initialize ifmedia for this port */
ifmedia_init(&pi->media, IFM_IMASK, cxgbe_media_change,
@@ -1028,30 +1029,50 @@ fail:
if (IFCAP_TSO & ifp->if_capenable &&
!(IFCAP_TXCSUM & ifp->if_capenable)) {
- ifp->if_capenable &= ~IFCAP_TSO;
- ifp->if_hwassist &= ~CSUM_TSO;
+ ifp->if_capenable &= ~IFCAP_TSO4;
if_printf(ifp,
"tso disabled due to -txcsum.\n");
}
}
+ if (mask & IFCAP_TXCSUM_IPV6) {
+ ifp->if_capenable ^= IFCAP_TXCSUM_IPV6;
+ ifp->if_hwassist ^= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6);
+
+ if (IFCAP_TSO6 & ifp->if_capenable &&
+ !(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) {
+ ifp->if_capenable &= ~IFCAP_TSO6;
+ if_printf(ifp,
+ "tso6 disabled due to -txcsum6.\n");
+ }
+ }
if (mask & IFCAP_RXCSUM)
ifp->if_capenable ^= IFCAP_RXCSUM;
+ if (mask & IFCAP_RXCSUM_IPV6)
+ ifp->if_capenable ^= IFCAP_RXCSUM_IPV6;
+
+ /*
+ * Note that we leave CSUM_TSO alone (it is always set). The
+ * kernel takes both IFCAP_TSOx and CSUM_TSO into account before
+ * sending a TSO request our way, so it's sufficient to toggle
+ * IFCAP_TSOx only.
+ */
if (mask & IFCAP_TSO4) {
+ if (!(IFCAP_TSO4 & ifp->if_capenable) &&
+ !(IFCAP_TXCSUM & ifp->if_capenable)) {
+ if_printf(ifp, "enable txcsum first.\n");
+ rc = EAGAIN;
+ goto fail;
+ }
ifp->if_capenable ^= IFCAP_TSO4;
-
- if (IFCAP_TSO & ifp->if_capenable) {
- if (IFCAP_TXCSUM & ifp->if_capenable)
- ifp->if_hwassist |= CSUM_TSO;
- else {
- ifp->if_capenable &= ~IFCAP_TSO;
- ifp->if_hwassist &= ~CSUM_TSO;
- if_printf(ifp,
- "enable txcsum first.\n");
- rc = EAGAIN;
- goto fail;
- }
- } else
- ifp->if_hwassist &= ~CSUM_TSO;
+ }
+ if (mask & IFCAP_TSO6) {
+ if (!(IFCAP_TSO6 & ifp->if_capenable) &&
+ !(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) {
+ if_printf(ifp, "enable txcsum6 first.\n");
+ rc = EAGAIN;
+ goto fail;
+ }
+ ifp->if_capenable ^= IFCAP_TSO6;
}
if (mask & IFCAP_LRO) {
#ifdef INET
Modified: head/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- head/sys/dev/cxgbe/t4_sge.c Fri Jun 29 16:30:15 2012 (r237798)
+++ head/sys/dev/cxgbe/t4_sge.c Fri Jun 29 16:50:52 2012 (r237799)
@@ -1054,15 +1054,23 @@ t4_eth_rx(struct sge_iq *iq, const struc
m0->m_flags |= M_FLOWID;
m0->m_pkthdr.flowid = rss->hash_val;
- if (cpl->csum_calc && !cpl->err_vec &&
- ifp->if_capenable & IFCAP_RXCSUM) {
- m0->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED |
- CSUM_IP_VALID | CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
- if (cpl->ip_frag)
+ if (cpl->csum_calc && !cpl->err_vec) {
+ if (ifp->if_capenable & IFCAP_RXCSUM &&
+ cpl->l2info & htobe32(F_RXF_IP)) {
+ m0->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED |
+ CSUM_IP_VALID | CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
+ rxq->rxcsum++;
+ } else if (ifp->if_capenable & IFCAP_RXCSUM_IPV6 &&
+ cpl->l2info & htobe32(F_RXF_IP6)) {
+ m0->m_pkthdr.csum_flags |= (CSUM_DATA_VALID_IPV6 |
+ CSUM_PSEUDO_HDR);
+ rxq->rxcsum++;
+ }
+
+ if (__predict_false(cpl->ip_frag))
m0->m_pkthdr.csum_data = be16toh(cpl->csum);
else
m0->m_pkthdr.csum_data = 0xffff;
- rxq->rxcsum++;
}
if (cpl->vlan_ex) {
@@ -2827,9 +2835,11 @@ write_txpkt_wr(struct port_info *pi, str
ctrl1 = 0;
if (!(m->m_pkthdr.csum_flags & CSUM_IP))
ctrl1 |= F_TXPKT_IPCSUM_DIS;
- if (!(m->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP)))
+ if (!(m->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP | CSUM_UDP_IPV6 |
+ CSUM_TCP_IPV6)))
ctrl1 |= F_TXPKT_L4CSUM_DIS;
- if (m->m_pkthdr.csum_flags & (CSUM_IP | CSUM_TCP | CSUM_UDP))
+ if (m->m_pkthdr.csum_flags & (CSUM_IP | CSUM_TCP | CSUM_UDP |
+ CSUM_UDP_IPV6 | CSUM_TCP_IPV6))
txq->txcsum++; /* some hardware assistance provided */
/* VLAN tag insertion */
More information about the svn-src-all
mailing list