svn commit: r312636 - head/sys/arm/ti/cpsw
Luiz Otavio O Souza
loos at FreeBSD.org
Sun Jan 22 17:07:39 UTC 2017
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];
More information about the svn-src-head
mailing list