Re: mec and resets

Izumi Tsutsui <[email protected]>
Newsgroups gmane.os.netbsd.ports.sgimips
Message-ID <[email protected]>
I wrote:
> Please try this one.

This is an updated one (mostly taken from OpenBSD):
---

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	2 Aug 2008 06:01:32 -0000
@@ -125,6 +125,7 @@
 #define MEC_NTXDESC		64
 #define MEC_NTXDESC_MASK	(MEC_NTXDESC - 1)
 #define MEC_NEXTTX(x)		(((x) + 1) & MEC_NTXDESC_MASK)
+#define MEC_NTXDESC_RSVD	4
 
 /*
  * software state for TX
@@ -341,8 +342,8 @@
 static void	mec_setfilter(struct mec_softc *);
 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_rxintr(struct mec_softc *, uint32_t);
+static void	mec_txintr(struct mec_softc *, uint32_t);
 static void	mec_shutdown(void *);
 
 CFATTACH_DECL_NEW(mec, sizeof(struct mec_softc),
@@ -1223,7 +1224,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, rxptr, txptr;
 	int handled, sent;
 
 	DPRINTF(MEC_DEBUG_INTR, ("mec_intr: called\n"));
@@ -1246,10 +1247,12 @@
 		if (statack &
 		    (MEC_INT_RX_THRESHOLD |
 		     MEC_INT_RX_FIFO_UNDERFLOW)) {
-			mec_rxintr(sc);
+			rxptr = (statreg & MEC_INT_RX_MCL_FIFO_ALIAS)
+			    >> MEC_INT_RX_MCL_FIFO_SHIFT;
+			txptr &= MEC_NRXDESC_MASK;
+			mec_rxintr(sc, rxptr);
 		}
 
-		dmac = bus_space_read_8(st, sh, MEC_DMA_CONTROL);
 		DPRINTF(MEC_DEBUG_INTR,
 		    ("mec_intr: DMA_CONT = 0x%08x\n", dmac));
 
@@ -1257,10 +1260,11 @@
 		    (MEC_INT_TX_EMPTY |
 		     MEC_INT_TX_PACKET_SENT |
 		     MEC_INT_TX_ABORT)) {
-			mec_txintr(sc);
+			txptr = (statreg & MEC_INT_TX_RING_BUFFER_ALIAS)
+			    >> MEC_INT_TX_RING_BUFFER_SHIFT;
+			mec_txintr(sc, txptr);
 			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
@@ -1282,7 +1286,7 @@
 		}
 	}
 
-	if (sent) {
+	if (sent && IFQ_IS_EMPTY(&ifp->if_snd)) {
 		/* try to get more packets going */
 		mec_start(ifp);
 	}
@@ -1296,7 +1300,7 @@
 }
 
 static void
-mec_rxintr(struct mec_softc *sc)
+mec_rxintr(struct mec_softc *sc, uint32_t rxptr)
 {
 	bus_space_tag_t st = sc->sc_st;
 	bus_space_handle_t sh = sc->sc_sh;
@@ -1309,7 +1313,7 @@
 
 	DPRINTF(MEC_DEBUG_RXINTR, ("mec_rxintr: called\n"));
 
-	for (i = sc->sc_rxptr;; i = MEC_NEXTRX(i)) {
+	for (i = sc->sc_rxptr; i != rxptr; i = MEC_NEXTRX(i)) {
 		rxd = &sc->sc_rxdesc[i];
 
 		MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_POSTREAD);
@@ -1417,7 +1421,7 @@
 }
 
 static void
-mec_txintr(struct mec_softc *sc)
+mec_txintr(struct mec_softc *sc, uint32_t txptr)
 {
 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 	struct mec_txdesc *txd;
@@ -1427,11 +1431,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 != txptr && sc->sc_txpending != 0;
 	    i = MEC_NEXTTX(i), sc->sc_txpending--) {
 		txd = &sc->sc_txdesc[i];
 
@@ -1478,6 +1480,8 @@
 	/* cancel the watchdog timer if there are no pending TX packets */
 	if (sc->sc_txpending == 0)
 		ifp->if_timer = 0;
+	if (sc->sc_txpending < MEC_NTXDESC - MEC_NTXDESC_RSVD)
+		ifp->if_flags &= ~IFF_OACTIVE;
 }
 
 static void
Index: if_mecreg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/mace/if_mecreg.h,v
retrieving revision 1.3
diff -u -r1.3 if_mecreg.h
--- if_mecreg.h	10 Dec 2005 07:05:10 -0000	1.3
+++ if_mecreg.h	2 Aug 2008 06:01:32 -0000
@@ -74,7 +74,9 @@
 #define  MEC_INT_RX_FIFO_UNDERFLOW	0x0000000000000040
 #define  MEC_INT_RX_DMA_UNDERFLOW	0x0000000000000080
 #define  MEC_INT_RX_MCL_FIFO_ALIAS	0x0000000000001f00
+#define  MEC_INT_RX_MCL_FIFO_SHIFT	8
 #define  MEC_INT_TX_RING_BUFFER_ALIAS	0x0000000001ff0000
+#define  MEC_INT_TX_RING_BUFFER_SHIFT	16
 #define  MEC_INT_RX_SEQUENCE_NUMBER	0x000000003e000000
 #define  MEC_INT_MCAST_HASH_OUTPUT	0x0000000040000000
 

---
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.