2.6.33-stable review patch. If anyone has any objections, please let us know.

------------------

From: Neil Horman <nhorman@redhat.com>

[ Upstream commit c0cd884af045338476b8e69a61fceb3f34ff22f1 ]

Official patch to fix the r8169 frame length check error.

Based on this initial thread:http://marc.info/?l=linux-netdev&m=126202972828626&w=1This is the official patch to fix the frame length problems in the r8169driver. As noted in the previous thread, while this patch incurs a performancehit on the driver, its possible to improve performance dynamically by updatingthe mtu and rx_copybreak values at runtime to return performance to what it wasfor those NICS which are unaffected by the ideosyncracy (if there are any).

Summary:

A while back Eric submitted a patch for r8169 in which the properallocated frame size was written to RXMaxSize to prevent the NIC from dmaing toomuch data. This was done in commit fdd7b4c3302c93f6833e338903ea77245eb510b4. Along time prior to that however, Francois posted126fa4b9ca5d9d7cb7d46f779ad3bd3631ca387c, which expiclitly disabled the MaxSizesetting due to the fact that the hardware behaved in odd ways when overlongframes were received on NIC's supported by this driver. This was mentioned in asecurity conference recently:http://events.ccc.de/congress/2009/Fahrplan//events/3596.en.html

It seems that if we can't enable frame size filtering, then, as Eric correctlynoticed, we can find ourselves DMA-ing too much data to a buffer, causingcorruption. As a result is seems that we are forced to allocate a frame whichis ready to handle a maximally sized receive.

This obviously has performance issues with it, so to mitigate that issue, thispatch does two things:

1) Raises the copybreak value to the frame allocation size, which should forceappropriately sized packets to get allocated on rx, rather than a full new 16kbuffer.

2) This patch only disables frame filtering initially (i.e., during the NICopen), changing the MTU results in ring buffer allocation of a size in relationto the new mtu (along with a warning indicating that this is dangerous).

Because of item (2), individuals who can't cope with the performance hit (or canotherwise filter frames to prevent the bug), or who have hardware they are sureis unaffected by this issue, can manually lower the copybreak and reset the mtusuch that performance is restored easily.

- rtl8169_set_rxbufsize(tp, dev);+ /*+ * Note that we use a magic value here, its wierd I know+ * its done because, some subset of rtl8169 hardware suffers from+ * a problem in which frames received that are longer than+ * the size set in RxMaxSize register return garbage sizes+ * when received. To avoid this we need to turn off filtering,+ * which is done by setting a value of 16383 in the RxMaxSize register+ * and allocating 16k frames to handle the largest possible rx value+ * thats what the magic math below does.+ */+ rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN);