git: 1dac1e0a05b3 - stable/15 - e1000: Correct Rx descriptor threshold programming

Kevin Bowling <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src,gmane.os.freebsd.devel.stable.scm
Message-ID <[email protected]>
The branch stable/15 has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=1dac1e0a05b313f5c4ca4ceb3c6d96bc8034a981

commit 1dac1e0a05b313f5c4ca4ceb3c6d96bc8034a981
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-08-08 12:26:23 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-08-22 00:31:48 +0000

    e1000: Correct Rx descriptor threshold programming
    
    Jumbo receive tuning on integrated controllers enabled PTHRESH without
    a nonzero HTHRESH, contrary to the hardware programming requirements.
    It also covered only the integrated MAC generations present when the
    workaround was added.  Enumerate every jumbo-capable ICH and PCH type
    and program PTHRESH=3 with HTHRESH=1.  Linux fixed the same HTHRESH
    omission in b701cacdbcfb.
    
    The 82574 path combined threshold values with the reset values using
    bitwise OR.  Requesting WTHRESH=4 while the reset value was one thus
    programmed five.  Clear the complete threshold fields before installing
    the established PTHRESH=32, HTHRESH=4, WTHRESH=4 descriptor-granularity
    policy.
    
    MFC after:      2 weeks
    
    (cherry picked from commit abe22383f1b144f0868aa0654ec4514d36f7a4f5)
---
 sys/dev/e1000/if_em.c | 50 ++++++++++++++++++++++++++++++++++++--------------
 sys/dev/e1000/if_em.h | 13 +++++++++++++
 2 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index b9a4ceb8d6a8..0d0a2d2fe6b0 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -3906,6 +3906,27 @@ em_initialize_transmit_unit(if_ctx_t ctx)
  **********************************************************************/
 #define BSIZEPKT_ROUNDUP ((1<<E1000_SRRCTL_BSIZEPKT_SHIFT)-1)
 
+static bool
+em_integrated_jumbo_rx(struct e1000_hw *hw)
+{
+	switch (hw->mac.type) {
+	case e1000_ich9lan:
+	case e1000_ich10lan:
+	case e1000_pchlan:
+	case e1000_pch2lan:
+	case e1000_pch_lpt:
+	case e1000_pch_spt:
+	case e1000_pch_cnp:
+	case e1000_pch_tgp:
+	case e1000_pch_adp:
+	case e1000_pch_mtp:
+	case e1000_pch_ptp:
+		return (true);
+	default:
+		return (false);
+	}
+}
+
 static void
 em_initialize_receive_unit(if_ctx_t ctx)
 {
@@ -4055,24 +4076,25 @@ em_initialize_receive_unit(if_ctx_t ctx)
 		E1000_WRITE_REG(hw, E1000_RDT(i), 0);
 	}
 
-	/*
-	 * Set PTHRESH for improved jumbo performance
-	 * According to 10.2.5.11 of Intel 82574 Datasheet,
-	 * RXDCTL(1) is written whenever RXDCTL(0) is written.
-	 * Only write to RXDCTL(1) if there is a need for different
-	 * settings.
-	 */
-	if ((hw->mac.type == e1000_ich9lan || hw->mac.type == e1000_pch2lan ||
-	    hw->mac.type == e1000_ich10lan) && if_getmtu(ifp) > ETHERMTU) {
+	/* Increase receive-descriptor prefetching for integrated jumbo MACs. */
+	if (em_integrated_jumbo_rx(hw) && if_getmtu(ifp) > ETHERMTU) {
 		u32 rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(0));
-		E1000_WRITE_REG(hw, E1000_RXDCTL(0), rxdctl | 3);
+
+		rxdctl &= ~(EM_RXDCTL_PTHRESH_MASK |
+		    EM_RXDCTL_HTHRESH_MASK);
+		rxdctl |= EM_JUMBO_RX_PTHRESH |
+		    (EM_JUMBO_RX_HTHRESH << 8);
+		E1000_WRITE_REG(hw, E1000_RXDCTL(0), rxdctl);
 	} else if (hw->mac.type == e1000_82574) {
+		/* RXDCTL(0) writes are mirrored to RXDCTL(1) on 82574. */
 		for (int i = 0; i < sc->rx_num_queues; i++) {
 			u32 rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(i));
-			rxdctl |= 0x20; /* PTHRESH */
-			rxdctl |= 4 << 8; /* HTHRESH */
-			rxdctl |= 4 << 16;/* WTHRESH */
-			rxdctl |= 1 << 24; /* Switch to granularity */
+
+			rxdctl &= ~EM_RXDCTL_THRESH_MASK;
+			rxdctl |= EM_82574_RX_PTHRESH |
+			    (EM_82574_RX_HTHRESH << 8) |
+			    (EM_82574_RX_WTHRESH << 16) |
+			    E1000_RXDCTL_THRESH_UNIT_DESC;
 			E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl);
 		}
 	} else if (hw->mac.type >= igb_mac_min) {
diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h
index 0c61261a5af6..07a92bef1d21 100644
--- a/sys/dev/e1000/if_em.h
+++ b/sys/dev/e1000/if_em.h
@@ -297,6 +297,19 @@
 #define EM_TX_HTHRESH		1
 #define EM_TX_WTHRESH		1
 
+#define EM_RXDCTL_PTHRESH_MASK	0x0000003F
+#define EM_RXDCTL_HTHRESH_MASK	0x00003F00
+#define EM_RXDCTL_WTHRESH_MASK	0x003F0000
+#define EM_RXDCTL_THRESH_MASK	(EM_RXDCTL_PTHRESH_MASK | \
+				 EM_RXDCTL_HTHRESH_MASK | \
+				 EM_RXDCTL_WTHRESH_MASK)
+
+#define EM_JUMBO_RX_PTHRESH	3
+#define EM_JUMBO_RX_HTHRESH	1
+#define EM_82574_RX_PTHRESH	32
+#define EM_82574_RX_HTHRESH	4
+#define EM_82574_RX_WTHRESH	4
+
 #define IGB_RX_PTHRESH	((hw->mac.type == e1000_i354) ? 12 : \
 			    ((hw->mac.type <= e1000_82576) ? 16 : 8))
 #define IGB_RX_HTHRESH	8
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.