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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.