diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2017-11-24 07:02:56 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2017-11-24 07:02:56 +0000 |
commit | 34f8ee06ad27b530db073e6e0ca3693e74271901 (patch) | |
tree | 5e722f798c3e4ce085019492dafb7fc547da2fef /sys | |
parent | 8c8ca2984185a4971d1e2ba781ed9b1c266168b1 (diff) |
rework transmit to get rid of ifq_deq_begin, and to improve speed.
i had a diff that did a small change to replace
ifq_deq_begin/commit/rollback with ifq_dequeue, and Eduard Nicodei
tweaked it a bit with Artturi Alm to use the fifo registers properly
and bump the ifq len.
the latter changes improve performance significantly.
"if you think that diff is correct, commit it" kettenis@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/armv7/sunxi/sxie.c | 95 |
1 files changed, 44 insertions, 51 deletions
diff --git a/sys/arch/armv7/sunxi/sxie.c b/sys/arch/armv7/sunxi/sxie.c index 1cd713cd52a..116fda5f8d7 100644 --- a/sys/arch/armv7/sunxi/sxie.c +++ b/sys/arch/armv7/sunxi/sxie.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sxie.c,v 1.25 2017/01/22 10:17:37 dlg Exp $ */ +/* $OpenBSD: sxie.c,v 1.26 2017/11/24 07:02:55 dlg Exp $ */ /* * Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se> * Copyright (c) 2013 Artturi Alm @@ -250,7 +250,7 @@ sxie_attach(struct device *parent, struct device *self, void *aux) ifp->if_watchdog = sxie_watchdog; ifp->if_capabilities = IFCAP_VLAN_MTU; /* XXX status check in recv? */ - IFQ_SET_MAXLEN(&ifp->if_snd, 1); + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); /* Initialize MII/media info. */ mii = &sc->sc_mii; @@ -439,16 +439,15 @@ sxie_intr(void *arg) } if (pending & (SXIE_TX_FIFO0 | SXIE_TX_FIFO1)) { - ifq_clr_oactive(&ifp->if_snd); sc->txf_inuse &= ~pending; if (sc->txf_inuse == 0) ifp->if_timer = 0; else ifp->if_timer = 5; - } - if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd)) - sxie_start(ifp); + if (ifq_is_oactive(&ifp->if_snd)) + ifq_restart(&ifp->if_snd); + } SXISET4(sc, SXIE_INTCR, SXIE_INTR_ENABLE); @@ -468,65 +467,59 @@ sxie_start(struct ifnet *ifp) uint32_t fifo; uint32_t txbuf[SXIE_MAX_PKT_SIZE / sizeof(uint32_t)]; /* XXX !!! */ - if (sc->txf_inuse == (SXIE_TX_FIFO0 | SXIE_TX_FIFO1)) - ifq_set_oactive(&ifp->if_snd); - if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd)) return; + td = (uint8_t *)&txbuf[0]; m = NULL; head = NULL; -trynext: - m = ifq_deq_begin(&ifp->if_snd); - if (m == NULL) - return; - if (m->m_pkthdr.len > SXIE_MAX_PKT_SIZE) { - ifq_deq_commit(&ifp->if_snd, m); - printf("sxie_start: packet too big\n"); - m_freem(m); - return; - } + for (;;) { + if (sc->txf_inuse == (SXIE_TX_FIFO0 | SXIE_TX_FIFO1)) { + ifq_set_oactive(&ifp->if_snd); + break; + } - if (sc->txf_inuse == (SXIE_TX_FIFO0 | SXIE_TX_FIFO1)) { - ifq_deq_rollback(&ifp->if_snd, m); - printf("sxie_start: tx fifos in use.\n"); - ifq_set_oactive(&ifp->if_snd); - return; - } + m = ifq_dequeue(&ifp->if_snd); + if (m == NULL) + break; - /* select fifo */ - if (sc->txf_inuse & SXIE_TX_FIFO0) { - sc->txf_inuse |= SXIE_TX_FIFO1; - fifo = 1; - } else { - sc->txf_inuse |= SXIE_TX_FIFO0; - fifo = 0; - } - SXIWRITE4(sc, SXIE_TXINS, fifo); + if (m->m_pkthdr.len > SXIE_MAX_PKT_SIZE) { + m_freem(m); + continue; + } - /* set packet length */ - SXIWRITE4(sc, SXIE_TXPKTLEN0 + (fifo * 4), m->m_pkthdr.len); +#if NBPFILTER > 0 + if (ifp->if_bpf) + bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); +#endif - /* copy the actual packet to fifo XXX through 'align buffer'.. */ - m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)td); - bus_space_write_multi_4(sc->sc_iot, sc->sc_ioh, - SXIE_TXIO0 + (fifo * 4), - (uint32_t *)td, SXIE_ROUNDUP(m->m_pkthdr.len, 4) >> 2); + /* select fifo */ + if (sc->txf_inuse & SXIE_TX_FIFO0) { + sc->txf_inuse |= SXIE_TX_FIFO1; + fifo = 1; + } else { + sc->txf_inuse |= SXIE_TX_FIFO0; + fifo = 0; + } + SXIWRITE4(sc, SXIE_TXINS, fifo); - /* transmit to PHY from fifo */ - SXISET4(sc, SXIE_TXCR0 + (fifo * 4), 1); - ifp->if_timer = 5; - ifq_deq_commit(&ifp->if_snd, m); + /* set packet length */ + SXIWRITE4(sc, SXIE_TXPKTLEN0 + (fifo * 4), m->m_pkthdr.len); -#if NBPFILTER > 0 - if (ifp->if_bpf) - bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); -#endif - m_freem(m); + /* copy the actual packet to fifo XXX through 'align buffer' */ + m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)td); + bus_space_write_multi_4(sc->sc_iot, sc->sc_ioh, + SXIE_TXIO0, + (uint32_t *)td, SXIE_ROUNDUP(m->m_pkthdr.len, 4) >> 2); - goto trynext; + /* transmit to PHY from fifo */ + SXISET4(sc, SXIE_TXCR0 + (fifo * 4), 1); + ifp->if_timer = 5; + + m_freem(m); + } } void |