[RESEND][PATCH net-drivers-2.6 6/16] e1000: Delay clean-up of last Tx packet (fwd)
From: Malli Chilakala <hidden>
Date: 2005-04-27 18:22:46
Delay clean-up of last Tx packet to fix pre-mature writeback issue of Tx descriptors only when TSO is enabled Signed-off-by: Mallikarjuna R Chilakala <redacted> Signed-off-by: Ganesh Venkatesan <redacted> Signed-off-by: John Ronciak <redacted> diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c
--- net-drivers-2.6/drivers/net/e1000/e1000_main.c 2005-04-11 02:22:27.000000000 -0700
+++ net-drivers-2.6/drivers/net/e1000.new/e1000_main.c 2005-04-11 02:22:29.000000000 -0700@@ -2384,11 +2384,10 @@ e1000_clean_tx_irq(struct e1000_adapter eop_desc = E1000_TX_DESC(*tx_ring, eop);
while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
- /* pre-mature writeback of Tx descriptors */
- /* clear (free buffers and unmap pci_mapping) */
- /* previous_buffer_info */
+ /* Premature writeback of Tx descriptors clear (free buffers
+ * and unmap pci_mapping) previous_buffer_info */
if (likely(adapter->previous_buffer_info.skb != NULL)) {
- e1000_unmap_and_free_tx_resource(adapter,
+ e1000_unmap_and_free_tx_resource(adapter,
&adapter->previous_buffer_info);
}
@@ -2397,20 +2725,25 @@ e1000_clean_tx_irq(struct e1000_adapter buffer_info = &tx_ring->buffer_info[i];
cleaned = (i == eop);
- /* pre-mature writeback of Tx descriptors */
- /* save the cleaning of the this for the */
- /* next iteration */
- if (cleaned) {
- memcpy(&adapter->previous_buffer_info,
- buffer_info,
- sizeof(struct e1000_buffer));
- memset(buffer_info,
- 0,
- sizeof(struct e1000_buffer));
+#ifdef NETIF_F_TSO
+ if (!(netdev->features & NETIF_F_TSO)) {
+#endif
+ e1000_unmap_and_free_tx_resource(adapter,
+ buffer_info);
+#ifdef NETIF_F_TSO
} else {
- e1000_unmap_and_free_tx_resource(adapter,
- buffer_info);
+ if (cleaned) {
+ memcpy(&adapter->previous_buffer_info,
+ buffer_info,
+ sizeof(struct e1000_buffer));
+ memset(buffer_info, 0,
+ sizeof(struct e1000_buffer));
+ } else {
+ e1000_unmap_and_free_tx_resource(
+ adapter, buffer_info);
+ }
}
+#endif
tx_desc->buffer_addr = 0;
tx_desc->lower.data = 0;@@ -2443,7 +2760,14 @@ e1000_clean_tx_irq(struct e1000_adapter!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF)) netif_stop_queue(netdev); } +#ifdef NETIF_F_TSO + + if( unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && + time_after(jiffies, adapter->previous_buffer_info.time_stamp + HZ))) + e1000_unmap_and_free_tx_resource( + adapter, &adapter->previous_buffer_info); +#endif return cleaned; }