rl(4) TX_UNDERRUN fix

Joerg Sonnenberger joerg at britannica.bec.de
Tue May 17 03:49:03 PDT 2005


On Mon, Feb 21, 2005 at 08:39:22PM +0100, Max Laier wrote:
> I choose the less aggressive one for a (couple of) reason(s):
>  - not all chips can RL_TXCFG_CLRABRT some even forbid it in the specs.
>  - the ifp->if_opackets++ just isn't right. You should only increase it
>    if you 
> get RL_TXSTAT_TX_OK.
>  - removing the reset/init cycle *might* be a good thing, but only if you can 
> assure that it doesn't break the older chips.  Some notes in the specs 
> suggest different.

Attached is a better patch, similiar to what NetBSD does.
The driver checks first for TX underruns and updates threshold.
Afterwards it checks for successful transmit (opacket++) and
resets the TX configuration otherwise. It doesn't fix the hangs
to move the TX underrun handling into the error case, they can
still occur. This seems to be partly explained in the documentation
about successful transmission with TX underrun.

I can't test this on older revisions, but I believe it is save
(since NetBSD basically does this).

Please test this patch, I'd like to commit this soon.

Joerg

P.S.: I'm still searching for a reason why I only get ~3.0MBps TX,
under Linux I get > 9MBps.
Index: if_rl.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/rl/if_rl.c,v
retrieving revision 1.18
diff -u -r1.18 if_rl.c
--- if_rl.c	21 Feb 2005 18:40:37 -0000	1.18
+++ if_rl.c	17 May 2005 10:26:41 -0000
@@ -1197,26 +1197,19 @@
 		m_freem(RL_LAST_TXMBUF(sc));
 		RL_LAST_TXMBUF(sc) = NULL;
 
-		if ((txstat & RL_TXSTAT_TX_OK) == 0) {
-			int oldthresh;
+		if (txstat & RL_TXSTAT_TX_UNDERRUN) {
+			sc->rl_txthresh += 32;
+			if (sc->rl_txthresh > RL_TX_THRESH_MAX)
+				sc->rl_txthresh = RL_TX_THRESH_MAX;
+		}
 
+		if (txstat & RL_TXSTAT_TX_OK) {
+			ifp->if_opackets++;
+		} else {
 			ifp->if_oerrors++;
-			if ((txstat & RL_TXSTAT_TXABRT) ||
-			    (txstat & RL_TXSTAT_OUTOFWIN))
+			if (txstat & (RL_TXSTAT_TXABRT | RL_TXSTAT_OUTOFWIN))
 				CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG);
-			oldthresh = sc->rl_txthresh;
-			/* error recovery */
-			rl_reset(sc);
-			rl_init(sc);
-			/*
-			 * If there was a transmit underrun,
-			 * bump the TX threshold.
-			 */
-			if (txstat & RL_TXSTAT_TX_UNDERRUN)
-				sc->rl_txthresh = oldthresh + 32;
-			return;
 		}
-		ifp->if_opackets++;
 		RL_INC(sc->rl_cdata.last_tx);
 		ifp->if_flags &= ~IFF_OACTIVE;
 	} while (sc->rl_cdata.last_tx != sc->rl_cdata.cur_tx);
Index: if_rlreg.h
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/rl/if_rlreg.h,v
retrieving revision 1.4
diff -u -r1.4 if_rlreg.h
--- if_rlreg.h	10 Nov 2004 18:30:13 -0000	1.4
+++ if_rlreg.h	17 May 2005 08:36:13 -0000
@@ -303,6 +303,7 @@
 #define RL_MIN_FRAMELEN		60
 #define RL_TXTHRESH(x)		((x) << 11)
 #define RL_TX_THRESH_INIT	96
+#define RL_TX_THRESH_MAX	2016
 #define RL_RX_FIFOTHRESH	RL_RXFIFO_256BYTES
 #define RL_RX_MAXDMA		RL_RXDMA_1024BYTES
 #define RL_TX_MAXDMA		RL_TXDMA_2048BYTES




More information about the Submit mailing list