- this fixes an issue of premature desc writeback by hardware
Signed-off-by: Jeff Kirsher <[EMAIL PROTECTED]>
Signed-off-by: Jesse Brandeburg <[EMAIL PROTECTED]>
Signed-off-by: John Ronciak <[EMAIL PROTECTED]>
---
drivers/net/ixgb/ixgb_main.c | 21 +++++++++++++++------
1 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 5996d91..c10a1c1 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -454,9 +454,7 @@ ixgb_probe(struct pci_dev *pdev,
NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER;
-#ifdef NETIF_F_TSO
netdev->features |= NETIF_F_TSO;
-#endif
if(pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
@@ -1173,7 +1171,6 @@ ixgb_watchdog(unsigned long data)
static inline int
ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb)
{
-#ifdef NETIF_F_TSO
struct ixgb_context_desc *context_desc;
unsigned int i;
uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
@@ -1227,7 +1224,6 @@ ixgb_tso(struct ixgb_adapter *adapter, s
return TRUE;
}
-#endif
return FALSE;
}
@@ -1278,6 +1274,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter
struct ixgb_buffer *buffer_info;
int len = skb->len;
unsigned int offset = 0, size, count = 0, i;
+ unsigned int mss = skb_shinfo(skb)->tso_size;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int f;
@@ -1289,6 +1286,11 @@ ixgb_tx_map(struct ixgb_adapter *adapter
while(len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE);
+ /* Workaround for premature desc write-backs
+ * in TSO mode. Append 4-byte sentinel desc */
+ if(unlikely(mss && !nr_frags && size == len && size > 8))
+ size -= 4;
+
buffer_info->length = size;
buffer_info->dma =
pci_map_single(adapter->pdev,
@@ -1313,6 +1315,12 @@ ixgb_tx_map(struct ixgb_adapter *adapter
while(len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE);
+ /* Workaround for premature desc write-backs
+ * in TSO mode. Append 4-byte sentinel desc */
+ if(unlikely(mss && (f == (nr_frags-1)) && (size == len)
+ && (size > 8)))
+ size -= 4;
+
buffer_info->length = size;
buffer_info->dma =
pci_map_page(adapter->pdev,
@@ -1390,7 +1398,8 @@ ixgb_tx_queue(struct ixgb_adapter *adapt
#define TXD_USE_COUNT(S) (((S) >> IXGB_MAX_TXD_PWR) + \
(((S) & (IXGB_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
#define DESC_NEEDED TXD_USE_COUNT(IXGB_MAX_DATA_PER_TXD) + \
- MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
+ MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1 \
+ /* one more for TSO workaround */ + 1
static int
ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
@@ -1428,7 +1437,7 @@ ixgb_xmit_frame(struct sk_buff *skb, str
return NETDEV_TX_OK;
}
- if (tso)
+ if (likely(tso))
tx_flags |= IXGB_TX_FLAGS_TSO;
else if(ixgb_tx_csum(adapter, skb))
tx_flags |= IXGB_TX_FLAGS_CSUM;
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html