summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/gen68360/network/network.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2000-02-11 15:21:40 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2000-02-11 15:21:40 +0000
commit35ece2ecb2e2f7669643c42d4157cf499d223dbe (patch)
treef95fe20ae64269960a304adaf009e5a15780d23d /c/src/lib/libbsp/m68k/gen68360/network/network.c
parentFixed typos introduced in last modification. Spotted by (diff)
downloadrtems-35ece2ecb2e2f7669643c42d4157cf499d223dbe.tar.bz2
Patch from Eric Norum <eric@cls.usask.ca> based on working with
Bob Wisdon <bobwis@ascweb.co.uk> and Chris Johns <ccj@acm.org> to resolve a random network lockup problem. ckinit.c: Occasional network lockups have been noted when the PIT has a higher interrupt request level than the CPM. The SCC1 bit in the CISR is set even though the SCC1 interrupt handler is not active. This blocks interrupts from SCC1 (and all other CPM sources) and locks up the system. It has not been determined whether the error is within the 68360 or in the RTEMS interrupt support assembler code. The solution, for now, is to set both PIT and CPM interrupt request levels to the same value (4). network.c: Set CPM transmitter buffer pointer (_tbptr) to beginning of frame before restarting transmitter. Don't retire transmitter buffer descriptors belonging to the restarted frame.
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++;