From owner-svn-src-head@FreeBSD.ORG Thu Feb 9 23:19:09 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 76E2F1065670; Thu, 9 Feb 2012 23:19:09 +0000 (UTC) (envelope-from np@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 65D238FC08; Thu, 9 Feb 2012 23:19:09 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q19NJ9Wn042699; Thu, 9 Feb 2012 23:19:09 GMT (envelope-from np@svn.freebsd.org) Received: (from np@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q19NJ9EC042696; Thu, 9 Feb 2012 23:19:09 GMT (envelope-from np@svn.freebsd.org) Message-Id: <201202092319.q19NJ9EC042696@svn.freebsd.org> From: Navdeep Parhar Date: Thu, 9 Feb 2012 23:19:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r231317 - head/sys/dev/cxgb X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Feb 2012 23:19:09 -0000 Author: np Date: Thu Feb 9 23:19:09 2012 New Revision: 231317 URL: http://svn.freebsd.org/changeset/base/231317 Log: Add IPv6 TSO (including TSO+VLAN) support to cxgb(4). If an IPv6 packet has extension headers the kernel needs to deal with it itself. For the rest it can set various CSUM_XXX flags and the driver will act on them. Modified: head/sys/dev/cxgb/cxgb_main.c head/sys/dev/cxgb/cxgb_sge.c Modified: head/sys/dev/cxgb/cxgb_main.c ============================================================================== --- head/sys/dev/cxgb/cxgb_main.c Thu Feb 9 22:54:16 2012 (r231316) +++ head/sys/dev/cxgb/cxgb_main.c Thu Feb 9 23:19:09 2012 (r231317) @@ -982,7 +982,7 @@ cxgb_makedev(struct port_info *pi) #define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | \ IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO | \ IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE) -#define CXGB_CAP_ENABLE (CXGB_CAP & ~IFCAP_TSO6) +#define CXGB_CAP_ENABLE CXGB_CAP static int cxgb_port_attach(device_t dev) @@ -2059,8 +2059,8 @@ fail: } if (mask & IFCAP_RXCSUM) ifp->if_capenable ^= IFCAP_RXCSUM; - if (mask & IFCAP_TSO4) { - ifp->if_capenable ^= IFCAP_TSO4; + if (mask & IFCAP_TSO) { + ifp->if_capenable ^= IFCAP_TSO; if (IFCAP_TSO & ifp->if_capenable) { if (IFCAP_TXCSUM & ifp->if_capenable) Modified: head/sys/dev/cxgb/cxgb_sge.c ============================================================================== --- head/sys/dev/cxgb/cxgb_sge.c Thu Feb 9 22:54:16 2012 (r231316) +++ head/sys/dev/cxgb/cxgb_sge.c Thu Feb 9 23:19:09 2012 (r231317) @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -1492,10 +1493,10 @@ t3_encap(struct sge_qset *qs, struct mbu check_ring_tx_db(sc, txq, 0); return (0); } else if (tso_info) { - int eth_type; + uint16_t eth_type; struct cpl_tx_pkt_lso *hdr = (struct cpl_tx_pkt_lso *)txd; struct ether_header *eh; - struct ip *ip; + void *l3hdr; struct tcphdr *tcp; txd->flit[2] = 0; @@ -1521,18 +1522,37 @@ t3_encap(struct sge_qset *qs, struct mbu } eh = mtod(m0, struct ether_header *); - if (eh->ether_type == htons(ETHERTYPE_VLAN)) { - eth_type = CPL_ETH_II_VLAN; - ip = (struct ip *)((struct ether_vlan_header *)eh + 1); + eth_type = eh->ether_type; + if (eth_type == htons(ETHERTYPE_VLAN)) { + struct ether_vlan_header *evh = (void *)eh; + + tso_info |= V_LSO_ETH_TYPE(CPL_ETH_II_VLAN); + l3hdr = evh + 1; + eth_type = evh->evl_proto; } else { - eth_type = CPL_ETH_II; - ip = (struct ip *)(eh + 1); + tso_info |= V_LSO_ETH_TYPE(CPL_ETH_II); + l3hdr = eh + 1; } - tcp = (struct tcphdr *)(ip + 1); - tso_info |= V_LSO_ETH_TYPE(eth_type) | - V_LSO_IPHDR_WORDS(ip->ip_hl) | - V_LSO_TCPHDR_WORDS(tcp->th_off); + if (eth_type == htons(ETHERTYPE_IP)) { + struct ip *ip = l3hdr; + + tso_info |= V_LSO_IPHDR_WORDS(ip->ip_hl); + tcp = (struct tcphdr *)(ip + 1); + } else if (eth_type == htons(ETHERTYPE_IPV6)) { + struct ip6_hdr *ip6 = l3hdr; + + KASSERT(ip6->ip6_nxt == IPPROTO_TCP, + ("%s: CSUM_TSO with ip6_nxt %d", + __func__, ip6->ip6_nxt)); + + tso_info |= F_LSO_IPV6; + tso_info |= V_LSO_IPHDR_WORDS(sizeof(*ip6) >> 2); + tcp = (struct tcphdr *)(ip6 + 1); + } else + panic("%s: CSUM_TSO but neither ip nor ip6", __func__); + + tso_info |= V_LSO_TCPHDR_WORDS(tcp->th_off); hdr->lso_info = htonl(tso_info); if (__predict_false(mlen <= PIO_LEN)) {