Under a heavy RX load, at least with D-Link DFE-550TX adapters,

the driver's RX ring head may fall behind the chip, causing the
stuck traffic, disordered packets, etc.  Work around this by
adopting the technique of resyncing RX head used in dc(4) and
xl(4) drivers, but do it in a slightly different place to reduce
the number of resyncs needed.

Also, set the NIC's RX polling period to a more meaningful value,
to stop overloading the PCI bus (this also reduces the number of
resyncs by a factor of 3 or more in a long run; the actual number
is very dependent on a nature of the traffic).

Maintain the statistics counter as the hw.ste_rxsyncs sysctl.

In cooperation with:	Vsevolod Lobko
OK'ed by:		ambrisko
MFC after:		5 days
This commit is contained in:
Ruslan Ermilov 2004-03-31 21:10:01 +00:00
parent 457180a40d
commit 065566e6a3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=127688

View File

@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_arp.h>
@ -162,6 +163,9 @@ static devclass_t ste_devclass;
DRIVER_MODULE(ste, pci, ste_driver, ste_devclass, 0, 0);
DRIVER_MODULE(miibus, ste, miibus_driver, miibus_devclass, 0, 0);
static int ste_rxsyncs;
SYSCTL_INT(_hw, OID_AUTO, ste_rxsyncs, CTLFLAG_RW, &ste_rxsyncs, 0, "");
#define STE_SETBIT4(sc, reg, x) \
CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | (x))
@ -758,6 +762,19 @@ ste_rxeof(sc)
ifp = &sc->arpcom.ac_if;
if (sc->ste_cdata.ste_rx_head->ste_ptr->ste_status == 0) {
cur_rx = sc->ste_cdata.ste_rx_head;
do {
cur_rx = cur_rx->ste_next;
/* If the ring is empty, just return. */
if (cur_rx == sc->ste_cdata.ste_rx_head)
return;
} while (cur_rx->ste_ptr->ste_status == 0);
/* We've fallen behind the chip: catch it. */
sc->ste_cdata.ste_rx_head = cur_rx;
++ste_rxsyncs;
};
while((rxstat = sc->ste_cdata.ste_rx_head->ste_ptr->ste_status)
& STE_RXSTAT_DMADONE) {
#ifdef DEVICE_POLLING
@ -1309,7 +1326,7 @@ ste_init(xsc)
}
/* Set RX polling interval */
CSR_WRITE_1(sc, STE_RX_DMAPOLL_PERIOD, 1);
CSR_WRITE_1(sc, STE_RX_DMAPOLL_PERIOD, 64);
/* Init TX descriptors */
ste_init_tx_list(sc);