git: 9a89886460b6 - stable/14 - e1000: sysctl for TCP flag handling during TSO

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Sun, 24 Nov 2024 03:21:55 UTC
The branch stable/14 has been updated by kbowling:

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

commit 9a89886460b6932c7a93bc324529250241f25521
Author:     Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2024-11-21 02:22:10 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2024-11-24 03:21:17 +0000

    e1000: sysctl for TCP flag handling during TSO
    
    Add tso_tcp_flags_mask_first_segment, tso_tcp_flags_mask_middle_segment,
    and tso_tcp_flags_mask_last_segment sysctl-variables to control the
    handling of TCP flags during TSO.
    
    This allows to change the masks appropriate for classical ECN and to
    configure appropriate masks for accurate ECN.
    
    Reviewed by:    rrs
    Sponsored by:   Netflix
    Differential Revision:  https://reviews.freebsd.org/D44259
    
    (cherry picked from commit 90853dfac851afa9e8840f5a38383256d75458b6)
---
 sys/dev/e1000/if_em.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index 0b99f1b06130..98521e6e6ee9 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -333,6 +333,7 @@ static int 	em_is_valid_ether_addr(u8 *);
 static void	em_newitr(struct e1000_softc *, struct em_rx_queue *,
     struct tx_ring *, struct rx_ring *);
 static bool	em_automask_tso(if_ctx_t);
+static int	em_sysctl_tso_tcp_flags_mask(SYSCTL_HANDLER_ARGS);
 static int	em_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
 static void	em_add_int_delay_sysctl(struct e1000_softc *, const char *,
     const char *, struct em_int_delay_info *, int, int);
@@ -876,6 +877,24 @@ em_if_attach_pre(if_ctx_t ctx)
 		    igb_sysctl_dmac, "I", "DMA Coalesce");
 	}
 
+	SYSCTL_ADD_PROC(ctx_list, child, OID_AUTO,
+	    "tso_tcp_flags_mask_first_segment",
+	    CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
+	    sc, 0, em_sysctl_tso_tcp_flags_mask, "IU",
+	    "TSO TCP flags mask for first segment");
+
+	SYSCTL_ADD_PROC(ctx_list, child, OID_AUTO,
+	    "tso_tcp_flags_mask_middle_segment",
+	    CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
+	    sc, 1, em_sysctl_tso_tcp_flags_mask, "IU",
+	    "TSO TCP flags mask for middle segment");
+
+	SYSCTL_ADD_PROC(ctx_list, child, OID_AUTO,
+	    "tso_tcp_flags_mask_last_segment",
+	    CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
+	    sc, 2, em_sysctl_tso_tcp_flags_mask, "IU",
+	    "TSO TCP flags mask for last segment");
+
 	scctx->isc_tx_nsegments = EM_MAX_SCATTER;
 	scctx->isc_nrxqsets_max = scctx->isc_ntxqsets_max = em_set_num_queues(ctx);
 	if (bootverbose)
@@ -5182,6 +5201,43 @@ em_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
 	return (0);
 }
 
+static int
+em_sysctl_tso_tcp_flags_mask(SYSCTL_HANDLER_ARGS)
+{
+	struct e1000_softc *sc;
+	u32 reg, val, shift;
+	int error, mask;
+
+	sc = oidp->oid_arg1;
+	switch (oidp->oid_arg2) {
+	case 0:
+		reg = E1000_DTXTCPFLGL;
+		shift = 0;
+		break;
+	case 1:
+		reg = E1000_DTXTCPFLGL;
+		shift = 16;
+		break;
+	case 2:
+		reg = E1000_DTXTCPFLGH;
+		shift = 0;
+		break;
+	default:
+		return (EINVAL);
+		break;
+	}
+	val = E1000_READ_REG(&sc->hw, reg);
+	mask = (val >> shift) & 0xfff;
+	error = sysctl_handle_int(oidp, &mask, 0, req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+	if (mask < 0 || mask > 0xfff)
+		return (EINVAL);
+	val = (val & ~(0xfff << shift)) | (mask << shift);
+	E1000_WRITE_REG(&sc->hw, reg, val);
+	return (0);
+}
+
 static void
 em_add_int_delay_sysctl(struct e1000_softc *sc, const char *name,
 	const char *description, struct em_int_delay_info *info,