Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Hardware checksums on bge(4) interfaces



        hello.  Could you try the following patch and let me know if you get
better results?  I'm testing it on a couple of machines here, and, so far,
things look promising.
        Our driver initializes the Broadcom hardware to peform a tcp and udp
checksum on only the payload of the tcp or udp packet, rather than the
entire packet.  The FreeBSD and Linux drivers instruct the hardware to compute
the checksum for the entire packet.  I believe the bug is that some revisions
of the BCM hardware, under certain circumstances, revert to doing the
complete checksum calculation, as the FreeBSD and Linux drivers request, while
things are running. As
a result, when we pull the computed checksum from the hardware and pass it
up to the upper layers, we assume the checksum is the more minimal
one, and the upper layers perform the appropriate checks, which, when this
happens, cause the packet to be rejected because the resultant checksum is
decidedly incorrect.
        This patch changes the driver to instruct the hardware to perform the
checksum over the entire packet, just as the FreeBSD and Linux drivers do,
and to notify the upper layers appropriately.  

        If this patch works, I'll amend the bug report to include the patch
and this explanation.
        The patch file below was made against 5.x sources, but applies cleanly
to 4.x and 3.x sources as well.  I haven't tried, but I assume it will apply
cleanly to -current sources too.

Let me know what you find.
-Brian


Index: if_bge.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_bge.c,v
retrieving revision 1.152.4.2
diff -u -r1.152.4.2 if_bge.c
--- if_bge.c    2 Feb 2009 20:44:16 -0000       1.152.4.2
+++ if_bge.c    15 Sep 2010 07:12:43 -0000
@@ -1444,7 +1444,7 @@
         */
        CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS|
                    BGE_MODECTL_MAC_ATTN_INTR|BGE_MODECTL_HOST_SEND_BDS|
-                   BGE_MODECTL_TX_NO_PHDR_CSUM|BGE_MODECTL_RX_NO_PHDR_CSUM);
+                   BGE_MODECTL_TX_NO_PHDR_CSUM);
 
        /* Get cache line size. */
        cachesize = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CACHESZ);
@@ -3276,7 +3276,7 @@
                            cur_rx->bge_tcp_udp_csum;
                        m->m_pkthdr.csum_flags |=
                            (M_CSUM_TCPv4|M_CSUM_UDPv4|
-                            M_CSUM_DATA|M_CSUM_NO_PSEUDOHDR);
+                            M_CSUM_DATA);
                }
 
                /*


Home | Main Index | Thread Index | Old Index