fxp/82550 bug (was Re: IP fragmentation disagreement between current and stable)

Don Lewis truckman at FreeBSD.org
Wed Apr 23 00:10:58 PDT 2003


> It's starting to smell like a bug in the -current fxp driver.

I did some digging in the fxp driver, and now I think it's a chip bug
that is being triggered by the -current fxp driver, which attempts to
use some more advanced features of the 82550.  I found this suspicious
comment in the code:

                /*
                 * XXX The 82550 chip appears to have trouble
                 * dealing with IP header checksums in very small
                 * datagrams, namely fragments from 1 to 3 bytes
                 * in size. For example, say you want to transmit
                 * a UDP packet of 1473 bytes. The packet will be
                 * fragmented over two IP datagrams, the latter
                 * containing only one byte of data. The 82550 will
                 * botch the header checksum on the 1-byte fragment.
                 * As long as the datagram contains 4 or more bytes
                 * of data, you're ok.
                 *
                 * The following code attempts to work around this
                 * problem: if the datagram is less than 38 bytes
                 * in size (14 bytes ether header, 20 bytes IP header,
                 * plus 4 bytes of data), we punt and compute the IP
                 * header checksum by hand. This workaround doesn't
                 * work very well, however, since it can be fooled
                 * by things like VLAN tags and IP options that make
                 * the header sizes/offsets vary.
                 */

The code it mentions is inside a #ifdef block that is not enabled.

I think the problem is worse than mentioned above.  I attempted to
totally disable hardware checksumming with some surgery to the code
(because the fxp driver doesn't appear to support the ifconfig run time
knobs for this), but even with hardware checksumming disabled, the final
fragment was still bad.

Once I totally disabled the special transmit features for the 82550 with
the following patch so that the driver used the transmit code for the
older chips, I was able to successfully send large fragmented pings with
the troublesome sizes.

diff -u -r1.173 if_fxp.c
--- if_fxp.c    16 Apr 2003 09:16:55 -0000      1.173
+++ if_fxp.c    23 Apr 2003 06:45:39 -0000
@@ -573,7 +573,11 @@
         * Be careful to do this only on the right devices.
         */
 
+#if 0
        if (sc->revision == FXP_REV_82550 || sc->revision == FXP_REV_82550_C) {
+#else
+       if (0) {
+#endif
                sc->rfa_size = sizeof (struct fxp_rfa);
                sc->tx_cmd = FXP_CB_COMMAND_IPCBXMIT;
                sc->flags |= FXP_FLAG_EXT_RFA;



More information about the freebsd-net mailing list