Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Jan 2017 17:07:37 +0000 (UTC)
From:      Luiz Otavio O Souza <loos@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r312636 - head/sys/arm/ti/cpsw
Message-ID:  <201701221707.v0MH7bAF027769@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: loos
Date: Sun Jan 22 17:07:37 2017
New Revision: 312636
URL: https://svnweb.freebsd.org/changeset/base/312636

Log:
  Properly assemble an mbuf chain out of received fragments.
  
  Remove the rx_batch hack, it makes no difference now that most of bugs have
  been sorted out.
  
  Sponsored by:	Rubicon Communications, LLC (Netgate)

Modified:
  head/sys/arm/ti/cpsw/if_cpsw.c
  head/sys/arm/ti/cpsw/if_cpswvar.h

Modified: head/sys/arm/ti/cpsw/if_cpsw.c
==============================================================================
--- head/sys/arm/ti/cpsw/if_cpsw.c	Sun Jan 22 17:05:33 2017	(r312635)
+++ head/sys/arm/ti/cpsw/if_cpsw.c	Sun Jan 22 17:07:37 2017	(r312636)
@@ -1582,14 +1582,19 @@ cpsw_intr_rx(void *arg)
 static struct mbuf *
 cpsw_rx_dequeue(struct cpsw_softc *sc)
 {
+	int nsegs, port, removed;
 	struct cpsw_cpdma_bd bd;
 	struct cpsw_slot *last, *slot;
 	struct cpswp_softc *psc;
-	struct mbuf *mb_head, *mb_tail;
-	int port, removed = 0;
+	struct mbuf *m, *m0, *mb_head, *mb_tail;
+	uint16_t m0_flags;
 
+	nsegs = 0;
+	m0 = NULL;
 	last = NULL;
-	mb_head = mb_tail = NULL;
+	mb_head = NULL;
+	mb_tail = NULL;
+	removed = 0;
 
 	/* Pull completed packets off hardware RX queue. */
 	while ((slot = STAILQ_FIRST(&sc->rx.active)) != NULL) {
@@ -1612,10 +1617,12 @@ cpsw_rx_dequeue(struct cpsw_softc *sc)
 		bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_POSTREAD);
 		bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
 
+		m = slot->mbuf;
+		slot->mbuf = NULL;
+
 		if (bd.flags & CPDMA_BD_TDOWNCMPLT) {
 			CPSW_DEBUGF(sc, ("RX teardown is complete"));
-			m_freem(slot->mbuf);
-			slot->mbuf = NULL;
+			m_freem(m);
 			sc->rx.running = 0;
 			sc->rx.teardown = 0;
 			break;
@@ -1627,28 +1634,36 @@ cpsw_rx_dequeue(struct cpsw_softc *sc)
 		psc = device_get_softc(sc->port[port].dev);
 
 		/* Set up mbuf */
-		/* TODO: track SOP/EOP bits to assemble a full mbuf
-		   out of received fragments. */
-		slot->mbuf->m_data += bd.bufoff;
-		slot->mbuf->m_len = bd.buflen;
+		m->m_data += bd.bufoff;
+		m->m_len = bd.buflen;
 		if (bd.flags & CPDMA_BD_SOP) {
-			slot->mbuf->m_pkthdr.len = bd.pktlen;
-			slot->mbuf->m_pkthdr.rcvif = psc->ifp;
-			slot->mbuf->m_flags |= M_PKTHDR;
-		}
-		slot->mbuf->m_next = NULL;
-		slot->mbuf->m_nextpkt = NULL;
-		if (bd.flags & CPDMA_BD_PASS_CRC)
-			m_adj(slot->mbuf, -ETHER_CRC_LEN);
+			m->m_pkthdr.len = bd.pktlen;
+			m->m_pkthdr.rcvif = psc->ifp;
+			m->m_flags |= M_PKTHDR;
+			m0_flags = bd.flags;
+			m0 = m;
+		}
+		nsegs++;
+		m->m_next = NULL;
+		m->m_nextpkt = NULL;
+		if (bd.flags & CPDMA_BD_EOP && m0 != NULL) {
+			if (m0_flags & CPDMA_BD_PASS_CRC)
+				m_adj(m0, -ETHER_CRC_LEN);
+			m0_flags = 0;
+			m0 = NULL;
+			if (nsegs > sc->rx.longest_chain)
+				sc->rx.longest_chain = nsegs;
+			nsegs = 0;
+		}
 
 		if ((psc->ifp->if_capenable & IFCAP_RXCSUM) != 0) {
 			/* check for valid CRC by looking into pkt_err[5:4] */
 			if ((bd.flags &
 			    (CPDMA_BD_SOP | CPDMA_BD_PKT_ERR_MASK)) ==
 			    CPDMA_BD_SOP) {
-				slot->mbuf->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
-				slot->mbuf->m_pkthdr.csum_flags |= CSUM_IP_VALID;
-				slot->mbuf->m_pkthdr.csum_data = 0xffff;
+				m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
+				m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+				m->m_pkthdr.csum_data = 0xffff;
 			}
 		}
 
@@ -1661,15 +1676,21 @@ cpsw_rx_dequeue(struct cpsw_softc *sc)
 		}
 
 		/* Add mbuf to packet list to be returned. */
-		if (mb_tail) {
-			mb_tail->m_nextpkt = slot->mbuf;
+		if (mb_tail != NULL && (bd.flags & CPDMA_BD_SOP)) {
+			mb_tail->m_nextpkt = m;
+		} else if (mb_tail != NULL) {
+			mb_tail->m_next = m;
+		} else if (mb_tail == NULL && (bd.flags & CPDMA_BD_SOP) == 0) {
+			if (bootverbose)
+				printf(
+				    "%s: %s: discanding fragment packet w/o header\n",
+				    __func__, psc->ifp->if_xname);
+			m_freem(m);
+			continue;
 		} else {
-			mb_head = slot->mbuf;
+			mb_head = m;
 		}
-		mb_tail = slot->mbuf;
-		slot->mbuf = NULL;
-		if (sc->rx_batch > 0 && sc->rx_batch == removed)
-			break;
+		mb_tail = m;
 	}
 
 	if (removed != 0) {
@@ -2686,9 +2707,6 @@ cpsw_add_sysctls(struct cpsw_softc *sc)
 	SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "debug",
 	    CTLFLAG_RW, &sc->debug, 0, "Enable switch debug messages");
 
-	SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "rx_batch",
-	    CTLFLAG_RW, &sc->rx_batch, 0, "Set the rx batch size");
-
 	SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "attachedSecs",
 	    CTLTYPE_UINT | CTLFLAG_RD, sc, 0, cpsw_stat_attached, "IU",
 	    "Time since driver attach");

Modified: head/sys/arm/ti/cpsw/if_cpswvar.h
==============================================================================
--- head/sys/arm/ti/cpsw/if_cpswvar.h	Sun Jan 22 17:05:33 2017	(r312635)
+++ head/sys/arm/ti/cpsw/if_cpswvar.h	Sun Jan 22 17:07:37 2017	(r312636)
@@ -89,7 +89,6 @@ struct cpsw_softc {
 	int		active_slave;
 	int		debug;
 	int		dualemac;
-	int		rx_batch;
 	phandle_t	node;
 	struct bintime	attach_uptime; /* system uptime when attach happened. */
 	struct cpsw_port port[2];



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