aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/mgb
diff options
context:
space:
mode:
authorVincenzo Maffione <vmaffione@FreeBSD.org>2020-09-01 20:41:47 +0000
committerVincenzo Maffione <vmaffione@FreeBSD.org>2020-09-01 20:41:47 +0000
commit35d8a463e8097cffb0e4942c0e3f3b5412ea7953 (patch)
treead5869c5d1db073e296c4c630d2d777a9a591abb /sys/dev/mgb
parentf7eec6b204f10f9f62f78dfe3e9e0ba42a3649fa (diff)
Notes
Diffstat (limited to 'sys/dev/mgb')
-rw-r--r--sys/dev/mgb/if_mgb.c7
-rw-r--r--sys/dev/mgb/if_mgb.h3
2 files changed, 8 insertions, 2 deletions
diff --git a/sys/dev/mgb/if_mgb.c b/sys/dev/mgb/if_mgb.c
index 071bfd81fd71..29e234191589 100644
--- a/sys/dev/mgb/if_mgb.c
+++ b/sys/dev/mgb/if_mgb.c
@@ -1191,7 +1191,12 @@ mgb_isc_rxd_flush(void *xsc, uint16_t rxqid, uint8_t flid, qidx_t pidx)
sc = xsc;
KASSERT(rxqid == 0, ("tried to flush RX Channel %d.\n", rxqid));
- sc->rx_ring_data.last_tail = pidx;
+ /*
+ * According to the programming guide, last_tail must be set to
+ * the last valid RX descriptor, rather than to the one past that.
+ * Note that this is not true for the TX ring!
+ */
+ sc->rx_ring_data.last_tail = MGB_PREV_RING_IDX(pidx);
CSR_WRITE_REG(sc, MGB_DMA_RX_TAIL(rxqid), sc->rx_ring_data.last_tail);
return;
}
diff --git a/sys/dev/mgb/if_mgb.h b/sys/dev/mgb/if_mgb.h
index 84845655bf66..0db5d5e01f85 100644
--- a/sys/dev/mgb/if_mgb.h
+++ b/sys/dev/mgb/if_mgb.h
@@ -178,7 +178,8 @@
#define MGB_DESC_GET_FRAME_LEN(_desc) \
(((_desc)->ctl & MGB_DESC_FRAME_LEN_MASK) >> 16)
-#define MGB_NEXT_RING_IDX(_idx) (((_idx) + 1) % MGB_DMA_RING_SIZE)
+#define MGB_NEXT_RING_IDX(_idx) (((_idx) == MGB_DMA_RING_SIZE - 1) ? 0 : ((_idx_) + 1))
+#define MGB_PREV_RING_IDX(_idx) (((_idx) == 0) ? (MGB_DMA_RING_SIZE - 1) : ((_idx_) - 1))
#define MGB_RING_SPACE(_sc) \
((((_sc)->tx_ring_data.last_head - (_sc)->tx_ring_data.last_tail - 1) \
+ MGB_DMA_RING_SIZE ) % MGB_DMA_RING_SIZE )