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.
This commit is contained in:
Joel Sherrill
2000-02-11 15:21:40 +00:00
parent 1249edfa3a
commit 35ece2ecb2
3 changed files with 45 additions and 1 deletions

View File

@@ -299,3 +299,17 @@ The board support package has been tested with:
Arnewsh Inc.
P.O. Box 270352
Fort Collins, CO 80527-0352
Interrupt Notes
===============
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).

View File

@@ -35,7 +35,7 @@
#include "m68360.h"
#define CLOCK_VECTOR 120
#define CLOCK_IRQ_LEVEL 6
#define CLOCK_IRQ_LEVEL 4
/*
* Clock_driver_ticks is a monotonically increasing counter of the

View File

@@ -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)
@@ -371,10 +373,38 @@ m360Enet_retire_tx_bd (struct scc_softc *sc)
if (status & M360_BD_UNDERRUN)
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++;