Port-sgimips archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: mec and resets
jacereda%gmail.com@localhost wrote:
> Does that mean you reproduced it? Should I try the patch?
Please try this one.
---
Index: if_mec.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/mace/if_mec.c,v
retrieving revision 1.20
diff -u -r1.20 if_mec.c
--- if_mec.c 14 May 2008 13:29:28 -0000 1.20
+++ if_mec.c 1 Aug 2008 13:26:23 -0000
@@ -179,7 +179,7 @@
#define MEC_TXSTAT_UNUSED 0x7fffffffe0000000ULL /* should be zero */
#define MEC_TXSTAT_SENT 0x8000000000000000ULL /* packet sent
*/
- uint64_t txd_ptr[MEC_NTXPTR];
+ volatile uint64_t txd_ptr[MEC_NTXPTR];
#define MEC_TXPTR_UNUSED2 0x0000000000000007 /* should be zero */
#define MEC_TXPTR_DMAADDR 0x00000000fffffff8 /* TX DMA address */
#define MEC_TXPTR_LEN 0x0000ffff00000000ULL /* buffer length */
@@ -342,7 +342,7 @@
static int mec_intr(void *arg);
static void mec_stop(struct ifnet *, int);
static void mec_rxintr(struct mec_softc *);
-static void mec_txintr(struct mec_softc *);
+static void mec_txintr(struct mec_softc *, uint32_t);
static void mec_shutdown(void *);
CFATTACH_DECL_NEW(mec, sizeof(struct mec_softc),
@@ -1223,7 +1223,7 @@
bus_space_tag_t st = sc->sc_st;
bus_space_handle_t sh = sc->sc_sh;
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
- uint32_t statreg, statack, dmac;
+ uint32_t statreg, statack, txring;
int handled, sent;
DPRINTF(MEC_DEBUG_INTR, ("mec_intr: called\n"));
@@ -1249,7 +1249,6 @@
mec_rxintr(sc);
}
- dmac = bus_space_read_8(st, sh, MEC_DMA_CONTROL);
DPRINTF(MEC_DEBUG_INTR,
("mec_intr: DMA_CONT = 0x%08x\n", dmac));
@@ -1257,10 +1256,11 @@
(MEC_INT_TX_EMPTY |
MEC_INT_TX_PACKET_SENT |
MEC_INT_TX_ABORT)) {
- mec_txintr(sc);
+ txring = (statreg & MEC_INT_TX_RING_BUFFER_ALIAS) >> 16;
+ txring &= MEC_NTXDESC_MASK;
+ mec_txintr(sc, txring);
sent = 1;
- if ((statack & MEC_INT_TX_EMPTY) != 0 &&
- (dmac & MEC_DMA_TX_INT_ENABLE) != 0) {
+ if ((statack & MEC_INT_TX_EMPTY) != 0) {
/*
* disable TX interrupt to stop
* TX empty interrupt
@@ -1314,6 +1314,7 @@
MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_POSTREAD);
rxstat = rxd->rxd_stat;
+ MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_PREREAD);
DPRINTF(MEC_DEBUG_RXINTR,
("mec_rxintr: rxstat = 0x%016llx, rxptr = %d\n",
@@ -1321,10 +1322,8 @@
DPRINTF(MEC_DEBUG_RXINTR, ("mec_rxintr: rxfifo = 0x%08x\n",
(u_int)bus_space_read_8(st, sh, MEC_RX_FIFO)));
- if ((rxstat & MEC_RXSTAT_RECEIVED) == 0) {
- MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_PREREAD);
+ if ((rxstat & MEC_RXSTAT_RECEIVED) == 0)
break;
- }
len = rxstat & MEC_RXSTAT_LEN;
@@ -1417,7 +1416,7 @@
}
static void
-mec_txintr(struct mec_softc *sc)
+mec_txintr(struct mec_softc *sc, uint32_t txring)
{
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
struct mec_txdesc *txd;
@@ -1427,11 +1426,9 @@
int i;
u_int col;
- ifp->if_flags &= ~IFF_OACTIVE;
-
DPRINTF(MEC_DEBUG_TXINTR, ("mec_txintr: called\n"));
- for (i = sc->sc_txdirty; sc->sc_txpending != 0;
+ for (i = sc->sc_txdirty; i != txring && sc->sc_txpending != 0;
i = MEC_NEXTTX(i), sc->sc_txpending--) {
txd = &sc->sc_txdesc[i];
@@ -1439,13 +1436,12 @@
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
txstat = txd->txd_stat;
+ MEC_TXCMDSYNC(sc, i, BUS_DMASYNC_PREREAD);
DPRINTF(MEC_DEBUG_TXINTR,
("mec_txintr: dirty = %d, txstat = 0x%016llx\n",
i, txstat));
- if ((txstat & MEC_TXSTAT_SENT) == 0) {
- MEC_TXCMDSYNC(sc, i, BUS_DMASYNC_PREREAD);
+ if ((txstat & MEC_TXSTAT_SENT) == 0)
break;
- }
if ((txstat & MEC_TXSTAT_SUCCESS) == 0) {
printf("%s: TX error: txstat = 0x%016llx\n",
@@ -1478,6 +1474,8 @@
/* cancel the watchdog timer if there are no pending TX packets */
if (sc->sc_txpending == 0)
ifp->if_timer = 0;
+ else if (sc->sc_txpending < MEC_NTXDESC - 4)
+ ifp->if_flags &= ~IFF_OACTIVE;
}
static void
---
Izumi Tsutsui
Home |
Main Index |
Thread Index |
Old Index