summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2017-11-24 07:02:56 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2017-11-24 07:02:56 +0000
commit34f8ee06ad27b530db073e6e0ca3693e74271901 (patch)
tree5e722f798c3e4ce085019492dafb7fc547da2fef /sys
parent8c8ca2984185a4971d1e2ba781ed9b1c266168b1 (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.c95
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