5.2-RC oerrs and collisions on dc0

Don Lewis truckman at FreeBSD.org
Sat Jan 3 22:51:06 PST 2004


On  3 Jan, Don Lewis wrote:
> On  4 Jan, Dejan Lesjak wrote:
> 
>> Hello again,
>> With this line commented out, I still get both errors and collisions, twice as 
>> much collisions as errors. On another occasion, I also added two printf lines 
>> in here:
>>                         if (txstat & DC_TXSTAT_EXCESSCOLL)
>>                                 ifp->if_collisions++;
>> 				printf("EXCESSCOLL\n");
>>                         if (txstat & DC_TXSTAT_LATECOLL)
>>                                 ifp->if_collisions++;
>> 				printf("LATECOLL\n");
>> and I constantly get both of those, so this would be where counters go up if 
>> this helps in any way.

> 
> I'm not familiar with this hardware, but I suspect that these two flags
> should probably not increment the collision counter.  These are errors
> that result in the packet being dropped, so they should count as output
> errors.  The hardware collision counter is probably incremented in these
> cases, so incrementing if_collisions probably results in these types of
> collisions being double counted.

Hmn, it seems that I lied.  I actually have studied this hardware in the
past.  I don't think the following code fragment in dc_txeof() is quite
correct.

                if (txstat & DC_TXSTAT_ERRSUM) {
                        ifp->if_oerrors++;
                        if (txstat & DC_TXSTAT_EXCESSCOLL)
                                ifp->if_collisions++;
                        if (txstat & DC_TXSTAT_LATECOLL)
                                ifp->if_collisions++;
                        if (!(txstat & DC_TXSTAT_UNDERRUN)) {  
                                dc_init(sc);
                                return;
                        }
                }
                    
                ifp->if_collisions += (txstat & DC_TXSTAT_COLLCNT) >> 3;

I don't happen to have a copy of the 21143 documentation, but my crufty
old 21140A documentation says that the collision count field is valid if
the late collision bit is set, but not if the excess collision count bit
is set.  The documentation can't make up its mind as to whether the late
collision bit is valid if the underrun bit is set.

It looks like the code should be:

                if (txstat & DC_TXSTAT_ERRSUM) {
                        ifp->if_oerrors++;
                        if (!(txstat & DC_TXSTAT_UNDERRUN)) {  
                                dc_init(sc);
                                return;
                        }
                }

		ifp->if_collisions += (txstat & DC_TXSTAT_EXCESSCOLL) ?
                        16 : (txstat & DC_TXSTAT_COLLCNT) >> 3);

This still doesn't explain why you are seeing output errors in full
duplex mode.  If the chip is really in full duplex mode, the circuitry
that sets the collision counter and the late and excess collision bits
should be disabled.  It looks like the code to put the chip in full
duplex mode is correct and I didn't see anything obvious in the busdma
modifications to the driver.


More information about the freebsd-current mailing list