Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Aug 2010 02:14:02 +0000 (UTC)
From:      Navdeep Parhar <np@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r211856 - stable/7/sys/dev/cxgb
Message-ID:  <201008270214.o7R2E2tQ060108@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: np
Date: Fri Aug 27 02:14:02 2010
New Revision: 211856
URL: http://svn.freebsd.org/changeset/base/211856

Log:
  MFC r204348, r206109
  
  r204348
  Support IFCAP_VLAN_HWTSO capability.
  
  r206109
  Bump response queue size to 2K, add statistic for starvation.

Modified:
  stable/7/sys/dev/cxgb/cxgb_adapter.h
  stable/7/sys/dev/cxgb/cxgb_main.c
  stable/7/sys/dev/cxgb/cxgb_sge.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/dev/cxgb/cxgb_adapter.h
==============================================================================
--- stable/7/sys/dev/cxgb/cxgb_adapter.h	Thu Aug 26 23:44:32 2010	(r211855)
+++ stable/7/sys/dev/cxgb/cxgb_adapter.h	Fri Aug 27 02:14:02 2010	(r211856)
@@ -149,7 +149,7 @@ enum {
 
 #define FL_Q_SIZE	4096
 #define JUMBO_Q_SIZE	1024
-#define RSPQ_Q_SIZE	1024
+#define RSPQ_Q_SIZE	2048
 #define TX_ETH_Q_SIZE	1024
 
 enum { TXQ_ETH = 0,
@@ -187,6 +187,7 @@ struct sge_rspq {
 	uint32_t        offload_bundles;
 	uint32_t        pure_rsps;
 	uint32_t        unhandled_irqs;
+	uint32_t        starved;
 
 	bus_addr_t	phys_addr;
 	bus_dma_tag_t	desc_tag;

Modified: stable/7/sys/dev/cxgb/cxgb_main.c
==============================================================================
--- stable/7/sys/dev/cxgb/cxgb_main.c	Thu Aug 26 23:44:32 2010	(r211855)
+++ stable/7/sys/dev/cxgb/cxgb_main.c	Fri Aug 27 02:14:02 2010	(r211856)
@@ -1012,9 +1012,9 @@ cxgb_makedev(struct port_info *pi)
 }
 
 #ifdef TSO_SUPPORTED
-#define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO)
+#define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO | IFCAP_VLAN_HWTSO)
 /* Don't enable TSO6 yet */
-#define CXGB_CAP_ENABLE (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO4 | IFCAP_JUMBO_MTU | IFCAP_LRO)
+#define CXGB_CAP_ENABLE (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO4 | IFCAP_JUMBO_MTU | IFCAP_LRO | IFCAP_VLAN_HWTSO)
 #else
 #define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_JUMBO_MTU)
 /* Don't enable TSO6 yet */
@@ -1072,9 +1072,9 @@ cxgb_port_attach(device_t dev)
 	/*
 	 * disable TSO on 4-port - it isn't supported by the firmware yet
 	 */	
-	if (p->adapter->params.nports > 2) {
-		ifp->if_capabilities &= ~(IFCAP_TSO4 | IFCAP_TSO6);
-		ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TSO6);
+	if (sc->params.nports > 2) {
+		ifp->if_capabilities &= ~(IFCAP_TSO4 | IFCAP_TSO6 | IFCAP_VLAN_HWTSO);
+		ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TSO6 | IFCAP_VLAN_HWTSO);
 		ifp->if_hwassist &= ~CSUM_TSO;
 	}
 
@@ -2095,28 +2095,34 @@ fail:
 
 		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 		if (mask & IFCAP_TXCSUM) {
-			if (IFCAP_TXCSUM & ifp->if_capenable) {
-				ifp->if_capenable &= ~(IFCAP_TXCSUM|IFCAP_TSO4);
-				ifp->if_hwassist &= ~(CSUM_TCP | CSUM_UDP
-				    | CSUM_IP | CSUM_TSO);
-			} else {
-				ifp->if_capenable |= IFCAP_TXCSUM;
-				ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP
-				    | CSUM_IP);
+			ifp->if_capenable ^= IFCAP_TXCSUM;
+			ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP);
+
+			if (IFCAP_TSO & ifp->if_capenable &&
+			    !(IFCAP_TXCSUM & ifp->if_capenable)) {
+				ifp->if_capenable &= ~IFCAP_TSO;
+				ifp->if_hwassist &= ~CSUM_TSO;
+				if_printf(ifp,
+				    "tso disabled due to -txcsum.\n");
 			}
 		}
