git: 512eb6235fcb - stable/13 - cxgbe(4): separate sysctls for user-requested and in-use FEC.

From: Navdeep Parhar <np_at_FreeBSD.org>
Date: Mon, 28 Feb 2022 06:55:38 UTC
The branch stable/13 has been updated by np:

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

commit 512eb6235fcb2a3ef3a1b2ebaf4767aece54cdac
Author:     Navdeep Parhar <np@FreeBSD.org>
AuthorDate: 2021-11-10 18:54:53 +0000
Commit:     Navdeep Parhar <np@FreeBSD.org>
CommitDate: 2022-02-28 06:43:59 +0000

    cxgbe(4): separate sysctls for user-requested and in-use FEC.
    
    Recent firmwares have more leeway in FEC selection and there is a need
    to track the FECs requested by the driver separately from the FEC in use
    on the link. The existing dev.<port>.<inst>.fec sysctl can read both but
    its behavior depends on the link state and it is sometimes hard to find
    out what was requested when the link is up.
    
    Split the fec sysctl into two (requested_fec and link_fec) to get access
    to both pieces of information regardless of the link state.
    
    Sponsored by:   Chelsio Communications
    
    (cherry picked from commit f6a2e1100fa09742aa29d8e51fd6181fb5c171bb)
---
 share/man/man4/cxgbe.4  |  8 +++++---
 sys/dev/cxgbe/t4_main.c | 52 ++++++++++++++++++++++++++++++++++---------------
 2 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/share/man/man4/cxgbe.4 b/share/man/man4/cxgbe.4
index f4484b644802..5f959299d2ad 100644
--- a/share/man/man4/cxgbe.4
+++ b/share/man/man4/cxgbe.4
@@ -31,7 +31,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 19, 2020
+.Dd November 10, 2021
 .Dt CXGBE 4
 .Os
 .Sh NAME
@@ -300,8 +300,10 @@ Bit 0 enables RS FEC, bit 1 enables BASE-R FEC (aka Firecode FEC), bit
 transceiver/cable that is plugged in.
 These bits can be set together in any combination.
 This tunable establishes the default FEC settings for all ports.
-Settings can be displayed and controlled on a per-port basis via the
-dev.<port>.X.fec sysctl.
+Settings can be controlled on a per-port basis via the
+dev.<port>.X.requested_fec sysctl.
+The FEC in use on the link is available in dev.<port>.X.link_fec when
+the link is up.
 .It Va hw.cxgbe.autoneg
 Link autonegotiation settings.
 This tunable establishes the default autonegotiation settings for all ports.
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index 235f9a52546a..71be2c1db71d 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -776,7 +776,8 @@ static int sysctl_holdoff_pktc_idx(SYSCTL_HANDLER_ARGS);
 static int sysctl_qsize_rxq(SYSCTL_HANDLER_ARGS);
 static int sysctl_qsize_txq(SYSCTL_HANDLER_ARGS);
 static int sysctl_pause_settings(SYSCTL_HANDLER_ARGS);
-static int sysctl_fec(SYSCTL_HANDLER_ARGS);
+static int sysctl_link_fec(SYSCTL_HANDLER_ARGS);
+static int sysctl_requested_fec(SYSCTL_HANDLER_ARGS);
 static int sysctl_module_fec(SYSCTL_HANDLER_ARGS);
 static int sysctl_autoneg(SYSCTL_HANDLER_ARGS);
 static int sysctl_handle_t4_reg64(SYSCTL_HANDLER_ARGS);
@@ -7812,9 +7813,12 @@ cxgbe_sysctls(struct port_info *pi)
 	    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, pi, 0,
 	    sysctl_pause_settings, "A",
 	    "PAUSE settings (bit 0 = rx_pause, 1 = tx_pause, 2 = pause_autoneg)");
-	SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "fec",
+	SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "link_fec",
+	    CTLTYPE_STRING | CTLFLAG_MPSAFE, pi, 0, sysctl_link_fec, "A",
+	    "FEC in use on the link");
+	SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "requested_fec",
 	    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, pi, 0,
-	    sysctl_fec, "A",
+	    sysctl_requested_fec, "A",
 	    "FECs to use (bit 0 = RS, 1 = FC, 2 = none, 5 = auto, 6 = module)");
 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "module_fec",
 	    CTLTYPE_STRING | CTLFLAG_MPSAFE, pi, 0, sysctl_module_fec, "A",
@@ -8334,7 +8338,33 @@ sysctl_pause_settings(SYSCTL_HANDLER_ARGS)
 }
 
 static int
-sysctl_fec(SYSCTL_HANDLER_ARGS)
+sysctl_link_fec(SYSCTL_HANDLER_ARGS)
+{
+	struct port_info *pi = arg1;
+	struct link_config *lc = &pi->link_cfg;
+	int rc;
+	struct sbuf *sb;
+	static char *bits = "\20\1RS-FEC\2FC-FEC\3NO-FEC\4RSVD1\5RSVD2";
+
+	rc = sysctl_wire_old_buffer(req, 0);
+	if (rc != 0)
+		return(rc);
+
+	sb = sbuf_new_for_sysctl(NULL, NULL, 128, req);
+	if (sb == NULL)
+		return (ENOMEM);
+	if (lc->link_ok)
+		sbuf_printf(sb, "%b", lc->fec, bits);
+	else
+		sbuf_printf(sb, "no link");
+	rc = sbuf_finish(sb);
+	sbuf_delete(sb);
+
+	return (rc);
+}
+
+static int
+sysctl_requested_fec(SYSCTL_HANDLER_ARGS)
 {
 	struct port_info *pi = arg1;
 	struct adapter *sc = pi->adapter;
@@ -8355,17 +8385,7 @@ sysctl_fec(SYSCTL_HANDLER_ARGS)
 		if (sb == NULL)
 			return (ENOMEM);
 
-		/*
-		 * Display the requested_fec when the link is down -- the actual
-		 * FEC makes sense only when the link is up.
-		 */
-		if (lc->link_ok) {
-			sbuf_printf(sb, "%b", (lc->fec & M_FW_PORT_CAP32_FEC) |
-			    (lc->requested_fec & (FEC_AUTO | FEC_MODULE)),
-			    bits);
-		} else {
-			sbuf_printf(sb, "%b", lc->requested_fec, bits);
-		}
+		sbuf_printf(sb, "%b", lc->requested_fec, bits);
 		rc = sbuf_finish(sb);
 		sbuf_delete(sb);
 	} else {
@@ -8387,7 +8407,7 @@ sysctl_fec(SYSCTL_HANDLER_ARGS)
 			return (EINVAL);/* some other bit is set too */
 
 		rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK,
-		    "t4fec");
+		    "t4reqf");
 		if (rc)
 			return (rc);
 		PORT_LOCK(pi);