3Com509B Behavior under FreeBSD 2.2.8

There's a fix (Nov 23 '99).

Problem

In Fall 1998, we noticed that some of the 3Com509B cards were generating duplicate hardware packets under FreeBSD 2.2.7 and 2.2.8. These cards came on the motherboards of the Intel boxes as device xl0. We found information that pointed to a faulty shipment from 3Com. Look at the card and if there is an assembly number of 03-172 written on the GREEN part of the FAB (NOT in the YELLOW perimeter), then the card is faulty. (It could also be that the FreeBSD driver is bad. I don't think anyone's checked this with FreeBSD 3.x.)

Status

Last time I checked, our cards were in this batch. We switched to using mainly Intel cards because of this. If you need to use the 3Com cards, be careful. An easy way to check for duplicates is to take a tcpdump where the 3Com card is the sender, and run it through tcptrace, which will alert you if there are hardware duplicates found.


Fix

This problem is fixed in a newer version of the xl driver, which is available from http://www.freebsd.org/~wpaul/ Our friends in Denmark have used the new driver and see no more duplicate packets.

Note: If you change the driver on an ALTQ kernel, you need to re-apply the ALTQ patch because ALTQ makes changes to the xl driver. Also, in the new xl driver, a new routine, xl_start_90xB, has been added. This routine is not patched by the ALTQ 2.0 patch, so this needs to be done by hand. Look at Step 2 of [your favorite ALTQ distribution]/docs/howto-modify-drivers.txt (see below) for info on how to perform the manual patch.

Thanks to Jan Justensen (justesen@cs.auc.dk) and Jesper Krogh (jkrogh@cs.auc.dk) for finding this.

[my ALTQ distribution]/docs/howto-modify-drivers.txt

Currently supported drivers are very limited.  If you want to use
unsupported drivers, you have to make modifications by yourself.

If you successfully made modifications, please send diffs to
(kjc@csl.sony.co.jp).  I'll include the support in the next release.

(1) ethernet drivers

Step 1: attach routine  (e.g. vxattach)

When a driver supports ALTQ, it should set the ALTQF_READY flag in the
driver's attach routine.

        #ifdef ALTQ
                /*
                 * set ALTQF_READY to show this driver supports
                 * alternate queueing.
                 */
                ifp->if_altqflags |= ALTQF_READY;
        #endif
                if_attach(ifp);

Step 2: if_start routine.  (e.g. vxstart)

This is an example of how to put the alternate dequeue operation in
the if_start routine.

        #ifdef ALTQ
            if (IS_ALTQ_ON(ifp))
                m0 = (*ifp->if_altqdequeue)(ifp, ALTDQ_DEQUEUE);
            else
        #endif
            IF_DEQUEUE(&ifp->if_snd, m0);

Also, many drivers peek the next packet in the queue to see they have
enough buffer space.  Those should be modified like this.

            /* Sneak a peek at the next packet */
        #ifdef ALTQ
            if (IS_ALTQ_ON(ifp))
                m0 = (*ifp->if_altqdequeue)(ifp, ALTDQ_PEEK);
            else
        #endif
            m0 = ifp->if_snd.ifq_head;

A queueing scheme guarantees that if a driver peeks the next packet
and then dequeues the packet, the same peeked packet is returned.
Because if_start is assumed to be called in splimp, if_start can
safely dequeue the same packet.

The last variation is flushing the queue.  This is necessary for
non-work conserving queueing schemes, since just dequeueing until NULL
returned doesn't drain those queues.

        (*ifp->if_altqdequeue)(ifp, ALTDQ_FLUSH);

See the altq document for more details.  Also, vxstart in if_vx.c is a 
good reference.

Other DiRT documents
Author: Michele Clark