From c3a11cf422c8edfe07146395c1084fdc45d44486 Mon Sep 17 00:00:00 2001
From: veega <zhuweijia@huawei.com>
Date: Wed, 26 Jul 2023 17:35:06 +0800
Subject: [PATCH] hikptool: add show CDR DFX info in nic_port cmd

If the port contains CDRs, the nic_port command displays the hardware information of the CDRs, which helps locate port link setup faults.

Signed-off-by: veega <zhuweijia@huawei.com>
---
 net/nic/nic_mac/hikp_mac_cmd.h  |  1 +
 net/nic/nic_mac/hikp_nic_port.c | 72 ++++++++++++++++++++++++++++++++-
 net/nic/nic_mac/hikp_nic_port.h | 49 +++++++++++++++++++---
 3 files changed, 116 insertions(+), 6 deletions(-)

diff --git a/net/nic/nic_mac/hikp_mac_cmd.h b/net/nic/nic_mac/hikp_mac_cmd.h
index 5f0450a..adaadf4 100644
--- a/net/nic/nic_mac/hikp_mac_cmd.h
+++ b/net/nic/nic_mac/hikp_mac_cmd.h
@@ -30,6 +30,7 @@ enum mac_port_sub_cmd {
 	QUERY_PORT_ADAPT_DFX,
 	QUERY_PORT_PHY_DFX,
 	QUERY_HOT_PLUG_CARD_DFX,
+	QUERY_PORT_CDR_DFX,
 };

 enum mac_dump_reg_sub_cmd {
diff --git a/net/nic/nic_mac/hikp_nic_port.c b/net/nic/nic_mac/hikp_nic_port.c
index 22a6467..c9f46fc 100644
--- a/net/nic/nic_mac/hikp_nic_port.c
+++ b/net/nic/nic_mac/hikp_nic_port.c
@@ -405,6 +405,73 @@ static void mac_cmd_show_hot_plug_card(struct major_cmd_ctrl *self)
 	free(cmd_ret);
 }

