From 6b3b919054909ca3d7bdfb1c9c2fe48c098ff1cb Mon Sep 17 00:00:00 2001 From: Xiongchuan Zhou Date: Wed, 29 Oct 2025 16:39:38 +0800 Subject: [PATCH 1/5] ub: ubase: support debugfs for active dev stats. drivers inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/ID41MP CVE: NA ------------------------------------------------------------ This commit is used to support debugfs for active dev stats. Current commit uses debugfs to collect statistics on the number of times that the rx stream stop and resume interfaces are invoked. In addition, the latest 10 statistics can be queried. Signed-off-by: Xiaobo Zhang Signed-off-by: Xiongchuan Zhou --- drivers/ub/ubase/debugfs/ubase_debugfs.c | 57 ++++++++++++++++++++++++ drivers/ub/ubase/ubase_dev.c | 10 ++++- drivers/ub/ubase/ubase_stats.c | 22 +++++++++ drivers/ub/ubase/ubase_stats.h | 3 ++ 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/drivers/ub/ubase/debugfs/ubase_debugfs.c b/drivers/ub/ubase/debugfs/ubase_debugfs.c index d7495d8b4ef7..ef0b162e1188 100644 --- a/drivers/ub/ubase/debugfs/ubase_debugfs.c +++ b/drivers/ub/ubase/debugfs/ubase_debugfs.c @@ -30,6 +30,55 @@ static int ubase_dbg_dump_rst_info(struct seq_file *s, void *data) return 0; } +static int ubase_dbg_dump_activate_record(struct seq_file *s, void *data) +{ + struct ubase_dev *udev = dev_get_drvdata(s->private); + struct ubase_activate_dev_stats *record; + u8 cnt = 1, stats_cnt; + u64 total, idx; + + if (!test_bit(UBASE_STATE_INITED_B, &udev->state_bits) || + test_bit(UBASE_STATE_RST_HANDLING_B, &udev->state_bits)) + return -EBUSY; + + record = &udev->stats.activate_record; + + mutex_lock(&record->lock); + + seq_puts(s, "current time : "); + ubase_dbg_format_time(ktime_get_real_seconds(), s); + seq_puts(s, "\n"); + seq_printf(s, "activate dev count : %llu\n", record->act_cnt); + seq_printf(s, "deactivate dev count : %llu\n", record->deact_cnt); + + total = record->act_cnt + record->deact_cnt; + if (!total) { + seq_puts(s, "activate dev change records : NA\n"); + mutex_unlock(&record->lock); + return 0; + } + + seq_puts(s, "activate dev change records :\n"); + seq_puts(s, "\tNo.\tTIME\t\t\t\tSTATUS\t\tRESULT\n"); + + stats_cnt = min(total, UBASE_ACT_STAT_MAX_NUM); + while (cnt <= stats_cnt) { + total--; + idx = total % UBASE_ACT_STAT_MAX_NUM; + seq_printf(s, "\t%-2d\t", cnt); + ubase_dbg_format_time(record->stats[idx].time, s); + seq_printf(s, "\t%s", record->stats[idx].activate ? + "activate" : "deactivate"); + seq_printf(s, "\t%d", record->stats[idx].result); + seq_puts(s, "\n"); + cnt++; + } + + mutex_unlock(&record->lock); + + return 0; +} + static void ubase_dbg_fill_single_port(struct seq_file *s, struct ubase_perf_stats_result *stats) { @@ -193,6 +242,14 @@ static struct ubase_dbg_cmd_info ubase_dbg_cmd[] = { .init = __ubase_dbg_seq_file_init, .read_func = ubase_dbg_dump_rst_info, }, + { + .name = "activate_record", + .dentry_index = UBASE_DBG_DENTRY_ROOT, + .property = UBASE_SUP_URMA | UBASE_SUP_CDMA | UBASE_SUP_UBL_ETH, + .support = __ubase_dbg_dentry_support, + .init = __ubase_dbg_seq_file_init, + .read_func = ubase_dbg_dump_activate_record, + }, { .name = "sl_vl_map", .dentry_index = UBASE_DBG_DENTRY_QOS, diff --git a/drivers/ub/ubase/ubase_dev.c b/drivers/ub/ubase/ubase_dev.c index abdb3232edea..3921cd0ff824 100644 --- a/drivers/ub/ubase/ubase_dev.c +++ b/drivers/ub/ubase/ubase_dev.c @@ -16,6 +16,7 @@ #include "ubase_mailbox.h" #include "ubase_pmem.h" #include "ubase_reset.h" +#include "ubase_stats.h" #include "ubase_dev.h" #define UBASE_PERIOD_100MS 100 @@ -1317,12 +1318,15 @@ int ubase_activate_dev(struct auxiliary_device *adev) if (ret) { ubase_err(udev, "failed to activate ubase dev, ret = %d.\n", ret); - return ret; + goto activate_dev_err; } ubase_activate_notify(udev, adev, true); - return 0; +activate_dev_err: + ubase_update_activate_stats(udev, true, ret); + + return ret; } EXPORT_SYMBOL(ubase_activate_dev); @@ -1352,6 +1356,8 @@ int ubase_deactivate_dev(struct auxiliary_device *adev) ubase_activate_notify(udev, adev, true); } + ubase_update_activate_stats(udev, false, ret); + return ret; } EXPORT_SYMBOL(ubase_deactivate_dev); diff --git a/drivers/ub/ubase/ubase_stats.c b/drivers/ub/ubase/ubase_stats.c index b30e839ebb0b..7f536e0cd537 100644 --- a/drivers/ub/ubase/ubase_stats.c +++ b/drivers/ub/ubase/ubase_stats.c @@ -65,3 +65,25 @@ int ubase_get_ub_port_stats(struct auxiliary_device *adev, u16 port_id, sizeof(*data) / sizeof(u64), false); } EXPORT_SYMBOL(ubase_get_ub_port_stats); + +void ubase_update_activate_stats(struct ubase_dev *udev, bool activate, + int result) +{ + struct ubase_activate_dev_stats *record = &udev->stats.activate_record; + u64 idx, total; + + mutex_lock(&record->lock); + + if (activate) + record->act_cnt++; + else + record->deact_cnt++; + + total = record->act_cnt + record->deact_cnt; + idx = (total - 1) % UBASE_ACT_STAT_MAX_NUM; + record->stats[idx].activate = activate; + record->stats[idx].time = ktime_get_real_seconds(); + record->stats[idx].result = result; + + mutex_unlock(&record->lock); +} diff --git a/drivers/ub/ubase/ubase_stats.h b/drivers/ub/ubase/ubase_stats.h index b3f6e5d788cc..a6826dd461c7 100644 --- a/drivers/ub/ubase/ubase_stats.h +++ b/drivers/ub/ubase/ubase_stats.h @@ -15,4 +15,7 @@ struct ubase_query_mac_stats_cmd { __le64 stats_val[]; }; +void ubase_update_activate_stats(struct ubase_dev *udev, bool activate, + int result); + #endif /* _UBASE_STATS_H */ -- Gitee From 0bbe314ab1feb4918f0643fd752f319fb2cfe310 Mon Sep 17 00:00:00 2001 From: Xiongchuan Zhou Date: Tue, 23 Sep 2025 15:18:35 +0800 Subject: [PATCH 2/5] ub: ubase: Added debug information query function for FST/FVT/RQMT entries drivers inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/ID41MP CVE: NA ------------------------------------------------------------------ This patch enhances the debugfs of the ubase driver by adding support for querying information on FST (Flow Steering Table), FVT (Flow Virtualization Table), and RQMT (Requirement) entries, thereby improving QoS debugging capabilities. Main Features: 1. Entry Information Display: - FST Table: Displays configuration details such as the number of service level queue virtual channels and the starting queue ID. - FVT Table: Shows information on virtual channel size and requirement offsets. - FST_REVERT Table: Provides mapping relationships between FST index, UE index, queue index, and the number of virtual channels. - RQMT Table: Displays requirement information, including FST index, starting queue index, and queue number offset. 2. Multi-User Entity Support: - Supports querying entry information for the current UE and all registered UEs. - Uses a UE list lock to ensure thread-safe access. This feature provides network administrators with an in-depth visualization tool for traffic steering and virtualization configurations, aiding in the diagnosis and optimization of complex QoS policy configurations. Signed-off-by: Zihao Sheng Signed-off-by: Xiongchuan Zhou --- drivers/ub/ubase/debugfs/ubase_debugfs.c | 8 ++ drivers/ub/ubase/debugfs/ubase_qos_debugfs.c | 102 +++++++++++++++++++ drivers/ub/ubase/debugfs/ubase_qos_debugfs.h | 1 + 3 files changed, 111 insertions(+) diff --git a/drivers/ub/ubase/debugfs/ubase_debugfs.c b/drivers/ub/ubase/debugfs/ubase_debugfs.c index ef0b162e1188..56ce970411bd 100644 --- a/drivers/ub/ubase/debugfs/ubase_debugfs.c +++ b/drivers/ub/ubase/debugfs/ubase_debugfs.c @@ -314,6 +314,14 @@ static struct ubase_dbg_cmd_info ubase_dbg_cmd[] = { .init = __ubase_dbg_seq_file_init, .read_func = ubase_dbg_dump_adev_qos_info, }, + { + .name = "fst_fvt_rqmt_info", + .dentry_index = UBASE_DBG_DENTRY_QOS, + .property = UBASE_SUP_URMA | UBASE_SUP_CDMA | UBASE_SUP_UBL_ETH, + .support = __ubase_dbg_dentry_support, + .init = __ubase_dbg_seq_file_init, + .read_func = ubase_dbg_dump_fsv_fvt_rqmt, + }, { .name = "tm_queue", .dentry_index = UBASE_DBG_DENTRY_QOS, diff --git a/drivers/ub/ubase/debugfs/ubase_qos_debugfs.c b/drivers/ub/ubase/debugfs/ubase_qos_debugfs.c index 9b8221e422da..91e05df180bb 100644 --- a/drivers/ub/ubase/debugfs/ubase_qos_debugfs.c +++ b/drivers/ub/ubase/debugfs/ubase_qos_debugfs.c @@ -252,6 +252,108 @@ int ubase_dbg_dump_adev_qos_info(struct seq_file *s, void *data) return 0; } +static void ubase_dbg_fill_fst_fvt(struct seq_file *s, + struct ubase_query_fst_fvt_rqmt_cmd *resp) +{ + seq_puts(s, "\tFST:\n"); + seq_printf(s, "\t\tsl_queue_vl_num: %u\n", + le16_to_cpu(resp->sl_queue_vl_num)); + seq_printf(s, "\t\tsl_queue_start_qid: %u\n", + le16_to_cpu(resp->sl_queue_start_qid)); + seq_puts(s, "\tFVT:\n"); + seq_printf(s, "\t\tfvt_vl_size: %u\n", le16_to_cpu(resp->fvt_vl_size)); + seq_printf(s, "\t\tfvt_rqmt_offset: %u\n", + le16_to_cpu(resp->fvt_rqmt_offset)); +} + +static void ubase_dbg_fill_fst_revert(struct seq_file *s, + struct ubase_query_fst_fvt_rqmt_cmd *resp) +{ + u16 vl_num = min(UBASE_MAX_VL_NUM, le16_to_cpu(resp->sl_queue_vl_num)); + u16 j; + + seq_puts(s, "\tFST_REVERT:\n"); + seq_puts(s, "\t\tFST_IDX UE_IDX QUE_IDX VL_NUM\n"); + + for (j = 0; j < vl_num; j++) { + seq_puts(s, "\t\t"); + seq_printf(s, "%-9u", le16_to_cpu(resp->fstr_info[j].fst_idx)); + seq_printf(s, "%-10u", resp->fstr_info[j].queue_ue_num); + seq_printf(s, "%-10u", resp->fstr_info[j].queue_que_num); + seq_printf(s, "%-9u", le16_to_cpu(resp->fstr_info[j].queue_vl_num)); + seq_puts(s, "\n"); + } +} + +static void ubase_dbg_fill_rqmt(struct seq_file *s, + struct ubase_query_fst_fvt_rqmt_cmd *resp) +{ + u16 vl_size = min(UBASE_MAX_VL_NUM, le16_to_cpu(resp->fvt_vl_size)); + u16 j; + + seq_puts(s, "\tRQMT:\n"); + seq_puts(s, "\t\tFST_IDX QUE_IDX QUE_SHIFT\n"); + + for (j = 0; j < vl_size; j++) { + seq_puts(s, "\t\t"); + seq_printf(s, "%-9u", le16_to_cpu(resp->rqmt_info[j].fst_idx)); + seq_printf(s, "%-10u", + le16_to_cpu(resp->rqmt_info[j].start_queue_idx)); + seq_printf(s, "%-12u", + le16_to_cpu(resp->rqmt_info[j].queue_quantity_shift)); + seq_puts(s, "\n"); + } + + seq_puts(s, "\n"); +} + +static void ubase_dbg_fill_tbl_content(struct seq_file *s, + struct ubase_query_fst_fvt_rqmt_cmd *resp) +{ + ubase_dbg_fill_fst_fvt(s, resp); + + ubase_dbg_fill_fst_revert(s, resp); + + ubase_dbg_fill_rqmt(s, resp); +} + +int ubase_dbg_dump_fsv_fvt_rqmt(struct seq_file *s, void *data) +{ + struct ubase_dev *udev = dev_get_drvdata(s->private); + struct ubase_query_fst_fvt_rqmt_cmd resp = {0}; + struct ubase_ue_node *ue_node; + u16 ue_id; + int ret; + + if (!test_bit(UBASE_STATE_INITED_B, &udev->state_bits) || + test_bit(UBASE_STATE_RST_HANDLING_B, &udev->state_bits)) + return -EBUSY; + + seq_puts(s, "current ue:\n"); + ret = ubase_query_fst_fvt_rqmt(udev, &resp, 0); + if (ret) + return ret; + + ubase_dbg_fill_tbl_content(s, &resp); + + mutex_lock(&udev->ue_list_lock); + list_for_each_entry(ue_node, &udev->ue_list, list) { + ue_id = ue_node->bus_ue_id; + memset(&resp, 0, sizeof(resp)); + + seq_printf(s, "ue%u:\n", ue_id); + + ret = ubase_query_fst_fvt_rqmt(udev, &resp, ue_id); + if (ret) + goto out; + ubase_dbg_fill_tbl_content(s, &resp); + } + +out: + mutex_unlock(&udev->ue_list_lock); + return ret; +} + static void ubase_dbg_fill_tm_queue_seq(struct seq_file *s, struct ubase_query_tm_queue_cmd *resp) { diff --git a/drivers/ub/ubase/debugfs/ubase_qos_debugfs.h b/drivers/ub/ubase/debugfs/ubase_qos_debugfs.h index 48f45a2dbec0..e44b4cacd21e 100644 --- a/drivers/ub/ubase/debugfs/ubase_qos_debugfs.h +++ b/drivers/ub/ubase/debugfs/ubase_qos_debugfs.h @@ -16,6 +16,7 @@ int ubase_dbg_dump_ets_tcg_info(struct seq_file *s, void *data); int ubase_dbg_dump_ets_port_info(struct seq_file *s, void *data); int ubase_dbg_dump_rack_vl_bitmap(struct seq_file *s, void *data); int ubase_dbg_dump_adev_qos_info(struct seq_file *s, void *data); +int ubase_dbg_dump_fsv_fvt_rqmt(struct seq_file *s, void *data); int ubase_dbg_dump_tm_queue_info(struct seq_file *s, void *data); int ubase_dbg_dump_tm_qset_info(struct seq_file *s, void *data); int ubase_dbg_dump_tm_pri_info(struct seq_file *s, void *data); -- Gitee From f817c5c6db98ed97a926202808d90fa395048dc2 Mon Sep 17 00:00:00 2001 From: Xiongchuan Zhou Date: Wed, 29 Oct 2025 16:50:32 +0800 Subject: [PATCH 3/5] ub: ubase: add function that query aeq/ceq/tp/tpg context drivers inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/ID41MP CVE: NA ------------------------------------------------------- This patch adds hardware context debugging functionality to the ubase driver, providing visual query capabilities for key hardware contexts such as AEQ, CEQ, TPG, and TP through the debugfs interface. 1. Main Features: - Supports querying AEQ/CEQ event queue contexts (status, size, interrupt configuration, etc.) - Provides display of TPG (Transmission Port Group) and TP (Transmission Port) context information - Implements hardware register context dump functionality with desensitization of key fields - Adds a new context debugging directory, integrating various context query interfaces 2. Technical Features: - Uses a mailbox mechanism to query hardware context registers - Masks sensitive addresses and token information - Supports multi-context group and port bitmap filtering - Thread-safe lock mechanism protects data structure access This implementation provides developers with an in-depth hardware state diagnostic tool, facilitating the debugging of complex hardware interaction issues. Signed-off-by: Fengyan Mu Signed-off-by: Xiongchuan Zhou --- drivers/ub/ubase/debugfs/ubase_ctx_debugfs.c | 369 +++++++++++++++++++ drivers/ub/ubase/debugfs/ubase_ctx_debugfs.h | 20 + drivers/ub/ubase/debugfs/ubase_debugfs.c | 62 ++++ drivers/ub/ubase/ubase_tp.h | 26 ++ 4 files changed, 477 insertions(+) create mode 100644 drivers/ub/ubase/debugfs/ubase_ctx_debugfs.h diff --git a/drivers/ub/ubase/debugfs/ubase_ctx_debugfs.c b/drivers/ub/ubase/debugfs/ubase_ctx_debugfs.c index 1004033c1581..33221a90edd9 100644 --- a/drivers/ub/ubase/debugfs/ubase_ctx_debugfs.c +++ b/drivers/ub/ubase/debugfs/ubase_ctx_debugfs.c @@ -7,6 +7,237 @@ #include #include "ubase_debugfs.h" +#include "ubase_hw.h" +#include "ubase_mailbox.h" +#include "ubase_tp.h" +#include "ubase_ctx_debugfs.h" + +#define UBASE_DEFAULT_CTXGN 0 + +static void ubase_dump_eq_ctx(struct seq_file *s, struct ubase_eq *eq) +{ + seq_printf(s, "%-5u", eq->eqn); + seq_printf(s, "%-13u", eq->entries_num); + seq_printf(s, "%-7u", eq->state); + seq_printf(s, "%-8u", eq->arm_st); + seq_printf(s, "%-10u", eq->eqe_size); + seq_printf(s, "%-11u", eq->eq_period); + seq_printf(s, "%-14u", eq->coalesce_cnt); + seq_printf(s, "%-6u", eq->irqn); + seq_printf(s, "%-10u", eq->eqc_irqn); + seq_printf(s, "%-12u", eq->cons_index); + seq_puts(s, "\n"); +} + +static void ubase_eq_ctx_titles_print(struct seq_file *s) +{ + seq_puts(s, "EQN ENTRIES_NUM STATE ARM_ST EQE_SIZE EQ_PERIOD "); + seq_puts(s, "COALESCE_CNT IRQN EQC_IRQN CONS_INDEX\n"); +} + +static void ubase_dump_aeq_ctx(struct seq_file *s, struct ubase_dev *udev, u32 idx) +{ + struct ubase_aeq *aeq = &udev->irq_table.aeq; + struct ubase_eq *eq = &aeq->eq; + + ubase_dump_eq_ctx(s, eq); +} + +static void ubase_dump_ceq_ctx(struct seq_file *s, struct ubase_dev *udev, u32 idx) +{ + struct ubase_ceq *ceq = &udev->irq_table.ceqs.ceq[idx]; + struct ubase_eq *eq = &ceq->eq; + + ubase_dump_eq_ctx(s, eq); +} + +static void ubase_tpg_ctx_titles_print(struct seq_file *s) +{ + seq_puts(s, "CHANNEL_ID TPGN TP_SHIFT VALID_TP "); + seq_puts(s, "START_TPN TPG_STATE TP_CNT\n"); +} + +static void ubase_dump_tpg_ctx(struct seq_file *s, struct ubase_dev *udev, u32 idx) +{ + struct ubase_tpg *tpg = &udev->tp_ctx.tpg[idx]; + + seq_printf(s, "%-12u", idx); + seq_printf(s, "%-9u", tpg->mb_tpgn); + seq_printf(s, "%-10u", tpg->tp_shift); + seq_printf(s, "%-10lu", tpg->valid_tp); + seq_printf(s, "%-11u", tpg->start_tpn); + seq_printf(s, "%-11u", tpg->tpg_state); + seq_printf(s, "%-8u", tpg->tp_cnt); + seq_puts(s, "\n"); +} + +enum ubase_dbg_ctx_type { + UBASE_DBG_AEQ_CTX = 0, + UBASE_DBG_CEQ_CTX, + UBASE_DBG_TPG_CTX, + UBASE_DBG_TP_CTX, +}; + +static u32 ubase_get_ctx_num(struct ubase_dev *udev, + enum ubase_dbg_ctx_type ctx_type, u32 ctxgn) +{ + struct ubase_adev_caps *unic_caps = &udev->caps.unic_caps; + u32 ctx_num = 0; + + switch (ctx_type) { + case UBASE_DBG_AEQ_CTX: + ctx_num = udev->caps.dev_caps.num_aeq_vectors; + break; + case UBASE_DBG_CEQ_CTX: + ctx_num = udev->irq_table.ceqs.num; + break; + case UBASE_DBG_TPG_CTX: + ctx_num = unic_caps->tpg.max_cnt; + break; + case UBASE_DBG_TP_CTX: + spin_lock(&udev->tp_ctx.tpg_lock); + if (udev->tp_ctx.tpg) + ctx_num = udev->tp_ctx.tpg[ctxgn].tp_cnt; + spin_unlock(&udev->tp_ctx.tpg_lock); + break; + default: + ubase_err(udev, "failed to get ctx num, ctx_type = %u.\n", + ctx_type); + break; + } + + return ctx_num; +} + +static int ubase_dbg_dump_context(struct seq_file *s, + enum ubase_dbg_ctx_type ctx_type) +{ + struct ubase_dbg_ctx { + void (*print_ctx_titles)(struct seq_file *s); + void (*get_ctx)(struct seq_file *s, struct ubase_dev *udev, u32 idx); + } dbg_ctx[] = { + {ubase_eq_ctx_titles_print, ubase_dump_aeq_ctx}, + {ubase_eq_ctx_titles_print, ubase_dump_ceq_ctx}, + {ubase_tpg_ctx_titles_print, ubase_dump_tpg_ctx}, + }; + struct ubase_dev *udev = dev_get_drvdata(s->private); + struct ubase_adev_caps *unic_caps = &udev->caps.unic_caps; + unsigned long port_bitmap; + u32 tp_pos, i; + + dbg_ctx[ctx_type].print_ctx_titles(s); + + port_bitmap = unic_caps->utp_port_bitmap; + for (i = 0; i < ubase_get_ctx_num(udev, ctx_type, UBASE_DEFAULT_CTXGN); i++) { + if (ctx_type != UBASE_DBG_TP_CTX) { + dbg_ctx[ctx_type].get_ctx(s, udev, i); + continue; + } + + tp_pos = (i % unic_caps->tpg.depth) * UBASE_TP_PORT_BITMAP_STEP; + if (test_bit(tp_pos, &port_bitmap)) + dbg_ctx[ctx_type].get_ctx(s, udev, i); + } + + return 0; +} + +struct ubase_ctx_info { + u32 start_idx; + u32 ctx_size; + u8 op; + const char *ctx_name; +}; + +static inline u32 ubase_get_ctx_group_num(struct ubase_dev *udev, + enum ubase_dbg_ctx_type ctx_type) +{ + if (ctx_type == UBASE_DBG_TP_CTX) + return udev->caps.unic_caps.tpg.max_cnt; + + return 1; +} + +static void ubase_get_ctx_info(struct ubase_dev *udev, + enum ubase_dbg_ctx_type ctx_type, + struct ubase_ctx_info *ctx_info, u32 ctxgn) +{ + switch (ctx_type) { + case UBASE_DBG_AEQ_CTX: + ctx_info->start_idx = 0; + ctx_info->ctx_size = UBASE_AEQ_CTX_SIZE; + ctx_info->op = UBASE_MB_QUERY_AEQ_CONTEXT; + ctx_info->ctx_name = "aeq"; + break; + case UBASE_DBG_CEQ_CTX: + ctx_info->start_idx = 0; + ctx_info->ctx_size = UBASE_CEQ_CTX_SIZE; + ctx_info->op = UBASE_MB_QUERY_CEQ_CONTEXT; + ctx_info->ctx_name = "ceq"; + break; + case UBASE_DBG_TPG_CTX: + ctx_info->start_idx = udev->caps.unic_caps.tpg.start_idx; + ctx_info->ctx_size = udev->ctx_buf.tpg.entry_size; + ctx_info->op = UBASE_MB_QUERY_TPG_CONTEXT; + ctx_info->ctx_name = "tpg"; + break; + case UBASE_DBG_TP_CTX: + spin_lock(&udev->tp_ctx.tpg_lock); + ctx_info->start_idx = udev->tp_ctx.tpg ? + udev->tp_ctx.tpg[ctxgn].start_tpn : 0; + spin_unlock(&udev->tp_ctx.tpg_lock); + + ctx_info->ctx_size = udev->ctx_buf.tp.entry_size; + ctx_info->op = UBASE_MB_QUERY_TP_CONTEXT; + ctx_info->ctx_name = "tp"; + break; + default: + ubase_err(udev, "failed to get ctx info, ctx_type = %u.\n", + ctx_type); + break; + } +} + +static void ubase_mask_eq_ctx_key_words(void *buf) +{ + struct ubase_eq_ctx *eq = (struct ubase_eq_ctx *)buf; + + eq->eqe_base_addr_l = 0; + eq->eqe_base_addr_h = 0; + eq->eqe_token_id = 0; + eq->eqe_token_value = 0; +} + +static void ubase_mask_tp_ctx_key_words(void *buf) +{ + struct ubase_tp_ctx *tp = (struct ubase_tp_ctx *)buf; + + tp->wqe_ba_l = 0; + tp->wqe_ba_h = 0; + tp->tp_wqe_token_id = 0; + tp->reorder_q_addr_l = 0; + tp->reorder_q_addr_h = 0; + tp->scc_token = 0; + tp->scc_token_1 = 0; +} + +static void ubase_mask_ctx_key_words(void *buf, + enum ubase_dbg_ctx_type ctx_type) +{ + switch (ctx_type) { + case UBASE_DBG_AEQ_CTX: + case UBASE_DBG_CEQ_CTX: + ubase_mask_eq_ctx_key_words(buf); + break; + case UBASE_DBG_TPG_CTX: + break; + case UBASE_DBG_TP_CTX: + ubase_mask_tp_ctx_key_words(buf); + break; + default: + break; + } +} static void __ubase_print_context_hw(struct seq_file *s, void *ctx_addr, u32 ctx_len) @@ -29,3 +260,141 @@ void ubase_print_context_hw(struct seq_file *s, void *ctx_addr, u32 ctx_len) __ubase_print_context_hw(s, ctx_addr, ctx_len); } EXPORT_SYMBOL(ubase_print_context_hw); + +static int ubase_dbg_dump_ctx_hw(struct seq_file *s, void *data, + enum ubase_dbg_ctx_type ctx_type) +{ + struct ubase_dev *udev = dev_get_drvdata(s->private); + struct ubase_ctx_info ctx_info = {0}; + struct ubase_cmd_mailbox *mailbox; + u32 max_ctxgn, ctxn, ctxgn; + struct ubase_mbx_attr attr; + int ret = 0; + + if (!test_bit(UBASE_STATE_INITED_B, &udev->state_bits) || + test_bit(UBASE_STATE_RST_HANDLING_B, &udev->state_bits)) + return -EBUSY; + + mailbox = __ubase_alloc_cmd_mailbox(udev); + if (IS_ERR_OR_NULL(mailbox)) { + ubase_err(udev, + "failed to alloc mailbox for dump hw context.\n"); + return -ENOMEM; + } + + max_ctxgn = ubase_get_ctx_group_num(udev, ctx_type); + for (ctxgn = 0; ctxgn < max_ctxgn; ctxgn++) { + ubase_get_ctx_info(udev, ctx_type, &ctx_info, ctxgn); + + for (ctxn = 0; ctxn < ubase_get_ctx_num(udev, ctx_type, ctxgn); ctxn++) { + ubase_fill_mbx_attr(&attr, ctxn + ctx_info.start_idx, + ctx_info.op, 0); + ret = __ubase_hw_upgrade_ctx_ex(udev, &attr, mailbox); + if (ret) { + ubase_err(udev, + "failed to post query %s ctx mbx, ret = %d.\n", + ctx_info.ctx_name, ret); + goto upgrade_ctx_err; + } + + seq_printf(s, "offset\t%s%u\n", ctx_info.ctx_name, + ctxn + ctx_info.start_idx); + ubase_mask_ctx_key_words(mailbox->buf, ctx_type); + __ubase_print_context_hw(s, mailbox->buf, ctx_info.ctx_size); + seq_puts(s, "\n"); + } + } + +upgrade_ctx_err: + __ubase_free_cmd_mailbox(udev, mailbox); + + return ret; +} + +int ubase_dbg_dump_aeq_context(struct seq_file *s, void *data) +{ + return ubase_dbg_dump_context(s, UBASE_DBG_AEQ_CTX); +} + +int ubase_dbg_dump_ceq_context(struct seq_file *s, void *data) +{ + struct ubase_dev *udev = dev_get_drvdata(s->private); + int ret; + + if (!mutex_trylock(&udev->irq_table.ceq_lock)) + return -EBUSY; + + if (!udev->irq_table.ceqs.ceq) { + mutex_unlock(&udev->irq_table.ceq_lock); + return -EBUSY; + } + + ret = ubase_dbg_dump_context(s, UBASE_DBG_CEQ_CTX); + mutex_unlock(&udev->irq_table.ceq_lock); + + return ret; +} + +int ubase_dbg_dump_tpg_ctx(struct seq_file *s, void *data) +{ + struct ubase_dev *udev = dev_get_drvdata(s->private); + int ret; + + if (!test_bit(UBASE_STATE_INITED_B, &udev->state_bits)) + return -EBUSY; + + if (!ubase_get_ctx_num(udev, UBASE_DBG_TPG_CTX, UBASE_DEFAULT_CTXGN)) + return -EOPNOTSUPP; + + if (!spin_trylock(&udev->tp_ctx.tpg_lock)) + return -EBUSY; + + if (!udev->tp_ctx.tpg) { + spin_unlock(&udev->tp_ctx.tpg_lock); + return -EBUSY; + } + + ret = ubase_dbg_dump_context(s, UBASE_DBG_TPG_CTX); + spin_unlock(&udev->tp_ctx.tpg_lock); + + return ret; +} + +int ubase_dbg_dump_tpg_ctx_hw(struct seq_file *s, void *data) +{ + struct ubase_dev *udev = dev_get_drvdata(s->private); + + if (!test_bit(UBASE_STATE_INITED_B, &udev->state_bits)) + return -EBUSY; + + if (!ubase_get_ctx_num(udev, UBASE_DBG_TPG_CTX, UBASE_DEFAULT_CTXGN)) + return -EOPNOTSUPP; + + return ubase_dbg_dump_ctx_hw(s, data, UBASE_DBG_TPG_CTX); +} + +int ubase_dbg_dump_tp_ctx_hw(struct seq_file *s, void *data) +{ + struct ubase_dev *udev = dev_get_drvdata(s->private); + + if (!test_bit(UBASE_STATE_INITED_B, &udev->state_bits)) + return -EBUSY; + + if (!ubase_get_ctx_num(udev, UBASE_DBG_TP_CTX, UBASE_DEFAULT_CTXGN)) + return -EOPNOTSUPP; + + if (!ubase_get_ctx_group_num(udev, UBASE_DBG_TP_CTX)) + return -EOPNOTSUPP; + + return ubase_dbg_dump_ctx_hw(s, data, UBASE_DBG_TP_CTX); +} + +int ubase_dbg_dump_aeq_ctx_hw(struct seq_file *s, void *data) +{ + return ubase_dbg_dump_ctx_hw(s, data, UBASE_DBG_AEQ_CTX); +} + +int ubase_dbg_dump_ceq_ctx_hw(struct seq_file *s, void *data) +{ + return ubase_dbg_dump_ctx_hw(s, data, UBASE_DBG_CEQ_CTX); +} diff --git a/drivers/ub/ubase/debugfs/ubase_ctx_debugfs.h b/drivers/ub/ubase/debugfs/ubase_ctx_debugfs.h new file mode 100644 index 000000000000..532665141fc8 --- /dev/null +++ b/drivers/ub/ubase/debugfs/ubase_ctx_debugfs.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2025 HiSilicon Technologies Co., Ltd. All rights reserved. + * + */ + +#ifndef __UBASE_CTX_DEBUGFS_H__ +#define __UBASE_CTX_DEBUGFS_H__ + +struct device; + +int ubase_dbg_dump_aeq_context(struct seq_file *s, void *data); +int ubase_dbg_dump_ceq_context(struct seq_file *s, void *data); +int ubase_dbg_dump_tpg_ctx(struct seq_file *s, void *data); +int ubase_dbg_dump_tp_ctx_hw(struct seq_file *s, void *data); +int ubase_dbg_dump_tpg_ctx_hw(struct seq_file *s, void *data); +int ubase_dbg_dump_aeq_ctx_hw(struct seq_file *s, void *data); +int ubase_dbg_dump_ceq_ctx_hw(struct seq_file *s, void *data); + +#endif diff --git a/drivers/ub/ubase/debugfs/ubase_debugfs.c b/drivers/ub/ubase/debugfs/ubase_debugfs.c index 56ce970411bd..ab3e1a88ced8 100644 --- a/drivers/ub/ubase/debugfs/ubase_debugfs.c +++ b/drivers/ub/ubase/debugfs/ubase_debugfs.c @@ -8,6 +8,7 @@ #include #include +#include "ubase_ctx_debugfs.h" #include "ubase_dev.h" #include "ubase_hw.h" #include "ubase_qos_debugfs.h" @@ -216,6 +217,11 @@ int ubase_dbg_seq_file_init(struct device *dev, EXPORT_SYMBOL(ubase_dbg_seq_file_init); static struct ubase_dbg_dentry_info ubase_dbg_dentry[] = { + { + .name = "context", + .property = UBASE_SUP_URMA | UBASE_SUP_CDMA | UBASE_SUP_UBL_ETH, + .support = __ubase_dbg_dentry_support, + }, { .name = "qos", .property = UBASE_SUP_URMA | UBASE_SUP_CDMA | UBASE_SUP_UBL_ETH, @@ -242,6 +248,22 @@ static struct ubase_dbg_cmd_info ubase_dbg_cmd[] = { .init = __ubase_dbg_seq_file_init, .read_func = ubase_dbg_dump_rst_info, }, + { + .name = "aeq_context", + .dentry_index = UBASE_DBG_DENTRY_CONTEXT, + .property = UBASE_SUP_URMA | UBASE_SUP_CDMA | UBASE_SUP_UBL_ETH, + .support = __ubase_dbg_dentry_support, + .init = __ubase_dbg_seq_file_init, + .read_func = ubase_dbg_dump_aeq_context, + }, + { + .name = "ceq_context", + .dentry_index = UBASE_DBG_DENTRY_CONTEXT, + .property = UBASE_SUP_URMA | UBASE_SUP_CDMA | UBASE_SUP_UBL_ETH, + .support = __ubase_dbg_dentry_support, + .init = __ubase_dbg_seq_file_init, + .read_func = ubase_dbg_dump_ceq_context, + }, { .name = "activate_record", .dentry_index = UBASE_DBG_DENTRY_ROOT, @@ -250,6 +272,46 @@ static struct ubase_dbg_cmd_info ubase_dbg_cmd[] = { .init = __ubase_dbg_seq_file_init, .read_func = ubase_dbg_dump_activate_record, }, + { + .name = "tpg_context", + .dentry_index = UBASE_DBG_DENTRY_CONTEXT, + .property = UBASE_SUP_URMA | UBASE_SUP_UBL_ETH, + .support = __ubase_dbg_dentry_support, + .init = __ubase_dbg_seq_file_init, + .read_func = ubase_dbg_dump_tpg_ctx, + }, + { + .name = "tp_context_hw", + .dentry_index = UBASE_DBG_DENTRY_CONTEXT, + .property = UBASE_SUP_URMA | UBASE_SUP_UBL_ETH, + .support = __ubase_dbg_dentry_support, + .init = __ubase_dbg_seq_file_init, + .read_func = ubase_dbg_dump_tp_ctx_hw, + }, + { + .name = "tpg_context_hw", + .dentry_index = UBASE_DBG_DENTRY_CONTEXT, + .property = UBASE_SUP_URMA | UBASE_SUP_UBL_ETH, + .support = __ubase_dbg_dentry_support, + .init = __ubase_dbg_seq_file_init, + .read_func = ubase_dbg_dump_tpg_ctx_hw, + }, + { + .name = "aeq_context_hw", + .dentry_index = UBASE_DBG_DENTRY_CONTEXT, + .property = UBASE_SUP_URMA | UBASE_SUP_CDMA | UBASE_SUP_UBL_ETH, + .support = __ubase_dbg_dentry_support, + .init = __ubase_dbg_seq_file_init, + .read_func = ubase_dbg_dump_aeq_ctx_hw, + }, + { + .name = "ceq_context_hw", + .dentry_index = UBASE_DBG_DENTRY_CONTEXT, + .property = UBASE_SUP_URMA | UBASE_SUP_CDMA | UBASE_SUP_UBL_ETH, + .support = __ubase_dbg_dentry_support, + .init = __ubase_dbg_seq_file_init, + .read_func = ubase_dbg_dump_ceq_ctx_hw, + }, { .name = "sl_vl_map", .dentry_index = UBASE_DBG_DENTRY_QOS, diff --git a/drivers/ub/ubase/ubase_tp.h b/drivers/ub/ubase/ubase_tp.h index 965535a18f1a..0506e77c98f0 100644 --- a/drivers/ub/ubase/ubase_tp.h +++ b/drivers/ub/ubase/ubase_tp.h @@ -11,8 +11,34 @@ #include "ubase_dev.h" +#define UBASE_TP_PORT_BITMAP_STEP 2 + #define UBASE_WAIT_TP_FLUSH_TOTAL_STEPS 12 +struct ubase_tp_ctx { + u32 rsvd0; + u32 wqe_ba_l; + u32 wqe_ba_h : 20; + u32 rsvd1 : 12; + u32 rsvd2[5]; + u32 rsvd3_0 : 4; + u32 tp_wqe_token_id : 20; + u32 rsvd3_1 : 8; + u32 rsvd4[5]; + u32 rsvd5 : 4; + u32 reorder_q_addr_l : 28; + u32 reorder_q_addr_h : 24; + u32 rsvd6 : 8; + u32 rsvd7[5]; + u32 scc_token : 19; + u32 rsvd8 : 13; + u32 rsvd9[4]; + u32 rsvd10_0 : 24; + u32 scc_token_1 : 4; + u32 rsvd10_1 : 4; + u32 rsvd11[37]; +}; + struct ubase_tpg { u32 mb_tpgn; u8 tpg_state; -- Gitee From 8a2d8b74eb75df90052e3baad58e645aa0706b7f Mon Sep 17 00:00:00 2001 From: Xiongchuan Zhou Date: Wed, 29 Oct 2025 16:53:51 +0800 Subject: [PATCH 4/5] ub: ubase: Supports the query of UBCL config. drivers inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/ID41MP CVE: NA ------------------------------------------------------------------ UBCL config file is a binary file. The file content determines the configuration of the UB system and deeply affects the running of it. If the file can be read conveniently and effectively, the maintenance capability of the system will be greatly improved. This patch allows the UBASE driver to read the content of UBCL config through debugfs. Users can use debugfs to read the file. Signed-off-by: Yixi Shen Signed-off-by: Haibin Lu Signed-off-by: Xiongchuan Zhou --- drivers/ub/ubase/debugfs/ubase_debugfs.c | 88 ++++++++++++++++++++++++ drivers/ub/ubase/ubase_cmd.h | 10 +++ include/ub/ubase/ubase_comm_cmd.h | 1 + 3 files changed, 99 insertions(+) diff --git a/drivers/ub/ubase/debugfs/ubase_debugfs.c b/drivers/ub/ubase/debugfs/ubase_debugfs.c index ab3e1a88ced8..76175d604366 100644 --- a/drivers/ub/ubase/debugfs/ubase_debugfs.c +++ b/drivers/ub/ubase/debugfs/ubase_debugfs.c @@ -8,6 +8,7 @@ #include #include +#include "ubase_cmd.h" #include "ubase_ctx_debugfs.h" #include "ubase_dev.h" #include "ubase_hw.h" @@ -31,6 +32,85 @@ static int ubase_dbg_dump_rst_info(struct seq_file *s, void *data) return 0; } +static int ubase_query_ubcl_config(struct ubase_dev *udev, u16 offset, + u16 is_query, u16 size, + struct ubase_ubcl_config_cmd *resp) +{ + struct ubase_ubcl_config_cmd req; + struct ubase_cmd_buf in, out; + int ret; + + memset(resp, 0, sizeof(*resp)); + memset(&req, 0, sizeof(req)); + req.offset = cpu_to_le16(offset); + req.size = cpu_to_le16(size); + req.is_query_size = cpu_to_le16(is_query); + + __ubase_fill_inout_buf(&in, UBASE_OPC_QUERY_UBCL_CONFIG, true, + sizeof(req), &req); + __ubase_fill_inout_buf(&out, UBASE_OPC_QUERY_UBCL_CONFIG, true, + sizeof(*resp), resp); + ret = __ubase_cmd_send_inout(udev, &in, &out); + if (ret && ret != -EPERM) + ubase_err(udev, "failed to query UBCL_config, ret = %d.\n", ret); + + if (ret == -EPERM) + return -EOPNOTSUPP; + + return ret; +} + +static void ubase_dbg_fill_ubcl_content(struct ubase_ubcl_config_cmd *resp, + u32 *addr, struct seq_file *s) +{ + int i, j; + + for (i = 0; i < UBASE_UBCL_CFG_DATA_NUM; i += UBASE_UBCL_CFG_DATA_ALIGN) { + seq_printf(s, "%08X: ", (*addr * UBASE_UBCL_CFG_DATA_ALIGN)); + for (j = 0; j < UBASE_UBCL_CFG_DATA_ALIGN; j++) + seq_printf(s, "%08X ", resp->data[i + j]); + seq_puts(s, "\n"); + + *addr += UBASE_UBCL_CFG_DATA_ALIGN; + if ((i * sizeof(u32)) >= resp->size) + break; + } +} + +static int ubase_dbg_dump_ubcl_config(struct seq_file *s, void *data) +{ + struct ubase_dev *udev = dev_get_drvdata(s->private); + struct ubase_ubcl_config_cmd resp = {0}; + u16 read_size = sizeof(resp.data); + u16 offset = 0; + u16 total_size; + u32 addr = 0; + int ret; + + if (!test_bit(UBASE_STATE_INITED_B, &udev->state_bits) || + test_bit(UBASE_STATE_RST_HANDLING_B, &udev->state_bits)) + return -EBUSY; + + ret = ubase_query_ubcl_config(udev, offset, 1, 0, &resp); + if (ret) + return ret; + total_size = le16_to_cpu(resp.size); + + seq_puts(s, "UBCL_config:\n"); + seq_printf(s, "total_size: %u\n", total_size); + while (offset < total_size) { + read_size = min(read_size, total_size - offset); + ret = ubase_query_ubcl_config(udev, offset, 0, read_size, &resp); + if (ret) + return ret; + offset += le16_to_cpu(resp.size); + + ubase_dbg_fill_ubcl_content(&resp, &addr, s); + } + + return 0; +} + static int ubase_dbg_dump_activate_record(struct seq_file *s, void *data) { struct ubase_dev *udev = dev_get_drvdata(s->private); @@ -264,6 +344,14 @@ static struct ubase_dbg_cmd_info ubase_dbg_cmd[] = { .init = __ubase_dbg_seq_file_init, .read_func = ubase_dbg_dump_ceq_context, }, + { + .name = "UBCL_config", + .dentry_index = UBASE_DBG_DENTRY_ROOT, + .property = UBASE_SUP_URMA | UBASE_SUP_CDMA | UBASE_SUP_UBL_ETH, + .support = __ubase_dbg_dentry_support, + .init = __ubase_dbg_seq_file_init, + .read_func = ubase_dbg_dump_ubcl_config, + }, { .name = "activate_record", .dentry_index = UBASE_DBG_DENTRY_ROOT, diff --git a/drivers/ub/ubase/ubase_cmd.h b/drivers/ub/ubase/ubase_cmd.h index 0187597493b7..63b67179f2fb 100644 --- a/drivers/ub/ubase/ubase_cmd.h +++ b/drivers/ub/ubase/ubase_cmd.h @@ -49,6 +49,16 @@ struct ubase_query_version_cmd { __le32 caps[UBASE_CAP_LEN]; }; +#define UBASE_UBCL_CFG_DATA_ALIGN 4 +#define UBASE_UBCL_CFG_DATA_NUM 60 +struct ubase_ubcl_config_cmd { + __le16 is_query_size; + __le16 offset; + __le16 size; + __le16 rsv; + __le32 data[UBASE_UBCL_CFG_DATA_NUM]; +}; + enum ubase_ue2ue_sub_cmd { UBASE_UE2UE_CTRLQ_MSG = 3, }; diff --git a/include/ub/ubase/ubase_comm_cmd.h b/include/ub/ubase/ubase_comm_cmd.h index c412d77ed281..f59035bd4460 100644 --- a/include/ub/ubase/ubase_comm_cmd.h +++ b/include/ub/ubase/ubase_comm_cmd.h @@ -33,6 +33,7 @@ enum ubase_opcode_type { UBASE_OPC_QUERY_COMM_RSRC_PARAM = 0x0030, UBASE_OPC_STATS_MAC_ALL = 0x0038, UBASE_OPC_QUERY_BUS_EID = 0x0047, + UBASE_OPC_QUERY_UBCL_CONFIG = 0x0050, /* NL commands */ UBASE_OPC_CFG_ETS_TC_INFO = 0x2340, -- Gitee From 7bb0989aa20b20df97785020ba318a0fc5915d37 Mon Sep 17 00:00:00 2001 From: Xiongchuan Zhou Date: Wed, 29 Oct 2025 16:58:25 +0800 Subject: [PATCH 5/5] ub: ubase: Support querying dev caps. drivers inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/ID41MP CVE: NA ------------------------------------------------------------------ The UB driver supports a set of code running in different business contexts. The ub driver uses dev caps to distinguish different contexts. Therefore, the debugging method of dev caps is important. This patch allows the UBASE driver to print dev caps for users. Users can use this function through debugfs. Signed-off-by: Yaoyao Tu Signed-off-by: Fengyan Mu Signed-off-by: Haibin Lu Signed-off-by: Xiongchuan Zhou --- drivers/ub/ubase/debugfs/ubase_debugfs.c | 157 +++++++++++++++++++++++ 1 file changed, 157 insertions(+) diff --git a/drivers/ub/ubase/debugfs/ubase_debugfs.c b/drivers/ub/ubase/debugfs/ubase_debugfs.c index 76175d604366..ad97d7a58188 100644 --- a/drivers/ub/ubase/debugfs/ubase_debugfs.c +++ b/drivers/ub/ubase/debugfs/ubase_debugfs.c @@ -32,6 +32,154 @@ static int ubase_dbg_dump_rst_info(struct seq_file *s, void *data) return 0; } +static void ubase_dbg_dump_caps_bits(struct seq_file *s, struct ubase_dev *udev) +{ +#define CAP_FMT(name) "\tsupport_" #name ": %d\n" +#define PTRINT_CAP(name, func) seq_printf(s, CAP_FMT(name), func(udev)) + + PTRINT_CAP(ub_link, ubase_dev_ubl_supported); + PTRINT_CAP(ta_extdb_buffer_config, ubase_dev_ta_extdb_buf_supported); + PTRINT_CAP(ta_timer_buffer_config, ubase_dev_ta_timer_buf_supported); + PTRINT_CAP(err_handle, ubase_dev_err_handle_supported); + PTRINT_CAP(ctrlq, ubase_dev_ctrlq_supported); + PTRINT_CAP(eth_mac, ubase_dev_eth_mac_supported); + PTRINT_CAP(mac_stats, ubase_dev_mac_stats_supported); + PTRINT_CAP(prealloc, __ubase_dev_prealloc_supported); + PTRINT_CAP(udma, ubase_dev_udma_supported); + PTRINT_CAP(unic, ubase_dev_unic_supported); + PTRINT_CAP(uvb, ubase_dev_uvb_supported); + PTRINT_CAP(ip_over_urma, ubase_ip_over_urma_supported); + if (ubase_ip_over_urma_supported(udev)) + PTRINT_CAP(ip_over_urma_utp, ubase_ip_over_urma_utp_supported); + PTRINT_CAP(activate_proxy, ubase_activate_proxy_supported); + PTRINT_CAP(utp, ubase_utp_supported); +} + +static void ubase_dbg_dump_caps_info(struct seq_file *s, struct ubase_dev *udev) +{ + struct ubase_caps *dev_caps = &udev->caps.dev_caps; + struct ubase_dbg_common_caps_info { + const char *format; + u64 caps_info; + } ubase_common_caps_info[] = { + {"\tnum_ceq_vectors: %u\n", dev_caps->num_ceq_vectors}, + {"\tnum_aeq_vectors: %u\n", dev_caps->num_aeq_vectors}, + {"\tnum_misc_vectors: %u\n", dev_caps->num_misc_vectors}, + {"\taeqe_size: %u\n", dev_caps->aeqe_size}, + {"\tceqe_size: %u\n", dev_caps->ceqe_size}, + {"\taeqe_depth: %u\n", dev_caps->aeqe_depth}, + {"\tceqe_depth: %u\n", dev_caps->ceqe_depth}, + {"\ttotal_ue_num: %u\n", dev_caps->total_ue_num}, + {"\tta_extdb_buf_size: %llu\n", udev->ta_ctx.extdb_buf.size}, + {"\tta_timer_buf_size: %llu\n", udev->ta_ctx.timer_buf.size}, + {"\tpublic_jetty_cnt: %u\n", dev_caps->public_jetty_cnt}, + {"\tvl_num: %hhu\n", dev_caps->vl_num}, + {"\trsvd_jetty_cnt: %hu\n", dev_caps->rsvd_jetty_cnt}, + {"\tpacket_pattern_mode: %u\n", dev_caps->packet_pattern_mode}, + {"\tack_queue_num: %u\n", dev_caps->ack_queue_num}, + {"\toor_en: %u\n", dev_caps->oor_en}, + {"\treorder_queue_en: %u\n", dev_caps->reorder_queue_en}, + {"\ton_flight_size: %u\n", dev_caps->on_flight_size}, + {"\treorder_cap: %u\n", dev_caps->reorder_cap}, + {"\treorder_queue_shift: %u\n", dev_caps->reorder_queue_shift}, + {"\tat_times: %u\n", dev_caps->at_times}, + {"\tue_num: %u\n", dev_caps->ue_num}, + {"\tmac_stats_num: %u\n", dev_caps->mac_stats_num}, + {"\tlogic_port_bitmap: 0x%x\n", dev_caps->logic_port_bitmap}, + {"\tub_port_logic_id: %u\n", dev_caps->ub_port_logic_id}, + {"\tio_port_logic_id: %u\n", dev_caps->io_port_logic_id}, + {"\tio_port_id: %u\n", dev_caps->io_port_id}, + {"\tnl_port_id: %u\n", dev_caps->nl_port_id}, + {"\tchip_id: %u\n", dev_caps->chip_id}, + {"\tdie_id: %u\n", dev_caps->die_id}, + {"\tue_id: %u\n", dev_caps->ue_id}, + {"\tnl_id: %u\n", dev_caps->nl_id}, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(ubase_common_caps_info); i++) + seq_printf(s, ubase_common_caps_info[i].format, + ubase_common_caps_info[i].caps_info); +} + +static void ubase_dbg_dump_common_caps(struct seq_file *s, struct ubase_dev *udev) +{ + struct ubase_caps *dev_caps = &udev->caps.dev_caps; + + ubase_dbg_dump_caps_info(s, udev); + + seq_puts(s, "\treq_vl:"); + ubase_dbg_dump_arr_info(s, dev_caps->req_vl, dev_caps->vl_num); + + seq_puts(s, "\tresp_vl:"); + ubase_dbg_dump_arr_info(s, dev_caps->resp_vl, dev_caps->vl_num); +} + +static void ubase_dbg_dump_adev_caps(struct seq_file *s, + struct ubase_adev_caps *caps) +{ + struct ubase_dbg_adev_caps_info { + const char *format; + u32 caps_info; + } ubase_adev_caps_info[] = { + {"\tjfs_max_cnt: %u\n", caps->jfs.max_cnt}, + {"\tjfs_reserved_cnt: %u\n", caps->jfs.reserved_cnt}, + {"\tjfs_depth: %u\n", caps->jfs.depth}, + {"\tjfr_max_cnt: %u\n", caps->jfr.max_cnt}, + {"\tjfr_reserved_cnt: %u\n", caps->jfr.reserved_cnt}, + {"\tjfr_depth: %u\n", caps->jfr.depth}, + {"\tjfc_max_cnt: %u\n", caps->jfc.max_cnt}, + {"\tjfc_reserved_cnt: %u\n", caps->jfc.reserved_cnt}, + {"\tjfc_depth: %u\n", caps->jfc.depth}, + {"\ttp_max_cnt: %u\n", caps->tp.max_cnt}, + {"\ttp_reserved_cnt: %u\n", caps->tp.reserved_cnt}, + {"\ttp_depth: %u\n", caps->tp.depth}, + {"\ttpg_max_cnt: %u\n", caps->tpg.max_cnt}, + {"\ttpg_reserved_cnt: %u\n", caps->tpg.reserved_cnt}, + {"\ttpg_depth: %u\n", caps->tpg.depth}, + {"\tcqe_size: %hu\n", caps->cqe_size}, + {"\tutp_port_bitmap: 0x%x\n", caps->utp_port_bitmap}, + {"\tjtg_max_cnt: %u\n", caps->jtg_max_cnt}, + {"\trc_max_cnt: %u\n", caps->rc_max_cnt}, + {"\trc_depth: %u\n", caps->rc_que_depth}, + {"\tccc_max_cnt: %u\n", caps->ccc_max_cnt}, + {"\tdest_addr_max_cnt: %u\n", caps->dest_addr_max_cnt}, + {"\tseid_upi_max_cnt: %u\n", caps->seid_upi_max_cnt}, + {"\ttpm_max_cnt: %u\n", caps->tpm_max_cnt}, + {"\tprealloc_mem_dma_len: %llu\n", caps->pmem.dma_len}, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(ubase_adev_caps_info); i++) + seq_printf(s, ubase_adev_caps_info[i].format, + ubase_adev_caps_info[i].caps_info); +} + +static int ubase_dbg_dump_dev_caps(struct seq_file *s, void *data) +{ + struct ubase_dev *udev = dev_get_drvdata(s->private); + struct ubase_dev_caps *udev_caps = &udev->caps; + + seq_puts(s, "CAP_BITS:\n"); + ubase_dbg_dump_caps_bits(s, udev); + seq_puts(s, "\nCOMMON_CAPS:\n"); + ubase_dbg_dump_common_caps(s, udev); + + if (ubase_dev_pmu_supported(udev)) + return 0; + + seq_puts(s, "\nUNIC_CAPS:\n"); + ubase_dbg_dump_adev_caps(s, &udev_caps->unic_caps); + + if (ubase_dev_cdma_supported(udev)) + seq_puts(s, "\nCDMA_CAPS:\n"); + else + seq_puts(s, "\nUDMA_CAPS:\n"); + ubase_dbg_dump_adev_caps(s, &udev_caps->udma_caps); + + return 0; +} + static int ubase_query_ubcl_config(struct ubase_dev *udev, u16 offset, u16 is_query, u16 size, struct ubase_ubcl_config_cmd *resp) @@ -344,6 +492,15 @@ static struct ubase_dbg_cmd_info ubase_dbg_cmd[] = { .init = __ubase_dbg_seq_file_init, .read_func = ubase_dbg_dump_ceq_context, }, + { + .name = "caps_info", + .dentry_index = UBASE_DBG_DENTRY_ROOT, + .property = UBASE_SUP_URMA | UBASE_SUP_CDMA | UBASE_SUP_PMU | + UBASE_SUP_UBL_ETH, + .support = __ubase_dbg_dentry_support, + .init = __ubase_dbg_seq_file_init, + .read_func = ubase_dbg_dump_dev_caps, + }, { .name = "UBCL_config", .dentry_index = UBASE_DBG_DENTRY_ROOT, -- Gitee