[RFC PATCH ethtool-next] ethtool: Add clear FEC stats Support
From: Pei Lee Ling <hidden>
Date: 2026-09-21 16:26:01
Subsystem:
the rest · Maintainer:
Linus Torvalds
In high-speed links such as 25G, 100G, and 200G, FEC counters continuously accumulate over time. When troubleshooting intermittent physical-layer issues, users need to establish a clean baseline without resetting the entire device interface. Therefore, this dedicated FEC-stats-clear operation avoids unnecessary operational disruptions. Introducing a fec-clear command would also help to standardize behavior across different network drivers, providing a more consistent and predictable user experience. To clear-fec-stats: ethtool --clear-fec-stats <ETH1> Signed-off-by: Pei Lee Ling <redacted> --- ethtool.c | 5 ++++ netlink/extapi.h | 2 ++ netlink/fec.c | 40 ++++++++++++++++++++++++++ uapi/linux/ethtool_netlink_generated.h | 1 + 4 files changed, 48 insertions(+)
diff --git a/ethtool.c b/ethtool.c
index 3076c12..92d641f 100644
--- a/ethtool.c
+++ b/ethtool.c@@ -6389,6 +6389,11 @@ static const struct option args[] = { .help = "Set FEC settings", .xhelp = " [ encoding auto|off|rs|baser|llrs [...] ]\n" }, + { + .opts = "--clear-fec-stats", + .nlfunc = nl_cfecstats, + .help = "Clear FEC statistics", + }, { .opts = "-Q|--per-queue", .func = do_perqueue,
diff --git a/netlink/extapi.h b/netlink/extapi.h
index b0e4588..272677e 100644
--- a/netlink/extapi.h
+++ b/netlink/extapi.h@@ -43,6 +43,7 @@ int nl_cable_test_tdr(struct cmd_context *ctx); int nl_gtunnels(struct cmd_context *ctx); int nl_gfec(struct cmd_context *ctx); int nl_sfec(struct cmd_context *ctx); +int nl_cfecstats(struct cmd_context *ctx); bool nl_gstats_chk(struct cmd_context *ctx); int nl_gstats(struct cmd_context *ctx); int nl_gmodule(struct cmd_context *ctx);
@@ -124,6 +125,7 @@ nl_get_eeprom_page(struct cmd_context *ctx __maybe_unused, #define nl_gtunnels NULL #define nl_gfec NULL #define nl_sfec NULL +#define nl_cfecstats NULL #define nl_gstats_chk NULL #define nl_gstats NULL #define nl_getmodule NULL
diff --git a/netlink/fec.c b/netlink/fec.c
index c014749..60630d5 100644
--- a/netlink/fec.c
+++ b/netlink/fec.c@@ -438,3 +438,43 @@ int nl_sfec(struct cmd_context *ctx) else return nlctx->exit_code ?: 83; } + +/* FEC_STATS_CLEAR */ + +int nl_cfecstats(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + u32 flags = 0; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_FEC_SET, false)) + return -EOPNOTSUPP; + + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_FEC_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + + if (ethnla_fill_header(msgbuff, ETHTOOL_A_FEC_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + if (ethnla_put_u8(msgbuff, ETHTOOL_A_FEC_STATS_CLEAR, flags)) + return -EMSGSIZE; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 83; + + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 83; +}
diff --git a/uapi/linux/ethtool_netlink_generated.h b/uapi/linux/ethtool_netlink_generated.h
index 572c5f9..2e66531 100644
--- a/uapi/linux/ethtool_netlink_generated.h
+++ b/uapi/linux/ethtool_netlink_generated.h@@ -595,6 +595,7 @@ enum { ETHTOOL_A_FEC_AUTO, ETHTOOL_A_FEC_ACTIVE, ETHTOOL_A_FEC_STATS, + ETHTOOL_A_FEC_STATS_CLEAR, __ETHTOOL_A_FEC_CNT, ETHTOOL_A_FEC_MAX = (__ETHTOOL_A_FEC_CNT - 1)
--
2.43.0