Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Jul 2006 20:28:00 GMT
From:      Doug Havir <rally@nbs-inc.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/101000: I may have found a subtle bug in the "em" driver in relase 6.1 - duplex/collision mismatch
Message-ID:  <200607282028.k6SKS03q092039@www.freebsd.org>
Resent-Message-ID: <200607282030.k6SKUQdB006407@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         101000
>Category:       kern
>Synopsis:       I may have found a subtle bug in the "em" driver in relase 6.1 - duplex/collision mismatch
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jul 28 20:30:25 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Doug Havir
>Release:        i386 release 6.1
>Organization:
National Bankcard Services, Inc.
>Environment:
FreeBSD bsd.nbs 6.1-RELEASE FreeBSD 6.1-RELEASE #2: Mon Jul 10 09:56:35 CDT 2006     user@bsd.nbs:/usr/obj/usr/src/sys/QNXKERNEL  i386
>Description:
In the file dev/em/if_em_hw.h, which is part of the Intel 825xx ethernet driver, the defines for DUPLEX are as follows:
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2

In the file dev/em/if_em.c the message printed at the end of the em_attach() call is:
printf("em%d:  Speed:%d Mbps  Duplex:%s\n", adapter->unit, adapter->link_speed,
              adapter->link_duplex == FULL_DUPLEX ? "Full" : "Half");

Given that the code reads right, and nobody has complained about the message being wrong, one might assume the definitions for FULL and HALF duplex are correct.  BUT THEN,

In the file dev/em/if_em.c, function em_initialize_transmit_unit(struct adapter * adapter),
line 2396-2400:
if (adapter->link_duplex == 1) {
    reg_tctl |= E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT;
} else {
    reg_tctl |= E1000_HDX_COLLISION_DISTANCE << E1000_COLD_SHIFT;
}

Correct me if I'm wrong, but what that really says is if link_duplex == HALF_DUPLEX then set the collision distance to the full duplex setting.  At least one of the two usages are incorrect.

I figured I'd point it out just in case it actually has a meaningful impact.  Could it possibly explain some of the half duplex workaround stuff in here?  One can only hope....
>How-To-Repeat:
Lookie at the source code.
>Fix:
1) Use the define for FULL_DUPLEX or HALF_DUPLEX instead of "1"
2) Make sure the effects of the if/else match whichever duplex definition you choose
3) Spend copious free time seeing if it has any effect on performance or reliability :-)

Best regards,
-Doug

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607282028.k6SKS03q092039>