svn commit: r237819 - in head/sys: dev/cxgbe modules/cxgbe/if_cxgbe

Navdeep Parhar np at FreeBSD.org
Fri Jun 29 19:51:07 UTC 2012


Author: np
Date: Fri Jun 29 19:51:06 2012
New Revision: 237819
URL: http://svn.freebsd.org/changeset/base/237819

Log:
  cxgbe(4): support for IPv6 TSO and LRO.
  
  Submitted by:	bz (this is a modified version of that patch)

Modified:
  head/sys/dev/cxgbe/adapter.h
  head/sys/dev/cxgbe/t4_l2t.c
  head/sys/dev/cxgbe/t4_main.c
  head/sys/dev/cxgbe/t4_sge.c
  head/sys/modules/cxgbe/if_cxgbe/Makefile

Modified: head/sys/dev/cxgbe/adapter.h
==============================================================================
--- head/sys/dev/cxgbe/adapter.h	Fri Jun 29 19:05:29 2012	(r237818)
+++ head/sys/dev/cxgbe/adapter.h	Fri Jun 29 19:51:06 2012	(r237819)
@@ -392,7 +392,7 @@ struct sge_txq {
 	/* stats for common events first */
 
 	uint64_t txcsum;	/* # of times hardware assisted with checksum */
-	uint64_t tso_wrs;	/* # of IPv4 TSO work requests */
+	uint64_t tso_wrs;	/* # of TSO work requests */
 	uint64_t vlan_insertion;/* # of times VLAN tag was inserted */
 	uint64_t imm_wrs;	/* # of work requests with immediate data */
 	uint64_t sgl_wrs;	/* # of work requests with direct SGL */
@@ -412,7 +412,7 @@ struct sge_rxq {
 	struct sge_fl fl;	/* MUST follow iq */
 
 	struct ifnet *ifp;	/* the interface this rxq belongs to */
-#ifdef INET
+#if defined(INET) || defined(INET6)
 	struct lro_ctrl lro;	/* LRO state */
 #endif
 

Modified: head/sys/dev/cxgbe/t4_l2t.c
==============================================================================
--- head/sys/dev/cxgbe/t4_l2t.c	Fri Jun 29 19:05:29 2012	(r237818)
+++ head/sys/dev/cxgbe/t4_l2t.c	Fri Jun 29 19:51:06 2012	(r237819)
@@ -27,6 +27,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_inet.h"
+#include "opt_inet6.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c	Fri Jun 29 19:05:29 2012	(r237818)
+++ head/sys/dev/cxgbe/t4_main.c	Fri Jun 29 19:51:06 2012	(r237819)
@@ -29,6 +29,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_inet.h"
+#include "opt_inet6.h"
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -823,7 +824,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_HWCSUM_IPV6)
-#define T4_CAP_ENABLE (T4_CAP & ~IFCAP_TSO6)
+#define T4_CAP_ENABLE (T4_CAP)
 
 static int
 cxgbe_attach(device_t dev)
@@ -1075,7 +1076,7 @@ fail:
 			ifp->if_capenable ^= IFCAP_TSO6;
 		}
 		if (mask & IFCAP_LRO) {
-#ifdef INET
+#if defined(INET) || defined(INET6)
 			int i;
 			struct sge_rxq *rxq;
 

Modified: head/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- head/sys/dev/cxgbe/t4_sge.c	Fri Jun 29 19:05:29 2012	(r237818)
+++ head/sys/dev/cxgbe/t4_sge.c	Fri Jun 29 19:51:06 2012	(r237819)
@@ -29,6 +29,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_inet.h"
+#include "opt_inet6.h"
 
 #include <sys/types.h>
 #include <sys/mbuf.h>
@@ -46,6 +47,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_vlan_var.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
+#include <netinet/ip6.h>
 #include <netinet/tcp.h>
 
 #include "common/common.h"
@@ -908,7 +910,7 @@ service_iq(struct sge_iq *iq, int budget
 			STAILQ_INSERT_TAIL(&iql, q, link);
 	}
 
-#ifdef INET
+#if defined(INET) || defined(INET6)
 	if (iq->flags & IQ_LRO_ENABLED) {
 		struct lro_ctrl *lro = &rxq->lro;
 		struct lro_entry *l;
@@ -1039,7 +1041,7 @@ t4_eth_rx(struct sge_iq *iq, const struc
 	struct sge_rxq *rxq = iq_to_rxq(iq);
 	struct ifnet *ifp = rxq->ifp;
 	const struct cpl_rx_pkt *cpl = (const void *)(rss + 1);
-#ifdef INET
+#if defined(INET) || defined(INET6)
 	struct lro_ctrl *lro = &rxq->lro;
 #endif
 
@@ -1079,7 +1081,7 @@ t4_eth_rx(struct sge_iq *iq, const struc
 		rxq->vlan_extraction++;
 	}
 
-#ifdef INET
+#if defined(INET) || defined(INET6)
 	if (cpl->l2info & htobe32(F_RXF_LRO) &&
 	    iq->flags & IQ_LRO_ENABLED &&
 	    tcp_lro_rx(lro, m0, 0) == 0) {
@@ -1805,7 +1807,7 @@ alloc_rxq(struct port_info *pi, struct s
 	refill_fl(pi->adapter, &rxq->fl, rxq->fl.needed / 8);
 	FL_UNLOCK(&rxq->fl);
 
-#ifdef INET
+#if defined(INET) || defined(INET6)
 	rc = tcp_lro_init(&rxq->lro);
 	if (rc != 0)
 		return (rc);
@@ -1832,7 +1834,7 @@ alloc_rxq(struct port_info *pi, struct s
 	SYSCTL_ADD_PROC(&pi->ctx, children, OID_AUTO, "cidx",
 	    CTLTYPE_INT | CTLFLAG_RD, &rxq->iq.cidx, 0, sysctl_uint16, "I",
 	    "consumer index");
-#ifdef INET
+#if defined(INET) || defined(INET6)
 	SYSCTL_ADD_INT(&pi->ctx, children, OID_AUTO, "lro_queued", CTLFLAG_RD,
 	    &rxq->lro.lro_queued, 0, NULL);
 	SYSCTL_ADD_INT(&pi->ctx, children, OID_AUTO, "lro_flushed", CTLFLAG_RD,
@@ -1865,7 +1867,7 @@ free_rxq(struct port_info *pi, struct sg
 {
 	int rc;
 
-#ifdef INET
+#if defined(INET) || defined(INET6)
 	if (rxq->lro.ifp) {
 		tcp_lro_free(&rxq->lro);
 		rxq->lro.ifp = NULL;
@@ -2273,7 +2275,7 @@ alloc_txq(struct port_info *pi, struct s
 	    CTLFLAG_RD, &txq->vlan_insertion,
 	    "# of times hardware inserted 802.1Q tag");
 	SYSCTL_ADD_UQUAD(&pi->ctx, children, OID_AUTO, "tso_wrs", CTLFLAG_RD,
-	    &txq->tso_wrs, "# of IPv4 TSO work requests");
+	    &txq->tso_wrs, "# of TSO work requests");
 	SYSCTL_ADD_UQUAD(&pi->ctx, children, OID_AUTO, "imm_wrs", CTLFLAG_RD,
 	    &txq->imm_wrs, "# of work requests with immediate data");
 	SYSCTL_ADD_UQUAD(&pi->ctx, children, OID_AUTO, "sgl_wrs", CTLFLAG_RD,
@@ -2802,22 +2804,60 @@ write_txpkt_wr(struct port_info *pi, str
 	if (m->m_pkthdr.tso_segsz) {
 		struct cpl_tx_pkt_lso_core *lso = (void *)(wr + 1);
 		struct ether_header *eh;
-		struct ip *ip;
+		void *l3hdr;
+#if defined(INET) || defined(INET6)
 		struct tcphdr *tcp;
+#endif
+		uint16_t eh_type;
 
 		ctrl = V_LSO_OPCODE(CPL_TX_PKT_LSO) | F_LSO_FIRST_SLICE |
 		    F_LSO_LAST_SLICE;
 
 		eh = mtod(m, struct ether_header *);
-		if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
+		eh_type = ntohs(eh->ether_type);
+		if (eh_type == ETHERTYPE_VLAN) {
+			struct ether_vlan_header *evh = (void *)eh;
+
 			ctrl |= V_LSO_ETHHDR_LEN(1);
-			ip = (void *)((struct ether_vlan_header *)eh + 1);
+			l3hdr = evh + 1;
+			eh_type = ntohs(evh->evl_proto);
 		} else
-			ip = (void *)(eh + 1);
+			l3hdr = eh + 1;
 
-		tcp = (void *)((uintptr_t)ip + ip->ip_hl * 4);
-		ctrl |= V_LSO_IPHDR_LEN(ip->ip_hl) |
-		    V_LSO_TCPHDR_LEN(tcp->th_off);
+		switch (eh_type) {
+#ifdef INET6
+		case ETHERTYPE_IPV6:
+		{
+			struct ip6_hdr *ip6 = l3hdr;
+
+			/*
+			 * XXX-BZ For now we do not pretend to support
+			 * IPv6 extension headers.
+			 */
+			KASSERT(ip6->ip6_nxt == IPPROTO_TCP, ("%s: CSUM_TSO "
+			    "with ip6_nxt != TCP: %u", __func__, ip6->ip6_nxt));
+			tcp = (struct tcphdr *)(ip6 + 1);
+			ctrl |= F_LSO_IPV6;
+			ctrl |= V_LSO_IPHDR_LEN(sizeof(*ip6) >> 2) |
+			    V_LSO_TCPHDR_LEN(tcp->th_off);
+			break;
+		}
+#endif
+#ifdef INET
+		case ETHERTYPE_IP:
+		{
+			struct ip *ip = l3hdr;
+
+			tcp = (void *)((uintptr_t)ip + ip->ip_hl * 4);
+			ctrl |= V_LSO_IPHDR_LEN(ip->ip_hl) |
+			    V_LSO_TCPHDR_LEN(tcp->th_off);
+			break;
+		}
+#endif
+		default:
+			panic("%s: CSUM_TSO but no supported IP version "
+			    "(0x%04x)", __func__, eh_type);
+		}
 
 		lso->lso_ctrl = htobe32(ctrl);
 		lso->ipid_ofst = htobe16(0);

Modified: head/sys/modules/cxgbe/if_cxgbe/Makefile
==============================================================================
--- head/sys/modules/cxgbe/if_cxgbe/Makefile	Fri Jun 29 19:05:29 2012	(r237818)
+++ head/sys/modules/cxgbe/if_cxgbe/Makefile	Fri Jun 29 19:51:06 2012	(r237819)
@@ -9,7 +9,7 @@ KMOD = if_cxgbe
 SRCS = t4_main.c t4_sge.c t4_l2t.c
 SRCS+= t4_hw.c
 SRCS+= device_if.h bus_if.h pci_if.h
-SRCS+= opt_inet.h
+SRCS+= opt_inet.h opt_inet6.h
 SRCS+= opt_ofed.h
 
 CFLAGS+= -I${CXGBE}


More information about the svn-src-head mailing list