summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_rge.c
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2024-08-10 21:53:07 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2024-08-10 21:53:07 +0000
commitda78b99976e33dbdf93db6a21f3773fdd88f7914 (patch)
tree778f0c5f77615b8722fe15b76b57a4e1891b67b4 /sys/dev/pci/if_rge.c
parentcde60ccdd163ade80e42aa1c16aa93f1f09e1e40 (diff)
Fix TX descriptors DMA syncs. So far only a single TX desc was synced, which
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@
Diffstat (limited to 'sys/dev/pci/if_rge.c')
-rw-r--r--sys/dev/pci/if_rge.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/sys/dev/pci/if_rge.c b/sys/dev/pci/if_rge.c
index b9d42eedfda..b6ba51494d5 100644
--- a/sys/dev/pci/if_rge.c
+++ b/sys/dev/pci/if_rge.c
@@ -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. */