-		if (mask & IFCAP_RXCSUM) {
+		if (mask & IFCAP_RXCSUM)
 			ifp->if_capenable ^= IFCAP_RXCSUM;
-		}
 		if (mask & IFCAP_TSO4) {
-			if (IFCAP_TSO4 & ifp->if_capenable) {
-				ifp->if_capenable &= ~IFCAP_TSO4;
-				ifp->if_hwassist &= ~CSUM_TSO;
-			} else if (IFCAP_TXCSUM & ifp->if_capenable) {
-				ifp->if_capenable |= IFCAP_TSO4;
-				ifp->if_hwassist |= CSUM_TSO;
+			ifp->if_capenable ^= IFCAP_TSO4;
+
+			if (IFCAP_TSO & ifp->if_capenable) {
+				if (IFCAP_TXCSUM & ifp->if_capenable)
+					ifp->if_hwassist |= CSUM_TSO;
+				else {
+					ifp->if_capenable &= ~IFCAP_TSO;
+					ifp->if_hwassist &= ~CSUM_TSO;
+					if_printf(ifp,
+					    "enable txcsum first.\n");
+					error = EAGAIN;
+				}
 			} else
-				error = EINVAL;
+				ifp->if_hwassist &= ~CSUM_TSO;
 		}
 		if (mask & IFCAP_LRO) {
 			ifp->if_capenable ^= IFCAP_LRO;
@@ -2140,6 +2146,8 @@ fail:
 				PORT_UNLOCK(p);
 			}
 		}
+		if (mask & IFCAP_VLAN_HWTSO)
+			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
 		if (mask & IFCAP_VLAN_HWCSUM)
 			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
 
@@ -2431,25 +2439,33 @@ cxgb_tick_handler(void *arg, int count)
 	if (p->rev == T3_REV_B2 && p->nports < 4 && sc->open_device_map) 
 		check_t3b2_mac(sc);
 
-	cause = t3_read_reg(sc, A_SG_INT_CAUSE);
-	reset = 0;
-	if (cause & F_FLEMPTY) {
+	cause = t3_read_reg(sc, A_SG_INT_CAUSE) & (F_RSPQSTARVE | F_FLEMPTY);
+	if (cause) {
 		struct sge_qset *qs = &sc->sge.qs[0];
+		uint32_t mask, v;
+
+		v = t3_read_reg(sc, A_SG_RSPQ_FL_STATUS) & ~0xff00;
+
+		mask = 1;
+		for (i = 0; i < SGE_QSETS; i++) {
+			if (v & mask)
+				qs[i].rspq.starved++;
+			mask <<= 1;
+		}
 
-		i = 0;
-		reset |= F_FLEMPTY;
+		mask <<= SGE_QSETS; /* skip RSPQXDISABLED */
 
-		cause = (t3_read_reg(sc, A_SG_RSPQ_FL_STATUS) >>
-			 S_FL0EMPTY) & 0xffff;
-		while (cause) {
-			qs->fl[i].empty += (cause & 1);
-			if (i)
-				qs++;
-			i ^= 1;
-			cause >>= 1;
+		for (i = 0; i < SGE_QSETS * 2; i++) {
+			if (v & mask) {
+				qs[i / 2].fl[i % 2].empty++;
+			}
+			mask <<= 1;
 		}
+
+		/* clear */
+		t3_write_reg(sc, A_SG_RSPQ_FL_STATUS, v);
+		t3_write_reg(sc, A_SG_INT_CAUSE, cause);
 	}
-	t3_write_reg(sc, A_SG_INT_CAUSE, reset);
 
 	for (i = 0; i < sc->params.nports; i++) {
 		struct port_info *pi = &sc->port[i];

Modified: stable/7/sys/dev/cxgb/cxgb_sge.c
==============================================================================
--- stable/7/sys/dev/cxgb/cxgb_sge.c	Thu Aug 26 23:44:32 2010	(r211855)
+++ stable/7/sys/dev/cxgb/cxgb_sge.c	Fri Aug 27 02:14:02 2010	(r211856)
@@ -52,6 +52,11 @@ __FBSDID("$FreeBSD$");
 #include <sys/smp.h>
 #include <sys/systm.h>
 #include <sys/syslog.h>
+#include <sys/socket.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_vlan_var.h>
 
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
@@ -1215,8 +1220,8 @@ write_wr_hdr_sgl(unsigned int ndesc, str
 	}
 }
 
-/* sizeof(*eh) + sizeof(*vhdr) + sizeof(*ip) + sizeof(*tcp) */
-#define TCPPKTHDRSIZE (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + 20 + 20)
+/* sizeof(*eh) + sizeof(*ip) + sizeof(*tcp) */
+#define TCPPKTHDRSIZE (ETHER_HDR_LEN + 20 + 20)
 
 #ifdef VLAN_SUPPORTED
 #define GET_VTAG(cntrl, m) \
@@ -1266,12 +1271,7 @@ t3_encap(struct sge_qset *qs, struct mbu
 	txsd = &txq->sdesc[txq->pidx];
 	sgl = txq->txq_sgl;
 	m0 = *m;
-	
-	DPRINTF("t3_encap port_id=%d qsidx=%d ", pi->port_id, pi->first_qset);
-	DPRINTF("mlen=%d txpkt_intf=%d tx_chan=%d\n", m[0]->m_pkthdr.len, pi->txpkt_intf, pi->tx_chan);
-	if (cxgb_debug)
-		printf("mi_base=%p cidx=%d pidx=%d\n\n", txsd->mi.mi_base, txq->cidx, txq->pidx);
-	
+
 	mtx_assert(&txq->lock, MA_OWNED);
 	cntrl = V_TXPKT_INTF(pi->txpkt_intf);
 /*
@@ -1339,11 +1339,11 @@ t3_encap(struct sge_qset *qs, struct mbu
 		
 		return (0);		
 	} else if (tso_info) {
-		int min_size = TCPPKTHDRSIZE, eth_type, tagged;
+		int eth_type;
 		struct cpl_tx_pkt_lso *hdr = (struct cpl_tx_pkt_lso *)txd;
+		struct ether_header *eh;
 		struct ip *ip;
 		struct tcphdr *tcp;
-		char *pkthdr;
 
 		txd->flit[2] = 0;
 		GET_VTAG(cntrl, m0);
@@ -1352,13 +1352,7 @@ t3_encap(struct sge_qset *qs, struct mbu
 		mlen = m0->m_pkthdr.len;
 		hdr->len = htonl(mlen | 0x80000000);
 
-		DPRINTF("tso buf len=%d\n", mlen);
-
-		tagged = m0->m_flags & M_VLANTAG;
-		if (!tagged)
-			min_size -= ETHER_VLAN_ENCAP_LEN;
-
-		if (__predict_false(mlen < min_size)) {
+		if (__predict_false(mlen < TCPPKTHDRSIZE)) {
 			printf("mbuf=%p,len=%d,tso_segsz=%d,csum_flags=%#x,flags=%#x",
 			    m0, mlen, m0->m_pkthdr.tso_segsz,
 			    m0->m_pkthdr.csum_flags, m0->m_flags);
@@ -1366,25 +1360,23 @@ t3_encap(struct sge_qset *qs, struct mbu
 		}
 
 		/* Make sure that ether, ip, tcp headers are all in m0 */
-		if (__predict_false(m0->m_len < min_size)) {
-			m0 = m_pullup(m0, min_size);
+		if (__predict_false(m0->m_len < TCPPKTHDRSIZE)) {
+			m0 = m_pullup(m0, TCPPKTHDRSIZE);
 			if (__predict_false(m0 == NULL)) {
 				/* XXX panic probably an overreaction */
 				panic("couldn't fit header into mbuf");
 			}
 		}
-		pkthdr = m0->m_data;
 
-		if (tagged) {
+		eh = mtod(m0, struct ether_header *);
+		if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
 			eth_type = CPL_ETH_II_VLAN;
-			ip = (struct ip *)(pkthdr + ETHER_HDR_LEN +
-			    ETHER_VLAN_ENCAP_LEN);
+			ip = (struct ip *)((struct ether_vlan_header *)eh + 1);
 		} else {
 			eth_type = CPL_ETH_II;
-			ip = (struct ip *)(pkthdr + ETHER_HDR_LEN);
+			ip = (struct ip *)(eh + 1);
 		}
-		tcp = (struct tcphdr *)((uint8_t *)ip +
-		    sizeof(*ip)); 
+		tcp = (struct tcphdr *)(ip + 1);
 
 		tso_info |= V_LSO_ETH_TYPE(eth_type) |
 			    V_LSO_IPHDR_WORDS(ip->ip_hl) |
@@ -1392,11 +1384,10 @@ t3_encap(struct sge_qset *qs, struct mbu
 		hdr->lso_info = htonl(tso_info);
 
 		if (__predict_false(mlen <= PIO_LEN)) {
-			/* pkt not undersized but fits in PIO_LEN
+			/*
+			 * pkt not undersized but fits in PIO_LEN
 			 * Indicates a TSO bug at the higher levels.
 			 */
-			DPRINTF("**5592 Fix** mbuf=%p,len=%d,tso_segsz=%d,csum_flags=%#x,flags=%#x",
-			    m0, mlen, m0->m_pkthdr.tso_segsz, m0->m_pkthdr.csum_flags, m0->m_flags);
 			txq_prod(txq, 1, &txqs);
 			m_copydata(m0, 0, mlen, (caddr_t)&txd->flit[3]);
 			m_freem(m0);
@@ -3487,6 +3478,9 @@ t3_add_configured_sysctls(adapter_t *sc)
 			SYSCTL_ADD_UINT(ctx, rspqpoidlist, OID_AUTO, "credits",
 			    CTLFLAG_RD, &qs->rspq.credits,
 			    0, "#credits");
+			SYSCTL_ADD_UINT(ctx, rspqpoidlist, OID_AUTO, "starved",
+			    CTLFLAG_RD, &qs->rspq.starved,
+			    0, "#times starved");
 			SYSCTL_ADD_XLONG(ctx, rspqpoidlist, OID_AUTO, "phys_addr",
 			    CTLFLAG_RD, &qs->rspq.phys_addr,
 			    "physical_address_of the queue");



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008270214.o7R2E2tQ060108>