Author: np
Date: Sun Jul  1 09:17:55 2012
New Revision: 237916
URL: http://svn.freebsd.org/changeset/base/237916

Log:
  MFC r231317, r235963 (bz@), r234831, r234833.
  
  r231317
  Add IPv6 TSO (including TSO+VLAN) support to cxgb(4).
  
  r235963 (bz@)
  Allow LRO to work on IPv6 as well.
  Fix the module Makefile to at least properly inlcude opt_inet6.h
  and allow builds without INET or INET6.
  
  r234831
  Make sure that the firmware version is available in
  dev.t4nex.X.firmware_version even if the driver fails to attach
  properly.  At least it'll be easy to tell what we're dealing with.
  
  r234833:
  Change the default to not use packet counters to generate rx interrupts.
  Rely solely on the timer based mechanism.
  
  Update man page to reflect this change.

Modified:
  stable/9/share/man/man4/cxgbe.4
  stable/9/sys/dev/cxgb/cxgb_main.c
  stable/9/sys/dev/cxgb/cxgb_sge.c
  stable/9/sys/dev/cxgbe/t4_main.c
  stable/9/sys/dev/cxgbe/t4_sge.c
  stable/9/sys/modules/cxgb/cxgb/Makefile
Directory Properties:
  stable/9/share/man/man4/   (props changed)
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)
  stable/9/sys/modules/   (props changed)

Modified: stable/9/share/man/man4/cxgbe.4
==============================================================================
--- stable/9/share/man/man4/cxgbe.4     Sun Jul  1 09:17:17 2012        
(r237915)
+++ stable/9/share/man/man4/cxgbe.4     Sun Jul  1 09:17:55 2012        
(r237916)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2011, Chelsio Inc
+.\" Copyright (c) 2011-2012, Chelsio Inc
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -145,10 +145,9 @@ dev.cxgbe.X.holdoff_tmr_idx sysctl.
 The packet-count index value to use to delay interrupts.
 The packet-count list has the values 1, 8, 16, and 32 by default
 and the index selects a value from this list.
