From f5cf15d5ada2b85df94aead46868fac392e933a0 Mon Sep 17 00:00:00 2001
From: Maxime Bizon <mbizon@freebox.fr>
Date: Tue, 20 Sep 2022 10:19:52 +0200
Subject: [PATCH 5/6] ethtool: add --show-sfp-state command

---
 ethtool.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/ethtool.c b/ethtool.c
index a714b16..480b4f5 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -5312,6 +5312,51 @@ static int do_get_shaper_params(struct cmd_context *ctx)
 	return 0;
 }
 
+static const char *sfp_fsm_state_str[] = {
+        [ETHTOOL_SFP_S_DOWN] = "down",
+        [ETHTOOL_SFP_S_FAIL] = "fail",
+        [ETHTOOL_SFP_S_WAIT] = "wait",
+        [ETHTOOL_SFP_S_INIT] = "init",
+        [ETHTOOL_SFP_S_INIT_PHY] = "init_phy",
+        [ETHTOOL_SFP_S_INIT_TX_FAULT] = "init_tx_fault",
+        [ETHTOOL_SFP_S_WAIT_LOS] = "wait_los",
+        [ETHTOOL_SFP_S_LINK_UP] = "link_up",
+        [ETHTOOL_SFP_S_TX_FAULT] = "tx_fault",
+        [ETHTOOL_SFP_S_REINIT] = "reinit",
+        [ETHTOOL_SFP_S_TX_DISABLE] = "tx_disable",
+};
+
+static int do_show_sfp_state(struct cmd_context *ctx)
+{
+	struct ethtool_sfp_state sfpcmd;
+	const char *state;
+
+	if (ctx->argc != 0)
+		exit_bad_args();
+
+	sfpcmd.cmd = ETHTOOL_GSFP_STATE;
+
+	if (send_ioctl(ctx, &sfpcmd) < 0) {
+		perror("cannot get epon params");
+		return 87;
+	}
+
+	fprintf(stdout, "SFP %s state:\n", ctx->devname);
+
+	if (sfpcmd.fsm_state >= ARRAY_SIZE(sfp_fsm_state_str))
+		state = "unknown";
+	else
+		state = sfp_fsm_state_str[sfpcmd.fsm_state];
+	fprintf(stdout, "FSM state:     %s\n", state);
+	fprintf(stdout, "presence:      %d\n", sfpcmd.i_presence);
+	fprintf(stdout, "rxlos:         %d\n", sfpcmd.i_rxlos);
+	fprintf(stdout, "pwren:         %d\n", sfpcmd.o_pwren);
+	fprintf(stdout, "txdis:         %d\n", sfpcmd.o_txdis);
+	fprintf(stdout, "txfault:       %d\n", sfpcmd.i_txfault);
+
+	return 0;
+}
+
 static int do_perqueue(struct cmd_context *ctx);
 
 #ifndef TEST_ETHTOOL
@@ -5514,6 +5559,7 @@ static const struct option {
 	{ "--show-epon-param", 1, do_show_epon_param, "Show EPON params"},
 	{ "--set-tx-shaper-param", 1, do_set_shaper_params, "Set HW TX shaper params" },
 	{ "--get-tx-shaper-param", 1, do_get_shaper_params, "Get HW TX shaper params" },
+	{ "--show-sfp-state", 1, do_show_sfp_state, "Show SFP kernel state"},
 	{ "-Q|--per-queue", 1, do_perqueue, "Apply per-queue command."
 	  "The supported sub commands include --show-coalesce, --coalesce",
 	  "             [queue_mask %x] SUB_COMMAND\n"},
-- 
2.34.1

