From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id BEB9146D85; Thu, 21 Aug 2025 10:13:44 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 07E7640292; Thu, 21 Aug 2025 10:13:44 +0200 (CEST) Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by mails.dpdk.org (Postfix) with ESMTP id 775654026C for ; Thu, 21 Aug 2025 10:13:40 +0200 (CEST) Received: from mail.maildlp.com (unknown [172.19.163.48]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4c6x0Z37Bjz14Mfq; Thu, 21 Aug 2025 16:13:34 +0800 (CST) Received: from kwepemk500009.china.huawei.com (unknown [7.202.194.94]) by mail.maildlp.com (Postfix) with ESMTPS id 92F79180080; Thu, 21 Aug 2025 16:13:38 +0800 (CST) Received: from [10.67.121.161] (10.67.121.161) by kwepemk500009.china.huawei.com (7.202.194.94) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Thu, 21 Aug 2025 16:13:37 +0800 Message-ID: <653e9495-3f76-4226-b88e-7c1a907b4c0c@huawei.com> Date: Thu, 21 Aug 2025 16:13:37 +0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [V5 15/18] net/hinic3: add MML and EEPROM access feature To: Feifei Wang , CC: Xin Wang , Feifei Wang , Yi Chen References: <20250418090621.9638-1-wff_light@vip.163.com> <20250702020953.599-1-wff_light@vip.163.com> <20250702020953.599-16-wff_light@vip.163.com> Content-Language: en-US From: fengchengwen In-Reply-To: <20250702020953.599-16-wff_light@vip.163.com> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Originating-IP: [10.67.121.161] X-ClientProxiedBy: kwepems500001.china.huawei.com (7.221.188.70) To kwepemk500009.china.huawei.com (7.202.194.94) X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org On 7/2/2025 10:09 AM, Feifei Wang wrote: > From: Xin Wang > > > Add man-machine language support and implements the get eeprom method. how about split this commit to two commits? could you explain the mml? and I see the ioctl was not really ioctl, it seem a wrapper. > > > > Signed-off-by: Xin Wang > > Reviewed-by: Feifei Wang > > Reviewed-by: Yi Chen > > --- > > drivers/net/hinic3/hinic3_ethdev.c | 13 + > > drivers/net/hinic3/mml/hinic3_dbg.c | 171 +++++ > > drivers/net/hinic3/mml/hinic3_dbg.h | 160 +++++ > > drivers/net/hinic3/mml/hinic3_mml_cmd.c | 375 +++++++++++ > > drivers/net/hinic3/mml/hinic3_mml_cmd.h | 131 ++++ > > drivers/net/hinic3/mml/hinic3_mml_ioctl.c | 215 +++++++ > > drivers/net/hinic3/mml/hinic3_mml_lib.c | 136 ++++ > > drivers/net/hinic3/mml/hinic3_mml_lib.h | 276 ++++++++ > > drivers/net/hinic3/mml/hinic3_mml_main.c | 167 +++++ > > drivers/net/hinic3/mml/hinic3_mml_queue.c | 745 ++++++++++++++++++++++ > > drivers/net/hinic3/mml/hinic3_mml_queue.h | 256 ++++++++ > > drivers/net/hinic3/mml/meson.build | 62 ++ > > 12 files changed, 2707 insertions(+) > > create mode 100644 drivers/net/hinic3/mml/hinic3_dbg.c > > create mode 100644 drivers/net/hinic3/mml/hinic3_dbg.h > > create mode 100644 drivers/net/hinic3/mml/hinic3_mml_cmd.c > > create mode 100644 drivers/net/hinic3/mml/hinic3_mml_cmd.h > > create mode 100644 drivers/net/hinic3/mml/hinic3_mml_ioctl.c > > create mode 100644 drivers/net/hinic3/mml/hinic3_mml_lib.c > > create mode 100644 drivers/net/hinic3/mml/hinic3_mml_lib.h > > create mode 100644 drivers/net/hinic3/mml/hinic3_mml_main.c > > create mode 100644 drivers/net/hinic3/mml/hinic3_mml_queue.c > > create mode 100644 drivers/net/hinic3/mml/hinic3_mml_queue.h > > create mode 100644 drivers/net/hinic3/mml/meson.build > > > > diff --git a/drivers/net/hinic3/hinic3_ethdev.c b/drivers/net/hinic3/hinic3_ethdev.c > > index 47b47b7412..ac36c49afc 100644 > > --- a/drivers/net/hinic3/hinic3_ethdev.c > > +++ b/drivers/net/hinic3/hinic3_ethdev.c > > @@ -21,6 +21,7 @@ > > #include "base/hinic3_hw_comm.h" > > #include "base/hinic3_nic_cfg.h" > > #include "base/hinic3_nic_event.h" > > +#include "mml/hinic3_mml_lib.h" > > #include "hinic3_nic_io.h" > > #include "hinic3_tx.h" > > #include "hinic3_rx.h" > > @@ -2276,6 +2277,16 @@ hinic3_dev_allmulticast_disable(struct rte_eth_dev *dev) > > return 0; > > } > > > > +static int > > +hinic3_get_eeprom(__rte_unused struct rte_eth_dev *dev, > > + struct rte_dev_eeprom_info *info) > > +{ > > +#define MAX_BUF_OUT_LEN 2048 > > + > > + return hinic3_pmd_mml_lib(info->data, info->offset, info->data, > > + &info->length, MAX_BUF_OUT_LEN); > > +} > > + > > /** > > * Get device generic statistics. > > * > > @@ -2879,6 +2890,7 @@ static const struct eth_dev_ops hinic3_pmd_ops = { > > .vlan_offload_set = hinic3_vlan_offload_set, > > .allmulticast_enable = hinic3_dev_allmulticast_enable, > > .allmulticast_disable = hinic3_dev_allmulticast_disable, > > + .get_eeprom = hinic3_get_eeprom, > > .stats_get = hinic3_dev_stats_get, > > .stats_reset = hinic3_dev_stats_reset, > > .xstats_get = hinic3_dev_xstats_get, > > @@ -2919,6 +2931,7 @@ static const struct eth_dev_ops hinic3_pmd_vf_ops = { > > .vlan_offload_set = hinic3_vlan_offload_set, > > .allmulticast_enable = hinic3_dev_allmulticast_enable, > > .allmulticast_disable = hinic3_dev_allmulticast_disable, > > + .get_eeprom = hinic3_get_eeprom, > > .stats_get = hinic3_dev_stats_get, > > .stats_reset = hinic3_dev_stats_reset, > > .xstats_get = hinic3_dev_xstats_get, > > diff --git a/drivers/net/hinic3/mml/hinic3_dbg.c b/drivers/net/hinic3/mml/hinic3_dbg.c > > new file mode 100644 > > index 0000000000..30051c8e6b > > --- /dev/null > > +++ b/drivers/net/hinic3/mml/hinic3_dbg.c > > @@ -0,0 +1,171 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. > > + */ > > + > > +#include "hinic3_compat.h" > > +#include "hinic3_hwif.h" > > +#include "hinic3_hwdev.h" > > +#include "hinic3_wq.h" > > +#include "hinic3_nic_cfg.h" > > +#include "hinic3_ethdev.h" > > +#include "hinic3_rx.h" > > +#include "hinic3_tx.h" > > +#include "hinic3_nic_io.h" > > +#include "hinic3_dbg.h" > > + > > +#define DB_IDX(db, db_base) \ > > + ((u32)(((ulong)(db) - (ulong)(db_base)) / HINIC3_DB_PAGE_SIZE)) > > + > > +int > > +hinic3_dbg_get_rq_info(void *hwdev, uint16_t q_id, > > + struct hinic3_dbg_rq_info *rq_info, u16 *msg_size) > > +{ > > + struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev; > > + struct hinic3_nic_dev *nic_dev = > > + (struct hinic3_nic_dev *)dev->dev_handle; > > + struct hinic3_rxq *rxq = NULL; > > + > > + if (q_id >= nic_dev->num_rqs) { > > + PMD_DRV_LOG(ERR, "Invalid rx queue id, q_id: %d, num_rqs: %d", > > + q_id, nic_dev->num_rqs); > > + return -EINVAL; > > + } > > + > > + rq_info->q_id = q_id; > > + rxq = nic_dev->rxqs[q_id]; > > + > > + rq_info->hw_pi = (u16)cpu_to_be16(*rxq->pi_virt_addr); > > + rq_info->ci = rxq->cons_idx & rxq->q_mask; > > + rq_info->sw_pi = rxq->prod_idx & rxq->q_mask; > > + rq_info->wqebb_size = HINIC3_SQ_WQEBB_SIZE; > > + rq_info->q_depth = rxq->q_depth; > > + rq_info->buf_len = rxq->buf_len; > > + rq_info->ci_wqe_page_addr = rxq->queue_buf_vaddr; > > + rq_info->ci_cla_tbl_addr = NULL; > > + rq_info->msix_idx = 0; > > + rq_info->msix_vector = 0; > > + > > + *msg_size = sizeof(*rq_info); > > + > > + return 0; > > +} > > + > > +int > > +hinic3_dbg_get_rx_cqe_info(void *hwdev, uint16_t q_id, uint16_t idx, > > + void *buf_out, uint16_t *out_size) > > +{ > > + struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev; > > + struct hinic3_nic_dev *nic_dev = > > + (struct hinic3_nic_dev *)dev->dev_handle; > > + > > + if (q_id >= nic_dev->num_rqs || idx >= nic_dev->rxqs[q_id]->q_depth) > > + return -EFAULT; > > + > > + memcpy(buf_out, (void *)&nic_dev->rxqs[q_id]->rx_cqe[idx], > > + sizeof(struct hinic3_rq_cqe)); > > + *out_size = sizeof(struct hinic3_rq_cqe); > > + > > + return 0; > > +} > > + > > +int > > +hinic3_dbg_get_sq_info(void *dev, u16 q_id, struct hinic3_dbg_sq_info *sq_info, > > + u16 *msg_size) > > +{ > > + struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)dev; > > + struct hinic3_nic_dev *nic_dev = > > + (struct hinic3_nic_dev *)hwdev->dev_handle; > > + struct hinic3_txq *txq = NULL; > > + > > + if (q_id >= nic_dev->num_sqs) { > > + PMD_DRV_LOG(ERR, > > + "Inputting tx queue id is larger than actual tx " > > + "queue number, qid: %d, num_sqs: %d", > > + q_id, nic_dev->num_sqs); > > + return -EINVAL; > > + } > > + > > + sq_info->q_id = q_id; > > + txq = nic_dev->txqs[q_id]; > > + > > + sq_info->pi = txq->prod_idx & txq->q_mask; > > + sq_info->ci = txq->cons_idx & txq->q_mask; > > + sq_info->fi = (*(volatile u16 *)txq->ci_vaddr_base) & txq->q_mask; > > + sq_info->q_depth = txq->q_depth; > > + sq_info->weqbb_size = HINIC3_SQ_WQEBB_SIZE; > > + sq_info->ci_addr = > > + (volatile u16 *)HINIC3_CI_VADDR(txq->ci_vaddr_base, q_id); > > + sq_info->cla_addr = txq->queue_buf_paddr; > > + sq_info->db_addr.phy_addr = (u64 *)txq->db_addr; > > + sq_info->pg_idx = DB_IDX(txq->db_addr, hwdev->hwif->db_base); > > + > > + *msg_size = sizeof(*sq_info); > > + > > + return 0; > > +} > > + > > +int > > +hinic3_dbg_get_sq_wqe_info(void *dev, u16 q_id, u16 idx, u16 wqebb_cnt, u8 *wqe, > > + u16 *wqe_size) > > +{ > > + struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)dev; > > + struct hinic3_nic_dev *nic_dev = > > + (struct hinic3_nic_dev *)hwdev->dev_handle; > > + struct hinic3_txq *txq = NULL; > > + void *src_wqe = NULL; > > + u32 offset; > > + > > + if (q_id >= nic_dev->num_sqs) { > > + PMD_DRV_LOG(ERR, > > + "Inputting tx queue id is larger than actual tx " > > + "queue number, qid: %d, num_sqs: %d", > > + q_id, nic_dev->num_sqs); > > + return -EINVAL; > > + } > > + > > + txq = nic_dev->txqs[q_id]; > > + if (idx + wqebb_cnt > txq->q_depth) > > + return -EFAULT; > > + > > + src_wqe = (void *)txq->queue_buf_vaddr; > > + offset = (u32)idx << txq->wqebb_shift; > > + > > + memcpy((void *)wqe, (void *)((u8 *)src_wqe + offset), > > + (size_t)((u32)wqebb_cnt << txq->wqebb_shift)); > > + > > + *wqe_size = (u16)((u32)wqebb_cnt << txq->wqebb_shift); > > + return 0; > > +} > > + > > +int > > +hinic3_dbg_get_rq_wqe_info(void *dev, u16 q_id, u16 idx, u16 wqebb_cnt, u8 *wqe, > > + u16 *wqe_size) > > +{ > > + struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)dev; > > + struct hinic3_nic_dev *nic_dev = > > + (struct hinic3_nic_dev *)hwdev->dev_handle; > > + struct hinic3_rxq *rxq = NULL; > > + void *src_wqe = NULL; > > + u32 offset; > > + > > + if (q_id >= nic_dev->num_rqs) { > > + PMD_DRV_LOG(ERR, > > + "Inputting rx queue id is larger than actual rx " > > + "queue number, qid: %d, num_rqs: %d", > > + q_id, nic_dev->num_rqs); > > + return -EINVAL; > > + } > > + > > + rxq = nic_dev->rxqs[q_id]; > > + if (idx + wqebb_cnt > rxq->q_depth) > > + return -EFAULT; > > + > > + src_wqe = (void *)rxq->queue_buf_vaddr; > > + offset = (u32)idx << rxq->wqebb_shift; > > + > > + memcpy((void *)wqe, (void *)((u8 *)src_wqe + offset), > > + (size_t)((u32)wqebb_cnt << rxq->wqebb_shift)); > > + > > + *wqe_size = (u16)((u32)wqebb_cnt << rxq->wqebb_shift); > > + return 0; > > +} > > diff --git a/drivers/net/hinic3/mml/hinic3_dbg.h b/drivers/net/hinic3/mml/hinic3_dbg.h > > new file mode 100644 > > index 0000000000..bac96c84a0 > > --- /dev/null > > +++ b/drivers/net/hinic3/mml/hinic3_dbg.h > > @@ -0,0 +1,160 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. > > + */ > > + > > +#ifndef _HINIC3_MML_DBG_H > > +#define _HINIC3_MML_DBG_H > > + > > +/* nic_tool */ > > +struct hinic3_tx_hw_page { > > + u64 *phy_addr; > > + u64 *map_addr; > > +}; > > + > > +/* nic_tool */ > > +struct hinic3_dbg_sq_info { > > + u16 q_id; > > + u16 pi; > > + u16 ci; /**< sw_ci */ > > + u16 fi; /**< hw_ci */ > > + > > + u32 q_depth; > > + u16 weqbb_size; > > + > > + volatile u16 *ci_addr; > > + u64 cla_addr; > > + > > + struct hinic3_tx_hw_page db_addr; > > + u32 pg_idx; > > +}; > > + > > +/* nic_tool */ > > +struct hinic3_dbg_rq_info { > > + u16 q_id; > > + u16 hw_pi; > > + u16 ci; /**< sw_ci */ > > + u16 sw_pi; > > + u16 wqebb_size; > > + u16 q_depth; > > + u16 buf_len; > > + > > + void *ci_wqe_page_addr; > > + void *ci_cla_tbl_addr; > > + u16 msix_idx; > > + u32 msix_vector; > > +}; > > + > > +void *hinic3_dbg_get_sq_wq_handle(void *hwdev, u16 q_id); > > + > > +void *hinic3_dbg_get_rq_wq_handle(void *hwdev, u16 q_id); > > + > > +void *hinic3_dbg_get_sq_ci_addr(void *hwdev, u16 q_id); > > + > > +u16 hinic3_dbg_get_global_qpn(void *hwdev); > > + > > +/** > > + * Get details of specified RX queue and store in `rq_info`. > > + * > > + * @param[in] hwdev > > + * Pointer to the hardware device. > > + * @param[in] q_id > > + * RX queue ID. > > + * @param[out] rq_info > > + * Structure to store RX queue information. > > + * @param[out] msg_size > > + * Size of the message. > > + * > > + * @return > > + * 0 on success, non-zero on failure. > > + */ > > +int hinic3_dbg_get_rq_info(void *hwdev, uint16_t q_id, > > + struct hinic3_dbg_rq_info *rq_info, u16 *msg_size); > > + > > +/** > > + * Get the RX CQE at the specified index from the given RX queue. > > + * > > + * @param[in] hwdev > > + * Pointer to hardware device structure. > > + * @param[in] q_id > > + * RX queue ID. > > + * @param[in] idx > > + * Index of the CQE. > > + * @param[out] buf_out > > + * Buffer to store the CQE. > > + * @param[out] out_size > > + * Size of the CQE. > > + * > > + * @return > > + * 0 on success, non-zero on failure. > > + */ > > +int hinic3_dbg_get_rx_cqe_info(void *hwdev, uint16_t q_id, uint16_t idx, > > + void *buf_out, uint16_t *out_size); > > + > > +/** > > + * Get SQ information for debugging. > > + * > > + * @param[in] dev > > + * Pointer to ethernet device structure. > > + * @param[in] q_id > > + * ID of SQ to retrieve information for. > > + * @param[out] sq_info > > + * Pointer to the structure where the SQ information will be stored. > > + * @param[out] msg_size > > + * The size (in bytes) of the `sq_info` structure. > > + * > > + * @return > > + * 0 on success, non-zero on failure. > > + * - -EINVAL if the queue ID is invalid. > > + */ > > +int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, > > + struct hinic3_dbg_sq_info *sq_info, u16 *msg_size); > > + > > +/** > > + * Get WQE information from a send queue. > > + * > > + * @param[in] dev > > + * Pointer to ethernet device structure. > > + * @param[in] q_id > > + * The ID of the send queue from which to retrieve WQE information. > > + * @param[in] idx > > + * The index of the first WQE to retrieve. > > + * @param[in] wqebb_cnt > > + * The number of WQEBBs to retrieve. > > + * @param[out] wqe > > + * Pointer to the buffer where the WQE data will be stored. > > + * @param[out] wqe_size > > + * The size (in bytes) of the retrieved WQE data. > > + * > > + * @return > > + * 0 on success, non-zero on failure. > > + * - -EINVAL if queue ID invalid. > > + * - -EFAULT if index invalid. > > + */ > > +int hinic3_dbg_get_sq_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt, > > + u8 *wqe, u16 *wqe_size); > > + > > +/** > > + * Get WQE information from a receive queue. > > + * > > + * @param[in] dev > > + * Pointer to the device structure. > > + * @param[in] q_id > > + * The ID of the receive queue from which to retrieve WQE information. > > + * @param[in] idx > > + * The index of the first WQE to retrieve. > > + * @param[in] wqebb_cnt > > + * The number of WQEBBs to retrieve. > > + * @param[out] wqe > > + * Pointer to the buffer where the WQE data will be stored. > > + * @param[out] wqe_size > > + * The size (in bytes) of the retrieved WQE data. > > + * > > + * @return > > + * 0 on success, non-zero on failure. > > + * - -EINVAL if queue ID invalid. > > + * - -EFAULT if index invalid. > > + */ > > +int hinic3_dbg_get_rq_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt, > > + u8 *wqe, u16 *wqe_size); > > + > > +#endif /* _HINIC3_MML_DBG_H */ > > diff --git a/drivers/net/hinic3/mml/hinic3_mml_cmd.c b/drivers/net/hinic3/mml/hinic3_mml_cmd.c > > new file mode 100644 > > index 0000000000..797952b8c0 > > --- /dev/null > > +++ b/drivers/net/hinic3/mml/hinic3_mml_cmd.c > > @@ -0,0 +1,375 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. > > + */ > > + > > +#include "hinic3_mml_lib.h" > > +#include "hinic3_compat.h" > > +#include "hinic3_hwdev.h" > > +#include "hinic3_nic_cfg.h" > > +#include "hinic3_ethdev.h" > > +#include "hinic3_mml_cmd.h" > > + > > +/** > > + * Compares two strings for equality. > > + * > > + * @param[in] command > > + * The first string to compare. > > + * @param[in] argument > > + * The second string to compare. > > + * > > + * @return > > + * UDA_TRUE if the strings are equal, otherwise UDA_FALSE. > > + */ > > +static int > > +string_cmp(const char *command, const char *argument) > > +{ > > + const char *cmd = command; > > + const char *arg = argument; > > + > > + if (!cmd || !arg) > > + return UDA_FALSE; > > + > > + if (strlen(cmd) != strlen(arg)) > > + return UDA_FALSE; > > + > > + do { > > + if (*cmd != *arg) > > + return UDA_FALSE; > > + cmd++; > > + arg++; > > + } while (*cmd != '\0'); > > + > > + return UDA_TRUE; > > +} > > + > > +static void > > +show_tool_version(cmd_adapter_t *adapter) > > +{ > > + hinic3_pmd_mml_log(adapter->show_str, &adapter->show_len, > > + "hinic3 pmd version %s", HINIC3_PMD_DRV_VERSION); > > +} > > + > > +static void > > +show_tool_help(cmd_adapter_t *adapter) > > +{ > > + int i; > > + major_cmd_t *major_cmd = NULL; > > + > > + if (!adapter) > > + return; > > + > > + hinic3_pmd_mml_log(adapter->show_str, &adapter->show_len, > > + "\n Usage:evsadm exec dump-hinic-status " > > + "[option]\n"); > > + hinic3_pmd_mml_log(adapter->show_str, &adapter->show_len, > > + " -h, --help show help information"); > > + hinic3_pmd_mml_log(adapter->show_str, &adapter->show_len, > > + " -v, --version show version information"); > > + hinic3_pmd_mml_log(adapter->show_str, &adapter->show_len, > > + "\n Major Commands:\n"); > > + > > + for (i = 0; i < adapter->major_cmds; i++) { > > + major_cmd = adapter->p_major_cmd[i]; > > + hinic3_pmd_mml_log(adapter->show_str, &adapter->show_len, > > + " %-23s %s", major_cmd->name, > > + major_cmd->description); > > + } > > + hinic3_pmd_mml_log(adapter->show_str, &adapter->show_len, "\n"); > > +} > > + > > +void > > +major_command_option(major_cmd_t *major_cmd, const char *little, > > + const char *large, uint32_t have_param, > > + command_record_t record) > > +{ > > + cmd_option_t *option = NULL; > > + > > + if (major_cmd == NULL || (little == NULL && large == NULL) || !record) { > > + PMD_DRV_LOG(ERR, "Invalid input parameter."); > > + return; > > + } > > + > > + if (major_cmd->option_count >= COMMAND_MAX_OPTIONS) { > > + PMD_DRV_LOG(ERR, "Do not support more than %d options", > > + COMMAND_MAX_OPTIONS); > > + return; > > + } > > + > > + option = &major_cmd->options[major_cmd->option_count]; > > + major_cmd->options_repeat_flag[major_cmd->option_count] = 0; > > + major_cmd->option_count++; > > + > > + option->record = record; > > + option->little = little; > > + option->large = large; > > + option->have_param = have_param; > > +} > > + > > +void > > +major_command_register(cmd_adapter_t *adapter, major_cmd_t *major_cmd) > > +{ > > + int i = 0; > > + > > + if (adapter == NULL || major_cmd == NULL) { > > + PMD_DRV_LOG(ERR, "Invalid input parameter."); > > + return; > > + } > > + > > + if (adapter->major_cmds >= COMMAND_MAX_MAJORS) { > > + PMD_DRV_LOG(ERR, "Major Commands is full"); > > + return; > > + } > > + while (adapter->p_major_cmd[i] != NULL) > > + i++; > > + adapter->p_major_cmd[i] = major_cmd; > > + adapter->major_cmds++; > > + major_cmd->adapter = adapter; > > + major_cmd->err_no = UDA_SUCCESS; > > + memset(major_cmd->err_str, 0, sizeof(major_cmd->err_str)); > > +} > > + > > +static int > > +is_help_version(cmd_adapter_t *adapter, int argc, char *arg) > > +{ > > + if (COMMAND_HELP_POSITION(argc) && > > + (string_cmp("-h", arg) || string_cmp("--help", arg))) { > > + show_tool_help(adapter); > > + return UDA_TRUE; > > + } > > + > > + if (COMMAND_VERSION_POSITION(argc) && > > + (string_cmp("-v", arg) || string_cmp("--version", arg))) { > > + show_tool_version(adapter); > > + return UDA_TRUE; > > + } > > + > > + return UDA_FALSE; > > +} > > + > > +static int > > +check_command_length(int argc, char **argv) > > +{ > > + int i; > > + unsigned long long str_len = 0; > > + > > + for (i = 1; i < argc; i++) > > + str_len += strlen(argv[i]); > > + > > + if (str_len > COMMAND_MAX_STRING) > > + return -UDA_EINVAL; > > + > > + return UDA_SUCCESS; > > +} > > + > > +static inline int > > +char_check(const char cmd) > > +{ > > + if (cmd >= 'a' && cmd <= 'z') > > + return UDA_SUCCESS; > > + > > + if (cmd >= 'A' && cmd <= 'Z') > > + return UDA_SUCCESS; > > + return UDA_FAIL; > > +} > > + > > +static int > > +major_command_check_param(cmd_option_t *option, char *arg) > > +{ > > + if (!option) > > + return -UDA_EINVAL; > > + if (option->have_param != 0) { > > + if (!arg || ((arg[0] == '-') && char_check(arg[1]))) > > + return -UDA_EINVAL; > > + return UDA_SUCCESS; > > + } > > + > > + return -UDA_ENOOBJ; > > +} > > + > > +static int > > +major_cmd_repeat_option_set(major_cmd_t *major_cmd, const cmd_option_t *option, > > + u32 *options_repeat_flag) > > +{ > > + int err; > > + > > + if (*options_repeat_flag != 0) { > > + major_cmd->err_no = -UDA_EINVAL; > > + err = snprintf(major_cmd->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Repeated option %s|%s.", option->little, > > + option->large); > > + if (err <= 0) { > > + PMD_DRV_LOG(ERR, > > + "snprintf cmd repeat option failed, err: %d.", > > + err); > > + } > > + return -UDA_EINVAL; > > + } > > + *options_repeat_flag = 1; > > + return UDA_SUCCESS; > > +} > > + > > +static int > > +major_cmd_option_check(major_cmd_t *major_cmd, char **argv, int *index) > > +{ > > + int j, ret, err, option_ok, intermediate_var; > > + cmd_option_t *option = NULL; > > + char *arg = argv[*index]; > > + > > + /* Find command. */ > > + for (j = 0; j < major_cmd->option_count; j++) { > > + option = &major_cmd->options[j]; > > + option_ok = (((option->little != NULL) && > > + string_cmp(option->little, arg)) || > > + ((option->large != NULL) && > > + string_cmp(option->large, arg))); > > + if (!option_ok) > > + continue; > > + /* Find same option. */ > > + ret = major_cmd_repeat_option_set(major_cmd, > > + option, &major_cmd->options_repeat_flag[j]); > > + if (ret != UDA_SUCCESS) > > + return ret; > > + > > + arg = NULL; > > + /* If this option need parameters. */ > > + intermediate_var = (*index) + 1; > > + ret = major_command_check_param(option, argv[intermediate_var]); > > + if (ret == UDA_SUCCESS) { > > + (*index)++; > > + arg = argv[*index]; > > + } else if (ret == -UDA_EINVAL) { > > + major_cmd->err_no = -UDA_EINVAL; > > + err = snprintf(major_cmd->err_str, > > + COMMANDER_ERR_MAX_STRING - 1, > > + "%s|%s option need parameter.", > > + option->little, option->large); > > + if (err <= 0) { > > + PMD_DRV_LOG(ERR, > > + "snprintf cmd option need para " > > + "failed, err: %d.", > > + err); > > + } > > + return -UDA_EINVAL; > > + } > > + > > + /* Record messages. */ > > + ret = option->record(major_cmd, arg); > > + if (ret != UDA_SUCCESS) > > + return ret; > > + break; > > + } > > + > > + /* Illegal option. */ > > + if (j == major_cmd->option_count) { > > + major_cmd->err_no = -UDA_EINVAL; > > + err = snprintf(major_cmd->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "%s is not option needed.", arg); > > + if (err <= 0) { > > + PMD_DRV_LOG(ERR, > > + "snprintf cmd option invalid failed, err: %d.", > > + err); > > + } > > + return -UDA_EINVAL; > > + } > > + return UDA_SUCCESS; > > +} > > + > > +static int > > +major_command_parse(major_cmd_t *major_cmd, int argc, char **argv) > > +{ > > + int i, err; > > + > > + for (i = 0; i < argc; i++) { > > + err = major_cmd_option_check(major_cmd, argv, &i); > > + if (err != UDA_SUCCESS) > > + return err; > > + } > > + > > + return UDA_SUCCESS; > > +} > > + > > +static int > > +copy_result_to_buffer(void *buf_out, char *result, int len) > > +{ > > + int ret; > > + > > + ret = snprintf(buf_out, len - 1, "%s", result); > > + if (ret <= 0) > > + return 0; > > + > > + return ret + 1; > > +} > > + > > +void > > +command_parse(cmd_adapter_t *adapter, int argc, char **argv, void *buf_out, > > + uint32_t *out_len) > > +{ > > + int i; > > + major_cmd_t *major_cmd = NULL; > > + char *arg = argv[1]; > > + > > + if (is_help_version(adapter, argc, arg) == UDA_TRUE) { > > + *out_len = (u32)copy_result_to_buffer(buf_out, > > + adapter->show_str, MAX_SHOW_STR_LEN); > > + return; > > + } > > + > > + for (i = 0; i < adapter->major_cmds; i++) { > > + major_cmd = adapter->p_major_cmd[i]; > > + > > + /* Find major command. */ > > + if (!string_cmp(major_cmd->name, arg)) > > + continue; > > + if (check_command_length(argc, argv) != UDA_SUCCESS) { > > + major_cmd->err_no = -UDA_EINVAL; > > + snprintf(major_cmd->err_str, > > + COMMANDER_ERR_MAX_STRING - 1, > > + "Command input too long."); > > + break; > > + } > > + > > + /* Deal sub command. */ > > + if (argc > SUB_COMMAND_OFFSET) { > > + if (major_command_parse(major_cmd, > > + argc - SUB_COMMAND_OFFSET, > > + argv + SUB_COMMAND_OFFSET) != UDA_SUCCESS) { > > + goto PARSE_OUT; > > + } > > + } > > + > > + /* Command exec. */ > > + major_cmd->execute(major_cmd); > > + break; > > + } > > + > > + /* Not find command. */ > > + if (i == adapter->major_cmds) { > > + hinic3_pmd_mml_log(adapter->show_str, &adapter->show_len, > > + "Unknown major command, assign 'evsadm exec " > > + "dump-hinic-status -h' for help."); > > + *out_len = (u32)copy_result_to_buffer(buf_out, > > + adapter->show_str, MAX_SHOW_STR_LEN); > > + return; > > + } > > + > > +PARSE_OUT: > > + if (major_cmd->err_no != UDA_SUCCESS && > > + major_cmd->err_no != -UDA_CANCEL) { > > + PMD_DRV_LOG(ERR, "%s command error(%d): %s", major_cmd->name, > > + major_cmd->err_no, major_cmd->err_str); > > + > > + hinic3_pmd_mml_log(major_cmd->show_str, &major_cmd->show_len, > > + "%s command error(%d): %s", > > + major_cmd->name, major_cmd->err_no, > > + major_cmd->err_str); > > + } > > + *out_len = (u32)copy_result_to_buffer(buf_out, major_cmd->show_str, > > + MAX_SHOW_STR_LEN); > > +} > > + > > +void > > +tool_target_init(int *bus_num, char *dev_name, int len) > > +{ > > + *bus_num = TRGET_UNKNOWN_BUS_NUM; > > + memset(dev_name, 0, len); > > +} > > diff --git a/drivers/net/hinic3/mml/hinic3_mml_cmd.h b/drivers/net/hinic3/mml/hinic3_mml_cmd.h > > new file mode 100644 > > index 0000000000..b9c32441b5 > > --- /dev/null > > +++ b/drivers/net/hinic3/mml/hinic3_mml_cmd.h > > @@ -0,0 +1,131 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. > > + */ > > + > > +#ifndef _HINIC3_MML_CMD > > +#define _HINIC3_MML_CMD > > + > > +#include > > + > > +#define COMMAND_HELP_POSITION(argc) \ > > + ({ \ > > + typeof(argc) __argc = (argc); \ > > + (__argc == 1 || __argc == 2); \ > > + }) > > +#define COMMAND_VERSION_POSITION(argc) ((argc) == 2) > > +#define SUB_COMMAND_OFFSET 2 > > + > > +#define COMMAND_MAX_MAJORS 128 > > +#define COMMAND_MAX_OPTIONS 64 > > +#define PARAM_MAX_STRING 128 > > +#define COMMAND_MAX_STRING 512 > > +#define COMMANDER_ERR_MAX_STRING 128 > > + > > +#define MAX_NAME_LEN 32 > > +#define MAX_DES_LEN 128 > > +#define MAX_SHOW_STR_LEN 2048 > > + > > +struct tag_major_cmd_t; > > +struct tag_cmd_adapter_t; > > + > > +typedef int (*command_record_t)(struct tag_major_cmd_t *major, char *param); > > +typedef void (*command_executeute_t)(struct tag_major_cmd_t *major); > > + > > +typedef struct { > > + const char *little; > > + const char *large; > > + unsigned int have_param; > > + command_record_t record; > > +} cmd_option_t; > > + > > +/* Major command structure for save command details and options. */ > > +typedef struct tag_major_cmd_t { > > + struct tag_cmd_adapter_t *adapter; > > + char name[MAX_NAME_LEN]; > > + int option_count; > > + cmd_option_t options[COMMAND_MAX_OPTIONS]; > > + uint32_t options_repeat_flag[COMMAND_MAX_OPTIONS]; > > + command_executeute_t execute; > > + int err_no; > > + char err_str[COMMANDER_ERR_MAX_STRING]; > > + char show_str[MAX_SHOW_STR_LEN]; > > + int show_len; > > + char description[MAX_DES_LEN]; > > + void *cmd_st; /**< Command show queue state structure. */ > > +} major_cmd_t; > > + > > +typedef struct tag_cmd_adapter_t { > > + const char *name; > > + const char *version; > > + major_cmd_t *p_major_cmd[COMMAND_MAX_MAJORS]; > > + int major_cmds; > > + char show_str[MAX_SHOW_STR_LEN]; > > + int show_len; > > + char *cmd_buf; > > +} cmd_adapter_t; > > + > > +/** > > + * Add an option to a major command. > > + * > > + * This function adds a command option with its short and long forms, whether it > > + * requires a parameter, and the function to handle it. > > + * > > + * @param[in] major_cmd > > + * Pointer to the major command structure. > > + * @param[in] little > > + * Short form of the option. > > + * @param[in] large > > + * Long form of the option. > > + * @param[in] have_param > > + * Flag indicating whether the option requires a parameter. > > + * @param[in] record > > + * Function to handle the option's action. > > + */ > > +void major_command_option(major_cmd_t *major_cmd, const char *little, > > + const char *large, uint32_t have_param, > > + command_record_t record); > > + > > +/** > > + * Register a major command with adapter. > > + * > > + * @param[in] adapter > > + * Pointer to command adapter. > > + * @param[in] major_cmd > > + * The major command to be registered with the adapter. > > + */ > > +void major_command_register(cmd_adapter_t *adapter, major_cmd_t *major_cmd); > > + > > +/** > > + * Parse and execute commands. > > + * > > + * @param[in] adapter > > + * Pointer to command adapter. > > + * @param[in] argc > > + * The number of command arguments. > > + * @param[in] argv > > + * The array of command arguments. > > + * @param[out] buf_out > > + * The buffer used to store the output result. > > + * @param[out] out_len > > + * The length (in bytes) of the output result. > > + */ > > +void command_parse(cmd_adapter_t *adapter, int argc, char **argv, void *buf_out, > > + uint32_t *out_len); > > + > > +/** > > + * Initialize the target bus number and device name. > > + * > > + * @param[out] bus_num > > + * Pointer to the bus number, which will be set to a default unknown value. > > + * @param[out] dev_name > > + * Pointer to the device name buffer, which will be cleared (set to zeros). > > + * @param[in] len > > + * The length of the device name buffer. > > + */ > > +void tool_target_init(int *bus_num, char *dev_name, int len); > > + > > +int cmd_show_q_init(cmd_adapter_t *adapter); > > +int cmd_show_xstats_init(cmd_adapter_t *adapter); > > +int cmd_show_dump_init(cmd_adapter_t *adapter); > > + > > +#endif /* _HINIC3_MML_CMD */ > > diff --git a/drivers/net/hinic3/mml/hinic3_mml_ioctl.c b/drivers/net/hinic3/mml/hinic3_mml_ioctl.c > > new file mode 100644 > > index 0000000000..e0ae558f05 > > --- /dev/null > > +++ b/drivers/net/hinic3/mml/hinic3_mml_ioctl.c > > @@ -0,0 +1,215 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. > > + */ > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include "hinic3_mml_lib.h" > > +#include "hinic3_dbg.h" > > +#include "hinic3_compat.h" > > +#include "hinic3_csr.h" > > +#include "hinic3_hwdev.h" > > +#include "hinic3_nic_cfg.h" > > +#include "hinic3_ethdev.h" > > + > > +static int > > +get_tx_info(struct rte_eth_dev *dev, void *buf_in, uint16_t in_size, > > + void *buf_out, uint16_t *out_size) > > +{ > > + uint16_t q_id = *((uint16_t *)buf_in); > > + struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); > > + > > + if (in_size != sizeof(int)) > > + return -UDA_EINVAL; > > + > > + return hinic3_dbg_get_sq_info(nic_dev->hwdev, q_id, buf_out, out_size); > > +} > > + > > +static int > > +get_tx_wqe_info(struct rte_eth_dev *dev, void *buf_in, uint16_t in_size, > > + void *buf_out, uint16_t *out_size) > > +{ > > + struct hinic_wqe_info *wqe_info = (struct hinic_wqe_info *)buf_in; > > + uint16_t q_id = (uint16_t)wqe_info->q_id; > > + uint16_t idx = (uint16_t)wqe_info->wqe_id; > > + uint16_t wqebb_cnt = (uint16_t)wqe_info->wqebb_cnt; > > + struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); > > + > > + if (in_size != sizeof(struct hinic_wqe_info)) > > + return -UDA_EINVAL; > > + > > + return hinic3_dbg_get_sq_wqe_info(nic_dev->hwdev, q_id, idx, wqebb_cnt, > > + buf_out, out_size); > > +} > > + > > +static int > > +get_rx_info(struct rte_eth_dev *dev, void *buf_in, uint16_t in_size, > > + void *buf_out, uint16_t *out_size) > > +{ > > + uint16_t q_id = *((uint16_t *)buf_in); > > + struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); > > + > > + if (in_size != sizeof(int)) > > + return -UDA_EINVAL; > > + > > + return hinic3_dbg_get_rq_info(nic_dev->hwdev, q_id, buf_out, out_size); > > +} > > + > > +static int > > +get_rx_wqe_info(struct rte_eth_dev *dev, void *buf_in, uint16_t in_size, > > + void *buf_out, uint16_t *out_size) > > +{ > > + struct hinic_wqe_info *wqe_info = (struct hinic_wqe_info *)buf_in; > > + uint16_t q_id = (uint16_t)wqe_info->q_id; > > + uint16_t idx = (uint16_t)wqe_info->wqe_id; > > + uint16_t wqebb_cnt = (uint16_t)wqe_info->wqebb_cnt; > > + struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); > > + > > + if (in_size != sizeof(struct hinic_wqe_info)) > > + return -UDA_EINVAL; > > + > > + return hinic3_dbg_get_rq_wqe_info(nic_dev->hwdev, q_id, idx, wqebb_cnt, > > + buf_out, out_size); > > +} > > + > > +static int > > +get_rx_cqe_info(struct rte_eth_dev *dev, void *buf_in, uint16_t in_size, > > + void *buf_out, uint16_t *out_size) > > +{ > > + struct hinic_wqe_info *wqe_info = (struct hinic_wqe_info *)buf_in; > > + uint16_t q_id = (uint16_t)wqe_info->q_id; > > + uint16_t idx = (uint16_t)wqe_info->wqe_id; > > + struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); > > + > > + if (in_size != sizeof(struct hinic_wqe_info)) > > + return -UDA_EINVAL; > > + > > + return hinic3_dbg_get_rx_cqe_info(nic_dev->hwdev, q_id, idx, buf_out, > > + out_size); > > +} > > + > > +typedef int (*nic_drv_module)(struct rte_eth_dev *dev, void *buf_in, > > + uint16_t in_size, void *buf_out, > > + uint16_t *out_size); > > + > > +struct nic_drv_module_handle { > > + enum driver_cmd_type drv_cmd_name; > > + nic_drv_module drv_func; > > +}; > > + > > +const struct nic_drv_module_handle g_nic_drv_module_cmd_handle[] = { > > + {TX_INFO, get_tx_info}, {TX_WQE_INFO, get_tx_wqe_info}, > > + {RX_INFO, get_rx_info}, {RX_WQE_INFO, get_rx_wqe_info}, > > + {RX_CQE_INFO, get_rx_cqe_info}, > > +}; > > + > > +static int > > +send_to_nic_driver(struct rte_eth_dev *dev, struct msg_module *nt_msg) > > +{ > > + int index; > > + int err = 0; > > + enum driver_cmd_type cmd_type = > > + (enum driver_cmd_type)nt_msg->msg_format; > > + int num_cmds = sizeof(g_nic_drv_module_cmd_handle) / > > + sizeof(g_nic_drv_module_cmd_handle[0]); > > + > > + for (index = 0; index < num_cmds; index++) { > > + if (cmd_type == > > + g_nic_drv_module_cmd_handle[index].drv_cmd_name) { > > + err = g_nic_drv_module_cmd_handle[index].drv_func(dev, > > + nt_msg->in_buf, > > + (uint16_t)nt_msg->buf_in_size, nt_msg->out_buf, > > + (uint16_t *)&nt_msg->buf_out_size); > > + break; > > + } > > + } > > + > > + if (index == num_cmds) { > > + PMD_DRV_LOG(ERR, "Unknown nic driver cmd: %d", cmd_type); > > + err = -UDA_EINVAL; > > + } > > + > > + return err; > > +} > > + > > +static int > > +hinic3_msg_handle(struct rte_eth_dev *dev, struct msg_module *nt_msg) > > +{ > > + int err; > > + > > + switch (nt_msg->module) { > > + case SEND_TO_NIC_DRIVER: > > + err = send_to_nic_driver(dev, nt_msg); > > + if (err != 0) > > + PMD_DRV_LOG(ERR, "Send message to driver failed"); > > + break; > > + default: > > + PMD_DRV_LOG(ERR, "Unknown message module: %d", nt_msg->module); > > + err = -UDA_EINVAL; > > + break; > > + } > > + > > + return err; > > +} > > + > > +static struct rte_eth_dev * > > +get_eth_dev_by_pci_addr(char *pci_addr, __rte_unused int len) > > +{ > > + uint32_t i; > > + struct rte_eth_dev *eth_dev = NULL; > > + struct rte_pci_device *pci_dev = NULL; > > + int ret; > > + uint32_t bus, devid, function; > > + > > + ret = sscanf(pci_addr, "%02x:%02x.%x", &bus, &devid, &function); > > + if (ret <= 0) { > > + PMD_DRV_LOG(ERR, > > + "Get pci bus devid and function id fail, err: %d", > > + ret); > > + return NULL; > > + } > > + > > + for (i = 0; i < RTE_MAX_ETHPORTS; i++) { > > + eth_dev = &rte_eth_devices[i]; > > + if (eth_dev->state != RTE_ETH_DEV_ATTACHED) > > + continue; > > + > > + pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); > > + > > +#ifdef CONFIG_SP_VID_DID > > + if (pci_dev->id.vendor_id == PCI_VENDOR_ID_SPNIC && > > + (pci_dev->id.device_id == HINIC3_DEV_ID_STANDARD || > > + pci_dev->id.device_id == HINIC3_DEV_ID_VF) && > > +#else > > + if (pci_dev->id.vendor_id == PCI_VENDOR_ID_HUAWEI && > > + (pci_dev->id.device_id == HINIC3_DEV_ID_STANDARD || > > + pci_dev->id.device_id == HINIC3_DEV_ID_VF) && > > +#endif > > + pci_dev->addr.bus == bus && pci_dev->addr.devid == devid && > > + pci_dev->addr.function == function) { > > + return eth_dev; > > + } > > + } > > + > > + return NULL; > > +} > > + > > +int > > +hinic3_pmd_mml_ioctl(void *msg) > > +{ > > + struct msg_module *nt_msg = msg; > > + struct rte_eth_dev *dev; > > + > > + dev = get_eth_dev_by_pci_addr(nt_msg->device_name, > > + sizeof(nt_msg->device_name)); > > + if (!dev) { > > + PMD_DRV_LOG(ERR, "Can not get the device %s correctly", > > + nt_msg->device_name); > > + return UDA_FAIL; > > + } > > + > > + return hinic3_msg_handle(dev, nt_msg); > > +} > > diff --git a/drivers/net/hinic3/mml/hinic3_mml_lib.c b/drivers/net/hinic3/mml/hinic3_mml_lib.c > > new file mode 100644 > > index 0000000000..c74777f50b > > --- /dev/null > > +++ b/drivers/net/hinic3/mml/hinic3_mml_lib.c > > @@ -0,0 +1,136 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. > > + */ > > +#include "hinic3_compat.h" > > +#include "hinic3_mml_lib.h" > > + > > +int > > +tool_get_valid_target(char *name, struct tool_target *target) > > +{ > > + int ret = UDA_SUCCESS; > > + > > + if (strlen(name) >= MAX_DEV_LEN) { > > + PMD_DRV_LOG(ERR, > > + "Input parameter of device name is too long."); > > + ret = -UDA_ELEN; > > + } else { > > + memcpy(target->dev_name, name, strlen(name)); > > + target->bus_num = 0; > > + } > > + > > + return ret; > > +} > > + > > +static void > > +fill_ioctl_msg_hd(struct msg_module *msg, unsigned int module, > > + unsigned int msg_format, unsigned int in_buff_len, > > + unsigned int out_buff_len, char *dev_name, int bus_num) > > +{ > > + memcpy(msg->device_name, dev_name, strlen(dev_name) + 1); > > + > > + msg->module = module; > > + msg->msg_format = msg_format; > > + msg->buf_in_size = in_buff_len; > > + msg->buf_out_size = out_buff_len; > > + msg->bus_num = bus_num; > > +} > > + > > +static int > > +lib_ioctl(struct msg_module *in_buf, void *out_buf) > > +{ > > + in_buf->out_buf = out_buf; > > + > > + return hinic3_pmd_mml_ioctl(in_buf); > > +} > > + > > +int > > +lib_tx_sq_info_get(struct tool_target target, struct nic_sq_info *sq_info, > > + int sq_id) > > +{ > > + struct msg_module msg_to_kernel; > > + > > + memset(&msg_to_kernel, 0, sizeof(msg_to_kernel)); > > + fill_ioctl_msg_hd(&msg_to_kernel, SEND_TO_NIC_DRIVER, TX_INFO, > > + (unsigned int)sizeof(int), > > + (unsigned int)sizeof(struct nic_sq_info), > > + target.dev_name, target.bus_num); > > + msg_to_kernel.in_buf = (void *)&sq_id; > > + > > + return lib_ioctl(&msg_to_kernel, sq_info); > > +} > > + > > +int > > +lib_tx_wqe_info_get(struct tool_target target, struct nic_sq_info *sq_info, > > + int sq_id, int wqe_id, void *nwqe, int nwqe_size) > > +{ > > + struct msg_module msg_to_kernel; > > + struct hinic_wqe_info wqe = {0}; > > + > > + wqe.wqe_id = wqe_id; > > + wqe.q_id = sq_id; > > + wqe.wqebb_cnt = nwqe_size / sq_info->sq_wqebb_size; > > + > > + memset(&msg_to_kernel, 0, sizeof(msg_to_kernel)); > > + fill_ioctl_msg_hd(&msg_to_kernel, SEND_TO_NIC_DRIVER, TX_WQE_INFO, > > + (unsigned int)(sizeof(struct hinic_wqe_info)), > > + nwqe_size, target.dev_name, target.bus_num); > > + msg_to_kernel.in_buf = (void *)&wqe; > > + > > + return lib_ioctl(&msg_to_kernel, nwqe); > > +} > > + > > +int > > +lib_rx_rq_info_get(struct tool_target target, struct nic_rq_info *rq_info, > > + int rq_id) > > +{ > > + struct msg_module msg_to_kernel; > > + > > + memset(&msg_to_kernel, 0, sizeof(msg_to_kernel)); > > + fill_ioctl_msg_hd(&msg_to_kernel, SEND_TO_NIC_DRIVER, RX_INFO, > > + (unsigned int)(sizeof(int)), > > + (unsigned int)sizeof(struct nic_rq_info), > > + target.dev_name, target.bus_num); > > + msg_to_kernel.in_buf = &rq_id; > > + > > + return lib_ioctl(&msg_to_kernel, rq_info); > > +} > > + > > +int > > +lib_rx_wqe_info_get(struct tool_target target, struct nic_rq_info *rq_info, > > + int rq_id, int wqe_id, void *nwqe, int nwqe_size) > > +{ > > + struct msg_module msg_to_kernel; > > + struct hinic_wqe_info wqe = {0}; > > + > > + wqe.wqe_id = wqe_id; > > + wqe.q_id = rq_id; > > + wqe.wqebb_cnt = nwqe_size / rq_info->rq_wqebb_size; > > + > > + memset(&msg_to_kernel, 0, sizeof(msg_to_kernel)); > > + fill_ioctl_msg_hd(&msg_to_kernel, SEND_TO_NIC_DRIVER, RX_WQE_INFO, > > + (unsigned int)(sizeof(struct hinic_wqe_info)), > > + nwqe_size, target.dev_name, target.bus_num); > > + msg_to_kernel.in_buf = (void *)&wqe; > > + > > + return lib_ioctl(&msg_to_kernel, nwqe); > > +} > > + > > +int > > +lib_rx_cqe_info_get(struct tool_target target, > > + __rte_unused struct nic_rq_info *rq_info, int rq_id, > > + int wqe_id, void *nwqe, int nwqe_size) > > +{ > > + struct msg_module msg_to_kernel; > > + struct hinic_wqe_info wqe = {0}; > > + > > + wqe.wqe_id = wqe_id; > > + wqe.q_id = rq_id; > > + > > + memset(&msg_to_kernel, 0, sizeof(msg_to_kernel)); > > + fill_ioctl_msg_hd(&msg_to_kernel, SEND_TO_NIC_DRIVER, RX_CQE_INFO, > > + (unsigned int)(sizeof(struct hinic_wqe_info)), > > + nwqe_size, target.dev_name, target.bus_num); > > + msg_to_kernel.in_buf = (void *)&wqe; > > + > > + return lib_ioctl(&msg_to_kernel, nwqe); > > +} > > diff --git a/drivers/net/hinic3/mml/hinic3_mml_lib.h b/drivers/net/hinic3/mml/hinic3_mml_lib.h > > new file mode 100644 > > index 0000000000..ab045525f3 > > --- /dev/null > > +++ b/drivers/net/hinic3/mml/hinic3_mml_lib.h > > @@ -0,0 +1,276 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. > > + */ > > + > > +#ifndef _HINIC3_MML_LIB > > +#define _HINIC3_MML_LIB > > + > > +#include > > +#include > > + > > +#include "hinic3_mml_cmd.h" > > +#include "hinic3_compat.h" > > +#include "hinic3_mgmt.h" > > + > > +#define MAX_DEV_LEN 16 > > +#define TRGET_UNKNOWN_BUS_NUM (-1) > > + > > +#ifndef DEV_NAME_LEN > > +#define DEV_NAME_LEN 64 > > +#endif > > + > > +enum { > > + UDA_SUCCESS = 0x0, > > + UDA_FAIL, > > + UDA_ENXIO, > > + UDA_ENONMEM, > > + UDA_EBUSY, > > + UDA_ECRC, > > + UDA_EINVAL, > > + UDA_EFAULT, > > + UDA_ELEN, > > + UDA_ECMD, > > + UDA_ENODRIVER, > > + UDA_EXIST, > > + UDA_EOVERSTEP, > > + UDA_ENOOBJ, > > + UDA_EOBJ, > > + UDA_ENOMATCH, > > + UDA_ETIMEOUT, > > + > > + UDA_CONTOP, > > + > > + UDA_REBOOT = 0xFD, > > + UDA_CANCEL = 0xFE, > > + UDA_KILLED = 0xFF, > > +}; > > + > > +#define PARAM_NEED 1 > > +#define PARAM_NOT_NEED 0 > > + > > +#define BASE_ALL 0 > > +#define BASE_8 8 > > +#define BASE_10 10 > > +#define BASE_16 16 > > + > > +enum module_name { > > + SEND_TO_NPU = 1, > > + SEND_TO_MPU, > > + SEND_TO_SM, > > + > > + SEND_TO_HW_DRIVER, > > + SEND_TO_NIC_DRIVER, > > + SEND_TO_OVS_DRIVER, > > + SEND_TO_ROCE_DRIVER, > > + SEND_TO_TOE_DRIVER, > > + SEND_TO_IWAP_DRIVER, > > + SEND_TO_FC_DRIVER, > > + SEND_FCOE_DRIVER, > > +}; > > + > > +enum driver_cmd_type { > > + TX_INFO = 1, > > + Q_NUM, > > + TX_WQE_INFO, > > + TX_MAPPING, > > + RX_INFO, > > + RX_WQE_INFO, > > + RX_CQE_INFO > > +}; > > + > > +struct tool_target { > > + int bus_num; > > + char dev_name[MAX_DEV_LEN]; > > + void *pri; > > +}; > > + > > +struct nic_tx_hw_page { > > + long long phy_addr; > > + long long *map_addr; > > +}; > > + > > +struct nic_sq_info { > > + unsigned short q_id; > > + unsigned short pi; /**< Ring buffer queue producer point. */ > > + unsigned short ci; /**< Ring buffer queue consumer point. */ > > + unsigned short fi; /**< Ring buffer queue complete point. */ > > + unsigned int sq_depth; > > + unsigned short sq_wqebb_size; > > + unsigned short *ci_addr; > > + uint64_t cla_addr; > > + > > + struct nic_tx_hw_page doorbell; > > + unsigned int page_idx; > > +}; > > + > > +struct comm_info_l2nic_sq_ci_attr { > > + struct mgmt_msg_head msg_head; > > + > > + uint16_t func_idx; > > + uint8_t dma_attr_off; > > + uint8_t pending_limit; > > + > > + uint8_t coalescing_time; > > + uint8_t int_en; > > + uint16_t int_offset; > > + > > + uint32_t l2nic_sqn; > > + uint32_t rsv; > > + uint64_t ci_addr; > > +}; > > + > > +struct nic_rq_info { > > + unsigned short q_id; /**< Queue id in current function, 0, 1, 2... */ > > + > > + unsigned short hw_pi; /**< Where pkt buf allocated. */ > > + unsigned short ci; /**< Where hw pkt received, owned by hw. */ > > + unsigned short sw_pi; /**< Where driver begin receive pkt. */ > > + unsigned short rq_wqebb_size; /**< wqebb size, default to 32 bytes. */ > > + > > + unsigned short rq_depth; > > + unsigned short buf_len; /**< 2K. */ > > + void *ci_wqe_page_addr; /**< For queue context init. */ > > + void *ci_cla_tbl_addr; > > + unsigned short int_num; /**< RSS support should consider int_num. */ > > + unsigned int msix_vector; /**< For debug. */ > > +}; > > + > > +struct hinic_wqe_info { > > + int q_id; > > + void *slq_handle; > > + uint32_t wqe_id; > > + uint32_t wqebb_cnt; > > +}; > > + > > +struct npu_cmd_st { > > + uint32_t mod : 8; > > + uint32_t cmd : 8; > > + uint32_t ack_type : 3; > > + uint32_t direct_resp : 1; > > + uint32_t len : 12; > > +}; > > + > > +struct mpu_cmd_st { > > + uint32_t api_type : 8; > > + uint32_t mod : 8; > > + uint32_t cmd : 16; > > +}; > > + > > +struct msg_module { > > + char device_name[DEV_NAME_LEN]; > > + uint32_t module; > > + union { > > + uint32_t msg_format; /**< For driver. */ > > + struct npu_cmd_st npu_cmd; > > + struct mpu_cmd_st mpu_cmd; > > + }; > > + uint32_t timeout; /**< For mpu/npu cmd. */ > > + uint32_t func_idx; > > + uint32_t buf_in_size; > > + uint32_t buf_out_size; > > + void *in_buf; > > + void *out_buf; > > + int bus_num; > > + uint32_t rsvd2[5]; > > +}; > > + > > +/** > > + * Convert the provided string into `uint32_t` according to the specified base. > > + * > > + * @param[in] nptr > > + * The string to be converted. > > + * @param[in] base > > + * The base to use for conversion (e.g., 10 for decimal, 16 for hexadecimal). > > + * @param[out] value > > + * The output variable where the converted `uint32_t` value will be stored. > > + * > > + * @return > > + * 0 on success, non-zero on failure. > > + * - -UDA_EINVAL if the string is invalid or the value is out of range. > > + */ > > +static inline int > > +string_toui(const char *nptr, int base, uint32_t *value) > > +{ > > + char *endptr = NULL; > > + long tmp_value; > > + > > + tmp_value = strtol(nptr, &endptr, base); > > + if ((*endptr != 0) || tmp_value >= 0x7FFFFFFF || tmp_value < 0) > > + return -UDA_EINVAL; > > + *value = (uint32_t)tmp_value; > > + return UDA_SUCCESS; > > +} > > + > > +#define UDA_TRUE 1 > > +#define UDA_FALSE 0 > > + > > +/** > > + * Format and append a log message to a string buffer. > > + * > > + * @param[out] show_str > > + * The string buffer where the formatted message will be appended. > > + * @param[out] show_len > > + * The current length of the string in the buffer. It is updated after > > + * appending. > > + * @param[in] fmt > > + * The format string that specifies how to format the log message. > > + * @param[in] args > > + * The variable arguments to be formatted according to the format string. > > + */ > > +static inline void > > +__rte_format_printf(3, 4) > > +hinic3_pmd_mml_log(char *show_str, int *show_len, const char *fmt, ...) > > +{ > > + va_list args; > > + int ret = 0; > > + > > + va_start(args, fmt); > > + ret = vsprintf(show_str + *show_len, fmt, args); > > + va_end(args); > > + > > + if (ret > 0) { > > + *show_len += ret; > > + } else { > > + PMD_DRV_LOG(ERR, "MML show string snprintf failed, err: %d", > > + ret); > > + } > > +} > > + > > +/** > > + * Get a valid target device based on the given name. > > + * > > + * This function checks if the device name is valid (within the length limit) > > + * and then stores it in the target structure. The bus number is initialized to > > + * 0. > > + * > > + * @param[in] name > > + * The device name to be validated and stored. > > + * @param[out] target > > + * The structure where the device name and bus number will be stored. > > + * > > + * @return > > + * 0 on success, non-zero on failure. > > + */ > > +int tool_get_valid_target(char *name, struct tool_target *target); > > + > > +int hinic3_pmd_mml_ioctl(void *msg); > > + > > +int lib_tx_sq_info_get(struct tool_target target, struct nic_sq_info *sq_info, > > + int sq_id); > > + > > +int lib_tx_wqe_info_get(struct tool_target target, struct nic_sq_info *sq_info, > > + int sq_id, int wqe_id, void *nwqe, int nwqe_size); > > + > > +int lib_rx_rq_info_get(struct tool_target target, struct nic_rq_info *rq_info, > > + int rq_id); > > + > > +int lib_rx_wqe_info_get(struct tool_target target, struct nic_rq_info *rq_info, > > + int rq_id, int wqe_id, void *nwqe, int nwqe_size); > > + > > +int lib_rx_cqe_info_get(struct tool_target target, struct nic_rq_info *rq_info, > > + int rq_id, int wqe_id, void *nwqe, int nwqe_size); > > + > > +int hinic3_pmd_mml_lib(const char *buf_in, uint32_t in_size, char *buf_out, > > + uint32_t *out_len, uint32_t max_buf_out_len); > > + > > +#endif /* _HINIC3_MML_LIB */ > > diff --git a/drivers/net/hinic3/mml/hinic3_mml_main.c b/drivers/net/hinic3/mml/hinic3_mml_main.c > > new file mode 100644 > > index 0000000000..0b508bc1c3 > > --- /dev/null > > +++ b/drivers/net/hinic3/mml/hinic3_mml_main.c > > @@ -0,0 +1,167 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. > > + */ > > + > > +#include "hinic3_mml_lib.h" > > +#include "hinic3_mml_cmd.h" > > + > > +#define MAX_ARGC 20 > > + > > +/** > > + * Free all memory associated with the command adapter, including the command > > + * states and command buffer. > > + * > > + * @param[in] adapter > > + * Pointer to command adapter. > > + */ > > +static void > > +cmd_deinit(cmd_adapter_t *adapter) > > +{ > > + int i; > > + > > + for (i = 0; i < COMMAND_MAX_MAJORS; i++) { > > + if (adapter->p_major_cmd[i]) { > > + if (adapter->p_major_cmd[i]->cmd_st) { > > + free(adapter->p_major_cmd[i]->cmd_st); > > + adapter->p_major_cmd[i]->cmd_st = NULL; > > + } > > + > > + free(adapter->p_major_cmd[i]); > > + adapter->p_major_cmd[i] = NULL; > > + } > > + } > > + > > + if (adapter->cmd_buf) { > > + free(adapter->cmd_buf); > > + adapter->cmd_buf = NULL; > > + } > > +} > > + > > +static int > > +cmd_init(cmd_adapter_t *adapter) > > +{ > > + int err; > > + > > + err = cmd_show_q_init(adapter); > > + if (err != 0) { > > + PMD_DRV_LOG(ERR, "Init cmd show queue fail"); > > + return err; > > + } > > + > > + return UDA_SUCCESS; > > +} > > + > > +/** > > + * Separate the input command string into arguments. > > + * > > + * @param[in] adapter > > + * Pointer to command adapter. > > + * @param[in] buf_in > > + * The input command string. > > + * @param[in] in_size > > + * The size of the input command string. > > + * @param[out] argv > > + * The array to store separated arguments. > > + * > > + * @return > > + * The number of arguments on success, a negative error code otherwise. > > + */ > > +static int > > +cmd_separate(cmd_adapter_t *adapter, const char *buf_in, uint32_t in_size, > > + char **argv) > > +{ > > + char *cmd_buf = NULL; > > + char *tmp = NULL; > > + char *saveptr = NULL; > > + int i; > > + > > + cmd_buf = calloc(1, in_size + 1); > > + if (!cmd_buf) { > > + PMD_DRV_LOG(ERR, "Failed to allocate cmd_buf"); > > + return -UDA_ENONMEM; > > + } > > + > > + memcpy(cmd_buf, buf_in, in_size); > > + > > + tmp = cmd_buf; > > + for (i = 1; i < MAX_ARGC; i++) { > > + argv[i] = strtok_r(tmp, " ", &saveptr); > > + if (!argv[i]) > > + break; > > + tmp = NULL; > > + } > > + > > + if (i == MAX_ARGC) { > > + PMD_DRV_LOG(ERR, "Parameters is too many"); > > + free(cmd_buf); > > + return -UDA_FAIL; > > + } > > + > > + adapter->cmd_buf = cmd_buf; > > + return i; > > +} > > + > > +/** > > + * Process the input command string, parse arguments, and return the result. > > + * > > + * @param[in] buf_in > > + * The input command string. > > + * @param[in] in_size > > + * The size of the input command string. > > + * @param[out] buf_out > > + * The output buffer to store the command result. > > + * @param[out] out_len > > + * The length of the output buffer. > > + * @param[in] max_buf_out_len > > + * The maximum size of the output buffer. > > + * > > + * @return > > + * 0 on success, non-zero on failure. > > + */ > > +int > > +hinic3_pmd_mml_lib(const char *buf_in, uint32_t in_size, char *buf_out, > > + uint32_t *out_len, uint32_t max_buf_out_len) > > +{ > > + cmd_adapter_t *adapter = NULL; > > + char *argv[MAX_ARGC]; > > + int argc; > > + int err = -UDA_EINVAL; > > + > > + if (!buf_in || !in_size) { > > + PMD_DRV_LOG(ERR, "Invalid param, buf_in: %d, in_size: 0x%x", > > + !!buf_in, in_size); > > + return err; > > + } > > + > > + if (!buf_out || max_buf_out_len < MAX_SHOW_STR_LEN) { > > + PMD_DRV_LOG(ERR, > > + "Invalid param, buf_out: %d, max_buf_out_len: 0x%x", > > + !!buf_out, max_buf_out_len); > > + return err; > > + } > > + > > + adapter = calloc(1, sizeof(cmd_adapter_t)); > > + if (!adapter) { > > + PMD_DRV_LOG(ERR, "Failed to allocate cmd adapter"); > > + return -UDA_ENONMEM; > > + } > > + > > + err = cmd_init(adapter); > > + if (err != 0) > > + goto parse_cmd_fail; > > + > > + argc = cmd_separate(adapter, buf_in, in_size, argv); > > + if (argc < 0) { > > + err = -UDA_FAIL; > > + goto parse_cmd_fail; > > + } > > + > > + memset(buf_out, 0, max_buf_out_len); > > + command_parse(adapter, argc, argv, buf_out, out_len); > > + > > +parse_cmd_fail: > > + cmd_deinit(adapter); > > + free(adapter); > > + > > + return err; > > +} > > diff --git a/drivers/net/hinic3/mml/hinic3_mml_queue.c b/drivers/net/hinic3/mml/hinic3_mml_queue.c > > new file mode 100644 > > index 0000000000..2e0c4a284b > > --- /dev/null > > +++ b/drivers/net/hinic3/mml/hinic3_mml_queue.c > > @@ -0,0 +1,745 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. > > + */ > > + > > +#include "hinic3_mml_lib.h" > > +#include "hinic3_mml_cmd.h" > > +#include "hinic3_mml_queue.h" > > + > > +#define ADDR_HI_BIT 32 > > + > > +/** > > + * This function perform similar operations as `hinic3_pmd_mml_log`, but it > > + * return a code. > > + * > > + * @param[out] show_str > > + * The string buffer where the formatted message will be appended. > > + * @param[out] show_len > > + * The current length of the string in the buffer. It is updated after > > + * appending. > > + * @param[in] fmt > > + * The format string that specifies how to format the log message. > > + * @param[in] args > > + * The variable arguments to be formatted according to the format string. > > + * > > + * @return > > + * 0 on success, non-zero on failure. > > + * - `-UDA_EINVAL` if an error occurs during the formatting process. > > + * > > + * @see hinic3_pmd_mml_log > > + */ > > +static int > > +__rte_format_printf(3, 4) > > +hinic3_pmd_mml_log_ret(char *show_str, int *show_len, const char *fmt, ...) > > +{ > > + va_list args; > > + int ret = 0; > > + > > + va_start(args, fmt); > > + ret = vsprintf(show_str + *show_len, fmt, args); > > + va_end(args); > > + > > + if (ret > 0) { > > + *show_len += ret; > > + } else { > > + PMD_DRV_LOG(ERR, "MML show string snprintf failed, err: %d", > > + ret); > > + return -UDA_EINVAL; > > + } > > + > > + return UDA_SUCCESS; > > +} > > + > > +/** > > + * Format and log the information about the RQ by appending details such as > > + * queue ID, ci, sw pi, RQ depth, RQ WQE buffer size, buffer length, interrupt > > + * number, and MSIX vector to the output buffer. > > + * > > + * @param[in] self > > + * Pointer to major command structure. > > + * @param[in] rq_info > > + * The receive queue information to be displayed, which includes various > > + * properties like queue ID, depth, interrupt number, etc. > > + */ > > +static void > > +rx_show_rq_info(major_cmd_t *self, struct nic_rq_info *rq_info) > > +{ > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "Receive queue information:"); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "queue_id:%u", > > + rq_info->q_id); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "ci:%u", > > + rq_info->ci); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "sw_pi:%u", > > + rq_info->sw_pi); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "rq_depth:%u", > > + rq_info->rq_depth); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "rq_wqebb_size:%u", rq_info->rq_wqebb_size); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "buf_len:%u", > > + rq_info->buf_len); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "int_num:%u", > > + rq_info->int_num); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "msix_vector:%u", > > + rq_info->msix_vector); > > +} > > + > > +static void > > +rx_show_wqe(major_cmd_t *self, nic_rq_wqe *wqe) > > +{ > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "Rx buffer section information:"); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "buf_addr:0x%" PRIx64, > > + (((uint64_t)wqe->buf_desc.pkt_buf_addr_high) << ADDR_HI_BIT) | > > + wqe->buf_desc.pkt_buf_addr_low); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "buf_len:%u", > > + wqe->buf_desc.len); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "rsvd0:%u", > > + wqe->rsvd0); > > + > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "Cqe buffer section information:"); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "buf_hi:0x%" PRIx64, > > + (((uint64_t)wqe->cqe_sect.pkt_buf_addr_high) << ADDR_HI_BIT) | > > + wqe->cqe_sect.pkt_buf_addr_low); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "buf_len:%u", > > + wqe->cqe_sect.len); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "rsvd1:%u", > > + wqe->rsvd1); > > +} > > + > > +static void > > +rx_show_cqe_info(major_cmd_t *self, struct tag_l2nic_rx_cqe *wqe_cs) > > +{ > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "Rx cqe info:"); > > + > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "cs_dw0:0x%08x", > > + wqe_cs->dw0.value); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "rx_done:0x%x", > > + wqe_cs->dw0.bs.rx_done); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "bp_en:0x%x", > > + wqe_cs->dw0.bs.bp_en); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "decry_pkt:0x%x", > > + wqe_cs->dw0.bs.decry_pkt); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "flush:0x%x", > > + wqe_cs->dw0.bs.flush); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "spec_flags:0x%x", > > + wqe_cs->dw0.bs.spec_flags); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "rsvd0:0x%x", > > + wqe_cs->dw0.bs.rsvd0); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "lro_num:0x%x", > > + wqe_cs->dw0.bs.lro_num); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "checksum_err:0x%x", wqe_cs->dw0.bs.checksum_err); > > + > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "cs_dw1:0x%08x", > > + wqe_cs->dw1.value); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "length:%u", > > + wqe_cs->dw1.bs.length); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "vlan:0x%x", > > + wqe_cs->dw1.bs.vlan); > > + > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "cs_dw2:0x%08x", > > + wqe_cs->dw2.value); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "rss_type:0x%x", > > + wqe_cs->dw2.bs.rss_type); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "rsvd0:0x%x", > > + wqe_cs->dw2.bs.rsvd0); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "vlan_offload_en:0x%x", > > + wqe_cs->dw2.bs.vlan_offload_en); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "umbcast:0x%x", > > + wqe_cs->dw2.bs.umbcast); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "rsvd1:0x%x", > > + wqe_cs->dw2.bs.rsvd1); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "pkt_types:0x%x", > > + wqe_cs->dw2.bs.pkt_types); > > + > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "rss_hash_value:0x%08x", > > + wqe_cs->dw3.bs.rss_hash_value); > > + > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "cs_dw4:0x%08x", > > + wqe_cs->dw4.value); > > + > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "cs_dw5:0x%08x", > > + wqe_cs->dw5.value); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "mac_type:0x%x", > > + wqe_cs->dw5.ovs_bs.mac_type); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "l3_type:0x%x", > > + wqe_cs->dw5.ovs_bs.l3_type); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "l4_type:0x%x", > > + wqe_cs->dw5.ovs_bs.l4_type); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "rsvd0:0x%x", > > + wqe_cs->dw5.ovs_bs.rsvd0); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "traffic_type:0x%x", > > + wqe_cs->dw5.ovs_bs.traffic_type); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "traffic_from:0x%x", > > + wqe_cs->dw5.ovs_bs.traffic_from); > > + > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "cs_dw6:0x%08x", > > + wqe_cs->dw6.value); > > + > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "localtag:0x%08x", > > + wqe_cs->dw7.ovs_bs.localtag); > > +} > > + > > +#define HINIC3_PMD_MML_LOG_RET(fmt, ...) \ > > + hinic3_pmd_mml_log_ret(self->show_str, &self->show_len, fmt, \ > > + ##__VA_ARGS__) > > + > > +/** > > + * Display help information for queue command. > > + * > > + * @param[in] self > > + * Pointer to major command structure. > > + * @param[in] argc > > + * A string representing the value associated with the command option (unused_). > > + * > > + * @return > > + * 0 on success, non-zero on failure. > > + */ > > +static int > > +cmd_queue_help(major_cmd_t *self, __rte_unused char *argc) > > +{ > > + int ret; > > + ret = HINIC3_PMD_MML_LOG_RET("\n") || > > + HINIC3_PMD_MML_LOG_RET(" Usage: %s %s", self->name, > > + "-i -d -t " > > + "-q [-w ]") || > > + HINIC3_PMD_MML_LOG_RET("\n %s", self->description) || > > + HINIC3_PMD_MML_LOG_RET("\n Options:\n") || > > + HINIC3_PMD_MML_LOG_RET(" %s, %-25s %s", "-h", "--help", > > + "display this help and exit") || > > + HINIC3_PMD_MML_LOG_RET(" %s, %-25s %s", "-i", > > + "--device=", > > + "device target, e.g. 08:00.0") || > > + HINIC3_PMD_MML_LOG_RET(" %s, %-25s %s", "-d", "--direction", > > + "tx or rx") || > > + HINIC3_PMD_MML_LOG_RET(" %s, %-25s %s", " ", "", "0: tx") || > > + HINIC3_PMD_MML_LOG_RET(" %s, %-25s %s", " ", "", "1: rx") || > > + HINIC3_PMD_MML_LOG_RET(" %s, %-25s %s", "-t", "--type", "") || > > + HINIC3_PMD_MML_LOG_RET(" %s, %-25s %s", " ", "", > > + "0: queue info") || > > + HINIC3_PMD_MML_LOG_RET(" %s, %-25s %s", " ", "", > > + "1: wqe info") || > > + HINIC3_PMD_MML_LOG_RET(" %s, %-25s %s", " ", "", > > + "2: cqe info(only for rx)") || > > + HINIC3_PMD_MML_LOG_RET(" %s, %-25s %s", "-q", "--queue_id", > > + "") || > > + HINIC3_PMD_MML_LOG_RET(" %s, %-25s %s", "-w", "--wqe_id", "") || > > + HINIC3_PMD_MML_LOG_RET("\n"); > > + > > + return ret; > > +} > > + > > +static void > > +tx_show_sq_info(major_cmd_t *self, struct nic_sq_info *sq_info) > > +{ > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "Send queue information:"); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "queue_id:%u", > > + sq_info->q_id); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "pi:%u", > > + sq_info->pi); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "ci:%u", > > + sq_info->ci); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "fi:%u", > > + sq_info->fi); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "sq_depth:%u", > > + sq_info->sq_depth); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "sq_wqebb_size:%u", sq_info->sq_wqebb_size); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "cla_addr:0x%" PRIu64, > > + sq_info->cla_addr); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "doorbell phy_addr:0x%" PRId64, > > + (uintptr_t)sq_info->doorbell.phy_addr); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "page_idx:%u", > > + sq_info->page_idx); > > +} > > + > > +static void > > +tx_show_wqe(major_cmd_t *self, struct nic_tx_wqe_desc *wqe) > > +{ > > + struct nic_tx_ctrl_section *control = NULL; > > + struct nic_tx_task_section *task = NULL; > > + unsigned int *val = (unsigned int *)wqe; > > + > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "dw0:0x%08x", > > + *(val++)); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "dw1:0x%08x", > > + *(val++)); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "dw2:0x%08x", > > + *(val++)); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "dw3:0x%08x", > > + *(val++)); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "dw4:0x%08x", > > + *(val++)); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "dw5:0x%08x", > > + *(val++)); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "dw6:0x%08x", > > + *(val++)); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "dw7:0x%08x", > > + *(val++)); > > + > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "\nWqe may analyse as follows:"); > > + control = &wqe->control; > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "\nInformation about wqe control section:"); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "ctrl_format:0x%08x", control->ctrl_format); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "owner:%u", > > + control->ctrl_sec.o); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "extended_compact:%u", control->ctrl_sec.ec); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "direct_normal:%u", control->ctrl_sec.dn); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "inline_sgl:%u", > > + control->ctrl_sec.df); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "ts_size:%u", > > + control->ctrl_sec.tss); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "bds_len:%u", > > + control->ctrl_sec.bdsl); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "rsvd:%u", > > + control->ctrl_sec.r); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "1st_buf_len:%u", > > + control->ctrl_sec.len); > > + > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "queue_info:0x%08x", control->queue_info); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "pri:%u", > > + control->qsf.pri); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "uc:%u", > > + control->qsf.uc); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "sctp:%u", > > + control->qsf.sctp); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "mss:%u", > > + control->qsf.mss); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "tcp_udp_cs:%u", > > + control->qsf.tcp_udp_cs); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "tso:%u", > > + control->qsf.tso); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "ufo:%u", > > + control->qsf.ufo); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "payload_offset:%u", control->qsf.payload_offset); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "pkt_type:%u", > > + control->qsf.pkt_type); > > + > > + /* First buffer section. */ > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "bd0_hi_addr:0x%08x", wqe->bd0_hi_addr); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "bd0_lo_addr:0x%08x", wqe->bd0_lo_addr); > > + > > + /* Show the task section. */ > > + task = &wqe->task; > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "\nInformation about wqe task section:"); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "vport_id:%u", > > + task->bs2.vport_id); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "vport_type:%u", > > + task->bs2.vport_type); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "traffic_type:%u", > > + task->bs2.traffic_type); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "secondary_port_id:%u", task->bs2.secondary_port_id); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "rsvd0:%u", > > + task->bs2.rsvd0); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "crypto_en:%u", > > + task->bs2.crypto_en); > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, "pkt_type:%u", > > + task->bs2.pkt_type); > > +} > > + > > +static int > > +cmd_queue_target(major_cmd_t *self, char *argc) > > +{ > > + struct cmd_show_q_st *show_q = self->cmd_st; > > + int ret; > > + > > + if (tool_get_valid_target(argc, &show_q->target) != UDA_SUCCESS) { > > + self->err_no = -UDA_EINVAL; > > + ret = snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Unknown device %s.", argc); > > + if (ret <= 0) { > > + PMD_DRV_LOG(ERR, > > + "snprintf queue err msg failed, ret: %d", > > + ret); > > + } > > + return -UDA_EINVAL; > > + } > > + > > + return UDA_SUCCESS; > > +} > > + > > +static int > > +get_queue_type(major_cmd_t *self, char *argc) > > +{ > > + struct cmd_show_q_st *show_q = self->cmd_st; > > + unsigned int num = 0; > > + > > + if (string_toui(argc, BASE_10, &num) != UDA_SUCCESS) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Unknown queuetype %u.", num); > > + return -UDA_EINVAL; > > + } > > + > > + show_q->qobj = (int)num; > > + return UDA_SUCCESS; > > +} > > + > > +static int > > +get_queue_id(major_cmd_t *self, char *argc) > > +{ > > + struct cmd_show_q_st *show_q = self->cmd_st; > > + unsigned int num = 0; > > + > > + if (string_toui(argc, BASE_10, &num) != UDA_SUCCESS) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Invalid queue id."); > > + return -UDA_EINVAL; > > + } > > + > > + show_q->q_id = (int)num; > > + return UDA_SUCCESS; > > +} > > + > > +static int > > +get_q_wqe_id(major_cmd_t *self, char *argc) > > +{ > > + struct cmd_show_q_st *show_q = self->cmd_st; > > + unsigned int num = 0; > > + > > + if (string_toui(argc, BASE_10, &num) != UDA_SUCCESS) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Invalid wqe id."); > > + return -UDA_EINVAL; > > + } > > + > > + show_q->wqe_id = (int)num; > > + return UDA_SUCCESS; > > +} > > + > > +/** > > + * Set direction for queue query. > > + * > > + * @param[in] self > > + * Pointer to major command structure. > > + * @param[in] argc > > + * The input argument representing the direction (as a string). > > + * > > + * @return > > + * 0 on success, non-zero on failure. > > + * - -UDA_EINVAL If the input is invalid (not a number or out of range), it sets > > + * an error in `err_no` and `err_str`. > > + */ > > +static int > > +get_direction(major_cmd_t *self, char *argc) > > +{ > > + struct cmd_show_q_st *show_q = self->cmd_st; > > + unsigned int num = 0; > > + > > + if (string_toui(argc, BASE_10, &num) != UDA_SUCCESS || num > 1) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Unknown mode."); > > + return -UDA_EINVAL; > > + } > > + > > + show_q->direction = (int)num; > > + return UDA_SUCCESS; > > +} > > + > > +static int > > +rx_param_check(major_cmd_t *self, struct cmd_show_q_st *rx_param) > > +{ > > + struct cmd_show_q_st *show_q = self->cmd_st; > > + > > + if (rx_param->target.bus_num == TRGET_UNKNOWN_BUS_NUM) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Need device name."); > > + return self->err_no; > > + } > > + > > + if (show_q->qobj > OBJ_CQE_INFO || show_q->qobj < OBJ_Q_INFO) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Unknown queue type."); > > + return self->err_no; > > + } > > + > > + if (show_q->q_id == -1) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Need queue id."); > > + return self->err_no; > > + } > > + > > + if (show_q->qobj != OBJ_Q_INFO && show_q->wqe_id == -1) { > > + self->err_no = -UDA_FAIL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Get cqe_info or wqe_info, must set wqeid."); > > + return -UDA_FAIL; > > + } > > + > > + if (show_q->qobj == OBJ_Q_INFO && show_q->wqe_id != -1) { > > + self->err_no = -UDA_FAIL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Get queue info, need not set wqeid."); > > + return -UDA_FAIL; > > + } > > + > > + return UDA_SUCCESS; > > +} > > + > > +static int > > +tx_param_check(major_cmd_t *self, struct cmd_show_q_st *tx_param) > > +{ > > + struct cmd_show_q_st *show_q = self->cmd_st; > > + > > + if (tx_param->target.bus_num == TRGET_UNKNOWN_BUS_NUM) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Need device name."); > > + return self->err_no; > > + } > > + > > + if (show_q->qobj > OBJ_WQE_INFO || show_q->qobj < OBJ_Q_INFO) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Unknown queue type."); > > + return self->err_no; > > + } > > + > > + if (show_q->q_id == -1) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Need queue id."); > > + return self->err_no; > > + } > > + > > + if (show_q->qobj == OBJ_WQE_INFO && show_q->wqe_id == -1) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Get wqe_info, must set wqeid."); > > + return self->err_no; > > + } > > + > > + if (show_q->qobj != OBJ_WQE_INFO && show_q->wqe_id != -1) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Get queue info, need not set wqeid."); > > + return self->err_no; > > + } > > + > > + return UDA_SUCCESS; > > +} > > + > > +static void > > +cmd_tx_execute(major_cmd_t *self) > > +{ > > + struct cmd_show_q_st *show_q = self->cmd_st; > > + int ret; > > + struct nic_sq_info sq_info = {0}; > > + struct nic_tx_wqe_desc nwqe; > > + > > + if (tx_param_check(self, show_q) != UDA_SUCCESS) > > + return; > > + > > + if (show_q->qobj == OBJ_Q_INFO || show_q->qobj == OBJ_WQE_INFO) { > > + ret = lib_tx_sq_info_get(show_q->target, (void *)&sq_info, > > + show_q->q_id); > > + if (ret != UDA_SUCCESS) { > > + self->err_no = ret; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Get tx sq_info failed."); > > + return; > > + } > > + > > + if (show_q->qobj == OBJ_Q_INFO) { > > + tx_show_sq_info(self, &sq_info); > > + return; > > + } > > + > > + if (show_q->wqe_id >= (int)sq_info.sq_depth) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Max wqe id is %u.", sq_info.sq_depth - 1); > > + return; > > + } > > + > > + memset(&nwqe, 0, sizeof(nwqe)); > > + ret = lib_tx_wqe_info_get(show_q->target, &sq_info, > > + show_q->q_id, show_q->wqe_id, > > + (void *)&nwqe, sizeof(nwqe)); > > + if (ret != UDA_SUCCESS) { > > + self->err_no = ret; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Get tx wqe_info failed."); > > + return; > > + } > > + > > + tx_show_wqe(self, &nwqe); > > + return; > > + } > > +} > > + > > +static void > > +cmd_rx_execute(major_cmd_t *self) > > +{ > > + int ret; > > + struct nic_rq_info rq_info = {0}; > > + struct tag_l2nic_rx_cqe cqe; > > + nic_rq_wqe wqe; > > + struct cmd_show_q_st *show_q = self->cmd_st; > > + > > + if (rx_param_check(self, show_q) != UDA_SUCCESS) > > + return; > > + > > + ret = lib_rx_rq_info_get(show_q->target, &rq_info, show_q->q_id); > > + if (ret != UDA_SUCCESS) { > > + self->err_no = ret; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Get rx rq_info failed."); > > + return; > > + } > > + > > + if (show_q->qobj == OBJ_Q_INFO) { > > + rx_show_rq_info(self, &rq_info); > > + return; > > + } > > + > > + if ((uint32_t)show_q->wqe_id >= rq_info.rq_depth) { > > + self->err_no = -UDA_EINVAL; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Max wqe id is %u.", rq_info.rq_depth - 1); > > + return; > > + } > > + > > + if (show_q->qobj == OBJ_WQE_INFO) { > > + memset(&wqe, 0, sizeof(wqe)); > > + ret = lib_rx_wqe_info_get(show_q->target, &rq_info, > > + show_q->q_id, show_q->wqe_id, > > + (void *)&wqe, sizeof(wqe)); > > + if (ret != UDA_SUCCESS) { > > + self->err_no = ret; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Get rx wqe_info failed."); > > + return; > > + } > > + > > + rx_show_wqe(self, &wqe); > > + return; > > + } > > + > > + /* OBJ_CQE_INFO */ > > + memset(&cqe, 0, sizeof(cqe)); > > + ret = lib_rx_cqe_info_get(show_q->target, &rq_info, show_q->q_id, > > + show_q->wqe_id, (void *)&cqe, sizeof(cqe)); > > + if (ret != UDA_SUCCESS) { > > + self->err_no = ret; > > + snprintf(self->err_str, COMMANDER_ERR_MAX_STRING - 1, > > + "Get rx cqe_info failed."); > > + return; > > + } > > + > > + rx_show_cqe_info(self, &cqe); > > +} > > + > > +/** > > + * Execute the NIC queue query command based on the direction. > > + * > > + * @param[in] self > > + * Pointer to major command structure. > > + */ > > +static void > > +cmd_nic_queue_execute(major_cmd_t *self) > > +{ > > + struct cmd_show_q_st *show_q = self->cmd_st; > > + > > + if (show_q->direction == -1) { > > + hinic3_pmd_mml_log(self->show_str, &self->show_len, > > + "Need -d parameter."); > > + return; > > + } > > + > > + if (show_q->direction == 0) > > + cmd_tx_execute(self); > > + else > > + cmd_rx_execute(self); > > +} > > + > > +/** > > + * Initialize and register the queue query command. > > + * > > + * @param[in] adapter > > + * The command adapter, which holds the registered commands and their states. > > + * > > + * @return > > + * 0 on success, non-zero on failure. > > + * - -UDA_ENONMEM if memory allocation fail or an error occur. > > + */ > > +int > > +cmd_show_q_init(cmd_adapter_t *adapter) > > +{ > > + struct cmd_show_q_st *show_q = NULL; > > + major_cmd_t *show_q_cmd; > > + > > + show_q_cmd = calloc(1, sizeof(*show_q_cmd)); > > + if (!show_q_cmd) { > > + PMD_DRV_LOG(ERR, "Failed to allocate queue cmd"); > > + return -UDA_ENONMEM; > > + } > > + > > + snprintf(show_q_cmd->name, MAX_NAME_LEN - 1, "%s", "nic_queue"); > > + snprintf(show_q_cmd->description, > > + MAX_DES_LEN - 1, "%s", > > + "Query the rx/tx queue information of a specified pci_addr"); > > + > > + show_q_cmd->option_count = 0; > > + show_q_cmd->execute = cmd_nic_queue_execute; > > + > > + show_q = calloc(1, sizeof(*show_q)); > > + if (!show_q) { > > + free(show_q_cmd); > > + PMD_DRV_LOG(ERR, "Failed to allocate show queue"); > > + return -UDA_ENONMEM; > > + } > > + > > + show_q->qobj = -1; > > + show_q->q_id = -1; > > + show_q->wqe_id = -1; > > + show_q->direction = -1; > > + > > + show_q_cmd->cmd_st = show_q; > > + > > + tool_target_init(&show_q->target.bus_num, show_q->target.dev_name, > > + MAX_DEV_LEN); > > + > > + major_command_option(show_q_cmd, "-h", "--help", PARAM_NOT_NEED, > > + cmd_queue_help); > > + major_command_option(show_q_cmd, "-i", "--device", PARAM_NEED, > > + cmd_queue_target); > > + major_command_option(show_q_cmd, "-t", "--type", PARAM_NEED, > > + get_queue_type); > > + major_command_option(show_q_cmd, "-q", "--queue_id", PARAM_NEED, > > + get_queue_id); > > + major_command_option(show_q_cmd, "-w", "--wqe_id", PARAM_NEED, > > + get_q_wqe_id); > > + major_command_option(show_q_cmd, "-d", "--direction", PARAM_NEED, > > + get_direction); > > + > > + major_command_register(adapter, show_q_cmd); > > + > > + return UDA_SUCCESS; > > +} > > diff --git a/drivers/net/hinic3/mml/hinic3_mml_queue.h b/drivers/net/hinic3/mml/hinic3_mml_queue.h > > new file mode 100644 > > index 0000000000..61b91fb115 > > --- /dev/null > > +++ b/drivers/net/hinic3/mml/hinic3_mml_queue.h > > @@ -0,0 +1,256 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. > > + * Description : hinic3 mml for queue > > + */ > > + > > +#ifndef _HINIC3_MML_QUEUE > > +#define _HINIC3_MML_QUEUE > > + > > +#define OBJ_Q_INFO 0 > > +#define OBJ_WQE_INFO 1 > > +#define OBJ_CQE_INFO 2 > > + > > +/* TX. */ > > +struct nic_tx_ctrl_section { > > + union { > > + struct { > > + unsigned int len : 18; > > + unsigned int r : 1; > > + unsigned int bdsl : 8; > > + unsigned int tss : 1; > > + unsigned int df : 1; > > + unsigned int dn : 1; > > + unsigned int ec : 1; > > + unsigned int o : 1; > > + } ctrl_sec; > > + unsigned int ctrl_format; > > + }; > > + union { > > + struct { > > + unsigned int pkt_type : 2; > > + unsigned int payload_offset : 8; > > + unsigned int ufo : 1; > > + unsigned int tso : 1; > > + unsigned int tcp_udp_cs : 1; > > + unsigned int mss : 14; > > + unsigned int sctp : 1; > > + unsigned int uc : 1; > > + unsigned int pri : 3; > > + } qsf; > > + unsigned int queue_info; > > + }; > > +}; > > + > > +struct nic_tx_task_section { > > + unsigned int dw0; > > + unsigned int dw1; > > + > > + /* dw2. */ > > + union { > > + struct { > > + /* > > + * When TX direct, output bond id; > > + * when RX direct, output function id. > > + */ > > + unsigned int vport_id : 12; > > + unsigned int vport_type : 4; > > + unsigned int traffic_type : 6; > > + /* > > + * Only used in TX direct, ctrl pkt(LACP\LLDP) output > > + * port id. > > + */ > > + unsigned int secondary_port_id : 2; > > + unsigned int rsvd0 : 6; > > + unsigned int crypto_en : 1; > > + unsigned int pkt_type : 1; > > + } bs2; > > + unsigned int dw2; > > + }; > > + > > + unsigned int dw3; > > +}; > > + > > +struct nic_tx_sge { > > + union { > > + struct { > > + unsigned int length : 31; /**< SGE length. */ > > + unsigned int rsvd : 1; > > + } bs0; > > + unsigned int dw0; > > + }; > > + > > + union { > > + struct { > > + /* Key or unused. */ > > + unsigned int key : 30; > > + /* 0:normal, 1:pointer to next SGE. */ > > + unsigned int extension : 1; > > + /* 0:list, 1:last. */ > > + unsigned int list : 1; > > + } bs1; > > + unsigned int dw1; > > + }; > > + > > + unsigned int dma_addr_high; > > + unsigned int dma_addr_low; > > +}; > > + > > +struct nic_tx_wqe_desc { > > + struct nic_tx_ctrl_section control; > > + struct nic_tx_task_section task; > > + unsigned int bd0_hi_addr; > > + unsigned int bd0_lo_addr; > > +}; > > + > > +/* RX. */ > > +typedef struct tag_l2nic_rx_cqe { > > + union { > > + struct { > > + unsigned int checksum_err : 16; > > + unsigned int lro_num : 8; > > + unsigned int rsvd0 : 1; > > + unsigned int spec_flags : 3; > > + unsigned int flush : 1; > > + unsigned int decry_pkt : 1; > > + unsigned int bp_en : 1; > > + unsigned int rx_done : 1; > > + } bs; > > + unsigned int value; > > + } dw0; > > + > > + union { > > + struct { > > + unsigned int vlan : 16; > > + unsigned int length : 16; > > + } bs; > > + unsigned int value; > > + } dw1; > > + > > + union { > > + struct { > > + unsigned int pkt_types : 12; > > + unsigned int rsvd1 : 7; > > + unsigned int umbcast : 2; > > + unsigned int vlan_offload_en : 1; > > + unsigned int rsvd0 : 2; > > + unsigned int rss_type : 8; > > + } bs; > > + unsigned int value; > > + } dw2; > > + > > + union { > > + struct { > > + unsigned int rss_hash_value; > > + } bs; > > + unsigned int value; > > + } dw3; > > + > > + /* dw4~dw7 field for nic/ovs multipexing. */ > > + union { > > + struct { /**< For nic. */ > > + unsigned int tx_ts_seq : 16; > > + unsigned int msg_1588_offset : 8; > > + unsigned int msg_1588_type : 4; > > + unsigned int rsvd : 1; > > + unsigned int if_rx_ts : 1; > > + unsigned int if_tx_ts : 1; > > + unsigned int if_1588 : 1; > > + } bs; > > + > > + struct { /**< For ovs. */ > > + unsigned int reserved; > > + } ovs_bs; > > + > > + struct { > > + unsigned int xid; > > + } crypt_bs; > > + > > + unsigned int value; > > + } dw4; > > + > > + union { > > + struct { /**< For nic. */ > > + unsigned int msg_1588_ts; > > + } bs; > > + > > + struct { /**< For ovs. */ > > + unsigned int traffic_from : 16; > > + unsigned int traffic_type : 6; > > + unsigned int rsvd0 : 2; > > + unsigned int l4_type : 3; > > + unsigned int l3_type : 3; > > + unsigned int mac_type : 2; > > + } ovs_bs; > > + > > + struct { /**< For crypt. */ > > + unsigned int esp_next_head : 8; > > + unsigned int decrypt_status : 8; > > + unsigned int rsvd : 16; > > + } crypt_bs; > > + > > + unsigned int value; > > + } dw5; > > + > > + union { > > + struct { /**< For nic. */ > > + unsigned int lro_ts; > > + } bs; > > + > > + struct { /**< For ovs. */ > > + unsigned int reserved; > > + } ovs_bs; > > + > > + unsigned int value; > > + } dw6; > > + > > + union { > > + struct { /**< For nic. */ > > + /* Data len of the first or middle pkt size. */ > > + unsigned int first_len : 13; > > + /* Data len of the last pkt size. */ > > + unsigned int last_len : 13; > > + /* The number of packet. */ > > + unsigned int pkt_num : 5; > > + /* Only this bit = 1, other dw fields is valid. */ > > + unsigned int super_cqe_en : 1; > > + } bs; > > + > > + struct { /**< For ovs. */ > > + unsigned int localtag; > > + } ovs_bs; > > + > > + unsigned int value; > > + } dw7; > > +} l2nic_rx_cqe_s; > > + > > +struct nic_rq_bd_sec { > > + unsigned int pkt_buf_addr_high; /**< Packet buffer address high. */ > > + unsigned int pkt_buf_addr_low; /**< Packet buffer address low. */ > > + unsigned int len; > > +}; > > + > > +typedef struct _nic_rq_wqe { > > + /* RX buffer SGE. Notes, buf_desc.len limit in bit 0~13. */ > > + struct nic_rq_bd_sec buf_desc; > > + /* Reserved field 0 for 16B align. */ > > + unsigned int rsvd0; > > + /* > > + * CQE buffer SGE. Notes, cqe_sect.len is in unit of 16B and limit in > > + * bit 0~4. > > + */ > > + struct nic_rq_bd_sec cqe_sect; > > + /* Reserved field 1 for unused. */ > > + unsigned int rsvd1; > > +} nic_rq_wqe; > > + > > +/* CMD. */ > > +struct cmd_show_q_st { > > + struct tool_target target; > > + > > + int qobj; > > + int q_id; > > + int wqe_id; > > + int direction; > > +}; > > + > > +#endif /* _HINIC3_MML_QUEUE */ > > diff --git a/drivers/net/hinic3/mml/meson.build b/drivers/net/hinic3/mml/meson.build > > new file mode 100644 > > index 0000000000..f8d2650d8d > > --- /dev/null > > +++ b/drivers/net/hinic3/mml/meson.build > > @@ -0,0 +1,62 @@ > > +# SPDX-License-Identifier: BSD-3-Clause > > +# Copyright(c) 2025 Huawei Technologies Co., Ltd > > + > > +sources = files( > > + 'hinic3_dbg.c', > > + 'hinic3_mml_cmd.c', > > + 'hinic3_mml_ioctl.c', > > + 'hinic3_mml_lib.c', > > + 'hinic3_mml_main.c', > > + 'hinic3_mml_queue.c', > > +) > > + > > +extra_flags = [ > > + '-Wno-cast-qual', > > + '-Wno-format', > > + '-Wno-format-nonliteral', > > + '-Wno-format-security', > > + '-Wno-missing-braces', > > + '-Wno-missing-field-initializers', > > + '-Wno-missing-prototypes', > > + '-Wno-pointer-sign', > > + '-Wno-pointer-to-int-cast', > > + '-Wno-sign-compare', > > + '-Wno-strict-aliasing', > > + '-Wno-unused-parameter', > > + '-Wno-unused-value', > > + '-Wno-unused-variable', > > +] > > + > > +# The driver runs only on arch64 machine, remove 32bit warnings > > +if not dpdk_conf.get('RTE_ARCH_64') > > + extra_flags += [ > > + '-Wno-int-to-pointer-cast', > > + '-Wno-pointer-to-int-cast', > > + ] > > +endif > > + > > +foreach flag: extra_flags > > + if cc.has_argument(flag) > > + cflags += flag > > + endif > > +endforeach > > + > > +deps += ['hash'] > > + > > +c_args = cflags > > +includes += include_directories('../') > > +includes += include_directories('../base/') > > + > > +mml_lib = static_library( > > + 'hinic3_mml', > > + sources, > > + dependencies: [ > > + static_rte_eal, > > + static_rte_ethdev, > > + static_rte_bus_pci, > > + static_rte_hash, > > + ], > > + include_directories: includes, > > + c_args: c_args, > > +) > > +mml_objs = mml_lib.extract_all_objects() >