Index: if_rge.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_rge.c,v retrieving revision 1.21 diff -u -p -r1.21 if_rge.c --- if_rge.c 21 Dec 2022 02:31:09 -0000 1.21 +++ if_rge.c 2 Apr 2023 21:24:27 -0000 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -493,19 +494,15 @@ rge_encap(struct rge_queues *q, struct m /* 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), - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - /* Update info of TX queue and descriptors. */ txq->txq_mbuf = m; txq->txq_descidx = last; + /* Transfer ownership of packet to the chip. */ + membar_producer(); + d = &q->q_tx.rge_tx_list[idx]; + d->rge_cmdsts |= htole32(RGE_TDCMDSTS_OWN); + return (nsegs); } @@ -579,6 +576,10 @@ rge_start(struct ifqueue *ifq) free += RGE_TX_LIST_CNT; free -= idx; + bus_dmamap_sync(sc->sc_dmat, q->q_tx.rge_tx_list_map, + 0, sizeof(struct rge_tx_desc) * RGE_TX_LIST_CNT, + BUS_DMASYNC_POSTWRITE); + for (;;) { if (RGE_TX_NSEGS >= free + 2) { ifq_set_oactive(&ifp->if_snd); @@ -610,6 +611,10 @@ rge_start(struct ifqueue *ifq) queued++; } + bus_dmamap_sync(sc->sc_dmat, q->q_tx.rge_tx_list_map, + 0, sizeof(struct rge_tx_desc) * RGE_TX_LIST_CNT, + BUS_DMASYNC_PREWRITE); + if (queued == 0) return; @@ -1320,6 +1325,10 @@ rge_txeof(struct rge_queues *q) prod = q->q_tx.rge_txq_prodidx; cons = q->q_tx.rge_txq_considx; + bus_dmamap_sync(sc->sc_dmat, q->q_tx.rge_tx_list_map, + 0, sizeof(struct rge_tx_desc) * RGE_TX_LIST_CNT, + BUS_DMASYNC_POSTREAD); + while (prod != cons) { txq = &q->q_tx.rge_txq[cons]; idx = txq->txq_descidx; @@ -1355,6 +1364,10 @@ rge_txeof(struct rge_queues *q) cons = RGE_NEXT_TX_DESC(idx); free = 1; } + + bus_dmamap_sync(sc->sc_dmat, q->q_tx.rge_tx_list_map, + 0, sizeof(struct rge_tx_desc) * RGE_TX_LIST_CNT, + BUS_DMASYNC_PREREAD); if (free == 0) return (0);