1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-19 02:29:40 +00:00

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.

MFC after:	1 week
Sponsored by:	Chelsio Communications
This commit is contained in:
Navdeep Parhar 2021-11-10 10:54:53 -08:00
parent ac2b544417
commit f6a2e1100f
2 changed files with 41 additions and 19 deletions

View File

@ -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.

View File

@ -771,7 +771,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);
@ -7759,9 +7760,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",
@ -8281,7 +8285,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;
@ -8302,17 +8332,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 {
@ -8334,7 +8354,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);