Author: bz
Date: Fri May 25 03:02:56 2012
New Revision: 235964
URL: http://svn.freebsd.org/changeset/base/235964

Log:
  MFp4 bz_ipv6_fast:
  
    Add TSO6 and LRO/IPv6 support.
    Fix the module Makefile to at least properly inlcude opt_inet6.h
    and allow builds without INET or INET6.
  
    Sponsored by:       The FreeBSD Foundation
    Sponsored by:       iXsystems
  
  Reviewed by:  gnn (as part of the whole)
  MFC After:    3 days

Modified:
  head/sys/dev/ixgbe/ixgbe.c
  head/sys/modules/ixgbe/Makefile

Modified: head/sys/dev/ixgbe/ixgbe.c
==============================================================================
--- head/sys/dev/ixgbe/ixgbe.c  Fri May 25 03:00:34 2012        (r235963)
+++ head/sys/dev/ixgbe/ixgbe.c  Fri May 25 03:02:56 2012        (r235964)
@@ -162,7 +162,7 @@ static void     ixgbe_dma_free(struct ad
 static void    ixgbe_add_rx_process_limit(struct adapter *, const char *,
                    const char *, int *, int);
 static bool    ixgbe_tx_ctx_setup(struct tx_ring *, struct mbuf *);
-static bool    ixgbe_tso_setup(struct tx_ring *, struct mbuf *, u32 *);
+static bool    ixgbe_tso_setup(struct tx_ring *, struct mbuf *, u32 *, u32 *);
 static void    ixgbe_set_ivar(struct adapter *, u8, u8, s8);
 static void    ixgbe_configure_ivars(struct adapter *);
 static u8 *    ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
@@ -997,6 +997,8 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
                        ifp->if_capenable ^= IFCAP_HWCSUM;
                if (mask & IFCAP_TSO4)
                        ifp->if_capenable ^= IFCAP_TSO4;
+               if (mask & IFCAP_TSO6)
+                       ifp->if_capenable ^= IFCAP_TSO6;
                if (mask & IFCAP_LRO)
                        ifp->if_capenable ^= IFCAP_LRO;
                if (mask & IFCAP_VLAN_HWTAGGING)
@@ -1061,7 +1063,7 @@ ixgbe_init_locked(struct adapter *adapte
 
        /* Set the various hardware offload abilities */
        ifp->if_hwassist = 0;
-       if (ifp->if_capenable & IFCAP_TSO4)
+       if (ifp->if_capenable & IFCAP_TSO)
                ifp->if_hwassist |= CSUM_TSO;
        if (ifp->if_capenable & IFCAP_TXCSUM) {
                ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
@@ -1767,9 +1769,8 @@ ixgbe_xmit(struct tx_ring *txr, struct m
        ** a packet.
        */
        if (m_head->m_pkthdr.csum_flags & CSUM_TSO) {
-               if (ixgbe_tso_setup(txr, m_head, &paylen)) {
+               if (ixgbe_tso_setup(txr, m_head, &paylen, &olinfo_status)) {
                        cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
-                       olinfo_status |= IXGBE_TXD_POPTS_IXSM << 8;
                        olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8;
                        olinfo_status |= paylen << IXGBE_ADVTXD_PAYLEN_SHIFT;
                        ++adapter->tso_tx;
@@ -2562,7 +2563,7 @@ ixgbe_setup_interface(device_t dev, stru
         */
        ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
 
-       ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4 | IFCAP_VLAN_HWCSUM;
+       ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO | IFCAP_VLAN_HWCSUM;
        ifp->if_capabilities |= IFCAP_JUMBO_MTU;
        ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING
                             |  IFCAP_VLAN_HWTSO
@@ -3234,6 +3235,7 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, 
                case ETHERTYPE_IPV6:
                        ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
                        ip_hlen = sizeof(struct ip6_hdr);
+                       /* XXX-BZ this will go badly in case of ext hdrs. */
                        ipproto = ip6->ip6_nxt;
                        type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6;
                        break;
@@ -3292,17 +3294,23 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, 
  *
  **********************************************************************/
 static bool
-ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen)
+ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen,
+    u32 *olinfo_status)
 {
        struct adapter *adapter = txr->adapter;
        struct ixgbe_adv_tx_context_desc *TXD;
        struct ixgbe_tx_buf        *tx_buffer;
        u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
-       u32 mss_l4len_idx = 0;
-       u16 vtag = 0;
-       int ctxd, ehdrlen,  hdrlen, ip_hlen, tcp_hlen;
+       u32 mss_l4len_idx = 0, len;
+       u16 vtag = 0, eh_type;
+       int ctxd, ehdrlen, ip_hlen, tcp_hlen;
        struct ether_vlan_header *eh;
+#ifdef INET6
+       struct ip6_hdr *ip6;
+#endif
+#ifdef INET
        struct ip *ip;
+#endif
        struct tcphdr *th;
 
 
@@ -3311,32 +3319,62 @@ ixgbe_tso_setup(struct tx_ring *txr, str
         * Jump over vlan headers if already present
         */
        eh = mtod(mp, struct ether_vlan_header *);
-       if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) 
+       if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
                ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
-       else
+               eh_type = eh->evl_proto;
+       } else {
                ehdrlen = ETHER_HDR_LEN;
+               eh_type = eh->evl_encap_proto;
+       }
 
         /* Ensure we have at least the IP+TCP header in the first mbuf. */
-        if (mp->m_len < ehdrlen + sizeof(struct ip) + sizeof(struct tcphdr))
-               return FALSE;
+       len = ehdrlen + sizeof(struct tcphdr);
+       switch (ntohs(eh_type)) {
+#ifdef INET6
+       case ETHERTYPE_IPV6:
+               if (mp->m_len < len + sizeof(struct ip6_hdr))
+                       return FALSE;
+               ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
+               /* XXX-BZ For now we do not pretend to support ext. hdrs. */
+               if (ip6->ip6_nxt != IPPROTO_TCP)
+                       return FALSE;
+               ip_hlen = sizeof(struct ip6_hdr);
+               th = (struct tcphdr *)((caddr_t)ip6 + ip_hlen);
+               th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0);
+               type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6;
+               break;
+#endif
+#ifdef INET
+       case ETHERTYPE_IP:
+               if (mp->m_len < len + sizeof(struct ip))
+                       return FALSE;
+               ip = (struct ip *)(mp->m_data + ehdrlen);
+               if (ip->ip_p != IPPROTO_TCP)
+                       return FALSE;
+               ip->ip_sum = 0;
+               ip_hlen = ip->ip_hl << 2;
+               th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
+               th->th_sum = in_pseudo(ip->ip_src.s_addr,
+                   ip->ip_dst.s_addr, htons(IPPROTO_TCP));
+               type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
+               /* Tell transmit desc to also do IPv4 checksum. */
+               *olinfo_status |= IXGBE_TXD_POPTS_IXSM << 8;
+               break;
+#endif
+       default:
+               panic("%s: CSUM_TSO but no supported IP version (0x%04x)",
+                   __func__, ntohs(eh_type));
+               break;
+       }
 
        ctxd = txr->next_avail_desc;
        tx_buffer = &txr->tx_buffers[ctxd];
        TXD = (struct ixgbe_adv_tx_context_desc *) &txr->tx_base[ctxd];
 
-       ip = (struct ip *)(mp->m_data + ehdrlen);
-       if (ip->ip_p != IPPROTO_TCP)
-               return FALSE;   /* 0 */
-       ip->ip_sum = 0;
-       ip_hlen = ip->ip_hl << 2;
-       th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
-       th->th_sum = in_pseudo(ip->ip_src.s_addr,
-           ip->ip_dst.s_addr, htons(IPPROTO_TCP));
        tcp_hlen = th->th_off << 2;
-       hdrlen = ehdrlen + ip_hlen + tcp_hlen;
 
        /* This is used in the transmit desc in encap */
-       *paylen = mp->m_pkthdr.len - hdrlen;
+       *paylen = mp->m_pkthdr.len - ehdrlen - ip_hlen - tcp_hlen;
 
        /* VLAN MACLEN IPLEN */
        if (mp->m_flags & M_VLANTAG) {
@@ -3351,10 +3389,8 @@ ixgbe_tso_setup(struct tx_ring *txr, str
        /* ADV DTYPE TUCMD */
        type_tucmd_mlhl |= IXGBE_ADVTXD_DCMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT;
        type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
-       type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
        TXD->type_tucmd_mlhl |= htole32(type_tucmd_mlhl);
 
-
        /* MSS L4LEN IDX */
        mss_l4len_idx |= (mp->m_pkthdr.tso_segsz << IXGBE_ADVTXD_MSS_SHIFT);
        mss_l4len_idx |= (tcp_hlen << IXGBE_ADVTXD_L4LEN_SHIFT);
@@ -4295,15 +4331,17 @@ ixgbe_rx_input(struct rx_ring *rxr, stru
 {
                  
         /*
-         * ATM LRO is only for IPv4/TCP packets and TCP checksum of the packet
+         * ATM LRO is only for IP/TCP packets and TCP checksum of the packet
          * should be computed by hardware. Also it should not have VLAN tag in
-         * ethernet header.
+         * ethernet header.  In case of IPv6 we do not yet support ext. hdrs.
          */
         if (rxr->lro_enabled &&
             (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 &&
             (ptype & IXGBE_RXDADV_PKTTYPE_ETQF) == 0 &&
-            (ptype & (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP)) ==
-            (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP) &&
+            ((ptype & (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP)) 
==
+            (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP) ||
+            (ptype & (IXGBE_RXDADV_PKTTYPE_IPV6 | IXGBE_RXDADV_PKTTYPE_TCP)) ==
+            (IXGBE_RXDADV_PKTTYPE_IPV6 | IXGBE_RXDADV_PKTTYPE_TCP)) &&
             (m->m_pkthdr.csum_flags & (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) ==
             (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) {
                 /*

Modified: head/sys/modules/ixgbe/Makefile
==============================================================================
--- head/sys/modules/ixgbe/Makefile     Fri May 25 03:00:34 2012        
(r235963)
+++ head/sys/modules/ixgbe/Makefile     Fri May 25 03:02:56 2012        
(r235964)
@@ -2,10 +2,23 @@
 .PATH:  ${.CURDIR}/../../dev/ixgbe
 KMOD    = ixgbe
 SRCS    = device_if.h bus_if.h pci_if.h
+SRCS   += opt_inet.h opt_inet6.h
 SRCS    += ixgbe.c ixv.c
 # Shared source
 SRCS    += ixgbe_common.c ixgbe_api.c ixgbe_phy.c ixgbe_mbx.c ixgbe_vf.c
 SRCS    += ixgbe_82599.c ixgbe_82598.c ixgbe_x540.c
 CFLAGS+= -I${.CURDIR}/../../dev/ixgbe -DSMP -DIXGBE_FDIR
 
+.if !defined(KERNBUILDDIR)
+.if ${MK_INET_SUPPORT} != "no"
+opt_inet.h:
+       @echo "#define INET 1" > ${.TARGET}
+.endif
+
+.if ${MK_INET6_SUPPORT} != "no"
+opt_inet6.h:
+       @echo "#define INET6 1" > ${.TARGET}
+.endif
+.endif
+
 .include <bsd.kmod.mk>
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to