Subject: kern/11549: ex driver counting 2x if_[io]bytes, bad oerrors count
To: None <gnats-bugs@gnats.netbsd.org>
From: None <srp@zgi.com>
List: netbsd-bugs
Date: 11/22/2000 11:02:16
>Number:         11549
>Category:       kern
>Synopsis:       ex driver counting 2x if_[io]bytes, bad oerrors count
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Nov 22 11:02:01 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Scott Presnell
>Release:        1.4.2
>Organization:
Self
>Environment:
System: NetBSD srp1.olywa.net 1.4.2 NetBSD 1.4.2 (PO) #10:
Sun Nov 12 13:32:24 PST 2000 root@srp4:/usr/src/sys/arch/i386/compile/PO i386

Driver recognition

ex0 at pci1 dev 8 function 0: 3Com 3c905-TX 10/100 Ethernet
ex0: interrupting at irq 11
ex0: MAC address 00:c0:4f:b9:19:08
exphy0 at ex0 phy 24: 3Com internal media interface


>Description:

After tracking byte counts across interfaces with different drivers
attached using mrtg/SNMP and netstat, it would appear that the ex driver in
NetBSD 1.4.2 is counting 2x the bytes it should (ex dirver itself seems to
work OK, packet counts are OK).

>How-To-Repeat:

Track byte count across ex0 and compare to ftp rate comparison or some
other known trusted method of counting bytes (I also checked against fxp
ethernet interface).

>Fix:

This should (obviously) not be considered a production patch, however it
fixes the problem.  Someone with some experience with the driver should
examine the hack and determine why this works and/or why these data were
used to add to the byte count in the first place.

Explanation of diff:

Basically I now read the buffer space entries but toss the results that
were previously added into the totals.  (If I simply didn't do the
bus_space_reads, I ran into kernel troubles...)

This difference also addresses what I hacked to not count the deferrals as
oerrors: this is already patched/changed in 1.5beta2.


*** elinkxl.c.orig      Wed Nov 22 10:43:58 2000
--- elinkxl.c   Fri Nov 17 16:54:31 2000
***************
*** 1362,1367 ****
--- 1362,1368 ----
        bus_space_handle_t ioh = sc->sc_ioh;
        bus_space_tag_t iot = sc->sc_iot;
        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+       long int oerrors;
        u_int8_t upperok;

        GO_WINDOW(6);
***************
*** 1371,1377 ****
        ifp->if_opackets += bus_space_read_1(iot, ioh, TX_FRAMES_OK);
        ifp->if_opackets += (upperok & 0x30) << 4;
        ifp->if_ierrors += bus_space_read_1(iot, ioh, RX_OVERRUNS);
!       ifp->if_oerrors += bus_space_read_1(iot, ioh, TX_DEFERRALS);
        ifp->if_collisions += bus_space_read_1(iot, ioh, TX_COLLISIONS);
        /*
         * There seems to be no way to get the exact number of collisions,
--- 1372,1382 ----
        ifp->if_opackets += bus_space_read_1(iot, ioh, TX_FRAMES_OK);
        ifp->if_opackets += (upperok & 0x30) << 4;
        ifp->if_ierrors += bus_space_read_1(iot, ioh, RX_OVERRUNS);
! /*
!  *      deferrals are not oerrors - Scott Presnell, srp@zgi.com
!  *    ifp->if_oerrors += bus_space_read_1(iot, ioh, TX_DEFERRALS);
!  */
!       oerrors = bus_space_read_1(iot, ioh, TX_DEFERRALS);
        ifp->if_collisions += bus_space_read_1(iot, ioh, TX_COLLISIONS);
        /*
         * There seems to be no way to get the exact number of collisions,
***************
*** 1379,1387 ****
         */
        ifp->if_collisions += 2 * bus_space_read_1(iot, ioh,
            TX_AFTER_X_COLLISIONS);
!       ifp->if_ibytes += bus_space_read_2(iot, ioh, RX_TOTAL_OK);
!       ifp->if_obytes += bus_space_read_2(iot, ioh, TX_TOTAL_OK);

        /*
         * Clear the following to avoid stats overflow interrupts
         */
--- 1384,1396 ----
         */
        ifp->if_collisions += 2 * bus_space_read_1(iot, ioh,
            TX_AFTER_X_COLLISIONS);
! /*
!  *    ifp->if_ibytes += bus_space_read_2(iot, ioh, RX_TOTAL_OK);
!  *    ifp->if_obytes += bus_space_read_2(iot, ioh, TX_TOTAL_OK);
!  */

+       oerrors = bus_space_read_2(iot, ioh, RX_TOTAL_OK);
+       oerrors = bus_space_read_2(iot, ioh, TX_TOTAL_OK);
        /*
         * Clear the following to avoid stats overflow interrupts
         */

>Release-Note:
>Audit-Trail:
>Unformatted: