git: c577d5eb972d - stable/14 - igc: Work around I225 v1 minimum IPG erratum

Kevin Bowling <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a82556d.38bb3.40983569__633.674177673527$1786926485$gmane$org@gitrepo.freebsd.org>
The branch stable/14 has been updated by kbowling:

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

commit c577d5eb972dc406a079ee7ed8b44fb9132b6da7
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-08-03 10:28:49 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-08-17 00:26:19 +0000

    igc: Work around I225 v1 minimum IPG erratum
    
    I225 v1 cannot receive the minimum inter-packet gap required at
    2.5 Gb/s.  For affected back-to-back links, Intel recommends using a
    15-byte transmit IPG instead of 12 bytes.
    
    Program TIPG.IPGT to 0xb for pre-v2 I225 devices at 2.5 Gb/s and
    restore the default at lower speeds.  Avoid penalizing fixed I225 and
    I226 parts.
    
    (cherry picked from commit 709426551c6a3607fb5a33f5b8dbb87cfa9c8125)
---
 sys/dev/igc/if_igc.c      | 29 +++++++++++++++++++++++++++++
 sys/dev/igc/igc_defines.h |  1 +
 2 files changed, 30 insertions(+)

diff --git a/sys/dev/igc/if_igc.c b/sys/dev/igc/if_igc.c
index c49948f7c57e..17784f5f5f43 100644
--- a/sys/dev/igc/if_igc.c
+++ b/sys/dev/igc/if_igc.c
@@ -129,6 +129,7 @@ static int	igc_if_rx_queue_intr_enable(if_ctx_t, uint16_t);
 static int	igc_if_tx_queue_intr_enable(if_ctx_t, uint16_t);
 static void	igc_if_multi_set(if_ctx_t);
 static void	igc_if_update_admin_status(if_ctx_t);
+static void	igc_apply_i225_ipg_workaround(struct igc_softc *);
 static void	igc_if_debug(if_ctx_t);
 static void	igc_update_stats_counters(struct igc_softc *);
 static void	igc_add_hw_stats(struct igc_softc *);
@@ -1397,6 +1398,33 @@ igc_if_timer(if_ctx_t ctx, uint16_t qid)
 	iflib_admin_intr_deferred(ctx);
 }
 
+static void
+igc_apply_i225_ipg_workaround(struct igc_softc *sc)
+{
+	struct igc_hw *hw = &sc->hw;
+	u32 ipgt, tipg;
+
+	/*
+	 * I225 v1 cannot receive the minimum IPG required at 2.5 Gb/s.
+	 * Intel's documented back-to-back workaround is for the transmitter
+	 * to use a 15-byte IPG instead of 12 bytes.  I225 v2 and later have
+	 * the receive-side fix and should retain the standard IPG.
+	 */
+	if (!igc_is_device_id_i225(hw) ||
+	    hw->revision_id >= IGC_REVISION_2)
+		return;
+
+	ipgt = sc->link_speed == SPEED_2500 ? IGC_I225_TIPG_IPGT_2P5 :
+	    DEFAULT_82543_TIPG_IPGT_COPPER;
+	tipg = IGC_READ_REG(hw, IGC_TIPG);
+	if ((tipg & IGC_TIPG_IPGT_MASK) == ipgt)
+		return;
+
+	tipg &= ~IGC_TIPG_IPGT_MASK;
+	tipg |= ipgt;
+	IGC_WRITE_REG(hw, IGC_TIPG, tipg);
+}
+
 static void
 igc_if_update_admin_status(if_ctx_t ctx)
 {
@@ -1442,6 +1470,7 @@ igc_if_update_admin_status(if_ctx_t ctx)
 		sc->link_active = 0;
 		iflib_link_state_change(ctx, LINK_STATE_DOWN, 0);
 	}
+	igc_apply_i225_ipg_workaround(sc);
 	igc_update_stats_counters(sc);
 }
 
diff --git a/sys/dev/igc/igc_defines.h b/sys/dev/igc/igc_defines.h
index 09f75fe2787e..3e6309176204 100644
--- a/sys/dev/igc/igc_defines.h
+++ b/sys/dev/igc/igc_defines.h
@@ -364,6 +364,7 @@
 /* Default values for the transmit IPG register */
 #define DEFAULT_82543_TIPG_IPGT_FIBER	9
 #define DEFAULT_82543_TIPG_IPGT_COPPER	8
+#define IGC_I225_TIPG_IPGT_2P5		0xB
 
 #define IGC_TIPG_IPGT_MASK		0x000003FF
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.