Fix TX descriptors DMA syncs. So far only a single TX desc was synced, which
authorpatrick <patrick@openbsd.org>
Sat, 10 Aug 2024 21:53:06 +0000 (21:53 +0000)
committerpatrick <patrick@openbsd.org>
Sat, 10 Aug 2024 21:53:06 +0000 (21:53 +0000)
wasn't even one that we filled.  Ensure that we sync all descs that we touch
before we give the whole chain to the hardware.

ok kettenis@

sys/dev/pci/if_rge.c

index b9d42ee..b6ba514 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_rge.c,v 1.27 2024/06/30 08:13:02 kevlo Exp $       */
+/*     $OpenBSD: if_rge.c,v 1.28 2024/08/10 21:53:06 patrick Exp $     */
 
 /*
  * Copyright (c) 2019, 2020, 2023, 2024
@@ -480,24 +480,27 @@ rge_encap(struct rge_queues *q, struct mbuf *m, int idx)
 
                if (cur == RGE_TX_LIST_CNT - 1)
                        cmdsts |= RGE_TDCMDSTS_EOR;
+               if (i == (txmap->dm_nsegs - 1))
+                       cmdsts |= RGE_TDCMDSTS_EOF;
 
                d->rge_cmdsts = htole32(cmdsts);
 
+               bus_dmamap_sync(sc->sc_dmat, q->q_tx.rge_tx_list_map,
+                   cur * sizeof(struct rge_tx_desc), sizeof(struct rge_tx_desc),
+                   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
                last = cur;
                cmdsts = RGE_TDCMDSTS_OWN;
                cur = RGE_NEXT_TX_DESC(cur);
        }
 
-       /* Set EOF on the last descriptor. */
-       d->rge_cmdsts |= htole32(RGE_TDCMDSTS_EOF);
-
        /* Transfer ownership of packet to the chip. */
        d = &q->q_tx.rge_tx_list[idx];
 
        d->rge_cmdsts |= htole32(RGE_TDCMDSTS_OWN);
 
        bus_dmamap_sync(sc->sc_dmat, q->q_tx.rge_tx_list_map,
-           cur * sizeof(struct rge_tx_desc), sizeof(struct rge_tx_desc),
+           idx * sizeof(struct rge_tx_desc), sizeof(struct rge_tx_desc),
            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
        /* Update info of TX queue and descriptors. */