Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2701234f authored by Malli Chilakala's avatar Malli Chilakala Committed by Jeff Garzik
Browse files

[PATCH] e1000: Delay clean-up of last Tx packet



Delay clean-up of last Tx packet to fix pre-mature writeback issue of Tx descriptors only when TSO is enabled

Signed-off-by: default avatarMallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com>
Signed-off-by: default avatarGanesh Venkatesan <ganesh.venkatesan@intel.com>
Signed-off-by: default avatarJohn Ronciak <john.ronciak@intel.com>
diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c
parent 4e48a2b9
Loading
Loading
Loading
Loading
+27 −16
Original line number Diff line number Diff line
@@ -2384,9 +2384,8 @@ e1000_clean_tx_irq(struct e1000_adapter *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,
					&adapter->previous_buffer_info);
@@ -2397,20 +2396,25 @@ e1000_clean_tx_irq(struct e1000_adapter *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                         */
#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 {
				if (cleaned) {
					memcpy(&adapter->previous_buffer_info,
					       buffer_info,
					       sizeof(struct e1000_buffer));
				memset(buffer_info,
					0,
					memset(buffer_info, 0,
					       sizeof(struct e1000_buffer));
				} else {
				e1000_unmap_and_free_tx_resource(adapter, 
							buffer_info);
					e1000_unmap_and_free_tx_resource(
					    adapter, buffer_info);
				}
			}
#endif

			tx_desc->buffer_addr = 0;
			tx_desc->lower.data = 0;
@@ -2443,7 +2447,14 @@ e1000_clean_tx_irq(struct e1000_adapter *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;
}