Skip to contentSkip to conversation

e1000e: Fix jumbo frame receive code.

PATCH In review Auke Kok 2 participants 6 messages Oct 25, 2007 – Oct 29, 2007

Subsystems (2)
lore
Share & tools
lore

Auke Kok

author
#0 lore raw

PATCH 1/4 e1000e: Fix jumbo frame receive code.

Fix allocation and freeing of jumbo frames where several bugs were recently introduced by cleanups after we forked this code from e1000. This moves ps_pages to buffer_info where it really belongs and makes it a dynamically allocated array. The penalty is not that high since it's allocated outside of the buffer_info struct anyway.

Without this patch all jumbo frames are completely broken and the driver panics.

---

 drivers/net/e1000e/e1000.h  |    4 +-
 drivers/net/e1000e/netdev.c |  102 ++++++++++++++++++++++---------------------
 2 files changed, 54 insertions(+), 52 deletions(-)
drivers/net/e1000e/e1000.h +2 -2
index d2499bb..811eada 100644
@@ -123,6 +123,8 @@ struct e1000_buffer {
 		};
 		/* RX */
 		struct page *page;
+		/* arrays of page information for packet split */
+		struct e1000_ps_page *ps_pages;
 	};
 
 };
@@ -142,8 +144,6 @@ struct e1000_ring {
 	/* array of buffer information structs */
 	struct e1000_buffer *buffer_info;
 
-	/* arrays of page information for packet split */
-	struct e1000_ps_page *ps_pages;
 	struct sk_buff *rx_skb_top;
 
 	struct e1000_queue_stats stats;
drivers/net/e1000e/netdev.c +52 -50

179 lines not on this page · raw message

author
#1 lore raw

PATCH 2/4 e1000e: Fix PBA calculation for jumbo frame packets

Upon inspection the rx FIFO size calculation code was found to have 2 significant flaws: A superfluous minus sign resulting in the wrong size to be used for jumbo frames on 82573 and ich9, as well as that this code rewrote the read-only adapter->pba variable resulting in different values at each run.

Without this patch jumbo's will work but performance will be awkward since the TX size is not adequate for two whole frames.

---

 drivers/net/e1000e/netdev.c |   22 +++++++++++++---------
 1 files changed, 13 insertions(+), 9 deletions(-)
drivers/net/e1000e/netdev.c +13 -9
index 46c5ac6..e87ed31 100644
@@ -2328,8 +2328,11 @@ void e1000e_reset(struct e1000_adapter *adapter)
 	struct e1000_mac_info *mac = &adapter->hw.mac;
 	struct e1000_hw *hw = &adapter->hw;
 	u32 tx_space, min_tx_space, min_rx_space;
+	u32 pba;
 	u16 hwm;
 
+	ew32(PBA, adapter->pba);
+
 	if (mac->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN ) {
 		/* To maintain wire speed transmits, the Tx FIFO should be
 		 * large enough to accommodate two full transmit packets,
@@ -2337,11 +2340,11 @@ void e1000e_reset(struct e1000_adapter *adapter)
 		 * the Rx FIFO should be large enough to accommodate at least
 		 * one full receive packet and is similarly rounded up and
 		 * expressed in KB. */
-		adapter->pba = er32(PBA);
+		pba = er32(PBA);
 		/* upper 16 bits has Tx packet buffer allocation size in KB */
-		tx_space = adapter->pba >> 16;
+		tx_space = pba >> 16;
 		/* lower 16 bits has Rx packet buffer allocation size in KB */
-		adapter->pba &= 0xffff;
+		pba &= 0xffff;
 		/* the tx fifo also stores 16 bytes of information about the tx
 		 * but don't include ethernet FCS because hardware appends it */
 		min_tx_space = (mac->max_frame_size +
@@ -2357,20 +2360,21 @@ void e1000e_reset(struct e1000_adapter *adapter)
 		/* If current Tx allocation is less than the min Tx FIFO size,
 		 * and the min Tx FIFO size is less than the current Rx FIFO
 		 * allocation, take space away from current Rx allocation */
-		if (tx_space < min_tx_space &&
-		    ((min_tx_space - tx_space) < adapter->pba)) {
-			adapter->pba -= - (min_tx_space - tx_space);
+		if ((tx_space < min_tx_space) &&
+		    ((min_tx_space - tx_space) < pba)) {
+			pba -= min_tx_space - tx_space;
 
 			/* if short on rx space, rx wins and must trump tx
 			 * adjustment or use Early Receive if available */
-			if ((adapter->pba < min_rx_space) &&
+			if ((pba < min_rx_space) &&
 			    (!(adapter->flags & FLAG_HAS_ERT)))
 				/* ERT enabled in e1000_configure_rx */
-				adapter->pba = min_rx_space;
+				pba = min_rx_space;
 		}
+
+		ew32(PBA, pba);
 	}
 
-	ew32(PBA, adapter->pba);
 
 	/* flow control settings */
 	/* The high water mark must be low enough to fit one full frame
author
#2 lore raw

PATCH 3/4 e1000e: Re-enable SECRC - crc stripping

In reply to Auke Kok

This workaround code performed software stripping instead of the hardware which can do it much faster. None of the e1000e target hardware has issues with this feature and should work fine. This gives us some performance back on receive, and removes some kludging stripping the 4 bytes.

---

 drivers/net/e1000e/netdev.c |   19 ++++++-------------
 1 files changed, 6 insertions(+), 13 deletions(-)
drivers/net/e1000e/netdev.c +6 -13
index e87ed31..03fcc70 100644
@@ -494,10 +494,6 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 			goto next_desc;
 		}
 
-		/* adjust length to remove Ethernet CRC */
-		length -= 4;
-
-		/* probably a little skewed due to removing CRC */
 		total_rx_bytes += length;
 		total_rx_packets++;
 
@@ -964,8 +960,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
 			kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
 			pci_dma_sync_single_for_device(pdev, ps_page->dma,
 				PAGE_SIZE, PCI_DMA_FROMDEVICE);
-			/* remove the CRC */
-			l1 -= 4;
+
 			skb_put(skb, l1);
 			goto copydone;
 		} /* if */
@@ -987,10 +982,6 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
 			skb->truesize += length;
 		}
 
-		/* strip the ethernet crc, problem is we're using pages now so
-		 * this whole operation can get a little cpu intensive */
-		pskb_trim(skb, skb->len - 4);
-
 copydone:
 		total_rx_bytes += skb->len;
 		total_rx_packets++;
@@ -2034,9 +2025,11 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
 
 		ew32(RFCTL, rfctl);
 
-		/* disable the stripping of CRC because it breaks
-		 * BMC firmware connected over SMBUS */
-		rctl |= E1000_RCTL_DTYP_PS /* | E1000_RCTL_SECRC */;
+		/* Enable Packet split descriptors */
+		rctl |= E1000_RCTL_DTYP_PS;
+		
+		/* Enable hardware CRC frame stripping */
+		rctl |= E1000_RCTL_SECRC;
 
 		psrctl |= adapter->rx_ps_bsize0 >>
 			E1000_PSRCTL_BSIZE0_SHIFT;
author
#3 lore raw

PATCH 4/4 e1000e: Remove legacy jumbo frame receive code

In reply to Auke Kok

The legacy jumbo frame receive code is no longer needed since all hardware can do packet split and we're no longer offering a bypass kernel config option to disable packet split. Remove the unused code.

---

 drivers/net/e1000e/e1000.h  |    1 
 drivers/net/e1000e/netdev.c |  282 -------------------------------------------
 2 files changed, 1 insertions(+), 282 deletions(-)
drivers/net/e1000e/e1000.h +0 -1
index 811eada..473f78d 100644
@@ -122,7 +122,6 @@ struct e1000_buffer {
 			u16 next_to_watch;
 		};
 		/* RX */
-		struct page *page;
 		/* arrays of page information for packet split */
 		struct e1000_ps_page *ps_pages;
 	};
drivers/net/e1000e/netdev.c +1 -281

324 lines not on this page · raw message

author
#4 lore raw
In reply to Auke Kok
Quoted 9 lines · Auke Kok

Fix allocation and freeing of jumbo frames where several bugs were recently introduced by cleanups after we forked this code from e1000. This moves ps_pages to buffer_info where it really belongs and makes it a dynamically allocated array. The penalty is not that high since it's allocated outside of the buffer_info struct anyway.

Without this patch all jumbo frames are completely broken and the driver panics.

Jeff,

I strongly suggest that you apply patches #1 and #2 (but preferably all) to #upstream-fixes since these patches fix the -absolutely- broken jumbo frames code in e1000e. On top of that patches #1 and #2 only touch the jumbo frame codepath, so the impact is zero to the normal way people use these cards.

patch #3 is an optimization, patch #4 is mostly cosmetical.

Cheers,

Auke

#5 lore raw
In reply to Auke Kok
Quoted 10 lines · Auke Kok

Fix allocation and freeing of jumbo frames where several bugs were recently introduced by cleanups after we forked this code from e1000. This moves ps_pages to buffer_info where it really belongs and makes it a dynamically allocated array. The penalty is not that high since it's allocated outside of the buffer_info struct anyway.

Without this patch all jumbo frames are completely broken and the driver panics.

Quoted 7 lines

---

 drivers/net/e1000e/e1000.h  |    4 +-
 drivers/net/e1000e/netdev.c |  102 ++++++++++++++++++++++---------------------
 2 files changed, 54 insertions(+), 52 deletions(-)

applied 1-4 to #upstream-fixes