summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/gen68360/network/network.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/m68k/gen68360/network/network.c')
-rw-r--r--c/src/lib/libbsp/m68k/gen68360/network/network.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/m68k/gen68360/network/network.c b/c/src/lib/libbsp/m68k/gen68360/network/network.c
index db0340cc58..7dc4f4a73f 100644
--- a/c/src/lib/libbsp/m68k/gen68360/network/network.c
+++ b/c/src/lib/libbsp/m68k/gen68360/network/network.c
@@ -364,6 +364,8 @@ m360Enet_retire_tx_bd (struct scc_softc *sc)
if (status & (M360_BD_LATE_COLLISION |
M360_BD_RETRY_LIMIT |
M360_BD_UNDERRUN)) {
+ int j;
+
if (status & M360_BD_LATE_COLLISION)
scc_softc[0].txLateCollision++;
if (status & M360_BD_RETRY_LIMIT)
@@ -372,9 +374,37 @@ m360Enet_retire_tx_bd (struct scc_softc *sc)
scc_softc[0].txUnderrun++;
/*
+ * Reenable buffer descriptors
+ */
+ j = sc->txBdTail;
+ for (;;) {
+ status = (sc->txBdBase + j)->status;
+ if (status & M360_BD_READY)
+ break;
+ (sc->txBdBase + j)->status = M360_BD_READY |
+ (status & (M360_BD_PAD |
+ M360_BD_WRAP |
+ M360_BD_INTERRUPT |
+ M360_BD_LAST |
+ M360_BD_TX_CRC));
+ if (status & M360_BD_LAST)
+ break;
+ if (++j == sc->txBdCount)
+ j = 0;
+ }
+
+ /*
+ * Move transmitter back to the first
+ * buffer descriptor in the frame.
+ */
+ m360.scc1p._tbptr = m360.scc1p.tbase +
+ sc->txBdTail * sizeof (m360BufferDescriptor_t);
+
+ /*
* Restart the transmitter
*/
M360ExecuteRISC (M360_CR_OP_RESTART_TX | M360_CR_CHAN_SCC1);
+ continue;
}
if (status & M360_BD_DEFER)
scc_softc[0].txDeferred++;