-The default value is 2 for both 10Gb and 1Gb ports, which means 16
-packets (or the holdoff timer going off) before an interrupt is
-generated.
--1 disables packet counting.
+The default value is -1 for both 10Gb and 1Gb ports, which means packet
+counting is disabled and interrupts are generated based solely on the
+holdoff timer value.
 Different cxgbe interfaces can be assigned different values via the
 dev.cxgbe.X.holdoff_pktc_idx sysctl.
 This sysctl works only when the interface has never been marked up (as done by

Modified: stable/9/sys/dev/cxgb/cxgb_main.c
==============================================================================
--- stable/9/sys/dev/cxgb/cxgb_main.c   Sun Jul  1 09:17:17 2012        
(r237915)
+++ stable/9/sys/dev/cxgb/cxgb_main.c   Sun Jul  1 09:17:55 2012        
(r237916)
@@ -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: stable/9/sys/dev/cxgb/cxgb_sge.c
==============================================================================
--- stable/9/sys/dev/cxgb/cxgb_sge.c    Sun Jul  1 09:17:17 2012        
(r237915)
+++ stable/9/sys/dev/cxgb/cxgb_sge.c    Sun Jul  1 09:17:55 2012        
(r237916)
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_inet6.h"
 #include "opt_inet.h"
 
 #include <sys/param.h>
@@ -62,6 +63,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
+#include <netinet/ip6.h>
 #include <netinet/tcp.h>
 
 #include <dev/pci/pcireg.h>
@@ -1492,10 +1494,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 +1523,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)) {
@@ -2065,7 +2086,7 @@ t3_free_qset(adapter_t *sc, struct sge_q
                MTX_DESTROY(&q->rspq.lock);
        }
 
-#ifdef INET
+#if defined(INET6) || defined(INET)
        tcp_lro_free(&q->lro.ctrl);
 #endif
 
@@ -2648,7 +2669,7 @@ t3_sge_alloc_qset(adapter_t *sc, u_int i
 
        /* Allocate and setup the lro_ctrl structure */
        q->lro.enabled = !!(pi->ifp->if_capenable & IFCAP_LRO);
-#ifdef INET
+#if defined(INET6) || defined(INET)
        ret = tcp_lro_init(&q->lro.ctrl);
        if (ret) {
                printf("error %d from tcp_lro_init\n", ret);
@@ -2941,9 +2962,11 @@ process_responses(adapter_t *adap, struc
        struct rsp_desc *r = &rspq->desc[rspq->cidx];
        int budget_left = budget;
        unsigned int sleeping = 0;
+#if defined(INET6) || defined(INET)
        int lro_enabled = qs->lro.enabled;
        int skip_lro;
        struct lro_ctrl *lro_ctrl = &qs->lro.ctrl;
+#endif
        struct mbuf *offload_mbufs[RX_BUNDLE_SIZE];
        int ngathered = 0;
        struct t3_mbuf_hdr *mh = &rspq->rspq_mh;
@@ -3062,15 +3085,16 @@ process_responses(adapter_t *adap, struc
                         * The mbuf's rcvif was derived from the cpl header and
                         * is accurate.  Skip LRO and just use that.
                         */
+#if defined(INET6) || defined(INET)
                        skip_lro = __predict_false(qs->port->ifp != 
m->m_pkthdr.rcvif);
 
                        if (lro_enabled && lro_ctrl->lro_cnt && !skip_lro
-#ifdef INET
                            && (tcp_lro_rx(lro_ctrl, m, 0) == 0)
-#endif
                            ) {
                                /* successfully queue'd for LRO */
-                       } else {
+                       } else
+#endif
+                       {
                                /*
                                 * LRO not enabled, packet unsuitable for LRO,
                                 * or unable to queue.  Pass it up right now in
@@ -3089,7 +3113,7 @@ process_responses(adapter_t *adap, struc
 
        deliver_partial_bundle(&adap->tdev, rspq, offload_mbufs, ngathered);
 
-#ifdef INET
+#if defined(INET6) || defined(INET)
        /* Flush LRO */
        while (!SLIST_EMPTY(&lro_ctrl->lro_active)) {
                struct lro_entry *queued = SLIST_FIRST(&lro_ctrl->lro_active);

Modified: stable/9/sys/dev/cxgbe/t4_main.c
==============================================================================
--- stable/9/sys/dev/cxgbe/t4_main.c    Sun Jul  1 09:17:17 2012        
(r237915)
+++ stable/9/sys/dev/cxgbe/t4_main.c    Sun Jul  1 09:17:55 2012        
(r237916)
@@ -174,7 +174,7 @@ TUNABLE_INT("hw.cxgbe.nofldrxq1g", &t4_n
 static int t4_tmr_idx_10g = TMR_IDX_10G;
 TUNABLE_INT("hw.cxgbe.holdoff_timer_idx_10G", &t4_tmr_idx_10g);
 
-#define PKTC_IDX_10G 2
+#define PKTC_IDX_10G (-1)
 static int t4_pktc_idx_10g = PKTC_IDX_10G;
 TUNABLE_INT("hw.cxgbe.holdoff_pktc_idx_10G", &t4_pktc_idx_10g);
 
@@ -182,7 +182,7 @@ TUNABLE_INT("hw.cxgbe.holdoff_pktc_idx_1
 static int t4_tmr_idx_1g = TMR_IDX_1G;
 TUNABLE_INT("hw.cxgbe.holdoff_timer_idx_1G", &t4_tmr_idx_1g);
 
-#define PKTC_IDX_1G 2
+#define PKTC_IDX_1G (-1)
 static int t4_pktc_idx_1g = PKTC_IDX_1G;
 TUNABLE_INT("hw.cxgbe.holdoff_pktc_idx_1G", &t4_pktc_idx_1g);
 
@@ -1449,6 +1449,11 @@ prep_firmware(struct adapter *sc)
 
        /* Check firmware version and install a different one if necessary */
        rc = t4_check_fw_version(sc);
+       snprintf(sc->fw_version, sizeof(sc->fw_version), "%u.%u.%u.%u",
+           G_FW_HDR_FW_VER_MAJOR(sc->params.fw_vers),
+           G_FW_HDR_FW_VER_MINOR(sc->params.fw_vers),
+           G_FW_HDR_FW_VER_MICRO(sc->params.fw_vers),
+           G_FW_HDR_FW_VER_BUILD(sc->params.fw_vers));
        if (rc != 0) {
                uint32_t v = 0;
 
@@ -1505,6 +1510,12 @@ prep_firmware(struct adapter *sc)
                        } else {
                                /* refresh */
                                (void) t4_check_fw_version(sc);
+                               snprintf(sc->fw_version,
+                                   sizeof(sc->fw_version), "%u.%u.%u.%u",
+                                   G_FW_HDR_FW_VER_MAJOR(sc->params.fw_vers),
+                                   G_FW_HDR_FW_VER_MINOR(sc->params.fw_vers),
+                                   G_FW_HDR_FW_VER_MICRO(sc->params.fw_vers),
+                                   G_FW_HDR_FW_VER_BUILD(sc->params.fw_vers));
                        }
                }
        }
@@ -1548,11 +1559,6 @@ prep_firmware(struct adapter *sc)
                        goto done;      /* error message displayed already */
        }
 
-       snprintf(sc->fw_version, sizeof(sc->fw_version), "%u.%u.%u.%u",
-           G_FW_HDR_FW_VER_MAJOR(sc->params.fw_vers),
-           G_FW_HDR_FW_VER_MINOR(sc->params.fw_vers),
-           G_FW_HDR_FW_VER_MICRO(sc->params.fw_vers),
-           G_FW_HDR_FW_VER_BUILD(sc->params.fw_vers));
        sc->flags |= FW_OK;
 
 done:

Modified: stable/9/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- stable/9/sys/dev/cxgbe/t4_sge.c     Sun Jul  1 09:17:17 2012        
(r237915)
+++ stable/9/sys/dev/cxgbe/t4_sge.c     Sun Jul  1 09:17:55 2012        
(r237916)
@@ -1420,9 +1420,12 @@ init_iq(struct sge_iq *iq, struct adapte
 
        iq->flags = 0;
        iq->adapter = sc;
-       iq->intr_params = V_QINTR_TIMER_IDX(tmr_idx) |
-           V_QINTR_CNT_EN(pktc_idx >= 0);
-       iq->intr_pktc_idx = pktc_idx;
+       iq->intr_params = V_QINTR_TIMER_IDX(tmr_idx);
+       iq->intr_pktc_idx = SGE_NCOUNTERS - 1;
+       if (pktc_idx >= 0) {
+               iq->intr_params |= F_QINTR_CNT_EN;
+               iq->intr_pktc_idx = pktc_idx;
+       }
        iq->qsize = roundup(qsize, 16);         /* See FW_IQ_CMD/iqsize */
        iq->esize = max(esize, 16);             /* See FW_IQ_CMD/iqesize */
        strlcpy(iq->lockname, name, sizeof(iq->lockname));

Modified: stable/9/sys/modules/cxgb/cxgb/Makefile
==============================================================================
--- stable/9/sys/modules/cxgb/cxgb/Makefile     Sun Jul  1 09:17:17 2012        
(r237915)
+++ stable/9/sys/modules/cxgb/cxgb/Makefile     Sun Jul  1 09:17:55 2012        
(r237916)
@@ -8,9 +8,21 @@ SRCS=  cxgb_mc5.c cxgb_vsc8211.c cxgb_ael
 SRCS+= cxgb_xgmac.c cxgb_vsc7323.c cxgb_t3_hw.c cxgb_main.c cxgb_aq100x.c
 SRCS+=  cxgb_sge.c cxgb_offload.c cxgb_tn1010.c
 SRCS+= device_if.h bus_if.h pci_if.h
-SRCS+= opt_inet.h opt_zero.h opt_sched.h
+SRCS+= opt_inet.h opt_inet6.h opt_zero.h opt_sched.h
 SRCS+= uipc_mvec.c
 
 CFLAGS+= -g -DDEFAULT_JUMBO -I${CXGB}
 
+.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>
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to