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