Date: Fri, 29 Jun 2012 19:51:07 +0000 (UTC) From: Navdeep Parhar <np@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r237819 - in head/sys: dev/cxgbe modules/cxgbe/if_cxgbe Message-ID: <201206291951.q5TJp71W066970@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206291951.q5TJp71W066970>