diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2006-08-06 05:18:23 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2006-08-06 05:18:23 +0000 |
commit | 49e787eda17940329b83f3d5c12d4bff86f89b82 (patch) | |
tree | c147066df8c21624ec7eb95ed4f440a30630b3aa /sys/dev/ic/re.c | |
parent | 907e9019018d47c2d12a5b93597e602667138677 (diff) |
With the PCIe devices, it looks as if issuing a TX command while
there is already a transmission in progress has no effect. In other
words, if you send two packets in rapid succession, the second one may
end up sitting in the TX DMA ring until another transmit command is
issued later in the future. Basically, if re_txeof() sees that there
are still descriptors outstanding, it needs to manually resume the
TX DMA channel by issuing another TX command to make sure all
transmissions are flushed out. (The PCI devices seem to keep the
TX channel moving until all descriptors have been consumed. I'm not
sure why the PCIe devices behave differently.)
From wpaul@FreeBSD
Diffstat (limited to 'sys/dev/ic/re.c')
-rw-r--r-- | sys/dev/ic/re.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/sys/dev/ic/re.c b/sys/dev/ic/re.c index 5faa23d6f79..aa099255aa7 100644 --- a/sys/dev/ic/re.c +++ b/sys/dev/ic/re.c @@ -1,4 +1,4 @@ -/* $OpenBSD: re.c,v 1.39 2006/08/05 21:38:20 brad Exp $ */ +/* $OpenBSD: re.c,v 1.40 2006/08/06 05:18:22 brad Exp $ */ /* $FreeBSD: if_re.c,v 1.31 2004/09/04 07:54:05 ru Exp $ */ /* * Copyright (c) 1997, 1998-2003 @@ -1372,6 +1372,16 @@ re_txeof(struct rl_softc *sc) } /* + * Some chips will ignore a second TX request issued while an + * existing transmission is in progress. If the transmitter goes + * idle but there are still packets waiting to be sent, we need + * to restart the channel here to flush them out. This only seems + * to be required with the PCIe devices. + */ + if (sc->rl_ldata.rl_tx_free < RL_TX_DESC_CNT(sc)) + CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START); + + /* * If not all descriptors have been released reaped yet, * reload the timer so that we will eventually get another * interrupt that will cause us to re-enter this routine. |