hikptool/0093-hikptool-hccs-support-dump-hccs-info.patch
zhangyuyang a1e8d45430 hikptool: Add HCCS and SDMA modules along with log collection
The HCCS and SDMA modules and the log collection function are added.

Signed-off-by: zhangyuyang <zhangyuyang31@huawei.com>
(cherry picked from commit 73fe961568c3b5e4406a65a46e926f2f0623d585)
2025-03-18 17:06:56 +08:00

1033 lines
29 KiB
Diff

From 71cc63275102a8956afaf60f9183899cd7c4cc82 Mon Sep 17 00:00:00 2001
From: Jie Hai <haijie1@huawei.com>
Date: Tue, 17 Dec 2024 15:29:28 +0800
Subject: [PATCH] hikptool/hccs: support dump hccs info
1. support dump HCCS topology.
e.g. hikptool hccs -g topo
2. support dump HCCS port fixed attributes.
e.g. hikptool hccs -g fixed_attr -c <chip_id> \
-d <die_id> -p <port_id>
3. support dump HCCS port dfx information.
e.g. hikptool hccs -g dfx_info -c <chip_id> \
-d <die_id> -p <port_id>
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Jie Hai <haijie1@huawei.com>
---
CMakeLists.txt | 1 +
hccs/hikp_hccs.c | 807 ++++++++++++++++++++++++++++
hccs/hikp_hccs.h | 161 ++++++
libhikptdev/include/hikptdev_plug.h | 1 +
4 files changed, 970 insertions(+)
create mode 100644 hccs/hikp_hccs.c
create mode 100644 hccs/hikp_hccs.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 56cc932..72f2dab 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,6 +45,7 @@ file(GLOB_RECURSE HIKPTOOL_SRC
${CMAKE_CURRENT_SOURCE_DIR}/sata/*.c
${CMAKE_CURRENT_SOURCE_DIR}/serdes/*.c
${CMAKE_CURRENT_SOURCE_DIR}/socip/*.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hccs/*.c
${CMAKE_CURRENT_SOURCE_DIR}/tool_lib/*.c
${CMAKE_CURRENT_SOURCE_DIR}/info_collect/*.c
${CMAKE_CURRENT_SOURCE_DIR}/hikp_init_main.c
diff --git a/hccs/hikp_hccs.c b/hccs/hikp_hccs.c
new file mode 100644
index 0000000..5ef4222
--- /dev/null
+++ b/hccs/hikp_hccs.c
@@ -0,0 +1,807 @@
+/*
+ * Copyright (c) 2024-2025 Hisilicon Technologies Co., Ltd.
+ * Hikptool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ *
+ * See the Mulan PSL v2 for more details.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include "tool_cmd.h"
+#include "hikpt_rciep.h"
+#include "hikp_hccs.h"
+
+enum hccs_link_fsm {
+ HCCS_PORT_RESET = 1,
+ HCCS_PORT_SETUP,
+ HCCS_PORT_CONFIG,
+ HCCS_PORT_READY
+};
+
+const struct {
+ enum hccs_link_fsm link_fsm;
+ const char *str;
+} link_fsm_map[] = {
+ {HCCS_PORT_RESET, "reset"},
+ {HCCS_PORT_SETUP, "setup"},
+ {HCCS_PORT_CONFIG, "config"},
+ {HCCS_PORT_READY, "link-up"},
+};
+
+static struct hccs_param g_hccs_param = { 0 };
+static struct hikp_plat_hccs_info g_hccs_info = { 0 };
+
+static int hikp_hccs_get_plat_topo(struct hccs_param *param,
+ union hccs_feature_info *info);
+static void hikp_hccs_show_topo(union hccs_feature_info *data);
+static int hikp_hccs_get_port_attr(struct hccs_param *param,
+ union hccs_feature_info *info);
+static void hikp_hccs_show_port_attr(union hccs_feature_info *feature_info);
+static int hikp_hccs_get_port_dfx_info(struct hccs_param *param,
+ union hccs_feature_info *info);
+static void hikp_hccs_show_port_dfx_info(union hccs_feature_info *feature_info);
+static int hikp_plat_hccs_hw_info(struct hikp_plat_hccs_info *hccs_info);
+static int hikp_hccs_get_die_num(uint8_t chip_id, struct hikp_plat_hccs_info *hccs_info);
+
+static const struct hikp_hccs_feature_cmd g_hccs_feature_cmd[] = {
+ {"topo", HCCS_GET_PORT_IDS_ON_DIE, hikp_hccs_get_plat_topo,
+ hikp_hccs_show_topo, 0},
+ {"fixed_attr", HCCS_GET_PORT_FIXED_ATTR, hikp_hccs_get_port_attr,
+ hikp_hccs_show_port_attr, HCCS_PORT_INFO_MASK},
+ {"dfx_info", HCCS_GET_PORT_DFX_INFO, hikp_hccs_get_port_dfx_info,
+ hikp_hccs_show_port_dfx_info, HCCS_PORT_INFO_MASK},
+};
+
+static int hikp_hccs_cmd_help(struct major_cmd_ctrl *self, const char *argv)
+{
+ HIKP_SET_USED(argv);
+
+ printf("\n Usage: %s\n", self->cmd_ptr->name);
+ printf("\n %s\n", self->cmd_ptr->help_info);
+ printf("\n Options:\n\n");
+ printf(" %s, %-25s %s\n", "-h", "--help", "display this help and exit");
+ printf(" %s, %-25s %s\n", "-c", "--chip_id=<chip_id>", "target chip");
+ printf(" %s, %-25s %s\n", "-d", "--die_id=<die_id>", "target die");
+ printf(" %s, %-25s %s\n", "-p", "--port_id=<port_id>", "target port");
+ printf(" %s\n",
+ "[-g/--get <options>]\n"
+ " topo : get hccs_typo info, no target specified.\n"
+ " fixed_attr : get fixed attributes for port specified by -c X -d X -p X.\n"
+ " dfx_info : get dfx info for port specified by -c X -d X -p X.\n");
+ return 0;
+}
+
+static int hikp_hccs_cmd_send(struct hikp_cmd_header *req_header,
+ struct hikp_hccs_req *req_data,
+ void *buff, size_t buff_len,
+ struct hikp_hccs_rsp_head *rsp_head)
+{
+ struct hikp_cmd_ret *cmd_ret;
+ struct hikp_hccs_rsp *rsp;
+ uint64_t cur_blk_size;
+ int ret;
+
+ cmd_ret = hikp_cmd_alloc(req_header, req_data, sizeof(struct hikp_hccs_req));
+ ret = hikp_rsp_normal_check(cmd_ret);
+ if (ret != 0) {
+ HIKP_ERROR_PRINT("Failed to query from firmware! ret = %d.\n", ret);
+ goto out;
+ }
+
+ rsp = (struct hikp_hccs_rsp *)cmd_ret->rsp_data;
+ cur_blk_size = rsp->rsp_head.cur_blk_size;
+ if (cur_blk_size == 0) {
+ HIKP_ERROR_PRINT("Firmware reported zero data size!\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ if (cur_blk_size > buff_len ||
+ cur_blk_size > sizeof(struct hikp_hccs_rsp)) {
+ HIKP_ERROR_PRINT("The firmware data size (%" PRIu64 ") greater than "
+ "sw buffer(%zu) or hikp_hccs_rsp size(%zu).\n",
+ cur_blk_size, buff_len, sizeof(struct hikp_hccs_rsp));
+ ret = -EINVAL;
+ goto out;
+ }
+
+ memcpy(buff, rsp->rsp_data, rsp->rsp_head.cur_blk_size);
+ rsp_head->total_blk_num = rsp->rsp_head.total_blk_num;
+ rsp_head->cur_blk_size = rsp->rsp_head.cur_blk_size;
+
+out:
+ hikp_cmd_free(&cmd_ret);
+ return ret;
+}
+
+static int hikp_hccs_query(struct hikp_cmd_header *req_header,
+ struct hikp_hccs_req *req_data,
+ void *buff, size_t buff_len)
+{
+ struct hikp_hccs_rsp_head rsp_head = {0};
+ uint16_t total_blk_size = 0;
+ uint16_t total_blk_num;
+ uint16_t blk_id = 0;
+ int ret;
+
+ ret = hikp_hccs_cmd_send(req_header, req_data, buff, buff_len, &rsp_head);
+ if (ret != 0)
+ return ret;
+ total_blk_num = rsp_head.total_blk_num;
+ total_blk_size += rsp_head.cur_blk_size;
+ for (blk_id = 1; blk_id < total_blk_num; blk_id++) {
+ if (buff_len <= total_blk_size) {
+ HIKP_ERROR_PRINT("No enough buffer to get block-(%u) context.\n",
+ blk_id);
+ return -EINVAL;
+ }
+
+ req_data->head.blk_id = blk_id;
+ ret = hikp_hccs_cmd_send(req_header, req_data,
+ (uint8_t *)buff + total_blk_size,
+ buff_len - total_blk_size, &rsp_head);
+ if (ret != 0) {
+ HIKP_ERROR_PRINT("Failed to get context for block-(%u)!\n",
+ blk_id);
+ return -EINVAL;
+ }
+ total_blk_size += rsp_head.cur_blk_size;
+ }
+
+ return 0;
+}
+
+static int hikp_hccs_get_chip_num(struct hikp_plat_hccs_info *hccs_info)
+{
+ struct hccs_chip_num_rsp_data rsp_data = {0};
+ struct hikp_cmd_header req_header = {0};
+ struct hikp_hccs_req req = {0};
+ int ret;
+
+ hikp_cmd_init(&req_header, HCCS_MOD, HCCS_GET_CHIP_NUM, 0);
+ ret = hikp_hccs_query(&req_header, &req,
+ &rsp_data, sizeof(struct hccs_chip_num_rsp_data));
+ if (ret != 0) {
+ HIKP_ERROR_PRINT("Failed to get chip number from firmware, ret = %d!\n", ret);
+ return ret;
+ }
+
+ if (rsp_data.chip_num == 0) {
+ HIKP_ERROR_PRINT("The chip number obtained from firmware is zero!\n");
+ return -EINVAL;
+ }
+ hccs_info->chip_num = rsp_data.chip_num;
+
+ return 0;
+}
+
+static int hikp_hccs_get_die_num(uint8_t chip_id, struct hikp_plat_hccs_info *hccs_info)
+{
+ struct hccs_die_num_rsp_data rsp_data = {0};
+ struct hikp_cmd_header req_header = {0};
+ struct hccs_die_num_req_para *req_param;
+ struct hikp_hccs_req req = {0};
+ int ret;
+
+ hikp_cmd_init(&req_header, HCCS_MOD, HCCS_GET_DIE_NUM, 0);
+ req_param = (struct hccs_die_num_req_para *)&req.req_data;
+ req_param->chip_id = chip_id;
+ ret = hikp_hccs_query(&req_header, &req,
+ &rsp_data, sizeof(struct hccs_die_num_rsp_data));
+ if (ret != 0) {
+ HIKP_ERROR_PRINT("Failed to get die number from firmware, ret = %d!\n", ret);
+ return ret;
+ }
+
+ hccs_info->chip_info[chip_id].die_num = rsp_data.die_num;
+ return 0;
+}
+
+static int hikp_hccs_get_die_info(struct hccs_die_info *die_info,
+ uint8_t chip_id, uint8_t die_idx)
+{
+ struct hccs_die_info_rsp_data rsp_data = {0};
+ struct hccs_die_info_req_para *req_param;
+ struct hikp_cmd_header req_header = {0};
+ struct hikp_hccs_req req = {0};
+ int ret;
+
+ hikp_cmd_init(&req_header, HCCS_MOD, HCCS_GET_DIE_INFO, 0);
+ req_param = (struct hccs_die_info_req_para *)&req.req_data;
+ req_param->chip_id = chip_id;
+ req_param->die_idx = die_idx;
+ ret = hikp_hccs_query(&req_header, &req,
+ &rsp_data, sizeof(struct hccs_die_info_rsp_data));
+ if (ret != 0) {
+ HIKP_ERROR_PRINT("Fail to get die information from firmware, ret = %d!\n", ret);
+ return ret;
+ }
+
+ die_info->die_id = rsp_data.die_id;
+ die_info->port_num = rsp_data.port_num;
+ return 0;
+}
+
+static int hikp_hccs_get_all_die_info(struct hikp_plat_hccs_info *hccs_info)
+{
+ uint8_t chip_id, die_idx, die_num;
+ struct hccs_chip_info *chip_info;
+ struct hccs_die_info *die_info;
+ bool has_die = false;
+ int ret;
+
+ for (chip_id = 0; chip_id < hccs_info->chip_num; chip_id++) {
+ chip_info = &hccs_info->chip_info[chip_id];
+ die_num = chip_info->die_num;
+ if (die_num == 0)
+ continue;
+
+ has_die = true;
+ die_info = (struct hccs_die_info *)calloc(die_num, sizeof(struct hccs_die_info));
+ if (die_info == NULL) {
+ HIKP_ERROR_PRINT("Failed to allocate memory for die information!\n");
+ return -ENOMEM;
+ }
+ chip_info->die_info = die_info;
+ for (die_idx = 0; die_idx < die_num; die_idx++, die_info++) {
+ ret = hikp_hccs_get_die_info(die_info, chip_id, die_idx);
+ if (ret < 0) {
+ HIKP_ERROR_PRINT("Failed to get die information for die idx %u!\n",
+ die_idx);
+ return ret;
+ }
+ }
+ }
+
+ return has_die ? 0 : -EINVAL;
+}
+
+static int hikp_hccs_get_ports_on_die(uint8_t *port_ids, uint16_t port_num,
+ uint8_t chip_id, uint8_t die_id)
+{
+ struct hccs_die_ports_req_para *req_param;
+ struct hikp_cmd_header req_header = {0};
+ struct hikp_hccs_req req = {0};
+ int ret;
+
+ hikp_cmd_init(&req_header, HCCS_MOD, HCCS_GET_PORT_IDS_ON_DIE, 0);
+ req_param = (struct hccs_die_ports_req_para *)&req.req_data;
+ req_param->chip_id = chip_id;
+ req_param->die_id = die_id;
+ ret = hikp_hccs_query(&req_header, &req,
+ port_ids, sizeof(uint8_t) * port_num);
+ if (ret != 0) {
+ HIKP_ERROR_PRINT("Fail to get port ids from firmware, ret = %d!\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int hikp_hccs_get_all_port_info(struct hikp_plat_hccs_info *hccs_info)
+{
+ struct hccs_chip_info *chip_info;
+ struct hccs_die_info *die_info;
+ struct hccs_die_info *dies;
+ uint8_t chip_id, die_idx;
+ bool has_port = false;
+ int ret;
+
+ for (chip_id = 0; chip_id < hccs_info->chip_num; chip_id++) {
+ chip_info = &hccs_info->chip_info[chip_id];
+ dies = chip_info->die_info;
+ has_port = false;
+ for (die_idx = 0; die_idx < chip_info->die_num; die_idx++) {
+ die_info = &dies[die_idx];
+ if (die_info->port_num == 0)
+ continue;
+
+ has_port = true;
+ die_info->port_ids = (uint8_t *)calloc(die_info->port_num,
+ sizeof(uint8_t));
+ if (die_info->port_ids == NULL)
+ return -ENOMEM;
+
+ ret = hikp_hccs_get_ports_on_die(die_info->port_ids, die_info->port_num,
+ chip_id, die_info->die_id);
+ if (ret < 0) {
+ HIKP_ERROR_PRINT("Failed to get port ids for "
+ "chip (%u) die idx (%u)!\n",
+ chip_id, die_idx);
+ return ret;
+ }
+ }
+ }
+
+ return has_port ? 0 : -EINVAL;
+}
+
+static int hikp_hccs_get_chip_info(struct hikp_plat_hccs_info *hccs_info)
+{
+ uint8_t chip_id;
+ int ret;
+
+ ret = hikp_hccs_get_chip_num(hccs_info);
+ if (ret < 0) {
+ HIKP_ERROR_PRINT("Failed to get chip num!\n");
+ return ret;
+ }
+
+ hccs_info->chip_info = (struct hccs_chip_info *)calloc(hccs_info->chip_num,
+ sizeof(struct hccs_chip_info));
+ if (hccs_info->chip_info == NULL) {
+ HIKP_ERROR_PRINT("Failed to allocate memory for chip info!\n");
+ return -ENOMEM;
+ }
+
+ for (chip_id = 0; chip_id < hccs_info->chip_num; chip_id++) {
+ ret = hikp_hccs_get_die_num(chip_id, hccs_info);
+ if (ret < 0) {
+ HIKP_ERROR_PRINT("Failed to get die num!\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int hikp_plat_hccs_hw_info(struct hikp_plat_hccs_info *hccs_info)
+{
+ int ret;
+
+ ret = hikp_hccs_get_chip_info(hccs_info);
+ if (ret != 0) {
+ HIKP_ERROR_PRINT("Failed to get chip info, ret = %d!\n", ret);
+ return ret;
+ }
+
+ ret = hikp_hccs_get_all_die_info(hccs_info);
+ if (ret != 0) {
+ HIKP_ERROR_PRINT("Failed to get all die info, ret = %d!\n", ret);
+ return ret;
+ }
+
+ ret = hikp_hccs_get_all_port_info(hccs_info);
+ if (ret != 0) {
+ HIKP_ERROR_PRINT("Failed to get all port info, ret = %d!\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int hikp_hccs_get_plat_topo(struct hccs_param *param,
+ union hccs_feature_info *info)
+{
+ int ret;
+
+ HIKP_SET_USED(param);
+ HIKP_SET_USED(info);
+
+ ret = hikp_plat_hccs_hw_info(&g_hccs_info);
+ if (ret < 0) {
+ HIKP_ERROR_PRINT("Failed to get HCCS hardware info, ret = %d!\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static void hikp_plat_hccs_free(struct hikp_plat_hccs_info *hccs_info)
+{
+ struct hccs_chip_info *chip_info;
+ struct hccs_die_info *die_info;
+ uint8_t chip_id, die_idx;
+
+ if (hccs_info->chip_info == NULL)
+ return;
+
+ for (chip_id = 0; chip_id < hccs_info->chip_num; chip_id++) {
+ chip_info = &hccs_info->chip_info[chip_id];
+ die_info = chip_info->die_info;
+ if (die_info == NULL)
+ continue;
+
+ for (die_idx = 0; die_idx < chip_info->die_num; die_idx++) {
+ if (die_info[die_idx].port_ids == NULL)
+ continue;
+ free(die_info[die_idx].port_ids);
+ die_info[die_idx].port_ids = NULL;
+ }
+ free(die_info);
+ chip_info->die_info = NULL;
+ }
+ free(hccs_info->chip_info);
+ hccs_info->chip_info = NULL;
+}
+
+static bool hikp_hccs_die_id_valid(struct hikp_plat_hccs_info *hccs_info,
+ struct hccs_param *param, uint8_t *die_idx)
+{
+ struct hccs_chip_info *chip_info;
+ struct hccs_die_info *die_info;
+ uint8_t idx;
+
+ chip_info = &hccs_info->chip_info[param->chip_id];
+ die_info = chip_info->die_info;
+ for (idx = 0; idx < chip_info->die_num; idx++) {
+ if (param->die_id != die_info[idx].die_id)
+ continue;
+ *die_idx = idx;
+ return true;
+ }
+ return false;
+}
+
+static bool hikp_hccs_port_id_valid(struct hikp_plat_hccs_info *hccs_info,
+ struct hccs_param *param, uint8_t die_idx)
+{
+ struct hccs_chip_info *chip_info;
+ struct hccs_die_info *die_info;
+ uint8_t port_id, *port_ids;
+
+ chip_info = &hccs_info->chip_info[param->chip_id];
+ die_info = &chip_info->die_info[die_idx];
+ port_ids = die_info->port_ids;
+
+ for (port_id = 0; port_id < die_info->port_num; port_id++) {
+ if (param->port_id == port_ids[port_id])
+ return true;
+ }
+
+ return false;
+}
+
+static bool hikp_hccs_req_param_check(struct hikp_plat_hccs_info *hccs_info,
+ struct hccs_param *param)
+{
+ uint8_t die_idx;
+
+ if (param->chip_id >= hccs_info->chip_num) {
+ HIKP_ERROR_PRINT("param error: chip id %u exceed chip number %u!\n",
+ param->chip_id, hccs_info->chip_num);
+ return false;
+ }
+
+ if (!hikp_hccs_die_id_valid(hccs_info, param, &die_idx)) {
+ HIKP_ERROR_PRINT("Param error: die%u not found on chip%u!\n",
+ param->die_id, param->chip_id);
+ return false;
+ }
+
+ if (!hikp_hccs_port_id_valid(hccs_info, param, die_idx)) {
+ HIKP_ERROR_PRINT("Param error: port id %u not found on chip%u die%u!\n",
+ param->port_id, param->chip_id, param->die_id);
+ return false;
+ }
+
+ return true;
+}
+
+static int hikp_hccs_get_port_attr(struct hccs_param *param,
+ union hccs_feature_info *info)
+{
+ struct hccs_port_attr_req_para *req_para;
+ struct hikp_cmd_header req_header = {0};
+ struct hikp_hccs_req req = {0};
+ int ret;
+
+ ret = hikp_plat_hccs_hw_info(&g_hccs_info);
+ if (ret != 0) {
+ HIKP_ERROR_PRINT("Failed to get HCCS hardware info for "
+ "port attributes, ret = %d.\n", ret);
+ return ret;
+ }
+
+ if (!hikp_hccs_req_param_check(&g_hccs_info, param))
+ return -EINVAL;
+
+ hikp_cmd_init(&req_header, HCCS_MOD, HCCS_GET_PORT_FIXED_ATTR, 0);
+ req_para = (struct hccs_port_attr_req_para *)&req.req_data;
+ req_para->chip_id = param->chip_id;
+ req_para->die_id = param->die_id;
+ req_para->port_id = param->port_id;
+ ret = hikp_hccs_query(&req_header, &req,
+ info, sizeof(union hccs_feature_info));
+ if (ret != 0)
+ return ret;
+ return 0;
+}
+
+static int hikp_hccs_get_port_dfx_info(struct hccs_param *param,
+ union hccs_feature_info *info)
+{
+ struct hikp_hccs_rsp_head rsp_head = {0};
+ struct hikp_cmd_header req_header = {0};
+ struct hccs_port_dfx_info_vld *dfx_info;
+ struct hccs_port_dfx_req_para *dfx_req;
+ struct hikp_hccs_req req = {0};
+ int ret;
+
+ ret = hikp_plat_hccs_hw_info(&g_hccs_info);
+ if (ret != 0) {
+ HIKP_ERROR_PRINT("Failed to get HCCS hardware info for dfx info, ret = %d\n",
+ ret);
+ return ret;
+ }
+
+ if (!hikp_hccs_req_param_check(&g_hccs_info, param))
+ return -EINVAL;
+
+ dfx_info = &info->dfx_info;
+ dfx_req = (struct hccs_port_dfx_req_para *)&req.req_data;
+ dfx_req->chip_id = param->chip_id;
+ dfx_req->port_id = param->port_id;
+ dfx_req->die_id = param->die_id;
+ hikp_cmd_init(&req_header, HCCS_MOD, HCCS_GET_PORT_DFX_INFO, 0);
+ ret = hikp_hccs_cmd_send(&req_header, &req,
+ &dfx_info->info,
+ sizeof(struct hccs_port_dfx_info),
+ &rsp_head);
+ if (ret != 0)
+ return ret;
+
+ dfx_info->vld_size = rsp_head.cur_blk_size;
+
+ return 0;
+}
+
+static void hikp_hccs_show_topo(union hccs_feature_info *data)
+{
+ uint8_t chip_id, die_idx, die_num, port_idx, *port_ids;
+ struct hccs_die_info *die_info;
+ struct hccs_die_info *dies;
+
+ HIKP_SET_USED(data);
+
+ for (chip_id = 0; chip_id < g_hccs_info.chip_num; chip_id++) {
+ die_num = g_hccs_info.chip_info[chip_id].die_num;
+ dies = g_hccs_info.chip_info[chip_id].die_info;
+ printf("--chip%u\n", chip_id);
+ if (die_num == 0)
+ continue;
+ for (die_idx = 0; die_idx < die_num; die_idx++) {
+ die_info = &dies[die_idx];
+ printf("\t--die%u\n", die_info->die_id);
+ port_ids = die_info->port_ids;
+ if (die_info->port_num == 0)
+ continue;
+
+ for (port_idx = 0; port_idx < die_info->port_num; port_idx++)
+ printf("\t\t--hccs%u\n", port_ids[port_idx]);
+ }
+ }
+}
+
+static void hikp_hccs_show_port_attr(union hccs_feature_info *feature_info)
+{
+ struct hccs_port_fixed_attr *info = &feature_info->attr;
+
+ printf("%-16s\tHCCS-V%u\n"
+ "%-16s\tx%u\n"
+ "%-16s\t%uMbps\n"
+ "%-16s\t%u\n",
+ "hccs_type", info->hccs_type,
+ "lane_mode", info->lane_mode,
+ "speed", info->speed,
+ "enabled", info->enabled);
+}
+
+static const char *hikp_hccs_link_fsm_to_str(uint8_t link_fsm)
+{
+ size_t i;
+
+ for (i = 0; i < sizeof(link_fsm_map) / sizeof(link_fsm_map[0]); i++) {
+ if (link_fsm_map[i].link_fsm == link_fsm)
+ return link_fsm_map[i].str;
+ }
+
+ return "unknown";
+}
+
+static void hikp_hccs_show_port_dfx_info(union hccs_feature_info *feature_info)
+{
+ struct hccs_port_dfx_info_vld *info_vld = &feature_info->dfx_info;
+ struct hccs_port_dfx_info *info = &info_vld->info;
+ size_t vld_size;
+
+ vld_size = (size_t)info_vld->vld_size;
+ if (vld_size >= sizeof(info->link_fsm)) {
+ printf("%-16s\t%s\n", "link_fsm", hikp_hccs_link_fsm_to_str(info->link_fsm));
+ vld_size -= sizeof(info->link_fsm);
+ }
+
+ if (vld_size >= sizeof(info->cur_lane_num)) {
+ printf("%-16s\t%u\n", "cur_lane_num", info->cur_lane_num);
+ vld_size -= sizeof(info->cur_lane_num);
+ }
+
+ if (vld_size >= sizeof(info->lane_mask)) {
+ printf("%-16s\t0x%x\n", "lane_mask", info->lane_mask);
+ vld_size -= sizeof(info->lane_mask);
+ }
+
+ if (vld_size >= sizeof(info->crc_err_cnt)) {
+ printf("%-16s\t%u\n", "crc_err_cnt", info->crc_err_cnt);
+ vld_size -= sizeof(info->crc_err_cnt);
+ }
+
+ if (vld_size >= sizeof(info->retry_cnt)) {
+ printf("%-16s\t%u\n", "retry_cnt", info->retry_cnt);
+ vld_size -= sizeof(info->retry_cnt);
+ }
+
+ if (vld_size >= sizeof(info->phy_reinit_cnt)) {
+ printf("%-16s\t%u\n", "phy_reinit_cnt", info->phy_reinit_cnt);
+ vld_size -= sizeof(info->phy_reinit_cnt);
+ }
+
+ if (vld_size >= sizeof(info->tx_credit)) {
+ printf("%-16s\t%u\n", "tx_credit", info->tx_credit);
+ vld_size -= sizeof(info->tx_credit);
+ }
+}
+
+static void hikp_hccs_cmd_execute(struct major_cmd_ctrl *self)
+{
+ const struct hikp_hccs_feature_cmd *hccs_cmd;
+ union hccs_feature_info info = {0};
+ int ret;
+
+ if (g_hccs_param.feature_idx == -1) {
+ hikp_hccs_cmd_help(self, NULL);
+ snprintf(self->err_str, sizeof(self->err_str), "-g/--get param error!");
+ self->err_no = -EINVAL;
+ return;
+ }
+
+ hccs_cmd = &g_hccs_feature_cmd[g_hccs_param.feature_idx];
+ if (g_hccs_param.param_mask != hccs_cmd->param_needed) {
+ hikp_hccs_cmd_help(self, NULL);
+ snprintf(self->err_str, sizeof(self->err_str), "Parameter mismatched!");
+ self->err_no = -EINVAL;
+ return;
+ }
+
+ ret = hikp_hccs_get_chip_num(&g_hccs_info);
+ if (ret < 0) {
+ self->err_no = ret;
+ return;
+ }
+
+ if (g_hccs_info.chip_num == 1) {
+ snprintf(self->err_str, sizeof(self->err_str),
+ "The command is just supported on multi-sockets!\n");
+ self->err_no = -EINVAL;
+ return;
+ }
+
+ ret = hccs_cmd->query(&g_hccs_param, &info);
+ if (ret != 0) {
+ snprintf(self->err_str, sizeof(self->err_str), "Failed to query %s, ret = %d.",
+ hccs_cmd->feature_name, ret);
+ self->err_no = ret;
+ hikp_plat_hccs_free(&g_hccs_info);
+ return;
+ }
+
+ printf("############## HCCS: %s info ############\n", hccs_cmd->feature_name);
+ hccs_cmd->show(&info);
+ printf("#################### END #######################\n");
+
+ hikp_plat_hccs_free(&g_hccs_info);
+}
+
+static int hikp_hccs_cmd_feature_select(struct major_cmd_ctrl *self, const char *argv)
+{
+ size_t feat_size = HIKP_ARRAY_SIZE(g_hccs_feature_cmd);
+ size_t i;
+
+ for (i = 0; i < feat_size; i++) {
+ if (strcmp(argv, g_hccs_feature_cmd[i].feature_name) == 0) {
+ g_hccs_param.feature_idx = i;
+ return 0;
+ }
+ }
+
+ hikp_hccs_cmd_help(self, NULL);
+ snprintf(self->err_str, sizeof(self->err_str), "-g/--get param error!!!");
+ self->err_no = -EINVAL;
+
+ return self->err_no;
+}
+
+static int hikp_hccs_cmd_parse_chip(struct major_cmd_ctrl *self, const char *argv)
+{
+ uint32_t chip_id;
+
+ self->err_no = string_toui(argv, &chip_id);
+ if (self->err_no) {
+ snprintf(self->err_str, sizeof(self->err_str),
+ "Failed to parse -c/--chip_id parameter.");
+ return self->err_no;
+ }
+ if (chip_id > UINT8_MAX) {
+ snprintf(self->err_str, sizeof(self->err_str),
+ "chip id should not be greater than %u.", UINT8_MAX);
+ self->err_no = -EINVAL;
+ return self->err_no;
+ }
+
+ g_hccs_param.param_mask |= HCCS_ENABLE_CHIP_ID;
+ g_hccs_param.chip_id = (uint8_t)chip_id;
+
+ return 0;
+}
+
+static int hikp_hccs_cmd_parse_die(struct major_cmd_ctrl *self, const char *argv)
+{
+ uint32_t die_id;
+
+ self->err_no = string_toui(argv, &die_id);
+ if (self->err_no) {
+ snprintf(self->err_str, sizeof(self->err_str),
+ "Failed to parse -d/--die_id parameter.");
+ return self->err_no;
+ }
+
+ if (die_id > UINT8_MAX) {
+ snprintf(self->err_str, sizeof(self->err_str),
+ "die id should not be greater than %u.", UINT8_MAX);
+ self->err_no = -EINVAL;
+ return self->err_no;
+ }
+
+ g_hccs_param.param_mask |= HCCS_ENABLE_DIE_ID;
+ g_hccs_param.die_id = (uint8_t)die_id;
+
+ return 0;
+}
+
+static int hikp_hccs_cmd_parse_port(struct major_cmd_ctrl *self, const char *argv)
+{
+ uint32_t port_id;
+
+ self->err_no = string_toui(argv, &port_id);
+ if (self->err_no) {
+ snprintf(self->err_str, sizeof(self->err_str),
+ "Failed to parse -p/--port_id parameter.");
+ return self->err_no;
+ }
+
+ if (port_id > UINT8_MAX) {
+ snprintf(self->err_str, sizeof(self->err_str),
+ "port id should not be greater %u.", UINT8_MAX);
+ self->err_no = -EINVAL;
+ return self->err_no;
+ }
+
+ g_hccs_param.param_mask |= HCCS_ENABLE_PORT_ID;
+ g_hccs_param.port_id = (uint8_t)port_id;
+ return 0;
+}
+
+static void hikp_hccs_cmd_init(void)
+{
+ struct major_cmd_ctrl *major_cmd = get_major_cmd();
+
+ g_hccs_param.feature_idx = -1;
+
+ major_cmd->option_count = 0;
+ major_cmd->execute = hikp_hccs_cmd_execute;
+
+ cmd_option_register("-h", "--help", false, hikp_hccs_cmd_help);
+ cmd_option_register("-g", "--get", true, hikp_hccs_cmd_feature_select);
+ cmd_option_register("-c", "--chip_id", true, hikp_hccs_cmd_parse_chip);
+ cmd_option_register("-d", "--die_id", true, hikp_hccs_cmd_parse_die);
+ cmd_option_register("-p", "--port_id", true, hikp_hccs_cmd_parse_port);
+}
+
+HIKP_CMD_DECLARE("hccs", "dump HCCS information.", hikp_hccs_cmd_init);
diff --git a/hccs/hikp_hccs.h b/hccs/hikp_hccs.h
new file mode 100644
index 0000000..8ccc01a
--- /dev/null
+++ b/hccs/hikp_hccs.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2024-2025 Hisilicon Technologies Co., Ltd.
+ * Hikptool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ *
+ * See the Mulan PSL v2 for more details.
+ */
+
+#ifndef HIKP_HCCS_H
+#define HIKP_HCCS_H
+
+#include <stdint.h>
+
+enum hikp_hccs_cmd_type {
+ HCCS_GET_CHIP_NUM = 0,
+ HCCS_GET_DIE_NUM,
+ HCCS_GET_DIE_INFO,
+ HCCS_GET_PORT_IDS_ON_DIE,
+ HCCS_GET_PORT_FIXED_ATTR,
+ HCCS_GET_PORT_DFX_INFO,
+};
+
+struct hccs_die_info {
+ uint8_t die_id;
+ uint16_t port_num;
+ uint8_t *port_ids;
+};
+
+struct hccs_chip_info {
+ uint8_t chip_id;
+ uint8_t die_num;
+ struct hccs_die_info *die_info;
+};
+
+struct hccs_port_fixed_attr {
+ uint8_t hccs_type; /* HCCS_V1, HCCS_V2 and etc. */
+ uint8_t lane_mode;
+ uint16_t speed; /* Unit Mbps. */
+ uint8_t enabled; /* Indicate if port is enabled. */
+ uint8_t rsv[3];
+};
+
+struct hccs_port_dfx_info {
+ uint8_t link_fsm;
+ uint8_t cur_lane_num;
+ uint16_t lane_mask;
+ uint32_t crc_err_cnt;
+ uint32_t retry_cnt;
+ uint32_t phy_reinit_cnt;
+ uint32_t tx_credit;
+ uint32_t rsv1[54];
+};
+
+struct hccs_port_dfx_info_vld {
+ struct hccs_port_dfx_info info;
+ uint8_t vld_size; /* Indicate the valid bytes firmware reported. */
+};
+
+union hccs_feature_info {
+ struct hccs_port_fixed_attr attr;
+ struct hccs_port_dfx_info_vld dfx_info;
+};
+
+struct hccs_chip_num_rsp_data {
+ uint8_t chip_num;
+};
+
+struct hccs_die_num_req_para {
+ uint8_t chip_id;
+};
+
+struct hccs_die_num_rsp_data {
+ uint8_t die_num;
+};
+
+struct hccs_die_info_req_para {
+ uint8_t chip_id;
+ uint8_t die_idx;
+};
+
+struct hccs_die_info_rsp_data {
+ uint8_t die_id;
+ uint8_t rsv;
+ uint16_t port_num;
+};
+
+struct hccs_die_ports_req_para {
+ uint8_t chip_id;
+ uint8_t die_id;
+};
+
+struct hccs_port_attr_req_para {
+ uint8_t chip_id;
+ uint8_t die_id;
+ uint8_t port_id;
+};
+
+struct hccs_port_dfx_req_para {
+ uint8_t chip_id;
+ uint8_t die_id;
+ uint8_t port_id;
+};
+
+struct hikp_hccs_rsp_head {
+ uint16_t total_blk_num;
+ uint8_t cur_blk_size; /* real data size, not contain header size. */
+ uint8_t rsv;
+};
+
+#define HCCS_MAX_RSP_DATA 59
+struct hikp_hccs_rsp {
+ struct hikp_hccs_rsp_head rsp_head; /* 4 Byte */
+ uint32_t rsp_data[HCCS_MAX_RSP_DATA];
+};
+
+struct hikp_hccs_req_head {
+ uint16_t blk_id;
+ uint16_t rsv;
+};
+
+#define HCCS_MAX_REQ_DATA 31
+struct hikp_hccs_req {
+ struct hikp_hccs_req_head head; /* 4 Byte */
+ uint32_t req_data[HCCS_MAX_REQ_DATA];
+};
+
+#define HCCS_ENABLE_CHIP_ID HI_BIT(0)
+#define HCCS_ENABLE_DIE_ID HI_BIT(1)
+#define HCCS_ENABLE_PORT_ID HI_BIT(2)
+#define HCCS_PORT_INFO_MASK (HCCS_ENABLE_CHIP_ID | HCCS_ENABLE_DIE_ID | \
+ HCCS_ENABLE_PORT_ID)
+
+struct hccs_param {
+ int feature_idx;
+ uint8_t chip_id;
+ uint8_t die_id;
+ uint32_t port_id;
+ /* mask for param passed by user, see HCCS_ENABLE_XXX. */
+ uint16_t param_mask;
+};
+
+struct hikp_plat_hccs_info {
+ uint8_t chip_num;
+ struct hccs_chip_info *chip_info;
+};
+
+#define HIKP_HCCS_FEATURE_NAME_LEN 20
+struct hikp_hccs_feature_cmd {
+ const char feature_name[HIKP_HCCS_FEATURE_NAME_LEN];
+ uint32_t cmd_code;
+ int (*query)(struct hccs_param *param, union hccs_feature_info *info);
+ void (*show)(union hccs_feature_info *data);
+ uint16_t param_needed;
+};
+
+#endif /* HIKP_HCCS_H */
diff --git a/libhikptdev/include/hikptdev_plug.h b/libhikptdev/include/hikptdev_plug.h
index 2123935..d45a654 100644
--- a/libhikptdev/include/hikptdev_plug.h
+++ b/libhikptdev/include/hikptdev_plug.h
@@ -44,6 +44,7 @@ enum cmd_module_type {
DPDK_MOD = 9,
CXL_MOD = 10,
UB_MOD = 11,
+ HCCS_MOD = 16
};
void hikp_unlock(void);
--
2.45.0.windows.1