git: ab540d44ba32 - main - igc: sysctl for TCP flag handling during TSO

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Thu, 21 Nov 2024 02:38:50 UTC
The branch main has been updated by kbowling:

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

commit ab540d44ba3201ff8313b90ba0096004603b2e34
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2024-11-21 02:38:01 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2024-11-21 02:38:01 +0000

    igc: 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.
    
    MFC after:      3 days
    Sponsored by:   Netflix
---
 sys/dev/igc/if_igc.c   | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/igc/igc_regs.h |  2 ++
 2 files changed, 61 insertions(+)

diff --git a/sys/dev/igc/if_igc.c b/sys/dev/igc/if_igc.c
index 38fb1406b1c1..9a4d0b2dd0ac 100644
--- a/sys/dev/igc/if_igc.c
+++ b/sys/dev/igc/if_igc.c
@@ -127,6 +127,7 @@ static void	igc_print_debug_info(struct igc_softc *);
 static int 	igc_is_valid_ether_addr(u8 *);
 static void	igc_neweitr(struct igc_softc *, struct igc_rx_queue *,
     struct tx_ring *, struct rx_ring *);
+static int	igc_sysctl_tso_tcp_flags_mask(SYSCTL_HANDLER_ARGS);
 /* Management and WOL Support */
 static void	igc_get_hw_control(struct igc_softc *);
 static void	igc_release_hw_control(struct igc_softc *);
@@ -497,6 +498,27 @@ igc_if_attach_pre(if_ctx_t ctx)
 	    CTLTYPE_INT | CTLFLAG_RW, sc, 0,
 	    igc_sysctl_dmac, "I", "DMA Coalesce");
 
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+	    OID_AUTO, "tso_tcp_flags_mask_first_segment",
+	    CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
+	    sc, 0, igc_sysctl_tso_tcp_flags_mask, "IU",
+	    "TSO TCP flags mask for first segment");
+
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+	    OID_AUTO, "tso_tcp_flags_mask_middle_segment",
+	    CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
+	    sc, 1, igc_sysctl_tso_tcp_flags_mask, "IU",
+	    "TSO TCP flags mask for middle segment");
+
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+	    OID_AUTO, "tso_tcp_flags_mask_last_segment",
+	    CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
+	    sc, 2, igc_sysctl_tso_tcp_flags_mask, "IU",
+	    "TSO TCP flags mask for last segment");
+
 	/* Determine hardware and mac info */
 	igc_identify_hardware(ctx);
 
@@ -3013,6 +3035,43 @@ igc_print_nvm_info(struct igc_softc *sc)
 	printf("\n");
 }
 
+static int
+igc_sysctl_tso_tcp_flags_mask(SYSCTL_HANDLER_ARGS)
+{
+	struct igc_softc *sc;
+	u32 reg, val, shift;
+	int error, mask;
+
+	sc = oidp->oid_arg1;
+	switch (oidp->oid_arg2) {
+	case 0:
+		reg = IGC_DTXTCPFLGL;
+		shift = 0;
+		break;
+	case 1:
+		reg = IGC_DTXTCPFLGL;
+		shift = 16;
+		break;
+	case 2:
+		reg = IGC_DTXTCPFLGH;
+		shift = 0;
+		break;
+	default:
+		return (EINVAL);
+		break;
+	}
+	val = IGC_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);
+	IGC_WRITE_REG(&sc->hw, reg, val);
+	return (0);
+}
+
 /*
  * Set flow control using sysctl:
  * Flow control values:
diff --git a/sys/dev/igc/igc_regs.h b/sys/dev/igc/igc_regs.h
index 26614dc33df6..17fa89e492e8 100644
--- a/sys/dev/igc/igc_regs.h
+++ b/sys/dev/igc/igc_regs.h
@@ -145,6 +145,8 @@
 #define IGC_FFVT_REG(_i)	(0x09800 + ((_i) * 8))
 #define IGC_FFLT_REG(_i)	(0x05F00 + ((_i) * 8))
 #define IGC_TXPBS		0x03404  /* Tx Packet Buffer Size - RW */
+#define IGC_DTXTCPFLGL	0x0359C  /* DMA Tx Control flag low - RW */
+#define IGC_DTXTCPFLGH	0x035A0  /* DMA Tx Control flag high - RW */
 /* Statistics Register Descriptions */
 #define IGC_CRCERRS		0x04000  /* CRC Error Count - R/clr */
 #define IGC_ALGNERRC		0x04004  /* Alignment Error Count - R/clr */