Re: mec and resets
Izumi Tsutsui <[email protected]>
| Newsgroups | gmane.os.netbsd.ports.sgimips |
|---|---|
| Message-ID | <[email protected]> |
[email protected] 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