git: abe22383f1b1 - main - e1000: Correct Rx descriptor threshold programming

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

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

commit abe22383f1b144f0868aa0654ec4514d36f7a4f5
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-08-08 12:26:23 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-08-08 15:37:01 +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
---
 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 e7bc457ed1bd..b14087f2c88c 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -4419,6 +4419,27 @@ igb_initialize_receive_rings(if_ctx_t ctx, bool drop)
 	}
 }
 
+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)
 {
@@ -4562,24 +4583,25 @@ em_initialize_receive_unit(if_ctx_t ctx)
 		E1000_WRITE_REG(hw, E1000_RDT(qid), 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 5f53f4074fcf..99d4e9d02309 100644
--- a/sys/dev/e1000/if_em.h
+++ b/sys/dev/e1000/if_em.h
@@ -300,6 +300,19 @@ struct igb_vf_mac_filter;
 #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.