git: cd9b04bdb1cc - stable/14 - igb: Program Rx descriptor thresholds by family

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

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

commit cd9b04bdb1cc18496e84ee86fcdee8cf6b19d431
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-08-08 12:27:37 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-08-22 00:56:22 +0000

    igb: Program Rx descriptor thresholds by family
    
    82576 specification-update erratum 26 says MSI-X EITR expiration can
    fail to trigger receive descriptor writeback.  A WTHRESH above one can
    therefore leave received packets invisible until the threshold fills.
    
    The shared threshold macros selected policy by enum ordering, so an
    82576 VF fell into the generic WTHRESH=4 case.  VFs always use MSI-X
    and require the same WTHRESH=1 workaround as the PF.
    
    Use PTHRESH=8 for 82575 and 82576 PFs and VFs, matching DPDK and the
    current Linux PF driver.  The legacy FreeBSD PF and Linux igbvf value
    of 16 thrashes limited descriptor cache; no specification or erratum
    requires it.  Retain the i354 PTHRESH=12 exception.
    
    Enumerate every supported igb PF and VF MAC type so each receives its
    intended policy.  Also clear every threshold bit before installing the
    new values.  The old mask retained the high WTHRESH bit, and 82575
    uses six-bit fields while later controllers use five-bit fields.
    
    (cherry picked from commit bd4182a2c96eb8329de54448a96bbd15f14238da)
---
 sys/dev/e1000/if_em.c | 57 +++++++++++++++++++++++++++++++++++++++++++++------
 sys/dev/e1000/if_em.h | 18 +++++++++++-----
 2 files changed, 64 insertions(+), 11 deletions(-)

diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index d78cd0f89ac5..340ebe479eb7 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -3924,6 +3924,56 @@ em_initialize_transmit_unit(if_ctx_t ctx)
  **********************************************************************/
 #define BSIZEPKT_ROUNDUP ((1<<E1000_SRRCTL_BSIZEPKT_SHIFT)-1)
 
+static u32
+igb_rxdctl(struct e1000_softc *sc, u32 rxdctl)
+{
+	struct e1000_hw *hw;
+	u32 mask, pthresh, wthresh;
+
+	hw = &sc->hw;
+	mask = IGB_RXDCTL_THRESH_MASK;
+	switch (hw->mac.type) {
+	case e1000_82575:
+		mask = IGB_82575_RXDCTL_THRESH_MASK;
+		pthresh = IGB_RX_PTHRESH;
+		wthresh = IGB_RX_WTHRESH;
+		break;
+	case e1000_82576:
+		pthresh = IGB_RX_PTHRESH;
+		wthresh = sc->intr_type == IFLIB_INTR_MSIX ?
+		    IGB_82576_RX_WTHRESH : IGB_RX_WTHRESH;
+		break;
+	case e1000_vfadapt:
+		/* 82576 VFs always need the MSI-X writeback workaround. */
+		pthresh = IGB_RX_PTHRESH;
+		wthresh = IGB_82576_RX_WTHRESH;
+		break;
+	case e1000_i354:
+		pthresh = I354_RX_PTHRESH;
+		wthresh = IGB_RX_WTHRESH;
+		break;
+	case e1000_82580:
+	case e1000_i350:
+	case e1000_i210:
+	case e1000_i211:
+	case e1000_vfadapt_i350:
+		pthresh = IGB_RX_PTHRESH;
+		wthresh = IGB_RX_WTHRESH;
+		break;
+	default:
+		KASSERT(0, ("%s: unsupported MAC type %d", __func__,
+		    hw->mac.type));
+		pthresh = IGB_RX_PTHRESH;
+		wthresh = IGB_RX_WTHRESH;
+		break;
+	}
+
+	rxdctl &= ~mask;
+	rxdctl |= pthresh | (IGB_RX_HTHRESH << 8) |
+	    (wthresh << 16) | E1000_RXDCTL_QUEUE_ENABLE;
+	return (rxdctl);
+}
+
 static bool
 em_integrated_jumbo_rx(struct e1000_hw *hw)
 {
@@ -4175,12 +4225,7 @@ em_initialize_receive_unit(if_ctx_t ctx)
 			E1000_WRITE_REG(hw, E1000_RDH(i), 0);
 			E1000_WRITE_REG(hw, E1000_RDT(i), 0);
 			E1000_WRITE_REG(hw, E1000_SRRCTL(i), srrctl);
-			/* Enable this Queue */
-			rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
-			rxdctl &= 0xFFF00000;
-			rxdctl |= IGB_RX_PTHRESH;
-			rxdctl |= IGB_RX_HTHRESH << 8;
-			rxdctl |= IGB_RX_WTHRESH << 16;
+			rxdctl = igb_rxdctl(sc, rxdctl);
 			E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl);
 		}		
 	} else if (hw->mac.type >= e1000_pch2lan) {
diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h
index 4873eb330e87..51eaee3ae19c 100644
--- a/sys/dev/e1000/if_em.h
+++ b/sys/dev/e1000/if_em.h
@@ -310,11 +310,19 @@
 #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
-#define IGB_RX_WTHRESH	((hw->mac.type == e1000_82576 && \
-			    (sc->intr_type == IFLIB_INTR_MSIX)) ? 1 : 4)
+#define IGB_RXDCTL_PTHRESH_MASK	0x0000001F
+#define IGB_RXDCTL_HTHRESH_MASK	0x00001F00
+#define IGB_RXDCTL_WTHRESH_MASK	0x001F0000
+#define IGB_RXDCTL_THRESH_MASK	(IGB_RXDCTL_PTHRESH_MASK | \
+				 IGB_RXDCTL_HTHRESH_MASK | \
+				 IGB_RXDCTL_WTHRESH_MASK)
+#define IGB_82575_RXDCTL_THRESH_MASK	0x003F3F3F
+
+#define IGB_RX_PTHRESH		8
+#define I354_RX_PTHRESH		12
+#define IGB_RX_HTHRESH		8
+#define IGB_RX_WTHRESH		4
+#define IGB_82576_RX_WTHRESH	1
 
 #define IGB_TX_PTHRESH		8
 #define I354_TX_PTHRESH	20
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.