aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Bowling <kbowling@FreeBSD.org>2024-11-21 02:38:01 +0000
committerKevin Bowling <kbowling@FreeBSD.org>2024-11-21 02:38:01 +0000
commitab540d44ba3201ff8313b90ba0096004603b2e34 (patch)
treeb26de88d1db524f4a460902758daadfb19db0b87
parent90853dfac851afa9e8840f5a38383256d75458b6 (diff)
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
-rw-r--r--sys/dev/igc/if_igc.c59
-rw-r--r--sys/dev/igc/igc_regs.h2
2 files changed, 61 insertions, 0 deletions
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 */