Subject: kern/29373: wm driver's packet rate is limited to 30kpps (w/ fix)
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <salvet@ics.muni.cz>
List: netbsd-bugs
Date: 02/14/2005 17:33:00
>Number:         29373
>Category:       kern
>Synopsis:       wm driver's packet rate is limited to 30kpps (w/ fix)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Feb 14 17:33:00 +0000 2005
>Originator:     Zdenek Salvet <salvet@ics.muni.cz>
>Release:        NetBSD 2.0
>Organization:
Masaryk University, Brno, Czech Republic
>Environment:
System: NetBSD azaghal.ics.muni.cz 2.0 NetBSD 2.0 (AZAGHAL_MODM2E) #0: Sat Feb 12 03:47:41 MET 2005 salvet@azaghal.ics.muni.cz:/p3/src/sys/arch/i386/compile/AZAGHAL_MODM2E i386
Architecture: i386
Machine: i386
>Description:
	The wm network driver uses chip's interrupt mitigation registers
	incorrectly. It asks to delay RX interrupt without using max. delay
	timer. 
>How-To-Repeat:
	Test router throughput with small packets.
>Fix:
	Something similar to the following (the default values of
	interrupt delay registers are those used in linux driver,
	additional tuning may be required to obtain maximum throughput
	possible):
--- if_wm.c     19 Feb 2004 05:19:52 -0000      1.68
+++ if_wm.c     14 Feb 2005 17:17:10 -0000
@@ -99,6 +99,10 @@

 #include <dev/pci/if_wmreg.h>

+int wm_param_radv = 128;
+int wm_param_rdtr = 0;
+int wm_param_itr = 8000;
+
 #ifdef WM_DEBUG
 #define        WM_DEBUG_LINK           0x01
 #define        WM_DEBUG_TX             0x02
@@ -2320,7 +2365,7 @@
                CSR_WRITE(sc, WMREG_OLD_RDLEN0, sizeof(sc->sc_rxdescs));
                CSR_WRITE(sc, WMREG_OLD_RDH0, 0);
                CSR_WRITE(sc, WMREG_OLD_RDT0, 0);
-               CSR_WRITE(sc, WMREG_OLD_RDTR0, 28 | RDTR_FPD);
+               CSR_WRITE(sc, WMREG_OLD_RDTR0, wm_param_rdtr | RDTR_FPD);

                CSR_WRITE(sc, WMREG_OLD_RDBA1_HI, 0);
                CSR_WRITE(sc, WMREG_OLD_RDBA1_LO, 0);
@@ -2334,7 +2379,9 @@
                CSR_WRITE(sc, WMREG_RDLEN, sizeof(sc->sc_rxdescs));
                CSR_WRITE(sc, WMREG_RDH, 0);
                CSR_WRITE(sc, WMREG_RDT, 0);
-               CSR_WRITE(sc, WMREG_RDTR, 28 | RDTR_FPD);
+               CSR_WRITE(sc, WMREG_RDTR, wm_param_rdtr | RDTR_FPD);
+               CSR_WRITE(sc, 0x0282C, wm_param_radv);
+               CSR_WRITE(sc, 0x000C4, 1000000000/(wm_param_itr*256));
        }
        for (i = 0; i < WM_NRXDESC; i++) {
                rxs = &sc->sc_rxsoft[i];