From 27b893b735d55221cda822d1ae7c44bb13836990 Mon Sep 17 00:00:00 2001
From: Maxime Bizon <mbizon@freebox.fr>
Date: Tue, 3 Dec 2019 23:24:46 +0100
Subject: [PATCH 3/4] ethtool: add command to show current epon params

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

diff --git a/ethtool.c b/ethtool.c
index 5c61f88..589c7e2 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -4922,6 +4922,66 @@ static int do_get_phy_tunable(struct cmd_context *ctx)
 	return 0;
 }
 
+static void dump_hex_string(uint8_t *bin,
+			    char *hex,
+			    size_t bin_count)
+{
+	static const char *chars = "0123456789abcdef";
+	size_t i;
+
+	for (i = 0; i < bin_count; i++) {
+		*hex++ = chars[bin[i] >> 4];
+		*hex++ = chars[bin[i] & 0xf];
+	}
+	*hex++ = 0;
+}
+
+static int do_show_epon_param(struct cmd_context *ctx)
+{
+	struct ethtool_epon_param eponcmd;
+	char keyhex[33];
+
+	if (ctx->argc != 0)
+		exit_bad_args();
+
+	eponcmd.cmd = ETHTOOL_GEPON_PARAM;
+
+	if (send_ioctl(ctx, &eponcmd) < 0) {
+		perror("cannot get epon params");
+		return 87;
+	}
+
+	fprintf(stdout, "EPON parameters for %s:\n", ctx->devname);
+	fprintf(stdout, "discovery received:   %s\n",
+		eponcmd.discovery_rx ? "yes" : "no");
+	fprintf(stdout, "registration count:   %u\n", eponcmd.change_count);
+	fprintf(stdout, "registered:           %s\n",
+		eponcmd.registered ? "yes" : "no");
+
+	if (!eponcmd.registered)
+		return 0;
+
+	fprintf(stdout, "llid:                 0x%04x\n", eponcmd.llid);
+	fprintf(stdout, "burst_cap:            %u\n", eponcmd.burst_cap);
+
+	fprintf(stdout, "rx decrypt:           %s\n",
+		eponcmd.down_encrypt ? "enabled" : "disabled");
+
+	dump_hex_string(eponcmd.key_sci, keyhex, sizeof (eponcmd.key_sci));
+	fprintf(stdout, "rx key SCI:           %s\n", keyhex);
+	dump_hex_string(eponcmd.down_key0, keyhex, sizeof (eponcmd.down_key0));
+	fprintf(stdout, "rx user key 0:        %s\n", keyhex);
+	dump_hex_string(eponcmd.down_key1, keyhex, sizeof (eponcmd.down_key1));
+	fprintf(stdout, "rx user key 1:        %s\n", keyhex);
+
+	fprintf(stdout, "last user rx frame:   %s\n",
+		eponcmd.down_last_rx_encrypted ? "encrypted" : "clear");
+	fprintf(stdout, "last user rx key id:  %u\n",
+		eponcmd.down_last_rx_key_id);
+
+	return 0;
+}
+
 static __u32 parse_reset(char *val, __u32 bitset, char *arg, __u32 *data)
 {
 	__u32 bitval = 0;
@@ -5408,6 +5466,7 @@ static const struct option {
 	{ "--show-fec", 1, do_gfec, "Show FEC settings"},
 	{ "--set-fec", 1, do_sfec, "Set FEC settings",
 	  "		[ encoding auto|off|rs|baser [...]]\n"},
+	{ "--show-epon-param", 1, do_show_epon_param, "Show EPON params"},
 	{ "-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.17.1

