From 05792cf6978f4b058c09f5ff9c7bbc6f1c445e43 Mon Sep 17 00:00:00 2001 From: Patrick Wildt Date: Fri, 26 Jun 2020 09:40:43 +0000 Subject: Add TX completion handling. I'm not quite sure, but I think that we receive interrupts for the physical TX queues, but the TX buffers which need to be freed were taken from the aggregated (per core) TX queue. This means we probably should have the physical TX queues tied to specific cores, so that the TX enqueue and TX completion share the same per-core info for the free-handling. For now we only have a single physical and aggregated TX queue, so it's comparatively easy. --- sys/dev/fdt/if_mvpp.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) (limited to 'sys/dev/fdt') diff --git a/sys/dev/fdt/if_mvpp.c b/sys/dev/fdt/if_mvpp.c index b367a80b255..4511646c7d1 100644 --- a/sys/dev/fdt/if_mvpp.c +++ b/sys/dev/fdt/if_mvpp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mvpp.c,v 1.4 2020/06/26 09:30:10 patrick Exp $ */ +/* $OpenBSD: if_mvpp.c,v 1.5 2020/06/26 09:40:42 patrick Exp $ */ /* * Copyright (c) 2008, 2019 Mark Kettenis * Copyright (c) 2017, 2020 Patrick Wildt @@ -280,6 +280,7 @@ void mvpp2_rxtick(void *); int mvpp2_link_intr(void *); int mvpp2_intr(void *); void mvpp2_tx_proc(struct mvpp2_port *, uint8_t); +void mvpp2_txq_proc(struct mvpp2_port *, struct mvpp2_tx_queue *); void mvpp2_rx_proc(struct mvpp2_port *, uint8_t); void mvpp2_rxq_proc(struct mvpp2_port *, struct mvpp2_rx_queue *); @@ -1967,22 +1968,52 @@ mvpp2_intr(void *arg) void mvpp2_tx_proc(struct mvpp2_port *sc, uint8_t queues) { -// struct ifnet *ifp = &sc->sc_ac.ac_if; struct mvpp2_tx_queue *txq; - uint32_t reg; int i; for (i = 0; i < sc->sc_ntxq; i++) { txq = &sc->sc_txqs[i]; if ((queues & (1 << i)) == 0) continue; - reg = mvpp2_read(sc->sc, MVPP2_TXQ_SENT_REG(txq->id)); - printf("%s: txq %u sent reg %u\n", sc->sc_dev.dv_xname, - i, (reg & MVPP2_TRANSMITTED_COUNT_MASK) >> - MVPP2_TRANSMITTED_COUNT_OFFSET); + mvpp2_txq_proc(sc, txq); } +} - /* FIXME: tx done processing */ +void +mvpp2_txq_proc(struct mvpp2_port *sc, struct mvpp2_tx_queue *txq) +{ + struct ifnet *ifp = &sc->sc_ac.ac_if; + struct mvpp2_tx_queue *aggr_txq = &sc->sc->sc_aggr_txqs[0]; + struct mvpp2_buf *txb; + int i, idx, nsent; + + nsent = (mvpp2_read(sc->sc, MVPP2_TXQ_SENT_REG(txq->id)) & + MVPP2_TRANSMITTED_COUNT_MASK) >> + MVPP2_TRANSMITTED_COUNT_OFFSET; + + for (i = 0; i < nsent; i++) { + idx = aggr_txq->cons; + KASSERT(idx < MVPP2_AGGR_TXQ_SIZE); + + txb = &aggr_txq->buf[idx]; + if (txb->mb_m) { + bus_dmamap_sync(sc->sc_dmat, txb->mb_map, 0, + txb->mb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmat, txb->mb_map); + + m_freem(txb->mb_m); + txb->mb_m = NULL; + } + + aggr_txq->cnt--; + aggr_txq->cons = (aggr_txq->cons + 1) % MVPP2_AGGR_TXQ_SIZE; + } + + if (aggr_txq->cnt == 0) + ifp->if_timer = 0; + + if (ifq_is_oactive(&ifp->if_snd)) + ifq_restart(&ifp->if_snd); } void -- cgit v1.2.3