Date: Thu, 22 May 2003 01:23:09 -0700 (PDT) From: Don Lewis <truckman@FreeBSD.org> To: wpaul@FreeBSD.org, =?iso-8859-1?Q?David_Sieb=F6rger?= <drs@rucus.ru.ac.za>, Hiroki Sato <hrs@eos.ocn.ne.jp>, Matt Douhan <matt@hasta.se> Cc: current@FreeBSD.org Subject: possible bug fix for 82550-based fxp packet truncation problem Message-ID: <200305220823.h4M8N9M7075271@gw.catspoiler.org>
next in thread | raw e-mail | index | archive | help
I downloaded a copy of the "Intel 8255x 10/100 Mbps Ethernet Controller Family Open Source Software Developer Manual" a few days ago and stumbled across a statement that suggested a possible fix for the packet truncation problem with 82550-based fxp cards that a number of us have observed. On page 155 in Appendix B, which covers the 82550 and 82551 IPCB stuff, there is a note that says: Using software parsing is only allowed with legal TCP/IP and UDP/IP packets. When software parsing is used, the IP and TCP offsets in the IPCB must point to the appropriate headers, and the total TCP/UDP payload should be specified. For all other datagrams, hardware parsing must be used. This sounded rather odd to me. Why should hardware parsing of the packet be enabled if arbitrary packets are being sent? Couldn't the chip get confused? Why would it make a difference if hardware checksumming were not requested? I noticed that the driver only enabled the hardware parsing bit in the IPCB if the hardware checksum request bit was set, which would only happen for TCP and UDP packets. Since this didn't match the official Intel documentation, I decided to try modifying the driver to always enable hardware parsing, since the driver never filled in the header offsets that would be necessary to use software parsing. When I tried the ping tests with the packet sizes which previously failed, the modified driver was able to sucessfully transmit the packets without truncation. If you are using one of my previous patches which worked around the problem by disabling the IPCB mode, you may want to try the patch below. Another note in the above mentioned document may shed some light on the problem mentioned in this comment in the driver: /* * 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 note on page 156 says: IP fragmentation is not supported by the 82550. Therefore the driver should not request any offload features for an IP fragment. Since the fxp driver does not claim to support for checksumming IP fragments (indicated by the CSUM_IP_FRAGS flag), the stack should not request hardware checksums for fragmented packets. If hardware parsing is also enabled as required by the first note, then it may be possible to safely enable IP header checksumming as well. My patch does not address this, but maybe this could be enabled after 5.1-RELEASE. Index: sys/dev/fxp/if_fxp.c =================================================================== RCS file: /home/ncvs/src/sys/dev/fxp/if_fxp.c,v retrieving revision 1.179 diff -u -r1.179 if_fxp.c --- sys/dev/fxp/if_fxp.c 16 May 2003 01:13:16 -0000 1.179 +++ sys/dev/fxp/if_fxp.c 22 May 2003 07:41:08 -0000 @@ -1277,6 +1295,23 @@ txp = sc->fxp_desc.tx_last->tx_next; /* + * A note in Appendix B of the Intel 8255x 10/100 Mbps + * Ethernet Controller Family Open Source Software + * Developer Manual says: + * Using software parsing is only allowed with legal + * TCP/IP or UDP/IP packets. + * ... + * For all other datagrams, hardware parsing must + * be used. + * Software parsing appears to truncate ICMP and + * fragmented UDP packets that contain one to three + * bytes in the second (and final) mbuf of the packet. + */ + if (sc->flags & FXP_FLAG_EXT_RFA) + txp->tx_cb->ipcb_ip_activation_high = + FXP_IPCB_HARDWAREPARSING_ENABLE; + + /* * Deal with TCP/IP checksum offload. Note that * in order for TCP checksum offload to work, * the pseudo header checksum must have already @@ -1287,8 +1322,6 @@ if (mb_head->m_pkthdr.csum_flags) { if (mb_head->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { - txp->tx_cb->ipcb_ip_activation_high = - FXP_IPCB_HARDWAREPARSING_ENABLE; txp->tx_cb->ipcb_ip_schedule = FXP_IPCB_TCPUDP_CHECKSUM_ENABLE; if (mb_head->m_pkthdr.csum_flags & CSUM_TCP)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200305220823.h4M8N9M7075271>