ixbge: fix bug when using large pages and jumbo frames
authorJesse Brandeburg <jesse.brandeburg@intel.com>
Wed, 25 Feb 2009 00:37:31 +0000 (16:37 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 25 Feb 2009 00:37:31 +0000 (16:37 -0800)
it was pointed out on the list that ixgbe was failing when using 64kB pages
and large 16kB MTU.

since with a 64kB PAGE_SIZE MAX_SKB_FRAGS = 3, the way the driver was
configuring page usage was assuming 2kB is half a page, and was only
ever dmaing that much data to a half page.

(16kB - header size) / 2048 = 7 or 8 pages, which would far exceed 3

adjust the driver to account for these large pages, the hardware can
support DMA to up to 16kB for each descriptor.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ixgbe/ixgbe.h
drivers/net/ixgbe/ixgbe_main.c

index c0e56aab5489c4ae33f89c6f2d6f2c0ae1e2385e..2d877da143cfc9fa6bef5b304004a5acf4b06302 100644 (file)
@@ -71,6 +71,7 @@
 #define IXGBE_RXBUFFER_128   128    /* Used for packet split */
 #define IXGBE_RXBUFFER_256   256    /* Used for packet split */
 #define IXGBE_RXBUFFER_2048  2048
+#define IXGBE_MAX_RXBUFFER   16384  /* largest size for a single descriptor */
 
 #define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256
 
index e0d736cc245bd54842fa94f4cb71f089c43ac20a..65642355a836b8402f4793fda0900731eebb7514 100644 (file)
@@ -1550,7 +1550,14 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
        srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
 
        if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
-               srrctl |= IXGBE_RXBUFFER_2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+               u16 bufsz = IXGBE_RXBUFFER_2048;
+               /* grow the amount we can receive on large page machines */
+               if (bufsz < (PAGE_SIZE / 2))
+                       bufsz = (PAGE_SIZE / 2);
+               /* cap the bufsz at our largest descriptor size */
+               bufsz = min((u16)IXGBE_MAX_RXBUFFER, bufsz);
+
+               srrctl |= bufsz >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
                srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
                srrctl |= ((IXGBE_RX_HDR_SIZE <<
                            IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &