--- sys/pci/if_rl.c.orig	Thu Sep  9 14:39:52 2004
+++ sys/pci/if_rl.c	Fri Oct 15 10:18:34 2004
@@ -92,6 +92,7 @@ __FBSDID("$FreeBSD: src/sys/pci/if_rl.c,
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/socket.h>
+#include <sys/ktr.h>
 
 #include <net/if.h>
 #include <net/if_arp.h>
@@ -713,6 +714,8 @@ rl_reset(struct rl_softc *sc)
 {
 	register int		i;
 
+	TR0("rl_reset");
+
 	RL_LOCK_ASSERT(sc);
 
 	CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RESET);
@@ -1100,6 +1103,7 @@ rl_rxeof(struct rl_softc *sc)
 	uint16_t		cur_rx;
 	uint16_t		limit;
 	uint16_t		max_bytes, rx_bytes = 0;
+	int			cnt = 0;
 
 	RL_LOCK_ASSERT(sc);
 
@@ -1116,6 +1120,9 @@ rl_rxeof(struct rl_softc *sc)
 	else
 		max_bytes = limit - cur_rx;
 
+	TR3("rl_rxeof: cur_rx %d limit %d max_bytes %d",
+		cur_rx, limit, max_bytes);
+
 	while((CSR_READ_1(sc, RL_COMMAND) & RL_CMD_EMPTY_RXBUF) == 0) {
 #ifdef DEVICE_POLLING
 		if (ifp->if_flags & IFF_POLLING) {
@@ -1127,6 +1134,9 @@ rl_rxeof(struct rl_softc *sc)
 		rxbufpos = sc->rl_cdata.rl_rx_buf + cur_rx;
 		rxstat = le32toh(*(uint32_t *)rxbufpos);
 
+		TR2("rl_rxeof: rxbufpos %p rxstat 0x%x",
+			rxbufpos, rxstat);
+
 		/*
 		 * Here's a totally undocumented fact for you. When the
 		 * RealTek chip is in the process of copying a packet into
@@ -1157,6 +1167,9 @@ rl_rxeof(struct rl_softc *sc)
 		 */
 		total_len -= ETHER_CRC_LEN;
 
+		TR2("rl_rxeof: total_len %d rx_bytes %d",
+			total_len, rx_bytes);
+
 		/*
 		 * Avoid trying to read more bytes than we know
 		 * the chip has prepared for us.
@@ -1190,6 +1203,10 @@ rl_rxeof(struct rl_softc *sc)
 
 		/* Round up to 32-bit boundary. */
 		cur_rx = (cur_rx + 3) & ~3;
+
+		TR1("rl_rxeof: cur_rx %d",
+			cur_rx);
+
 		CSR_WRITE_2(sc, RL_CURRXADDR, cur_rx - 16);
 
 		if (m == NULL)
@@ -1199,7 +1216,9 @@ rl_rxeof(struct rl_softc *sc)
 		RL_UNLOCK(sc);
 		(*ifp->if_input)(ifp, m);
 		RL_LOCK(sc);
+		cnt++;
 	}
+	TR1("rl_rxeof: cnt %d", cnt);
 }
 
 /*
@@ -1211,6 +1230,7 @@ rl_txeof(struct rl_softc *sc)
 {
 	struct ifnet		*ifp = &sc->arpcom.ac_if;
 	uint32_t		txstat;
+	int			cnt = 0;
 
 	RL_LOCK_ASSERT(sc);
 
@@ -1222,6 +1242,7 @@ rl_txeof(struct rl_softc *sc)
 		if (RL_LAST_TXMBUF(sc) == NULL)
 			break;
 		txstat = CSR_READ_4(sc, RL_LAST_TXSTAT(sc));
+		TR1("rl_txeof: txstat 0x%x", txstat);
 		if (!(txstat & (RL_TXSTAT_TX_OK|
 		    RL_TXSTAT_TX_UNDERRUN|RL_TXSTAT_TXABRT)))
 			break;
@@ -1237,25 +1258,33 @@ rl_txeof(struct rl_softc *sc)
 		else {
 			int			oldthresh;
 			ifp->if_oerrors++;
+			oldthresh = sc->rl_txthresh;
 			if ((txstat & RL_TXSTAT_TXABRT) ||
-			    (txstat & RL_TXSTAT_OUTOFWIN))
+			    (txstat & RL_TXSTAT_OUTOFWIN)) {
 				CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG);
-			oldthresh = sc->rl_txthresh;
-			/* error recovery */
-			rl_reset(sc);
-			rl_init_locked(sc);
+				/* error recovery only from major errors */
+				rl_reset(sc);
+				rl_init_locked(sc);
+				return;
+			}
 			/*
 			 * If there was a transmit underrun,
 			 * bump the TX threshold.
 			 */
-			if (txstat & RL_TXSTAT_TX_UNDERRUN)
+			if ((txstat & RL_TXSTAT_TX_UNDERRUN) &&
+			    oldthresh < 1536)
 				sc->rl_txthresh = oldthresh + 32;
-			return;
+			TR2("rl_txeof: txunderrun: oldthresh %d newthresh %d",
+				oldthresh, sc->rl_txthresh);
 		}
 		RL_INC(sc->rl_cdata.last_tx);
+		cnt++;
 		ifp->if_flags &= ~IFF_OACTIVE;
 	} while (sc->rl_cdata.last_tx != sc->rl_cdata.cur_tx);
 
+	TR2("rl_txeof: cnt %d txqueue %d", cnt,
+		(sc->rl_cdata.cur_tx - sc->rl_cdata.last_tx) % 4);
+
 	if (RL_LAST_TXMBUF(sc) == NULL)
 		ifp->if_timer = 0;
 	else if (ifp->if_timer == 0)
@@ -1338,6 +1367,7 @@ rl_intr(void *arg)
 	struct rl_softc		*sc = arg;
 	struct ifnet		*ifp = &sc->arpcom.ac_if;
 	uint16_t		status;
+	int			cnt = 0;
 
 	RL_LOCK(sc);
 
@@ -1359,6 +1389,7 @@ rl_intr(void *arg)
 
 	for (;;) {
 		status = CSR_READ_2(sc, RL_ISR);
+		TR1("rl_intr: status 0x%x", status);
 		/* If the card has gone away, the read returns 0xffff. */
 		if (status == 0xffff)
 			break;
@@ -1376,8 +1407,11 @@ rl_intr(void *arg)
 			rl_reset(sc);
 			rl_init_locked(sc);
 		}
+		cnt++;
 	}
 
+	TR1("rl_intr: cnt %d", cnt);
+
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 		rl_start_locked(ifp);
 
@@ -1447,6 +1481,7 @@ rl_start_locked(struct ifnet *ifp)
 {
 	struct rl_softc		*sc = ifp->if_softc;
 	struct mbuf		*m_head = NULL;
+	int			cnt = 0;
 
 	RL_LOCK_ASSERT(sc);
 
@@ -1475,11 +1510,14 @@ rl_start_locked(struct ifnet *ifp)
 		    RL_CUR_TXMBUF(sc)->m_pkthdr.len);
 
 		RL_INC(sc->rl_cdata.cur_tx);
+		cnt++;
 
 		/* Set a timeout in case the chip goes out to lunch. */
 		ifp->if_timer = 5;
 	}
 
+	TR1("rl_start: cnt %d", cnt);
+
 	/*
 	 * We broke out of the loop because all our TX slots are
 	 * full. Mark the NIC as busy until it drains some of the
@@ -1506,6 +1544,8 @@ rl_init_locked(struct rl_softc *sc)
 	struct mii_data		*mii;
 	uint32_t		rxcfg = 0;
 
+	TR0("rl_init");
+
 	RL_LOCK_ASSERT(sc);
 
 	mii = device_get_softc(sc->rl_miibus);
@@ -1702,6 +1742,8 @@ rl_stop(struct rl_softc *sc)
 {
 	register int		i;
 	struct ifnet		*ifp = &sc->arpcom.ac_if;
+
+	TR0("rl_stop");
 
 	RL_LOCK_ASSERT(sc);
 
