- 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