+static void mac_cmd_print_cdr_dfx(struct mac_cmd_cdr_dfx *cdr_dfx, struct mac_port_cdr_dfx *info)
+{
+	struct mac_item type_table[] = {
+		{PORT_CDR_TYPE_A, "cdr_a"}, {PORT_CDR_TYPE_B, "cdr_b"},
+	};
+	struct mac_item cdr_a_mode[] = {
+		{CDR_A_MODE_2PLL, "2pll"}, {CDR_A_MODE_FASTPI, "fastpi"},
+	};
+	struct mac_item cdr_b_mode[] = {
+		{CDR_B_MODE_PCS, "pcs"}, {CDR_B_MODE_CDR, "cdr"},
+	};
+	struct mac_item status_table[] = {
+		{CDR_STATUS_NORMAL, "normal"}, {CDR_STATUS_ERROR, "error"},
+	};
+	const char *type_str = mac_get_str(cdr_dfx->cdr_type,
+					   type_table, HIKP_ARRAY_SIZE(type_table), "unknown");
+	const char *mode_str = "NA";
+
+	for (uint32_t i = 0; i < cdr_dfx->cdr_num; i++) {
+		if (cdr_dfx->cdr_type == PORT_CDR_TYPE_A) {
+			mode_str = mac_get_str(info->dfx[i].cdr_mode, cdr_a_mode,
+					       HIKP_ARRAY_SIZE(cdr_a_mode), "unknown");
+		} else if (cdr_dfx->cdr_type == PORT_CDR_TYPE_B) {
+			mode_str = mac_get_str(info->dfx[i].cdr_mode, cdr_b_mode,
+					       HIKP_ARRAY_SIZE(cdr_b_mode), "unknown");
+		}
+		printf("\t|0x%-8x%-9u%-10s%-10s%-10s\n", info->dfx[i].cdr_addr,
+		       info->dfx[i].cdr_start_lane, type_str, mode_str,
+		       mac_get_str(info->dfx[i].cdr_err,
+				   status_table, HIKP_ARRAY_SIZE(status_table), "unknown"));
+	}
+}
+
+static void mac_cmd_disp_cdr_info(struct mac_cmd_cdr_dfx *cdr_dfx)
+{
+	if (!cdr_dfx->cdr_num)
+		return;
+
+	printf("\n======================== PORT CDR INFO =======================\n");
+	printf("direct\t|addr     |lane    |type     |mode     |status   \n");
+	printf("----------------------------------------------------------------------------\n");
+
+	printf("WIRE");
+	mac_cmd_print_cdr_dfx(cdr_dfx, &cdr_dfx->wire_cdr);
+
+	printf("HOST");
+	mac_cmd_print_cdr_dfx(cdr_dfx, &cdr_dfx->host_cdr);
+}
+
+static void mac_cmd_show_cdr(struct major_cmd_ctrl *self)
+{
+	struct mac_cmd_cdr_dfx *cdr_dfx = NULL;
+	struct hikp_cmd_ret *cmd_ret = NULL;
+	int ret;
+
+	ret = mac_cmd_get_dfx_cfg(QUERY_PORT_CDR_DFX, &cmd_ret);
+	if (ret != 0) {
+		self->err_no = -ENOSPC;
+		snprintf(self->err_str, sizeof(self->err_str), "mac get cdr dfx failed.");
+		return;
+	}
+
+	cdr_dfx = (struct mac_cmd_cdr_dfx *)(cmd_ret->rsp_data);
+	mac_cmd_disp_cdr_info(cdr_dfx);
+	free(cmd_ret);
+}
+
 static void mac_cmd_show_port_dfx(struct major_cmd_ctrl *self, uint32_t mask)
 {
 	struct mac_cmd_dfx_callback dfx_cb[] = {
@@ -413,6 +480,7 @@ static void mac_cmd_show_port_dfx(struct major_cmd_ctrl *self, uint32_t mask)
 		{MAC_LSPORT_PHY, mac_cmd_show_phy},
 		{MAC_LSPORT_ARB, mac_cmd_show_arb},
 		{MAC_HOT_PLUG_CARD, mac_cmd_show_hot_plug_card},
+		{MAC_LSPORT_CDR, mac_cmd_show_cdr}
 	};
 	size_t size = HIKP_ARRAY_SIZE(dfx_cb);
 	size_t i;
@@ -425,9 +493,9 @@ static void mac_cmd_show_port_dfx(struct major_cmd_ctrl *self, uint32_t mask)

 static void mac_cmd_port_execute(struct major_cmd_ctrl *self)
 {
-	uint32_t mask = MAC_LSPORT_LINK | MAC_LSPORT_MAC | MAC_LSPORT_ARB | MAC_HOT_PLUG_CARD;
 	struct mac_cmd_port_hardware *port_hw = NULL;
 	struct hikp_cmd_ret *hw_cmd_ret = NULL;
+	uint32_t mask;
 	int ret;

 	if (!g_port_info.port_flag) {
@@ -443,6 +511,8 @@ static void mac_cmd_port_execute(struct major_cmd_ctrl *self)
 		return;
 	}

+	mask = MAC_LSPORT_LINK | MAC_LSPORT_MAC |
+	       MAC_LSPORT_ARB | MAC_HOT_PLUG_CARD | MAC_LSPORT_CDR;
 	port_hw = (struct mac_cmd_port_hardware *)(hw_cmd_ret->rsp_data);
 	if (port_hw->port_type == HIKP_PORT_TYPE_PHY ||
 	    port_hw->port_type == HIKP_PORT_TYPE_PHY_SDS)
diff --git a/net/nic/nic_mac/hikp_nic_port.h b/net/nic/nic_mac/hikp_nic_port.h
index f6334d0..42ab3f9 100644
--- a/net/nic/nic_mac/hikp_nic_port.h
+++ b/net/nic/nic_mac/hikp_nic_port.h
@@ -16,11 +16,12 @@

 #include "hikp_net_lib.h"

-#define MAC_LSPORT_LINK     HI_BIT(0)
-#define MAC_LSPORT_MAC      HI_BIT(1)
-#define MAC_LSPORT_PHY      HI_BIT(2)
-#define MAC_LSPORT_ARB      HI_BIT(3)
-#define MAC_HOT_PLUG_CARD      HI_BIT(4)
+#define MAC_LSPORT_LINK		HI_BIT(0)
+#define MAC_LSPORT_MAC		HI_BIT(1)
+#define MAC_LSPORT_PHY		HI_BIT(2)
+#define MAC_LSPORT_ARB		HI_BIT(3)
+#define MAC_HOT_PLUG_CARD	HI_BIT(4)
+#define MAC_LSPORT_CDR		HI_BIT(5)

 enum {
 	PORT_CFG_NOT_SET = 0,
@@ -186,6 +187,44 @@ struct mac_cmd_phy_info {
 	struct mac_cmd_phy_dfx phy_dfx;
 };

+enum {
+	PORT_CDR_TYPE_A = 0,
+	PORT_CDR_TYPE_B,
+};
+
+enum {
+	CDR_A_MODE_2PLL = 0,
+	CDR_A_MODE_FASTPI,
+};
+
+enum {
+	CDR_B_MODE_PCS = 0,
+	CDR_B_MODE_CDR,
+};
+
+enum {
+	CDR_STATUS_NORMAL = 0,
+	CDR_STATUS_ERROR,
+};
+
+struct cdr_dfx_info {
+	uint8_t cdr_mode;
+	uint8_t cdr_addr;
+	uint8_t cdr_start_lane;
+	uint8_t cdr_err; /* 0:normal, 1:error */
+};
+
+struct mac_port_cdr_dfx {
+    struct cdr_dfx_info dfx[2]; /* one side reserved max 2 cdr */
+};
+
+struct mac_cmd_cdr_dfx {
+	uint8_t cdr_num;
+	uint8_t cdr_type;
+	struct mac_port_cdr_dfx wire_cdr;
+	struct mac_port_cdr_dfx host_cdr;
+};
+
 struct mac_cmd_dfx_callback {
 	uint32_t mask;
 	void (*show_dfx)(struct major_cmd_ctrl *self);
--
2.36.1.windows.1
